From 345932e0e1a1a9472ad809484766bda39608a8ec Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 9 Oct 2022 16:25:38 +0200 Subject: [PATCH 001/104] Add Meson Build System to CMaNGOS WotLK --- contrib/extractor/meson.build | 18 + contrib/git_id/meson.build | 3 + contrib/mmap/meson.build | 51 ++ contrib/vmap_assembler/meson.build | 31 + contrib/vmap_extractor/meson.build | 7 + .../vmap_extractor/vmapextract/meson.build | 20 + dep/g3dlite/meson.build | 52 ++ dep/libmpq/meson.build | 34 + dep/meson.build | 8 + dep/recastnavigation/Detour/meson.build | 26 + dep/recastnavigation/Recast/meson.build | 23 + dep/recastnavigation/meson.build | 14 + dep/src/bzip2/meson.build | 21 + dep/src/gsoap/meson.build | 6 + dep/src/meson.build | 7 + doc/meson.build | 12 + meson.build | 131 +++ meson_options.txt | 15 + src/framework/meson.build | 13 + src/game/meson.build | 805 ++++++++++++++++++ src/mangosd/meson.build | 34 + src/meson.build | 5 + src/realmd/meson.build | 29 + src/shared/meson.build | 90 ++ src/shared/meson_revision.h.in | 6 + subprojects/openssl.wrap | 15 + subprojects/sqlite3.wrap | 13 + subprojects/utfcpp.wrap | 13 + subprojects/zlib.wrap | 13 + 29 files changed, 1515 insertions(+) create mode 100644 contrib/extractor/meson.build create mode 100644 contrib/git_id/meson.build create mode 100644 contrib/mmap/meson.build create mode 100644 contrib/vmap_assembler/meson.build create mode 100644 contrib/vmap_extractor/meson.build create mode 100644 contrib/vmap_extractor/vmapextract/meson.build create mode 100644 dep/g3dlite/meson.build create mode 100644 dep/libmpq/meson.build create mode 100644 dep/meson.build create mode 100644 dep/recastnavigation/Detour/meson.build create mode 100644 dep/recastnavigation/Recast/meson.build create mode 100644 dep/recastnavigation/meson.build create mode 100644 dep/src/bzip2/meson.build create mode 100644 dep/src/gsoap/meson.build create mode 100644 dep/src/meson.build create mode 100644 doc/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 src/framework/meson.build create mode 100644 src/game/meson.build create mode 100644 src/mangosd/meson.build create mode 100644 src/meson.build create mode 100644 src/realmd/meson.build create mode 100644 src/shared/meson.build create mode 100644 src/shared/meson_revision.h.in create mode 100644 subprojects/openssl.wrap create mode 100644 subprojects/sqlite3.wrap create mode 100644 subprojects/utfcpp.wrap create mode 100644 subprojects/zlib.wrap diff --git a/contrib/extractor/meson.build b/contrib/extractor/meson.build new file mode 100644 index 00000000000..ad7a78c5047 --- /dev/null +++ b/contrib/extractor/meson.build @@ -0,0 +1,18 @@ +ad_sources = [ + 'loadlib/loadlib.cpp', + 'loadlib/adt.cpp', + 'loadlib/wdt.cpp', + 'dbcfile.cpp', + 'mpq_libmpq.cpp', + 'System.cpp', +] + +executable('ad', + ad_sources, + link_with: [lib_libmpq], + include_directories: global_includes, + dependencies: [boost_dep, zlib_dep], + link_args: _linker_args, + install_dir: 'bin/tools', + install: true +) diff --git a/contrib/git_id/meson.build b/contrib/git_id/meson.build new file mode 100644 index 00000000000..4d46efc4d0a --- /dev/null +++ b/contrib/git_id/meson.build @@ -0,0 +1,3 @@ +executable('git_id', + 'git_id.cpp', +) \ No newline at end of file diff --git a/contrib/mmap/meson.build b/contrib/mmap/meson.build new file mode 100644 index 00000000000..3d8fcdb630d --- /dev/null +++ b/contrib/mmap/meson.build @@ -0,0 +1,51 @@ +movemapgen_args = '' +movemapgen_args = [movemapgen_args, '-DMMAP_GENERATOR', '-DNO_CORE_FUNCS', '-DNO_vsnprintf', '-DDT_POLYREF64'] +movemapgen_sources = [ + 'src/generator.cpp', + 'src/IntermediateValues.cpp', + 'src/MapBuilder.cpp', + 'src/TerrainBuilder.cpp', + 'src/VMapExtensions.cpp' +] + +if build_machine.system() == 'linux' + movemapgen_args = [movemapgen_args, '-ggdb'] +endif + +vmaplib = static_library('vmaplib', + ['../../src/game/Vmap/BIH.cpp', '../../src/game/Vmap/VMapManager2.cpp', '../../src/game/Vmap/MapTree.cpp', '../../src/game/Vmap/TileAssembler.cpp', '../../src/game/Vmap/WorldModel.cpp', '../../src/game/Vmap/ModelInstance.cpp', '../../src/game/Vmap/GameObjectModelVmaps.cpp'], + include_directories: global_includes, + dependencies: [zlib_dep, boost_dep], + cpp_args: movemapgen_args, + link_with: [g3dlib, detourlib, recastlib, frameworklib, sharedlib], + install : false +) + +mmaplib = static_library('mmaplib', + ['src/generator.cpp', 'src/IntermediateValues.cpp', 'src/MapBuilder.cpp', 'src/TerrainBuilder.cpp', 'src/VMapExtensions.cpp', '../../src/game/MotionGenerators/MoveMapSharedDefines.cpp'], + include_directories: global_includes, + dependencies: [zlib_dep, boost_dep], + cpp_args: movemapgen_args, + link_with: [vmaplib, detourlib, recastlib, g3dlib, frameworklib], + install: false +) + +if get_option('BUILD_EXTRACTORS') + if build_machine.system() == 'linux' + local_linker = [_linker_args, '-rdynamic'] + endif + executable('MoveMapGen', + movemapgen_sources, + link_with: [vmaplib, detourlib, recastlib, mmaplib], + include_directories: global_includes, + dependencies: [boost_dep, zlib_dep], + cpp_args: movemapgen_args, + link_args: _linker_args, + install_dir: 'bin/tools', + install: true + ) + install_data(movemapgen_script_file, install_dir: 'bin/tools') + install_data(offmesh_file, install_dir: 'bin/tools') + install_data(config_json_file, install_dir: 'bin/tools') +endif + diff --git a/contrib/vmap_assembler/meson.build b/contrib/vmap_assembler/meson.build new file mode 100644 index 00000000000..39742f3b437 --- /dev/null +++ b/contrib/vmap_assembler/meson.build @@ -0,0 +1,31 @@ +assembler_args = '' +if get_option('DEBUG') + assembler_args = [assembler_args, '-DIOMAP_DEBUG'] +endif + +assembler_args = [assembler_args, '-DNO_CORE_FUNCS'] + +if build_machine.system() == 'linux' + assembler_args = [assembler_args, '-ggdb'] +endif + +vmap_assembler_sources = [ + '../../src/game/Vmap/BIH.cpp', + '../../src/game/Vmap/VMapManager2.cpp', + '../../src/game/Vmap/MapTree.cpp', + '../../src/game/Vmap/TileAssembler.cpp', + '../../src/game/Vmap/WorldModel.cpp', + '../../src/game/Vmap/ModelInstance.cpp', + 'vmap_assembler.cpp' +] + +executable('vmap_assembler', + vmap_assembler_sources, + link_with: [sharedlib, g3dlib, frameworklib], + include_directories: global_includes, + dependencies: [boost_dep, zlib_dep], + cpp_args: assembler_args, + link_args: _linker_args, + install_dir: 'bin/tools', + install: true +) \ No newline at end of file diff --git a/contrib/vmap_extractor/meson.build b/contrib/vmap_extractor/meson.build new file mode 100644 index 00000000000..3188f07f848 --- /dev/null +++ b/contrib/vmap_extractor/meson.build @@ -0,0 +1,7 @@ +vmap_extractor_args = ['-DIOMAP_DEBUG', '-DUSE_LIBMPQ04'] + +if build_machine.system() == 'linux' + vmap_extractor_args = [vmap_extractor_args, '-ggdb'] +endif + +subdir('vmapextract') \ No newline at end of file diff --git a/contrib/vmap_extractor/vmapextract/meson.build b/contrib/vmap_extractor/vmapextract/meson.build new file mode 100644 index 00000000000..08174f1bb3f --- /dev/null +++ b/contrib/vmap_extractor/vmapextract/meson.build @@ -0,0 +1,20 @@ +vmap_extractor_sources = [ + 'adtfile.cpp', + 'dbcfile.cpp', + 'gameobject_extract.cpp', + 'model.cpp', + 'mpq_libmpq.cpp', + 'vmapexport.cpp', + 'wdtfile.cpp', + 'wmo.cpp' +] + +executable('vmap_extractor', + vmap_extractor_sources, + include_directories: global_includes, + link_with: [g3dlib, lib_libmpq, detourlib, recastlib], + link_args: _linker_args, + install_dir: 'bin/tools', + install: true +) +install_data(extractor_script_file, install_dir: 'bin/tools') \ No newline at end of file diff --git a/dep/g3dlite/meson.build b/dep/g3dlite/meson.build new file mode 100644 index 00000000000..d67873f1ab0 --- /dev/null +++ b/dep/g3dlite/meson.build @@ -0,0 +1,52 @@ +g3d_sources = [ + 'AABox.cpp', + 'Any.cpp', + 'BinaryFormat.cpp', + 'BinaryInput.cpp', + 'BinaryOutput.cpp', + 'Box.cpp', + 'Capsule.cpp', + 'CollisionDetection.cpp', + 'CoordinateFrame.cpp', + 'Crypto.cpp', + 'Cylinder.cpp', + 'FileSystem.cpp', + 'Line.cpp', + 'LineSegment.cpp', + 'Log.cpp', + 'Matrix3.cpp', + 'Matrix4.cpp', + 'MemoryManager.cpp', + 'PhysicsFrame.cpp', + 'Plane.cpp', + 'Quat.cpp', + 'Random.cpp', + 'Ray.cpp', + 'ReferenceCount.cpp', + 'RegistryUtil.cpp', + 'Sphere.cpp', + 'System.cpp', + 'TextInput.cpp', + 'TextOutput.cpp', + 'Triangle.cpp', + 'UprightFrame.cpp', + 'Vector2.cpp', + 'Vector3.cpp', + 'Vector4.cpp', + 'debugAssert.cpp', + 'fileutils.cpp', + 'format.cpp', + 'g3dfnmatch.cpp', + 'g3dmath.cpp', + 'prompt.cpp', + 'stringutils.cpp', + 'uint128.cpp' +] + +g3d_inc = include_directories('G3D', '../include') + +g3dlib = static_library('g3dlite', + g3d_sources, + include_directories: g3d_inc, + dependencies: zlib_dep, + install : false) \ No newline at end of file diff --git a/dep/libmpq/meson.build b/dep/libmpq/meson.build new file mode 100644 index 00000000000..9cb6aeb0dfb --- /dev/null +++ b/dep/libmpq/meson.build @@ -0,0 +1,34 @@ +libmpq_sources = [ + 'config.h', + 'libmpq/common.c', + 'libmpq/common.h', + 'libmpq/crypt_buf.h', + 'libmpq/explode.c', + 'libmpq/explode.h', + 'libmpq/extract.c', + 'libmpq/huffman.c', + 'libmpq/huffman.h', + 'libmpq/mpq-internal.h', + 'libmpq/mpq.c', + 'libmpq/mpq.h', + 'libmpq/pack_begin.h', + 'libmpq/pack_end.h', + 'libmpq/platform.h', + 'libmpq/wave.c', + 'libmpq/wave.h' +] + +libmpq_inc_dir = ['.'] + +if meson.get_compiler('cpp').get_id() == 'msvc' + libmpq_inc_dir = [libmpq_inc_dir, 'win'] +endif + +libmpq_inc = include_directories(libmpq_inc_dir) + +lib_libmpq = static_library('libmpq', + libmpq_sources, + include_directories: libmpq_inc, + dependencies: [zlib_dep, bzip2_dep], + install : false +) \ No newline at end of file diff --git a/dep/meson.build b/dep/meson.build new file mode 100644 index 00000000000..7ea6c11152b --- /dev/null +++ b/dep/meson.build @@ -0,0 +1,8 @@ +if get_option('BUILD_GAME_SERVER') or get_option('BUILD_LOGIN_SERVER') or get_option('BUILD_EXTRACTORS') + subdir('recastnavigation') + subdir('src') + subdir('g3dlite') + if get_option('BUILD_EXTRACTORS') + subdir('libmpq') + endif +endif \ No newline at end of file diff --git a/dep/recastnavigation/Detour/meson.build b/dep/recastnavigation/Detour/meson.build new file mode 100644 index 00000000000..a8b4604a843 --- /dev/null +++ b/dep/recastnavigation/Detour/meson.build @@ -0,0 +1,26 @@ +detour_sources = [ + 'Source/DetourAlloc.cpp', + 'Source/DetourAssert.cpp', + 'Source/DetourCommon.cpp', + 'Source/DetourNavMesh.cpp', + 'Source/DetourNavMeshBuilder.cpp', + 'Source/DetourNavMeshQuery.cpp', + 'Source/DetourNode.cpp', + 'Include/DetourAlloc.h', + 'Include/DetourAssert.h', + 'Include/DetourCommon.h', + 'Include/DetourMath.h', + 'Include/DetourNavMesh.h', + 'Include/DetourNavMeshBuilder.h', + 'Include/DetourNavMeshQuery.h', + 'Include/DetourNode.h', + 'Include/DetourStatus.h' +] + +detour_inc = include_directories('Include') + +detourlib = static_library('Detour', + detour_sources, + include_directories: detour_inc, + cpp_args: recastnav_args, + install : false) \ No newline at end of file diff --git a/dep/recastnavigation/Recast/meson.build b/dep/recastnavigation/Recast/meson.build new file mode 100644 index 00000000000..ead65597fd2 --- /dev/null +++ b/dep/recastnavigation/Recast/meson.build @@ -0,0 +1,23 @@ +recast_sources = [ + 'Source/Recast.cpp', + 'Source/RecastAlloc.cpp', + 'Source/RecastArea.cpp', + 'Source/RecastAssert.cpp', + 'Source/RecastContour.cpp', + 'Source/RecastFilter.cpp', + 'Source/RecastLayers.cpp', + 'Source/RecastMesh.cpp', + 'Source/RecastMeshDetail.cpp', + 'Source/RecastRasterization.cpp', + 'Source/RecastRegion.cpp', + 'Include/Recast.h', + 'Include/RecastAlloc.h', + 'Include/RecastAssert.h' +] + +recastlib = static_library('recast', + recast_sources, + include_directories: include_directories('Include'), + cpp_args: recastnav_args, + install : false +) \ No newline at end of file diff --git a/dep/recastnavigation/meson.build b/dep/recastnavigation/meson.build new file mode 100644 index 00000000000..6cc57ac9b1c --- /dev/null +++ b/dep/recastnavigation/meson.build @@ -0,0 +1,14 @@ +if get_option('BUILD_GAME_SERVER') or get_option('BUILD_EXTRACTORS') or get_option('BUILD_RECASTDEMOMOD') + recastnav_args = '-DDT_POLYREF64' + subdir('Detour') +endif + +if get_option('BUILD_EXTRACTORS') or get_option('BUILD_RECASTDEMOMOD') + subdir('Recast') +endif + +if get_option('BUILD_RECASTDEMOMOD') + subdir('DetourCrowd') + subdir('DetourTileCache') + subdir('DebugUtils') +endif \ No newline at end of file diff --git a/dep/src/bzip2/meson.build b/dep/src/bzip2/meson.build new file mode 100644 index 00000000000..d6d94c17cc5 --- /dev/null +++ b/dep/src/bzip2/meson.build @@ -0,0 +1,21 @@ +bzip2_sources = [ + 'compress.c', + 'crctable.c', + 'decompress.c', + 'huffman.c', + 'randtable.c', + 'blocksort.c', + 'bzlib.c' +] + +bz2_inc = include_directories('.') + +bz2lib = static_library('bzip2', + bzip2_sources, + include_directories: [global_includes, bz2_inc], + install : false) + +bzip2_dep = declare_dependency( + include_directories: bz2_inc, + link_with: bz2lib +) \ No newline at end of file diff --git a/dep/src/gsoap/meson.build b/dep/src/gsoap/meson.build new file mode 100644 index 00000000000..13611254ab1 --- /dev/null +++ b/dep/src/gsoap/meson.build @@ -0,0 +1,6 @@ +gsoap_sources = ['stdsoap2.cpp'] + +gsoaplib = static_library('gsoap', + gsoap_sources, + include_directories: global_includes, + install : false) \ No newline at end of file diff --git a/dep/src/meson.build b/dep/src/meson.build new file mode 100644 index 00000000000..cf0c7baa5b3 --- /dev/null +++ b/dep/src/meson.build @@ -0,0 +1,7 @@ +subdir('gsoap') +if get_option('BUILD_EXTRACTORS') + bzip2_dep = dependency('bzip2', required: false) + if not bzip2_dep.found() + subdir('bzip2') + endif +endif \ No newline at end of file diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 00000000000..45d4466d891 --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,12 @@ +doxygen = find_program('doxygen', required : false) +if doxygen.found() + doxy_file = configure_file( + configuration: {'PACKAGE': meson.project_name(), 'VERSION': meson.project_version(), 'TOPSRCDIR': meson.source_root(), 'DESTDIR': meson.build_root() + '/doc/docs'}, + input: 'Doxyfile.dist', + output: 'Doxyfile' + ) + run_command([doxygen, meson.build_root() + '/doc/Doxyfile'], check: false) + install_subdir(meson.build_root() + '/doc/docs/html', install_dir: 'docs') +else + warning('Documentation disabled without doxygen') +endif diff --git a/meson.build b/meson.build new file mode 100644 index 00000000000..03e36fd2d95 --- /dev/null +++ b/meson.build @@ -0,0 +1,131 @@ +project('CMaNGOS WotLK', 'cpp', 'c', + default_options : ['cpp_std=c++17', 'buildtype=release', 'warning_level=0', 'default_library=static']) + +if build_machine.system() == 'windows' + add_project_arguments('/Zc:strictStrings-', language : 'cpp') +endif + +_linker_args = '' + +boost_dep = dependency('boost', version: '>=1.66.0', static: true, modules: ['thread', 'program_options', 'system', 'filesystem'], required: false) +if not boost_dep.found() + message('Static Boost libraries could not be found. Trying dynamic libraries') + boost_dep = dependency('boost', version: '>=1.66.0', static:false, modules: ['thread', 'program_options', 'system', 'filesystem'], required: true) +endif +dblib_dep = dependency('mariadb', 'libmariadb', 'mysql', 'libmysql', 'postgresql', required: false) +zlib_dep = dependency('zlib', version: '>=1.2.13', static: true, fallback: ['zlib', 'zlib_dep'], required: true) +openssl_dep = dependency('openssl', version: '>=1.1.1', static: true, fallback: ['openssl'], required: true) +utfcpp_dep = dependency('utf8cpp', 'utfcpp', static: true, required: false) + +global_includes = include_directories('src/game', 'dep/libmpq', 'src', 'src/framework', 'src/game/Vmap', + 'dep/json', 'dep/g3dlite', 'src/shared', 'dep/recastnavigation', + 'dep/recastnavigation/Recast/Include', 'dep/recastnavigation/Detour/Include', + 'src/game/MotionGenerators', 'dep/include/bzip2', 'dep/include/gsoap', + 'dep/include') + +if not dblib_dep.found() + if build_machine.system() == 'windows' + mysql_dirs = [ + 'C:\Program Files\MySQL\MySQL Server 8.0\lib', + 'C:\Program Files\MySQL\MySQL Server 5.7\lib', + 'C:\Program Files\MariaDB 11.0\lib', + 'C:\Program Files\MariaDB 11.1\lib', + 'C:\Program Files\MariaDB 11.2\lib', + ] + + fs = import('fs') + if fs.is_dir('C:\Program Files\MySQL\MySQL Server 8.0\lib') + mysql_dll = 'C:\Program Files\MySQL\MySQL Server 8.0\lib\libmysql.dll' + elif fs.is_dir('C:\Program Files\MySQL\MySQL Server 5.7\lib') + mysql_dll = 'C:\Program Files\MySQL\MySQL Server 5.7\lib\libmysql.dll' + elif fs.is_dir('C:\Program Files\MariaDB 11.2\lib') + mysql_dll = 'C:\Program Files\MariaDB 11.2\lib\libmariadb.dll' + elif fs.is_dir('C:\Program Files\MariaDB 11.1\lib') + mysql_dll = 'C:\Program Files\MariaDB 11.1\liblibmariadb.dll' + elif fs.is_dir('C:\Program Files\MariaDB 11.0\lib') + mysql_dll = 'C:\Program Files\MariaDB 11.0\lib\libmariadb.dll' + else + error('No local MySQL Server installation found') + endif + + dblib_dep = meson.get_compiler('cpp').find_library('mysql', dirs: mysql_dirs, static: true, required: false) + if not dblib_dep.found() + dblib_dep = meson.get_compiler('cpp').find_library('mariadb', dirs: mysql_dirs, static: true, required: false) + endif + install_data(mysql_dll, install_dir: get_option('bindir')) + else + error('Either MySQL or MariaDB are required to build CMaNGOS') + endif +endif + +if not dblib_dep.found() + error('Either MySQL or MariaDB are required to build CMaNGOS') +endif + +if get_option('POSTGRESQL') + add_project_arguments('-DDO_POSTGRESQL', language: 'cpp') +endif + +if get_option('DEBUG') + add_project_arguments('-g3', language: 'cpp') +endif + +if not get_option('WARNINGS') + add_project_arguments('-w', language: 'cpp') +endif + +if build_machine.system() == 'linux' + add_project_arguments('-DSYSCONFDIR="../etc/"', language: 'cpp') +endif + +add_project_arguments('-DBOOST_ALL_NO_LIB', language: 'cpp') + +if get_option('BUILD_SCRIPTDEV') + add_project_arguments('-DBUILD_SCRIPTDEV', language: 'cpp') +endif +if get_option('BUILD_PLAYERBOT') + add_project_arguments('-DBUILD_PLAYERBOT', language: 'cpp') +endif +if get_option('BUILD_AHBOT') + add_project_arguments('-DBUILD_AHBOT', language: 'cpp') +endif +if get_option('BUILD_METRICS') + add_project_arguments('-DBUILD_METRICS', language: 'cpp') +endif + +if get_option('BUILD_DOCS') + subdir('doc') +endif + +if get_option('BUILD_RECASTDEMOMOD') + error('RECASTDEMOMOD currently unavailable') + if build_machine.system() == 'windows' + if not get_option('BUILD_EXTRACTORS') + subdir('contrib/mmap') + endif + subdir('contrib/recastdemomod') + else + message('BUILD_RECASTDEMOMOD forced to OFF. Not supported on non windows system.') + endif +endif + +if get_option('BUILD_GIT_ID') + subdir('contrib/git_id') +endif + +subdir('dep') +if get_option('BUILD_GAME_SERVER') or get_option('BUILD_LOGIN_SERVER') or get_option('BUILD_EXTRACTORS') + subdir('src') +endif + +if get_option('BUILD_EXTRACTORS') + extractor_script_file = files('contrib/extractor_scripts/ExtractResources.sh') + movemapgen_script_file = files('contrib/extractor_scripts/MoveMapGen.sh') + config_json_file = files('contrib/extractor_scripts/config.json') + offmesh_file = files('contrib/extractor_scripts/offmesh.txt') + subdir('contrib/extractor') + subdir('contrib/vmap_extractor') + subdir('contrib/vmap_assembler') + subdir('contrib/mmap') +endif + diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000000..98e8bd4e5bb --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,15 @@ +option('DEBUG', type : 'boolean', value: false, description: 'Include additional debug-code in core') +option('WARNINGS', type : 'boolean', value: false, description: 'Show all warnings during compile') +option('POSTGRESQL', type : 'boolean', value: false, description: 'Use PostgreSQL') +option('PCH', type : 'boolean', value: true, description: 'Use precompiled headers') +option('BUILD_GAME_SERVER', type : 'boolean', value: true, description: 'Build game server') +option('BUILD_LOGIN_SERVER', type : 'boolean', value: true, description: 'Build login server') +option('BUILD_EXTRACTORS', type : 'boolean', value: false, description: 'Build map/dbc/vmap/mmap extractors') +option('BUILD_SCRIPTDEV', type : 'boolean', value: true, description: 'Build ScriptDev. (Off speeds up build)') +option('BUILD_PLAYERBOT', type : 'boolean', value: false, description: 'Build Playerbot mod') +option('BUILD_AHBOT', type : 'boolean', value: false, description: 'Build Acution House Bot mod') +option('BUILD_METRICS', type : 'boolean', value: false, description: 'Build Metrics, generate data for Grafana') +option('BUILD_RECASTDEMOMOD', type : 'boolean', value: false, description: 'Build map/vmap/mmap viewer') +option('BUILD_GIT_ID', type : 'boolean', value: false, description: 'Build git_id') +option('BUILD_DOCS', type : 'boolean', value: false, description: 'Build documentation with doxygen') +option('USE_ANTICHEAT', type : 'boolean', value: true, description: 'Use anticheat system') diff --git a/src/framework/meson.build b/src/framework/meson.build new file mode 100644 index 00000000000..477e80daee0 --- /dev/null +++ b/src/framework/meson.build @@ -0,0 +1,13 @@ +framework_sources = [ + 'Policies/ObjectLifeTime.cpp', + 'Utilities/EventProcessor.cpp' +] + +if get_option('BUILD_GAME_SERVER') or get_option('BUILD_LOGIN_SERVER') or get_option('BUILD_EXTRACTORS') +frameworklib = static_library('framework', + framework_sources, + include_directories: global_includes, + dependencies: [boost_dep, dblib_dep, zlib_dep, openssl_dep, utfcpp_dep], + install : false +) +endif \ No newline at end of file diff --git a/src/game/meson.build b/src/game/meson.build new file mode 100644 index 00000000000..c03e467ad8d --- /dev/null +++ b/src/game/meson.build @@ -0,0 +1,805 @@ +game_sources = [ + 'Weather/Weather.cpp', + 'OutdoorPvP/OutdoorPvPEP.cpp', + 'OutdoorPvP/OutdoorPvPTF.cpp', + 'OutdoorPvP/OutdoorPvPSI.cpp', + 'OutdoorPvP/OutdoorPvPHP.cpp', + 'OutdoorPvP/OutdoorPvPGH.cpp', + 'OutdoorPvP/OutdoorPvP.cpp', + 'OutdoorPvP/OutdoorPvPZM.cpp', + 'OutdoorPvP/OutdoorPvPNA.cpp', + 'OutdoorPvP/OutdoorPvPMgr.cpp', + 'GMTickets/GMTicketMgr.cpp', + 'GMTickets/GMTicketHandler.cpp', + 'World/WorldStateVariableManager.cpp', + 'World/World.cpp', + 'World/WorldStateExpression.cpp', + 'World/WorldState.cpp', + 'Trade/TradeHandler.cpp', + 'Anticheat/module/Antispam/antispam.cpp', + 'Anticheat/module/Antispam/antispammgr.cpp', + 'Anticheat/module/config.cpp', + 'Anticheat/module/Warden/wardenmodule.cpp', + 'Anticheat/module/Warden/wardenmac.cpp', + 'Anticheat/module/Warden/wardenmodulemgr.cpp', + 'Anticheat/module/Warden/wardenscan.cpp', + 'Anticheat/module/Warden/wardenwin.cpp', + 'Anticheat/module/Warden/warden.cpp', + 'Anticheat/module/Warden/wardenscanmgr.cpp', + 'Anticheat/module/AddonHandler.cpp', + 'Anticheat/module/libanticheat.cpp', + 'Anticheat/module/anticheatchatcommandsfunctions.cpp', + 'Anticheat/module/Movement/movement.cpp', + 'BattleGround/BattleGroundMgr.cpp', + 'BattleGround/BattleGroundHandler.cpp', + 'BattleGround/BattleGroundRL.cpp', + 'BattleGround/BattleGroundIC.cpp', + 'BattleGround/BattleGround.cpp', + 'BattleGround/BattleGroundAV.cpp', + 'BattleGround/BattleGroundWS.cpp', + 'BattleGround/BattleGroundSA.cpp', + 'BattleGround/BattleGroundEY.cpp', + 'BattleGround/BattleGroundAB.cpp', + 'BattleGround/BattleGroundDS.cpp', + 'BattleGround/BattleGroundRV.cpp', + 'BattleGround/BattleGroundNA.cpp', + 'BattleGround/BattleGroundBE.cpp', + 'Entities/SkillHandler.cpp', + 'Entities/MiscHandler.cpp', + 'Entities/QueryHandler.cpp', + 'Entities/Corpse.cpp', + 'Entities/ObjectGuid.cpp', + 'Entities/StatSystem.cpp', + 'Entities/Bag.cpp', + 'Entities/CharacterHandler.cpp', + 'Entities/Pet.cpp', + 'Entities/ItemHandler.cpp', + 'Entities/Relations.cpp', + 'Entities/NPCHandler.cpp', + 'Entities/RafHandler.cpp', + 'Entities/Vehicle.cpp', + 'Entities/CreatureLinkingMgr.cpp', + 'Entities/Taxi.cpp', + 'Entities/DynamicObject.cpp', + 'Entities/Totem.cpp', + 'Entities/PetHandler.cpp', + 'Entities/Object.cpp', + 'Entities/Transports.cpp', + 'Entities/GossipDef.cpp', + 'Entities/ItemEnchantmentMgr.cpp', + 'Entities/UpdateData.cpp', + 'Entities/EntitiesMgr.cpp', + 'Entities/GameObject.cpp', + 'Entities/Camera.cpp', + 'Entities/TemporarySpawn.cpp', + 'Entities/PetitionsHandler.cpp', + 'Entities/ItemPrototype.cpp', + 'Entities/Creature.cpp', + 'Entities/CreatureSettings.cpp', + 'Entities/VehicleHandler.cpp', + 'Entities/ObjectVisibility.cpp', + 'Entities/Item.cpp', + 'Entities/Unit.cpp', + 'Entities/Player.cpp', + 'Entities/UpdateFields.cpp', + 'GameEvents/GameEventMgr.cpp', + 'GameEvents/moon.cpp', + 'AI/ScriptDevAI/base/pet_ai.cpp', + 'AI/ScriptDevAI/base/guard_ai.cpp', + 'AI/ScriptDevAI/base/CombatAI.cpp', + 'AI/ScriptDevAI/base/BossAI.cpp', + 'AI/ScriptDevAI/base/follower_ai.cpp', + 'AI/ScriptDevAI/base/TimerAI.cpp', + 'AI/ScriptDevAI/base/escort_ai.cpp', + 'AI/ScriptDevAI/include/sc_grid_searchers.cpp', + 'AI/ScriptDevAI/include/sc_instance.cpp', + 'AI/ScriptDevAI/include/sc_creature.cpp', + 'AI/ScriptDevAI/system/ScriptLoader.cpp', + 'AI/ScriptDevAI/system/system.cpp', + 'AI/ScriptDevAI/ScriptDevAIMgr.cpp', + 'AI/BaseAI/GuardAI.cpp', + 'AI/BaseAI/CreatureAI.cpp', + 'AI/BaseAI/PetAI.cpp', + 'AI/BaseAI/GuardianAI.cpp', + 'AI/BaseAI/PossessedAI.cpp', + 'AI/BaseAI/TotemAI.cpp', + 'AI/BaseAI/UnitAI.cpp', + 'AI/BaseAI/GameObjectAI.cpp', + 'AI/BaseAI/NullCreatureAI.cpp', + 'AI/EventAI/CreatureEventAI.cpp', + 'AI/EventAI/CreatureEventAIMgr.cpp', + 'AI/CreatureAISelector.cpp', + 'AI/CreatureAIRegistry.cpp', + 'AI/PlayerAI/PlayerAI.cpp', + 'AI/PlayerAI/CharmAI.cpp', + 'Calendar/Calendar.cpp', + 'Calendar/CalendarHandler.cpp', + 'Models/M2Stores.cpp', + 'Cinematics/CinematicMgr.cpp', + 'Arena/ArenaTeam.cpp', + 'Arena/ArenaTeamHandler.cpp', + 'VoiceChat/VoiceChatHandler.cpp', + 'DBScripts/ScriptMgr.cpp', + 'Maps/SpawnGroup.cpp', + 'Maps/GridMap.cpp', + 'Maps/Map.cpp', + 'Maps/SpawnManager.cpp', + 'Maps/MapDataContainer.cpp', + 'Maps/TaxiHandler.cpp', + 'Maps/InstanceData.cpp', + 'Maps/TransportMgr.cpp', + 'Maps/ObjectPosSelector.cpp', + 'Maps/TransportSystem.cpp', + 'Maps/MapManager.cpp', + 'Maps/MapPersistentStateMgr.cpp', + 'Maps/MapUpdater.cpp', + 'Quests/QuestDef.cpp', + 'Quests/QuestHandler.cpp', + 'MotionGenerators/IdleMovementGenerator.cpp', + 'MotionGenerators/PathFinder.cpp', + 'MotionGenerators/TargetedMovementGenerator.cpp', + 'MotionGenerators/HomeMovementGenerator.cpp', + 'MotionGenerators/PointMovementGenerator.cpp', + 'MotionGenerators/MovementHandler.cpp', + 'MotionGenerators/WrapperMovementGenerator.cpp', + 'MotionGenerators/MotionMaster.cpp', + 'MotionGenerators/MoveMap.cpp', + 'MotionGenerators/WaypointManager.cpp', + 'MotionGenerators/FollowerReference.cpp', + 'MotionGenerators/WaypointMovementGenerator.cpp', + 'MotionGenerators/MoveMapSharedDefines.cpp', + 'MotionGenerators/MovementGenerator.cpp', + 'MotionGenerators/RandomMovementGenerator.cpp', + 'MotionGenerators/PathMovementGenerator.cpp', + 'Tools/CharacterDatabaseCleaner.cpp', + 'Tools/PlayerDump.cpp', + 'Pools/PoolManager.cpp', + 'Guilds/Guild.cpp', + 'Guilds/GuildMgr.cpp', + 'Guilds/GuildHandler.cpp', + 'Battlefield/Battlefield.cpp', + 'Battlefield/BattlefieldWG.cpp', + 'Battlefield/BattlefieldHandler.cpp', + 'Chat/Level2.cpp', + 'Chat/Level1.cpp', + 'Chat/ChannelMgr.cpp', + 'Chat/Level0.cpp', + 'Chat/debugcmds.cpp', + 'Chat/Channel.cpp', + 'Chat/ChatHandler.cpp', + 'Chat/Level3.cpp', + 'Chat/TicketCommands.cpp', + 'Chat/NpcCommands.cpp', + 'Chat/ChannelHandler.cpp', + 'Chat/Chat.cpp', + 'Globals/Locales.cpp', + 'Globals/CombatCondition.cpp', + 'Globals/Conditions.cpp', + 'Globals/GraveyardManager.cpp', + 'Globals/ObjectAccessor.cpp', + 'Globals/ObjectMgr.cpp', + 'Globals/UnitCondition.cpp', + 'AuctionHouse/AuctionHouseHandler.cpp', + 'AuctionHouse/AuctionHouseMgr.cpp', + 'AuctionHouseBot/AuctionHouseBot.cpp', + 'Combat/CombatHandler.cpp', + 'Combat/HostileRefManager.cpp', + 'Combat/DuelHandler.cpp', + 'Combat/CombatManager.cpp', + 'Combat/ThreatManager.cpp', + 'Loot/LootMgr.cpp', + 'Loot/LootHandler.cpp', + 'Spells/Scripts/SpellScript.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Paladin.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Priest.cpp', + 'Spells/Scripts/Scripting/ClassScripts/DeathKnight.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Hunter.cpp', + 'Spells/Scripts/Scripting/ClassScripts/ScalingAuras.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Druid.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Rogue.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Warrior.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Warlock.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Shaman.cpp', + 'Spells/Scripts/Scripting/ClassScripts/Mage.cpp', + 'Spells/SpellHandler.cpp', + 'Spells/Spell.cpp', + 'Spells/SpellAuras.cpp', + 'Spells/UnitAuraProcHandler.cpp', + 'Spells/SpellMgr.cpp', + 'Spells/SpellTargets.cpp', + 'Spells/SpellDefines.cpp', + 'Spells/SpellEffects.cpp', + 'Groups/GroupHandler.cpp', + 'Groups/GroupReference.cpp', + 'Groups/Group.cpp', + 'Social/SocialMgr.cpp', + 'Skills/SkillExtraItems.cpp', + 'Skills/SkillDiscovery.cpp', + 'Vmap/VMapManager2.cpp', + 'Vmap/VMapFactory.cpp', + 'Vmap/BIH.cpp', + 'Vmap/DynamicTree.cpp', + 'Vmap/ModelInstance.cpp', + 'Vmap/WorldModel.cpp', + 'Vmap/TileAssembler.cpp', + 'Vmap/GameObjectModelVmaps.cpp', + 'Vmap/GameObjectModel.cpp', + 'Vmap/MapTree.cpp', + 'Achievements/AchievementMgr.cpp', + 'LFG/LFGQueue.cpp', + 'LFG/LFG.cpp', + 'LFG/LFGMgr.cpp', + 'LFG/LFGHandler.cpp', + 'Server/SQLStorages.cpp', + 'Server/DBCStores.cpp', + 'Server/PacketLog.cpp', + 'Server/Opcodes.cpp', + 'Server/WorldSession.cpp', + 'Server/WorldSocket.cpp', + 'Server/AuthCrypt.cpp', + 'Grids/GridNotifiers.cpp', + 'Grids/ObjectGridLoader.cpp', + 'Grids/GridStates.cpp', + 'Movement/util.cpp', + 'Movement/packet_builder.cpp', + 'Movement/spline.cpp', + 'Movement/MoveSpline.cpp', + 'Movement/MoveSplineInit.cpp', + 'Accounts/AccountMgr.cpp', + 'Reputation/ReputationMgr.cpp', + 'Mails/MassMailMgr.cpp', + 'Mails/MailHandler.cpp', + 'Mails/Mail.cpp' +] + +scriptdev_sources = [ + 'AI/ScriptDevAI/scripts/battlegrounds/battlegrounds.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/uldaman/uldaman.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stranglethorn_vale.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/arathi_highlands.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/westfall.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/karazhanScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_curator.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/chess_event.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/karazhan.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/loch_modan.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stratholme/stratholmeScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stratholme/stratholme.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/isle_of_queldanas.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/undercity.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/dun_morogh.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/burning_steppes.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/silverpine_forest.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/eversong_woods.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scholomance/scholomance.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/silvermoon_city.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/world_eastern_kingdoms.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/hinterlands.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/ironforge.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateauScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/tirisfal_glades.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/deadmines/deadmines.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/magisters_terrace/magisters_terraceScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/swamp_of_sorrows.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/zulaman.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/zulamanScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/boss_malacrass.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunken_temple/sunken_templeScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/shadowfang_keep/boss_hummel.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/boss_kazzak.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/searing_gorge.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackwing_lair/blackwing_lair.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/western_plaguelands.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/alterac_mountains.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_garr.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/molten_core.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/molten_coreScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scarlet_enclave/world_map_ebon_hold.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_depths/boss_coren_direbrew.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/blasted_lands.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/wetlands.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/ghostlands.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/zulgurubScripts.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/zulgurub.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/stormwind_city.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/eastern_plaguelands.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/redridge_mountains.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/elwynn_forest.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/gnomeregan/boss_thermaplugg.cpp', + 'AI/ScriptDevAI/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp', + 'AI/ScriptDevAI/scripts/world/bosses_emerald_dragons.cpp', + 'AI/ScriptDevAI/scripts/world/guards.cpp', + 'AI/ScriptDevAI/scripts/world/spell_scripts_wotlk.cpp', + 'AI/ScriptDevAI/scripts/world/npc_professions.cpp', + 'AI/ScriptDevAI/scripts/world/areatrigger_scripts.cpp', + 'AI/ScriptDevAI/scripts/world/npcs_special.cpp', + 'AI/ScriptDevAI/scripts/world/lunar_festival.cpp', + 'AI/ScriptDevAI/scripts/world/hallows_end.cpp', + 'AI/ScriptDevAI/scripts/world/midsummer_festival.cpp', + 'AI/ScriptDevAI/scripts/world/brewfest.cpp', + 'AI/ScriptDevAI/scripts/world/shade_of_the_horseman.cpp', + 'AI/ScriptDevAI/scripts/world/scourge_invasion.cpp', + 'AI/ScriptDevAI/scripts/world/world_map_scripts.cpp', + 'AI/ScriptDevAI/scripts/world/suns_reach_reclamation.cpp', + 'AI/ScriptDevAI/scripts/world/mob_generic_creature.cpp', + 'AI/ScriptDevAI/scripts/world/item_scripts_wotlk.cpp', + 'AI/ScriptDevAI/scripts/world/item_scripts.cpp', + 'AI/ScriptDevAI/scripts/world/boss_highlord_kruul.cpp', + 'AI/ScriptDevAI/scripts/world/spell_scripts.cpp', + 'AI/ScriptDevAI/scripts/world/war_effort.cpp', + 'AI/ScriptDevAI/scripts/world/childrens_week_tbc.cpp', + 'AI/ScriptDevAI/scripts/world/quest_scripts.cpp', + 'AI/ScriptDevAI/scripts/world/go_scripts.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/world_kalimdor.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/felwood.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/maraudon/boss_noxxion.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/maraudon/instance_maraudon.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/azshara.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/azuremyst_isle.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/darkshore.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/feralas.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/stonetalon_mountains.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/blackfathom_deeps/instance_blackfathom_deeps.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/wailing_caverns/wailing_cavernsScripts.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/boss_azuregos.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/silithus.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/razorfen_kraul/razorfen_kraul.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/tanaris.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/boss_anetheron.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/boss_kazrogal.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/boss_rage_winterchill.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/hyjalScripts.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/boss_azgalor.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbradScripts.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/dark_portal/dark_portalScripts.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqirajScripts.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/dustwallow_marsh.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/zulfarrak/zulfarrak.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/zulfarrak/boss_zumrah.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/teldrassil.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/winterspring.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/orgrimmar.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/durotar.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/razorfen_downs/instance_razorfen_downs.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/desolace.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/thousand_needles.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/ungoro_crater.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/mulgore.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/the_barrens.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/moonglade.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/thunder_bluff.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/bloodmyst_isle.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/dire_maul/instance_dire_maul.cpp', + 'AI/ScriptDevAI/scripts/kalimdor/dire_maul/dire_maul.cpp', + 'AI/ScriptDevAI/scripts/outland/nagrand.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_peninsula.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_mechanar/boss_mechano_lord_capacitus.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_mechanar/mechanar.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/boss_laj.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/boss_thorngrin_the_tender.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/arcatrazScripts.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/boss_soccothrates.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/boss_dalliah.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_alar.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/the_eye.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/shattered_halls/shattered_hallsScripts.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_nazan_and_vazruden.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.cpp', + 'AI/ScriptDevAI/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp', + 'AI/ScriptDevAI/scripts/outland/zangarmarsh.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_mother_shahraz.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/illidari_council.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_illidan.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/black_temple.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_supremus.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_shade_of_akama.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_reliquary_of_souls.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/black_templeScripts.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_bloodboil.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_teron_gorefiend.cpp', + 'AI/ScriptDevAI/scripts/outland/black_temple/boss_warlord_najentus.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/mana_tombs/boss_yor.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/mana_tombs/mana_tombsScripts.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp', + 'AI/ScriptDevAI/scripts/outland/auchindoun/sethekk_halls/boss_talon_king_ikiss.cpp', + 'AI/ScriptDevAI/scripts/outland/blades_edge_mountains.cpp', + 'AI/ScriptDevAI/scripts/outland/boss_terokk.cpp', + 'AI/ScriptDevAI/scripts/outland/boss_doomlord_kazzak.cpp', + 'AI/ScriptDevAI/scripts/outland/netherstorm.cpp', + 'AI/ScriptDevAI/scripts/outland/shattrath_city.cpp', + 'AI/ScriptDevAI/scripts/outland/boss_doomwalker.cpp', + 'AI/ScriptDevAI/scripts/outland/world_outland.cpp', + 'AI/ScriptDevAI/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp', + 'AI/ScriptDevAI/scripts/outland/gruuls_lair/boss_gruul.cpp', + 'AI/ScriptDevAI/scripts/outland/gruuls_lair/gruuls_lair.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/slave_pens/boss_ahune.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/slave_pens/slave_pens.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/serpent_shrine/boss_hydross_the_unstable.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/serpent_shrine/boss_leotheras_the_blind.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/serpent_shrine/serpent_shrine.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/underbog/boss_swamplord_muselek.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/underbog/boss_black_stalker.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/underbog/underbog.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/underbog/boss_hungarfen.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/steam_vault/steam_vault.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/steam_vault/boss_warlord_kalithresh.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/steam_vault/boss_hydromancer_thespia.cpp', + 'AI/ScriptDevAI/scripts/outland/coilfang_reservoir/steam_vault/boss_mekgineer_steamrigger.cpp', + 'AI/ScriptDevAI/scripts/outland/shadowmoon_valley.cpp', + 'AI/ScriptDevAI/scripts/outland/bashir_landing.cpp', + 'AI/ScriptDevAI/scripts/outland/shartuul_transporter.cpp', + 'AI/ScriptDevAI/scripts/outland/terokkar_forest.cpp', + 'AI/ScriptDevAI/scripts/northrend/wintergrasp.cpp', + 'AI/ScriptDevAI/scripts/northrend/world_northrend.cpp', + 'AI/ScriptDevAI/scripts/northrend/grizzly_hills.cpp', + 'AI/ScriptDevAI/scripts/northrend/dalaran.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/nexus/boss_telestra.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/nexus/boss_anomalus.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/nexus/nexus.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/nexus/boss_keristrasza.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/nexus/boss_ormorok.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/oculus/oculus.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/oculus/oculusScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/oculus/boss_varos.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/oculus/boss_urom.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/oculus/boss_eregos.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp', + 'AI/ScriptDevAI/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_bronjahm.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflectionScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saronScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_krick_and_ick.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadelScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_patchwerk.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_heigan.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_anubrekhan.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_thaddius.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_noth.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/naxxramas.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/naxxramasScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_four_horsemen.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_gothik.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_sapphiron.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_gluth.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_maexxna.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_kelthuzad.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_faerlina.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_razuvious.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_loatheb.cpp', + 'AI/ScriptDevAI/scripts/northrend/naxxramas/boss_grobbulus.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_stone/halls_of_stoneScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_xt_002.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/assembly_of_iron.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_algalon.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_freya.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_ignis.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_thorim.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduarScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_hodir.cpp', + 'AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusaderScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp', + 'AI/ScriptDevAI/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp', + 'AI/ScriptDevAI/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp', + 'AI/ScriptDevAI/scripts/northrend/obsidian_sanctum/obsidian_sanctum.cpp', + 'AI/ScriptDevAI/scripts/northrend/sholazar_basin.cpp', + 'AI/ScriptDevAI/scripts/northrend/dragonblight.cpp', + 'AI/ScriptDevAI/scripts/northrend/ruby_sanctum/boss_baltharus.cpp', + 'AI/ScriptDevAI/scripts/northrend/ruby_sanctum/boss_halion.cpp', + 'AI/ScriptDevAI/scripts/northrend/ruby_sanctum/boss_zarithrian.cpp', + 'AI/ScriptDevAI/scripts/northrend/ruby_sanctum/ruby_sanctumScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/ruby_sanctum/boss_saviana.cpp', + 'AI/ScriptDevAI/scripts/northrend/ruby_sanctum/ruby_sanctum.cpp', + 'AI/ScriptDevAI/scripts/northrend/howling_fjord.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_gortok.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keepScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar.cpp', + 'AI/ScriptDevAI/scripts/northrend/storm_peaks.cpp', + 'AI/ScriptDevAI/scripts/northrend/gundrak/boss_eck.cpp', + 'AI/ScriptDevAI/scripts/northrend/gundrak/boss_galdarah.cpp', + 'AI/ScriptDevAI/scripts/northrend/gundrak/boss_colossus.cpp', + 'AI/ScriptDevAI/scripts/northrend/gundrak/boss_moorabi.cpp', + 'AI/ScriptDevAI/scripts/northrend/gundrak/gundrak.cpp', + 'AI/ScriptDevAI/scripts/northrend/gundrak/boss_sladran.cpp', + 'AI/ScriptDevAI/scripts/northrend/icecrown.cpp', + 'AI/ScriptDevAI/scripts/northrend/draktharon_keep/boss_trollgore.cpp', + 'AI/ScriptDevAI/scripts/northrend/draktharon_keep/boss_tharonja.cpp', + 'AI/ScriptDevAI/scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp', + 'AI/ScriptDevAI/scripts/northrend/draktharon_keep/boss_novos.cpp', + 'AI/ScriptDevAI/scripts/northrend/vault_of_archavon/boss_archavon.cpp', + 'AI/ScriptDevAI/scripts/northrend/vault_of_archavon/boss_toravon.cpp', + 'AI/ScriptDevAI/scripts/northrend/vault_of_archavon/boss_koralon.cpp', + 'AI/ScriptDevAI/scripts/northrend/vault_of_archavon/boss_emalon.cpp', + 'AI/ScriptDevAI/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/azjol-nerub/boss_hadronox.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/azjol-nerub/boss_krikthir.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/azjol-nerub/azjol-nerub.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/azjol-nerub/boss_anubarak.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/ahnkahet/boss_nadox.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/ahnkahet/boss_amanitar.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/ahnkahet/ahnkahet.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/ahnkahet/boss_volazj.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/ahnkahet/boss_jedoga.cpp', + 'AI/ScriptDevAI/scripts/northrend/azjol-nerub/ahnkahet/boss_taldaram.cpp', + 'AI/ScriptDevAI/scripts/northrend/borean_tundra.cpp', + 'AI/ScriptDevAI/scripts/northrend/violet_hold/boss_ichoron.cpp', + 'AI/ScriptDevAI/scripts/northrend/violet_hold/violet_holdScripts.cpp', + 'AI/ScriptDevAI/scripts/northrend/violet_hold/boss_xevozz.cpp', + 'AI/ScriptDevAI/scripts/northrend/violet_hold/violet_hold.cpp', + 'AI/ScriptDevAI/scripts/northrend/zuldrak.cpp', + 'AI/ScriptDevAI/scripts/examples/example_escort.cpp', + 'AI/ScriptDevAI/scripts/examples/example_creature.cpp', + 'AI/ScriptDevAI/scripts/examples/example_misc.cpp', + 'AI/ScriptDevAI/scripts/examples/example_gossip_codebox.cpp', +] + +playerbot_sources = [ + 'PlayerBot/Base/PlayerbotClassAI.cpp', + 'PlayerBot/Base/PlayerbotMgr.cpp', + 'PlayerBot/Base/PlayerbotAI.cpp', + 'PlayerBot/AI/PlayerbotDruidAI.cpp', + 'PlayerBot/AI/PlayerbotWarlockAI.cpp', + 'PlayerBot/AI/PlayerbotDeathKnightAI.cpp', + 'PlayerBot/AI/PlayerbotMageAI.cpp', + 'PlayerBot/AI/PlayerbotPriestAI.cpp', + 'PlayerBot/AI/PlayerbotWarriorAI.cpp', + 'PlayerBot/AI/PlayerbotHunterAI.cpp', + 'PlayerBot/AI/PlayerbotRogueAI.cpp', + 'PlayerBot/AI/PlayerbotShamanAI.cpp', + 'PlayerBot/AI/PlayerbotPaladinAI.cpp', +] + +game_inc_dirs = ['.', 'Vmap', 'AuctionHouseBot', 'BattleGround', 'OutdoorPvP', 'PlayerBot'] + +if utfcpp_dep.found() == false + game_inc_dirs = [game_inc_dirs, '../../dep/include/utf8cpp'] +endif + +if build_machine.system() == 'windows' + game_inc_dirs = game_inc_dirs + ['../../dep/lib/include', '../../dep/lib/include/mysql'] +endif + +game_inc = include_directories(game_inc_dirs) + +if get_option('BUILD_SCRIPTDEV') + game_sources = [game_sources, scriptdev_sources] +endif + +if get_option('BUILD_PLAYERBOT') + game_sources = [game_sources, playerbot_sources] + install_data('PlayerBot/playerbot.conf.dist.in', rename: 'playerbot.conf.dist', install_dir: 'etc') +endif + +if not get_option('USE_ANTICHEAT') + game_sources = [game_sources, './Anticheat/Anticheat.cpp'] +else + install_data('Anticheat/module/anticheat.conf.dist.in', rename: 'anticheat.conf.dist', install_dir: 'etc') + install_subdir('Anticheat/module/warden_modules', install_dir : 'bin') # mydir subtree -> include/mydir +endif + +if get_option('BUILD_AHBOT') + install_data('AuctionHouseBot/ahbot.conf.dist.in', rename: 'ahbot.conf.dist', install_dir: 'etc') +endif + +if not get_option('PCH') + pch_files = [] +else + pch_files = ['../game/pchdef.h', '../game/pchdef.cpp'] +endif + +game_args = ['-DDT_POLYREF64', '-D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0'] + +if get_option('BUILD_GAME_SERVER') +gamelib = static_library('game', + game_sources, + include_directories: [game_inc, global_includes], + dependencies: [zlib_dep, boost_dep, dblib_dep, utfcpp_dep], + link_with: [frameworklib, sharedlib, g3dlib, detourlib], + cpp_args: game_args, + cpp_pch: pch_files, + install : false +) +endif diff --git a/src/mangosd/meson.build b/src/mangosd/meson.build new file mode 100644 index 00000000000..a7011253338 --- /dev/null +++ b/src/mangosd/meson.build @@ -0,0 +1,34 @@ +mangosd_sources = [ + 'Master.cpp', + 'MaNGOSsoap.cpp', + 'soapC.cpp', + 'WorldRunnable.cpp', + 'Main.cpp', + 'CliRunnable.cpp', + 'RASocket.cpp', + 'soapServer.cpp' +] + +mangosd_inc_dirs = [] + +if utfcpp_dep.found() == false + mangosd_inc_dirs = [mangosd_inc_dirs, '../../dep/include/utf8cpp'] +endif + +if build_machine.system() == 'windows' + mangosd_inc_dirs = [mangosd_inc_dirs, '../../dep/lib/include', '../../dep/lib/include/mysql'] +endif + +mangosd_inc = include_directories(mangosd_inc_dirs) + +if get_option('BUILD_GAME_SERVER') + executable('mangosd', + mangosd_sources, + link_with: [sharedlib, gamelib, gsoaplib], + include_directories: [mangosd_inc, global_includes], + dependencies: [boost_dep, dblib_dep, zlib_dep, openssl_dep, utfcpp_dep], + link_args: _linker_args, + install: true + ) + install_data('mangosd.conf.dist.in', rename: 'mangosd.conf.dist', install_dir: 'etc') +endif \ No newline at end of file diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000000..1ca4f20955f --- /dev/null +++ b/src/meson.build @@ -0,0 +1,5 @@ +subdir('framework') +subdir('shared') +subdir('game') +subdir('mangosd') +subdir('realmd') \ No newline at end of file diff --git a/src/realmd/meson.build b/src/realmd/meson.build new file mode 100644 index 00000000000..6e776c30697 --- /dev/null +++ b/src/realmd/meson.build @@ -0,0 +1,29 @@ +realmd_sources = [ + 'AuthSocket.cpp', + 'Main.cpp', + 'RealmList.cpp' +] + +realmd_inc_dirs = [] + +if utfcpp_dep.found() == false + realmd_inc_dirs = [realmd_inc_dirs, '../../dep/include/utf8cpp'] +endif + +if build_machine.system() == 'windows' + realmd_inc_dirs = realmd_inc_dirs + ['../../dep/lib/include', '../../dep/lib/include/mysql'] +endif + +realmd_inc = include_directories(realmd_inc_dirs) + +if get_option('BUILD_LOGIN_SERVER') +executable('realmd', + realmd_sources, + link_with: [sharedlib], + include_directories: [realmd_inc, global_includes], + dependencies: [boost_dep, dblib_dep, zlib_dep, openssl_dep, utfcpp_dep], + link_args: _linker_args, + install: true +) +install_data('realmd.conf.dist.in', rename: 'realmd.conf.dist', install_dir: 'etc') +endif \ No newline at end of file diff --git a/src/shared/meson.build b/src/shared/meson.build new file mode 100644 index 00000000000..5ab2fc8b784 --- /dev/null +++ b/src/shared/meson.build @@ -0,0 +1,90 @@ +shared_sources = [ + 'Metric/Measurement.cpp', + 'Metric/Metric.cpp', + 'Util/Util.cpp', + 'Multithreading/Messager.cpp', + 'Log.cpp', + 'Util/ProgressBar.cpp', + 'Multithreading/Threading.cpp', + 'Util/ByteBuffer.cpp', + 'Database/SqlPreparedStatement.cpp', + 'Database/SqlDelayThread.cpp', + 'Database/Field.cpp', + 'Database/Database.cpp', + 'Database/SqlOperations.cpp', + 'Database/QueryResultPostgre.cpp', + 'Database/DBCFileLoader.cpp', + 'Database/DatabasePostgre.cpp', + 'Database/SQLStorage.cpp', + 'Database/QueryResultMysql.cpp', + 'Database/DatabaseMysql.cpp', + 'Auth/SRP6.cpp', + 'Auth/SARC4.cpp', + 'Auth/base32.cpp', + 'Auth/HMACSHA1.cpp', + 'Auth/BigNumber.cpp', + 'Common.cpp', + 'Network/Socket.cpp', + 'Network/PacketBuffer.cpp', + 'Network/NetworkThread.cpp', + 'Network/Listener.cpp', + 'Config/Config.cpp' +] + +shared_linux = [ + 'Platform/PosixDaemon.cpp' +] + +shared_windows = [ + 'Platform/WheatyExceptionReport.cpp', + 'Platform/ServiceWin32.cpp' +] + +shared_inc_dirs = ['Database'] + +if utfcpp_dep.found() == false + shared_inc_dirs = [shared_inc_dirs, '../../dep/include/utf8cpp'] +endif + +if build_machine.system() == 'windows' + shared_sources = shared_sources + shared_windows + shared_inc_dirs = shared_inc_dirs + ['../../dep/lib/include', '../../dep/lib/include/mysql'] +else + shared_sources = shared_sources + shared_linux +endif + +shared_inc = include_directories(shared_inc_dirs) + +revision_target = vcs_tag( + command : ['git', 'rev-parse', 'HEAD'], + fallback : 'Devel', + input : 'meson_revision.h.in', + output : 'meson_revision.h.temp', + replace_string : '@REVISION_ID@' +) + +actual_rev = vcs_tag( + command: ['git', 'show', '--quiet', '--date=iso-strict', '--format="%ad"', 'HEAD'], + fallback: '"0000-00-00T00:00:00+00:00"', + input: revision_target, + output: 'revision.h', + replace_string: '@REVISION_DATE@' +) + +if not get_option('PCH') + pch_files = [] +else + pch_files = ['../shared/pchdef.h', '../shared/pchdef.cpp'] +endif + +if get_option('BUILD_GAME_SERVER') or get_option('BUILD_LOGIN_SERVER') or get_option('BUILD_EXTRACTORS') +sharedlib = static_library('shared', + [actual_rev, shared_sources], + include_directories: [global_includes, shared_inc], + implicit_include_directories: true, + dependencies: [zlib_dep, boost_dep, dblib_dep, openssl_dep, utfcpp_dep], + cpp_pch: pch_files, + link_with: [frameworklib], + install : false +) +endif diff --git a/src/shared/meson_revision.h.in b/src/shared/meson_revision.h.in new file mode 100644 index 00000000000..3ed189ee9d3 --- /dev/null +++ b/src/shared/meson_revision.h.in @@ -0,0 +1,6 @@ +#ifndef __REVISION_H__ +#define __REVISION_H__ + #define REVISION_ID "@REVISION_ID@" + #define REVISION_DATE @REVISION_DATE@ + #define VERSION "0.18" +#endif // __REVISION_H__ diff --git a/subprojects/openssl.wrap b/subprojects/openssl.wrap new file mode 100644 index 00000000000..7d15b54cfce --- /dev/null +++ b/subprojects/openssl.wrap @@ -0,0 +1,15 @@ +[wrap-file] +directory = openssl-3.0.8 +source_url = https://www.openssl.org/source/openssl-3.0.8.tar.gz +source_filename = openssl-3.0.8.tar.gz +source_hash = 6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e +patch_filename = openssl_3.0.8-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/openssl_3.0.8-1/get_patch +patch_hash = 12d9c884174a91ccd1aa9230e9567c019f8a582ce46c98736f99a5200b4f2514 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/openssl_3.0.8-1/openssl-3.0.8.tar.gz +wrapdb_version = 3.0.8-1 + +[provide] +libcrypto = libcrypto_dep +libssl = libssl_dep +openssl = openssl_dep diff --git a/subprojects/sqlite3.wrap b/subprojects/sqlite3.wrap new file mode 100644 index 00000000000..27d0bf156cf --- /dev/null +++ b/subprojects/sqlite3.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = sqlite-amalgamation-3430200 +source_url = https://www.sqlite.org/2023/sqlite-amalgamation-3430200.zip +source_filename = sqlite-amalgamation-3430200.zip +source_hash = a17ac8792f57266847d57651c5259001d1e4e4b46be96ec0d985c953925b2a1c +patch_filename = sqlite3_3.43.2-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.43.2-1/get_patch +patch_hash = 8bfec4036b76fcd0bc8376c0d252a24f5a0925a13c80d411296841a15ac0c3ac +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sqlite3_3.43.2-1/sqlite-amalgamation-3430200.zip +wrapdb_version = 3.43.2-1 + +[provide] +sqlite3 = sqlite3_dep diff --git a/subprojects/utfcpp.wrap b/subprojects/utfcpp.wrap new file mode 100644 index 00000000000..3512216208d --- /dev/null +++ b/subprojects/utfcpp.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = utfcpp-3.2.4 +source_url = https://github.com/nemtrif/utfcpp/archive/v3.2.4.tar.gz +source_filename = utfcpp-3.2.4.tar.gz +source_hash = fde21a4c519eed25f095a1cd8490167409cc70d7b5e9c38756142e588ccb7c7e +patch_filename = utfcpp_3.2.4-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/utfcpp_3.2.4-1/get_patch +patch_hash = 8e233b728579a5e14784e6886767b8e467862fe80baa19e4bea1e3e7c4cf12ae +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/utfcpp_3.2.4-1/utfcpp-3.2.4.tar.gz +wrapdb_version = 3.2.4-1 + +[provide] +utf8cpp = utfcpp_dep diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap new file mode 100644 index 00000000000..2f1a1e2c612 --- /dev/null +++ b/subprojects/zlib.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = zlib-1.3 +source_url = http://zlib.net/fossils/zlib-1.3.tar.gz +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/zlib_1.3-4/zlib-1.3.tar.gz +source_filename = zlib-1.3.tar.gz +source_hash = ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e +patch_filename = zlib_1.3-4_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.3-4/get_patch +patch_hash = 580e61fa3ca9b9ad0d39684b6b889ae92eb5c362c641d8f0d34cf19d49b766ce +wrapdb_version = 1.3-4 + +[provide] +zlib = zlib_dep From aeed048b6c5571affbed15ebefb732ca10fd45b4 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 4 Feb 2024 23:36:16 +0100 Subject: [PATCH 002/104] Meson: Add SQLite --- meson.build | 69 ++++++++++++++++++++++++------------------ meson_options.txt | 1 + src/shared/meson.build | 2 ++ 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/meson.build b/meson.build index 03e36fd2d95..cccc1b83506 100644 --- a/meson.build +++ b/meson.build @@ -16,6 +16,7 @@ dblib_dep = dependency('mariadb', 'libmariadb', 'mysql', 'libmysql', 'postgresql zlib_dep = dependency('zlib', version: '>=1.2.13', static: true, fallback: ['zlib', 'zlib_dep'], required: true) openssl_dep = dependency('openssl', version: '>=1.1.1', static: true, fallback: ['openssl'], required: true) utfcpp_dep = dependency('utf8cpp', 'utfcpp', static: true, required: false) +sqlite_dep = dependency('sqlite3', static: true, fallback: ['sqlite3'], required: get_option('SQLITE')) global_includes = include_directories('src/game', 'dep/libmpq', 'src', 'src/framework', 'src/game/Vmap', 'dep/json', 'dep/g3dlite', 'src/shared', 'dep/recastnavigation', @@ -23,49 +24,57 @@ global_includes = include_directories('src/game', 'dep/libmpq', 'src', 'src/fram 'src/game/MotionGenerators', 'dep/include/bzip2', 'dep/include/gsoap', 'dep/include') -if not dblib_dep.found() - if build_machine.system() == 'windows' - mysql_dirs = [ - 'C:\Program Files\MySQL\MySQL Server 8.0\lib', - 'C:\Program Files\MySQL\MySQL Server 5.7\lib', - 'C:\Program Files\MariaDB 11.0\lib', - 'C:\Program Files\MariaDB 11.1\lib', - 'C:\Program Files\MariaDB 11.2\lib', - ] - - fs = import('fs') - if fs.is_dir('C:\Program Files\MySQL\MySQL Server 8.0\lib') - mysql_dll = 'C:\Program Files\MySQL\MySQL Server 8.0\lib\libmysql.dll' - elif fs.is_dir('C:\Program Files\MySQL\MySQL Server 5.7\lib') - mysql_dll = 'C:\Program Files\MySQL\MySQL Server 5.7\lib\libmysql.dll' - elif fs.is_dir('C:\Program Files\MariaDB 11.2\lib') - mysql_dll = 'C:\Program Files\MariaDB 11.2\lib\libmariadb.dll' - elif fs.is_dir('C:\Program Files\MariaDB 11.1\lib') - mysql_dll = 'C:\Program Files\MariaDB 11.1\liblibmariadb.dll' - elif fs.is_dir('C:\Program Files\MariaDB 11.0\lib') - mysql_dll = 'C:\Program Files\MariaDB 11.0\lib\libmariadb.dll' +if not get_option('SQLITE') + if not dblib_dep.found() + if build_machine.system() == 'windows' + mysql_dirs = [ + 'C:\Program Files\MySQL\MySQL Server 8.0\lib', + 'C:\Program Files\MySQL\MySQL Server 5.7\lib', + 'C:\Program Files\MariaDB 11.0\lib', + 'C:\Program Files\MariaDB 11.1\lib', + 'C:\Program Files\MariaDB 11.2\lib', + ] + + fs = import('fs') + if fs.is_dir('C:\Program Files\MySQL\MySQL Server 8.0\lib') + mysql_dll = 'C:\Program Files\MySQL\MySQL Server 8.0\lib\libmysql.dll' + elif fs.is_dir('C:\Program Files\MySQL\MySQL Server 5.7\lib') + mysql_dll = 'C:\Program Files\MySQL\MySQL Server 5.7\lib\libmysql.dll' + elif fs.is_dir('C:\Program Files\MariaDB 11.2\lib') + mysql_dll = 'C:\Program Files\MariaDB 11.2\lib\libmariadb.dll' + elif fs.is_dir('C:\Program Files\MariaDB 11.1\lib') + mysql_dll = 'C:\Program Files\MariaDB 11.1\liblibmariadb.dll' + elif fs.is_dir('C:\Program Files\MariaDB 11.0\lib') + mysql_dll = 'C:\Program Files\MariaDB 11.0\lib\libmariadb.dll' + else + error('No local MySQL Server installation found') + endif + + dblib_dep = meson.get_compiler('cpp').find_library('mysql', dirs: mysql_dirs, static: true, required: false) + if not dblib_dep.found() + dblib_dep = meson.get_compiler('cpp').find_library('mariadb', dirs: mysql_dirs, static: true, required: false) + endif + install_data(mysql_dll, install_dir: get_option('bindir')) else error('No local MySQL Server installation found') endif - - dblib_dep = meson.get_compiler('cpp').find_library('mysql', dirs: mysql_dirs, static: true, required: false) - if not dblib_dep.found() - dblib_dep = meson.get_compiler('cpp').find_library('mariadb', dirs: mysql_dirs, static: true, required: false) - endif - install_data(mysql_dll, install_dir: get_option('bindir')) - else - error('Either MySQL or MariaDB are required to build CMaNGOS') endif +else + dblib_dep = sqlite_dep endif if not dblib_dep.found() - error('Either MySQL or MariaDB are required to build CMaNGOS') + error('No local SQL Server installation found') endif if get_option('POSTGRESQL') add_project_arguments('-DDO_POSTGRESQL', language: 'cpp') endif +if get_option('SQLITE') + add_project_arguments('-DDO_SQLITE=1', language: 'cpp') +endif + if get_option('DEBUG') add_project_arguments('-g3', language: 'cpp') endif diff --git a/meson_options.txt b/meson_options.txt index 98e8bd4e5bb..f501d07409b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,6 +1,7 @@ option('DEBUG', type : 'boolean', value: false, description: 'Include additional debug-code in core') option('WARNINGS', type : 'boolean', value: false, description: 'Show all warnings during compile') option('POSTGRESQL', type : 'boolean', value: false, description: 'Use PostgreSQL') +option('SQLITE', type : 'boolean', value: false, description: 'Use SQLite') option('PCH', type : 'boolean', value: true, description: 'Use precompiled headers') option('BUILD_GAME_SERVER', type : 'boolean', value: true, description: 'Build game server') option('BUILD_LOGIN_SERVER', type : 'boolean', value: true, description: 'Build login server') diff --git a/src/shared/meson.build b/src/shared/meson.build index 5ab2fc8b784..66493f4a0a6 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -13,8 +13,10 @@ shared_sources = [ 'Database/Database.cpp', 'Database/SqlOperations.cpp', 'Database/QueryResultPostgre.cpp', + 'Database/QueryResultSqlite.cpp', 'Database/DBCFileLoader.cpp', 'Database/DatabasePostgre.cpp', + 'Database/DatabaseSqlite.cpp', 'Database/SQLStorage.cpp', 'Database/QueryResultMysql.cpp', 'Database/DatabaseMysql.cpp', From 4493100014e4aa7c1976607ca64a7d0438804257 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 5 Feb 2024 22:13:28 +0100 Subject: [PATCH 003/104] Meson: Update wrap dependencies --- subprojects/openssl.wrap | 10 +++++----- subprojects/sqlite3.wrap | 18 +++++++++--------- subprojects/zlib.wrap | 18 +++++++++--------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/subprojects/openssl.wrap b/subprojects/openssl.wrap index 7d15b54cfce..873d55106e9 100644 --- a/subprojects/openssl.wrap +++ b/subprojects/openssl.wrap @@ -3,11 +3,11 @@ directory = openssl-3.0.8 source_url = https://www.openssl.org/source/openssl-3.0.8.tar.gz source_filename = openssl-3.0.8.tar.gz source_hash = 6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e -patch_filename = openssl_3.0.8-1_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/openssl_3.0.8-1/get_patch -patch_hash = 12d9c884174a91ccd1aa9230e9567c019f8a582ce46c98736f99a5200b4f2514 -source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/openssl_3.0.8-1/openssl-3.0.8.tar.gz -wrapdb_version = 3.0.8-1 +patch_filename = openssl_3.0.8-3_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/openssl_3.0.8-3/get_patch +patch_hash = 300da189e106942347d61a4a4295aa2edbcf06184f8d13b4cee0bed9fb936963 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/openssl_3.0.8-3/openssl-3.0.8.tar.gz +wrapdb_version = 3.0.8-3 [provide] libcrypto = libcrypto_dep diff --git a/subprojects/sqlite3.wrap b/subprojects/sqlite3.wrap index 27d0bf156cf..bacc6f5a552 100644 --- a/subprojects/sqlite3.wrap +++ b/subprojects/sqlite3.wrap @@ -1,13 +1,13 @@ [wrap-file] -directory = sqlite-amalgamation-3430200 -source_url = https://www.sqlite.org/2023/sqlite-amalgamation-3430200.zip -source_filename = sqlite-amalgamation-3430200.zip -source_hash = a17ac8792f57266847d57651c5259001d1e4e4b46be96ec0d985c953925b2a1c -patch_filename = sqlite3_3.43.2-1_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.43.2-1/get_patch -patch_hash = 8bfec4036b76fcd0bc8376c0d252a24f5a0925a13c80d411296841a15ac0c3ac -source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sqlite3_3.43.2-1/sqlite-amalgamation-3430200.zip -wrapdb_version = 3.43.2-1 +directory = sqlite-amalgamation-3450100 +source_url = https://www.sqlite.org/2024/sqlite-amalgamation-3450100.zip +source_filename = sqlite-amalgamation-3450100.zip +source_hash = 5592243caf28b2cdef41e6ab58d25d653dfc53deded8450eb66072c929f030c4 +patch_filename = sqlite3_3.45.1-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.45.1-1/get_patch +patch_hash = fc2d083fed0de64991c9754a25c7532ef1fd581f7751778b5484f099bec5d6dd +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sqlite3_3.45.1-1/sqlite-amalgamation-3450100.zip +wrapdb_version = 3.45.1-1 [provide] sqlite3 = sqlite3_dep diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap index 2f1a1e2c612..aa14de17740 100644 --- a/subprojects/zlib.wrap +++ b/subprojects/zlib.wrap @@ -1,13 +1,13 @@ [wrap-file] -directory = zlib-1.3 -source_url = http://zlib.net/fossils/zlib-1.3.tar.gz -source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/zlib_1.3-4/zlib-1.3.tar.gz -source_filename = zlib-1.3.tar.gz -source_hash = ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e -patch_filename = zlib_1.3-4_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.3-4/get_patch -patch_hash = 580e61fa3ca9b9ad0d39684b6b889ae92eb5c362c641d8f0d34cf19d49b766ce -wrapdb_version = 1.3-4 +directory = zlib-1.3.1 +source_url = http://zlib.net/fossils/zlib-1.3.1.tar.gz +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/zlib_1.3.1-1/zlib-1.3.1.tar.gz +source_filename = zlib-1.3.1.tar.gz +source_hash = 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23 +patch_filename = zlib_1.3.1-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.3.1-1/get_patch +patch_hash = e79b98eb24a75392009cec6f99ca5cdca9881ff20bfa174e8b8926d5c7a47095 +wrapdb_version = 1.3.1-1 [provide] zlib = zlib_dep From bdf12d30cac80ecd309460286080c3641ee6e69d Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 6 Feb 2024 18:52:50 +0100 Subject: [PATCH 004/104] Meson: Fix some Windows issues --- meson.build | 8 +++++++- meson_options.txt | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index cccc1b83506..a13cd4dce09 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('CMaNGOS WotLK', 'cpp', 'c', - default_options : ['cpp_std=c++17', 'buildtype=release', 'warning_level=0', 'default_library=static']) + default_options : ['cpp_std=vc++17,c++17', 'buildtype=release', 'warning_level=0', 'default_library=static']) if build_machine.system() == 'windows' add_project_arguments('/Zc:strictStrings-', language : 'cpp') @@ -33,6 +33,7 @@ if not get_option('SQLITE') 'C:\Program Files\MariaDB 11.0\lib', 'C:\Program Files\MariaDB 11.1\lib', 'C:\Program Files\MariaDB 11.2\lib', + get_option('LIBMYSQL_PATH'), ] fs = import('fs') @@ -46,6 +47,8 @@ if not get_option('SQLITE') mysql_dll = 'C:\Program Files\MariaDB 11.1\liblibmariadb.dll' elif fs.is_dir('C:\Program Files\MariaDB 11.0\lib') mysql_dll = 'C:\Program Files\MariaDB 11.0\lib\libmariadb.dll' + elif fs.is_dir(get_option('LIBMYSQL_PATH')) + mysql_dll = get_option('LIBMYSQL_PATH') + '\libmysql.dll' else error('No local MySQL Server installation found') endif @@ -87,6 +90,9 @@ if build_machine.system() == 'linux' add_project_arguments('-DSYSCONFDIR="../etc/"', language: 'cpp') endif +if build_machine.system() == 'windows' + meson.get_compiler('cpp'). + add_project_arguments('-DBOOST_ALL_NO_LIB', language: 'cpp') if get_option('BUILD_SCRIPTDEV') diff --git a/meson_options.txt b/meson_options.txt index f501d07409b..24a7d118053 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -14,3 +14,4 @@ option('BUILD_RECASTDEMOMOD', type : 'boolean', value: false, description: 'Buil option('BUILD_GIT_ID', type : 'boolean', value: false, description: 'Build git_id') option('BUILD_DOCS', type : 'boolean', value: false, description: 'Build documentation with doxygen') option('USE_ANTICHEAT', type : 'boolean', value: true, description: 'Use anticheat system') +option('LIBMYSQL_PATH', type : 'string', value: '', description: 'Path to the MySQL Library') From a7247f8aa65b4b95217e57093a9a71816bccfbb7 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 7 Feb 2024 10:53:25 +0100 Subject: [PATCH 005/104] Meson: Remove Experiment --- meson.build | 3 --- 1 file changed, 3 deletions(-) diff --git a/meson.build b/meson.build index a13cd4dce09..97950ef0e8c 100644 --- a/meson.build +++ b/meson.build @@ -90,9 +90,6 @@ if build_machine.system() == 'linux' add_project_arguments('-DSYSCONFDIR="../etc/"', language: 'cpp') endif -if build_machine.system() == 'windows' - meson.get_compiler('cpp'). - add_project_arguments('-DBOOST_ALL_NO_LIB', language: 'cpp') if get_option('BUILD_SCRIPTDEV') From fafb149d2e5aa3fd351c40a710289048ad6e6ca9 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 19 Feb 2024 13:35:03 +0100 Subject: [PATCH 006/104] Meson: Add license, minimum version, fix PCH --- meson.build | 2 ++ src/game/meson.build | 2 +- src/shared/meson.build | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 97950ef0e8c..2664f27af86 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,6 @@ project('CMaNGOS WotLK', 'cpp', 'c', + license: 'GPL-2.0-only', + meson_version: '>=1.3.1', default_options : ['cpp_std=vc++17,c++17', 'buildtype=release', 'warning_level=0', 'default_library=static']) if build_machine.system() == 'windows' diff --git a/src/game/meson.build b/src/game/meson.build index c03e467ad8d..2f2b2b8c465 100644 --- a/src/game/meson.build +++ b/src/game/meson.build @@ -787,7 +787,7 @@ endif if not get_option('PCH') pch_files = [] else - pch_files = ['../game/pchdef.h', '../game/pchdef.cpp'] + pch_files = ['../game/pchdef.h'] endif game_args = ['-DDT_POLYREF64', '-D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0'] diff --git a/src/shared/meson.build b/src/shared/meson.build index 66493f4a0a6..46ca2dad247 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -76,7 +76,7 @@ actual_rev = vcs_tag( if not get_option('PCH') pch_files = [] else - pch_files = ['../shared/pchdef.h', '../shared/pchdef.cpp'] + pch_files = ['../shared/pchdef.h'] endif if get_option('BUILD_GAME_SERVER') or get_option('BUILD_LOGIN_SERVER') or get_option('BUILD_EXTRACTORS') From 5416170d7e9a379445449bfc132c8ed44e0c90aa Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 14 Mar 2024 12:31:41 +0100 Subject: [PATCH 007/104] Add changes to Log.h --- src/shared/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/meson.build b/src/shared/meson.build index 46ca2dad247..55fc7d15c74 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -3,7 +3,7 @@ shared_sources = [ 'Metric/Metric.cpp', 'Util/Util.cpp', 'Multithreading/Messager.cpp', - 'Log.cpp', + 'Log/Log.cpp', 'Util/ProgressBar.cpp', 'Multithreading/Threading.cpp', 'Util/ByteBuffer.cpp', From e4940049bc64cf95fb43e80bdb6602544dabaaf5 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 3 May 2024 14:07:40 +0200 Subject: [PATCH 008/104] Meson: Remove unused files --- src/shared/meson.build | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/shared/meson.build b/src/shared/meson.build index 55fc7d15c74..3d4b13f23ef 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -26,10 +26,6 @@ shared_sources = [ 'Auth/HMACSHA1.cpp', 'Auth/BigNumber.cpp', 'Common.cpp', - 'Network/Socket.cpp', - 'Network/PacketBuffer.cpp', - 'Network/NetworkThread.cpp', - 'Network/Listener.cpp', 'Config/Config.cpp' ] From 064e206c467a4661e04a385e0485ee5d35753e42 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 4 May 2024 15:14:09 +0200 Subject: [PATCH 009/104] Meson: Ignore Modules --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 34f87cabac2..8e1bacb6355 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,8 @@ cmake_install.cmake # Special exceptions # +src/modules + # recastnavigation directory needs exception !dep/recastnavigation/RecastDemo/Build/ /_build/ From 3474443bd59d322962491f4df4acfca339f4a30e Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 10 May 2024 10:26:14 +0200 Subject: [PATCH 010/104] Meson: Add Botanica changes --- src/game/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/game/meson.build b/src/game/meson.build index 2f2b2b8c465..5a4ab8aacb4 100644 --- a/src/game/meson.build +++ b/src/game/meson.build @@ -500,6 +500,7 @@ scriptdev_sources = [ 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp', 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp', 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/boss_thorngrin_the_tender.cpp', + 'AI/ScriptDevAI/scripts/outland/tempest_keep/botanica/botanica.cpp', 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp', 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/arcatrazScripts.cpp', 'AI/ScriptDevAI/scripts/outland/tempest_keep/arcatraz/boss_soccothrates.cpp', From 459dda36626daa76d06a9fe9b1b8d3a14441e4f3 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 21 Dec 2022 14:16:30 +0100 Subject: [PATCH 011/104] BossAI: Add Queued Casts --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 2 +- src/game/AI/ScriptDevAI/base/BossAI.h | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index 3d340146a23..0b96ff9845c 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -114,4 +114,4 @@ void BossAI::AddCastOnDeath(QueuedCast cast) void BossAI::AddRespawnOnEvade(std::chrono::seconds delay) { m_respawnDelay = delay.count(); -} \ No newline at end of file +} diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index 43f96ef7c5b..b73b95358ac 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -122,6 +122,14 @@ class BossAI : public CombatAI void AddRespawnOnEvade(std::chrono::seconds delay); + void AddCastOnDeath(QueuedCast cast); + template + void AddCastOnDeath(QueuedCast cast, Targs... fargs) + { + AddCastOnDeath(cast); + AddCastOnDeath(fargs...); + } + std::chrono::seconds TimeSinceEncounterStart() { return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_combatStartTimestamp); @@ -147,4 +155,4 @@ class BossAI : public CombatAI std::chrono::steady_clock::time_point m_combatStartTimestamp; }; -#endif \ No newline at end of file +#endif From a8763ba6184e3e40c60b3a05c3ff7db19f659269 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 28 Dec 2022 18:10:14 +0100 Subject: [PATCH 012/104] BossAI: Add timed respawn on evade --- src/game/AI/ScriptDevAI/base/BossAI.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index b73b95358ac..79bd0c0dcfc 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -122,14 +122,6 @@ class BossAI : public CombatAI void AddRespawnOnEvade(std::chrono::seconds delay); - void AddCastOnDeath(QueuedCast cast); - template - void AddCastOnDeath(QueuedCast cast, Targs... fargs) - { - AddCastOnDeath(cast); - AddCastOnDeath(fargs...); - } - std::chrono::seconds TimeSinceEncounterStart() { return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_combatStartTimestamp); From 74372b32a192e4fe4704e834f29044b737d503c3 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 28 Dec 2022 22:21:38 +0100 Subject: [PATCH 013/104] BossAI: Add despawning of subordinates on Evade --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 17 +++++++++++++++++ src/game/AI/ScriptDevAI/base/BossAI.h | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index 0b96ff9845c..320b9426762 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -104,6 +104,18 @@ void BossAI::EnterEvadeMode() } m_creature->SetRespawnDelay(m_respawnDelay, true); m_creature->ForcedDespawn(); + for (ObjectGuid& guid : m_despawnSubordinateOnEvade) + { + Creature* addToDespawn = m_creature->GetMap()->GetCreature(guid); + if (!addToDespawn) + continue; + addToDespawn->SetRespawnDelay(m_respawnDelay); + addToDespawn->ForcedDespawn(); + } + if (m_instanceDataType == -1) + return; + if (ScriptedInstance* instance = static_cast(m_creature->GetInstanceData())) + instance->SetData(m_instanceDataType, FAIL); } void BossAI::AddCastOnDeath(QueuedCast cast) @@ -115,3 +127,8 @@ void BossAI::AddRespawnOnEvade(std::chrono::seconds delay) { m_respawnDelay = delay.count(); } + +void BossAI::DespawnSubordinateOnEvade(ObjectGuid guid) +{ + m_despawnSubordinateOnEvade.push_back(guid); +} diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index 79bd0c0dcfc..9392f603476 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -112,6 +112,10 @@ class BossAI : public CombatAI void SetGateDelay(std::chrono::milliseconds delay) { m_gateDelay = delay; } void EnterEvadeMode() override; + /** + * Adds one or more Spells to cast with DoCastSpellIfCan on creature death + * @param cast Initialized struct of QueuedCast type + */ void AddCastOnDeath(QueuedCast cast); template void AddCastOnDeath(QueuedCast cast, Targs... fargs) @@ -120,8 +124,25 @@ class BossAI : public CombatAI AddCastOnDeath(fargs...); } + /** + * Adds a timer to respawn the Creature on Evade (instead of walking back to spawn) + * @param delay The amount of time until the Creature is supposed to respawn as a std::chrono literal + */ void AddRespawnOnEvade(std::chrono::seconds delay); + /** + * Adds one or more Creatures to despawn alongside this Creature on Evade + * Uses the same timer for respawn as was set in AddRespawnOnEvade + * @param guid ObjectGuid of the creature to respawn + */ + void DespawnSubordinateOnEvade(ObjectGuid guid); + template + void DespawnSubordinateOnEvade(ObjectGuid guid, Targs... fargs) + { + DespawnSubordinateOnEvade(guid); + DespawnSubordinateOnEvade(fargs...); + } + std::chrono::seconds TimeSinceEncounterStart() { return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_combatStartTimestamp); @@ -134,6 +155,7 @@ class BossAI : public CombatAI private: std::vector m_onKilledTexts; std::vector m_onAggroTexts; + std::vector m_despawnSubordinateOnEvade; std::vector m_entranceObjects; std::vector m_exitObjects; From 3223183b62d80c3327dfeb72aa6eedce6c22cfe7 Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 29 Dec 2022 09:32:10 +0100 Subject: [PATCH 014/104] BossAI: Add Resettable Values --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 4 ++++ src/game/AI/ScriptDevAI/base/BossAI.h | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index 320b9426762..4ee4a016685 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -36,6 +36,10 @@ void BossAI::Reset() { CombatAI::Reset(); m_creature->SetSpellList(m_creature->GetCreatureInfo()->SpellList); + for (auto& func : m_resetValues) + { + func(); + } } void BossAI::JustDied(Unit* killer) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index 9392f603476..245bb562274 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -143,6 +143,17 @@ class BossAI : public CombatAI DespawnSubordinateOnEvade(fargs...); } + template + void ResetValueTo(T& var, W val) + { + static_assert(std::is_convertible::value, "Value must be of castable type to the variable!"); + T* ptr = &var; + m_resetValues.emplace_back([&]() + { + *ptr = static_cast(val); + }); + } + std::chrono::seconds TimeSinceEncounterStart() { return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_combatStartTimestamp); @@ -162,6 +173,8 @@ class BossAI : public CombatAI std::chrono::milliseconds m_gateDelay = 3s; std::vector m_castOnDeath; + std::vector> m_resetValues; + uint32 m_instanceDataType = -1; uint32 m_respawnDelay = -1; From 561bbd4cd91a754a7cbe3c4254936c87f2f8e917 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 9 Jan 2023 23:20:58 +0100 Subject: [PATCH 015/104] Ulduar: Convert Flame Leviathan to BossAI + Spell Lists --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 560 ++++++++---------- 1 file changed, 241 insertions(+), 319 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 774dcda069a..995a0a947b4 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -21,8 +21,10 @@ SDComment: Defense turret AI and related event NYI. SDCategory: Ulduar EndScriptData */ +#include "AI/ScriptDevAI/base/TimerAI.h" #include "AI/ScriptDevAI/include/sc_common.h" #include "ulduar.h" +#include "AI/ScriptDevAI/base/BossAI.h" enum { @@ -141,8 +143,8 @@ enum TOWER_ID_THORIM = 3, }; -static const int32 aLeviathanTowerYell[KEEPER_ENCOUNTER] = { SAY_TOWER_FROST, SAY_TOWER_NATURE, SAY_TOWER_FIRE, SAY_TOWER_ENERGY }; -static const int32 aLeviathanTowerEmote[KEEPER_ENCOUNTER] = { EMOTE_HODIR_FURY, EMOTE_FREYA_WARD, EMOTE_MIMIRON_INFERNO, EMOTE_THORIM_HAMMER }; +static const int32 leviathanTowerYell[KEEPER_ENCOUNTER] = { SAY_TOWER_FROST, SAY_TOWER_NATURE, SAY_TOWER_FIRE, SAY_TOWER_ENERGY }; +static const int32 leviathanTowerEmote[KEEPER_ENCOUNTER] = { EMOTE_HODIR_FURY, EMOTE_FREYA_WARD, EMOTE_MIMIRON_INFERNO, EMOTE_THORIM_HAMMER }; static const float afFreyaWard[MAX_FREYA_WARD][4] = { @@ -164,414 +166,319 @@ static const float afMimironInferno[3] = {329.1809f, 8.02577f, 409.887f}; ## boss_flame_leviathan ######*/ -struct boss_flame_leviathanAI : public ScriptedAI +enum FlameLeviathanActions { - boss_flame_leviathanAI(Creature* pCreature) : ScriptedAI(pCreature) + LEVIATHAN_FETCH_TOWERS, + LEVIATHAN_HARDMODES, + LEVIATHAN_THORIMS_HAMMER, + LEVIATHAN_ACTIONS_MAX, +}; + +struct boss_flame_leviathanAI : public BossAI +{ + boss_flame_leviathanAI(Creature* creature) : BossAI(creature, LEVIATHAN_ACTIONS_MAX), + m_instance(dynamic_cast(creature->GetInstanceData())), + m_isRegularMode(creature->GetMap()->IsRegularDifficulty()) { - m_pInstance = (instance_ulduar*)pCreature->GetInstanceData(); - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); - m_bInitTowers = false; - Reset(); - } + SetDataType(TYPE_LEVIATHAN); + AddOnAggroText(SAY_AGGRO); + AddOnKillText(SAY_SLAY); + AddOnDeathText(SAY_DEATH); + AddRespawnOnEvade(30s); + AddCustomAction(LEVIATHAN_HARDMODES, 10s, [&]() + { + HandleHardmode(); + }, TIMER_COMBAT_COMBAT); + AddCustomAction(LEVIATHAN_THORIMS_HAMMER, true, [&]() + { + DoSpawnThorimsHammer(); + ++m_thorimsHammerCount; - instance_ulduar* m_pInstance; - bool m_bIsRegularMode; - bool m_bInitTowers; - bool m_bUlduarTower[KEEPER_ENCOUNTER]; + if (m_thorimsHammerCount < MAX_THORIM_HAMMER) + ResetTimer(LEVIATHAN_THORIMS_HAMMER, 1s); + }); + AddTimerlessCombatAction(LEVIATHAN_FETCH_TOWERS, true); + } - uint32 m_uiBatteringRamTimer; - uint32 m_uiFlameVentsTimer; - uint32 m_uiMissileBarrageTimer; - uint32 m_uiPursueTimer; - uint32 m_uiGatheringSpeedTimer; + instance_ulduar* m_instance; + bool m_isRegularMode; + bool m_initTowers; + bool m_ulduarTower[KEEPER_ENCOUNTER]; - uint32 m_uiHardModeTimer; - uint8 m_uiHardModeStep; + uint8 m_hardmodeStep; - uint8 m_uiThorimHammerCount; + uint8 m_thorimsHammerCount; uint32 m_uiThorimHammerTimer; void Reset() override { + m_initTowers = false; DoCastSpellIfCan(m_creature, SPELL_INVISIBILITY_DETECTION, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT); - for (bool& i : m_bUlduarTower) + for (bool& i : m_ulduarTower) i = false; - m_uiBatteringRamTimer = 10000; - m_uiFlameVentsTimer = 30000; - m_uiMissileBarrageTimer = 1000; - m_uiPursueTimer = 1000; - m_uiGatheringSpeedTimer = 10000; - - m_uiHardModeTimer = 10000; - m_uiHardModeStep = 0; - m_uiThorimHammerCount = 0; - m_uiThorimHammerTimer = 0; + m_hardmodeStep = 0; + m_thorimsHammerCount = 0; } - void JustDied(Unit* /*pKiller*/) override + void JustDied(Unit* /*killer*/) override { - if (m_pInstance) + BossAI::JustDied(); + if (m_instance) { - m_pInstance->SetData(TYPE_LEVIATHAN, DONE); - // clear hard mode auras - if (Creature* pOrbital = m_pInstance->GetSingleCreatureFromStorage(NPC_ORBITAL_SUPPORT)) - pOrbital->RemoveAllAuras(); + if (Creature* orbital = m_instance->GetSingleCreatureFromStorage(NPC_ORBITAL_SUPPORT)) + orbital->RemoveAllAuras(); } - DoScriptText(SAY_DEATH, m_creature); - // start epilogue event if (Creature* pFlyMachine = m_creature->SummonCreature(NPC_BRANN_FLYING_MACHINE, 175.2838f, -210.4325f, 501.2375f, 1.42f, TEMPSPAWN_CORPSE_DESPAWN, 0)) { - if (Creature* pBrann = m_creature->SummonCreature(NPC_BRANN_BRONZEBEARD_LEVIATHAN, 175.2554f, -210.6305f, 500.7375f, 1.42f, TEMPSPAWN_CORPSE_DESPAWN, 0)) - pBrann->CastSpell(pFlyMachine, SPELL_RIDE_VEHICLE, TRIGGERED_OLD_TRIGGERED); + if (Creature* brann = m_creature->SummonCreature(NPC_BRANN_BRONZEBEARD_LEVIATHAN, 175.2554f, -210.6305f, 500.7375f, 1.42f, TEMPSPAWN_CORPSE_DESPAWN, 0)) + brann->CastSpell(pFlyMachine, SPELL_RIDE_VEHICLE, TRIGGERED_OLD_TRIGGERED); pFlyMachine->SetWalk(false); pFlyMachine->GetMotionMaster()->MovePoint(1, 229.9419f, -130.3764f, 409.5681f); } } - void Aggro(Unit* /*pWho*/) override + void Aggro(Unit* /*who*/) override { + BossAI::Aggro(); // check the towers again to make sure that some of them were not destroyed in the meanwhile FetchTowers(); - - if (m_pInstance) - m_pInstance->SetData(TYPE_LEVIATHAN, IN_PROGRESS); - - DoScriptText(SAY_AGGRO, m_creature); } - void KilledUnit(Unit* /*pVictim*/) override + void JustSummoned(Creature* summoned) override { - if (urand(0, 1)) - DoScriptText(SAY_SLAY, m_creature); - } - - void JustReachedHome() override - { - if (m_pInstance) - m_pInstance->SetData(TYPE_LEVIATHAN, FAIL); - } - - void JustSummoned(Creature* pSummoned) override - { - switch (pSummoned->GetEntry()) + switch (summoned->GetEntry()) { case NPC_THORIM_HAMMER_VEHICLE: - pSummoned->CastSpell(pSummoned, SPELL_LIGHTNING_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_LIGHTNING_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; case NPC_MIMIRON_INFERNO_VEHICLE: - pSummoned->CastSpell(pSummoned, SPELL_RED_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_RED_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; case NPC_HODIR_FURY_VEHICLE: - pSummoned->CastSpell(pSummoned, SPELL_BLUE_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_BLUE_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; case NPC_FREYA_WARD_VEHICLE: - pSummoned->CastSpell(pSummoned, SPELL_GREEN_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_GREEN_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; } } - void SummonedMovementInform(Creature* pSummoned, uint32 uiMoveType, uint32 uiPointId) override + void SummonedMovementInform(Creature* summoned, uint32 moveType, uint32 pointId) override { - if (uiMoveType != POINT_MOTION_TYPE || !uiPointId) + if (moveType != POINT_MOTION_TYPE || !pointId) return; - if (pSummoned->GetEntry() == NPC_BRANN_FLYING_MACHINE) + if (summoned->GetEntry() == NPC_BRANN_FLYING_MACHINE) { // spawn the Archmange and eject Brann - if (Creature* pArchmage = m_creature->SummonCreature(NPC_ARCHMANGE_RHYDIAN, 235.5596f, -136.1876f, 409.6508f, 1.78f, TEMPSPAWN_CORPSE_DESPAWN, 0)) + if (Creature* archmage = m_creature->SummonCreature(NPC_ARCHMANGE_RHYDIAN, 235.5596f, -136.1876f, 409.6508f, 1.78f, TEMPSPAWN_CORPSE_DESPAWN, 0)) { - pArchmage->SetWalk(false); - pArchmage->GetMotionMaster()->MovePoint(1, 239.3158f, -123.6443f, 409.8174f); + archmage->SetWalk(false); + archmage->GetMotionMaster()->MovePoint(1, 239.3158f, -123.6443f, 409.8174f); } - pSummoned->RemoveAllAuras(); + summoned->RemoveAllAuras(); } - else if (pSummoned->GetEntry() == NPC_ARCHMANGE_RHYDIAN) + else if (summoned->GetEntry() == NPC_ARCHMANGE_RHYDIAN) { - if (Creature* pBrann = GetClosestCreatureWithEntry(pSummoned, NPC_BRANN_BRONZEBEARD_LEVIATHAN, 30.0f)) + if (Creature* brann = GetClosestCreatureWithEntry(summoned, NPC_BRANN_BRONZEBEARD_LEVIATHAN, 30.0f)) { // rest will be handled by DB scripts - pBrann->SetWalk(false); - pBrann->GetMotionMaster()->MoveWaypoint(); + brann->SetWalk(false); + brann->GetMotionMaster()->MoveWaypoint(); } } } - void MovementInform(uint32 uiMoveType, uint32 uiPointId) override + void MovementInform(uint32 moveType, uint32 pointId) override { - if (uiMoveType != POINT_MOTION_TYPE || !uiPointId) + if (moveType != POINT_MOTION_TYPE || !pointId) return; // set boss in combat (if not already) m_creature->SetInCombatWithZone(); } - void SpellHitTarget(Unit* pTarget, SpellEntry const* pSpellEntry) override + void SpellHitTarget(Unit* target, SpellEntry const* spellEntry) override + { + if (target->IsVehicle() && spellEntry->Id == SPELL_PURSUED) + { + m_creature->FixateTarget(target); + + if (Player* player = target->GetBeneficiaryPlayer()) + DoBroadcastText(EMOTE_PURSUE, m_creature, player); + } + } + + void HandleHardmode() { - if (pTarget->IsVehicle() && pSpellEntry->Id == SPELL_PURSUED) + // if all towers are deactivated then skip the rest + if (!m_ulduarTower[TOWER_ID_HODIR] && !m_ulduarTower[TOWER_ID_FREYA] && !m_ulduarTower[TOWER_ID_MIMIRON] && !m_ulduarTower[TOWER_ID_THORIM]) { - m_creature->FixateTarget(pTarget); + DoBroadcastText(SAY_TOWER_DOWN, m_creature); + } + else + { + // yell hard mode start and start activating each tower one by one + switch (m_hardmodeStep) + { + case 0: + DoBroadcastText(SAY_HARD_MODE, m_creature); + ResetTimer(LEVIATHAN_HARDMODES, 10s); + ++m_hardmodeStep; + break; + default: + // iterate through all towers to check which is active; skip the ones which are deactivated without triggering the timer + for (uint8 i = m_hardmodeStep - 1; i < KEEPER_ENCOUNTER; ++i) + { + if (m_ulduarTower[i]) + { + // yell tower active + DoBroadcastText(leviathanTowerYell[i], m_creature); + DoBroadcastText(leviathanTowerEmote[i], m_creature); + + // activate the timer for each tower ability + switch (i) + { + case TOWER_ID_HODIR: DoSpawnHodirsFury(); break; + case TOWER_ID_FREYA: DoSpawnFreyasWard(); break; + case TOWER_ID_MIMIRON: DoSpawnMimironsInferno(); break; + case TOWER_ID_THORIM: ResetTimer(LEVIATHAN_THORIMS_HAMMER, 1s); break; + } + + // reset timer and wait for another turn + ResetTimer(LEVIATHAN_HARDMODES, 10s); + ++m_hardmodeStep; + break; + } + ++m_hardmodeStep; - if (Player* pPlayer = pTarget->GetBeneficiaryPlayer()) - DoScriptText(EMOTE_PURSUE, m_creature, pPlayer); + // stop the timer after the final element + if (i == KEEPER_ENCOUNTER - 1) + DisableTimer(LEVIATHAN_HARDMODES); + } + break; + } } } // check for all active towers void FetchTowers() { - if (!m_pInstance) + if (!m_instance) return; // the orbital support applies the tower auras - Creature* pOrbital = m_pInstance->GetSingleCreatureFromStorage(NPC_ORBITAL_SUPPORT); - if (!pOrbital) + Creature* orbital = m_instance->GetSingleCreatureFromStorage(NPC_ORBITAL_SUPPORT); + if (!orbital) return; - uint8 uiActiveTowers = 0; + uint8 activeTowers = 0; // check the states twice: at reset and at aggro to make sure that some towers were not destroyed in the meanwhile - if (m_pInstance->GetData(TYPE_TOWER_HODIR) == DONE) + if (m_instance->GetData(TYPE_TOWER_HODIR) == DONE) { - pOrbital->CastSpell(pOrbital, SPELL_TOWER_OF_FROST, TRIGGERED_OLD_TRIGGERED); - ++uiActiveTowers; - m_bUlduarTower[TOWER_ID_HODIR] = true; + orbital->CastSpell(orbital, SPELL_TOWER_OF_FROST, TRIGGERED_OLD_TRIGGERED); + ++activeTowers; + m_ulduarTower[TOWER_ID_HODIR] = true; } else - pOrbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_FROST); - if (m_pInstance->GetData(TYPE_TOWER_FREYA) == DONE) + orbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_FROST); + if (m_instance->GetData(TYPE_TOWER_FREYA) == DONE) { - pOrbital->CastSpell(pOrbital, SPELL_TOWER_OF_LIFE, TRIGGERED_OLD_TRIGGERED); - ++uiActiveTowers; - m_bUlduarTower[TOWER_ID_FREYA] = true; + orbital->CastSpell(orbital, SPELL_TOWER_OF_LIFE, TRIGGERED_OLD_TRIGGERED); + ++activeTowers; + m_ulduarTower[TOWER_ID_FREYA] = true; } else - pOrbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_LIFE); - if (m_pInstance->GetData(TYPE_TOWER_MIMIRON) == DONE) + orbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_LIFE); + if (m_instance->GetData(TYPE_TOWER_MIMIRON) == DONE) { - pOrbital->CastSpell(pOrbital, SPELL_TOWER_OF_FLAMES, TRIGGERED_OLD_TRIGGERED); - ++uiActiveTowers; - m_bUlduarTower[TOWER_ID_MIMIRON] = true; + orbital->CastSpell(orbital, SPELL_TOWER_OF_FLAMES, TRIGGERED_OLD_TRIGGERED); + ++activeTowers; + m_ulduarTower[TOWER_ID_MIMIRON] = true; } else - pOrbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_FLAMES); - if (m_pInstance->GetData(TYPE_TOWER_THORIM) == DONE) + orbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_FLAMES); + if (m_instance->GetData(TYPE_TOWER_THORIM) == DONE) { - pOrbital->CastSpell(pOrbital, SPELL_TOWER_OF_STORMS, TRIGGERED_OLD_TRIGGERED); - ++uiActiveTowers; - m_bUlduarTower[TOWER_ID_THORIM] = true; + orbital->CastSpell(orbital, SPELL_TOWER_OF_STORMS, TRIGGERED_OLD_TRIGGERED); + ++activeTowers; + m_ulduarTower[TOWER_ID_THORIM] = true; } else - pOrbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_STORMS); + orbital->RemoveAurasDueToSpell(SPELL_TOWER_OF_STORMS); // inform instance about all active towers for future use in achievements and hard mode loot - m_pInstance->SetData(TYPE_LEVIATHAN_HARD, uiActiveTowers); + m_instance->SetData(TYPE_LEVIATHAN_HARD, activeTowers); } // Functions which handle the spawn of each type of add - void DoSpawnHodirFury() + void DoSpawnHodirsFury() { for (auto i : afHodirFury) m_creature->SummonCreature(NPC_HODIR_FURY_VEHICLE, i[0], i[1], i[2], 0, TEMPSPAWN_DEAD_DESPAWN, 0); } - void DoSpawnFreyaWard() + void DoSpawnFreyasWard() { for (auto i : afFreyaWard) m_creature->SummonCreature(NPC_FREYA_WARD_VEHICLE, i[0], i[1], i[2], i[3], TEMPSPAWN_DEAD_DESPAWN, 0); } - void DoSpawnMimironInferno() + void DoSpawnMimironsInferno() { // Mimiron inferno has waypoint movement m_creature->SummonCreature(NPC_MIMIRON_INFERNO_VEHICLE, afMimironInferno[0], afMimironInferno[1], afMimironInferno[2], 0, TEMPSPAWN_DEAD_DESPAWN, 0); } - void DoSpawnThorimHammer() + void DoSpawnThorimsHammer() { - if (!m_pInstance) + if (!m_instance) return; // get a random point compared to the center and spawn the npcs - if (Creature* pOrbital = m_pInstance->GetSingleCreatureFromStorage(NPC_ORBITAL_SUPPORT)) + if (Creature* orbital = m_instance->GetSingleCreatureFromStorage(NPC_ORBITAL_SUPPORT)) { float fX, fY, fZ; - m_creature->GetRandomPoint(pOrbital->GetPositionX(), pOrbital->GetPositionY(), pOrbital->GetPositionZ(), 150.0f, fX, fY, fZ); + m_creature->GetRandomPoint(orbital->GetPositionX(), orbital->GetPositionY(), orbital->GetPositionZ(), 150.0f, fX, fY, fZ); m_creature->SummonCreature(NPC_THORIM_HAMMER_VEHICLE, fX, fY, fZ, 0, TEMPSPAWN_TIMED_DESPAWN, 8000); } } - void UpdateAI(const uint32 uiDiff) override + void ExecuteAction(uint32 action) override { - // fetch all tower buffs on the first update - if (!m_bInitTowers) + switch (action) { - FetchTowers(); - m_bInitTowers = true; - } - - if (!m_creature->SelectHostileTarget() || !m_creature->GetVictim()) - return; - - if (m_uiPursueTimer < uiDiff) - { - if (DoCastSpellIfCan(m_creature, SPELL_PURSUED) == CAST_OK) + case LEVIATHAN_FETCH_TOWERS: { - // don't yell from the beginning - if (!m_uiHardModeTimer) - { - switch (urand(0, 2)) - { - case 0: DoScriptText(SAY_CHANGE_1, m_creature); break; - case 1: DoScriptText(SAY_CHANGE_2, m_creature); break; - case 2: DoScriptText(SAY_CHANGE_3, m_creature); break; - } - } - m_uiPursueTimer = 30000; + FetchTowers(); + DisableCombatAction(action); + return; } } - else - m_uiPursueTimer -= uiDiff; - - if (m_uiFlameVentsTimer < uiDiff) - { - if (DoCastSpellIfCan(m_creature, SPELL_FLAME_VENTS) == CAST_OK) - m_uiFlameVentsTimer = urand(15000, 25000); - } - else - m_uiFlameVentsTimer -= uiDiff; - - if (m_uiBatteringRamTimer < uiDiff) - { - if (DoCastSpellIfCan(m_creature->GetVictim(), SPELL_BATTERING_RAM) == CAST_OK) - m_uiBatteringRamTimer = urand(10000, 15000); - } - else - m_uiBatteringRamTimer -= uiDiff; - - if (m_uiMissileBarrageTimer < uiDiff) - { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - { - if (DoCastSpellIfCan(pTarget, SPELL_MISSILE_BARRAGE_TARGET) == CAST_OK) - m_uiMissileBarrageTimer = urand(1000, 2000); - } - } - else - m_uiMissileBarrageTimer -= uiDiff; - - if (m_uiGatheringSpeedTimer < uiDiff) - { - if (DoCastSpellIfCan(m_creature, SPELL_GATHERING_SPEED) == CAST_OK) - m_uiGatheringSpeedTimer = 10000; - } - else - m_uiGatheringSpeedTimer -= uiDiff; - - // start hard mode - if (m_uiHardModeTimer) - { - if (m_uiHardModeTimer <= uiDiff) - { - // if all towers are deactivated then skip the rest - if (!m_bUlduarTower[TOWER_ID_HODIR] && !m_bUlduarTower[TOWER_ID_FREYA] && !m_bUlduarTower[TOWER_ID_MIMIRON] && !m_bUlduarTower[TOWER_ID_THORIM]) - { - DoScriptText(SAY_TOWER_DOWN, m_creature); - m_uiHardModeTimer = 0; - } - else - { - // yell hard mode start and start activating each tower one by one - switch (m_uiHardModeStep) - { - case 0: - DoScriptText(SAY_HARD_MODE, m_creature); - m_uiHardModeTimer = 10000; - ++m_uiHardModeStep; - break; - default: - // iterate through all towers to check which is active; skip the ones which are deactivated without triggering the timer - for (uint8 i = m_uiHardModeStep - 1; i < KEEPER_ENCOUNTER; ++i) - { - if (m_bUlduarTower[i]) - { - // yell tower active - DoScriptText(aLeviathanTowerYell[i], m_creature); - DoScriptText(aLeviathanTowerEmote[i], m_creature); - - // activate the timer for each tower ability - switch (i) - { - case TOWER_ID_HODIR: DoSpawnHodirFury(); break; - case TOWER_ID_FREYA: DoSpawnFreyaWard(); break; - case TOWER_ID_MIMIRON: DoSpawnMimironInferno(); break; - case TOWER_ID_THORIM: m_uiThorimHammerTimer = 1000; break; - } - - // reset timer and wait for another turn - m_uiHardModeTimer = 10000; - ++m_uiHardModeStep; - break; - } - ++m_uiHardModeStep; - - // stop the timer after the final element - if (i == KEEPER_ENCOUNTER - 1) - m_uiHardModeTimer = 0; - } - break; - } - } - } - else - m_uiHardModeTimer -= uiDiff; - } - - // Tower of Storm abilities - if (m_uiThorimHammerTimer) - { - if (m_uiThorimHammerTimer <= uiDiff) - { - DoSpawnThorimHammer(); - ++m_uiThorimHammerCount; - - if (m_uiThorimHammerCount == MAX_THORIM_HAMMER) - m_uiThorimHammerTimer = 0; - else - m_uiThorimHammerTimer = 1000; - } - else - m_uiThorimHammerTimer -= uiDiff; - } - - DoMeleeAttackIfReady(); } }; -UnitAI* GetAI_boss_flame_leviathan(Creature* pCreature) -{ - return new boss_flame_leviathanAI(pCreature); -} - /*###### ## npc_hodir_fury_reticle ######*/ struct npc_hodir_fury_reticleAI : public ScriptedAI { - npc_hodir_fury_reticleAI(Creature* pCreature) : ScriptedAI(pCreature) + npc_hodir_fury_reticleAI(Creature* creature) : ScriptedAI(creature) { - m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_instance = (ScriptedInstance*)creature->GetInstanceData(); Reset(); } - ScriptedInstance* m_pInstance; + ScriptedInstance* m_instance; uint32 m_uiTargetChaseTimer; ObjectGuid m_hodirFuryGuid; @@ -582,18 +489,18 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI SetCombatMovement(false); } - void AttackStart(Unit* /*pWho*/) override { } - void MoveInLineOfSight(Unit* /*pWho*/) override { } + void AttackStart(Unit* /*who*/) override { } + void MoveInLineOfSight(Unit* /*who*/) override { } - void JustSummoned(Creature* pSummoned) override + void JustSummoned(Creature* summoned) override { - if (pSummoned->GetEntry() == NPC_HODIR_FURY) - m_hodirFuryGuid = pSummoned->GetObjectGuid(); + if (summoned->GetEntry() == NPC_HODIR_FURY) + m_hodirFuryGuid = summoned->GetObjectGuid(); } - void MovementInform(uint32 uiMoveType, uint32 uiPointId) override + void MovementInform(uint32 moveType, uint32 pointId) override { - if (uiMoveType != POINT_MOTION_TYPE || !uiPointId) + if (moveType != POINT_MOTION_TYPE || !pointId) return; // cast Hodir Fury on point reached and search for another target @@ -603,33 +510,28 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI m_uiTargetChaseTimer = 5000; } - void UpdateAI(const uint32 uiDiff) override + void UpdateAI(const uint32 diff) override { if (m_uiTargetChaseTimer) { - if (m_uiTargetChaseTimer <= uiDiff) + if (m_uiTargetChaseTimer <= diff) { - if (m_pInstance) + if (m_instance) { - if (Creature* pLeviathan = m_pInstance->GetSingleCreatureFromStorage(NPC_LEVIATHAN)) + if (Creature* pLeviathan = m_instance->GetSingleCreatureFromStorage(NPC_LEVIATHAN)) { - if (Unit* pTarget = pLeviathan->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - m_creature->GetMotionMaster()->MovePoint(1, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ()); + if (Unit* target = pLeviathan->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_creature->GetMotionMaster()->MovePoint(1, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); } } m_uiTargetChaseTimer = 0; } else - m_uiTargetChaseTimer -= uiDiff; + m_uiTargetChaseTimer -= diff; } } }; -UnitAI* GetAI_npc_hodir_fury_reticle(Creature* pCreature) -{ - return new npc_hodir_fury_reticleAI(pCreature); -} - /*###### ## npc_hodir_fury ######*/ @@ -637,19 +539,14 @@ UnitAI* GetAI_npc_hodir_fury_reticle(Creature* pCreature) // TODO Remove this 'script' when combat can be proper prevented from core-side struct npc_hodir_furyAI : public Scripted_NoMovementAI { - npc_hodir_furyAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) { Reset(); } + npc_hodir_furyAI(Creature* creature) : Scripted_NoMovementAI(creature) { Reset(); } void Reset() override { } - void AttackStart(Unit* /*pWho*/) override { } - void MoveInLineOfSight(Unit* /*pWho*/) override { } - void UpdateAI(const uint32 /*uiDiff*/) override { } + void AttackStart(Unit* /*who*/) override { } + void MoveInLineOfSight(Unit* /*who*/) override { } + void UpdateAI(const uint32 /*diff*/) override { } }; -UnitAI* GetAI_npc_hodir_fury(Creature* pCreature) -{ - return new npc_hodir_furyAI(pCreature); -} - /*###### ## npc_freya_ward ######*/ @@ -657,7 +554,7 @@ UnitAI* GetAI_npc_hodir_fury(Creature* pCreature) // TODO Move this 'script' to eventAI when combat can be proper prevented from core-side struct npc_freya_wardAI : public Scripted_NoMovementAI { - npc_freya_wardAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) { Reset();} + npc_freya_wardAI(Creature* creature) : Scripted_NoMovementAI(creature) { Reset();} uint32 m_uiFreyaWardTimer; @@ -666,32 +563,27 @@ struct npc_freya_wardAI : public Scripted_NoMovementAI m_uiFreyaWardTimer = 30000; } - void AttackStart(Unit* /*pWho*/) override { } - void MoveInLineOfSight(Unit* /*pWho*/) override { } + void AttackStart(Unit* /*who*/) override { } + void MoveInLineOfSight(Unit* /*who*/) override { } - void JustSummoned(Creature* pSummoned) override + void JustSummoned(Creature* summoned) override { - if (pSummoned->GetEntry() == NPC_WRITHING_LASHER || pSummoned->GetEntry() == NPC_WARD_OF_LIFE) - pSummoned->SetInCombatWithZone(); + if (summoned->GetEntry() == NPC_WRITHING_LASHER || summoned->GetEntry() == NPC_WARD_OF_LIFE) + summoned->SetInCombatWithZone(); } - void UpdateAI(const uint32 uiDiff) override + void UpdateAI(const uint32 diff) override { - if (m_uiFreyaWardTimer < uiDiff) + if (m_uiFreyaWardTimer < diff) { if (DoCastSpellIfCan(m_creature, SPELL_FREYA_WARD) == CAST_OK) m_uiFreyaWardTimer = 30000; } else - m_uiFreyaWardTimer -= uiDiff; + m_uiFreyaWardTimer -= diff; } }; -UnitAI* GetAI_npc_freya_ward(Creature* pCreature) -{ - return new npc_freya_wardAI(pCreature); -} - /*###### ## npc_mimiron_inferno ######*/ @@ -699,7 +591,7 @@ UnitAI* GetAI_npc_freya_ward(Creature* pCreature) // TODO Move this 'script' to eventAI when combat can be proper prevented from core-side struct npc_mimiron_infernoAI : public Scripted_NoMovementAI { - npc_mimiron_infernoAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) { Reset(); } + npc_mimiron_infernoAI(Creature* creature) : Scripted_NoMovementAI(creature) { Reset(); } uint32 m_uiMimironInfernoTimer; @@ -708,50 +600,80 @@ struct npc_mimiron_infernoAI : public Scripted_NoMovementAI m_uiMimironInfernoTimer = 15000; } - void AttackStart(Unit* /*pWho*/) override { } - void MoveInLineOfSight(Unit* /*pWho*/) override { } + void AttackStart(Unit* /*who*/) override { } + void MoveInLineOfSight(Unit* /*who*/) override { } - void UpdateAI(const uint32 uiDiff) override + void UpdateAI(const uint32 diff) override { - if (m_uiMimironInfernoTimer < uiDiff) + if (m_uiMimironInfernoTimer < diff) { if (DoCastSpellIfCan(m_creature, SPELL_MIMIRON_INFERNO) == CAST_OK) m_uiMimironInfernoTimer = 1000; } else - m_uiMimironInfernoTimer -= uiDiff; + m_uiMimironInfernoTimer -= diff; } }; -UnitAI* GetAI_npc_mimiron_inferno(Creature* pCreature) +struct PursueLeviathan : public SpellScript { - return new npc_mimiron_infernoAI(pCreature); -} + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const override + { + if (effIdx != EFFECT_INDEX_0) + return; + Unit* caster = spell->GetCaster(); + if (!caster || !caster->AI() || caster->GetEntry() != NPC_LEVIATHAN) + return; + if (static_cast(caster->AI())->TimeSinceEncounterStart() < 10s) + return; + switch (urand(0, 2)) + { + case 0: DoBroadcastText(SAY_CHANGE_1, caster); break; + case 1: DoBroadcastText(SAY_CHANGE_2, caster); break; + case 2: DoBroadcastText(SAY_CHANGE_3, caster); break; + } + } + + void OnHit(Spell* spell, SpellMissInfo /*missInfo*/) const override + { + Unit* caster = spell->GetCaster(); + Unit* target = spell->GetUnitTarget(); + if (!caster || !target) + return; + if (!target->IsVehicle()) + return; + caster->FixateTarget(target); + if (Player* player = target->GetBeneficiaryPlayer()) + DoBroadcastText(EMOTE_PURSUE, caster, player); + } +}; void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; pNewScript->Name = "boss_flame_leviathan"; - pNewScript->GetAI = GetAI_boss_flame_leviathan; + pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_hodir_fury_reticle"; - pNewScript->GetAI = GetAI_npc_hodir_fury_reticle; + pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_hodir_fury"; - pNewScript->GetAI = GetAI_npc_hodir_fury; + pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_freya_ward"; - pNewScript->GetAI = GetAI_npc_freya_ward; + pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_mimiron_inferno"; - pNewScript->GetAI = GetAI_npc_mimiron_inferno; + pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); + + RegisterSpellScript("spell_pursue_leviathan"); } From fe870e1798408de1ca3954127c865329c42f1ee5 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 9 Jan 2023 23:49:03 +0100 Subject: [PATCH 016/104] Ulduar: Minor Leviathan improvements. Fix hardmodes not despawning --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 995a0a947b4..9d380e4a542 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -252,6 +252,7 @@ struct boss_flame_leviathanAI : public BossAI void JustSummoned(Creature* summoned) override { + m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); switch (summoned->GetEntry()) { case NPC_THORIM_HAMMER_VEHICLE: @@ -305,17 +306,6 @@ struct boss_flame_leviathanAI : public BossAI m_creature->SetInCombatWithZone(); } - void SpellHitTarget(Unit* target, SpellEntry const* spellEntry) override - { - if (target->IsVehicle() && spellEntry->Id == SPELL_PURSUED) - { - m_creature->FixateTarget(target); - - if (Player* player = target->GetBeneficiaryPlayer()) - DoBroadcastText(EMOTE_PURSUE, m_creature, player); - } - } - void HandleHardmode() { // if all towers are deactivated then skip the rest From da343326dd21f6616a6fe9a6ae25b3a86d58d0f4 Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 10 Jan 2023 13:03:25 +0100 Subject: [PATCH 017/104] Ulduar: Get Flame Leviathan to a working state --- sql/scriptdev2/spell.sql | 4 + .../ulduar/ulduar/boss_flame_leviathan.cpp | 99 ++++++++++++++++--- .../northrend/ulduar/ulduar/ulduar.cpp | 35 +++++-- src/game/Spells/SpellAuras.cpp | 4 + 4 files changed, 120 insertions(+), 22 deletions(-) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index f082b9fc9ec..78a97024413 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -952,6 +952,10 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (62108,'spell_tails_up_summon_female_frost_leopard'), (62116,'spell_tails_up_summon_female_icepaw_bear'), (62138,'spell_teleport_inside_violet_hold'), +(62297,'spell_hodirs_fury_leviathan'), +(62910,'spell_mimirons_inferno_leviathan'), +(62912,'spell_thorims_hammer_leviathan'), +(62374,'spell_pursue_leviathan'), (62382,'spell_ignis_brittle'), (62789,'spell_heart_overload'), (62826,'spell_energy_orb_dummy'), diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 9d380e4a542..38130ef9c64 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -105,10 +105,10 @@ enum // SPELL_BIRTH = 40031, // not used; purpose unk // vehicle accessories - // NPC_LEVIATHAN_SEAT = 33114, - // NPC_LEVIATHAN_TURRET = 33139, - // NPC_DEFENSE_TURRET = 33142, - // NPC_OVERLOAD_DEVICE = 33143, + NPC_LEVIATHAN_SEAT = 33114, + NPC_LEVIATHAN_TURRET = 33139, + NPC_DEFENSE_TURRET = 33142, + NPC_OVERLOAD_DEVICE = 33143, // hard mode beacons - they cast the actual damage spells NPC_HODIR_FURY = 33212, @@ -185,10 +185,6 @@ struct boss_flame_leviathanAI : public BossAI AddOnKillText(SAY_SLAY); AddOnDeathText(SAY_DEATH); AddRespawnOnEvade(30s); - AddCustomAction(LEVIATHAN_HARDMODES, 10s, [&]() - { - HandleHardmode(); - }, TIMER_COMBAT_COMBAT); AddCustomAction(LEVIATHAN_THORIMS_HAMMER, true, [&]() { DoSpawnThorimsHammer(); @@ -198,6 +194,8 @@ struct boss_flame_leviathanAI : public BossAI ResetTimer(LEVIATHAN_THORIMS_HAMMER, 1s); }); AddTimerlessCombatAction(LEVIATHAN_FETCH_TOWERS, true); + AddCombatAction(LEVIATHAN_HARDMODES, 10s); + Reset(); } instance_ulduar* m_instance; @@ -243,11 +241,19 @@ struct boss_flame_leviathanAI : public BossAI } } - void Aggro(Unit* /*who*/) override + void EnterEvadeMode() override { - BossAI::Aggro(); - // check the towers again to make sure that some of them were not destroyed in the meanwhile - FetchTowers(); + static const std::vector addEntries = {NPC_LEVIATHAN_SEAT, NPC_LEVIATHAN_TURRET, NPC_DEFENSE_TURRET, NPC_OVERLOAD_DEVICE}; + CreatureList leviAdds; + for (const uint32& entry : addEntries) + { + GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 50.f); + for (auto& add : leviAdds) + { + add->ForcedDespawn(); + } + } + BossAI::EnterEvadeMode(); } void JustSummoned(Creature* summoned) override @@ -299,7 +305,7 @@ struct boss_flame_leviathanAI : public BossAI void MovementInform(uint32 moveType, uint32 pointId) override { - if (moveType != POINT_MOTION_TYPE || !pointId) + if (moveType != EFFECT_MOTION_TYPE) return; // set boss in combat (if not already) @@ -312,6 +318,7 @@ struct boss_flame_leviathanAI : public BossAI if (!m_ulduarTower[TOWER_ID_HODIR] && !m_ulduarTower[TOWER_ID_FREYA] && !m_ulduarTower[TOWER_ID_MIMIRON] && !m_ulduarTower[TOWER_ID_THORIM]) { DoBroadcastText(SAY_TOWER_DOWN, m_creature); + DisableCombatAction(LEVIATHAN_HARDMODES); } else { @@ -320,7 +327,7 @@ struct boss_flame_leviathanAI : public BossAI { case 0: DoBroadcastText(SAY_HARD_MODE, m_creature); - ResetTimer(LEVIATHAN_HARDMODES, 10s); + ResetCombatAction(LEVIATHAN_HARDMODES, 10s); ++m_hardmodeStep; break; default: @@ -343,7 +350,7 @@ struct boss_flame_leviathanAI : public BossAI } // reset timer and wait for another turn - ResetTimer(LEVIATHAN_HARDMODES, 10s); + ResetCombatAction(LEVIATHAN_HARDMODES, 10s); ++m_hardmodeStep; break; } @@ -351,7 +358,7 @@ struct boss_flame_leviathanAI : public BossAI // stop the timer after the final element if (i == KEEPER_ENCOUNTER - 1) - DisableTimer(LEVIATHAN_HARDMODES); + DisableCombatAction(LEVIATHAN_HARDMODES); } break; } @@ -452,6 +459,10 @@ struct boss_flame_leviathanAI : public BossAI DisableCombatAction(action); return; } + case LEVIATHAN_HARDMODES: + { + HandleHardmode(); + } } } }; @@ -638,6 +649,59 @@ struct PursueLeviathan : public SpellScript } }; +struct BatteringRamLeviathan : public SpellScript +{ + // TODO: Figure out Targeting issues +}; + +// 62297 Hodir's Fury +struct HodirsFuryLeviathan : public SpellScript +{ + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override + { + Unit* caster = spell->GetCaster(); + if (!caster) + return false; + if (caster->IsFriend(target)) + return false; + if (!target->IsPlayer() && !target->IsControlledByPlayer()) + return false; + return true; + } +}; + +// 62912 Thorim's Hammer +struct ThorimsHammerLeviathan : public SpellScript +{ + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override + { + Unit* caster = spell->GetCaster(); + if (!caster) + return false; + if (caster->IsFriend(target)) + return false; + if (!target->IsPlayer() && !target->IsControlledByPlayer()) + return false; + return true; + } +}; + +// 62910 Mimiron's Inferno +struct MimironsInfernoLeviathan : public SpellScript +{ + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override + { + Unit* caster = spell->GetCaster(); + if (!caster) + return false; + if (caster->IsFriend(target)) + return false; + if (!target->IsPlayer() && !target->IsControlledByPlayer()) + return false; + return true; + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -666,4 +730,7 @@ void AddSC_boss_flame_leviathan() pNewScript->RegisterSelf(); RegisterSpellScript("spell_pursue_leviathan"); + RegisterSpellScript("spell_hodirs_fury_leviathan"); + RegisterSpellScript("spell_thorims_hammer_leviathan"); + RegisterSpellScript("spell_mimirons_inferno_leviathan"); } diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index 9d609047461..d34fd817692 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -335,7 +335,7 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) break; case GO_LEVIATHAN_GATE: if (m_auiEncounter[TYPE_LEVIATHAN] != NOT_STARTED) - pGo->SetGoState(GO_STATE_ACTIVE); + pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); break; case GO_XT002_GATE: pGo->SetGoState(GO_STATE_READY); @@ -513,14 +513,38 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) case TYPE_LEVIATHAN: m_auiEncounter[uiType] = uiData; if (uiData != SPECIAL) - DoUseDoorOrButton(GO_SHIELD_WALL); + { + if (GameObject* door = GetSingleGameObjectFromStorage(GO_SHIELD_WALL)) + { + switch (uiData) + { + case IN_PROGRESS: + { + sLog.outError("Close the door!"); + if (door->GetGoState() != GO_STATE_READY) + door->SetGoState(GO_STATE_READY); + break; + } + case DONE: + case FAIL: + { + sLog.outError("Open the door!"); + if (door->GetGoState() == GO_STATE_READY) + door->SetGoState(GO_STATE_ACTIVE); + break; + } + + } + } + } if (uiData == IN_PROGRESS) { // make sure that the Lightning door is closed when engaged in combat if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_LIGHTNING_DOOR)) { if (pDoor->GetGoState() != GO_STATE_READY) - DoUseDoorOrButton(GO_LIGHTNING_DOOR); + pDoor->SetGoState(GO_STATE_READY); + //DoUseDoorOrButton(GO_LIGHTNING_DOOR); } SetSpecialAchievementCriteria(TYPE_ACHIEV_SHUTOUT, true); @@ -1606,15 +1630,14 @@ void instance_ulduar::JustDidDialogueStep(int32 iEntry) float fSpeedRate = pLeviathan->GetSpeedRate(MOVE_RUN); pLeviathan->SetWalk(false); pLeviathan->SetSpeedRate(MOVE_RUN, 5); - pLeviathan->GetMotionMaster()->MovePoint(1, afLeviathanMovePos[0], afLeviathanMovePos[1], afLeviathanMovePos[2]); + pLeviathan->GetMotionMaster()->MoveCharge(afLeviathanMovePos[0], afLeviathanMovePos[1], afLeviathanMovePos[2], pLeviathan->GetSpeedRate(MOVE_RUN) * 10, EVENT_CHARGE); pLeviathan->SetSpeedRate(MOVE_RUN, fSpeedRate); // modify respawn / home position to the center of arena pLeviathan->SetRespawnCoord(afLeviathanMovePos[0], afLeviathanMovePos[1], afLeviathanMovePos[2], afLeviathanMovePos[3]); } - // Note: starting 4.x this gate is a GO 33 and it's destroyed at this point - DoUseDoorOrButton(GO_LEVIATHAN_GATE); + GetSingleGameObjectFromStorage(GO_LEVIATHAN_GATE)->SetGoState( GO_STATE_ACTIVE_ALTERNATIVE); break; } } diff --git a/src/game/Spells/SpellAuras.cpp b/src/game/Spells/SpellAuras.cpp index adf06238581..63c04ff82a1 100755 --- a/src/game/Spells/SpellAuras.cpp +++ b/src/game/Spells/SpellAuras.cpp @@ -6938,6 +6938,10 @@ void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/) case 60430: // Molten Fury case 64193: // Heartbreak case 65737: // Heartbreak + case 65077: // Tower of Frost + case 64482: // Tower of Life + case 65076: // Tower of Storms + case 65075: // Tower of Flames target->SetHealth(target->GetMaxHealth()); break; default: From 1cf967ce011d08d56739b5bfcf440b253b9228ee Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 10 Jan 2023 23:15:10 +0100 Subject: [PATCH 018/104] Vehicles/Transport: Fix boarding with existing driver --- src/game/Entities/Vehicle.cpp | 27 ++++++++++++++++++++++++++- src/game/Entities/Vehicle.h | 3 ++- src/game/Entities/VehicleHandler.cpp | 7 +++++-- src/game/Maps/TransportSystem.cpp | 22 ++++++++++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index 354424dd4e7..c4295785bd0 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -279,7 +279,7 @@ void VehicleInfo::Board(Unit* passenger, uint8 seat) if (!IsSeatAvailableFor(passenger, seat)) if (!GetUsableSeatFor(passenger, seat, true, true)) return; - + VehicleSeatEntry const* seatEntry = GetSeatEntry(seat); MANGOS_ASSERT(seatEntry); @@ -473,6 +473,13 @@ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle) { MANGOS_ASSERT(passenger); + for (const auto& m_passenger : m_passengers) + { + if (static_cast(m_passenger.first)->IsVehicle()) + { + static_cast(m_passenger.first)->GetVehicleInfo()->UnBoard(passenger, false); + } + } PassengerMap::const_iterator itr = m_passengers.find(passenger); if (itr == m_passengers.end()) return; @@ -779,11 +786,29 @@ uint8 VehicleInfo::GetTakenSeatsMask() const uint8 takenSeatsMask = 0; for (const auto& m_passenger : m_passengers) + { + if (m_passenger.first->IsUnit()) + if (static_cast(m_passenger.first)->IsVehicle()) + continue; takenSeatsMask |= 1 << m_passenger.second->GetTransportSeat(); + } return takenSeatsMask; } +uint8 VehicleInfo::GetEmptySeats() const +{ + int size = 0; + for (const auto& m_passenger : m_passengers) + { + if (m_passenger.first->IsUnit()) + if (static_cast(m_passenger.first)->IsVehicle()) + continue; + size++; + } + return m_vehicleSeats.size() - size; +} + bool VehicleInfo::IsUsableSeatForPlayer(uint32 seatFlags, uint32 seatFlagsB) const { return seatFlags & (SEAT_FLAG_HAS_ENTER_ANIM | SEAT_FLAG_HAS_RIDE_ANIM) || diff --git a/src/game/Entities/Vehicle.h b/src/game/Entities/Vehicle.h index 9d708bea1c1..2850105415c 100644 --- a/src/game/Entities/Vehicle.h +++ b/src/game/Entities/Vehicle.h @@ -119,7 +119,8 @@ class VehicleInfo : public TransportBase uint8 GetTakenSeatsMask() const; uint8 GetEmptySeatsMask() const { return ~GetTakenSeatsMask(); } - uint8 GetEmptySeats() const { return m_vehicleSeats.size() - m_passengers.size(); } + //uint8 GetEmptySeats() const { return m_vehicleSeats.size() - m_passengers.size(); } + uint8 GetEmptySeats() const; bool IsUsableSeatForPlayer(uint32 seatFlags, uint32 seatFlagsB) const; bool IsUsableSeatForCreature(uint32 /*seatFlags*/) const { return true; } // special flag?, !IsUsableSeatForPlayer(seatFlags)? diff --git a/src/game/Entities/VehicleHandler.cpp b/src/game/Entities/VehicleHandler.cpp index a6bb4000986..8e2b49f9556 100644 --- a/src/game/Entities/VehicleHandler.cpp +++ b/src/game/Entities/VehicleHandler.cpp @@ -47,7 +47,9 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket& recvPacket) return; // Remove Vehicle Control Aura - vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, _player->GetObjectGuid()); + //vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, _player->GetObjectGuid()); + + vehicle->GetVehicleInfo()->UnBoard(_player, false); } void WorldSession::HandleRequestVehicleExit(WorldPacket& recvPacket) @@ -184,7 +186,8 @@ void WorldSession::HandleRideVehicleInteract(WorldPacket& recvPacket) ObjectGuid playerGuid; recvPacket >> playerGuid; - Player* vehicle = _player->GetMap()->GetPlayer(playerGuid); + //Player* vehicle = _player->GetMap()->GetPlayer(playerGuid); + Unit* vehicle = _player->GetMap()->GetUnit(playerGuid); if (!vehicle || !vehicle->IsVehicle()) return; diff --git a/src/game/Maps/TransportSystem.cpp b/src/game/Maps/TransportSystem.cpp index d0c7c5d95f5..4aacfd5d77e 100644 --- a/src/game/Maps/TransportSystem.cpp +++ b/src/game/Maps/TransportSystem.cpp @@ -32,6 +32,7 @@ #include "Entities/Vehicle.h" #include "Maps/MapManager.h" #include "Entities/Transports.h" +#include "Log.h" /* **************************************** TransportBase ****************************************/ @@ -158,6 +159,18 @@ void TransportBase::BoardPassenger(WorldObject* passenger, float lx, float ly, f { TransportInfo* transportInfo = new TransportInfo(passenger, this, lx, ly, lz, lo, seat); + for (const auto& m_passenger : m_passengers) + { + if (transportInfo->GetTransportSeat() == m_passenger.second->GetTransportSeat()) + if (m_passenger.first->IsUnit()) + { + if (static_cast(m_passenger.first)->IsVehicle()) + { + static_cast(m_passenger.first)->GetVehicleInfo()->Board(static_cast(passenger), 0); + return; + } + } + } // Insert our new passenger m_passengers.insert(PassengerMap::value_type(passenger, transportInfo)); @@ -169,6 +182,15 @@ void TransportBase::UnBoardPassenger(WorldObject* passenger) { PassengerMap::iterator itr = m_passengers.find(passenger); + for (const auto& m_passenger : m_passengers) + { + if (m_passenger.first->IsUnit()) + { + if (static_cast(m_passenger.first)->IsVehicle() && static_cast(m_passenger.first)->GetVehicleInfo()->HasOnBoard(passenger)) + static_cast(m_passenger.first)->GetVehicleInfo()->UnBoard(static_cast(passenger), false); + } + } + if (itr == m_passengers.end()) return; From d0dd15ebf355ce5b6d4eb115b5ff7e623fe6a46d Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 11 Jan 2023 10:38:00 +0100 Subject: [PATCH 019/104] Vehicles: Also count passengers inside of passengers --- src/game/Entities/Vehicle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index c4295785bd0..8e980c47f74 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -788,7 +788,7 @@ uint8 VehicleInfo::GetTakenSeatsMask() const for (const auto& m_passenger : m_passengers) { if (m_passenger.first->IsUnit()) - if (static_cast(m_passenger.first)->IsVehicle()) + if (static_cast(m_passenger.first)->IsVehicle() && static_cast(m_passenger.first)->GetVehicleInfo()->GetEmptySeats() > 0) continue; takenSeatsMask |= 1 << m_passenger.second->GetTransportSeat(); } @@ -802,7 +802,7 @@ uint8 VehicleInfo::GetEmptySeats() const for (const auto& m_passenger : m_passengers) { if (m_passenger.first->IsUnit()) - if (static_cast(m_passenger.first)->IsVehicle()) + if (static_cast(m_passenger.first)->IsVehicle() && static_cast(m_passenger.first)->GetVehicleInfo()->GetEmptySeats() > 0) continue; size++; } From fa4ba94ce43ec28b488b3be07c1288a81c043d26 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 15 Jan 2023 23:47:30 +0100 Subject: [PATCH 020/104] Vehicles: More Vehicle fixes --- src/game/Entities/Vehicle.cpp | 45 ++++++++++++++++++++++++---- src/game/Entities/Vehicle.h | 1 + src/game/Entities/VehicleHandler.cpp | 29 ++++++++++++++++-- src/game/Maps/TransportSystem.cpp | 6 ++-- src/game/Maps/TransportSystem.h | 2 +- src/game/Spells/Spell.cpp | 3 +- 6 files changed, 73 insertions(+), 13 deletions(-) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index 8e980c47f74..6d8ab941405 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -202,6 +202,26 @@ VehicleInfo::~VehicleInfo() RemoveAccessoriesFromMap(); // Remove accessories (for example required with player vehicles) } +void VehicleInfo::RepopulateSeat(uint8 seatId) +{ + // Loading passengers (rough version only!) + SQLMultiStorage::SQLMSIteratorBounds bounds = sVehicleAccessoryStorage.getBounds(m_overwriteNpcEntry); + for (SQLMultiStorage::SQLMultiSIterator itr = bounds.first; itr != bounds.second; ++itr) + { + auto* seatEntry = GetSeatEntry(itr->seatId); + if (seatId == itr->seatId && seatEntry && seatEntry->m_ID && !GetPassenger(seatId)) + { + if (Creature* summoned = m_owner->SummonCreature(itr->passengerEntry, m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ(), 2 * m_owner->GetOrientation(), TEMPSPAWN_DEAD_DESPAWN, 0)) + { + DEBUG_LOG("VehicleInfo(of %s)::Initialize: Load vehicle accessory %s onto seat %u", m_owner->GetGuidStr().c_str(), summoned->GetGuidStr().c_str(), itr->seatId); + m_accessoryGuids.insert(summoned->GetObjectGuid()); + int32 basepoint0 = itr->seatId + 1; + summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED); + } + } + } +} + void VehicleInfo::Initialize() { if (!m_overwriteNpcEntry) @@ -213,9 +233,17 @@ void VehicleInfo::Initialize() SQLMultiStorage::SQLMSIteratorBounds bounds = sVehicleAccessoryStorage.getBounds(m_overwriteNpcEntry); for (SQLMultiStorage::SQLMultiSIterator itr = bounds.first; itr != bounds.second; ++itr) { - Position pos = m_owner->GetPosition(); - pos.o *= 2; - SummonPassenger(itr->passengerEntry, pos, itr->seatId); + auto* seatEntry = GetSeatEntry(itr->seatId); + if (seatEntry && seatEntry->m_ID) + { + if (Creature* summoned = m_owner->SummonCreature(itr->passengerEntry, m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ(), 2 * m_owner->GetOrientation(), TEMPSPAWN_DEAD_DESPAWN, 0)) + { + DEBUG_LOG("VehicleInfo(of %s)::Initialize: Load vehicle accessory %s onto seat %u", m_owner->GetGuidStr().c_str(), summoned->GetGuidStr().c_str(), itr->seatId); + m_accessoryGuids.insert(summoned->GetObjectGuid()); + int32 basepoint0 = itr->seatId + 1; + summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED); + } + } } } @@ -477,7 +505,7 @@ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle) { if (static_cast(m_passenger.first)->IsVehicle()) { - static_cast(m_passenger.first)->GetVehicleInfo()->UnBoard(passenger, false); + static_cast(m_passenger.first)->GetVehicleInfo()->UnBoard(passenger, changeVehicle); } } PassengerMap::const_iterator itr = m_passengers.find(passenger); @@ -844,6 +872,8 @@ void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags) pPlayer->SetCharm(pVehicle); pVehicle->SetCharmer(pPlayer); + pVehicle->SetCanEnterCombat(true); + pVehicle->GetMotionMaster()->Clear(); pVehicle->GetMotionMaster()->MoveIdle(); pVehicle->StopMoving(true); @@ -954,8 +984,8 @@ void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) if (pPlayer->IsPvPFreeForAll()) pVehicle->SetPvPFreeForAll(false); - // must be called after movement control unapplying - pPlayer->GetCamera().ResetView(); + // // must be called after movement control unapplying + // pPlayer->GetCamera().ResetView(); if (pVehicle->GetTypeId() == TYPEID_UNIT) { @@ -966,6 +996,9 @@ void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) } } + // must be called after movement control unapplying + pPlayer->GetCamera().ResetView(); + if (seatFlags & SEAT_FLAG_CAN_CAST) pPlayer->RemovePetActionBar(); } diff --git a/src/game/Entities/Vehicle.h b/src/game/Entities/Vehicle.h index 2850105415c..638b75a35f4 100644 --- a/src/game/Entities/Vehicle.h +++ b/src/game/Entities/Vehicle.h @@ -79,6 +79,7 @@ class VehicleInfo : public TransportBase { public: explicit VehicleInfo(Unit* owner, VehicleEntry const* vehicleEntry, uint32 overwriteNpcEntry); + void RepopulateSeat(uint8 seatId); void Initialize(); ///< Initializes the accessories bool IsInitialized() const { return m_isInitialized; } void SummonPassenger(uint32 entry, Position const& pos, uint8 seatId); diff --git a/src/game/Entities/VehicleHandler.cpp b/src/game/Entities/VehicleHandler.cpp index 8e2b49f9556..f25cdeee9f0 100644 --- a/src/game/Entities/VehicleHandler.cpp +++ b/src/game/Entities/VehicleHandler.cpp @@ -42,12 +42,18 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket& recvPacket) Unit* vehicle = (Unit*)transportInfo->GetTransport(); + if (!vehicle) + return; // Something went wrong if (vehicleGuid != vehicle->GetObjectGuid()) return; + if (vehicle->IsBoarded()) + { + vehicle = static_cast(vehicle->GetTransportInfo()->GetTransport()); + } // Remove Vehicle Control Aura - //vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, _player->GetObjectGuid()); + vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, _player->GetObjectGuid()); vehicle->GetVehicleInfo()->UnBoard(_player, false); } @@ -63,10 +69,19 @@ void WorldSession::HandleRequestVehicleExit(WorldPacket& recvPacket) Unit* vehicle = (Unit*)transportInfo->GetTransport(); + if (!vehicle) + return; + if (vehicle->IsBoarded()) + { + vehicle = static_cast(vehicle->GetTransportInfo()->GetTransport()); + } // Check for exit flag if (VehicleSeatEntry const* seatEntry = vehicle->GetVehicleInfo()->GetSeatEntry(transportInfo->GetTransportSeat())) if (seatEntry->m_flags & SEAT_FLAG_CAN_EXIT) + { vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, _player->GetObjectGuid()); + vehicle->GetVehicleInfo()->UnBoard(_player, false); + } } void WorldSession::HandleRequestVehicleNextSeat(WorldPacket& recvPacket) @@ -195,8 +210,16 @@ void WorldSession::HandleRideVehicleInteract(WorldPacket& recvPacket) // Only allowed if in same raid if (!vehicle->IsInGroup(_player)) return; - - _player->CastSpell(vehicle, SPELL_RIDE_VEHICLE_HARDCODED, TRIGGERED_OLD_TRIGGERED); + SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(vehicle->GetEntry()); + bool spellFound = false; + for (SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) + if (itr->second.IsFitToRequirements(_player, vehicle->GetTypeId() == TYPEID_UNIT ? (Creature*)vehicle : nullptr)) + { + _player->CastSpell(vehicle, itr->second.spellId, TRIGGERED_OLD_TRIGGERED); + spellFound = true; + } + if (!spellFound) + _player->CastSpell(vehicle, SPELL_RIDE_VEHICLE_HARDCODED, TRIGGERED_OLD_TRIGGERED); } void WorldSession::HandleEjectPassenger(WorldPacket& recvPacket) diff --git a/src/game/Maps/TransportSystem.cpp b/src/game/Maps/TransportSystem.cpp index 4aacfd5d77e..7fbbe0b838e 100644 --- a/src/game/Maps/TransportSystem.cpp +++ b/src/game/Maps/TransportSystem.cpp @@ -48,6 +48,7 @@ TransportBase::TransportBase(WorldObject* owner) : TransportBase::~TransportBase() { + m_passengers.clear(); MANGOS_ASSERT(m_passengers.empty()); } @@ -155,7 +156,7 @@ bool TransportBase::HasOnBoard(WorldObject const* passenger) const return false; } -void TransportBase::BoardPassenger(WorldObject* passenger, float lx, float ly, float lz, float lo, uint8 seat) +bool TransportBase::BoardPassenger(WorldObject* passenger, float lx, float ly, float lz, float lo, uint8 seat) { TransportInfo* transportInfo = new TransportInfo(passenger, this, lx, ly, lz, lo, seat); @@ -167,7 +168,7 @@ void TransportBase::BoardPassenger(WorldObject* passenger, float lx, float ly, f if (static_cast(m_passenger.first)->IsVehicle()) { static_cast(m_passenger.first)->GetVehicleInfo()->Board(static_cast(passenger), 0); - return; + return false; } } } @@ -176,6 +177,7 @@ void TransportBase::BoardPassenger(WorldObject* passenger, float lx, float ly, f // The passenger needs fast access to transportInfo passenger->SetTransportInfo(transportInfo); + return true; } void TransportBase::UnBoardPassenger(WorldObject* passenger) diff --git a/src/game/Maps/TransportSystem.h b/src/game/Maps/TransportSystem.h index c8b2434485d..311060ade38 100644 --- a/src/game/Maps/TransportSystem.h +++ b/src/game/Maps/TransportSystem.h @@ -75,7 +75,7 @@ class TransportBase protected: // Helper functions to add/ remove a passenger from the list - void BoardPassenger(WorldObject* passenger, float lx, float ly, float lz, float lo, uint8 seat); + bool BoardPassenger(WorldObject* passenger, float lx, float ly, float lz, float lo, uint8 seat); void UnBoardPassenger(WorldObject* passenger); WorldObject* m_owner; ///< The transporting unit diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index 9720a612adc..ac511d8c987 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -4081,7 +4081,8 @@ void Spell::update(uint32 difftime) // check if the player or unit caster has moved before the spell finished (exclude casting on vehicles) if ((m_trueCaster->IsUnit() && m_timer != 0) && (m_castPositionX != m_trueCaster->GetPositionX() || m_castPositionY != m_trueCaster->GetPositionY() || m_castPositionZ != m_trueCaster->GetPositionZ()) && - (m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK || !m_trueCaster->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR))) + (m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK || !m_trueCaster->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR)) && + (!m_trueCaster->m_movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))) { // always cancel for channeled spells if (m_spellState == SPELL_STATE_CHANNELING) From e0453c036aa90cf2dd4f2c8caf098a5f6e68cb3c Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 15 Jan 2023 23:56:16 +0100 Subject: [PATCH 021/104] Ulduar: Leviathan Fixes --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 340 +++++++++++++++++- .../northrend/ulduar/ulduar/ulduar.cpp | 38 +- .../scripts/northrend/ulduar/ulduar/ulduar.h | 3 + 3 files changed, 367 insertions(+), 14 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 38130ef9c64..4f1ab268f3e 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -21,10 +21,10 @@ SDComment: Defense turret AI and related event NYI. SDCategory: Ulduar EndScriptData */ -#include "AI/ScriptDevAI/base/TimerAI.h" #include "AI/ScriptDevAI/include/sc_common.h" #include "ulduar.h" #include "AI/ScriptDevAI/base/BossAI.h" +#include "Entities/Vehicle.h" enum { @@ -75,7 +75,8 @@ enum // SPELL_SMOKE_TRAIL = 63575, // SPELL_EJECT_ALL_PASSENGERS = 50630, // used by vehicles on death; currently handled by DB linking // SPELL_EJECT_PASSENGER_4 = 64614, - // SPELL_EJECT_PASSENGER_1 = 60603, + SPELL_EJECT_PASSENGER_1 = 60603, + SPELL_PASSENGER_LOADED = 62340, // tower buffs to Leviathan (applied on combat start if the towers are alive) SPELL_TOWER_OF_FROST = 65077, @@ -105,7 +106,7 @@ enum // SPELL_BIRTH = 40031, // not used; purpose unk // vehicle accessories - NPC_LEVIATHAN_SEAT = 33114, + //NPC_LEVIATHAN_SEAT = 33114, NPC_LEVIATHAN_TURRET = 33139, NPC_DEFENSE_TURRET = 33142, NPC_OVERLOAD_DEVICE = 33143, @@ -162,6 +163,8 @@ static const float afHodirFury[MAX_HODIR_FURY][3] = static const float afMimironInferno[3] = {329.1809f, 8.02577f, 409.887f}; +static const std::vector addEntries = {NPC_LEVIATHAN_SEAT, NPC_LEVIATHAN_TURRET, NPC_DEFENSE_TURRET, NPC_OVERLOAD_DEVICE}; + /*###### ## boss_flame_leviathan ######*/ @@ -171,6 +174,7 @@ enum FlameLeviathanActions LEVIATHAN_FETCH_TOWERS, LEVIATHAN_HARDMODES, LEVIATHAN_THORIMS_HAMMER, + LEVIATHAN_RESET_OVERLOAD, LEVIATHAN_ACTIONS_MAX, }; @@ -184,7 +188,6 @@ struct boss_flame_leviathanAI : public BossAI AddOnAggroText(SAY_AGGRO); AddOnKillText(SAY_SLAY); AddOnDeathText(SAY_DEATH); - AddRespawnOnEvade(30s); AddCustomAction(LEVIATHAN_THORIMS_HAMMER, true, [&]() { DoSpawnThorimsHammer(); @@ -196,6 +199,15 @@ struct boss_flame_leviathanAI : public BossAI AddTimerlessCombatAction(LEVIATHAN_FETCH_TOWERS, true); AddCombatAction(LEVIATHAN_HARDMODES, 10s); Reset(); + m_creature->SetActiveObjectState(true); + AddCustomAction(LEVIATHAN_RESET_OVERLOAD, true, [&]() + { + Aura* aura = m_creature->GetAura(SPELL_OVERLOAD_CIRCUIT, EFFECT_INDEX_1); + if (!aura) + return; + if (Unit* caster = aura->GetCaster()) + caster->InterruptNonMeleeSpells(true); + }); } instance_ulduar* m_instance; @@ -218,6 +230,16 @@ struct boss_flame_leviathanAI : public BossAI m_hardmodeStep = 0; m_thorimsHammerCount = 0; + + CreatureList leviAdds; + for (const uint32& entry : addEntries) + { + GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 50.f); + for (auto& add : leviAdds) + { + add->SetActiveObjectState(true); + } + } } void JustDied(Unit* /*killer*/) override @@ -241,19 +263,34 @@ struct boss_flame_leviathanAI : public BossAI } } + void Aggro(Unit* who) override + { + BossAI::Aggro(who); + SendAIEventAround(AI_EVENT_CUSTOM_EVENTAI_A, nullptr, 0, 20.f); + } + void EnterEvadeMode() override { - static const std::vector addEntries = {NPC_LEVIATHAN_SEAT, NPC_LEVIATHAN_TURRET, NPC_DEFENSE_TURRET, NPC_OVERLOAD_DEVICE}; + m_creature->CastSpell(m_creature, 50630, TRIGGERED_OLD_TRIGGERED); CreatureList leviAdds; for (const uint32& entry : addEntries) { GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 50.f); - for (auto& add : leviAdds) + for (auto add : leviAdds) { - add->ForcedDespawn(); + if (add) + add->ForcedDespawn(); } } + + if (m_instance) + { + // clear hard mode auras + if (Creature* orbital = m_instance->GetSingleCreatureFromStorage(NPC_ORBITAL_SUPPORT)) + orbital->RemoveAllAuras(); + } BossAI::EnterEvadeMode(); + m_creature->ForcedDespawn(3000); } void JustSummoned(Creature* summoned) override @@ -505,8 +542,8 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI return; // cast Hodir Fury on point reached and search for another target - if (Creature* pHodirFury = m_creature->GetMap()->GetCreature(m_hodirFuryGuid)) - pHodirFury->CastSpell(m_creature, SPELL_HODIR_FURY, TRIGGERED_OLD_TRIGGERED); + //if (Creature* pHodirFury = m_creature->GetMap()->GetCreature(m_hodirFuryGuid)) + m_creature->CastSpell(m_creature, SPELL_HODIR_FURY, TRIGGERED_OLD_TRIGGERED); m_uiTargetChaseTimer = 5000; } @@ -616,6 +653,89 @@ struct npc_mimiron_infernoAI : public Scripted_NoMovementAI } }; +struct npc_salvaged_demolisherAI : public CombatAI +{ + npc_salvaged_demolisherAI(Creature* creature) : CombatAI(creature, 0) + { + SetCombatMovement(false); + } + + void JustRespawned() override + { + CombatAI::JustRespawned(); + m_creature->SetMaxPower(POWER_ENERGY, 50); + m_creature->SetPower(POWER_ENERGY, 50); + if (!m_creature->IsVehicle()) + return; + Unit* mechanicSeat = m_creature->GetVehicleInfo()->GetPassenger(1); + if (!mechanicSeat) + return; + mechanicSeat->SetPowerType(POWER_ENERGY); + mechanicSeat->SetMaxPower(POWER_ENERGY, 50); + mechanicSeat->SetPower(POWER_ENERGY, 50); + } +}; + +enum DefenseTurretActions +{ + DEFENSE_TURRET_RANGE_CHECK, + DEFENSE_TURRET_ACTIONS_MAX, +}; + +struct npc_leviathan_defense_turretAI : public CombatAI +{ + npc_leviathan_defense_turretAI(Creature* creature) : CombatAI(creature, DEFENSE_TURRET_ACTIONS_MAX) + { + SetCombatMovement(false); + AddCombatAction(DEFENSE_TURRET_RANGE_CHECK, 1s); + } + + void JustDied(Unit* killer) override + { + uint8 seatId = m_creature->GetTransSeat(); + TransportInfo* transportInfo = m_creature->GetTransportInfo(); + if (!transportInfo) + return; + Unit* leviSeat = static_cast(transportInfo->GetTransport()); + if (!leviSeat || !leviSeat->IsVehicle()) + return; + Unit* overloadDevice = leviSeat->GetVehicleInfo()->GetPassenger(seatId == 1 ? 2 : 1); + if (!overloadDevice) + return; + overloadDevice->CastSpell(nullptr, SPELL_OVERLOAD_CIRCUIT, TRIGGERED_OLD_TRIGGERED); + m_creature->ForcedDespawn(1000); + } + + void ExecuteAction(uint32 action) override + { + if (action == DEFENSE_TURRET_RANGE_CHECK) + { + float newHealthVal = m_creature->GetHealthPercent() + 1.f; + if (!m_creature->GetVictim()) + m_creature->SetHealthPercent(std::min(newHealthVal, 100.f)); + m_creature->RemoveUnattackableTargets(); + ResetCombatAction(DEFENSE_TURRET_RANGE_CHECK, 1s); + } + } +}; + +bool NpcSpellClick_npc_salvaged_demolisher(Player* player, Creature* clickedCreature, uint32 spellId) +{ + if (!clickedCreature || clickedCreature->GetEntry() != NPC_SALVAGED_DEMOLISHER) + return false; + VehicleInfo* vehicleInfo = clickedCreature->GetVehicleInfo(); + if (!vehicleInfo) + return false; + if (vehicleInfo->CanBoard(player)) + { + player->CastSpell(clickedCreature, 62309, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG); + return true; + } + int32 newSeat = 0; + player->CastCustomSpell(clickedCreature, 62309, &newSeat, nullptr, nullptr, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG); + return true; +} + struct PursueLeviathan : public SpellScript { void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const override @@ -659,6 +779,8 @@ struct HodirsFuryLeviathan : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override { + if (!target) + return true; Unit* caster = spell->GetCaster(); if (!caster) return false; @@ -675,6 +797,8 @@ struct ThorimsHammerLeviathan : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override { + if (!target) + return true; Unit* caster = spell->GetCaster(); if (!caster) return false; @@ -691,6 +815,8 @@ struct MimironsInfernoLeviathan : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override { + if (!target) + return true; Unit* caster = spell->GetCaster(); if (!caster) return false; @@ -702,6 +828,184 @@ struct MimironsInfernoLeviathan : public SpellScript } }; +struct LoadIntoCatapultLeviathan : public AuraScript +{ + void OnApply(Aura* aura, bool apply) const override + { + Unit* target = aura->GetTarget(); + if (!target) + return; + if (apply) + { + target->CastSpell(nullptr, SPELL_PASSENGER_LOADED, TRIGGERED_OLD_TRIGGERED); + return; + } + target->RemoveAurasDueToSpell(SPELL_PASSENGER_LOADED); + aura->GetCaster()->RemoveAurasDueToSpell(SPELL_PASSENGER_LOADED); + } +}; + +// 62324 Throw Passenger. May also apply to 47792 +struct ThrowPassenger : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex /*effIdx*/) const override + { + Unit* caster = spell->GetCaster(); + if (!caster) + return; + auto& targetList = spell->GetTargetList(); + Unit* projectile = nullptr; + Unit* seat = nullptr; + + if (caster->GetVehicleInfo()) + if (caster->GetVehicleInfo()->GetPassenger(3)) + if (Unit* seat = static_cast(caster->GetVehicleInfo()->GetPassenger(3))) + if (seat->IsVehicle()) + projectile = seat->GetVehicleInfo()->GetPassenger(0); + if (!projectile) + return; + + if (seat) + seat->GetVehicleInfo()->UnBoard(projectile, false); + projectile->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, projectile->GetObjectGuid()); + projectile->RemoveAurasDueToSpell(64414); + projectile->KnockBackWithAngle(projectile->GetAngle(spell->m_targets.m_destPos.x, spell->m_targets.m_destPos.y), spell->m_targets.getSpeed() * cos(spell->m_targets.getElevation()), spell->m_targets.getSpeed() * sin(spell->m_targets.getElevation())); + projectile->CastSpell(nullptr, 62336, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + } +}; + +struct HookshotAura : public AuraScript +{ + void OnPeriodicDummy(Aura* aura) const override + { + if (aura->GetEffIndex() != EFFECT_INDEX_0) + return; + Unit* caster = aura->GetCaster(); + if (!caster) + return; + caster->CastSpell(nullptr, aura->GetBasePoints(), TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + if (aura->GetAuraTicks() < 6) + return; + caster->RemoveAurasByCasterSpell(62336, caster->GetObjectGuid()); + } +}; + +struct Hookshot : public SpellScript +{ + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override + { + if (eff != EFFECT_INDEX_0) + return true; + Unit* caster = spell->GetCaster(); + if (!caster || !target) + return true; + if (caster->GetPosition().GetDistance(target->GetPosition()) > 30.f * 30.f) + return false; + caster->RemoveAurasByCasterSpell(62336, caster->GetObjectGuid()); + return true; + } +}; + +struct OverloadCircuit : public AuraScript +{ + void OnApply(Aura* aura, bool apply) const override + { + if (!apply) + return; + Unit* target = aura->GetTarget(); + if (!target) + return; + if (target->GetEntry() != NPC_LEVIATHAN) + return; + Unit* caster = aura->GetCaster(); + if (!caster) + return; + bool isRegularMode = target->GetMap()->IsRegularDifficulty(); + if (target->GetAuraCount(62399) >= 2 && isRegularMode) + { + target->CastSpell(nullptr, SPELL_SYSTEMS_SHUTDOWN, TRIGGERED_OLD_TRIGGERED); + } + else if (target->GetAuraCount(62399) >= 4) + { + target->CastSpell(nullptr, SPELL_SYSTEMS_SHUTDOWN, TRIGGERED_OLD_TRIGGERED); + } + } +}; + +struct SystemsShutdown : public AuraScript +{ + void OnApply(Aura* aura, bool apply) const override + { + Unit* target = aura->GetTarget(); + if (!target) + return; + if (apply) + { + target->SetStunned(true); + if (target->AI()) + target->AI()->SetCombatScriptStatus(true); + if (target->GetEntry() == NPC_LEVIATHAN_SEAT) + target->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1, TRIGGERED_OLD_TRIGGERED); + } + else + { + target->SetStunned(false); + if (target->AI()) + target->AI()->SetCombatScriptStatus(false); + } + + if (target->GetEntry() != NPC_LEVIATHAN) + return; + if (apply) + { + CreatureList leviAdds; + for (const uint32& entry : addEntries) + { + GetCreatureListWithEntryInGrid(leviAdds, target, entry, 50.f); + for (auto add : leviAdds) + { + if (add) + { + add->CastSpell(nullptr, SPELL_SYSTEMS_SHUTDOWN, TRIGGERED_OLD_TRIGGERED); + add->SetTarget(nullptr); + } + } + } + target->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED); + return; + } + CreatureList leviSeats; + GetCreatureListWithEntryInGrid(leviSeats, target, NPC_LEVIATHAN_SEAT, 50.f); + for (auto seat : leviSeats) + { + if (seat && seat->IsVehicle()) + { + seat->GetVehicleInfo()->RepopulateSeat(1); + } + } + } +}; + +struct EjectPassenger1 : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex /*effIdx*/) const override + { + Unit* target = spell->GetUnitTarget(); + if (!target || !target->IsVehicle()) + return; + VehicleInfo* vInfo = target->GetVehicleInfo(); + if (!vInfo) + return; + Unit* passenger = vInfo->GetPassenger(spell->m_currentBasePoints[0]); + if (!passenger) + return; + vInfo->UnBoard(passenger, false); + passenger->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); + passenger->RemoveSpellsCausingAura(SPELL_AURA_FACTION_OVERRIDE); + passenger->CastSpell(passenger, 61243, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -729,8 +1033,26 @@ void AddSC_boss_flame_leviathan() pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "npc_salvaged_demolisher"; + pNewScript->GetAI = &GetNewAIInstance; + pNewScript->pNpcSpellClick = &NpcSpellClick_npc_salvaged_demolisher; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_leviathan_defense_turret"; + pNewScript->GetAI = &GetNewAIInstance; + pNewScript->RegisterSelf(); + RegisterSpellScript("spell_pursue_leviathan"); RegisterSpellScript("spell_hodirs_fury_leviathan"); RegisterSpellScript("spell_thorims_hammer_leviathan"); RegisterSpellScript("spell_mimirons_inferno_leviathan"); + RegisterSpellScript("spell_load_into_catapult_leviathan"); + RegisterSpellScript("spell_throw_passenger"); + RegisterSpellScript("spell_hookshot_aura"); + RegisterSpellScript("spell_hookshot"); + RegisterSpellScript("spell_overload_circuit"); + RegisterSpellScript("spell_systems_shutdown"); + RegisterSpellScript("spell_eject_passenger_1"); } diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index d34fd817692..fffc0c13663 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -298,7 +298,9 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) else m_vaporVezaxBunnyGuid = pCreature->GetObjectGuid(); return; - + case NPC_LEVIATHAN_SEAT: + m_leviathanSeatGuids.insert(pCreature->GetObjectGuid()); + return; default: return; } @@ -520,16 +522,14 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) { case IN_PROGRESS: { - sLog.outError("Close the door!"); - if (door->GetGoState() != GO_STATE_READY) + //if (door->GetGoState() != GO_STATE_READY) door->SetGoState(GO_STATE_READY); break; } case DONE: case FAIL: { - sLog.outError("Open the door!"); - if (door->GetGoState() == GO_STATE_READY) + //if (door->GetGoState() == GO_STATE_READY) door->SetGoState(GO_STATE_ACTIVE); break; } @@ -1364,6 +1364,9 @@ void instance_ulduar::OnCreatureDeath(Creature* pCreature) SetData(TYPE_FREYA_CONSPEEDATORY, DONE); } break; + case NPC_LEVIATHAN_SEAT: + m_leviathanSeatGuids.erase(pCreature->GetObjectGuid()); + break; } } @@ -1735,6 +1738,26 @@ void instance_ulduar::Update(uint32 uiDiff) } } +bool AreaTrigger_repair_station(Player* player, AreaTriggerEntry const* at) +{ + switch (at->id) + { + case AREATRIGGER_ID_REPAIR_1: + case AREATRIGGER_ID_REPAIR_2: + { + const Creature* vehicle = dynamic_cast(player->FindRootVehicle()); + Creature* vehiclePtr = const_cast(vehicle); + if (!vehiclePtr) + return false; + if (!vehiclePtr->HasAura(62705)) + player->CastSpell(vehiclePtr, 62705, TRIGGERED_NONE); + return false; + } + default: + return false; + } +} + InstanceData* GetInstanceData_instance_ulduar(Map* pMap) { return new instance_ulduar(pMap); @@ -1790,4 +1813,9 @@ void AddSC_instance_ulduar() pNewScript->Name = "event_ulduar"; pNewScript->pProcessEventId = &ProcessEventId_event_ulduar; pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "at_ulduar"; + pNewScript->pAreaTrigger = &AreaTrigger_repair_station; + pNewScript->RegisterSelf(); } diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h index 9f2245e8a0b..8da83fd9016 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h @@ -79,6 +79,7 @@ enum NPC_ORBITAL_SUPPORT = 34286, // NPC_GENERATOR = 33571, // spawns iron dwarfs from Storm Beacons NPC_GENERATOR_SMALL = 34159, // spawns iron dwarfs from hard mode towers + NPC_LEVIATHAN_SEAT = 33114, // Leviathan reinforcements // NPC_HIRED_ENGINEER = 33626, @@ -624,6 +625,7 @@ class instance_ulduar : public ScriptedInstance, private DialogueHelper void GetThunderOrbsGuids(GuidList& lOrbs) const { lOrbs = m_lUpperThunderOrbsGuids; } void GetSmashTargetsGuids(GuidList& lTargets, bool bLeft) { lTargets = bLeft ? m_lLeftHandBunniesGuids : m_lRightHandBunniesGuids; } void GetOminousCloudGuids(GuidList& lClouds) const { lClouds = m_lOminousCloudsGuids; } + void GetLeviathanSeatGuids(GuidSet& seats) const { seats = m_leviathanSeatGuids; } // Function that will trigger the tram turnaround object, based on the tram location void SetTramRotateTimer() { m_uiTramRotateTimer = m_bTramAtCenter ? 33000 : 30000; } @@ -676,6 +678,7 @@ class instance_ulduar : public ScriptedInstance, private DialogueHelper GuidList m_lRightHandBunniesGuids; GuidList m_lOminousCloudsGuids; GuidSet m_sColossusGuidSet; + GuidSet m_leviathanSeatGuids; }; #endif From b05350a0c973728ed43f1b93737e96be36f512bf Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 15 Jan 2023 23:56:41 +0100 Subject: [PATCH 022/104] BossAI: Minor execution order fix --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index 4ee4a016685..b2934f60ebc 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -107,7 +107,7 @@ void BossAI::EnterEvadeMode() return; } m_creature->SetRespawnDelay(m_respawnDelay, true); - m_creature->ForcedDespawn(); + m_creature->ForcedDespawn(2000); for (ObjectGuid& guid : m_despawnSubordinateOnEvade) { Creature* addToDespawn = m_creature->GetMap()->GetCreature(guid); @@ -116,10 +116,6 @@ void BossAI::EnterEvadeMode() addToDespawn->SetRespawnDelay(m_respawnDelay); addToDespawn->ForcedDespawn(); } - if (m_instanceDataType == -1) - return; - if (ScriptedInstance* instance = static_cast(m_creature->GetInstanceData())) - instance->SetData(m_instanceDataType, FAIL); } void BossAI::AddCastOnDeath(QueuedCast cast) From 7ebd046235da2c07c42583488dc535ad94fe17a4 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 16 Jan 2023 19:21:38 +0100 Subject: [PATCH 023/104] Ulduar: Add Smoke Trail spellscript --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 4f1ab268f3e..8c6096789e1 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -72,7 +72,7 @@ enum // Leviathan seat has missing aura 62421 // leviathan other spells - for the moment these are not used - // SPELL_SMOKE_TRAIL = 63575, + SPELL_SMOKE_TRAIL = 63575, // SPELL_EJECT_ALL_PASSENGERS = 50630, // used by vehicles on death; currently handled by DB linking // SPELL_EJECT_PASSENGER_4 = 64614, SPELL_EJECT_PASSENGER_1 = 60603, @@ -1002,7 +1002,23 @@ struct EjectPassenger1 : public SpellScript vInfo->UnBoard(passenger, false); passenger->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); passenger->RemoveSpellsCausingAura(SPELL_AURA_FACTION_OVERRIDE); - passenger->CastSpell(passenger, 61243, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + target->CastSpell(passenger, SPELL_SMOKE_TRAIL, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + } +}; + +struct SmokeTrailLeviathan : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const + { + if (effIdx != EFFECT_INDEX_0) + return; + Unit* target = spell->GetUnitTarget(); + if (!target || !target->IsPlayer()) + return; + Unit* caster = spell->GetCaster(); + if (!caster || !caster->IsVehicle()) + return; + target->KnockBackFrom(caster, 5.f, 25.f); } }; @@ -1055,4 +1071,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_overload_circuit"); RegisterSpellScript("spell_systems_shutdown"); RegisterSpellScript("spell_eject_passenger_1"); + RegisterSpellScript("spell_smoke_trail_leviathan"); } From 861d3d2410ce09e1bcb510d147827e4fa70bdb1e Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 16 Jan 2023 19:22:00 +0100 Subject: [PATCH 024/104] Ulduar: Ensure SpellClick is active during Leviathan encounter --- .../AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index fffc0c13663..e1916e21868 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -1113,7 +1113,7 @@ bool instance_ulduar::CheckConditionCriteriaMeet(Player const* pPlayer, uint32 u break; // handle vehicle spell clicks - are available only after the gauntlet was started by gossip or when Leviathan is active - return GetData(TYPE_LEVIATHAN_GAUNTLET) == IN_PROGRESS || GetData(TYPE_LEVIATHAN) == SPECIAL || GetData(TYPE_LEVIATHAN) == FAIL; + return GetData(TYPE_LEVIATHAN_GAUNTLET) == IN_PROGRESS || GetData(TYPE_LEVIATHAN) == SPECIAL || GetData(TYPE_LEVIATHAN) == FAIL || GetData(TYPE_LEVIATHAN) == IN_PROGRESS; } } From 7295fb753aa89447a043d38ff01a8b73f3ae6dde Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 16 Jan 2023 19:52:07 +0100 Subject: [PATCH 025/104] Ulduar: Add Spellscript for Parachute --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 8c6096789e1..e2af336e852 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1022,6 +1022,20 @@ struct SmokeTrailLeviathan : public SpellScript } }; +struct ParachuteLeviathan : public AuraScript +{ + void OnPeriodicDummy(Aura* aura) const override + { + Unit* caster = aura->GetCaster(); + if (!caster) + return; + if (!caster->IsFalling()) + return;caster->RemoveAura(aura); + caster->RemoveAurasDueToSpell(aura->GetSpellProto()->Id); + caster->CastSpell(caster, aura->GetBasePoints(), TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1072,4 +1086,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_systems_shutdown"); RegisterSpellScript("spell_eject_passenger_1"); RegisterSpellScript("spell_smoke_trail_leviathan"); + RegisterSpellScript("spell_parachute_leviathan"); } From b87b748d358bb647d14a287320ab063fad3766cf Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 16 Jan 2023 22:39:23 +0100 Subject: [PATCH 026/104] Ulduar: Remove incorrect line, add comment --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index e2af336e852..95111973913 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1002,7 +1002,7 @@ struct EjectPassenger1 : public SpellScript vInfo->UnBoard(passenger, false); passenger->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); passenger->RemoveSpellsCausingAura(SPELL_AURA_FACTION_OVERRIDE); - target->CastSpell(passenger, SPELL_SMOKE_TRAIL, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + target->CastSpell(passenger, SPELL_SMOKE_TRAIL, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); // This may actually be a separate cast, not sure. } }; @@ -1030,7 +1030,7 @@ struct ParachuteLeviathan : public AuraScript if (!caster) return; if (!caster->IsFalling()) - return;caster->RemoveAura(aura); + return; caster->RemoveAurasDueToSpell(aura->GetSpellProto()->Id); caster->CastSpell(caster, aura->GetBasePoints(), TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); } From 797505bddd37cd620572fb8b8113450217ab7e45 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 16 Jan 2023 22:43:58 +0100 Subject: [PATCH 027/104] Ulduar: Unmagic some magic numbers --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 95111973913..da2478b8c89 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -76,7 +76,10 @@ enum // SPELL_EJECT_ALL_PASSENGERS = 50630, // used by vehicles on death; currently handled by DB linking // SPELL_EJECT_PASSENGER_4 = 64614, SPELL_EJECT_PASSENGER_1 = 60603, + SPELL_LOAD_INTO_CATAPULT = 64414, SPELL_PASSENGER_LOADED = 62340, + SPELL_HOOKSHOT_AURA = 62336, + SPELL_RIDE_VEHICLE_SCALES_WITH_GEAR = 62309, // tower buffs to Leviathan (applied on combat start if the towers are alive) SPELL_TOWER_OF_FROST = 65077, @@ -728,11 +731,11 @@ bool NpcSpellClick_npc_salvaged_demolisher(Player* player, Creature* clickedCrea return false; if (vehicleInfo->CanBoard(player)) { - player->CastSpell(clickedCreature, 62309, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG); + player->CastSpell(clickedCreature, SPELL_RIDE_VEHICLE_SCALES_WITH_GEAR, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG); return true; } int32 newSeat = 0; - player->CastCustomSpell(clickedCreature, 62309, &newSeat, nullptr, nullptr, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG); + player->CastCustomSpell(clickedCreature, SPELL_RIDE_VEHICLE_SCALES_WITH_GEAR, &newSeat, nullptr, nullptr, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG); return true; } @@ -868,9 +871,9 @@ struct ThrowPassenger : public SpellScript if (seat) seat->GetVehicleInfo()->UnBoard(projectile, false); projectile->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, projectile->GetObjectGuid()); - projectile->RemoveAurasDueToSpell(64414); + projectile->RemoveAurasDueToSpell(SPELL_LOAD_INTO_CATAPULT); projectile->KnockBackWithAngle(projectile->GetAngle(spell->m_targets.m_destPos.x, spell->m_targets.m_destPos.y), spell->m_targets.getSpeed() * cos(spell->m_targets.getElevation()), spell->m_targets.getSpeed() * sin(spell->m_targets.getElevation())); - projectile->CastSpell(nullptr, 62336, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); + projectile->CastSpell(nullptr, SPELL_HOOKSHOT_AURA, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); } }; @@ -886,7 +889,7 @@ struct HookshotAura : public AuraScript caster->CastSpell(nullptr, aura->GetBasePoints(), TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); if (aura->GetAuraTicks() < 6) return; - caster->RemoveAurasByCasterSpell(62336, caster->GetObjectGuid()); + caster->RemoveAurasByCasterSpell(SPELL_HOOKSHOT_AURA, caster->GetObjectGuid()); } }; @@ -901,7 +904,7 @@ struct Hookshot : public SpellScript return true; if (caster->GetPosition().GetDistance(target->GetPosition()) > 30.f * 30.f) return false; - caster->RemoveAurasByCasterSpell(62336, caster->GetObjectGuid()); + caster->RemoveAurasByCasterSpell(SPELL_HOOKSHOT_AURA, caster->GetObjectGuid()); return true; } }; @@ -921,11 +924,11 @@ struct OverloadCircuit : public AuraScript if (!caster) return; bool isRegularMode = target->GetMap()->IsRegularDifficulty(); - if (target->GetAuraCount(62399) >= 2 && isRegularMode) + if (target->GetAuraCount(SPELL_OVERLOAD_CIRCUIT) >= 2 && isRegularMode) { target->CastSpell(nullptr, SPELL_SYSTEMS_SHUTDOWN, TRIGGERED_OLD_TRIGGERED); } - else if (target->GetAuraCount(62399) >= 4) + else if (target->GetAuraCount(SPELL_OVERLOAD_CIRCUIT) >= 4) { target->CastSpell(nullptr, SPELL_SYSTEMS_SHUTDOWN, TRIGGERED_OLD_TRIGGERED); } From a9137aa16e1312dea6a429b6ff6ff03d09543f7e Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 28 Jan 2023 15:44:03 +0100 Subject: [PATCH 028/104] Ulduar: Fix targeting reticle npc issues --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index da2478b8c89..65b72a97bbf 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -105,8 +105,8 @@ enum // SPELL_TARGET_SEARCH_B = 63762, // moves the caster to the target location // SPELL_TARGET_SEARCH_C = 63763, // these are not used since we are doing this by waypoint movement // SPELL_TARGET_SEARCH_D = 63764, - // SPELL_BEAM_TARGET_STATE = 62898, // cast by all tower reticles; purpose unk - // SPELL_BIRTH = 40031, // not used; purpose unk + SPELL_BEAM_TARGET_STATE = 62898, // cast by all tower reticles; purpose unk + SPELL_BIRTH = 40031, // not used; purpose unk // vehicle accessories //NPC_LEVIATHAN_SEAT = 33114, @@ -126,6 +126,10 @@ enum NPC_HODIR_FURY_VEHICLE = 33108, // has accessory 33212 NPC_FREYA_WARD_VEHICLE = 33366, // has accessory 33367 + /* +UPDATE vehicle_accessory SET seat=0 WHERE vehicle_entry IN (33364, 33369, 33108, 33366); + */ + // freya's ward summons - handled by eventAI NPC_WRITHING_LASHER = 33387, // both spam spell 65062 on target NPC_WARD_OF_LIFE = 34275, @@ -302,15 +306,23 @@ struct boss_flame_leviathanAI : public BossAI switch (summoned->GetEntry()) { case NPC_THORIM_HAMMER_VEHICLE: + summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_LIGHTNING_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; case NPC_MIMIRON_INFERNO_VEHICLE: + summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_RED_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; case NPC_HODIR_FURY_VEHICLE: + summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BLUE_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; case NPC_FREYA_WARD_VEHICLE: + summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_GREEN_SKYBEAM, TRIGGERED_OLD_TRIGGERED); break; } @@ -648,8 +660,8 @@ struct npc_mimiron_infernoAI : public Scripted_NoMovementAI { if (m_uiMimironInfernoTimer < diff) { - if (DoCastSpellIfCan(m_creature, SPELL_MIMIRON_INFERNO) == CAST_OK) - m_uiMimironInfernoTimer = 1000; + if (DoCastSpellIfCan(nullptr, SPELL_MIMIRON_INFERNO) == CAST_OK) + m_uiMimironInfernoTimer = 2000; } else m_uiMimironInfernoTimer -= diff; From 9cb4edd2a25c9016163376269dfffc0891fcb4bb Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 30 Jan 2023 18:21:41 +0100 Subject: [PATCH 029/104] Ulduar: Minor Leviathan fixes --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 65b72a97bbf..5008689fc89 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -558,7 +558,10 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI // cast Hodir Fury on point reached and search for another target //if (Creature* pHodirFury = m_creature->GetMap()->GetCreature(m_hodirFuryGuid)) - m_creature->CastSpell(m_creature, SPELL_HODIR_FURY, TRIGGERED_OLD_TRIGGERED); + if (m_creature->IsVehicle() && m_creature->GetVehicleInfo()) + if (Unit* hodirsFuryCaster = m_creature->GetVehicleInfo()->GetPassenger(0)) + hodirsFuryCaster->CastSpell(m_creature, SPELL_HODIR_FURY, TRIGGERED_IGNORE_CASTER_AURA_STATE); + //m_creature->CastSpell(m_creature, SPELL_HODIR_FURY, TRIGGERED_OLD_TRIGGERED); m_uiTargetChaseTimer = 5000; } @@ -661,7 +664,7 @@ struct npc_mimiron_infernoAI : public Scripted_NoMovementAI if (m_uiMimironInfernoTimer < diff) { if (DoCastSpellIfCan(nullptr, SPELL_MIMIRON_INFERNO) == CAST_OK) - m_uiMimironInfernoTimer = 2000; + m_uiMimironInfernoTimer = 3000; } else m_uiMimironInfernoTimer -= diff; From 7978b49935508ba6ee4c0a75119438cd50075d4c Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 5 Feb 2023 11:31:56 +0100 Subject: [PATCH 030/104] Ulduar: Fix demolisher energy-sync & Targetting issues --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 5008689fc89..9b0cd180aac 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -671,10 +671,29 @@ struct npc_mimiron_infernoAI : public Scripted_NoMovementAI } }; +enum DemolisherActions +{ + DEMOLISHER_ACTIONS_MAX, + DEMOLISHER_SYNC_ENERGY, +}; + struct npc_salvaged_demolisherAI : public CombatAI { - npc_salvaged_demolisherAI(Creature* creature) : CombatAI(creature, 0) + npc_salvaged_demolisherAI(Creature* creature) : CombatAI(creature, DEMOLISHER_ACTIONS_MAX) { + AddCustomAction(DEMOLISHER_SYNC_ENERGY, 1s, [&]() + { + if (!m_creature->IsAlive()) + return; + ResetTimer(DEMOLISHER_SYNC_ENERGY, 1s); + if (m_creature->GetVehicleInfo()->GetPassenger(0)) + { + Unit* mechanicSeat = m_creature->GetVehicleInfo()->GetPassenger(1); + if (!mechanicSeat) + return; + m_creature->SetPower(POWER_ENERGY, mechanicSeat->GetPower(POWER_ENERGY)); + } + }); SetCombatMovement(false); } @@ -731,7 +750,9 @@ struct npc_leviathan_defense_turretAI : public CombatAI float newHealthVal = m_creature->GetHealthPercent() + 1.f; if (!m_creature->GetVictim()) m_creature->SetHealthPercent(std::min(newHealthVal, 100.f)); - m_creature->RemoveUnattackableTargets(); + for (auto& attacker : m_creature->getAttackers()) + if (attacker->GetDistance(m_creature, true) >= (20.f * 20.f)) + m_creature->getThreatManager().modifyThreatPercent(attacker, -101); ResetCombatAction(DEFENSE_TURRET_RANGE_CHECK, 1s); } } @@ -756,6 +777,18 @@ bool NpcSpellClick_npc_salvaged_demolisher(Player* player, Creature* clickedCrea struct PursueLeviathan : public SpellScript { + bool OnCheckTarget(const Spell* /*spell*/, Unit* target, SpellEffectIndex /*eff*/) const override + { + if (!target) + return false; + if (!target->IsVehicle()) + return false; + if (auto vehicleInfo = target->GetVehicleInfo()) + if (vehicleInfo->GetPassenger(0)) + return true; + return false; + } + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const override { if (effIdx != EFFECT_INDEX_0) @@ -922,6 +955,22 @@ struct Hookshot : public SpellScript caster->RemoveAurasByCasterSpell(SPELL_HOOKSHOT_AURA, caster->GetObjectGuid()); return true; } + + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const override + { + if (effIdx != EFFECT_INDEX_0) + return; + Unit* target = spell->GetUnitTarget(); + if (!target) + return; + + CreatureList turrets; + GetCreatureListWithEntryInGrid(turrets, target, NPC_DEFENSE_TURRET, 10.f); + for (auto& turret : turrets) + { + turret->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); + } + } }; struct OverloadCircuit : public AuraScript From fd17676deb2eccddbbbcaba1467b0786d69fa822 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 5 Feb 2023 11:48:23 +0100 Subject: [PATCH 031/104] Ulduar: Flip seat Power sync --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 9b0cd180aac..327f0f5a4fa 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -691,7 +691,7 @@ struct npc_salvaged_demolisherAI : public CombatAI Unit* mechanicSeat = m_creature->GetVehicleInfo()->GetPassenger(1); if (!mechanicSeat) return; - m_creature->SetPower(POWER_ENERGY, mechanicSeat->GetPower(POWER_ENERGY)); + mechanicSeat->SetPower(POWER_ENERGY, m_creature->GetPower(POWER_ENERGY)); } }); SetCombatMovement(false); From 9575c508df67f4f42b37aad205261b09ef1d510e Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 5 Feb 2023 18:39:15 +0100 Subject: [PATCH 032/104] Ulduar: Minor Leviathan fixes --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 19 +++++++++++++++++++ src/game/Movement/MoveSplineFlag.h | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 327f0f5a4fa..f68da6ec449 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -691,6 +691,7 @@ struct npc_salvaged_demolisherAI : public CombatAI Unit* mechanicSeat = m_creature->GetVehicleInfo()->GetPassenger(1); if (!mechanicSeat) return; + mechanicSeat->SetMaxPower(POWER_ENERGY, 50); mechanicSeat->SetPower(POWER_ENERGY, m_creature->GetPower(POWER_ENERGY)); } }); @@ -1103,6 +1104,23 @@ struct ParachuteLeviathan : public AuraScript } }; +struct GrabPyrite : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex /*effIdx*/) const + { + Unit* caster = spell->GetCaster(); + Unit* target = spell->GetUnitTarget(); + if (!caster || !target) + return; + if (auto transportInfo = caster->GetTransportInfo()) + if (auto vehicle = static_cast(transportInfo->GetTransport())) + { + target->CastSpell(vehicle, spell->m_currentBasePoints[0], TRIGGERED_OLD_TRIGGERED); + target->CastSpell(vehicle, 62473, TRIGGERED_OLD_TRIGGERED | TRIGGERED_IGNORE_CASTER_AURA_STATE); + } + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1154,4 +1172,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_eject_passenger_1"); RegisterSpellScript("spell_smoke_trail_leviathan"); RegisterSpellScript("spell_parachute_leviathan"); + RegisterSpellScript("spell_grab_crate_leviathan"); } diff --git a/src/game/Movement/MoveSplineFlag.h b/src/game/Movement/MoveSplineFlag.h index 1c47f7c51e6..7acf7226774 100644 --- a/src/game/Movement/MoveSplineFlag.h +++ b/src/game/Movement/MoveSplineFlag.h @@ -100,12 +100,12 @@ namespace Movement void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic)) | Animation | anim;} void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Parabolic;} void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling;} - void EnableFlying() { raw() = (raw() & ~Catmullrom) | Flying; } + void EnableFlying() { raw() = (raw() & ~(Catmullrom | Falling)) | Flying; } void EnableCatmullRom() { raw() = (raw() & ~Flying) | Catmullrom; } void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point;} void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle;} void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target;} - void EnableBoardVehicle() { raw() = (raw() & ~(Catmullrom | ExitVehicle)) | BoardVehicle; } + void EnableBoardVehicle() { raw() = (raw() & ~ExitVehicle) | BoardVehicle; } void EnableExitVehicle() { raw() = (raw() & ~BoardVehicle) | ExitVehicle; } uint8 animId : 8; From 682d3756280b14b8478e2c36b25e08a378f37b4b Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 10 Feb 2023 11:21:12 +0100 Subject: [PATCH 033/104] Fix Hodir's Fury Reticle --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index f68da6ec449..d06ad80fa15 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -543,7 +543,17 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI } void AttackStart(Unit* /*who*/) override { } - void MoveInLineOfSight(Unit* /*who*/) override { } + void MoveInLineOfSight(Unit* who) override + { + if (m_creature->IsFriend(who)) + return; + if (who->GetDistance2d(m_creature->GetPositionX(), m_creature->GetPositionY()) <= 3.f) + { + m_creature->StopMoving(); + m_uiTargetChaseTimer = 0; + MovementInform(POINT_MOTION_TYPE, 1); + } + } void JustSummoned(Creature* summoned) override { @@ -752,7 +762,7 @@ struct npc_leviathan_defense_turretAI : public CombatAI if (!m_creature->GetVictim()) m_creature->SetHealthPercent(std::min(newHealthVal, 100.f)); for (auto& attacker : m_creature->getAttackers()) - if (attacker->GetDistance(m_creature, true) >= (20.f * 20.f)) + if (attacker->GetDistance(m_creature, true) >= (20.f * 20.f) || m_creature->IsFriend(attacker)) m_creature->getThreatManager().modifyThreatPercent(attacker, -101); ResetCombatAction(DEFENSE_TURRET_RANGE_CHECK, 1s); } From 3184b3f8b3f86136c021efe64dcb4b0bb9cdd6f6 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 20:08:30 +0100 Subject: [PATCH 034/104] Ulduar: Add Leashing to Flame Leviathan --- sql/scriptdev2/spell.sql | 1 + .../ulduar/ulduar/boss_flame_leviathan.cpp | 24 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index 78a97024413..c4d4f9e4428 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -971,6 +971,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (62717,'spell_slag_pot'), (63474,'spell_ignis_scorch'), (63482,'spell_lightning_whirl_heroic'), +(63618,'spell_overload_leviathan'), (63845,'spell_create_lance'), (64203,'spell_void_zone_xt'), (64209,'spell_consumption_xt'), diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index d06ad80fa15..112a61f2cd1 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -22,6 +22,7 @@ SDCategory: Ulduar EndScriptData */ #include "AI/ScriptDevAI/include/sc_common.h" +#include "Spells/Scripts/SpellScript.h" #include "ulduar.h" #include "AI/ScriptDevAI/base/BossAI.h" #include "Entities/Vehicle.h" @@ -71,15 +72,16 @@ enum SPELL_SYSTEMS_SHUTDOWN = 62475, // sends event 21605 for achiev check // Leviathan seat has missing aura 62421 - // leviathan other spells - for the moment these are not used + // leviathan other spells SPELL_SMOKE_TRAIL = 63575, - // SPELL_EJECT_ALL_PASSENGERS = 50630, // used by vehicles on death; currently handled by DB linking + SPELL_EJECT_ALL_PASSENGERS = 50630, // used by vehicles on death; currently handled by DB linking // SPELL_EJECT_PASSENGER_4 = 64614, SPELL_EJECT_PASSENGER_1 = 60603, SPELL_LOAD_INTO_CATAPULT = 64414, SPELL_PASSENGER_LOADED = 62340, SPELL_HOOKSHOT_AURA = 62336, SPELL_RIDE_VEHICLE_SCALES_WITH_GEAR = 62309, + SPELL_OVERLOAD = 63618, // tower buffs to Leviathan (applied on combat start if the towers are alive) SPELL_TOWER_OF_FROST = 65077, @@ -215,6 +217,10 @@ struct boss_flame_leviathanAI : public BossAI if (Unit* caster = aura->GetCaster()) caster->InterruptNonMeleeSpells(true); }); + m_creature->GetCombatManager().SetLeashingCheck([&](Unit*, float x, float, float) + { + return x < 148; + }); } instance_ulduar* m_instance; @@ -278,7 +284,8 @@ struct boss_flame_leviathanAI : public BossAI void EnterEvadeMode() override { - m_creature->CastSpell(m_creature, 50630, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(m_creature, SPELL_EJECT_ALL_PASSENGERS, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(nullptr, SPELL_OVERLOAD, TRIGGERED_OLD_TRIGGERED); CreatureList leviAdds; for (const uint32& entry : addEntries) { @@ -1131,6 +1138,16 @@ struct GrabPyrite : public SpellScript } }; +struct OverloadLeviathan : public SpellScript +{ + bool OnCheckTarget(const Spell* /*spell*/, Unit* target, SpellEffectIndex /*eff*/) const override + { + if (target->IsVehicle()) + return true; + return false; + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1183,4 +1200,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_smoke_trail_leviathan"); RegisterSpellScript("spell_parachute_leviathan"); RegisterSpellScript("spell_grab_crate_leviathan"); + RegisterSpellScript("spell_overload_leviathan"); } From ac5d9c24645ba014f8072610f61d3f4946109838 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 20:14:05 +0100 Subject: [PATCH 035/104] Ulduar: fix spellscript for eject passenger 1 --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 112a61f2cd1..29e4d414d67 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1030,7 +1030,14 @@ struct SystemsShutdown : public AuraScript if (target->AI()) target->AI()->SetCombatScriptStatus(true); if (target->GetEntry() == NPC_LEVIATHAN_SEAT) + { + Unit* passenger; + if (target && target->IsVehicle()) + passenger = target->GetVehicleInfo()->GetPassenger(0); target->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1, TRIGGERED_OLD_TRIGGERED); + if (passenger) + target->CastSpell(passenger, SPELL_SMOKE_TRAIL, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); // This may actually be a separate cast, not sure. + } } else { @@ -1086,8 +1093,6 @@ struct EjectPassenger1 : public SpellScript return; vInfo->UnBoard(passenger, false); passenger->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); - passenger->RemoveSpellsCausingAura(SPELL_AURA_FACTION_OVERRIDE); - target->CastSpell(passenger, SPELL_SMOKE_TRAIL, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); // This may actually be a separate cast, not sure. } }; From c0872c130c290be542983089aa88a15cf46cbb91 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 20:52:09 +0100 Subject: [PATCH 036/104] Ulduar: Partially fix initial Leviathan Gossip --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 5 ++- .../northrend/ulduar/ulduar/ulduar.cpp | 38 +++---------------- .../scripts/northrend/ulduar/ulduar/ulduar.h | 1 + .../northrend/ulduar/ulduar/ulduarScripts.cpp | 12 ++++++ 4 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 29e4d414d67..4d8c9ae2658 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1145,9 +1145,10 @@ struct GrabPyrite : public SpellScript struct OverloadLeviathan : public SpellScript { - bool OnCheckTarget(const Spell* /*spell*/, Unit* target, SpellEffectIndex /*eff*/) const override + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override { - if (target->IsVehicle()) + Unit* caster = spell->GetAffectiveCaster(); + if (target->IsVehicle() && caster->IsEnemy(target)) return true; return false; } diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index e1916e21868..9396ecc7a11 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -180,6 +180,7 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) case NPC_LEVIATHAN: case NPC_EXPLORER_DELLORAH: case NPC_BRANN_BRONZEBEARD: + case NPC_PROJECTION_UNIT: case NPC_ORBITAL_SUPPORT: case NPC_IGNIS: case NPC_RAZORSCALE: @@ -514,45 +515,18 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) // Siege of Ulduar case TYPE_LEVIATHAN: m_auiEncounter[uiType] = uiData; - if (uiData != SPECIAL) - { - if (GameObject* door = GetSingleGameObjectFromStorage(GO_SHIELD_WALL)) - { - switch (uiData) - { - case IN_PROGRESS: - { - //if (door->GetGoState() != GO_STATE_READY) - door->SetGoState(GO_STATE_READY); - break; - } - case DONE: - case FAIL: - { - //if (door->GetGoState() == GO_STATE_READY) - door->SetGoState(GO_STATE_ACTIVE); - break; - } - - } - } - } if (uiData == IN_PROGRESS) { // make sure that the Lightning door is closed when engaged in combat - if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_LIGHTNING_DOOR)) - { - if (pDoor->GetGoState() != GO_STATE_READY) - pDoor->SetGoState(GO_STATE_READY); - //DoUseDoorOrButton(GO_LIGHTNING_DOOR); - } - + DoUseOpenableObject(GO_LIGHTNING_DOOR, false); + DoUseOpenableObject(GO_SHIELD_WALL, false); SetSpecialAchievementCriteria(TYPE_ACHIEV_SHUTOUT, true); } else if (uiData == DONE) { - DoUseDoorOrButton(GO_XT002_GATE); - DoUseDoorOrButton(GO_LIGHTNING_DOOR); + DoUseOpenableObject(GO_XT002_GATE, true); + DoUseOpenableObject(GO_LIGHTNING_DOOR, true); + DoUseOpenableObject(GO_SHIELD_WALL, true); } else if (uiData == FAIL) DoCallLeviathanHelp(); diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h index 8da83fd9016..caf28a9b710 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h @@ -76,6 +76,7 @@ enum NPC_BRONZEBEARD_RADIO = 34054, NPC_EXPLORER_DELLORAH = 33701, NPC_BRANN_BRONZEBEARD = 33579, + NPC_PROJECTION_UNIT = 33721, NPC_ORBITAL_SUPPORT = 34286, // NPC_GENERATOR = 33571, // spawns iron dwarfs from Storm Beacons NPC_GENERATOR_SMALL = 34159, // spawns iron dwarfs from hard mode towers diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduarScripts.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduarScripts.cpp index 4313b904ce7..efd8d157113 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduarScripts.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduarScripts.cpp @@ -223,6 +223,11 @@ bool GossipSelect_npc_brann_ulduar(Player* pPlayer, Creature* pCreature, uint32 // set gauntlet in progress; rest of the event is done by DB scripts pInstance->SetData(TYPE_LEVIATHAN_GAUNTLET, IN_PROGRESS); pCreature->GetMotionMaster()->MoveWaypoint(); + + for (auto& player : pCreature->GetMap()->GetPlayers()) + { + player.getSource()->UpdateEverything(); + } } pPlayer->CLOSE_GOSSIP_MENU(); @@ -283,6 +288,13 @@ bool GossipSelect_npc_keeper_norgannon(Player* pPlayer, Creature* pCreature, uin pDellorah->GetMotionMaster()->MoveWaypoint(); if (Creature* pBrann = pInstance->GetSingleCreatureFromStorage(NPC_BRANN_BRONZEBEARD)) pBrann->GetMotionMaster()->MoveWaypoint(); + if (Creature* pProjector = pInstance->GetSingleCreatureFromStorage(NPC_PROJECTION_UNIT)) + pProjector->GetMotionMaster()->MovePath(1); + + for (auto& player : pCreature->GetMap()->GetPlayers()) + { + player.getSource()->UpdateEverything(); + } } pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_ID_ACTIVATED, pCreature->GetObjectGuid()); From 07c40de29f4979e7196a1011f1c630a16ceced5d Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 21:38:51 +0100 Subject: [PATCH 037/104] Ulduar: Fix friendly fire by vehicles --- sql/scriptdev2/spell.sql | 1 + .../ulduar/ulduar/boss_flame_leviathan.cpp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index c4d4f9e4428..5b1166e26d5 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -983,6 +983,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (64475,'spell_ignis_remove_strength'), (64503,'spell_ignis_water'), (64568,'spell_blood_reserve_enchant'), +(65045,'spell_flames_leviathan'), (65121,'spell_searing_light'), (65667,'spell_ignis_heat'), (65869,'spell_disengage'), diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 4d8c9ae2658..e9c149f9b33 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1148,12 +1148,23 @@ struct OverloadLeviathan : public SpellScript bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override { Unit* caster = spell->GetAffectiveCaster(); - if (target->IsVehicle() && caster->IsEnemy(target)) + if (target && target->IsVehicle() && caster->IsEnemy(target)) return true; return false; } }; +struct FlamesLeviathan : public SpellScript +{ + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override + { + Unit* caster = spell->GetAffectiveCaster(); + if (target && caster->IsFriend(target)) + return false; + return true; + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1207,4 +1218,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_parachute_leviathan"); RegisterSpellScript("spell_grab_crate_leviathan"); RegisterSpellScript("spell_overload_leviathan"); + RegisterSpellScript("spell_flames_leviathan"); } From 4b06d0088d205c61640e918afcd439918c2a6891 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 21:39:06 +0100 Subject: [PATCH 038/104] Ulduar: Open Leviathan door on Fail --- .../AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index 9396ecc7a11..8a66e87bf46 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -529,7 +529,10 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) DoUseOpenableObject(GO_SHIELD_WALL, true); } else if (uiData == FAIL) + { + DoUseOpenableObject(GO_SHIELD_WALL, true); DoCallLeviathanHelp(); + } break; case TYPE_IGNIS: m_auiEncounter[uiType] = uiData; From b50278941e9f357d342b8e113bdb08a842272fc9 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 21:45:39 +0100 Subject: [PATCH 039/104] Ulduar: Make Thorim's Hammer repeatable --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index e9c149f9b33..e23c33ea226 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -197,16 +197,9 @@ struct boss_flame_leviathanAI : public BossAI AddOnAggroText(SAY_AGGRO); AddOnKillText(SAY_SLAY); AddOnDeathText(SAY_DEATH); - AddCustomAction(LEVIATHAN_THORIMS_HAMMER, true, [&]() - { - DoSpawnThorimsHammer(); - ++m_thorimsHammerCount; - - if (m_thorimsHammerCount < MAX_THORIM_HAMMER) - ResetTimer(LEVIATHAN_THORIMS_HAMMER, 1s); - }); AddTimerlessCombatAction(LEVIATHAN_FETCH_TOWERS, true); AddCombatAction(LEVIATHAN_HARDMODES, 10s); + AddCombatAction(LEVIATHAN_THORIMS_HAMMER, true); Reset(); m_creature->SetActiveObjectState(true); AddCustomAction(LEVIATHAN_RESET_OVERLOAD, true, [&]() @@ -405,7 +398,7 @@ struct boss_flame_leviathanAI : public BossAI case TOWER_ID_HODIR: DoSpawnHodirsFury(); break; case TOWER_ID_FREYA: DoSpawnFreyasWard(); break; case TOWER_ID_MIMIRON: DoSpawnMimironsInferno(); break; - case TOWER_ID_THORIM: ResetTimer(LEVIATHAN_THORIMS_HAMMER, 1s); break; + case TOWER_ID_THORIM: ResetCombatAction(LEVIATHAN_THORIMS_HAMMER, 1s); break; } // reset timer and wait for another turn @@ -522,6 +515,19 @@ struct boss_flame_leviathanAI : public BossAI { HandleHardmode(); } + case LEVIATHAN_THORIMS_HAMMER: + { + DoSpawnThorimsHammer(); + ++m_thorimsHammerCount; + + if (m_thorimsHammerCount < MAX_THORIM_HAMMER) + ResetCombatAction(LEVIATHAN_THORIMS_HAMMER, 500ms); + else + { + ResetCombatAction(action, 40s); + m_thorimsHammerCount = 0; + } + } } } }; From 38c21f6fb58bcb8d3cc713b4911479f7ec05c2b6 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 22:30:29 +0100 Subject: [PATCH 040/104] Ulduar: Fix Freya-Tower --- sql/scriptdev2/spell.sql | 1 + .../ulduar/ulduar/boss_flame_leviathan.cpp | 19 ++++++++++++++++--- src/game/Entities/TemporarySpawn.cpp | 4 ++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index 5b1166e26d5..33485eef19a 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -953,6 +953,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (62116,'spell_tails_up_summon_female_icepaw_bear'), (62138,'spell_teleport_inside_violet_hold'), (62297,'spell_hodirs_fury_leviathan'), +(62907,'spell_freyas_ward_leviathan'), (62910,'spell_mimirons_inferno_leviathan'), (62912,'spell_thorims_hammer_leviathan'), (62374,'spell_pursue_leviathan'), diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index e23c33ea226..a24ebddb273 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -302,28 +302,31 @@ struct boss_flame_leviathanAI : public BossAI void JustSummoned(Creature* summoned) override { - m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); switch (summoned->GetEntry()) { case NPC_THORIM_HAMMER_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_LIGHTNING_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; case NPC_MIMIRON_INFERNO_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_RED_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; case NPC_HODIR_FURY_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BLUE_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; case NPC_FREYA_WARD_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_GREEN_SKYBEAM, TRIGGERED_OLD_TRIGGERED); + m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; } } @@ -648,14 +651,14 @@ struct npc_freya_wardAI : public Scripted_NoMovementAI void JustSummoned(Creature* summoned) override { if (summoned->GetEntry() == NPC_WRITHING_LASHER || summoned->GetEntry() == NPC_WARD_OF_LIFE) - summoned->SetInCombatWithZone(); + summoned->SetInCombatWithZone(false); } void UpdateAI(const uint32 diff) override { if (m_uiFreyaWardTimer < diff) { - if (DoCastSpellIfCan(m_creature, SPELL_FREYA_WARD) == CAST_OK) + if (DoCastSpellIfCan(nullptr, SPELL_FREYA_WARD) == CAST_OK) m_uiFreyaWardTimer = 30000; } else @@ -1160,6 +1163,15 @@ struct OverloadLeviathan : public SpellScript } }; +struct FreyasWard : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const override + { + Unit* caster = spell->GetAffectiveCaster(); + caster->CastSpell(caster, spell->m_currentBasePoints[1], TRIGGERED_OLD_TRIGGERED); + } +}; + struct FlamesLeviathan : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override @@ -1225,4 +1237,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_grab_crate_leviathan"); RegisterSpellScript("spell_overload_leviathan"); RegisterSpellScript("spell_flames_leviathan"); + RegisterSpellScript("spell_freyas_ward_leviathan"); } diff --git a/src/game/Entities/TemporarySpawn.cpp b/src/game/Entities/TemporarySpawn.cpp index efe034bbf60..d14830b6656 100644 --- a/src/game/Entities/TemporarySpawn.cpp +++ b/src/game/Entities/TemporarySpawn.cpp @@ -96,7 +96,7 @@ void TemporarySpawn::Update(const uint32 diff) case TEMPSPAWN_DEAD_DESPAWN: { - if (IsDespawned()) + if (IsDead() || IsDespawned()) { UnSummon(); return; @@ -174,7 +174,7 @@ void TemporarySpawn::Update(const uint32 diff) } if (!GetCharmerGuid()) { - if (IsExpired()) + if (IsExpired() && !IsInCombat()) { UnSummon(); return; From bf70bccc73c50a6172ef2c5210addb06a00ef09a Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 23:02:17 +0100 Subject: [PATCH 041/104] Ulduar: Fix Hodir's Fury --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index a24ebddb273..3a691e17ddf 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -550,6 +550,7 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI ScriptedInstance* m_instance; uint32 m_uiTargetChaseTimer; + std::chrono::time_point m_castOnCooldown = std::chrono::steady_clock::now(); ObjectGuid m_hodirFuryGuid; void Reset() override @@ -561,14 +562,16 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI void AttackStart(Unit* /*who*/) override { } void MoveInLineOfSight(Unit* who) override { - if (m_creature->IsFriend(who)) + if (who->GetDistance2d(m_creature->GetPositionX(), m_creature->GetPositionY()) > 3.f) return; - if (who->GetDistance2d(m_creature->GetPositionX(), m_creature->GetPositionY()) <= 3.f) - { - m_creature->StopMoving(); - m_uiTargetChaseTimer = 0; - MovementInform(POINT_MOTION_TYPE, 1); - } + if (std::chrono::steady_clock::now() < m_castOnCooldown) + return; + if (!who->HasCharmer() || m_creature->IsFriend(who)) + return; + m_creature->GetMotionMaster()->Clear(); + m_uiTargetChaseTimer = 0; + m_castOnCooldown = std::chrono::steady_clock::now() + 5s; + MovementInform(POINT_MOTION_TYPE, 1); } void JustSummoned(Creature* summoned) override From 04846c65b5fe7a4d35fb67136e6ac91f5c5d0ec0 Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 13 Feb 2023 23:13:10 +0100 Subject: [PATCH 042/104] Ulduar: Fix Thorim's Hammer --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 3a691e17ddf..5c838179009 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -369,6 +369,11 @@ struct boss_flame_leviathanAI : public BossAI void HandleHardmode() { + if(!m_creature->IsInCombat()) + { + DisableCombatAction(LEVIATHAN_HARDMODES); + return; + } // if all towers are deactivated then skip the rest if (!m_ulduarTower[TOWER_ID_HODIR] && !m_ulduarTower[TOWER_ID_FREYA] && !m_ulduarTower[TOWER_ID_MIMIRON] && !m_ulduarTower[TOWER_ID_THORIM]) { @@ -500,7 +505,7 @@ struct boss_flame_leviathanAI : public BossAI { float fX, fY, fZ; m_creature->GetRandomPoint(orbital->GetPositionX(), orbital->GetPositionY(), orbital->GetPositionZ(), 150.0f, fX, fY, fZ); - m_creature->SummonCreature(NPC_THORIM_HAMMER_VEHICLE, fX, fY, fZ, 0, TEMPSPAWN_TIMED_DESPAWN, 8000); + m_creature->SummonCreature(NPC_THORIM_HAMMER_VEHICLE, fX, fY, fZ, 0, TEMPSPAWN_TIMED_DESPAWN, 20000); } } @@ -527,7 +532,7 @@ struct boss_flame_leviathanAI : public BossAI ResetCombatAction(LEVIATHAN_THORIMS_HAMMER, 500ms); else { - ResetCombatAction(action, 40s); + ResetCombatAction(action, 80s); m_thorimsHammerCount = 0; } } From c644ad7b9e715fceae61780183abac0f144ee84c Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 14 Feb 2023 10:44:01 +0100 Subject: [PATCH 043/104] Ulduar: Rework Demolisher Energy --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 5c838179009..295d1bdfe0a 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -715,26 +715,12 @@ struct npc_salvaged_demolisherAI : public CombatAI { npc_salvaged_demolisherAI(Creature* creature) : CombatAI(creature, DEMOLISHER_ACTIONS_MAX) { - AddCustomAction(DEMOLISHER_SYNC_ENERGY, 1s, [&]() - { - if (!m_creature->IsAlive()) - return; - ResetTimer(DEMOLISHER_SYNC_ENERGY, 1s); - if (m_creature->GetVehicleInfo()->GetPassenger(0)) - { - Unit* mechanicSeat = m_creature->GetVehicleInfo()->GetPassenger(1); - if (!mechanicSeat) - return; - mechanicSeat->SetMaxPower(POWER_ENERGY, 50); - mechanicSeat->SetPower(POWER_ENERGY, m_creature->GetPower(POWER_ENERGY)); - } - }); + AddCustomAction(DEMOLISHER_SYNC_ENERGY, 1s, [&]() { initialize(); }); SetCombatMovement(false); } - void JustRespawned() override + void initialize() { - CombatAI::JustRespawned(); m_creature->SetMaxPower(POWER_ENERGY, 50); m_creature->SetPower(POWER_ENERGY, 50); if (!m_creature->IsVehicle()) @@ -746,6 +732,12 @@ struct npc_salvaged_demolisherAI : public CombatAI mechanicSeat->SetMaxPower(POWER_ENERGY, 50); mechanicSeat->SetPower(POWER_ENERGY, 50); } + + void JustRespawned() override + { + CombatAI::JustRespawned(); + ResetTimer(DEMOLISHER_SYNC_ENERGY, 1s); + } }; enum DefenseTurretActions From 3e82a8085fce1e7069e121b6b3815387e7f0cbed Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 14 Feb 2023 11:41:19 +0100 Subject: [PATCH 044/104] Ulduar: Make Bosses immune to Knockback --- src/game/Spells/SpellEffects.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/Spells/SpellEffects.cpp b/src/game/Spells/SpellEffects.cpp index 91f1faf8a15..08f578ebcff 100644 --- a/src/game/Spells/SpellEffects.cpp +++ b/src/game/Spells/SpellEffects.cpp @@ -11719,6 +11719,10 @@ void Spell::EffectKnockBack(SpellEffectIndex eff_idx) if (!unitTarget) return; + if (Creature* creatureTarget = dynamic_cast(unitTarget)) + if (creatureTarget->GetCreatureInfo()->Rank == 3) + return; + switch (m_spellInfo->Id) { case 36812: // Soaring - Test Flight quests From 057197714732625fc20f791c173956a946b10a8e Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 14 Feb 2023 17:28:02 +0100 Subject: [PATCH 045/104] Ulduar: Implement Ready to Fly spell and fix seat ejections --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 295d1bdfe0a..4d29a976da5 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -931,21 +931,33 @@ struct ThrowPassenger : public SpellScript Unit* caster = spell->GetCaster(); if (!caster) return; + if (caster->GetEntry() != NPC_SALVAGED_DEMOLISHER) + return; auto& targetList = spell->GetTargetList(); Unit* projectile = nullptr; Unit* seat = nullptr; if (caster->GetVehicleInfo()) if (caster->GetVehicleInfo()->GetPassenger(3)) - if (Unit* seat = static_cast(caster->GetVehicleInfo()->GetPassenger(3))) + if (seat = static_cast(caster->GetVehicleInfo()->GetPassenger(3))) if (seat->IsVehicle()) projectile = seat->GetVehicleInfo()->GetPassenger(0); if (!projectile) return; + if (!seat) + return; + + std::unordered_set spellIds; + for (auto aura : caster->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE)) + { + if (aura->GetCasterGuid() == projectile->GetObjectGuid()) + spellIds.emplace(aura->GetId()); + } + + for (uint32 spell : spellIds) + projectile->RemoveAurasByCasterSpell(spell, projectile->GetObjectGuid()); + spellIds.clear(); - if (seat) - seat->GetVehicleInfo()->UnBoard(projectile, false); - projectile->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, projectile->GetObjectGuid()); projectile->RemoveAurasDueToSpell(SPELL_LOAD_INTO_CATAPULT); projectile->KnockBackWithAngle(projectile->GetAngle(spell->m_targets.m_destPos.x, spell->m_targets.m_destPos.y), spell->m_targets.getSpeed() * cos(spell->m_targets.getElevation()), spell->m_targets.getSpeed() * sin(spell->m_targets.getElevation())); projectile->CastSpell(nullptr, SPELL_HOOKSHOT_AURA, TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); @@ -1100,8 +1112,17 @@ struct EjectPassenger1 : public SpellScript Unit* passenger = vInfo->GetPassenger(spell->m_currentBasePoints[0]); if (!passenger) return; - vInfo->UnBoard(passenger, false); - passenger->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); + + std::unordered_set spellIds; + for (auto aura : target->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE)) + { + if (aura->GetCasterGuid() == passenger->GetObjectGuid()) + spellIds.emplace(aura->GetId()); + } + + for (uint32 spell : spellIds) + passenger->RemoveAurasByCasterSpell(spell, passenger->GetObjectGuid()); + spellIds.clear(); } }; @@ -1183,6 +1204,33 @@ struct FlamesLeviathan : public SpellScript } }; +struct ReadyToFly : public SpellScript +{ + const std::vector bcts = {34429, 34433}; + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const override + { + Unit* target = spell->GetUnitTarget(); + if (!target) + return; + if (effIdx == EFFECT_INDEX_0) + { + if (!target->IsBoarded()) + return; + Unit* vehicle = dynamic_cast(target->GetTransportInfo()->GetTransport()); + if (!vehicle || !vehicle->IsVehicle()) + return; + Unit* driver = vehicle->GetVehicleInfo()->GetPassenger(0); + if (!driver) + return; + DoBroadcastText(spell->m_triggeredBySpellInfo->EffectBasePoints[2] + 1, spell->GetTrueCaster(), driver); + } + else if (effIdx == EFFECT_INDEX_1) + { + DoBroadcastText(bcts[urand(0,1)], target); + } + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1238,4 +1286,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_overload_leviathan"); RegisterSpellScript("spell_flames_leviathan"); RegisterSpellScript("spell_freyas_ward_leviathan"); + RegisterSpellScript("spell_ready_to_fly"); } From a8cb513864efbfc26a4b8ec1761197853c02f4af Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 14 Feb 2023 17:59:52 +0100 Subject: [PATCH 046/104] Ulduar: Minor semantic fix --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 4d29a976da5..0f96c8c3d52 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1151,7 +1151,7 @@ struct ParachuteLeviathan : public AuraScript return; if (!caster->IsFalling()) return; - caster->RemoveAurasDueToSpell(aura->GetSpellProto()->Id); + caster->RemoveAurasDueToSpell(aura->GetId()); caster->CastSpell(caster, aura->GetBasePoints(), TRIGGERED_IGNORE_CURRENT_CASTED_SPELL | TRIGGERED_IGNORE_GCD | TRIGGERED_HIDE_CAST_IN_COMBAT_LOG | TRIGGERED_IGNORE_CASTER_AURA_STATE); } }; From 58a26238b7a74c68b6824664aeeaac61c80be013 Mon Sep 17 00:00:00 2001 From: insunaa Date: Tue, 14 Feb 2023 19:57:03 +0100 Subject: [PATCH 047/104] Ulduar: Fix Visibility for Destructible Buildings --- src/game/Entities/GameObject.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/game/Entities/GameObject.cpp b/src/game/Entities/GameObject.cpp index 32372ceece3..db2e69a8d74 100644 --- a/src/game/Entities/GameObject.cpp +++ b/src/game/Entities/GameObject.cpp @@ -303,6 +303,9 @@ bool GameObject::Create(uint32 dbGuid, uint32 guidlow, uint32 name_id, Map* map, if (GetGOInfo()->IsLargeGameObject() && GetVisibilityData().GetVisibilityDistance() < VISIBILITY_DISTANCE_LARGE) GetVisibilityData().SetVisibilityDistanceOverride(VisibilityDistanceType::Large); + if (GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + GetVisibilityData().SetVisibilityDistanceOverride(VisibilityDistanceType::Infinite); + return true; } From 863a32c7035f329c5557c27f4c5aee1f50a1d694 Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 10:17:25 +0100 Subject: [PATCH 048/104] Allow triggering spell to serve as casterauraspell --- src/game/Spells/Spell.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index ac511d8c987..311c149d718 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -5603,7 +5603,8 @@ SpellCastResult Spell::CheckCast(bool strict) // Caster aura req check if need if (m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell)) - return SPELL_FAILED_CASTER_AURASTATE; + if (!m_triggeredBySpellInfo || m_triggeredBySpellInfo->Id != m_spellInfo->casterAuraSpell) + return SPELL_FAILED_CASTER_AURASTATE; if (m_spellInfo->excludeCasterAuraSpell) { // Special cases of non existing auras handling From 205c301ee71da245bbd97425aa5eead6a95e7ecc Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 10:34:07 +0100 Subject: [PATCH 049/104] Ulduar: Fully working pyrite refuel --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 0f96c8c3d52..b84fc187fe7 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -110,6 +110,10 @@ enum SPELL_BEAM_TARGET_STATE = 62898, // cast by all tower reticles; purpose unk SPELL_BIRTH = 40031, // not used; purpose unk + // player vehicle spells + SPELL_LIQUID_PYRITE = 62496, + SPELL_RELOAD_AMMMO = 62473, + // vehicle accessories //NPC_LEVIATHAN_SEAT = 33114, NPC_LEVIATHAN_TURRET = 33139, @@ -1158,8 +1162,10 @@ struct ParachuteLeviathan : public AuraScript struct GrabPyrite : public SpellScript { - void OnEffectExecute(Spell* spell, SpellEffectIndex /*effIdx*/) const + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const { + if (effIdx != EFFECT_INDEX_0) + return; Unit* caster = spell->GetCaster(); Unit* target = spell->GetUnitTarget(); if (!caster || !target) @@ -1167,8 +1173,12 @@ struct GrabPyrite : public SpellScript if (auto transportInfo = caster->GetTransportInfo()) if (auto vehicle = static_cast(transportInfo->GetTransport())) { - target->CastSpell(vehicle, spell->m_currentBasePoints[0], TRIGGERED_OLD_TRIGGERED); - target->CastSpell(vehicle, 62473, TRIGGERED_OLD_TRIGGERED | TRIGGERED_IGNORE_CASTER_AURA_STATE); + uint32 val = spell->m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_0); + target->CastSpell(vehicle, SPELL_LIQUID_PYRITE, TRIGGERED_OLD_TRIGGERED); + target->CastSpell(vehicle, val, TRIGGERED_OLD_TRIGGERED); + if (!vehicle->IsBoarded()) + return; + static_cast(target)->ForcedDespawn(3000); } } }; From 8ae5a06689c1113a943217d4b1269dd9db7338c8 Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 13:10:50 +0100 Subject: [PATCH 050/104] Ulduar: Final(ish) Pyrite Refueling fix --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 40 +++++++++++++++++-- src/game/MotionGenerators/MotionMaster.h | 3 ++ src/game/Movement/MoveSplineInit.cpp | 2 + 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index b84fc187fe7..d683a89a94f 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -111,6 +111,7 @@ enum SPELL_BIRTH = 40031, // not used; purpose unk // player vehicle spells + SPELL_LIQUID_PYRITE_AURA = 62494, SPELL_LIQUID_PYRITE = 62496, SPELL_RELOAD_AMMMO = 62473, @@ -709,6 +710,36 @@ struct npc_mimiron_infernoAI : public Scripted_NoMovementAI } }; +struct npc_liquid_pyriteAI : public Scripted_NoMovementAI +{ + npc_liquid_pyriteAI(Creature* creature) : Scripted_NoMovementAI(creature) { + AddCustomAction(0, true, [&]() + { + if (!m_creature->IsBoarded()) + return; + Unit* vehicle = dynamic_cast(m_creature->GetTransportInfo()->GetTransport()); + if (!vehicle) + return; + m_creature->CastSpell(vehicle, SPELL_LIQUID_PYRITE, TRIGGERED_OLD_TRIGGERED); + m_creature->ForcedDespawn(3000); + }); + Reset(); + } + + void Reset() override + { + Scripted_NoMovementAI::Reset(); + DoCastSpellIfCan(m_creature, SPELL_LIQUID_PYRITE_AURA, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT); + } + + void MovementInform(uint32 motionType, uint32 /*value*/) + { + if (motionType != BOARD_VEHICLE_MOTION_TYPE) + return; + ResetTimer(0, 2s); + } +}; + enum DemolisherActions { DEMOLISHER_ACTIONS_MAX, @@ -1174,11 +1205,7 @@ struct GrabPyrite : public SpellScript if (auto vehicle = static_cast(transportInfo->GetTransport())) { uint32 val = spell->m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_0); - target->CastSpell(vehicle, SPELL_LIQUID_PYRITE, TRIGGERED_OLD_TRIGGERED); target->CastSpell(vehicle, val, TRIGGERED_OLD_TRIGGERED); - if (!vehicle->IsBoarded()) - return; - static_cast(target)->ForcedDespawn(3000); } } }; @@ -1279,6 +1306,11 @@ void AddSC_boss_flame_leviathan() pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "npc_liquid_pyrite"; + pNewScript->GetAI = &GetNewAIInstance; + pNewScript->RegisterSelf(); + RegisterSpellScript("spell_pursue_leviathan"); RegisterSpellScript("spell_hodirs_fury_leviathan"); RegisterSpellScript("spell_thorims_hammer_leviathan"); diff --git a/src/game/MotionGenerators/MotionMaster.h b/src/game/MotionGenerators/MotionMaster.h index 98ed9af28f6..3f4ed5b562a 100644 --- a/src/game/MotionGenerators/MotionMaster.h +++ b/src/game/MotionGenerators/MotionMaster.h @@ -76,6 +76,9 @@ enum MovementGeneratorType EXTERNAL_WAYPOINT_FINISHED_LAST = 20, // Only used in UnitAI::MovementInform when the waittime of the last wp is finished The pathId >= 0 is added as additional value FORMATION_MOTION_TYPE = 21, // TargetedMovementGenerator.h + + BOARD_VEHICLE_MOTION_TYPE = 22, + UNBOARD_VEHICLE_MOTION_TYPE = 23, }; enum MMCleanFlag diff --git a/src/game/Movement/MoveSplineInit.cpp b/src/game/Movement/MoveSplineInit.cpp index cb027043122..559259b979a 100644 --- a/src/game/Movement/MoveSplineInit.cpp +++ b/src/game/Movement/MoveSplineInit.cpp @@ -197,6 +197,8 @@ namespace Movement data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); if (transportInfo) { + if (unit.AI()) + unit.AI()->MovementInform(BOARD_VEHICLE_MOTION_TYPE, transportInfo->GetTransportSeat()); data << transportInfo->GetTransportGuid().WriteAsPacked(); data << int8(transportInfo->GetTransportSeat()); } From d52fa0b52005fd1862680e8e22ac33508925550c Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 18:43:01 +0100 Subject: [PATCH 051/104] Ulduar: Fix Friendly Fire for AA Rocket --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index d683a89a94f..989f874e1ab 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1268,6 +1268,17 @@ struct ReadyToFly : public SpellScript } }; +struct AntiAirRocket : public SpellScript +{ + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override + { + Unit* caster = spell->GetAffectiveCaster(); + if (!caster->IsEnemy(target)) + return false; + return true; + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1329,4 +1340,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_flames_leviathan"); RegisterSpellScript("spell_freyas_ward_leviathan"); RegisterSpellScript("spell_ready_to_fly"); + RegisterSpellScript("spell_anti_air_rocket"); } From 37602e1706f2049b0738027e8e72383c831ea7ca Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 19:51:51 +0100 Subject: [PATCH 052/104] Ulduar: Fix Mechanolifts --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 989f874e1ab..6d1d10d06d0 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -740,6 +740,41 @@ struct npc_liquid_pyriteAI : public Scripted_NoMovementAI } }; +struct npc_pyrite_safety_containerAI : public Scripted_NoMovementAI +{ + npc_pyrite_safety_containerAI(Creature* creature) : Scripted_NoMovementAI(creature) + { + AddCustomAction(0, 1s, [&]() + { + Creature* lift = dynamic_cast(m_creature->GetSpawner()); + //Creature* lift = GetClosestCreatureWithEntry(m_creature, 33214, 6.f); + if (!lift) + return; + m_creature->CastSpell(lift, 63605, TRIGGERED_OLD_TRIGGERED); + }); + AddCustomAction(1, true, [&]() + { + if (m_creature->IsFalling()) + { + ResetTimer(1, 500ms); + return; + } + float gZ = m_creature->GetMap()->GetHeight(m_creature->GetPhaseMask(), m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); + if ((gZ + 0.1f) < m_creature->GetPositionZ()) + { + ResetTimer(1, 500ms); + return; + } + m_creature->CastSpell(nullptr, 63360, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(m_creature, 54740, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(m_creature, 62543, TRIGGERED_OLD_TRIGGERED); + //temporary until spell 62543 is implemented + m_creature->SummonCreature(33189, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0.f, TEMPSPAWN_TIMED_DESPAWN, 30000, false, false, 0, 0, 0, false, true); + m_creature->ForcedDespawn(1000); + }); + } +}; + enum DemolisherActions { DEMOLISHER_ACTIONS_MAX, @@ -1235,7 +1270,7 @@ struct FlamesLeviathan : public SpellScript bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override { Unit* caster = spell->GetAffectiveCaster(); - if (target && caster->IsFriend(target)) + if (!caster->IsEnemy(target)) return false; return true; } @@ -1275,10 +1310,29 @@ struct AntiAirRocket : public SpellScript Unit* caster = spell->GetAffectiveCaster(); if (!caster->IsEnemy(target)) return false; + if (target->GetEntry() == 33218) + return false; return true; } }; +// 63605 - Rope Beam +struct RopeBeam : public AuraScript +{ + void OnApply(Aura* aura, bool apply) const override + { + if (apply) + return; + Unit* caster = aura->GetCaster(); + if (!caster || caster->GetEntry() != 33218) + return; + caster->CastSpell(nullptr, 56093, TRIGGERED_OLD_TRIGGERED); + caster->GetMotionMaster()->MoveFall(); + if (caster->AI()) + caster->AI()->ResetTimer(1, 500ms); + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1322,6 +1376,11 @@ void AddSC_boss_flame_leviathan() pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "npc_pyrite_safety_container"; + pNewScript->GetAI = &GetNewAIInstance; + pNewScript->RegisterSelf(); + RegisterSpellScript("spell_pursue_leviathan"); RegisterSpellScript("spell_hodirs_fury_leviathan"); RegisterSpellScript("spell_thorims_hammer_leviathan"); @@ -1341,4 +1400,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_freyas_ward_leviathan"); RegisterSpellScript("spell_ready_to_fly"); RegisterSpellScript("spell_anti_air_rocket"); + RegisterSpellScript("spell_rope_beam"); } From 3f882c1a1c0838b370ebf94ce5520130d697247e Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 20:41:08 +0100 Subject: [PATCH 053/104] Ulduar: Implement Serverside Pyrite Spell --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 6d1d10d06d0..c99d335b16b 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -768,8 +768,6 @@ struct npc_pyrite_safety_containerAI : public Scripted_NoMovementAI m_creature->CastSpell(nullptr, 63360, TRIGGERED_OLD_TRIGGERED); m_creature->CastSpell(m_creature, 54740, TRIGGERED_OLD_TRIGGERED); m_creature->CastSpell(m_creature, 62543, TRIGGERED_OLD_TRIGGERED); - //temporary until spell 62543 is implemented - m_creature->SummonCreature(33189, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0.f, TEMPSPAWN_TIMED_DESPAWN, 30000, false, false, 0, 0, 0, false, true); m_creature->ForcedDespawn(1000); }); } From d66a18e86f54835899b9cbeb7c23fa65b05ad85c Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 20:55:36 +0100 Subject: [PATCH 054/104] Ulduar: neutral targetting for pyrite spells --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index c99d335b16b..4d608f42069 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -766,8 +766,8 @@ struct npc_pyrite_safety_containerAI : public Scripted_NoMovementAI return; } m_creature->CastSpell(nullptr, 63360, TRIGGERED_OLD_TRIGGERED); - m_creature->CastSpell(m_creature, 54740, TRIGGERED_OLD_TRIGGERED); - m_creature->CastSpell(m_creature, 62543, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(nullptr, 54740, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(nullptr, 62543, TRIGGERED_OLD_TRIGGERED); m_creature->ForcedDespawn(1000); }); } From 240ef5089c86dd9402538a43f4a14be2fdf213c2 Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 16 Feb 2023 21:06:52 +0100 Subject: [PATCH 055/104] Leviathan: Cleanup --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 4d608f42069..4dd96744414 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -747,18 +747,12 @@ struct npc_pyrite_safety_containerAI : public Scripted_NoMovementAI AddCustomAction(0, 1s, [&]() { Creature* lift = dynamic_cast(m_creature->GetSpawner()); - //Creature* lift = GetClosestCreatureWithEntry(m_creature, 33214, 6.f); if (!lift) return; m_creature->CastSpell(lift, 63605, TRIGGERED_OLD_TRIGGERED); }); AddCustomAction(1, true, [&]() { - if (m_creature->IsFalling()) - { - ResetTimer(1, 500ms); - return; - } float gZ = m_creature->GetMap()->GetHeight(m_creature->GetPhaseMask(), m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); if ((gZ + 0.1f) < m_creature->GetPositionZ()) { From fff90e24d303cf5eade69a4524fdce64870f1083 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 10:36:03 +0100 Subject: [PATCH 056/104] Ulduar: Improve vehicle spellclick behaviour --- .../scripts/northrend/ulduar/ulduar/ulduar.cpp | 8 +++++++- .../ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index 8a66e87bf46..337da2fa1a5 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -181,6 +181,7 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) case NPC_EXPLORER_DELLORAH: case NPC_BRANN_BRONZEBEARD: case NPC_PROJECTION_UNIT: + case NPC_LORE_KEEPER_NORGANNON: case NPC_ORBITAL_SUPPORT: case NPC_IGNIS: case NPC_RAZORSCALE: @@ -1090,7 +1091,12 @@ bool instance_ulduar::CheckConditionCriteriaMeet(Player const* pPlayer, uint32 u break; // handle vehicle spell clicks - are available only after the gauntlet was started by gossip or when Leviathan is active - return GetData(TYPE_LEVIATHAN_GAUNTLET) == IN_PROGRESS || GetData(TYPE_LEVIATHAN) == SPECIAL || GetData(TYPE_LEVIATHAN) == FAIL || GetData(TYPE_LEVIATHAN) == IN_PROGRESS; + Creature* keeper = GetSingleCreatureFromStorage(NPC_LORE_KEEPER_NORGANNON); + bool isDead = true; + if (keeper) + if (keeper->IsAlive()) + isDead = false; + return (isDead || GetData(TYPE_LEVIATHAN_GAUNTLET) == IN_PROGRESS || GetData(TYPE_LEVIATHAN) == SPECIAL || GetData(TYPE_LEVIATHAN) == FAIL || GetData(TYPE_LEVIATHAN) == IN_PROGRESS) && GetData(TYPE_LEVIATHAN) != DONE; } } diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h index caf28a9b710..9976329212f 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h @@ -72,6 +72,7 @@ enum NPC_XT_TOY_PILE = 33337, // robot spawner npc for XT002 // Leviathan other npcs + NPC_LORE_KEEPER_NORGANNON = 33686, NPC_ULDUAR_COLOSSUS = 33237, NPC_BRONZEBEARD_RADIO = 34054, NPC_EXPLORER_DELLORAH = 33701, From ef963425232a901889ddec9b8646f34e076ce5e3 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 12:53:16 +0100 Subject: [PATCH 057/104] WotLK: add Eject Passenger (Chopper) SpellScript --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 11 ++++-- .../scripts/world/spell_scripts_wotlk.cpp | 34 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 4dd96744414..d21027e9b44 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -720,8 +720,15 @@ struct npc_liquid_pyriteAI : public Scripted_NoMovementAI Unit* vehicle = dynamic_cast(m_creature->GetTransportInfo()->GetTransport()); if (!vehicle) return; - m_creature->CastSpell(vehicle, SPELL_LIQUID_PYRITE, TRIGGERED_OLD_TRIGGERED); - m_creature->ForcedDespawn(3000); + if (vehicle->GetEntry() == NPC_SALVAGED_DEMOLISHER) + { + m_creature->CastSpell(vehicle, SPELL_LIQUID_PYRITE, TRIGGERED_OLD_TRIGGERED); + m_creature->ForcedDespawn(3000); + } + else if (vehicle->GetEntry() == NPC_SALVAGED_CHOPPER) + { + vehicle->CastSpell(nullptr, 69748, TRIGGERED_OLD_TRIGGERED); + } }); Reset(); } diff --git a/src/game/AI/ScriptDevAI/scripts/world/spell_scripts_wotlk.cpp b/src/game/AI/ScriptDevAI/scripts/world/spell_scripts_wotlk.cpp index 1c2c8161600..ae2a1e06b43 100644 --- a/src/game/AI/ScriptDevAI/scripts/world/spell_scripts_wotlk.cpp +++ b/src/game/AI/ScriptDevAI/scripts/world/spell_scripts_wotlk.cpp @@ -16,6 +16,7 @@ #include "AI/ScriptDevAI/include/sc_common.h" #include "Globals/ObjectMgr.h" +#include "Entities/Vehicle.h" struct Replenishment : public SpellScript { @@ -164,6 +165,38 @@ struct AutoBreakProc : public AuraScript } }; +// 67393 - Eject Passenger +struct EjectPassengerChopper : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex /*effIdx*/) const override + { + Unit* target = spell->GetUnitTarget(); + if (!target || !target->IsVehicle()) + return; + VehicleInfo* vInfo = target->GetVehicleInfo(); + if (!vInfo) + return; + int32 simpleVal = spell->m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_0) - 1; + Unit* passenger = vInfo->GetPassenger(simpleVal); + if (!passenger) + return; + + std::unordered_set spellIds; + for (auto aura : target->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE)) + { + if (aura->GetCasterGuid() == passenger->GetObjectGuid()) + spellIds.emplace(aura->GetId()); + } + + for (uint32 spell : spellIds) + passenger->RemoveAurasByCasterSpell(spell, passenger->GetObjectGuid()); + spellIds.clear(); + if (passenger = vInfo->GetPassenger(simpleVal)) + vInfo->UnBoard(passenger, false); + target->CastSpell(nullptr, 67395, TRIGGERED_OLD_TRIGGERED); + } +}; + void AddSC_spell_scripts_wotlk() { RegisterSpellScript("spell_replenishment"); @@ -172,4 +205,5 @@ void AddSC_spell_scripts_wotlk() RegisterSpellScript("spell_stoicism"); RegisterSpellScript("spell_blood_reserve_enchant"); RegisterSpellScript("spell_auto_break_proc"); + RegisterSpellScript("spell_eject_passenger_chopper"); } \ No newline at end of file From 2099ddb64568f5d8d86a5e8325a8361effcec229 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 12:53:33 +0100 Subject: [PATCH 058/104] Ulduar: Spawn dead-by-default vehicles as dead --- .../AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index 337da2fa1a5..bb16f5aa0bd 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -323,6 +323,9 @@ void instance_ulduar::OnCreatureRespawn(Creature* creature) hodirHelper->CastSpell(hodirHelper, 64174, TRIGGERED_NONE); }); } + //Workaround because Vehicles aren't Creatures, so CreatureAddons aren't applied to them + if (creature->GetEntry() == 33059 || creature->GetEntry() == 33061 || creature->GetEntry() == 33063) + creature->CastSpell(nullptr, 29266, TRIGGERED_OLD_TRIGGERED); } void instance_ulduar::OnObjectCreate(GameObject* pGo) From edf0040f6f5b5a0cb4553084c57dbb452bf0dc15 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 13:27:00 +0100 Subject: [PATCH 059/104] Vehicles: Eject Passengers across subvehicles --- src/game/Entities/VehicleHandler.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/game/Entities/VehicleHandler.cpp b/src/game/Entities/VehicleHandler.cpp index f25cdeee9f0..328730ef638 100644 --- a/src/game/Entities/VehicleHandler.cpp +++ b/src/game/Entities/VehicleHandler.cpp @@ -235,11 +235,30 @@ void WorldSession::HandleEjectPassenger(WorldPacket& recvPacket) if (!passenger || !passenger->IsBoarded()) return; - // _player is not a vehicle - if (!_player->IsVehicle()) + // _player is not on a vehicle + if (!_player->IsBoarded()) return; - VehicleInfo* vehicleInfo = _player->GetVehicleInfo(); + Unit* vehicle = dynamic_cast(_player->GetTransportInfo()->GetTransport()); + + if (!vehicle) + return; + + VehicleInfo* vehicleInfo = vehicle->GetVehicleInfo(); + + for (int i = 0; i < MAX_VEHICLE_SEAT; i++) + { + if (Unit* psg = vehicleInfo->GetPassenger(i)) + if (psg->IsVehicle()) + { + if (VehicleInfo* vi = psg->GetVehicleInfo()) + if (vi->HasOnBoard(passenger)) + { + vehicleInfo = vi; + break; + } + } + } // _player must be transporting passenger if (!vehicleInfo->HasOnBoard(passenger)) @@ -248,5 +267,5 @@ void WorldSession::HandleEjectPassenger(WorldPacket& recvPacket) // Check for eject flag if (VehicleSeatEntry const* seatEntry = vehicleInfo->GetSeatEntry(passenger->GetTransportInfo()->GetTransportSeat())) if (seatEntry->m_flagsB & SEAT_FLAG_B_EJECTABLE) - _player->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, passengerGuid); + vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, passengerGuid); } From 6e97ccc9eb84afa69b8ac6e835bf3d81c43c5c48 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 13:55:45 +0100 Subject: [PATCH 060/104] Ulduar: Fix BCTs for Leviathan --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index d21027e9b44..a0b1e196bc5 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -29,30 +29,30 @@ EndScriptData */ enum { - SAY_AGGRO = -1603159, - SAY_SLAY = -1603160, - SAY_DEATH = -1603161, - SAY_CHANGE_1 = -1603162, - SAY_CHANGE_2 = -1603163, - SAY_CHANGE_3 = -1603164, - - SAY_PLAYER_RIDE = -1603165, - SAY_OVERLOAD_1 = -1603166, - SAY_OVERLOAD_2 = -1603167, - SAY_OVERLOAD_3 = -1603168, - - SAY_HARD_MODE = -1603169, - SAY_TOWER_FROST = -1603170, - SAY_TOWER_FIRE = -1603171, - SAY_TOWER_ENERGY = -1603172, - SAY_TOWER_NATURE = -1603173, - SAY_TOWER_DOWN = -1603174, - - EMOTE_PURSUE = -1603175, - EMOTE_HODIR_FURY = -1603242, - EMOTE_FREYA_WARD = -1603243, - EMOTE_MIMIRON_INFERNO = -1603244, - EMOTE_THORIM_HAMMER = -1603245, + SAY_AGGRO = 33487, + SAY_SLAY = 33507, + SAY_DEATH = 33506, + SAY_CHANGE_1 = 33488, + SAY_CHANGE_2 = 33489, + SAY_CHANGE_3 = 33490, + + SAY_PLAYER_RIDE = 33501, + SAY_OVERLOAD_1 = 33503, + SAY_OVERLOAD_2 = 33504, + SAY_OVERLOAD_3 = 33505, + + SAY_HARD_MODE = 33491, + SAY_TOWER_FROST = 33493, + SAY_TOWER_FIRE = 33495, + SAY_TOWER_ENERGY = 33499, + SAY_TOWER_NATURE = 33497, + SAY_TOWER_DOWN = 33492, + + EMOTE_PURSUE = 33502, + EMOTE_HODIR_FURY = 33494, + EMOTE_FREYA_WARD = 33498, + EMOTE_MIMIRON_INFERNO = 33496, + EMOTE_THORIM_HAMMER = 33500, // Leviathan spells SPELL_INVISIBILITY_DETECTION = 18950, @@ -1078,6 +1078,11 @@ struct Hookshot : public SpellScript { turret->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); } + instance_ulduar* instance = dynamic_cast(target->GetInstanceData()); + if (!instance) + return; + Creature* levi = instance->GetSingleCreatureFromStorage(NPC_LEVIATHAN); + DoBroadcastText(SAY_PLAYER_RIDE, levi); } }; @@ -1154,6 +1159,12 @@ struct SystemsShutdown : public AuraScript } } target->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED); + switch (urand(0,2)) + { + case 0: DoBroadcastText(SAY_OVERLOAD_1, target); + case 1: DoBroadcastText(SAY_OVERLOAD_2, target); + case 2: DoBroadcastText(SAY_OVERLOAD_3, target); + } return; } CreatureList leviSeats; From 1e6f791d6f31d0557239f8b1a8ee2c4979b43ab0 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 14:08:17 +0100 Subject: [PATCH 061/104] Ulduar: Kill Leviathan Adds on death --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index a0b1e196bc5..0462ecc8ed3 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -263,6 +263,19 @@ struct boss_flame_leviathanAI : public BossAI orbital->RemoveAllAuras(); } + CreatureList leviAdds; + for (const uint32& entry : addEntries) + { + GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 50.f); + for (auto add : leviAdds) + { + if (add && (add->GetEntry() == NPC_DEFENSE_TURRET || add->GetEntry() == NPC_LEVIATHAN_TURRET || add->GetEntry() == NPC_LEVIATHAN_SEAT)) + add->Suicide(); + else if (add) + add->ForcedDespawn(); + } + } + // start epilogue event if (Creature* pFlyMachine = m_creature->SummonCreature(NPC_BRANN_FLYING_MACHINE, 175.2838f, -210.4325f, 501.2375f, 1.42f, TEMPSPAWN_CORPSE_DESPAWN, 0)) { From e1fe8db82d41d5a997a2821405a4af6466604fe4 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 14:44:49 +0100 Subject: [PATCH 062/104] Ulduar: Make reticles float for spell visibility --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 0462ecc8ed3..ab8c11be0e8 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -163,19 +163,19 @@ static const int32 leviathanTowerEmote[KEEPER_ENCOUNTER] = { EMOTE_HODIR_FURY, E static const float afFreyaWard[MAX_FREYA_WARD][4] = { - {156.9291f, 61.52306f, 409.887f, 5.68f}, - {376.641f, 68.61361f, 411.2287f, 3.85f}, - {383.6206f, -130.8576f, 410.7088f, 2.26f}, - {154.9095f, -137.4339f, 409.887f, 0.79f}, + {156.9291f, 61.52306f, 410.887f, 5.68f}, + {376.641f, 68.61361f, 412.2287f, 3.85f}, + {383.6206f, -130.8576f, 411.7088f, 2.26f}, + {154.9095f, -137.4339f, 410.887f, 0.79f}, }; static const float afHodirFury[MAX_HODIR_FURY][3] = { - {219.9013f, 7.913357f, 409.7861f}, - {326.0777f, -74.99034f, 409.887f}, + {219.9013f, 7.913357f, 410.7861f}, + {326.0777f, -74.99034f, 410.887f}, }; -static const float afMimironInferno[3] = {329.1809f, 8.02577f, 409.887f}; +static const float afMimironInferno[3] = {329.1809f, 8.02577f, 410.887f}; static const std::vector addEntries = {NPC_LEVIATHAN_SEAT, NPC_LEVIATHAN_TURRET, NPC_DEFENSE_TURRET, NPC_OVERLOAD_DEVICE}; @@ -325,24 +325,28 @@ struct boss_flame_leviathanAI : public BossAI case NPC_THORIM_HAMMER_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, 50195, TRIGGERED_OLD_TRIGGERED); // Hackfix for reticles until hovering is properly implemented summoned->CastSpell(summoned, SPELL_LIGHTNING_SKYBEAM, TRIGGERED_OLD_TRIGGERED); m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; case NPC_MIMIRON_INFERNO_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, 50195, TRIGGERED_OLD_TRIGGERED); // Hackfix for reticles until hovering is properly implemented summoned->CastSpell(summoned, SPELL_RED_SKYBEAM, TRIGGERED_OLD_TRIGGERED); m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; case NPC_HODIR_FURY_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, 50195, TRIGGERED_OLD_TRIGGERED); // Hackfix for reticles until hovering is properly implemented summoned->CastSpell(summoned, SPELL_BLUE_SKYBEAM, TRIGGERED_OLD_TRIGGERED); m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; case NPC_FREYA_WARD_VEHICLE: summoned->CastSpell(summoned, SPELL_BIRTH, TRIGGERED_OLD_TRIGGERED); summoned->CastSpell(summoned, SPELL_BEAM_TARGET_STATE, TRIGGERED_OLD_TRIGGERED); + summoned->CastSpell(summoned, 50195, TRIGGERED_OLD_TRIGGERED); // Hackfix for reticles until hovering is properly implemented summoned->CastSpell(summoned, SPELL_GREEN_SKYBEAM, TRIGGERED_OLD_TRIGGERED); m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); break; @@ -382,7 +386,7 @@ struct boss_flame_leviathanAI : public BossAI return; // set boss in combat (if not already) - m_creature->SetInCombatWithZone(); + m_creature->SetInCombatWithZone(false); } void HandleHardmode() @@ -523,7 +527,7 @@ struct boss_flame_leviathanAI : public BossAI { float fX, fY, fZ; m_creature->GetRandomPoint(orbital->GetPositionX(), orbital->GetPositionY(), orbital->GetPositionZ(), 150.0f, fX, fY, fZ); - m_creature->SummonCreature(NPC_THORIM_HAMMER_VEHICLE, fX, fY, fZ, 0, TEMPSPAWN_TIMED_DESPAWN, 20000); + m_creature->SummonCreature(NPC_THORIM_HAMMER_VEHICLE, fX, fY, fZ + 1, 0, TEMPSPAWN_TIMED_DESPAWN, 8000); } } @@ -629,7 +633,7 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI if (Creature* pLeviathan = m_instance->GetSingleCreatureFromStorage(NPC_LEVIATHAN)) { if (Unit* target = pLeviathan->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - m_creature->GetMotionMaster()->MovePoint(1, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); + m_creature->GetMotionMaster()->MovePoint(1, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 1); } } m_uiTargetChaseTimer = 0; From 19c86ce01bff7a01f5cf05b0aa89e7fbf07be1ae Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 14:55:39 +0100 Subject: [PATCH 063/104] Ulduar: Increase Bubble visbility --- .../AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp | 1 + .../AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h | 1 + src/game/Entities/GameObject.cpp | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index bb16f5aa0bd..96a15752aa0 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -335,6 +335,7 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) // ----------------- Doors & Other ----------------- // The siege case GO_SHIELD_WALL: + case GO_PROTECTIVE_BUBBLE: break; case GO_LIGHTNING_DOOR: if (m_auiEncounter[TYPE_LEVIATHAN] == SPECIAL || m_auiEncounter[TYPE_LEVIATHAN] == FAIL) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h index 9976329212f..499900d3e51 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h @@ -280,6 +280,7 @@ enum // Doors and other Objects // The siege + GO_PROTECTIVE_BUBBLE = 194484, GO_SHIELD_WALL = 194416, // Gate before Leviathan GO_LIGHTNING_DOOR = 194905, // Lightning gate after the Leviathan. It closes after the boss enters the arena GO_LEVIATHAN_GATE = 194630, // Gate after Leviathan -> this will be broken when the boss enters the arena diff --git a/src/game/Entities/GameObject.cpp b/src/game/Entities/GameObject.cpp index db2e69a8d74..df8042ed1e7 100644 --- a/src/game/Entities/GameObject.cpp +++ b/src/game/Entities/GameObject.cpp @@ -305,6 +305,8 @@ bool GameObject::Create(uint32 dbGuid, uint32 guidlow, uint32 name_id, Map* map, if (GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) GetVisibilityData().SetVisibilityDistanceOverride(VisibilityDistanceType::Infinite); + if (GetGOInfo()->id == 194484) + GetVisibilityData().SetVisibilityDistanceOverride(VisibilityDistanceType::Gigantic); return true; } From e290b665a2246e80b08393b35d2b077c0d9af6df Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 17:06:46 +0100 Subject: [PATCH 064/104] Ulduar: Fix Freya's Ward spawn (Levi) --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index ab8c11be0e8..f1887999bf8 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -604,7 +604,7 @@ struct npc_hodir_fury_reticleAI : public ScriptedAI void JustSummoned(Creature* summoned) override { if (summoned->GetEntry() == NPC_HODIR_FURY) - m_hodirFuryGuid = summoned->GetObjectGuid(); + m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); } void MovementInform(uint32 moveType, uint32 pointId) override @@ -682,14 +682,20 @@ struct npc_freya_wardAI : public Scripted_NoMovementAI { if (summoned->GetEntry() == NPC_WRITHING_LASHER || summoned->GetEntry() == NPC_WARD_OF_LIFE) summoned->SetInCombatWithZone(false); + m_creature->AddSummonForOnDeathDespawn(summoned->GetObjectGuid()); } void UpdateAI(const uint32 diff) override { if (m_uiFreyaWardTimer < diff) { - if (DoCastSpellIfCan(nullptr, SPELL_FREYA_WARD) == CAST_OK) - m_uiFreyaWardTimer = 30000; + if (m_creature->IsBoarded()) + { + Unit* vehicle = dynamic_cast(m_creature->GetTransportInfo()->GetTransport()); + if (vehicle && vehicle->GetVehicleInfo()) + if (DoCastSpellIfCan(vehicle, SPELL_FREYA_WARD) == CAST_OK) + m_uiFreyaWardTimer = 30000; + } } else m_uiFreyaWardTimer -= diff; From 2a006f9a83b34b2256488ce6213d9911d6513236 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 17:24:52 +0100 Subject: [PATCH 065/104] Ulduar: Improve Hookshot Aura and Shutdown BCT --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index f1887999bf8..da11bc262ba 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1083,6 +1083,8 @@ struct Hookshot : public SpellScript return true; if (caster->GetPosition().GetDistance(target->GetPosition()) > 30.f * 30.f) return false; + if (target->HasAura(SPELL_SYSTEMS_SHUTDOWN)) + return false; caster->RemoveAurasByCasterSpell(SPELL_HOOKSHOT_AURA, caster->GetObjectGuid()); return true; } @@ -1184,9 +1186,9 @@ struct SystemsShutdown : public AuraScript target->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED); switch (urand(0,2)) { - case 0: DoBroadcastText(SAY_OVERLOAD_1, target); - case 1: DoBroadcastText(SAY_OVERLOAD_2, target); - case 2: DoBroadcastText(SAY_OVERLOAD_3, target); + case 0: DoBroadcastText(SAY_OVERLOAD_1, target); break; + case 1: DoBroadcastText(SAY_OVERLOAD_2, target); break; + case 2: DoBroadcastText(SAY_OVERLOAD_3, target); break; } return; } From 5c929d18c8ed705598e7a4a343a62150c5840bd0 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 17 Feb 2023 17:25:22 +0100 Subject: [PATCH 066/104] Leviathan: Update SD2 comment --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index da11bc262ba..5a6c1a000bc 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_flame_leviathan -SD%Complete: 75% -SDComment: Defense turret AI and related event NYI. +SD%Complete: 100% +SDComment: SDCategory: Ulduar EndScriptData */ From 99a042ef610530a54bfdae2196e6a43f3a441f05 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 18 Feb 2023 14:14:33 +0100 Subject: [PATCH 067/104] Ulduar: Improve Salvaged Chopper --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 59 +++++++++++++++++-- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 5a6c1a000bc..9eeb5855259 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -743,15 +743,11 @@ struct npc_liquid_pyriteAI : public Scripted_NoMovementAI Unit* vehicle = dynamic_cast(m_creature->GetTransportInfo()->GetTransport()); if (!vehicle) return; - if (vehicle->GetEntry() == NPC_SALVAGED_DEMOLISHER) + if (vehicle->GetEntry() == 33167 || vehicle->GetEntry() == NPC_SALVAGED_DEMOLISHER) { m_creature->CastSpell(vehicle, SPELL_LIQUID_PYRITE, TRIGGERED_OLD_TRIGGERED); m_creature->ForcedDespawn(3000); } - else if (vehicle->GetEntry() == NPC_SALVAGED_CHOPPER) - { - vehicle->CastSpell(nullptr, 69748, TRIGGERED_OLD_TRIGGERED); - } }); Reset(); } @@ -832,6 +828,54 @@ struct npc_salvaged_demolisherAI : public CombatAI } }; +struct npc_salvaged_chopperAI : public CombatAI +{ + npc_salvaged_chopperAI(Creature* creature) : CombatAI(creature, 0) + { + SetCombatMovement(false); + m_creature->SetCanEnterCombat(false); +#ifdef PRENERF_3_1 + m_creature->UpdateSpell(3, 0); +#endif + } + + void PassengerBoarded(Unit* passenger, uint8 seat) override + { + if (!seat) + return; + m_creature->CastSpell(nullptr, 69748, TRIGGERED_OLD_TRIGGERED); + m_creature->SetSpellList(3306201); +#ifdef PRENERF_3_1 + m_creature->UpdateSpell(3, 0); +#endif + + Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); + if (!driver) + return; + CharmInfo* charmInfo = m_creature->InitCharmInfo(m_creature); + charmInfo->InitVehicleCreateSpells(); + driver->VehicleSpellInitialize(); + } + + void PassengerUnboarded(Unit* passenger, uint8 seat) override + { + if (!seat) + return; + m_creature->CastSpell(nullptr, 67395, TRIGGERED_OLD_TRIGGERED); + m_creature->SetSpellList(3306200); +#ifdef PRENERF_3_1 + m_creature->UpdateSpell(3, 0); +#endif + + Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); + if (!driver) + return; + CharmInfo* charmInfo = m_creature->InitCharmInfo(m_creature); + charmInfo->InitVehicleCreateSpells(); + driver->VehicleSpellInitialize(); + } +}; + enum DefenseTurretActions { DEFENSE_TURRET_RANGE_CHECK, @@ -1416,6 +1460,11 @@ void AddSC_boss_flame_leviathan() pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "npc_salvaged_chopper"; + pNewScript->GetAI = &GetNewAIInstance; + pNewScript->RegisterSelf(); + RegisterSpellScript("spell_pursue_leviathan"); RegisterSpellScript("spell_hodirs_fury_leviathan"); RegisterSpellScript("spell_thorims_hammer_leviathan"); From eb42a7af443636a681233ce5acfaf5745738b2cd Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 18 Feb 2023 16:37:42 +0100 Subject: [PATCH 068/104] Ulduar: Cleanup in Leviathan code --- .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 9eeb5855259..eeef0419ef6 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -114,6 +114,8 @@ enum SPELL_LIQUID_PYRITE_AURA = 62494, SPELL_LIQUID_PYRITE = 62496, SPELL_RELOAD_AMMMO = 62473, + SPELL_GENERAL_TRIGGER_1_FROM_PSG_2 = 69748, + SPELL_GENERAL_TRIGGER_2_TO_SELF = 67395, // vehicle accessories //NPC_LEVIATHAN_SEAT = 33114, @@ -843,12 +845,11 @@ struct npc_salvaged_chopperAI : public CombatAI { if (!seat) return; - m_creature->CastSpell(nullptr, 69748, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(nullptr, SPELL_GENERAL_TRIGGER_1_FROM_PSG_2, TRIGGERED_OLD_TRIGGERED); m_creature->SetSpellList(3306201); #ifdef PRENERF_3_1 m_creature->UpdateSpell(3, 0); #endif - Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); if (!driver) return; @@ -861,12 +862,10 @@ struct npc_salvaged_chopperAI : public CombatAI { if (!seat) return; - m_creature->CastSpell(nullptr, 67395, TRIGGERED_OLD_TRIGGERED); m_creature->SetSpellList(3306200); #ifdef PRENERF_3_1 m_creature->UpdateSpell(3, 0); #endif - Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); if (!driver) return; From 619431584e5ca5fa56e771814c724f648a77ab25 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 18 Feb 2023 17:51:20 +0100 Subject: [PATCH 069/104] Ulduar: Simplify Chopper code slightly --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index eeef0419ef6..4a09daed587 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -116,6 +116,8 @@ enum SPELL_RELOAD_AMMMO = 62473, SPELL_GENERAL_TRIGGER_1_FROM_PSG_2 = 69748, SPELL_GENERAL_TRIGGER_2_TO_SELF = 67395, + SPELL_GRAB_PYRITE = 67372, + SPELL_EJECT_PASSENGER = 67393, // vehicle accessories //NPC_LEVIATHAN_SEAT = 33114, @@ -836,7 +838,7 @@ struct npc_salvaged_chopperAI : public CombatAI { SetCombatMovement(false); m_creature->SetCanEnterCombat(false); -#ifdef PRENERF_3_1 +#ifdef PRENERF_3_4_1 m_creature->UpdateSpell(3, 0); #endif } @@ -846,15 +848,15 @@ struct npc_salvaged_chopperAI : public CombatAI if (!seat) return; m_creature->CastSpell(nullptr, SPELL_GENERAL_TRIGGER_1_FROM_PSG_2, TRIGGERED_OLD_TRIGGERED); - m_creature->SetSpellList(3306201); -#ifdef PRENERF_3_1 + m_creature->UpdateSpell(3, SPELL_EJECT_PASSENGER); +#ifdef PRENERF_3_4_1 m_creature->UpdateSpell(3, 0); #endif Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); if (!driver) return; CharmInfo* charmInfo = m_creature->InitCharmInfo(m_creature); - charmInfo->InitVehicleCreateSpells(); + charmInfo->InitVehicleCreateSpells(); driver->VehicleSpellInitialize(); } @@ -862,15 +864,15 @@ struct npc_salvaged_chopperAI : public CombatAI { if (!seat) return; - m_creature->SetSpellList(3306200); -#ifdef PRENERF_3_1 + m_creature->UpdateSpell(3, SPELL_GRAB_PYRITE); +#ifdef PRENERF_3_4_1 m_creature->UpdateSpell(3, 0); #endif Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); if (!driver) return; CharmInfo* charmInfo = m_creature->InitCharmInfo(m_creature); - charmInfo->InitVehicleCreateSpells(); + charmInfo->InitVehicleCreateSpells(); driver->VehicleSpellInitialize(); } }; From 831429f18086d84fd472db3deef5e24389f6e2bc Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 19 Feb 2023 12:10:47 +0100 Subject: [PATCH 070/104] Ulduar: Temporarily disable trigger spell --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 4a09daed587..cd757b98b19 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -847,7 +847,7 @@ struct npc_salvaged_chopperAI : public CombatAI { if (!seat) return; - m_creature->CastSpell(nullptr, SPELL_GENERAL_TRIGGER_1_FROM_PSG_2, TRIGGERED_OLD_TRIGGERED); + //m_creature->CastSpell(nullptr, SPELL_GENERAL_TRIGGER_1_FROM_PSG_2, TRIGGERED_OLD_TRIGGERED); m_creature->UpdateSpell(3, SPELL_EJECT_PASSENGER); #ifdef PRENERF_3_4_1 m_creature->UpdateSpell(3, 0); From 6a543defb9df085bc640d623676bb37823ac5b93 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 19 Feb 2023 18:12:50 +0100 Subject: [PATCH 071/104] Ulduar: Use new vehicle hooks --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index cd757b98b19..c0b577fc01b 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -843,37 +843,33 @@ struct npc_salvaged_chopperAI : public CombatAI #endif } - void PassengerBoarded(Unit* passenger, uint8 seat) override + void OnPassengerRide(Unit* passenger, bool boarded, uint8 seat) override { - if (!seat) - return; - //m_creature->CastSpell(nullptr, SPELL_GENERAL_TRIGGER_1_FROM_PSG_2, TRIGGERED_OLD_TRIGGERED); - m_creature->UpdateSpell(3, SPELL_EJECT_PASSENGER); -#ifdef PRENERF_3_4_1 - m_creature->UpdateSpell(3, 0); -#endif Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); if (!driver) return; - CharmInfo* charmInfo = m_creature->InitCharmInfo(m_creature); - charmInfo->InitVehicleCreateSpells(); - driver->VehicleSpellInitialize(); - } - - void PassengerUnboarded(Unit* passenger, uint8 seat) override - { if (!seat) return; - m_creature->UpdateSpell(3, SPELL_GRAB_PYRITE); + CharmInfo* charmInfo = m_creature->InitCharmInfo(m_creature); + if (boarded) + { + //m_creature->CastSpell(nullptr, SPELL_GENERAL_TRIGGER_1_FROM_PSG_2, TRIGGERED_OLD_TRIGGERED); + m_creature->UpdateSpell(3, SPELL_EJECT_PASSENGER); #ifdef PRENERF_3_4_1 - m_creature->UpdateSpell(3, 0); + m_creature->UpdateSpell(3, 0); #endif - Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); - if (!driver) - return; - CharmInfo* charmInfo = m_creature->InitCharmInfo(m_creature); - charmInfo->InitVehicleCreateSpells(); - driver->VehicleSpellInitialize(); + charmInfo->InitVehicleCreateSpells(); + driver->VehicleSpellInitialize(); + } + else + { + m_creature->UpdateSpell(3, SPELL_GRAB_PYRITE); +#ifdef PRENERF_3_4_1 + m_creature->UpdateSpell(3, 0); +#endif + charmInfo->InitVehicleCreateSpells(); + driver->VehicleSpellInitialize(); + } } }; From 270f9d9d11a4c4a1524b687404583c895810438b Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 08:33:07 +0200 Subject: [PATCH 072/104] Respect Knockback Immunity --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 2 ++ src/game/Spells/SpellEffects.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index c0b577fc01b..05d0dc09a45 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -23,6 +23,7 @@ EndScriptData */ #include "AI/ScriptDevAI/include/sc_common.h" #include "Spells/Scripts/SpellScript.h" +#include "Spells/SpellEffectDefines.h" #include "ulduar.h" #include "AI/ScriptDevAI/base/BossAI.h" #include "Entities/Vehicle.h" @@ -223,6 +224,7 @@ struct boss_flame_leviathanAI : public BossAI { return x < 148; }); + m_creature->ApplySpellImmune(nullptr, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); } instance_ulduar* m_instance; diff --git a/src/game/Spells/SpellEffects.cpp b/src/game/Spells/SpellEffects.cpp index 08f578ebcff..0a50f771c2a 100644 --- a/src/game/Spells/SpellEffects.cpp +++ b/src/game/Spells/SpellEffects.cpp @@ -11720,7 +11720,7 @@ void Spell::EffectKnockBack(SpellEffectIndex eff_idx) return; if (Creature* creatureTarget = dynamic_cast(unitTarget)) - if (creatureTarget->GetCreatureInfo()->Rank == 3) + if (creatureTarget->IsImmuneToSpellEffect(m_spellInfo, eff_idx, false)) return; switch (m_spellInfo->Id) From 028af4354e05bc33e060b1bc7fa9169ca97c3ea3 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 08:40:39 +0200 Subject: [PATCH 073/104] Spell: Handle Knockback immunity in boss script --- src/game/Spells/SpellEffects.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/game/Spells/SpellEffects.cpp b/src/game/Spells/SpellEffects.cpp index 0a50f771c2a..91f1faf8a15 100644 --- a/src/game/Spells/SpellEffects.cpp +++ b/src/game/Spells/SpellEffects.cpp @@ -11719,10 +11719,6 @@ void Spell::EffectKnockBack(SpellEffectIndex eff_idx) if (!unitTarget) return; - if (Creature* creatureTarget = dynamic_cast(unitTarget)) - if (creatureTarget->IsImmuneToSpellEffect(m_spellInfo, eff_idx, false)) - return; - switch (m_spellInfo->Id) { case 36812: // Soaring - Test Flight quests From fa5a675c2c50c7de9bb228df6c4ba60352bcccaa Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 08:46:31 +0200 Subject: [PATCH 074/104] Vehicles: Ensure vehicle attachments stay attached --- src/game/Entities/Unit.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/game/Entities/Unit.cpp b/src/game/Entities/Unit.cpp index 015778193e1..9fbd0e6d02f 100644 --- a/src/game/Entities/Unit.cpp +++ b/src/game/Entities/Unit.cpp @@ -9185,6 +9185,12 @@ bool Unit::IsVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo if (m_Visibility == VISIBILITY_REMOVE_CORPSE) return false; + if (this->IsBoarded()) + if (Unit* vehicle = dynamic_cast(this->GetTransportInfo()->GetTransport())) + if (Player* player = const_cast(dynamic_cast(u))) + if (!player->HasAtClient(vehicle)) + return false; + Map& _map = *u->GetMap(); // Grid dead/alive checks if (u->GetTypeId() == TYPEID_PLAYER) From 3ec691d1788286a2622b38c79c48ca99eae7db76 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 17:26:50 +0200 Subject: [PATCH 075/104] Ulduar: Use BossAI door controls for Leviathan --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 14 +++----------- .../scripts/northrend/ulduar/ulduar/ulduar.cpp | 8 -------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 05d0dc09a45..88f1f57d784 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -210,8 +210,10 @@ struct boss_flame_leviathanAI : public BossAI AddTimerlessCombatAction(LEVIATHAN_FETCH_TOWERS, true); AddCombatAction(LEVIATHAN_HARDMODES, 10s); AddCombatAction(LEVIATHAN_THORIMS_HAMMER, true); + AddEntranceObject(GO_SHIELD_WALL); + AddExitObject(GO_LIGHTNING_DOOR, GO_XT002_GATE); + SetGateDelay(5s); Reset(); - m_creature->SetActiveObjectState(true); AddCustomAction(LEVIATHAN_RESET_OVERLOAD, true, [&]() { Aura* aura = m_creature->GetAura(SPELL_OVERLOAD_CIRCUIT, EFFECT_INDEX_1); @@ -247,16 +249,6 @@ struct boss_flame_leviathanAI : public BossAI m_hardmodeStep = 0; m_thorimsHammerCount = 0; - - CreatureList leviAdds; - for (const uint32& entry : addEntries) - { - GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 50.f); - for (auto& add : leviAdds) - { - add->SetActiveObjectState(true); - } - } } void JustDied(Unit* /*killer*/) override diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index 96a15752aa0..0b632271e45 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -524,18 +524,10 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) { // make sure that the Lightning door is closed when engaged in combat DoUseOpenableObject(GO_LIGHTNING_DOOR, false); - DoUseOpenableObject(GO_SHIELD_WALL, false); SetSpecialAchievementCriteria(TYPE_ACHIEV_SHUTOUT, true); } - else if (uiData == DONE) - { - DoUseOpenableObject(GO_XT002_GATE, true); - DoUseOpenableObject(GO_LIGHTNING_DOOR, true); - DoUseOpenableObject(GO_SHIELD_WALL, true); - } else if (uiData == FAIL) { - DoUseOpenableObject(GO_SHIELD_WALL, true); DoCallLeviathanHelp(); } break; From de5587dc1bb0c6cea796e0a8b122012b2ddff28d Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 19:29:29 +0200 Subject: [PATCH 076/104] Spells: Allow secondary target checking for area auras --- src/game/Grids/GridNotifiersImpl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/Grids/GridNotifiersImpl.h b/src/game/Grids/GridNotifiersImpl.h index 685b9211554..71c875abde7 100644 --- a/src/game/Grids/GridNotifiersImpl.h +++ b/src/game/Grids/GridNotifiersImpl.h @@ -287,6 +287,8 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) if (!holder->GetAuraByEffectIndex(eff_index)) { PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, &i_dynobject.GetDamage(), &i_dynobject.GetBasePoints(), holder, target, caster); + if (!i_dynobject.OnAreaAuraCheckTarget(Aur, target)) + return; holder->AddAura(Aur, eff_index); target->AddAuraToModList(Aur); Aur->ApplyModifier(true, true); @@ -301,6 +303,8 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) { holder = CreateSpellAuraHolder(spellInfo, target, caster); PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, &i_dynobject.GetDamage(), &i_dynobject.GetBasePoints(), holder, target, caster); + if (!i_dynobject.OnAreaAuraCheckTarget(Aur, target)) + return; holder->SetAuraDuration(i_dynobject.GetDuration()); holder->AddAura(Aur, eff_index); if (!target->AddSpellAuraHolder(holder)) From a96257c210316ea8fbd7215f1db074dd38353480 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 19:29:39 +0200 Subject: [PATCH 077/104] Fix Mimiron's Fury --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 1 + .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 10 ++++++---- src/game/Spells/SpellMgr.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index b2934f60ebc..e54f5c4104f 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -96,6 +96,7 @@ void BossAI::AddExitObject(uint32 value) void BossAI::EnterEvadeMode() { + OpenEntrances(); if (m_instanceDataType == -1) return; if (ScriptedInstance* instance = static_cast(m_creature->GetInstanceData())) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 88f1f57d784..bd1b796c070 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1016,17 +1016,19 @@ struct ThorimsHammerLeviathan : public SpellScript }; // 62910 Mimiron's Inferno -struct MimironsInfernoLeviathan : public SpellScript +struct MimironsInfernoLeviathan : public SpellScript, public AuraScript { - bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override + bool OnAreaAuraCheckTarget(Aura* aura, Unit* target) const override { if (!target) - return true; - Unit* caster = spell->GetCaster(); + return false; + Unit* caster = aura->GetCaster(); if (!caster) return false; if (caster->IsFriend(target)) + { return false; + } if (!target->IsPlayer() && !target->IsControlledByPlayer()) return false; return true; diff --git a/src/game/Spells/SpellMgr.h b/src/game/Spells/SpellMgr.h index ac82f335104..46b4795833d 100644 --- a/src/game/Spells/SpellMgr.h +++ b/src/game/Spells/SpellMgr.h @@ -1470,6 +1470,7 @@ inline bool IsPositiveEffect(const SpellEntry* spellproto, SpellEffectIndex effI case 37962: case 37968: case 35734: // Dropping Phase Disruptor + case 62910: return false; } From 1b9ab9c33b90716f28a3f70175c74639df2685f9 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 19:29:29 +0200 Subject: [PATCH 078/104] Spells: Allow secondary target checking for area auras --- src/game/Grids/GridNotifiersImpl.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/game/Grids/GridNotifiersImpl.h b/src/game/Grids/GridNotifiersImpl.h index 71c875abde7..685b9211554 100644 --- a/src/game/Grids/GridNotifiersImpl.h +++ b/src/game/Grids/GridNotifiersImpl.h @@ -287,8 +287,6 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) if (!holder->GetAuraByEffectIndex(eff_index)) { PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, &i_dynobject.GetDamage(), &i_dynobject.GetBasePoints(), holder, target, caster); - if (!i_dynobject.OnAreaAuraCheckTarget(Aur, target)) - return; holder->AddAura(Aur, eff_index); target->AddAuraToModList(Aur); Aur->ApplyModifier(true, true); @@ -303,8 +301,6 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) { holder = CreateSpellAuraHolder(spellInfo, target, caster); PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, &i_dynobject.GetDamage(), &i_dynobject.GetBasePoints(), holder, target, caster); - if (!i_dynobject.OnAreaAuraCheckTarget(Aur, target)) - return; holder->SetAuraDuration(i_dynobject.GetDuration()); holder->AddAura(Aur, eff_index); if (!target->AddSpellAuraHolder(holder)) From 26c301edc3804d0440e2a260064da28c1ef4f0c8 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 17 Jun 2023 20:46:45 +0200 Subject: [PATCH 079/104] Ulduar: Fix AreaAuraCheck for Leviathan --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index bd1b796c070..5c5f82b6af1 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -22,6 +22,7 @@ SDCategory: Ulduar EndScriptData */ #include "AI/ScriptDevAI/include/sc_common.h" +#include "Maps/GridDefines.h" #include "Spells/Scripts/SpellScript.h" #include "Spells/SpellEffectDefines.h" #include "ulduar.h" @@ -1018,11 +1019,11 @@ struct ThorimsHammerLeviathan : public SpellScript // 62910 Mimiron's Inferno struct MimironsInfernoLeviathan : public SpellScript, public AuraScript { - bool OnAreaAuraCheckTarget(Aura* aura, Unit* target) const override + bool OnAreaAuraCheckTarget(DynamicObject* dynGo, Unit* target) const override { if (!target) return false; - Unit* caster = aura->GetCaster(); + Unit* caster = dynGo->GetCaster(); if (!caster) return false; if (caster->IsFriend(target)) From 49f8429660f56915cb663c649dad6e54c7812923 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 4 Aug 2023 22:29:33 +0200 Subject: [PATCH 080/104] Vehicles: Allow switching between vehicles from within vehicles --- src/game/Entities/Vehicle.cpp | 2 ++ src/game/Spells/Spell.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index 6d8ab941405..b8f8aa22a5d 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -994,6 +994,8 @@ void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) pVehicle->AI()->SetReactState(REACT_AGGRESSIVE); } + + pVehicle->SetTarget(nullptr); } // must be called after movement control unapplying diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index 311c149d718..cad941d8c32 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -6994,7 +6994,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_BAD_TARGETS; // It is possible to change between vehicles that are boarded on each other - if (m_caster->IsBoarded() && m_caster->GetTransportInfo()->IsOnVehicle()) + /*if (m_caster->IsBoarded() && m_caster->GetTransportInfo()->IsOnVehicle()) { // Check if trying to board a vehicle that is boarded on current transport bool boardedOnEachOther = m_caster->GetTransportInfo()->HasOnBoard(expectedTarget); @@ -7004,7 +7004,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (!boardedOnEachOther) return SPELL_FAILED_NOT_ON_TRANSPORT; - } + }*/ if (!expectedTarget->GetVehicleInfo()->CanBoard(m_caster)) return SPELL_FAILED_BAD_TARGETS; From f409f4935bbfde6e86f70561ac8c557367dfd598 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 4 Aug 2023 22:40:14 +0200 Subject: [PATCH 081/104] Spells: Add Spellscripts to spell.sql --- sql/scriptdev2/spell.sql | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index 33485eef19a..49709018ac1 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -935,6 +935,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (60775,'spell_increased_spell_damage_done_dummy'), (60779,'spell_increased_healing_done_dummy'), (60831,'spell_alumeths_remains'), +(60603,'spell_eject_passenger_1'), (60929,'spell_loatheb_prewarn'), (61071,'spell_vortex_aura'), (61072,'spell_vortex_aura'), @@ -944,6 +945,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (61187,'spell_twilight_shift_aura'), (61190,'spell_twilight_shift_aura'), (61210,'spell_align_disk_aggro'), +(61242,'spell_parachute_leviathan'), (61474,'spell_grip_of_sladran'), (61475,'spell_gundrak_snake_wrap'), (61546,'spell_shatter'), @@ -953,11 +955,16 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (62116,'spell_tails_up_summon_female_icepaw_bear'), (62138,'spell_teleport_inside_violet_hold'), (62297,'spell_hodirs_fury_leviathan'), +(62323,'spell_hookshot'), +(62324,'spell_throw_passenger'), (62907,'spell_freyas_ward_leviathan'), (62910,'spell_mimirons_inferno_leviathan'), (62912,'spell_thorims_hammer_leviathan'), +(62336,'spell_hookshot_aura'), (62374,'spell_pursue_leviathan'), (62382,'spell_ignis_brittle'), +(62399,'spell_overload_circuit'), +(62475,'spell_systems_shutdown'), (62789,'spell_heart_overload'), (62826,'spell_energy_orb_dummy'), (62828,'spell_recharge_robot'), @@ -972,6 +979,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (62717,'spell_slag_pot'), (63474,'spell_ignis_scorch'), (63482,'spell_lightning_whirl_heroic'), +(63575,'spell_smoke_trail_leviathan'), (63618,'spell_overload_leviathan'), (63845,'spell_create_lance'), (64203,'spell_void_zone_xt'), @@ -979,6 +987,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (64210,'spell_life_spark_xt'), (64234,'spell_gravity_bomb'), (64235,'spell_void_zone_xt'), +(64414,'spell_load_into_catapult_leviathan'), (64411,'spell_blessing_of_ancient_kings'), (64415,'spell_valanyr_equip_effect'), (64475,'spell_ignis_remove_strength'), From dd390cca47bfc26029eca6a1ea2a9e500cd12c28 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 27 Oct 2023 22:45:22 +0200 Subject: [PATCH 082/104] BossAI: Minor Leviathan touchups --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 50 ++++++++++++++++--- .../scripts/northrend/ulduar/ulduar/ulduar.h | 2 + 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 5c5f82b6af1..cc0d1cd323c 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -77,7 +77,7 @@ enum // leviathan other spells SPELL_SMOKE_TRAIL = 63575, SPELL_EJECT_ALL_PASSENGERS = 50630, // used by vehicles on death; currently handled by DB linking - // SPELL_EJECT_PASSENGER_4 = 64614, + SPELL_EJECT_PASSENGER_4 = 64614, SPELL_EJECT_PASSENGER_1 = 60603, SPELL_LOAD_INTO_CATAPULT = 64414, SPELL_PASSENGER_LOADED = 62340, @@ -121,6 +121,13 @@ enum SPELL_GRAB_PYRITE = 67372, SPELL_EJECT_PASSENGER = 67393, + // gauntlet spells + SPELL_DUSTY_EXPLOSION = 63360, + SPELL_DUST_CLOUD_IMPACT = 54740, + SPELL_SPAWN_PYRITE = 62543, + SPELL_COSMETIC_PARACHITE = 56093, + SPELL_ROPE_BEAM = 63605, + // vehicle accessories //NPC_LEVIATHAN_SEAT = 33114, NPC_LEVIATHAN_TURRET = 33139, @@ -184,6 +191,7 @@ static const float afHodirFury[MAX_HODIR_FURY][3] = static const float afMimironInferno[3] = {329.1809f, 8.02577f, 410.887f}; static const std::vector addEntries = {NPC_LEVIATHAN_SEAT, NPC_LEVIATHAN_TURRET, NPC_DEFENSE_TURRET, NPC_OVERLOAD_DEVICE}; +static const std::vector playerVehicleEntries = {NPC_SALVAGED_SIEGE_ENGINE, NPC_SALVAGED_SIEGE_TURRET, NPC_SALVAGED_CHOPPER, NPC_SALVAGED_DEMOLISHER, NPC_SALVAGED_DEMOLISHER_SEAT}; /*###### ## boss_flame_leviathan @@ -275,6 +283,32 @@ struct boss_flame_leviathanAI : public BossAI } } + CreatureList playerVehicles; + for (const uint32& entry : playerVehicleEntries) + { + GetCreatureListWithEntryInGrid(playerVehicles, m_creature, entry, 1000.f); // probably very expensive. better solution? + for (auto* add : playerVehicles) + { + if (!add || !add->IsAlive()) + continue; + switch (add->GetEntry()) + { + case NPC_SALVAGED_SIEGE_ENGINE: + case NPC_SALVAGED_CHOPPER: + add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1, TRIGGERED_OLD_TRIGGERED); + break; + case NPC_SALVAGED_DEMOLISHER: + add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_4, TRIGGERED_OLD_TRIGGERED); + break; + case NPC_SALVAGED_SIEGE_TURRET: + case NPC_SALVAGED_DEMOLISHER_SEAT: + add->CastSpell(nullptr, SPELL_EJECT_ALL_PASSENGERS, TRIGGERED_OLD_TRIGGERED); + break; + default: break; + } + } + } + // start epilogue event if (Creature* pFlyMachine = m_creature->SummonCreature(NPC_BRANN_FLYING_MACHINE, 175.2838f, -210.4325f, 501.2375f, 1.42f, TEMPSPAWN_CORPSE_DESPAWN, 0)) { @@ -757,7 +791,7 @@ struct npc_liquid_pyriteAI : public Scripted_NoMovementAI DoCastSpellIfCan(m_creature, SPELL_LIQUID_PYRITE_AURA, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT); } - void MovementInform(uint32 motionType, uint32 /*value*/) + void MovementInform(uint32 motionType, uint32 /*value*/) override { if (motionType != BOARD_VEHICLE_MOTION_TYPE) return; @@ -774,7 +808,7 @@ struct npc_pyrite_safety_containerAI : public Scripted_NoMovementAI Creature* lift = dynamic_cast(m_creature->GetSpawner()); if (!lift) return; - m_creature->CastSpell(lift, 63605, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(lift, SPELL_ROPE_BEAM, TRIGGERED_OLD_TRIGGERED); }); AddCustomAction(1, true, [&]() { @@ -784,9 +818,9 @@ struct npc_pyrite_safety_containerAI : public Scripted_NoMovementAI ResetTimer(1, 500ms); return; } - m_creature->CastSpell(nullptr, 63360, TRIGGERED_OLD_TRIGGERED); - m_creature->CastSpell(nullptr, 54740, TRIGGERED_OLD_TRIGGERED); - m_creature->CastSpell(nullptr, 62543, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(nullptr, SPELL_DUSTY_EXPLOSION, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(nullptr, SPELL_DUST_CLOUD_IMPACT, TRIGGERED_OLD_TRIGGERED); + m_creature->CastSpell(nullptr, SPELL_SPAWN_PYRITE, TRIGGERED_OLD_TRIGGERED); m_creature->ForcedDespawn(1000); }); } @@ -1069,7 +1103,7 @@ struct ThrowPassenger : public SpellScript if (caster->GetVehicleInfo()) if (caster->GetVehicleInfo()->GetPassenger(3)) - if (seat = static_cast(caster->GetVehicleInfo()->GetPassenger(3))) + if ((seat = static_cast(caster->GetVehicleInfo()->GetPassenger(3)))) if (seat->IsVehicle()) projectile = seat->GetVehicleInfo()->GetPassenger(0); if (!projectile) @@ -1399,7 +1433,7 @@ struct RopeBeam : public AuraScript Unit* caster = aura->GetCaster(); if (!caster || caster->GetEntry() != 33218) return; - caster->CastSpell(nullptr, 56093, TRIGGERED_OLD_TRIGGERED); + caster->CastSpell(nullptr, SPELL_COSMETIC_PARACHITE, TRIGGERED_OLD_TRIGGERED); caster->GetMotionMaster()->MoveFall(); if (caster->AI()) caster->AI()->ResetTimer(1, 500ms); diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h index 499900d3e51..1194e5d7339 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h @@ -88,8 +88,10 @@ enum // NPC_HIRED_DEMOLITIONIST = 33627, // NPC_BATTLE_MAGE = 33662, NPC_SALVAGED_SIEGE_ENGINE = 33060, + NPC_SALVAGED_SIEGE_TURRET = 33067, NPC_SALVAGED_CHOPPER = 33062, NPC_SALVAGED_DEMOLISHER = 33109, + NPC_SALVAGED_DEMOLISHER_SEAT= 33167, // NPC_LIQUID_PYRITE = 33189, // Ignis adds From bf65c98e496700a9a3ac95540a076ecae4ff8455 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 28 Oct 2023 14:55:54 +0200 Subject: [PATCH 083/104] BossAI: prepare for rebase --- src/game/Entities/Unit.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/game/Entities/Unit.cpp b/src/game/Entities/Unit.cpp index 9fbd0e6d02f..015778193e1 100644 --- a/src/game/Entities/Unit.cpp +++ b/src/game/Entities/Unit.cpp @@ -9185,12 +9185,6 @@ bool Unit::IsVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo if (m_Visibility == VISIBILITY_REMOVE_CORPSE) return false; - if (this->IsBoarded()) - if (Unit* vehicle = dynamic_cast(this->GetTransportInfo()->GetTransport())) - if (Player* player = const_cast(dynamic_cast(u))) - if (!player->HasAtClient(vehicle)) - return false; - Map& _map = *u->GetMap(); // Grid dead/alive checks if (u->GetTypeId() == TYPEID_PLAYER) From 49cd2684d017900dfe093a46f966017a3afd2a79 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 28 Oct 2023 15:17:40 +0200 Subject: [PATCH 084/104] Leviathan: Use string_ids --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 68 +++++++++++-------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index cc0d1cd323c..00c8265fd05 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -270,45 +270,55 @@ struct boss_flame_leviathanAI : public BossAI orbital->RemoveAllAuras(); } - CreatureList leviAdds; - for (const uint32& entry : addEntries) - { - GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 50.f); - for (auto add : leviAdds) - { - if (add && (add->GetEntry() == NPC_DEFENSE_TURRET || add->GetEntry() == NPC_LEVIATHAN_TURRET || add->GetEntry() == NPC_LEVIATHAN_SEAT)) - add->Suicide(); - else if (add) - add->ForcedDespawn(); - } - } - - CreatureList playerVehicles; - for (const uint32& entry : playerVehicleEntries) + auto* LeviAdds = m_creature->GetMap()->GetCreatures("ULDUAR_FLAME_LEVIATHAN_PARTY"); + for (auto* leviPartyMember : *LeviAdds) { - GetCreatureListWithEntryInGrid(playerVehicles, m_creature, entry, 1000.f); // probably very expensive. better solution? - for (auto* add : playerVehicles) + if (leviPartyMember) { - if (!add || !add->IsAlive()) - continue; - switch (add->GetEntry()) + switch (leviPartyMember->GetEntry()) { - case NPC_SALVAGED_SIEGE_ENGINE: - case NPC_SALVAGED_CHOPPER: - add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1, TRIGGERED_OLD_TRIGGERED); - break; - case NPC_SALVAGED_DEMOLISHER: - add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_4, TRIGGERED_OLD_TRIGGERED); + case NPC_DEFENSE_TURRET: + case NPC_LEVIATHAN_TURRET: + case NPC_LEVIATHAN_SEAT: + { + if (leviPartyMember->IsAlive()) + leviPartyMember->Suicide(); break; - case NPC_SALVAGED_SIEGE_TURRET: - case NPC_SALVAGED_DEMOLISHER_SEAT: - add->CastSpell(nullptr, SPELL_EJECT_ALL_PASSENGERS, TRIGGERED_OLD_TRIGGERED); + } + case NPC_OVERLOAD_DEVICE: + case NPC_ORBITAL_SUPPORT: + { + leviPartyMember->ForcedDespawn(); break; + } default: break; } } } + auto* playerVehicles = m_creature->GetMap()->GetCreatures("ULDUAR_PLAYER_VEHICLES"); + for (auto* add : *playerVehicles) + { + if (!add || !add->IsAlive()) + continue; + switch (add->GetEntry()) + { + case NPC_SALVAGED_SIEGE_ENGINE: + case NPC_SALVAGED_CHOPPER: + add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1, TRIGGERED_OLD_TRIGGERED); + break; + case NPC_SALVAGED_DEMOLISHER: + add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_4, TRIGGERED_OLD_TRIGGERED); + break; + case NPC_SALVAGED_SIEGE_TURRET: + case NPC_SALVAGED_DEMOLISHER_SEAT: + add->CastSpell(nullptr, SPELL_EJECT_ALL_PASSENGERS, TRIGGERED_OLD_TRIGGERED); + break; + default: break; + } + } + + // start epilogue event if (Creature* pFlyMachine = m_creature->SummonCreature(NPC_BRANN_FLYING_MACHINE, 175.2838f, -210.4325f, 501.2375f, 1.42f, TEMPSPAWN_CORPSE_DESPAWN, 0)) { From f21c920a036edd8c42d61b01fdd37a59eb147d2d Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 28 Oct 2023 15:36:26 +0200 Subject: [PATCH 085/104] BossAI: Only target Flame Leviathan and Friends for hardmode spell --- sql/scriptdev2/spell.sql | 4 ++++ .../ulduar/ulduar/boss_flame_leviathan.cpp | 22 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index 49709018ac1..f69bad6e88d 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -927,6 +927,9 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (59906,'spell_swift_hand_of_justice'), (59915,'spell_discerning_eye_of_the_beast'), (60079,'spell_fire_sgm3'), +(60075,'spell_flame_leviathan_buff'), +(60076,'spell_flame_leviathan_buff'), +(60077,'spell_flame_leviathan_buff'), (60211,'spell_cauterize'), (60528,'spell_rod_of_siphoning'), (60539,'spell_sapphiron_achievement_check'), @@ -991,6 +994,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (64411,'spell_blessing_of_ancient_kings'), (64415,'spell_valanyr_equip_effect'), (64475,'spell_ignis_remove_strength'), +(64482,'spell_flame_leviathan_buff'), (64503,'spell_ignis_water'), (64568,'spell_blood_reserve_enchant'), (65045,'spell_flames_leviathan'), diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 00c8265fd05..a69077be3ae 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -87,7 +87,7 @@ enum // tower buffs to Leviathan (applied on combat start if the towers are alive) SPELL_TOWER_OF_FROST = 65077, - // SPELL_TOWER_OF_FROST_DEBUFF = 65079, // removed by hotfix + SPELL_TOWER_OF_FROST_DEBUFF = 65079, // removed by hotfix SPELL_TOWER_OF_LIFE = 64482, SPELL_TOWER_OF_STORMS = 65076, SPELL_TOWER_OF_FLAMES = 65075, @@ -169,6 +169,10 @@ UPDATE vehicle_accessory SET seat=0 WHERE vehicle_entry IN (33364, 33369, 33108, TOWER_ID_FREYA = 1, TOWER_ID_MIMIRON = 2, TOWER_ID_THORIM = 3, + + // string_ids + ULDUAR_PLAYER_VEHICLES = 6030001, + ULDUAR_FLAME_LEVIATHAN_PARTY = 6030002, }; static const int32 leviathanTowerYell[KEEPER_ENCOUNTER] = { SAY_TOWER_FROST, SAY_TOWER_NATURE, SAY_TOWER_FIRE, SAY_TOWER_ENERGY }; @@ -270,7 +274,7 @@ struct boss_flame_leviathanAI : public BossAI orbital->RemoveAllAuras(); } - auto* LeviAdds = m_creature->GetMap()->GetCreatures("ULDUAR_FLAME_LEVIATHAN_PARTY"); + auto* LeviAdds = m_creature->GetMap()->GetCreatures(ULDUAR_FLAME_LEVIATHAN_PARTY); for (auto* leviPartyMember : *LeviAdds) { if (leviPartyMember) @@ -296,7 +300,7 @@ struct boss_flame_leviathanAI : public BossAI } } - auto* playerVehicles = m_creature->GetMap()->GetCreatures("ULDUAR_PLAYER_VEHICLES"); + auto* playerVehicles = m_creature->GetMap()->GetCreatures(ULDUAR_PLAYER_VEHICLES); for (auto* add : *playerVehicles) { if (!add || !add->IsAlive()) @@ -1450,6 +1454,17 @@ struct RopeBeam : public AuraScript } }; +// 65077 - Tower of Frost, 64482 - Tower of Life, 65076 - Tower of Storms, 65075 - Tower of Flames +struct FlameLeviathanBuff : public SpellScript +{ + bool OnCheckTarget(const Spell* /*spell*/, Unit* target, SpellEffectIndex /*eff*/) const + { + if (target && target->HasStringId(ULDUAR_FLAME_LEVIATHAN_PARTY)) + return true; + return false; + } +}; + void AddSC_boss_flame_leviathan() { Script* pNewScript = new Script; @@ -1523,4 +1538,5 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_ready_to_fly"); RegisterSpellScript("spell_anti_air_rocket"); RegisterSpellScript("spell_rope_beam"); + RegisterSpellScript("spell_flame_leviathan_buff"); } From 64c3d8591851d4a2f3902d2823d6a779ea0a590f Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 28 Oct 2023 21:39:43 +0200 Subject: [PATCH 086/104] BossAI: cleanup --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index a69077be3ae..493678e9ce1 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -275,7 +275,7 @@ struct boss_flame_leviathanAI : public BossAI } auto* LeviAdds = m_creature->GetMap()->GetCreatures(ULDUAR_FLAME_LEVIATHAN_PARTY); - for (auto* leviPartyMember : *LeviAdds) + for (Creature* leviPartyMember : *LeviAdds) { if (leviPartyMember) { @@ -292,6 +292,8 @@ struct boss_flame_leviathanAI : public BossAI case NPC_OVERLOAD_DEVICE: case NPC_ORBITAL_SUPPORT: { + if (leviPartyMember->IsAlive()) + leviPartyMember->Suicide(); leviPartyMember->ForcedDespawn(); break; } @@ -301,7 +303,7 @@ struct boss_flame_leviathanAI : public BossAI } auto* playerVehicles = m_creature->GetMap()->GetCreatures(ULDUAR_PLAYER_VEHICLES); - for (auto* add : *playerVehicles) + for (Creature* add : *playerVehicles) { if (!add || !add->IsAlive()) continue; @@ -312,6 +314,7 @@ struct boss_flame_leviathanAI : public BossAI add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1, TRIGGERED_OLD_TRIGGERED); break; case NPC_SALVAGED_DEMOLISHER: + add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1, TRIGGERED_OLD_TRIGGERED); add->CastSpell(nullptr, SPELL_EJECT_PASSENGER_4, TRIGGERED_OLD_TRIGGERED); break; case NPC_SALVAGED_SIEGE_TURRET: @@ -347,7 +350,7 @@ struct boss_flame_leviathanAI : public BossAI CreatureList leviAdds; for (const uint32& entry : addEntries) { - GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 50.f); + GetCreatureListWithEntryInGrid(leviAdds, m_creature, entry, 30.f); for (auto add : leviAdds) { if (add) @@ -1126,7 +1129,7 @@ struct ThrowPassenger : public SpellScript return; std::unordered_set spellIds; - for (auto aura : caster->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE)) + for (Aura* aura : caster->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE)) { if (aura->GetCasterGuid() == projectile->GetObjectGuid()) spellIds.emplace(aura->GetId()); @@ -1259,7 +1262,7 @@ struct SystemsShutdown : public AuraScript CreatureList leviAdds; for (const uint32& entry : addEntries) { - GetCreatureListWithEntryInGrid(leviAdds, target, entry, 50.f); + GetCreatureListWithEntryInGrid(leviAdds, target, entry, 30.f); for (auto add : leviAdds) { if (add) @@ -1280,7 +1283,7 @@ struct SystemsShutdown : public AuraScript } CreatureList leviSeats; GetCreatureListWithEntryInGrid(leviSeats, target, NPC_LEVIATHAN_SEAT, 50.f); - for (auto seat : leviSeats) + for (Creature* seat : leviSeats) { if (seat && seat->IsVehicle()) { @@ -1305,7 +1308,7 @@ struct EjectPassenger1 : public SpellScript return; std::unordered_set spellIds; - for (auto aura : target->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE)) + for (Aura* aura : target->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE)) { if (aura->GetCasterGuid() == passenger->GetObjectGuid()) spellIds.emplace(aura->GetId()); @@ -1357,8 +1360,8 @@ struct GrabPyrite : public SpellScript Unit* target = spell->GetUnitTarget(); if (!caster || !target) return; - if (auto transportInfo = caster->GetTransportInfo()) - if (auto vehicle = static_cast(transportInfo->GetTransport())) + if (TransportInfo* transportInfo = caster->GetTransportInfo()) + if (Unit* vehicle = static_cast(transportInfo->GetTransport())) { uint32 val = spell->m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_0); target->CastSpell(vehicle, val, TRIGGERED_OLD_TRIGGERED); From 12f1a3804da309a044588c0a5a60d2debb1cc427 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 12 Jan 2024 12:53:52 +0100 Subject: [PATCH 087/104] Ulduar: Fix OnAreaAuraCheckTarget invocation --- .../scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 493678e9ce1..5f59b30ae1d 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1070,11 +1070,11 @@ struct ThorimsHammerLeviathan : public SpellScript // 62910 Mimiron's Inferno struct MimironsInfernoLeviathan : public SpellScript, public AuraScript { - bool OnAreaAuraCheckTarget(DynamicObject* dynGo, Unit* target) const override + bool OnAreaAuraCheckTarget(Aura const* aura, Unit* target) const override { if (!target) return false; - Unit* caster = dynGo->GetCaster(); + Unit* caster = aura->GetCaster(); if (!caster) return false; if (caster->IsFriend(target)) From a34d3f1b5e021ac0e61f1092c9969ded10bb1b83 Mon Sep 17 00:00:00 2001 From: insunaa Date: Fri, 12 Jan 2024 13:30:27 +0100 Subject: [PATCH 088/104] Ulduar: Leviathan optimizations --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 5f59b30ae1d..4c97a772761 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -741,7 +741,7 @@ struct npc_freya_wardAI : public Scripted_NoMovementAI { if (m_creature->IsBoarded()) { - Unit* vehicle = dynamic_cast(m_creature->GetTransportInfo()->GetTransport()); + Unit* vehicle = static_cast(m_creature->GetTransportInfo()->GetTransport()); if (vehicle && vehicle->GetVehicleInfo()) if (DoCastSpellIfCan(vehicle, SPELL_FREYA_WARD) == CAST_OK) m_uiFreyaWardTimer = 30000; @@ -790,7 +790,7 @@ struct npc_liquid_pyriteAI : public Scripted_NoMovementAI { if (!m_creature->IsBoarded()) return; - Unit* vehicle = dynamic_cast(m_creature->GetTransportInfo()->GetTransport()); + Unit* vehicle = static_cast(m_creature->GetTransportInfo()->GetTransport()); if (!vehicle) return; if (vehicle->GetEntry() == 33167 || vehicle->GetEntry() == NPC_SALVAGED_DEMOLISHER) @@ -822,24 +822,22 @@ struct npc_pyrite_safety_containerAI : public Scripted_NoMovementAI { AddCustomAction(0, 1s, [&]() { - Creature* lift = dynamic_cast(m_creature->GetSpawner()); - if (!lift) + Creature* lift = static_cast(m_creature->GetSpawner()); + if (!lift || !lift->IsCreature() || !lift->IsAlive()) return; m_creature->CastSpell(lift, SPELL_ROPE_BEAM, TRIGGERED_OLD_TRIGGERED); }); - AddCustomAction(1, true, [&]() + } + + void MovementInform(uint32 moveType, uint32 pointId) override + { + if (moveType == FALL_MOTION_TYPE && pointId == EVENT_FALL) { - float gZ = m_creature->GetMap()->GetHeight(m_creature->GetPhaseMask(), m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); - if ((gZ + 0.1f) < m_creature->GetPositionZ()) - { - ResetTimer(1, 500ms); - return; - } m_creature->CastSpell(nullptr, SPELL_DUSTY_EXPLOSION, TRIGGERED_OLD_TRIGGERED); m_creature->CastSpell(nullptr, SPELL_DUST_CLOUD_IMPACT, TRIGGERED_OLD_TRIGGERED); m_creature->CastSpell(nullptr, SPELL_SPAWN_PYRITE, TRIGGERED_OLD_TRIGGERED); m_creature->ForcedDespawn(1000); - }); + } } }; @@ -891,8 +889,8 @@ struct npc_salvaged_chopperAI : public CombatAI void OnPassengerRide(Unit* passenger, bool boarded, uint8 seat) override { - Player* driver = dynamic_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); - if (!driver) + Player* driver = static_cast(m_creature->GetVehicleInfo()->GetPassenger(0)); + if (!driver || !driver->IsPlayer()) return; if (!seat) return; @@ -1412,7 +1410,7 @@ struct ReadyToFly : public SpellScript { if (!target->IsBoarded()) return; - Unit* vehicle = dynamic_cast(target->GetTransportInfo()->GetTransport()); + Unit* vehicle = static_cast(target->GetTransportInfo()->GetTransport()); if (!vehicle || !vehicle->IsVehicle()) return; Unit* driver = vehicle->GetVehicleInfo()->GetPassenger(0); @@ -1452,8 +1450,6 @@ struct RopeBeam : public AuraScript return; caster->CastSpell(nullptr, SPELL_COSMETIC_PARACHITE, TRIGGERED_OLD_TRIGGERED); caster->GetMotionMaster()->MoveFall(); - if (caster->AI()) - caster->AI()->ResetTimer(1, 500ms); } }; From 24cf1ed572195949fb5945b091b8f9723a907309 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 13 Jan 2024 15:13:26 +0100 Subject: [PATCH 089/104] Ulduar: Update Spellscript data --- sql/scriptdev2/spell.sql | 4 ++++ .../ulduar/ulduar/boss_flame_leviathan.cpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index f69bad6e88d..eb600446c09 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -983,6 +983,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (63474,'spell_ignis_scorch'), (63482,'spell_lightning_whirl_heroic'), (63575,'spell_smoke_trail_leviathan'), +(63605,'spell_rope_beam'), (63618,'spell_overload_leviathan'), (63845,'spell_create_lance'), (64203,'spell_void_zone_xt'), @@ -997,6 +998,8 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (64482,'spell_flame_leviathan_buff'), (64503,'spell_ignis_water'), (64568,'spell_blood_reserve_enchant'), +(64979,'spell_anti_air_rocket'), +(64998,'spell_ready_to_fly'), (65045,'spell_flames_leviathan'), (65121,'spell_searing_light'), (65667,'spell_ignis_heat'), @@ -1008,6 +1011,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (67009,'spell_nether_power'), (67114,'spell_ignis_brittle'), (67322,'spell_burrower_submerge'), +(67372,'spell_grab_crate_leviathan'), (67470,'spell_pursuing_spikes'), (67547,'spell_clear_valkyr_essence'), (67590,'spell_powering_up'), diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 4c97a772761..d95615d4de0 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -979,6 +979,7 @@ bool NpcSpellClick_npc_salvaged_demolisher(Player* player, Creature* clickedCrea return true; } +// 62374 - Pursued struct PursueLeviathan : public SpellScript { bool OnCheckTarget(const Spell* /*spell*/, Unit* target, SpellEffectIndex /*eff*/) const override @@ -1024,6 +1025,7 @@ struct PursueLeviathan : public SpellScript } }; +// 62376 - Battering Ram struct BatteringRamLeviathan : public SpellScript { // TODO: Figure out Targeting issues @@ -1085,6 +1087,7 @@ struct MimironsInfernoLeviathan : public SpellScript, public AuraScript } }; +// 64414 - Load into Catapult struct LoadIntoCatapultLeviathan : public AuraScript { void OnApply(Aura* aura, bool apply) const override @@ -1143,6 +1146,7 @@ struct ThrowPassenger : public SpellScript } }; +// 62336 - Hookshot Aura struct HookshotAura : public AuraScript { void OnPeriodicDummy(Aura* aura) const override @@ -1159,6 +1163,7 @@ struct HookshotAura : public AuraScript } }; +// 62323 - Hookshot struct Hookshot : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override @@ -1198,6 +1203,7 @@ struct Hookshot : public SpellScript } }; +// 62399 - Overload Circuit struct OverloadCircuit : public AuraScript { void OnApply(Aura* aura, bool apply) const override @@ -1224,6 +1230,7 @@ struct OverloadCircuit : public AuraScript } }; +// 62475 - Systems Shutdown struct SystemsShutdown : public AuraScript { void OnApply(Aura* aura, bool apply) const override @@ -1291,6 +1298,7 @@ struct SystemsShutdown : public AuraScript } }; +// 60603 - Eject Passenger 1 struct EjectPassenger1 : public SpellScript { void OnEffectExecute(Spell* spell, SpellEffectIndex /*effIdx*/) const override @@ -1318,6 +1326,7 @@ struct EjectPassenger1 : public SpellScript } }; +// 63575 - Smoke Trail struct SmokeTrailLeviathan : public SpellScript { void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const @@ -1334,6 +1343,7 @@ struct SmokeTrailLeviathan : public SpellScript } }; +// 61242 - Parachute struct ParachuteLeviathan : public AuraScript { void OnPeriodicDummy(Aura* aura) const override @@ -1348,6 +1358,7 @@ struct ParachuteLeviathan : public AuraScript } }; +// 67372 - Grab Pyrite struct GrabPyrite : public SpellScript { void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const @@ -1367,6 +1378,7 @@ struct GrabPyrite : public SpellScript } }; +// 63618 - Overload struct OverloadLeviathan : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override @@ -1378,6 +1390,7 @@ struct OverloadLeviathan : public SpellScript } }; +// 62907 - Freya's Ward struct FreyasWard : public SpellScript { void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const override @@ -1387,6 +1400,7 @@ struct FreyasWard : public SpellScript } }; +// 65045 - Flames struct FlamesLeviathan : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override @@ -1398,6 +1412,7 @@ struct FlamesLeviathan : public SpellScript } }; +// 64998 - Say you're ready to fly! struct ReadyToFly : public SpellScript { const std::vector bcts = {34429, 34433}; @@ -1425,6 +1440,7 @@ struct ReadyToFly : public SpellScript } }; +// 64979 - Anti-Air Rocket struct AntiAirRocket : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override From 59a0d98edcb18c29d2eda2f54f895143923cb508 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sat, 27 Jan 2024 23:36:20 +0100 Subject: [PATCH 090/104] Vehicles: Fix various issues - Fix passenger sometimes visually not mounting - Fix wrong seat coordinate if the player is the vehicle - Deduplicate some code --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 2 +- src/game/Entities/Vehicle.cpp | 108 +++++++----------- src/game/Entities/Vehicle.h | 3 +- src/game/Entities/VehicleHandler.cpp | 7 +- 4 files changed, 47 insertions(+), 73 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index d95615d4de0..7ff44234525 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1292,7 +1292,7 @@ struct SystemsShutdown : public AuraScript { if (seat && seat->IsVehicle()) { - seat->GetVehicleInfo()->RepopulateSeat(1); + seat->GetVehicleInfo()->RespawnAccessories(1); } } } diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index b8f8aa22a5d..1def0bc2b19 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -202,26 +202,6 @@ VehicleInfo::~VehicleInfo() RemoveAccessoriesFromMap(); // Remove accessories (for example required with player vehicles) } -void VehicleInfo::RepopulateSeat(uint8 seatId) -{ - // Loading passengers (rough version only!) - SQLMultiStorage::SQLMSIteratorBounds bounds = sVehicleAccessoryStorage.getBounds(m_overwriteNpcEntry); - for (SQLMultiStorage::SQLMultiSIterator itr = bounds.first; itr != bounds.second; ++itr) - { - auto* seatEntry = GetSeatEntry(itr->seatId); - if (seatId == itr->seatId && seatEntry && seatEntry->m_ID && !GetPassenger(seatId)) - { - if (Creature* summoned = m_owner->SummonCreature(itr->passengerEntry, m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ(), 2 * m_owner->GetOrientation(), TEMPSPAWN_DEAD_DESPAWN, 0)) - { - DEBUG_LOG("VehicleInfo(of %s)::Initialize: Load vehicle accessory %s onto seat %u", m_owner->GetGuidStr().c_str(), summoned->GetGuidStr().c_str(), itr->seatId); - m_accessoryGuids.insert(summoned->GetObjectGuid()); - int32 basepoint0 = itr->seatId + 1; - summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED); - } - } - } -} - void VehicleInfo::Initialize() { if (!m_overwriteNpcEntry) @@ -233,17 +213,9 @@ void VehicleInfo::Initialize() SQLMultiStorage::SQLMSIteratorBounds bounds = sVehicleAccessoryStorage.getBounds(m_overwriteNpcEntry); for (SQLMultiStorage::SQLMultiSIterator itr = bounds.first; itr != bounds.second; ++itr) { - auto* seatEntry = GetSeatEntry(itr->seatId); - if (seatEntry && seatEntry->m_ID) - { - if (Creature* summoned = m_owner->SummonCreature(itr->passengerEntry, m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ(), 2 * m_owner->GetOrientation(), TEMPSPAWN_DEAD_DESPAWN, 0)) - { - DEBUG_LOG("VehicleInfo(of %s)::Initialize: Load vehicle accessory %s onto seat %u", m_owner->GetGuidStr().c_str(), summoned->GetGuidStr().c_str(), itr->seatId); - m_accessoryGuids.insert(summoned->GetObjectGuid()); - int32 basepoint0 = itr->seatId + 1; - summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED); - } - } + Position pos = m_owner->GetPosition(); + pos.o *= 2; + SummonPassenger(itr->passengerEntry, pos, itr->seatId); } } @@ -329,21 +301,7 @@ void VehicleInfo::Board(Unit* passenger, uint8 seat) // Calculate passengers local position float lx = 0.f, ly = 0.f, lz = 0.f, lo = 0.f; - auto* creatureDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(static_cast(m_owner)->GetNativeDisplayId()); - float scale = creatureDisplayInfo->scale; - scale *= sCreatureModelDataStore.LookupEntry(creatureDisplayInfo->ModelId)->Scale; - auto attachmentItr = sModelAttachmentStore.find(creatureDisplayInfo->ModelId); - if (attachmentItr != sModelAttachmentStore.end()) - for (auto& attachment : attachmentItr->second) - { - if (attachment.id == attachmentLookup(seatEntry->m_attachmentID)) - { - lx = (attachment.position.x + seatEntry->m_attachmentOffsetX) * scale; - ly = (attachment.position.y + seatEntry->m_attachmentOffsetY) * scale; - lz = (attachment.position.z + seatEntry->m_attachmentOffsetZ) * scale; - break; - } - } + GetSeatCoordinates(seatEntry, lx, ly, lz); BoardPassenger(passenger, lx, ly, lz, lo, seat); // Use TransportBase to store the passenger if (auto* rootVehicle = static_cast(m_owner)->FindRootVehicle()) @@ -355,7 +313,7 @@ void VehicleInfo::Board(Unit* passenger, uint8 seat) if (passenger->GetTypeId() == TYPEID_PLAYER) { - Player* pPlayer = (Player*)passenger; + Player* pPlayer = static_cast(passenger); pPlayer->UnsummonPetTemporaryIfAny(); WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA); @@ -364,13 +322,11 @@ void VehicleInfo::Board(Unit* passenger, uint8 seat) data.Initialize(SMSG_BREAK_TARGET, m_owner->GetPackGUID().size()); data << m_owner->GetPackGUID(); pPlayer->GetSession()->SendPacket(data); - - pPlayer->SetImmobilizedState(true); } else if (passenger->GetTypeId() == TYPEID_UNIT) { if (!passenger->IsRooted()) - ((Creature*)passenger)->SetImmobilizedState(true); + (static_cast(passenger))->SetImmobilizedState(true); } Movement::MoveSplineInit init(*passenger); @@ -441,21 +397,7 @@ void VehicleInfo::SwitchSeat(Unit* passenger, uint8 seat) RemoveSeatMods(passenger, seatEntry->m_flags); float lx = 0.f, ly = 0.f, lz = 0.f, lo = 0.f; - auto* creatureDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(static_cast(m_owner)->GetNativeDisplayId()); - float scale = creatureDisplayInfo->scale; - scale *= sCreatureModelDataStore.LookupEntry(creatureDisplayInfo->ModelId)->Scale; - auto attachmentItr = sModelAttachmentStore.find(creatureDisplayInfo->ModelId); - if (attachmentItr != sModelAttachmentStore.end()) - for (auto& attachment : attachmentItr->second) - { - if (attachment.id == attachmentLookup(seatEntry->m_attachmentID)) - { - lx = (attachment.position.x + seatEntry->m_attachmentOffsetX) * scale; - ly = (attachment.position.y + seatEntry->m_attachmentOffsetY) * scale; - lz = (attachment.position.z + seatEntry->m_attachmentOffsetZ) * scale; - break; - } - } + GetSeatCoordinates(seatEntry, lx, ly, lz); // Set to new seat itr->second->SetTransportSeat(seat); @@ -657,6 +599,32 @@ void VehicleInfo::CalculateBoardingPositionOf(float gx, float gy, float gz, floa lo = MapManager::NormalizeOrientation(go - m_owner->GetOrientation()); } +void VehicleInfo::GetSeatCoordinates(const VehicleSeatEntry* seatEntry, float& lx, float& ly, float& lz) const +{ + uint32 displayId = 0; + if (m_owner->IsPlayer() && static_cast(m_owner)->IsMounted()) + displayId = static_cast(m_owner)->GetMountID(); + else + displayId = static_cast(m_owner)->GetNativeDisplayId(); + auto* creatureDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(displayId); + float scale = creatureDisplayInfo->scale; + scale *= sCreatureModelDataStore.LookupEntry(creatureDisplayInfo->ModelId)->Scale; + auto attachmentItr = sModelAttachmentStore.find(creatureDisplayInfo->ModelId); + if (attachmentItr != sModelAttachmentStore.end()) + { + for (auto& attachment : attachmentItr->second) + { + if (attachment.id == attachmentLookup(seatEntry->m_attachmentID)) + { + lx = (attachment.position.x + seatEntry->m_attachmentOffsetX) * scale; + ly = (attachment.position.y + seatEntry->m_attachmentOffsetY) * scale; + lz = (attachment.position.z + seatEntry->m_attachmentOffsetZ) * scale; + break; + } + } + } +} + void VehicleInfo::RemoveAccessoriesFromMap() { // Remove all accessories @@ -850,7 +818,10 @@ bool VehicleInfo::IsUsableSeatForPlayer(uint32 seatFlags, uint32 seatFlagsB) con /// Add control and such modifiers to a passenger if required void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags) { - Unit* pVehicle = (Unit*)m_owner; // Vehicles are alawys Unit + if (m_owner->IsPlayer()) + return; + + Unit* pVehicle = static_cast(m_owner); // Vehicles are alawys Unit (except with multi-person mounts) if (seatFlags & SEAT_FLAG_NOT_SELECTABLE) passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); @@ -947,7 +918,10 @@ void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags) /// Remove control and such modifiers to a passenger if they were added void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) { - Unit* pVehicle = (Unit*)m_owner; + if (m_owner->IsPlayer()) + return; + + Unit* pVehicle = static_cast(m_owner); if (seatFlags & SEAT_FLAG_NOT_SELECTABLE) passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); diff --git a/src/game/Entities/Vehicle.h b/src/game/Entities/Vehicle.h index 638b75a35f4..7dd36832c1f 100644 --- a/src/game/Entities/Vehicle.h +++ b/src/game/Entities/Vehicle.h @@ -79,7 +79,6 @@ class VehicleInfo : public TransportBase { public: explicit VehicleInfo(Unit* owner, VehicleEntry const* vehicleEntry, uint32 overwriteNpcEntry); - void RepopulateSeat(uint8 seatId); void Initialize(); ///< Initializes the accessories bool IsInitialized() const { return m_isInitialized; } void SummonPassenger(uint32 entry, Position const& pos, uint8 seatId); @@ -113,6 +112,8 @@ class VehicleInfo : public TransportBase private: // Internal use to calculate the boarding position void CalculateBoardingPositionOf(float gx, float gy, float gz, float go, float& lx, float& ly, float& lz, float& lo) const; + // Internal use to calculate the coordinates of the seat + void GetSeatCoordinates(const VehicleSeatEntry* seatEntry, float& lx, float& ly, float& lz) const; // Seat information bool GetUsableSeatFor(Unit* passenger, uint8& seat, bool reset, bool next) const; diff --git a/src/game/Entities/VehicleHandler.cpp b/src/game/Entities/VehicleHandler.cpp index 328730ef638..919b1785557 100644 --- a/src/game/Entities/VehicleHandler.cpp +++ b/src/game/Entities/VehicleHandler.cpp @@ -201,7 +201,6 @@ void WorldSession::HandleRideVehicleInteract(WorldPacket& recvPacket) ObjectGuid playerGuid; recvPacket >> playerGuid; - //Player* vehicle = _player->GetMap()->GetPlayer(playerGuid); Unit* vehicle = _player->GetMap()->GetUnit(playerGuid); if (!vehicle || !vehicle->IsVehicle()) @@ -236,10 +235,10 @@ void WorldSession::HandleEjectPassenger(WorldPacket& recvPacket) return; // _player is not on a vehicle - if (!_player->IsBoarded()) + if (!_player->IsBoarded() && !_player->IsVehicle()) return; - - Unit* vehicle = dynamic_cast(_player->GetTransportInfo()->GetTransport()); + + Unit* vehicle = static_cast(passenger->GetTransportInfo()->GetTransport()); if (!vehicle) return; From d37fbe650d5ebe01c9e3c2e2e27b0fefa8a563c3 Mon Sep 17 00:00:00 2001 From: insunaa Date: Sun, 28 Jan 2024 10:09:47 +0100 Subject: [PATCH 091/104] Vehicles: Fix switching seats --- src/game/Entities/Vehicle.cpp | 5 ++++- src/game/Entities/VehicleHandler.cpp | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index 1def0bc2b19..884cb691b05 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -390,12 +390,15 @@ void VehicleInfo::SwitchSeat(Unit* passenger, uint8 seat) MANGOS_ASSERT(seatEntry); // Switching seats is only allowed if this flag is set - if (seatEntry->CanSwitchFromSeat()) + if (!seatEntry->CanSwitchFromSeat()) return; // Remove passenger modifications of the old seat RemoveSeatMods(passenger, seatEntry->m_flags); + // Get seatEntry of new seat + seatEntry = GetSeatEntry(seat); + float lx = 0.f, ly = 0.f, lz = 0.f, lo = 0.f; GetSeatCoordinates(seatEntry, lx, ly, lz); diff --git a/src/game/Entities/VehicleHandler.cpp b/src/game/Entities/VehicleHandler.cpp index 919b1785557..32cf603b59c 100644 --- a/src/game/Entities/VehicleHandler.cpp +++ b/src/game/Entities/VehicleHandler.cpp @@ -126,7 +126,7 @@ void WorldSession::HandleRequestVehicleSwitchSeat(WorldPacket& recvPacket) if (!transportInfo || !transportInfo->IsOnVehicle()) return; - Unit* vehicle = (Unit*)transportInfo->GetTransport(); + Unit* vehicle = static_cast(transportInfo->GetTransport()); if (vehicleGuid != vehicle->GetObjectGuid()) { @@ -141,7 +141,7 @@ void WorldSession::HandleRequestVehicleSwitchSeat(WorldPacket& recvPacket) SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(destVehicle->GetEntry()); for (SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) - if (itr->second.IsFitToRequirements(_player, destVehicle->GetTypeId() == TYPEID_UNIT ? (Creature*)destVehicle : nullptr)) + if (itr->second.IsFitToRequirements(_player, destVehicle->GetTypeId() == TYPEID_UNIT ? static_cast(destVehicle) : nullptr)) _player->CastSpell(destVehicle, itr->second.spellId, TRIGGERED_OLD_TRIGGERED); } else @@ -167,7 +167,7 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket& recvPacket) if (!transportInfo || !transportInfo->IsOnVehicle()) return; - Unit* srcVehicle = (Unit*)transportInfo->GetTransport(); + Unit* srcVehicle = static_cast(transportInfo->GetTransport()); // Something went wrong if (srcVehicleGuid != srcVehicle->GetObjectGuid()) From a00329415717c55cb49dc46a5e103ef54ba1692e Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 13 Jun 2024 11:33:54 +0200 Subject: [PATCH 092/104] Leviathan: Remove debug-print include --- src/game/Maps/TransportSystem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/game/Maps/TransportSystem.cpp b/src/game/Maps/TransportSystem.cpp index 7fbbe0b838e..89035a88e51 100644 --- a/src/game/Maps/TransportSystem.cpp +++ b/src/game/Maps/TransportSystem.cpp @@ -32,7 +32,6 @@ #include "Entities/Vehicle.h" #include "Maps/MapManager.h" #include "Entities/Transports.h" -#include "Log.h" /* **************************************** TransportBase ****************************************/ From aa6ae5419e1c1ff04298def560179d3b283e9a3e Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 13 Jun 2024 14:45:56 +0200 Subject: [PATCH 093/104] Leviathan: Fix door --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 1 - src/game/AI/ScriptDevAI/base/BossAI.h | 1 + .../northrend/ulduar/ulduar/boss_flame_leviathan.cpp | 8 +++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index e54f5c4104f..75908284ab0 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -101,7 +101,6 @@ void BossAI::EnterEvadeMode() return; if (ScriptedInstance* instance = static_cast(m_creature->GetInstanceData())) instance->SetData(m_instanceDataType, FAIL); - OpenEntrances(); if (m_respawnDelay == -1) { CombatAI::EnterEvadeMode(); diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index 245bb562274..63ff774ace7 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -54,6 +54,7 @@ class BossAI : public CombatAI for (auto& id : m_entranceObjects) instance->DoUseOpenableObject(id, open); } + void OpenExits() { ScriptedInstance* instance = dynamic_cast(m_creature->GetInstanceData()); diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 7ff44234525..be78c8d438f 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -365,7 +365,13 @@ struct boss_flame_leviathanAI : public BossAI orbital->RemoveAllAuras(); } BossAI::EnterEvadeMode(); - m_creature->ForcedDespawn(3000); + //m_creature->ForcedDespawn(3000); + } + + void JustReachedHome() override + { + BossAI::JustReachedHome(); + m_creature->GetVehicleInfo()->RecallAndRespawnAccessories(); } void JustSummoned(Creature* summoned) override From 636b7bd98d41d6dbbdf2a6a9ba1e746e4c387d75 Mon Sep 17 00:00:00 2001 From: insunaa Date: Thu, 13 Jun 2024 14:46:22 +0200 Subject: [PATCH 094/104] Vehicles: Don't respawn entities in non-existent seats --- src/game/Entities/Vehicle.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index 884cb691b05..e0da0866060 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -670,6 +670,8 @@ void VehicleInfo::RespawnAccessories(int32 seatIndex) { if (seatIndex != -1 && seatIndex != itr->seatId) continue; + if (m_vehicleSeats.find(itr->seatId) == m_vehicleSeats.end()) + continue; Position pos = m_owner->GetPosition(); pos.o *= 2; SummonPassenger(itr->passengerEntry, pos, itr->seatId); From c0df9dd5ef80549db8189368a2eef5c673fd120c Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 09:31:43 +0200 Subject: [PATCH 095/104] Vehicles: Remove check for switching vehicles directly --- src/game/Spells/Spell.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index cad941d8c32..5df00cd3a4c 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -6993,19 +6993,6 @@ SpellCastResult Spell::CheckCast(bool strict) if (!expectedTarget->IsVehicle()) return SPELL_FAILED_BAD_TARGETS; - // It is possible to change between vehicles that are boarded on each other - /*if (m_caster->IsBoarded() && m_caster->GetTransportInfo()->IsOnVehicle()) - { - // Check if trying to board a vehicle that is boarded on current transport - bool boardedOnEachOther = m_caster->GetTransportInfo()->HasOnBoard(expectedTarget); - // Check if trying to board a vehicle that has the current transport on board - if (!boardedOnEachOther) - boardedOnEachOther = expectedTarget->GetVehicleInfo()->HasOnBoard(m_caster); - - if (!boardedOnEachOther) - return SPELL_FAILED_NOT_ON_TRANSPORT; - }*/ - if (!expectedTarget->GetVehicleInfo()->CanBoard(m_caster)) return SPELL_FAILED_BAD_TARGETS; } From 87a973435537e1c38384ff5ad5af090c8f06acbc Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 09:38:38 +0200 Subject: [PATCH 096/104] Vehicle: Fix memory leak --- src/game/Maps/TransportSystem.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/game/Maps/TransportSystem.cpp b/src/game/Maps/TransportSystem.cpp index 89035a88e51..15863195f3b 100644 --- a/src/game/Maps/TransportSystem.cpp +++ b/src/game/Maps/TransportSystem.cpp @@ -157,11 +157,10 @@ bool TransportBase::HasOnBoard(WorldObject const* passenger) const bool TransportBase::BoardPassenger(WorldObject* passenger, float lx, float ly, float lz, float lo, uint8 seat) { - TransportInfo* transportInfo = new TransportInfo(passenger, this, lx, ly, lz, lo, seat); - for (const auto& m_passenger : m_passengers) { - if (transportInfo->GetTransportSeat() == m_passenger.second->GetTransportSeat()) + if (seat == m_passenger.second->GetTransportSeat()) + { if (m_passenger.first->IsUnit()) { if (static_cast(m_passenger.first)->IsVehicle()) @@ -170,7 +169,11 @@ bool TransportBase::BoardPassenger(WorldObject* passenger, float lx, float ly, f return false; } } + } } + + TransportInfo* transportInfo = new TransportInfo(passenger, this, lx, ly, lz, lo, seat); + // Insert our new passenger m_passengers.insert(PassengerMap::value_type(passenger, transportInfo)); From f4aebf102d615ab107a377484f469d3889b34087 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 09:43:19 +0200 Subject: [PATCH 097/104] BossAI: Remove resettable values --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 4 ---- src/game/AI/ScriptDevAI/base/BossAI.h | 15 +-------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index 75908284ab0..870cdc219a1 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -36,10 +36,6 @@ void BossAI::Reset() { CombatAI::Reset(); m_creature->SetSpellList(m_creature->GetCreatureInfo()->SpellList); - for (auto& func : m_resetValues) - { - func(); - } } void BossAI::JustDied(Unit* killer) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index 63ff774ace7..eaa62a123f2 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -18,8 +18,8 @@ #define BOSS_AI_H #include "AI/ScriptDevAI/include/sc_instance.h" -#include "Entities/Creature.h" #include "AI/ScriptDevAI/include/sc_creature.h" +#include "Entities/Creature.h" #include "AI/ScriptDevAI/base/CombatAI.h" enum InstanceActions @@ -144,17 +144,6 @@ class BossAI : public CombatAI DespawnSubordinateOnEvade(fargs...); } - template - void ResetValueTo(T& var, W val) - { - static_assert(std::is_convertible::value, "Value must be of castable type to the variable!"); - T* ptr = &var; - m_resetValues.emplace_back([&]() - { - *ptr = static_cast(val); - }); - } - std::chrono::seconds TimeSinceEncounterStart() { return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_combatStartTimestamp); @@ -174,8 +163,6 @@ class BossAI : public CombatAI std::chrono::milliseconds m_gateDelay = 3s; std::vector m_castOnDeath; - std::vector> m_resetValues; - uint32 m_instanceDataType = -1; uint32 m_respawnDelay = -1; From c050497873d553e835a818d99577605e4d5a77f6 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 09:52:42 +0200 Subject: [PATCH 098/104] BossAI: Remove Subordinate-Despawn --- src/game/AI/ScriptDevAI/base/BossAI.cpp | 15 --------------- src/game/AI/ScriptDevAI/base/BossAI.h | 14 -------------- 2 files changed, 29 deletions(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index 870cdc219a1..c9df747c948 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -14,11 +14,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "AI/ScriptDevAI/include/sc_creature.h" #include "AI/ScriptDevAI/include/sc_instance.h" #include "Entities/Creature.h" #include "AI/ScriptDevAI/base/BossAI.h" -#include "Spells/Spell.h" #include "Spells/SpellMgr.h" #include "AI/ScriptDevAI/ScriptDevAIMgr.h" @@ -104,14 +102,6 @@ void BossAI::EnterEvadeMode() } m_creature->SetRespawnDelay(m_respawnDelay, true); m_creature->ForcedDespawn(2000); - for (ObjectGuid& guid : m_despawnSubordinateOnEvade) - { - Creature* addToDespawn = m_creature->GetMap()->GetCreature(guid); - if (!addToDespawn) - continue; - addToDespawn->SetRespawnDelay(m_respawnDelay); - addToDespawn->ForcedDespawn(); - } } void BossAI::AddCastOnDeath(QueuedCast cast) @@ -123,8 +113,3 @@ void BossAI::AddRespawnOnEvade(std::chrono::seconds delay) { m_respawnDelay = delay.count(); } - -void BossAI::DespawnSubordinateOnEvade(ObjectGuid guid) -{ - m_despawnSubordinateOnEvade.push_back(guid); -} diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index eaa62a123f2..a4b3ec91815 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -131,19 +131,6 @@ class BossAI : public CombatAI */ void AddRespawnOnEvade(std::chrono::seconds delay); - /** - * Adds one or more Creatures to despawn alongside this Creature on Evade - * Uses the same timer for respawn as was set in AddRespawnOnEvade - * @param guid ObjectGuid of the creature to respawn - */ - void DespawnSubordinateOnEvade(ObjectGuid guid); - template - void DespawnSubordinateOnEvade(ObjectGuid guid, Targs... fargs) - { - DespawnSubordinateOnEvade(guid); - DespawnSubordinateOnEvade(fargs...); - } - std::chrono::seconds TimeSinceEncounterStart() { return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_combatStartTimestamp); @@ -156,7 +143,6 @@ class BossAI : public CombatAI private: std::vector m_onKilledTexts; std::vector m_onAggroTexts; - std::vector m_despawnSubordinateOnEvade; std::vector m_entranceObjects; std::vector m_exitObjects; From 946ff36a0a441eefe71fa231efe8e906b1d2b44c Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 09:54:29 +0200 Subject: [PATCH 099/104] BossAI: Change documentation for QueuedCasts --- src/game/AI/ScriptDevAI/base/BossAI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index a4b3ec91815..926b72ef953 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -114,7 +114,7 @@ class BossAI : public CombatAI void EnterEvadeMode() override; /** - * Adds one or more Spells to cast with DoCastSpellIfCan on creature death + * Adds one or more Spells to cast with CastSpell on creature death * @param cast Initialized struct of QueuedCast type */ void AddCastOnDeath(QueuedCast cast); From 0f3571cd86669292b39fd80411ef401ee6bbee3f Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 10:21:35 +0200 Subject: [PATCH 100/104] Ulduar: Remove unneeded Leviathan changes --- .../ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp | 6 ------ .../AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp index 0b632271e45..94291f6a33c 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -300,9 +300,6 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) else m_vaporVezaxBunnyGuid = pCreature->GetObjectGuid(); return; - case NPC_LEVIATHAN_SEAT: - m_leviathanSeatGuids.insert(pCreature->GetObjectGuid()); - return; default: return; } @@ -1343,9 +1340,6 @@ void instance_ulduar::OnCreatureDeath(Creature* pCreature) SetData(TYPE_FREYA_CONSPEEDATORY, DONE); } break; - case NPC_LEVIATHAN_SEAT: - m_leviathanSeatGuids.erase(pCreature->GetObjectGuid()); - break; } } diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h index 1194e5d7339..93ab7693bb1 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/ulduar.h @@ -630,7 +630,6 @@ class instance_ulduar : public ScriptedInstance, private DialogueHelper void GetThunderOrbsGuids(GuidList& lOrbs) const { lOrbs = m_lUpperThunderOrbsGuids; } void GetSmashTargetsGuids(GuidList& lTargets, bool bLeft) { lTargets = bLeft ? m_lLeftHandBunniesGuids : m_lRightHandBunniesGuids; } void GetOminousCloudGuids(GuidList& lClouds) const { lClouds = m_lOminousCloudsGuids; } - void GetLeviathanSeatGuids(GuidSet& seats) const { seats = m_leviathanSeatGuids; } // Function that will trigger the tram turnaround object, based on the tram location void SetTramRotateTimer() { m_uiTramRotateTimer = m_bTramAtCenter ? 33000 : 30000; } @@ -683,7 +682,6 @@ class instance_ulduar : public ScriptedInstance, private DialogueHelper GuidList m_lRightHandBunniesGuids; GuidList m_lOminousCloudsGuids; GuidSet m_sColossusGuidSet; - GuidSet m_leviathanSeatGuids; }; #endif From a43c2d7d615b671c87c3fb60f002292baa98f360 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 10:46:08 +0200 Subject: [PATCH 101/104] Vehicle: Style Changes --- src/game/Entities/Vehicle.cpp | 172 +++++++++++++++++----------------- 1 file changed, 84 insertions(+), 88 deletions(-) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index e0da0866060..f1c8efe3f1d 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -197,7 +197,7 @@ VehicleInfo::VehicleInfo(Unit* owner, VehicleEntry const* vehicleEntry, uint32 o VehicleInfo::~VehicleInfo() { - ((Unit*)m_owner)->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); + (static_cast(m_owner))->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); RemoveAccessoriesFromMap(); // Remove accessories (for example required with player vehicles) } @@ -221,28 +221,28 @@ void VehicleInfo::Initialize() // Initialize movement limitations uint32 vehicleFlags = GetVehicleEntry()->m_flags; - Unit* pVehicle = (Unit*)m_owner; + Unit* vehicle = static_cast(m_owner); if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE) - pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_STRAFE); + vehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_STRAFE); if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING) - pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_JUMPING); + vehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_JUMPING); if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING) - pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDTURNING); + vehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDTURNING); if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING) - pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_ALLOW_PITCHING); + vehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_ALLOW_PITCHING); if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING) - pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDPITCHING); + vehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDPITCHING); // NOTE: this is the best possible combination to root a vehicle if ((vehicleFlags & VEHICLE_FLAG_FIXED_POSITION) || m_owner->GetEntry() == 30236 || m_owner->GetEntry() == 39759) - pVehicle->SetImmobilizedState(true); + vehicle->SetImmobilizedState(true); // Initialize power type based on DBC values (creatures only) - if (pVehicle->GetTypeId() == TYPEID_UNIT) + if (vehicle->GetTypeId() == TYPEID_UNIT) { if (PowerDisplayEntry const* powerEntry = sPowerDisplayStore.LookupEntry(GetVehicleEntry()->m_powerDisplayID)) - pVehicle->SetPowerType(Powers(powerEntry->power)); + vehicle->SetPowerType(Powers(powerEntry->power)); } m_isInitialized = true; @@ -255,7 +255,7 @@ void VehicleInfo::SummonPassenger(uint32 entry, Position const& pos, uint8 seatI DEBUG_LOG("VehicleInfo(of %s)::Initialize: Load vehicle accessory %s onto seat %u", m_owner->GetGuidStr().c_str(), summoned->GetGuidStr().c_str(), seatId); m_accessoryGuids.insert(summoned->GetObjectGuid()); int32 basepoint0 = seatId + 1; - summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED); + summoned->CastCustomSpell(static_cast(m_owner), SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED); } } @@ -313,15 +313,15 @@ void VehicleInfo::Board(Unit* passenger, uint8 seat) if (passenger->GetTypeId() == TYPEID_PLAYER) { - Player* pPlayer = static_cast(passenger); - pPlayer->UnsummonPetTemporaryIfAny(); + Player* player = static_cast(passenger); + player->UnsummonPetTemporaryIfAny(); WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA); - pPlayer->GetSession()->SendPacket(data); + player->GetSession()->SendPacket(data); data.Initialize(SMSG_BREAK_TARGET, m_owner->GetPackGUID().size()); data << m_owner->GetPackGUID(); - pPlayer->GetSession()->SendPacket(data); + player->GetSession()->SendPacket(data); } else if (passenger->GetTypeId() == TYPEID_UNIT) { @@ -483,11 +483,9 @@ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle) if (passenger->IsPlayer()) { - Player* pPlayer = (Player*)passenger; - pPlayer->ResummonPetTemporaryUnSummonedIfAny(); - pPlayer->SetFallInformation(0, pPlayer->GetPositionZ()); - - // SMSG_PET_DISMISS_SOUND (?) + Player* player = static_cast(passenger); + player->ResummonPetTemporaryUnSummonedIfAny(); + player->SetFallInformation(0, player->GetPositionZ()); } if (passenger->hasUnitState(UNIT_STAT_ROOT) && !passenger->HasAuraType(SPELL_AURA_MOD_ROOT)) @@ -588,7 +586,7 @@ Unit* VehicleInfo::GetPassenger(uint8 seat) const { for (const auto& m_passenger : m_passengers) if (m_passenger.second->GetTransportSeat() == seat) - return (Unit*)m_passenger.first; + return static_cast(m_passenger.first); return nullptr; } @@ -643,7 +641,7 @@ void VehicleInfo::TeleportPassengers(uint32 mapId) { if (passenger.first->IsPlayer()) { - players.push_back((Player*)passenger.first); + players.push_back(static_cast(passenger.first)); } } GenericTransport* transport = GetOwner()->GetTransport(); @@ -826,7 +824,7 @@ void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags) if (m_owner->IsPlayer()) return; - Unit* pVehicle = static_cast(m_owner); // Vehicles are alawys Unit (except with multi-person mounts) + Unit* vehicle = static_cast(m_owner); // Vehicles are alawys Unit (except with multi-person mounts) if (seatFlags & SEAT_FLAG_NOT_SELECTABLE) passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); @@ -835,84 +833,84 @@ void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags) if (passenger->GetTypeId() == TYPEID_PLAYER) { - Player* pPlayer = (Player*)passenger; + Player* player = static_cast(passenger); // group update - if (pPlayer->GetGroup()) - pPlayer->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT); + if (player->GetGroup()) + player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT); if (seatFlags & SEAT_FLAG_CAN_CONTROL) { - pPlayer->GetCamera().SetView(pVehicle); + player->GetCamera().SetView(vehicle); - pPlayer->SetCharm(pVehicle); - pVehicle->SetCharmer(pPlayer); + player->SetCharm(vehicle); + vehicle->SetCharmer(player); - pVehicle->SetCanEnterCombat(true); + vehicle->SetCanEnterCombat(true); - pVehicle->GetMotionMaster()->Clear(); - pVehicle->GetMotionMaster()->MoveIdle(); - pVehicle->StopMoving(true); + vehicle->GetMotionMaster()->Clear(); + vehicle->GetMotionMaster()->MoveIdle(); + vehicle->StopMoving(true); - pVehicle->addUnitState(UNIT_STAT_POSSESSED); - pVehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); + vehicle->addUnitState(UNIT_STAT_POSSESSED); + vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); - pVehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - if (pPlayer->IsPvP()) - pVehicle->SetPvP(true); + if (player->IsPvP()) + vehicle->SetPvP(true); - if (pPlayer->IsPvPFreeForAll()) - pVehicle->SetPvPFreeForAll(true); + if (player->IsPvPFreeForAll()) + vehicle->SetPvPFreeForAll(true); - pPlayer->UpdateClientControl(pVehicle, true); - pPlayer->SetMover(pVehicle); + player->UpdateClientControl(vehicle, true); + player->SetMover(vehicle); // Unconfirmed - default speed handling - if (pVehicle->GetTypeId() == TYPEID_UNIT) + if (vehicle->GetTypeId() == TYPEID_UNIT) { - if (!pPlayer->IsWalking() && pVehicle->IsWalking()) + if (!player->IsWalking() && vehicle->IsWalking()) { - ((Creature*)pVehicle)->SetWalk(false, true); + (static_cast(vehicle))->SetWalk(false, true); } - else if (pPlayer->IsWalking() && !pVehicle->IsWalking()) + else if (player->IsWalking() && !vehicle->IsWalking()) { - ((Creature*)pVehicle)->SetWalk(true, true); + (static_cast(vehicle))->SetWalk(true, true); } // set vehicle faction as per the controller faction - m_originalFaction = pVehicle->GetFaction(); - ((Creature*)pVehicle)->SetFactionTemporary(pPlayer->GetFaction(), TEMPFACTION_NONE); + m_originalFaction = vehicle->GetFaction(); + (static_cast(vehicle))->SetFactionTemporary(player->GetFaction(), TEMPFACTION_NONE); // set vehicle react state to passive; player will control the vehicle - pVehicle->AI()->SetReactState(REACT_PASSIVE); + vehicle->AI()->SetReactState(REACT_PASSIVE); } } - pVehicle->SendForcedObjectUpdate(); // TODO: both of these should be one packet - pPlayer->SendForcedObjectUpdate(); + vehicle->SendForcedObjectUpdate(); // TODO: both of these should be one packet + player->SendForcedObjectUpdate(); if (seatFlags & SEAT_FLAG_CAN_CAST) { - CharmInfo* charmInfo = pVehicle->InitCharmInfo(pVehicle); + CharmInfo* charmInfo = vehicle->InitCharmInfo(vehicle); charmInfo->InitVehicleCreateSpells(); - pPlayer->VehicleSpellInitialize(); + player->VehicleSpellInitialize(); } } else if (passenger->GetTypeId() == TYPEID_UNIT) { if (seatFlags & SEAT_FLAG_CAN_CONTROL) { - passenger->SetCharm(pVehicle); - pVehicle->SetCharmer(passenger); + passenger->SetCharm(vehicle); + vehicle->SetCharmer(passenger); // Change vehicle react state; ToDo: also change the vehicle faction? - if (pVehicle->GetTypeId() == TYPEID_UNIT) - pVehicle->AI()->SetReactState(passenger->AI()->GetReactState()); + if (vehicle->GetTypeId() == TYPEID_UNIT) + vehicle->AI()->SetReactState(passenger->AI()->GetReactState()); } - ((Creature*)passenger)->AI()->SetCombatMovement(false); + (static_cast(passenger))->AI()->SetCombatMovement(false); // Not entirely sure how this must be handled in relation to CONTROL // But in any way this at least would require some changes in the movement system most likely passenger->GetMotionMaster()->Clear(false, true); @@ -926,7 +924,7 @@ void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) if (m_owner->IsPlayer()) return; - Unit* pVehicle = static_cast(m_owner); + Unit* vehicle = static_cast(m_owner); if (seatFlags & SEAT_FLAG_NOT_SELECTABLE) passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); @@ -935,65 +933,63 @@ void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) if (passenger->GetTypeId() == TYPEID_PLAYER) { - Player* pPlayer = (Player*)passenger; + Player* player = static_cast(passenger); // group update - if (pPlayer->GetGroup()) - pPlayer->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT); + if (player->GetGroup()) + player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT); if (seatFlags & SEAT_FLAG_CAN_CONTROL) { - pPlayer->SetCharm(nullptr); - pVehicle->SetCharmer(nullptr); - - pPlayer->UpdateClientControl(pVehicle, false); - pPlayer->SetMover(nullptr); + player->SetCharm(nullptr); + vehicle->SetCharmer(nullptr); - pVehicle->StopMoving(true); - pVehicle->GetMotionMaster()->Clear(); + player->UpdateClientControl(vehicle, false); + player->SetMover(nullptr); - pVehicle->clearUnitState(UNIT_STAT_POSSESSED); - pVehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); + vehicle->StopMoving(true); + vehicle->GetMotionMaster()->Clear(); - pVehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + vehicle->clearUnitState(UNIT_STAT_POSSESSED); + vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); - if (pPlayer->IsPvP()) - pVehicle->SetPvP(false); + vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - if (pPlayer->IsPvPFreeForAll()) - pVehicle->SetPvPFreeForAll(false); + if (player->IsPvP()) + vehicle->SetPvP(false); - // // must be called after movement control unapplying - // pPlayer->GetCamera().ResetView(); + if (player->IsPvPFreeForAll()) + vehicle->SetPvPFreeForAll(false); - if (pVehicle->GetTypeId() == TYPEID_UNIT) + if (vehicle->GetTypeId() == TYPEID_UNIT) { // reset vehicle faction - ((Creature*)pVehicle)->SetFactionTemporary(m_originalFaction, TEMPFACTION_NONE); + (static_cast(vehicle))->SetFactionTemporary(m_originalFaction, TEMPFACTION_NONE); - pVehicle->AI()->SetReactState(REACT_AGGRESSIVE); + vehicle->AI()->SetReactState(REACT_AGGRESSIVE); + } - pVehicle->SetTarget(nullptr); + vehicle->SetTarget(nullptr); } // must be called after movement control unapplying - pPlayer->GetCamera().ResetView(); + player->GetCamera().ResetView(); if (seatFlags & SEAT_FLAG_CAN_CAST) - pPlayer->RemovePetActionBar(); + player->RemovePetActionBar(); } else if (passenger->GetTypeId() == TYPEID_UNIT) { if (seatFlags & SEAT_FLAG_CAN_CONTROL) { passenger->SetCharm(nullptr); - pVehicle->SetCharmer(nullptr); + vehicle->SetCharmer(nullptr); } // Reinitialize movement - if (((Creature*)passenger)->AI()) - ((Creature*)passenger)->AI()->SetCombatMovement(true, true); + if ((static_cast(passenger))->AI()) + (static_cast(passenger))->AI()->SetCombatMovement(true, true); if (!passenger->GetVictim()) passenger->GetMotionMaster()->Initialize(); } From b380c7d4b1d4ba2cf5e1e2d65d0e0b9da01c278e Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 10:46:37 +0200 Subject: [PATCH 102/104] Vehicle: Return unit to passive instead of aggressive after unboarding --- src/game/Entities/Vehicle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index f1c8efe3f1d..23661d396ed 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -966,7 +966,7 @@ void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) // reset vehicle faction (static_cast(vehicle))->SetFactionTemporary(m_originalFaction, TEMPFACTION_NONE); - vehicle->AI()->SetReactState(REACT_AGGRESSIVE); + vehicle->AI()->SetReactState(REACT_DEFENSIVE); } From 477979ae10b77b15b2315c67d67384cc4bf6be68 Mon Sep 17 00:00:00 2001 From: insunaa Date: Wed, 10 Jul 2024 14:03:53 +0200 Subject: [PATCH 103/104] Leviathan: Minor style changes --- .../ulduar/ulduar/boss_flame_leviathan.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index be78c8d438f..cd946d3653e 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -195,7 +195,6 @@ static const float afHodirFury[MAX_HODIR_FURY][3] = static const float afMimironInferno[3] = {329.1809f, 8.02577f, 410.887f}; static const std::vector addEntries = {NPC_LEVIATHAN_SEAT, NPC_LEVIATHAN_TURRET, NPC_DEFENSE_TURRET, NPC_OVERLOAD_DEVICE}; -static const std::vector playerVehicleEntries = {NPC_SALVAGED_SIEGE_ENGINE, NPC_SALVAGED_SIEGE_TURRET, NPC_SALVAGED_CHOPPER, NPC_SALVAGED_DEMOLISHER, NPC_SALVAGED_DEMOLISHER_SEAT}; /*###### ## boss_flame_leviathan @@ -994,7 +993,7 @@ struct PursueLeviathan : public SpellScript return false; if (!target->IsVehicle()) return false; - if (auto vehicleInfo = target->GetVehicleInfo()) + if (VehicleInfo* vehicleInfo = target->GetVehicleInfo()) if (vehicleInfo->GetPassenger(0)) return true; return false; @@ -1172,6 +1171,7 @@ struct HookshotAura : public AuraScript // 62323 - Hookshot struct Hookshot : public SpellScript { + static constexpr float checkDist = 30.f * 30.f; bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override { if (eff != EFFECT_INDEX_0) @@ -1179,7 +1179,7 @@ struct Hookshot : public SpellScript Unit* caster = spell->GetCaster(); if (!caster || !target) return true; - if (caster->GetPosition().GetDistance(target->GetPosition()) > 30.f * 30.f) + if (caster->GetPosition().GetDistance(target->GetPosition()) > checkDist) return false; if (target->HasAura(SPELL_SYSTEMS_SHUTDOWN)) return false; @@ -1446,6 +1446,10 @@ struct ReadyToFly : public SpellScript } }; +enum SafetyContainerID : uint32 +{ + NPC_PYRITE_SAFETY_CONTAINER = 33218, +}; // 64979 - Anti-Air Rocket struct AntiAirRocket : public SpellScript { @@ -1454,7 +1458,7 @@ struct AntiAirRocket : public SpellScript Unit* caster = spell->GetAffectiveCaster(); if (!caster->IsEnemy(target)) return false; - if (target->GetEntry() == 33218) + if (target->GetEntry() == NPC_PYRITE_SAFETY_CONTAINER) return false; return true; } @@ -1468,7 +1472,7 @@ struct RopeBeam : public AuraScript if (apply) return; Unit* caster = aura->GetCaster(); - if (!caster || caster->GetEntry() != 33218) + if (!caster || caster->GetEntry() != NPC_PYRITE_SAFETY_CONTAINER) return; caster->CastSpell(nullptr, SPELL_COSMETIC_PARACHITE, TRIGGERED_OLD_TRIGGERED); caster->GetMotionMaster()->MoveFall(); From 74d9cc6c61d48fc9236db5f189d01f891e23ebcd Mon Sep 17 00:00:00 2001 From: insunaa Date: Mon, 15 Jul 2024 15:28:39 +0200 Subject: [PATCH 104/104] Leviathan: Fix friendly fire and mulitboarding --- sql/scriptdev2/spell.sql | 4 ++++ .../ulduar/ulduar/boss_flame_leviathan.cpp | 17 +++++++++++++++-- src/game/Entities/Vehicle.cpp | 12 +++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/sql/scriptdev2/spell.sql b/sql/scriptdev2/spell.sql index eb600446c09..bfc831027e7 100644 --- a/sql/scriptdev2/spell.sql +++ b/sql/scriptdev2/spell.sql @@ -964,10 +964,13 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (62910,'spell_mimirons_inferno_leviathan'), (62912,'spell_thorims_hammer_leviathan'), (62336,'spell_hookshot_aura'), +(62363,'spell_anti_air_rocket'), (62374,'spell_pursue_leviathan'), (62382,'spell_ignis_brittle'), (62399,'spell_overload_circuit'), (62475,'spell_systems_shutdown'), +(62634,'spell_demolisher_mortar'), +(62635,'spell_demolisher_mortar'), (62789,'spell_heart_overload'), (62826,'spell_energy_orb_dummy'), (62828,'spell_recharge_robot'), @@ -1000,6 +1003,7 @@ INSERT INTO spell_scripts(Id, ScriptName) VALUES (64568,'spell_blood_reserve_enchant'), (64979,'spell_anti_air_rocket'), (64998,'spell_ready_to_fly'), +(65044,'spell_flames_leviathan'), (65045,'spell_flames_leviathan'), (65121,'spell_searing_light'), (65667,'spell_ignis_heat'), diff --git a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index cd946d3653e..c110ddbe9a1 100644 --- a/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/game/AI/ScriptDevAI/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1406,7 +1406,7 @@ struct FreyasWard : public SpellScript } }; -// 65045 - Flames +// 65045, 65044 - Flames struct FlamesLeviathan : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex /*eff*/) const override @@ -1450,7 +1450,7 @@ enum SafetyContainerID : uint32 { NPC_PYRITE_SAFETY_CONTAINER = 33218, }; -// 64979 - Anti-Air Rocket +// 64979, 62363 - Anti-Air Rocket struct AntiAirRocket : public SpellScript { bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override @@ -1464,6 +1464,18 @@ struct AntiAirRocket : public SpellScript } }; +// 62634, 62635 - Mortar +struct DemolisherMortar : public SpellScript +{ + bool OnCheckTarget(const Spell* spell, Unit* target, SpellEffectIndex eff) const override + { + Unit* caster = spell->GetAffectiveCaster(); + if (!caster->IsEnemy(target)) + return false; + return true; + } +}; + // 63605 - Rope Beam struct RopeBeam : public AuraScript { @@ -1562,6 +1574,7 @@ void AddSC_boss_flame_leviathan() RegisterSpellScript("spell_freyas_ward_leviathan"); RegisterSpellScript("spell_ready_to_fly"); RegisterSpellScript("spell_anti_air_rocket"); + RegisterSpellScript("spell_demolisher_mortar"); RegisterSpellScript("spell_rope_beam"); RegisterSpellScript("spell_flame_leviathan_buff"); } diff --git a/src/game/Entities/Vehicle.cpp b/src/game/Entities/Vehicle.cpp index 23661d396ed..83b9dcee829 100644 --- a/src/game/Entities/Vehicle.cpp +++ b/src/game/Entities/Vehicle.cpp @@ -245,6 +245,14 @@ void VehicleInfo::Initialize() vehicle->SetPowerType(Powers(powerEntry->power)); } + // Experimental + if (vehicleFlags & (VEHICLE_FLAG_UNK8 | VEHICLE_FLAG_UNK7)) + { + vehicle->SetCanEnterCombat(false); + if (vehicle->AI()) + vehicle->AI()->SetReactState(REACT_PASSIVE); + } + m_isInitialized = true; } @@ -303,7 +311,9 @@ void VehicleInfo::Board(Unit* passenger, uint8 seat) float lx = 0.f, ly = 0.f, lz = 0.f, lo = 0.f; GetSeatCoordinates(seatEntry, lx, ly, lz); - BoardPassenger(passenger, lx, ly, lz, lo, seat); // Use TransportBase to store the passenger + if(!BoardPassenger(passenger, lx, ly, lz, lo, seat)) // Use TransportBase to store the passenger + return; + if (auto* rootVehicle = static_cast(m_owner)->FindRootVehicle()) passenger->SetRootVehicle(rootVehicle->GetObjectGuid());