diff --git a/.travis.yml b/.travis.yml index 6e473dabf8f..b10509e2425 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,18 @@ git: addons: apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: 'ppa:kzemek/boost' packages: - - libboost1.55-dev - - libboost-filesystem1.55-dev - - libboost-iostreams1.55-dev - - libboost-program-options1.55-dev - - libboost-regex1.55-dev - - libboost-system1.55-dev - - libboost-thread1.55-dev + - g++-6 + - libboost1.58-dev + - libboost-filesystem1.58-dev + - libboost-iostreams1.58-dev + - libboost-program-options1.58-dev + - libboost-regex1.58-dev + - libboost-system1.58-dev + - libboost-thread1.58-dev - libssl-dev - libmysqlclient-dev - libreadline6-dev diff --git a/README.md b/README.md index 6f0b978cdd0..a97d007689c 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,12 @@ website at [TrinityCore.org](https://www.trinitycore.org). + Platform: Linux, Windows or Mac + Processor with SSE2 support -+ Boost ≥ 1.55 (Linux) 1.63 (Windows) ++ Boost ≥ 1.58 (Linux) 1.63 (Windows) + MySQL ≥ 5.1.0 -+ CMake ≥ 3.0.2 (Linux) 3.3.2 (Windows) ++ CMake ≥ 3.2.0 (Linux) 3.3.2 (Windows) + OpenSSL = 1.0.x -+ GCC ≥ 4.9.2 (Linux only) (clang 3.5 heavy recommended) -+ MS Visual Studio ≥ 14 (2015) (Windows only) ++ GCC ≥ 6.3.0 (Linux only) (clang 3.5 heavy recommended) ++ MS Visual Studio ≥ 15 (2017) (Windows only) + zlib ≥ 1.2.7 + ZeroMQ: + apt-get install libzmq-dev (Linux only) diff --git a/cmake/compiler/clang/settings.cmake b/cmake/compiler/clang/settings.cmake index 1cd95bbf703..b826c1dba36 100644 --- a/cmake/compiler/clang/settings.cmake +++ b/cmake/compiler/clang/settings.cmake @@ -16,7 +16,7 @@ endif() # -Wno-narrowing needed to suppress a warning in g3d # -Wno-deprecated-register is needed to suppress 185 gsoap warnings on Unix systems. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-narrowing -Wno-deprecated-register") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wno-narrowing -Wno-deprecated-register") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1") if (BUILD_SHARED_LIBS) diff --git a/cmake/compiler/gcc/settings.cmake b/cmake/compiler/gcc/settings.cmake index a0c2b737475..52924ba0667 100644 --- a/cmake/compiler/gcc/settings.cmake +++ b/cmake/compiler/gcc/settings.cmake @@ -1,14 +1,14 @@ # Set build-directive (used in core to tell which buildtype we used) add_definitions(-D_BUILD_DIRECTIVE='"${CMAKE_BUILD_TYPE}"') -set(GCC_EXPECTED_VERSION 4.9.0) +set(GCC_EXPECTED_VERSION 6.3.0) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS GCC_EXPECTED_VERSION) message(FATAL_ERROR "GCC: TrinityCore requires version ${GCC_EXPECTED_VERSION} to build but found ${CMAKE_CXX_COMPILER_VERSION}") endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -message(STATUS "GCC: Enabled c++11 support") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +message(STATUS "GCC: Enabled c++14 support") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") message(STATUS "GCC: Enabled C99 support") diff --git a/cmake/macros/FindOpenSSL.cmake b/cmake/macros/FindOpenSSL.cmake index ca67601427c..2a691ee016c 100644 --- a/cmake/macros/FindOpenSSL.cmake +++ b/cmake/macros/FindOpenSSL.cmake @@ -26,7 +26,7 @@ # http://www.slproweb.com/products/Win32OpenSSL.html set(OPENSSL_EXPECTED_VERSION "1.0") -set(OPENSSL_MAX_VERSION "1.1") +set(OPENSSL_MAX_VERSION "1.2") SET(_OPENSSL_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]" @@ -80,30 +80,37 @@ IF(WIN32 AND NOT CYGWIN) # libeay32MD.lib is identical to ../libeay32.lib, and # ssleay32MD.lib is identical to ../ssleay32.lib + # Since OpenSSL 1.1, lib names are like libcrypto32MTd.lib and libssl32MTd.lib + if( "${CMAKE_SIZEOF_VOID_P}" STREQUAL "8" ) + set(_OPENSSL_MSVC_ARCH_SUFFIX "64") + else() + set(_OPENSSL_MSVC_ARCH_SUFFIX "32") + endif() + FIND_LIBRARY(LIB_EAY_DEBUG NAMES - libeay32MDd libeay32 + libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}MDd libeay32MDd libeay32 PATHS ${OPENSSL_ROOT_DIR}/lib/VC ) FIND_LIBRARY(LIB_EAY_RELEASE NAMES - libeay32MD libeay32 + libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}MD libeay32MD libeay32 PATHS ${OPENSSL_ROOT_DIR}/lib/VC ) FIND_LIBRARY(SSL_EAY_DEBUG NAMES - ssleay32MDd ssleay32 ssl + libssl${_OPENSSL_MSVC_ARCH_SUFFIX}MDd ssleay32MDd ssleay32 ssl PATHS ${OPENSSL_ROOT_DIR}/lib/VC ) FIND_LIBRARY(SSL_EAY_RELEASE NAMES - ssleay32MD ssleay32 ssl + libssl${_OPENSSL_MSVC_ARCH_SUFFIX}MD ssleay32MD ssleay32 ssl PATHS ${OPENSSL_ROOT_DIR}/lib/VC ) diff --git a/dep/boost/CMakeLists.txt b/dep/boost/CMakeLists.txt index c5e5ab17117..b556caaaf8b 100644 --- a/dep/boost/CMakeLists.txt +++ b/dep/boost/CMakeLists.txt @@ -38,7 +38,7 @@ if (WIN32) # On windows the requirements are higher according to the wiki. set(BOOST_REQUIRED_VERSION 1.59) else() - set(BOOST_REQUIRED_VERSION 1.55) + set(BOOST_REQUIRED_VERSION 1.56) endif() find_package(Boost ${BOOST_REQUIRED_VERSION} REQUIRED system filesystem thread program_options iostreams regex) diff --git a/revision_data.h.in.cmake b/revision_data.h.in.cmake index 99ad8bfe127..854ff6e3c4b 100644 --- a/revision_data.h.in.cmake +++ b/revision_data.h.in.cmake @@ -4,10 +4,12 @@ #define _DATE "@rev_date@" #define _BRANCH "@rev_branch@" #define _CMAKE_COMMAND R"(@CMAKE_COMMAND@)" + #define _CMAKE_VERSION R"(@CMAKE_VERSION@)" + #define _CMAKE_HOST_SYSTEM R"(@CMAKE_HOST_SYSTEM_NAME@ @CMAKE_HOST_SYSTEM_VERSION@)" #define _SOURCE_DIRECTORY R"(@CMAKE_SOURCE_DIR@)" #define _BUILD_DIRECTORY R"(@BUILDDIR@)" #define _MYSQL_EXECUTABLE R"(@MYSQL_EXECUTABLE@)" - #define _FULL_DATABASE "TDB_full_world_434.27_2018_02_16.sql" + #define _FULL_DATABASE "TDB_full_world_434.28_2018_03_16.sql" #define VER_COMPANYNAME_STR "TrinityCore Developers" #define VER_LEGALCOPYRIGHT_STR "(c)2008-2018 TrinityCore" #define VER_FILEVERSION 0,0,0 diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 4b4bcc6f29c..b97343966c7 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -975,6 +975,7 @@ INSERT INTO `rbac_linked_permissions` VALUES (196,843), (196,866), (196,867), +(196,872), (197,232), (197,236), (197,237), @@ -1868,7 +1869,8 @@ INSERT INTO `rbac_permissions` VALUES (863,'Command: group set maintank'), (864,'Command: group set mainassist'), (865,'Command: npc showloot'), -(867,'Command: reload quest_greeting_locale'); +(867,'Command: reload quest_greeting_locale'), +(872,'Command: server debug'); /*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */; UNLOCK TABLES; @@ -2001,7 +2003,9 @@ INSERT INTO `updates` VALUES ('2017_12_17_00_auth.sql','E2EC5999D5305FC12EA576D08EFB95D1660DCF4D','ARCHIVED','2017-12-17 01:40:04',0), ('2018_01_06_00_auth.sql','CD9B826B9D95697DC412DEF780E814FA3991D6CD','ARCHIVED','2018-01-06 01:40:04',0), ('2018_01_15_00_auth.sql','1C5C28490B27D86EBC14F6034AA4D34E66D5545D','ARCHIVED','2018-01-15 01:40:04',0), -('2018_02_16_00_auth.sql','1AAD2FC649CBE8093ECE5908EBBBB31EC326166A','ARCHIVED','2018-02-16 01:40:04',0); +('2018_02_16_00_auth.sql','1AAD2FC649CBE8093ECE5908EBBBB31EC326166A','ARCHIVED','2018-02-16 01:40:04',0), +('2018_03_06_00_auth_from_335_was_2018_03_06_00_auth.sql','3F8EA885898CE0F9D47043A832602D77','ARCHIVED','2018-02-16 01:40:04',0), +('2018_03_16_00_auth.sql','E77AFBFE7C1DEC8839AECC40140ED1AF55B56A10','ARCHIVED','2018-03-16 01:40:04',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index b5fa46f8c5f..7d65d6fd8aa 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -497,6 +497,81 @@ LOCK TABLES `character_action` WRITE; /*!40000 ALTER TABLE `character_action` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `character_archaeology_completed` +-- + +DROP TABLE IF EXISTS `character_archaeology_completed`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `character_archaeology_completed` ( + `guid` int(10) unsigned NOT NULL, + `project` smallint(5) unsigned NOT NULL, + `time` int(10) NOT NULL, + `count` int(10) NOT NULL, + PRIMARY KEY (`guid`,`project`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `character_archaeology_completed` +-- + +LOCK TABLES `character_archaeology_completed` WRITE; +/*!40000 ALTER TABLE `character_archaeology_completed` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_archaeology_completed` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_archaeology_projects` +-- + +DROP TABLE IF EXISTS `character_archaeology_projects`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `character_archaeology_projects` ( + `guid` int(10) unsigned NOT NULL, + `branch` tinyint(3) unsigned NOT NULL, + `project` mediumint(8) unsigned NOT NULL, + PRIMARY KEY (`guid`,`branch`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `character_archaeology_projects` +-- + +LOCK TABLES `character_archaeology_projects` WRITE; +/*!40000 ALTER TABLE `character_archaeology_projects` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_archaeology_projects` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_archaeology_sites` +-- + +DROP TABLE IF EXISTS `character_archaeology_sites`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `character_archaeology_sites` ( + `guid` int(10) unsigned NOT NULL, + `site` tinyint(3) unsigned NOT NULL, + `type` smallint(5) unsigned NOT NULL, + `finds` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`guid`,`site`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*Data for the table `character_archaeology_sites` */ +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `character_archaeology_sites` +-- + +LOCK TABLES `character_archaeology_sites` WRITE; +/*!40000 ALTER TABLE `character_archaeology_sites` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_archaeology_sites` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `character_arena_stats` -- @@ -2876,7 +2951,8 @@ INSERT INTO `updates` VALUES ('2017_11_28_00_characters.sql','6FF1F84B8985ADFC7FF97F0BF8E53403CF13C320','ARCHIVED','2017-11-28 00:00:00',0), ('2017_12_17_00_characters.sql','937E8F51DC74AC41FF8F213CE36C69DDEB878D6A','ARCHIVED','2017-12-17 00:00:00',0), ('2018_01_15_00_characters.sql','43C8E4549E1AA9610B377BC7139C88C63D0DC193','ARCHIVED','2018-01-15 00:00:00',0), -('2018_02_16_00_characters.sql','F1254689CE8A0B0AF149E557830287FF583B8D91','ARCHIVED','2018-02-16 00:00:00',0); +('2018_02_16_00_characters.sql','F1254689CE8A0B0AF149E557830287FF583B8D91','ARCHIVED','2018-02-16 00:00:00',0), +('2018_03_16_00_characters.sql','722EAFB7F508882F584DCAE61F97F1A11EDE126E','ARCHIVED','2018-03-16 00:00:00',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/base/dev/world_database.sql b/sql/base/dev/world_database.sql index 90f7c579503..6b426d60307 100644 --- a/sql/base/dev/world_database.sql +++ b/sql/base/dev/world_database.sql @@ -3186,6 +3186,7 @@ CREATE TABLE `smart_scripts` ( `event_param2` int(10) unsigned NOT NULL DEFAULT '0', `event_param3` int(10) unsigned NOT NULL DEFAULT '0', `event_param4` int(10) unsigned NOT NULL DEFAULT '0', + `event_param5` int(10) unsigned NOT NULL DEFAULT '0', `action_type` tinyint(3) unsigned NOT NULL DEFAULT '0', `action_param1` int(10) unsigned NOT NULL DEFAULT '0', `action_param2` int(10) unsigned NOT NULL DEFAULT '0', @@ -3616,6 +3617,51 @@ CREATE TABLE `spelleffect_dbc` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `terrain_phase_info` +-- + +DROP TABLE IF EXISTS `terrain_phase_info`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `terrain_phase_info` ( + `Id` int(10) unsigned NOT NULL, + `TerrainSwapMap` int(10) unsigned NOT NULL, + `Comment` varchar(255) DEFAULT NULL, + PRIMARY KEY (`Id`,`TerrainSwapMap`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `terrain_swap_defaults` +-- + +DROP TABLE IF EXISTS `terrain_swap_defaults`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `terrain_swap_defaults` ( + `MapId` int(10) unsigned NOT NULL, + `TerrainSwapMap` int(10) unsigned NOT NULL, + `Comment` varchar(255) DEFAULT NULL, + PRIMARY KEY (`MapId`,`TerrainSwapMap`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `terrain_worldmap` +-- + +DROP TABLE IF EXISTS `terrain_worldmap`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `terrain_worldmap` ( + `TerrainSwapMap` int(10) unsigned NOT NULL, + `WorldMapArea` int(10) unsigned NOT NULL, + `Comment` varchar(255) DEFAULT NULL, + PRIMARY KEY (`TerrainSwapMap`,`WorldMapArea`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `transports` -- diff --git a/sql/updates/auth/4.3.4/2018_02_16_00_auth.sql b/sql/old/4.3.4/auth/27_2018_03_16/2018_02_16_00_auth.sql similarity index 100% rename from sql/updates/auth/4.3.4/2018_02_16_00_auth.sql rename to sql/old/4.3.4/auth/27_2018_03_16/2018_02_16_00_auth.sql diff --git a/sql/old/4.3.4/auth/27_2018_03_16/2018_03_06_00_auth_from_335_was_2018_03_06_00_auth.sql b/sql/old/4.3.4/auth/27_2018_03_16/2018_03_06_00_auth_from_335_was_2018_03_06_00_auth.sql new file mode 100644 index 00000000000..ddaf1d13f0c --- /dev/null +++ b/sql/old/4.3.4/auth/27_2018_03_16/2018_03_06_00_auth_from_335_was_2018_03_06_00_auth.sql @@ -0,0 +1,5 @@ +DELETE FROM `rbac_permissions` WHERE `id`=872; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(872, 'Command: server debug'); +INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES +(196, 872); diff --git a/sql/updates/characters/4.3.4/2018_02_16_00_characters.sql b/sql/old/4.3.4/characters/27_2018_03_16/2018_02_16_00_characters.sql similarity index 100% rename from sql/updates/characters/4.3.4/2018_02_16_00_characters.sql rename to sql/old/4.3.4/characters/27_2018_03_16/2018_02_16_00_characters.sql diff --git a/sql/updates/world/4.3.4/2018_02_16_24_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_16_24_world.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_16_24_world.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_16_24_world.sql diff --git a/sql/updates/world/4.3.4/2018_02_17_00_world_from_335_was_2018_02_16_02_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_17_00_world_from_335_was_2018_02_16_02_world.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_17_00_world_from_335_was_2018_02_16_02_world.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_17_00_world_from_335_was_2018_02_16_02_world.sql diff --git a/sql/updates/world/4.3.4/2018_02_18_00_world_from_335_was_2018_02_17_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_18_00_world_from_335_was_2018_02_17_00_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_18_00_world_from_335_was_2018_02_17_00_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_18_00_world_from_335_was_2018_02_17_00_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_18_01_world_from_335_was_2018_02_17_01_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_18_01_world_from_335_was_2018_02_17_01_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_18_01_world_from_335_was_2018_02_17_01_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_18_01_world_from_335_was_2018_02_17_01_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_18_02_world_from_335_was_2018_02_17_02_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_18_02_world_from_335_was_2018_02_17_02_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_18_02_world_from_335_was_2018_02_17_02_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_18_02_world_from_335_was_2018_02_17_02_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_18_03_world_from_335_was_2018_02_17_03_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_18_03_world_from_335_was_2018_02_17_03_world.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_18_03_world_from_335_was_2018_02_17_03_world.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_18_03_world_from_335_was_2018_02_17_03_world.sql diff --git a/sql/updates/world/4.3.4/2018_02_18_04_world_from_335_was_2018_02_17_04_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_18_04_world_from_335_was_2018_02_17_04_world.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_18_04_world_from_335_was_2018_02_17_04_world.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_18_04_world_from_335_was_2018_02_17_04_world.sql diff --git a/sql/updates/world/4.3.4/2018_02_18_05_world_from_335_was_2018_02_17_05_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_18_05_world_from_335_was_2018_02_17_05_world.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_18_05_world_from_335_was_2018_02_17_05_world.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_18_05_world_from_335_was_2018_02_17_05_world.sql diff --git a/sql/updates/world/4.3.4/2018_02_18_06_world_from_335_was_2018_02_17_06_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_18_06_world_from_335_was_2018_02_17_06_world.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_18_06_world_from_335_was_2018_02_17_06_world.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_18_06_world_from_335_was_2018_02_17_06_world.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_00_world_from_335_was_2018_02_19_01_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_00_world_from_335_was_2018_02_19_01_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_00_world_from_335_was_2018_02_19_01_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_00_world_from_335_was_2018_02_19_01_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_01_world_from_335_was_2018_02_19_02_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_01_world_from_335_was_2018_02_19_02_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_01_world_from_335_was_2018_02_19_02_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_01_world_from_335_was_2018_02_19_02_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_02_world_from_335_was_2018_02_19_03_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_02_world_from_335_was_2018_02_19_03_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_02_world_from_335_was_2018_02_19_03_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_02_world_from_335_was_2018_02_19_03_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_03_world_from_335_was_2018_02_19_04_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_03_world_from_335_was_2018_02_19_04_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_03_world_from_335_was_2018_02_19_04_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_03_world_from_335_was_2018_02_19_04_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_04_world_from_335_was_2018_02_19_05_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_04_world_from_335_was_2018_02_19_05_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_04_world_from_335_was_2018_02_19_05_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_04_world_from_335_was_2018_02_19_05_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_05_world_from_335_was_2018_02_19_06_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_05_world_from_335_was_2018_02_19_06_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_05_world_from_335_was_2018_02_19_06_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_05_world_from_335_was_2018_02_19_06_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_06_world_from_335_was_2018_02_19_07_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_06_world_from_335_was_2018_02_19_07_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_06_world_from_335_was_2018_02_19_07_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_06_world_from_335_was_2018_02_19_07_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_07_world_from_335_was_2018_02_19_08_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_07_world_from_335_was_2018_02_19_08_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_07_world_from_335_was_2018_02_19_08_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_07_world_from_335_was_2018_02_19_08_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_08_world_from_335_was_2018_02_19_09_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_08_world_from_335_was_2018_02_19_09_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_08_world_from_335_was_2018_02_19_09_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_08_world_from_335_was_2018_02_19_09_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_09_world_from_335_was_2018_02_19_10_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_09_world_from_335_was_2018_02_19_10_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_09_world_from_335_was_2018_02_19_10_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_09_world_from_335_was_2018_02_19_10_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_10_world_from_335_was_2018_02_19_11_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_10_world_from_335_was_2018_02_19_11_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_10_world_from_335_was_2018_02_19_11_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_10_world_from_335_was_2018_02_19_11_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_11_world_from_335_was_2018_02_19_12_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_11_world_from_335_was_2018_02_19_12_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_11_world_from_335_was_2018_02_19_12_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_11_world_from_335_was_2018_02_19_12_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_12_world_from_335_was_2018_02_19_13_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_12_world_from_335_was_2018_02_19_13_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_12_world_from_335_was_2018_02_19_13_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_12_world_from_335_was_2018_02_19_13_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_13_world_from_335_was_2018_02_19_14_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_13_world_from_335_was_2018_02_19_14_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_13_world_from_335_was_2018_02_19_14_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_13_world_from_335_was_2018_02_19_14_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_14_world_from_335_was_2018_02_19_15_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_14_world_from_335_was_2018_02_19_15_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_14_world_from_335_was_2018_02_19_15_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_14_world_from_335_was_2018_02_19_15_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_15_world_from_335_was_2018_02_19_16_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_15_world_from_335_was_2018_02_19_16_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_15_world_from_335_was_2018_02_19_16_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_15_world_from_335_was_2018_02_19_16_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_16_world_from_335_was_2018_02_19_17_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_16_world_from_335_was_2018_02_19_17_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_16_world_from_335_was_2018_02_19_17_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_16_world_from_335_was_2018_02_19_17_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_20_17_world_from_335_was_2018_02_19_18_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_20_17_world_from_335_was_2018_02_19_18_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_20_17_world_from_335_was_2018_02_19_18_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_20_17_world_from_335_was_2018_02_19_18_world_335.sql diff --git a/sql/updates/world/4.3.4/2018_02_24_00_world_from_335_was_2018_02_21_01_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_24_00_world_from_335_was_2018_02_21_01_world.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_24_00_world_from_335_was_2018_02_21_01_world.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_24_00_world_from_335_was_2018_02_21_01_world.sql diff --git a/sql/updates/world/4.3.4/2018_02_24_01_world_from_335_was_2018_02_23_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_02_24_01_world_from_335_was_2018_02_23_00_world_335.sql similarity index 100% rename from sql/updates/world/4.3.4/2018_02_24_01_world_from_335_was_2018_02_23_00_world_335.sql rename to sql/old/4.3.4/world/27_2018_03_16/2018_02_24_01_world_from_335_was_2018_02_23_00_world_335.sql diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_00_world_from_335_was_2018_02_24_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_00_world_from_335_was_2018_02_24_00_world_335.sql new file mode 100644 index 00000000000..749c45988f6 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_00_world_from_335_was_2018_02_24_00_world_335.sql @@ -0,0 +1,37 @@ +/* +-- Deathguard Elite +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=7980; +DELETE FROM `smart_scripts` WHERE `entryorguid`=7980 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(7980,0,0,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Deathguard Elite - In Combat - Cast 'Shoot'"); + +-- Stormwind City Guard +DELETE FROM `smart_scripts` WHERE `entryorguid`=68 AND `source_type`=0 AND `id` IN (1,2,3,4,5,6,7,8,9,10); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (6800,6801,6802,6803,6804) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(68, 0, 1,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Stormwind City Guard - In Combat - Cast 'Shoot'"), +(68, 0, 2,0,9,0,100,0,0,5,11000,14000,11,12169,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - Within 0-5 Range - Cast 'Shield Block'"), +(68, 0, 3,0,0,0,100,0,5000,9000,8000,13000,11,12170,0,0,0,0,0,2,0,0,0,0,0,0,0,"Stormwind City Guard - In Combat - Cast 'Revenge'"), +(68, 0, 4,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Received Emote 'Wave' - Run Script"), +(68, 0, 5,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Received Emote 'Salute' - Run Script"), +(68, 0, 6,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Received Emote 'Kiss' - Run Script"), +(68, 0, 7,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Received Emote 'Shy' - Run Script"), +(68, 0, 8,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Received Emote 'Rude' - Run Script"), +(68, 0, 9,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Received Emote 'Chicken' - Run Script"), +(68, 0,10,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Received Emote 'Bow' - Run Script"), +(6800,9, 0,0, 0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6800,9, 1,0, 0,0,100,0,2000,2000,0,0,5,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Wave'"), +(6800,9, 2,0, 0,0,100,0,10000,10000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6801,9, 0,0, 0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6801,9, 1,0, 0,0,100,0,2000,2000,0,0,5,66,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Salute'"), +(6801,9, 2,0, 0,0,100,0,10000,10000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6802,9, 0,0, 0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6802,9, 1,0, 0,0,100,0,2000,2000,0,0,5,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Bow'"), +(6802,9, 2,0, 0,0,100,0,10000,10000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6803,9, 0,0, 0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6803,9, 1,0, 0,0,100,0,2000,2000,0,0,5,23,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Flex'"), +(6803,9, 2,0, 0,0,100,0,10000,10000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6804,9, 0,0, 0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6804,9, 1,0, 0,0,100,0,2000,2000,0,0,5,25,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Point'"), +(6804,9, 2,0, 0,0,100,0,10000,10000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_01_world_from_335_was_2018_02_24_01_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_01_world_from_335_was_2018_02_24_01_world_335.sql new file mode 100644 index 00000000000..5a65cfbcb37 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_01_world_from_335_was_2018_02_24_01_world_335.sql @@ -0,0 +1,2 @@ +-- Apothecary Keever's test subjects (Caged Human Male, Squirrel, Rabbit, Toad, Sheep) +-- UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry` IN (5736,5739,5741,5742,5743); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_02_world_from_335_was_2018_02_24_02_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_02_world_from_335_was_2018_02_24_02_world.sql new file mode 100644 index 00000000000..d2a4cdd79d4 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_02_world_from_335_was_2018_02_24_02_world.sql @@ -0,0 +1 @@ +UPDATE `spell_proc` SET `ProcFlags`=`ProcFlags`|2048 WHERE `SpellId`=17619; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_03_world_from_335_was_2018_02_24_03_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_03_world_from_335_was_2018_02_24_03_world.sql new file mode 100644 index 00000000000..f66c9121e05 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_03_world_from_335_was_2018_02_24_03_world.sql @@ -0,0 +1,27 @@ +-- +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (34925) AND `source_type`=0 AND `id`=11 AND `action_type`=70; +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=49141, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=30420 AND `source_type`=0 AND `id` IN (3); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=202969, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=28659 AND `source_type`=0 AND `id` IN (20); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=202970, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=28659 AND `source_type`=0 AND `id` IN (1); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=202969, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=28659 AND `source_type`=0 AND `id` IN (0); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=202970, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=28659 AND `source_type`=0 AND `id` IN (21); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=85322, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=27210 AND `source_type`=0 AND `id` IN (8); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=85098, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=26073 AND `source_type`=0 AND `id` IN (0); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=85118, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=26073 AND `source_type`=0 AND `id` IN (2); +UPDATE `smart_scripts` SET `action_type`=118, `action_param1`=1 WHERE `entryorguid`=25201 AND `source_type`=0 AND `id` IN (5) AND `action_type`=70; +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=74518, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=24023 AND `source_type`=0 AND `id` IN (6); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=74519, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=24023 AND `source_type`=0 AND `id` IN (7); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=74520, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=24023 AND `source_type`=0 AND `id` IN (8); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=70376, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=19720 AND `source_type`=0 AND `id` IN (9); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=70377, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=19720 AND `source_type`=0 AND `id` IN (10); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=48191, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=18471 AND `source_type`=0 AND `id`=26; +UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=18399 AND `source_type`=0 AND `id`=6; +UPDATE `smart_scripts` SET `event_type`=7, `action_type`=41, `target_type`=1, `target_param1`=0, `target_param2`=0, `Comment`="Murkblood Twin - On evade - Despawn" WHERE `entryorguid`=18399 AND `source_type`=0 AND `id`=7; +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=56862, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=17826 AND `source_type`=0 AND `id`=13; +UPDATE `smart_scripts` SET `action_param1`=180 WHERE `entryorguid`=8479 AND `source_type`=0 AND `id` IN (5,6); +UPDATE `smart_scripts` SET `action_param1`=120 WHERE `entryorguid`=7750 AND `source_type`=0 AND `id` IN (1,2); +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=48191, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=1806901 AND `source_type`=9 AND `id`=1; +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=24762, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=2362200 AND `source_type`=9 AND `id`=3; +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=106544, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=2724800 AND `source_type`=9 AND `id`=1; +UPDATE `smart_scripts` SET `action_type`=133, `action_param1`=0, `action_param2`=95366, `target_type`=1, `target_param1`=0, `target_param2`=0 WHERE `entryorguid`=3011600 AND `source_type`=9 AND `id`=0; +UPDATE `smart_scripts` SET `action_param1`=60 WHERE `entryorguid`=173265 AND `source_type`=1 AND `id`=0; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_04_world_from_335_was_2018_02_24_04_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_04_world_from_335_was_2018_02_24_04_world.sql new file mode 100644 index 00000000000..167b959156d --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_04_world_from_335_was_2018_02_24_04_world.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry`=66588 AND ConditionTypeOrReference=46; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 66588, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, '', "Flaming Spear could be casted only if the player is in taxi"), +(17, 0, 66588, 0, 1, 46, 0, 0, 0, 0, 0, 0, 0, '', "Flaming Spear could be casted only if the player is in taxi"); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_05_world_from_335_was_2018_02_24_05_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_05_world_from_335_was_2018_02_24_05_world.sql new file mode 100644 index 00000000000..0ff76b9a900 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_05_world_from_335_was_2018_02_24_05_world.sql @@ -0,0 +1,30 @@ +-- +UPDATE `conditions` SET `ConditionValue1`=11581 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9406; +UPDATE `conditions` SET `ConditionValue1`=11783 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9374; +UPDATE `conditions` SET `ConditionValue1`=11785 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9376; +UPDATE `conditions` SET `ConditionValue1`=11802 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9382; +UPDATE `conditions` SET `ConditionValue1`=11775 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9365; +UPDATE `conditions` SET `ConditionValue1`=11800 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9380; +UPDATE `conditions` SET `ConditionValue1`=11773 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9363; +UPDATE `conditions` SET `ConditionValue1`=11771 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9361; +UPDATE `conditions` SET `ConditionValue1`=11769 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9359; +UPDATE `conditions` SET `ConditionValue1`=11780 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9371; +UPDATE `conditions` SET `ConditionValue1`=11803 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9383; +UPDATE `conditions` SET `ConditionValue1`=11782 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9373; +UPDATE `conditions` SET `ConditionValue1`=11778 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9368; +UPDATE `conditions` SET `ConditionValue1`=11787 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9378; +UPDATE `conditions` SET `ConditionValue1`=11781 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9372; +UPDATE `conditions` SET `ConditionValue1`=11801 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9381; +UPDATE `conditions` SET `ConditionValue1`=11768 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9358; +UPDATE `conditions` SET `ConditionValue1`=11766 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9356; +UPDATE `conditions` SET `ConditionValue1`=11784 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9375; +UPDATE `conditions` SET `ConditionValue1`=11776 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9366; +UPDATE `conditions` SET `ConditionValue1`=11580 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9370; +UPDATE `conditions` SET `ConditionValue1`=11777 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9367; +UPDATE `conditions` SET `ConditionValue1`=11770 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9360; +UPDATE `conditions` SET `ConditionValue1`=11779 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9369; +UPDATE `conditions` SET `ConditionValue1`=11799 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9379; +UPDATE `conditions` SET `ConditionValue1`=11774 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9364; +UPDATE `conditions` SET `ConditionValue1`=11767 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9357; +UPDATE `conditions` SET `ConditionValue1`=11772 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9362; +UPDATE `conditions` SET `ConditionValue1`=11786 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9377; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_06_world_from_335_was_2018_02_25_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_06_world_from_335_was_2018_02_25_00_world_335.sql new file mode 100644 index 00000000000..8e5597649b3 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_06_world_from_335_was_2018_02_25_00_world_335.sql @@ -0,0 +1,25 @@ +/* +-- +DELETE FROM `gameobject_overrides` WHERE `spawnId` IN (76499, 76498, 76436, 76435, 76229, 76228, 76182, 76181, 76147, 76146, 76145, 76144, 76099, 76098, 76097, 76067, 76066, 76065, 76579, 76580); +INSERT INTO `gameobject_overrides` (`spawnId`, `faction`, `flags`) VALUES +(76499, 0, 16), +(76498, 0, 16), +(76436, 0, 16), +(76435, 0, 16), +(76229, 0, 16), +(76228, 0, 16), +(76182, 0, 16), +(76181, 0, 16), +(76147, 0, 16), +(76146, 0, 16), +(76145, 0, 16), +(76144, 0, 16), +(76099, 0, 16), +(76098, 0, 16), +(76097, 0, 16), +(76067, 0, 16), +(76066, 0, 16), +(76065, 0, 16), +(76579, 0, 16), +(76580, 0, 16); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_07_world_from_335_was_2018_02_28_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_07_world_from_335_was_2018_02_28_00_world_335.sql new file mode 100644 index 00000000000..781cff5226c --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_07_world_from_335_was_2018_02_28_00_world_335.sql @@ -0,0 +1,2 @@ +-- Fix prerequisite for quests "Hallowed Scroll" & "Glyphic Scroll" +-- UPDATE `quest_template_addon` SET `PrevQuestID`=364 WHERE `ID` IN (3097,3098); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_08_world_from_335_was_2018_02_28_01_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_08_world_from_335_was_2018_02_28_01_world_335.sql new file mode 100644 index 00000000000..c3d16de895a --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_08_world_from_335_was_2018_02_28_01_world_335.sql @@ -0,0 +1,2 @@ +-- Fix prerequisite for quest "Rot Hide Ichor" +-- UPDATE `quest_template_addon` SET `PrevQuestID`=439 WHERE `ID`=443; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_09_world_from_335_was_2018_02_28_02_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_09_world_from_335_was_2018_02_28_02_world_335.sql new file mode 100644 index 00000000000..9ac1010ff5b --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_09_world_from_335_was_2018_02_28_02_world_335.sql @@ -0,0 +1,11 @@ +/* +-- Advisor Duskingdawn --> Fix gossip text +DELETE FROM `gossip_menu` WHERE `MenuID`=7358 AND `TextID`=8787; +INSERT INTO `gossip_menu` (`MenuID`, `TextID`, `VerifiedBuild`) VALUES +(7358,8787,0); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=7358; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(14,7358,8789,0,0,16,0,512,0,0,0,0,0,"","Show gossip text if player is a Blood Elf"), +(14,7358,8787,0,0,16,0,1279,0,0,0,0,0,"","Show gossip text if player is not a Blood Elf"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_10_world_from_335_was_2018_02_28_03_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_10_world_from_335_was_2018_02_28_03_world_335.sql new file mode 100644 index 00000000000..0a77bc46bbe --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_10_world_from_335_was_2018_02_28_03_world_335.sql @@ -0,0 +1,17 @@ +/* +-- Gol'dir +DELETE FROM `creature_text` WHERE `CreatureID`=2316; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(2316,0,0,"Over here! Inside the room. Did you find the key to my chains? The human Borhuin has them.",12,1,100,22,0,0,598,0,"Gol'dir"); + +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=2316; +DELETE FROM `smart_scripts` WHERE `entryorguid`=2316 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2316,0,0,0,10,0,100,0,1,30,180000,180000,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Gol'dir - OOC LOS - Say Line 0"); + +-- Condition +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=2316; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22,1,2316,0,0,9,0,503,0,0,0,0,0,"","SAI triggers only if player has quest 'Gol'dir' taken"), +(22,1,2316,0,1,28,0,503,0,0,0,0,0,"","SAI triggers only if player has quest 'Gol'dir' completed"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_11_world_from_335_was_2018_02_28_04_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_11_world_from_335_was_2018_02_28_04_world_335.sql new file mode 100644 index 00000000000..9aaf0dccb80 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_11_world_from_335_was_2018_02_28_04_world_335.sql @@ -0,0 +1,27 @@ +/* +-- Blacksmith's Anvil +SET @GUID := 1508; +DELETE FROM `gameobject` WHERE `guid`=@GUID; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`) VALUES +(@GUID,1684,1,1657,1657,1,1,9920.39,2308.9,1330.78,3.32399,-0,-0,-0.995844,0.0910739,300,255,1,"",0); + +-- Mathiel +DELETE FROM `creature_text` WHERE `CreatureID`=6142; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(6142,0,0,"%s begins crafting...",16,0,100,0,0,0,2306,0,"Mathiel"), +(6142,1,0,"It is done. I have your weapon, $n.",12,0,100,1,0,0,2307,0,"Mathiel"); + +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=6142; +DELETE FROM `smart_scripts` WHERE `entryorguid`=6142 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=614200 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6142,0,0,0,20,0,100,0,1692,0,0,0,80,614200,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mathiel - On Quest 'Smith Mathiel' Finished - Run Script"), +(614200,9,0,0,0,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mathiel - On Script - Remove Npc Flag Questgiver"), +(614200,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,8,0,0,0,0,0,0,0.166394,"Mathiel - On Script - Set Orientation"), +(614200,9,2,0,0,0,100,0,1000,1000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mathiel - On Script - Say Line 0"), +(614200,9,3,0,0,0,100,0,0,0,0,0,17,233,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mathiel - On Script - Set Emote State 233"), +(614200,9,4,0,0,0,100,0,20000,20000,0,0,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mathiel - On Script - Set Emote State 0"), +(614200,9,5,0,0,0,100,0,1000,1000,0,0,66,0,0,0,0,0,0,8,0,0,0,0,0,0,1.71042,"Mathiel - On Script - Set Orientation"), +(614200,9,6,0,0,0,100,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mathiel - On Script - Say Line 2"), +(614200,9,7,0,0,0,100,0,0,0,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mathiel - On Script - Add Npc Flag Questgiver"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_12_world_from_335_was_2018_02_28_05_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_12_world_from_335_was_2018_02_28_05_world_335.sql new file mode 100644 index 00000000000..a577836fedc --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_12_world_from_335_was_2018_02_28_05_world_335.sql @@ -0,0 +1,29 @@ +/* +-- Quest "The Rescue" +-- Locked ball and chain +UPDATE `gameobject_template` SET `AIName`="SmartGameObjectAI" WHERE `entry` IN (1721,1722); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (1721,1722) AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(1721,1,0,0,70,0,100,0,2,0,0,0,45,1,1,0,0,0,0,19,2239,0,0,0,0,0,0,"Locked ball and chain - On Gameobject State Changed - Set Data to Drull"), +(1722,1,0,0,70,0,100,0,2,0,0,0,45,1,1,0,0,0,0,19,2238,0,0,0,0,0,0,"Locked ball and chain - On Gameobject State Changed - Set Data to Tog'thar"); + +-- Tog'thar / Drull +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry` IN (2238,2239); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (2238,2239) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (223800,223900) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2238,0,0,0,38,0,100,0,1,1,0,0,80,223800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tog'thar - On Data Set - Run Script"), +(2239,0,0,0,38,0,100,0,1,1,0,0,80,223900,0,0,0,0,0,1,0,0,0,0,0,0,0,"Drull - On Data Set - Run Script"), +(223800,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tog'thar - On Script - Say Line 0"), +(223800,9,1,0,0,0,100,0,4000,4000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tog'thar - On Script - Say Line 1"), +(223900,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Drull - On Script - Say Line 0"), +(223900,9,1,0,0,0,100,0,6000,6000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Drull - On Script - Say Line 1"); + +-- Texts +DELETE FROM `creature_text` WHERE `CreatureID` IN (2238,2239); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(2238,0,0,"Have you freed Drull yet? I don't know where he's being held.",12,1,100,6,0,0,593,0,"Tog'thar"), +(2238,1,0,"I will only slow you down, but no pink-skinned humans will keep me from freedom!",12,1,100,15,0,0,595,0,"Tog'thar"), +(2239,0,0,"Ah, it is good to be free of my bonds! Have you freed Tog'thar yet? The humans split us up after our capture.",12,1,100,4,0,0,592,0,"Drull"), +(2239,1,0,"Go on ahead without me! I will make my own way to Tarren Mill.",12,1,100,5,0,0,594,0,"Drull"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_13_world_from_335_was_2018_02_28_06_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_13_world_from_335_was_2018_02_28_06_world_335.sql new file mode 100644 index 00000000000..c27a7378e7b --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_13_world_from_335_was_2018_02_28_06_world_335.sql @@ -0,0 +1,27 @@ +/* +-- Quest "Helcular's Revenge (Part 2)" +-- Helcular's Grave +UPDATE `gameobject_template` SET `AIName`="SmartGameObjectAI" WHERE `entry`=1767; +DELETE FROM `smart_scripts` WHERE `entryorguid`=1767 AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(1767,1,0,0,20,0,100,0,553,0,0,0,12,2433,3,600000,0,0,0,8,0,0,0,-742.94,-615.67,18.72,1.61731,"Helcular's Grave - On Quest 'Helcular's Revenge (Part 2)' Rewarded - Summon Creature 'Helcular's Remains'"); + +-- Condition +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=1767; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22,1,1767,1,0,29,1,2433,200,0,1,0,0,"","SAI triggers only if Helcular's Remains is not already spawned"); + +-- Helcular's Remains +DELETE FROM `smart_scripts` WHERE `entryorguid`=2433 AND `source_type`=0 AND `id` IN (3,4); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2433,0,3,0,11,0,100,0,0,0,0,0,89,10,0,0,0,0,0,1,0,0,0,0,0,0,0,"Helcular's Remains - On Respawn - Start Random Movement"), +(2433,0,4,0,11,0,100,0,0,0,0,0,11,3390,0,0,0,0,0,1,0,0,0,0,0,0,0,"Helcular's Remains - On Respawn - Cast 'Helcular's Spawn'"); + +UPDATE `creature_text` SET `Emote`=15 WHERE `CreatureID`=2433 AND `GroupID`=0; +UPDATE `creature_text` SET `Emote`=0 WHERE `CreatureID`=2433 AND `GroupID`=1; +DELETE FROM `creature_text` WHERE `CreatureID`=2433 AND `GroupID`=0 AND `ID`=3; +DELETE FROM `creature_text` WHERE `CreatureID`=2433 AND `GroupID`=1 AND `ID`=1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(2433,0,3,"I returned from the grave to take my revenge!",14,0,100,15,0,0,599,0,"Helcular's Remains"), +(2433,1,1,"Die in the name of the Dark Lady, $n.",14,0,100,0,0,0,600,0,"Helcular's Remains"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_14_world_from_335_was_2018_03_01_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_14_world_from_335_was_2018_03_01_00_world_335.sql new file mode 100644 index 00000000000..52f3a7ea26d --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_14_world_from_335_was_2018_03_01_00_world_335.sql @@ -0,0 +1,2 @@ +-- Hit debuff stacking (Insect Swarm & Scorpid Sting) +-- UPDATE `spell_group_stack_rules` SET `stack_rule`= 3 WHERE `group_id`= 1060; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_15_world_from_335_was_2018_03_03_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_15_world_from_335_was_2018_03_03_00_world_335.sql new file mode 100644 index 00000000000..495c53ee2eb --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_15_world_from_335_was_2018_03_03_00_world_335.sql @@ -0,0 +1,2 @@ +-- Mountaineer Pebblebitty +-- UPDATE `conditions` SET `ConditionTypeOrReference`=14, `Comment`="Show gossip menu option only if quest 'The Horn of the Beast' is not taken" WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=1201; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_16_world_from_335_was_2018_03_03_01_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_16_world_from_335_was_2018_03_03_01_world_335.sql new file mode 100644 index 00000000000..3ef759e8201 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_16_world_from_335_was_2018_03_03_01_world_335.sql @@ -0,0 +1,6 @@ +/* +-- Sha'ni Proudtusk's Remains +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=160445; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22,1,160445,1,0,29,1,9136,200,0,1,0,0,"","SAI triggers only if Sha'ni Proudtusk is not already spawned"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_17_world_from_335_was_2018_03_03_02_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_17_world_from_335_was_2018_03_03_02_world_335.sql new file mode 100644 index 00000000000..3e64be1682a --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_17_world_from_335_was_2018_03_03_02_world_335.sql @@ -0,0 +1,2 @@ +-- Fix gossip option for Spark Nilminer +-- UPDATE `gossip_menu_option` SET `ActionMenuID`=2721 WHERE `MenuID`=2422; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_18_world_from_335_was_2018_03_03_03_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_18_world_from_335_was_2018_03_03_03_world_335.sql new file mode 100644 index 00000000000..87f495c7e01 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_18_world_from_335_was_2018_03_03_03_world_335.sql @@ -0,0 +1,14 @@ +/* +-- Jes'rimon - add Gossip Option +DELETE FROM `gossip_menu` WHERE `MenuID`=2190; +INSERT INTO `gossip_menu` (`MenuID`, `TextID`, `VerifiedBuild`) VALUES +(2190,2823,0); + +DELETE FROM `gossip_menu_option` WHERE `MenuID`=2189; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(2189,0,0,"Where is Un'Goro Crater?",5184,1,1,2190,0,0,0,"",0,0); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=2189; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(15,2189,0,0,0,9,0,4300,0,0,0,0,0,"","Show gossip option if quest 'Bone-Bladed Weapons' is taken"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_19_world_from_335_was_2018_03_03_04_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_19_world_from_335_was_2018_03_03_04_world_335.sql new file mode 100644 index 00000000000..8f5e1b57755 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_19_world_from_335_was_2018_03_03_04_world_335.sql @@ -0,0 +1,5 @@ +/* +-- Blastmaster Emi Shortfuse +UPDATE `creature_text` SET `Text`="FIRE IN THE HOLE!", `Language`=0, `BroadcastTextId`=4137 WHERE `CreatureID`=7998 AND `GroupID`=11; +UPDATE `creature_text` SET `BroadcastTextId`=4207 WHERE `CreatureID`=7998 AND `GroupID`=13; +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_20_world_from_335_was_2018_03_03_05_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_20_world_from_335_was_2018_03_03_05_world_335.sql new file mode 100644 index 00000000000..e96a83ceb91 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_20_world_from_335_was_2018_03_03_05_world_335.sql @@ -0,0 +1,31 @@ +/* +-- Laris Geardawdle - fix Gossip Texts +DELETE FROM `gossip_menu` WHERE `MenuID`=2405 AND `TextID` IN (3099,3098,3097); +DELETE FROM `gossip_menu` WHERE `MenuID` IN (2406,2407,2408); +INSERT INTO `gossip_menu` (`MenuID`, `TextID`, `VerifiedBuild`) VALUES +(2405,3097,0), +(2405,3099,0), +(2405,3098,0), +(2406,3100,0), +(2407,3101,0), +(2408,3102,0); + +DELETE FROM `gossip_menu_option` WHERE `MenuID` IN (2406,2407,2405); +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(2405,0,0,"Is there a difference between ooze and slime?",5450,1,1,2406,0,0,0,"",0,0), +(2406,0,0,"What do you mean by \"pure?\"",5452,1,1,2407,0,0,0,"",0,0), +(2407,0,0,"Are there any areas you can think of that would be so untouched?",5454,1,1,2408,0,0,0,"",0,0); + +DELETE FROM `npc_text` WHERE `ID` IN (3097,3099); +INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_1`) VALUES +(3097,"Incredible! Amazing! I don't even know what this means!","",5447,0,1,0), +(3099,"There must be someplace on Azeroth that we can find oozes uncorrupted by the Scourge or anything else. But where?!","",5449,0,1,0); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` IN (14,15) AND `SourceGroup`=2405; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(14,2405,3097,0,0,8,0,4512,0,0,0,0,0,"","Show gossip text 3099 if quest 'A Little Slime Goes a Long Way (Part 1)' is rewarded"), +(14,2405,3097,0,0,9,0,4513,0,0,1,0,0,"","Show gossip text 3099 if quest 'A Little Slime Goes a Long Way (Part 2)' is not taken"), +(14,2405,3099,0,0,9,0,4513,0,0,0,0,0,"","Show gossip text 3099 if quest 'A Little Slime Goes a Long Way (Part 2)' is taken"), +(14,2405,3098,0,0,8,0,4513,0,0,0,0,0,"","Show gossip text 3098 if quest 'A Little Slime Goes a Long Way (Part 2)' is rewarded"), +(15,2405,0,0,0,9,0,4513,0,0,0,0,0,"","Show gossip option if quest 'A Little Slime Goes a Long Way (Part 2)' is taken"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_21_world_from_335_was_2018_03_03_06_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_21_world_from_335_was_2018_03_03_06_world_335.sql new file mode 100644 index 00000000000..bca7ffb59c1 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_21_world_from_335_was_2018_03_03_06_world_335.sql @@ -0,0 +1,29 @@ +/* +-- Talen +DELETE FROM `creature_text` WHERE `CreatureID`=3846; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(3846,0,0,"This statuette must hold a hidden compartment....",12,7,100,1,0,0,0,0,"Talen"), +(3846,1,0,"%s searches the ancient statuette.",16,0,100,0,0,0,0,0,"Talen"), +(3846,2,0,"It's locked! NO!!",12,7,100,15,0,0,0,0,"Talen"), +(3846,3,0,"$n, I am in need of your help once again.",12,7,100,1,0,0,1355,0,"Talen"); + +DELETE FROM `smart_scripts` WHERE `entryorguid`=3846 AND `source_type`=0 AND `id`=1; +DELETE FROM `smart_scripts` WHERE `entryorguid`=384600 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(3846,0,1,0,20,0,100,0,1007,0,0,0,80,384600,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Quest 'The Ancient Statuette' Finished - Run Script"), +(384600,9,0,0,0,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Remove Npc Flag Questgiver"), +(384600,9,1,0,0,0,100,0,0,0,0,0,91,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Remove Flag Standstate 'Sit Down'"), +(384600,9,2,0,0,0,100,0,2000,2000,0,0,66,0,0,0,0,0,0,8,0,0,0,0,0,0,6.16678,"Talen - On Script - Set Orientation"), +(384600,9,3,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Say Line 0"), +(384600,9,4,0,0,0,100,0,4000,4000,0,0,90,8,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Set Flag Standstate 'Kneel'"), +(384600,9,5,0,0,0,100,0,1000,1000,0,0,50,18603,12,0,0,0,0,8,0,0,0,3471.69,846.893,5.39909,4.67058,"Talen - On Script - Summon Gameobject 'Ancient Statuette'"), +(384600,9,6,0,0,0,100,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Say Line 1"), +(384600,9,7,0,0,0,100,0,8000,8000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Say Line 2"), +(384600,9,8,0,0,0,100,0,4000,4000,0,0,91,8,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Remove Flag Standstate 'Kneel'"), +(384600,9,9,0,0,0,100,0,2000,2000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Set Orientation"), +(384600,9,10,0,0,0,100,0,0,0,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Say Line 3"), +(384600,9,11,0,0,0,100,0,0,0,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Add Npc Flag Questgiver"), +(384600,9,12,0,0,0,100,0,20000,20000,0,0,90,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talen - On Script - Set Flag Standstate Sit Down"); + +UPDATE `creature_template` SET `npcflag`=2, `gossip_menu_id`=0 WHERE `entry`=3846; -- Fix NPC flag and remove gossip +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_22_world_from_335_was_2018_03_03_07_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_22_world_from_335_was_2018_03_03_07_world_335.sql new file mode 100644 index 00000000000..3a4788028a0 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_22_world_from_335_was_2018_03_03_07_world_335.sql @@ -0,0 +1,146 @@ +/* +-- Ember Worg +UPDATE `smart_scripts` SET `event_param1`=6000, `event_param2`=13000, `event_param3`=17000, `event_param4`=24000 WHERE `entryorguid`=9690 AND `source_type`=0 AND `id`=0; + +-- Ember Worg +UPDATE `smart_scripts` SET `event_param1`=8000, `event_param2`=12000, `event_param3`=18000, `event_param4`=22000 WHERE `entryorguid`=9694 AND `source_type`=0 AND `id`=0; + +-- Ember Worg +UPDATE `smart_scripts` SET `event_param1`=7000, `event_param2`=11000, `event_param3`=16000, `event_param4`=20000 WHERE `entryorguid`=9697 AND `source_type`=0 AND `id`=0; + +-- Deathmaw +UPDATE `smart_scripts` SET `event_param1`=8000, `event_param2`=11000, `event_param3`=13000, `event_param4`=16000 WHERE `entryorguid`=10077 AND `source_type`=0 AND `id`=0; + +-- Flamekin Sprite +DELETE FROM `smart_scripts` WHERE `entryorguid`=9777 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(9777,0,0,0,25,0,100,0,0,0,0,0,11,8876,0,0,0,0,0,1,0,0,0,0,0,0,0,"Flamekin Sprite - On Reset - Cast 'Thrash'"); + +-- Black Wyrmkin +UPDATE `smart_scripts` SET `event_param3`=15000, `event_param4`=19000, `action_param2`=0 WHERE `entryorguid`=7041 AND `source_type`=0 AND `id`=1; + +-- Firegut Ogres +UPDATE `smart_scripts` SET `event_chance`=15 WHERE `entryorguid` IN (7033,7034,7035,9604) AND `source_type`=0 AND `id`=0; + +-- Black Dragonspawn +UPDATE `smart_scripts` SET `event_param1`=8000, `event_param2`=12000, `event_param3`=18000, `event_param4`=24000 WHERE `entryorguid`=7040 AND `source_type`=0 AND `id`=0; +UPDATE `smart_scripts` SET `event_param1`=5000, `event_param2`=7000, `event_param3`=9000, `event_param4`=11000 WHERE `entryorguid`=7040 AND `source_type`=0 AND `id`=1; + +-- Venomtip Scorpid +DELETE FROM `smart_scripts` WHERE `entryorguid`=9691 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(9691,0,0,0,25,0,100,0,0,0,0,0,11,3616,0,0,0,0,0,1,0,0,0,0,0,0,0,"Venomtip Scorpid - On Reset - Cast 'Poison Proc'"); + +-- Deathlash Scorpid +UPDATE `smart_scripts` SET `event_param1`=8000, `event_param2`=12000, `event_param3`=12000, `event_param4`=18000 WHERE `entryorguid`=9695 AND `source_type`=0 AND `id`=0; + +-- War Reaver +DELETE FROM `smart_scripts` WHERE `entryorguid`=7039 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7039,0,0,0,25,0,100,0,0,0,0,0,11,8876,0,0,0,0,0,1,0,0,0,0,0,0,0,"War Reaver - On Reset - Cast 'Thrash'"), +(7039,0,1,0,0,0,100,0,7000,11000,17000,21000,11,10966,0,0,0,0,0,2,0,0,0,0,0,0,0,"War Reaver - In Combat - Cast 'Uppercut'"); + +-- Malfunctioning Reaver +DELETE FROM `smart_scripts` WHERE `entryorguid`=8981 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(8981,0,0,0,25,0,100,0,0,0,0,0,11,8876,0,0,0,0,0,1,0,0,0,0,0,0,0,"Malfunctioning Reaver - On Reset - Cast 'Thrash'"), +(8981,0,1,0,0,0,100,0,7000,11000,17000,21000,11,10966,0,0,0,0,0,2,0,0,0,0,0,0,0,"Malfunctioning Reaver - In Combat - Cast 'Uppercut'"); + +-- Thaurissan Firewalker +UPDATE `smart_scripts` SET `action_param2`=0 WHERE `entryorguid`=7037 AND `source_type`=0 AND `id`=1; + +-- Thaurissan Spy +DELETE FROM `smart_scripts` WHERE `entryorguid`=7036 AND `source_type`=0 AND `id`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7036,0,0,0,25,0,100,0,0,0,0,0,11,3616,0,0,0,0,0,1,0,0,0,0,0,0,0,"Thaurissan Spy - On Reset - Cast 'Poison Proc'"); + +-- Thaurissan Agent +UPDATE `smart_scripts` SET `event_param3`=16000, `event_param4`=20000 WHERE `entryorguid`=7038 AND `source_type`=0 AND `id`=1; + +-- Thauris Balgarr +DELETE FROM `smart_scripts` WHERE `entryorguid`=8978 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(8978,0,0,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Thauris Balgarr - In Combat CMC - Cast 'Shoot'"), +(8978,0,1,0,9,0,100,0,0,20,11000,15000,11,6533,0,0,0,0,0,2,0,0,0,0,0,0,0,"Thauris Balgarr - Within 0-20 Range - Cast 'Net'"), +(8978,0,2,0,0,0,100,0,1000,3000,19000,23000,11,11802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Thauris Balgarr - In Combat - Cast 'Dark Iron Land Mine'"); + +-- Dark Iron Land Mine +UPDATE `smart_scripts` SET `event_flags`=1 WHERE `entryorguid`=8035 AND `source_type`=0; + +-- Scalding Drake +DELETE FROM `smart_scripts` WHERE `entryorguid`=7045 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7045,0,0,0,9,0,100,0,0,5,8000,16000,11,9573,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scalding Drake - Within 0-5 Range - Cast 'Flame Breath'"); + +-- Blackrock Sorcerer +UPDATE `smart_scripts` SET `event_param1`=8000, `event_param2`=12000, `event_param3`=14000, `event_param4`=19000, `action_param2`=0 WHERE `entryorguid`=7026 AND `source_type`=0 AND `id`=1; + +-- Blackrock Warlock +UPDATE `smart_scripts` SET `action_param2`=32 WHERE `entryorguid`=7028 AND `source_type`=0 AND `id` IN (1,2); +UPDATE `smart_scripts` SET `event_param3`=19000, `event_param4`=24000 WHERE `entryorguid`=7028 AND `source_type`=0 AND `id`=1; + +-- Gor'tesh +DELETE FROM `smart_scripts` WHERE `entryorguid`=9176 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(9176,0,0,0,25,0,100,0,0,0,0,0,11,8876,0,0,0,0,0,1,0,0,0,0,0,0,0,"Gor'tesh - On Reset - Cast 'Thrash'"), +(9176,0,1,0,0,0,100,0,5000,7000,12000,15000,11,12734,0,0,0,0,0,1,0,0,0,0,0,0,0,"Gor'tesh - In Combat - Cast 'Ground Smash'"), +(9176,0,2,0,0,0,100,0,9000,11000,14000,18000,11,10101,0,0,0,0,0,2,0,0,0,0,0,0,0,"Gor'tesh - In Combat - Cast 'Knock Away'"); + +-- Flamescale Dragonspawn +UPDATE `smart_scripts` SET `event_param1`=8000, `event_param2`=12000, `event_param3`=13000, `event_param4`=17000 WHERE `entryorguid`=7042 AND `source_type`=0 AND `id`=1; + +-- Flamescale Wyrmkin +UPDATE `smart_scripts` SET `action_param2`=0 WHERE `entryorguid`=7043 AND `source_type`=0 AND `id`=1; + +-- Searscale Drake +DELETE FROM `smart_scripts` WHERE `entryorguid`=7046 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7046,0,0,0,9,0,100,0,0,5,8000,16000,11,8873,0,0,0,0,0,2,0,0,0,0,0,0,0,"Searscale Drake - Within 0-5 Range - Cast 'Flame Breath'"); + +-- Flamescale Broodling +UPDATE `smart_scripts` SET `action_param2`=0 WHERE `entryorguid`=7049 AND `source_type`=0 AND `id`=1; + +-- Firetail Scorpid +UPDATE `smart_scripts` SET `event_param1`=6000, `event_param2`=12000, `event_param3`=12000, `event_param4`=20000, `action_param2`=0 WHERE `entryorguid`=9698 AND `source_type`=0 AND `id`=0; +UPDATE `smart_scripts` SET `event_param1`=12000, `event_param2`=16000, `event_param3`=14000, `event_param4`=18000, `action_param2`=32 WHERE `entryorguid`=9698 AND `source_type`=0 AND `id`=1; + +-- Terrorspark +DELETE FROM `smart_scripts` WHERE `entryorguid`=10078 AND `source_type`=0 AND `id` IN (1,2); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(10078,0,1,0,0,0,100,0,3000,3000,3000,3000,11,11968,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terrorspark - In Combat - Cast 'Fire Shield'"), +(10078,0,2,3,0,0,100,0,11000,15000,33000,37000,11,15710,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terrorspark - In Combat - Cast 'Summon Flamekin Torcher'"); + +-- Blackrock Battlemaster +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=7029; +DELETE FROM `smart_scripts` WHERE `entryorguid`=7029 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7029,0,0,0,4,0,100,0,0,0,0,0,11,674,0,0,0,0,0,1,0,0,0,0,0,0,0,"Blackrock Battlemaster - On Aggro - Cast 'Dual Wield'"); + +-- Volchan +DELETE FROM `smart_scripts` WHERE `entryorguid`=10119 AND `source_type`=0 AND `id` IN (0,2); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(10119,0,0,0,0,0,100,0,3000,3000,3000,3000,11,13376,0,0,0,0,0,1,0,0,0,0,0,0,0,"Volchan - In Combat - Cast 'Fire Shield'"), +(10119,0,2,0,0,0,100,0,11000,13000,9000,24000,11,12470,0,0,0,0,0,1,0,0,0,0,0,0,0,"Volchan - In Combat - Cast 'Fire Nova'"); + +-- Hematos +DELETE FROM `smart_scripts` WHERE `entryorguid`=8976 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(8976,0,0,0,9,0,100,0,0,5,8000,16000,11,9573,0,0,0,0,0,2,0,0,0,0,0,0,0,"Hematos - Within 0-5 Range - Cast 'Flame Breath'"); + +-- Scarshield Sentry +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=9044; +DELETE FROM `smart_scripts` WHERE `entryorguid`=9044 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(9044,0,0,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Scarshield Sentry - Combat CMC - Cast 'Shoot'"), +(9044,0,1,0,0,0,100,0,7000,11000,11000,15000,11,14443,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scarshield Sentry - In Combat - Cast 'Multi-Shot'"), +(9044,0,2,0,0,0,100,0,7000,12000,10000,16000,11,14897,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scarshield Sentry - In Combat - Cast 'Slowing Poison'"); + +-- Scarshield Grunt +DELETE FROM `smart_scripts` WHERE `entryorguid`=9043 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(9043,0,0,0,0,0,100,0,3000,5000,3000,5000,11,11976,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scarshield Grunt - In Combat - Cast 'Strike'"); + +-- Fix bytes2 for some creatures +UPDATE `creature_addon` SET `bytes2`=2 WHERE `guid` IN (SELECT `guid` FROM `creature` WHERE `id` IN (7038,8978)); +UPDATE `creature_template_addon` SET `bytes2`=2 WHERE `entry`=9044; +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_23_world_from_335_was_2018_03_03_08_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_23_world_from_335_was_2018_03_03_08_world_335.sql new file mode 100644 index 00000000000..f451d8f0b7f --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_23_world_from_335_was_2018_03_03_08_world_335.sql @@ -0,0 +1,14 @@ +/* +DELETE FROM `quest_greeting` WHERE `ID` IN (5204,1776,3441,4500,1950,7777,9536,6986,4485,7825); +INSERT INTO `quest_greeting` (`ID`, `Type`, `GreetEmoteType`, `GreetEmoteDelay`, `Greeting`, `VerifiedBuild`) VALUES +(5204,0,0,0,"If we are to make our place in this world, then we will do so through study, and through the will to ignore our fading human instincts.",0), -- Apothecary Zinge +(1776,0,0,0,"We spent so much of our lives in fight, memories of peaceful times grow evermore distant.",0), -- Magtoor +(3441,0,0,0,"To hunt a beast, one must know that beast. One must learn and respect its ways.$B$BTo do otherwise is not to hunt. To do otherwise is merely to kill.",0), -- Melor Stonehoof +(4500,0,0,0,"Overlord Mok'Morokk boss. You do what I say.",0), -- Overlord Mok'Morokk +(7777,0,0,0,"",0), -- Rok Orhan +(9536,0,0,0,"The quest for wealth is the only goal for a respectable goblin.$B$BWell, maybe wealth... and a big, loud death!",0), -- Maxwort Uberglint +(1950,0,0,0,"My brother and I are on a scouting mission, but we are holed up in this farmhouse. The Deathstalkers need your help!",0), -- Rane Yorick +(7825,0,0,0,"",0), -- Oran Snakewrithe +(6986,0,1,0,"My name is Dran Droffers, and this over here is my dummy son Malton. If you need salvage, or are looking to sell salvage, then we're who you need to be talking to!",0), -- Dran Droffers +(4485,0,1,0,"The days grow long, and still no end to the conflicts of these lands can be seen. It takes no spell caster to know that much. Take up a blade while you can, $c. War can come to our doors at any time, and if I'm not mistaken, you look to be one who revels in it.",0); -- Belgrom Rockmaul +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_24_world_from_335_was_2018_03_04_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_24_world_from_335_was_2018_03_04_00_world_335.sql new file mode 100644 index 00000000000..9e7767a3dc8 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_05_24_world_from_335_was_2018_03_04_00_world_335.sql @@ -0,0 +1,76 @@ +/* +-- Fix availability for quest "Zamek's Distraction" +UPDATE `quest_template_addon` SET `PrevQuestID`=0 WHERE `ID`=1191; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=19 AND `SourceEntry`=1191; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(19,0,1191,0,0,28,0,1190,0,0,0,0,0,'',"Show quest 'Zamek's Distraction' only if quest 'Keeping Pace' is taken but not rewarded"), +(19,0,1191,0,1,8,0,1190,0,0,0,0,0,'',"Show quest 'Zamek's Distraction' only if quest 'Keeping Pace' is rewarded"), +(19,0,1191,0,1,14,0,1194,0,0,0,0,0,'',"Show quest 'Zamek's Distraction' only if quest 'Rizzle's Schematics' is not taken and not rewarded"); + +-- Add gossip text for gameobjects "Rizzle's Guarded Plans" & "Rizzle's Unguarded Plans" +UPDATE `gossip_menu` SET `TextID`=7182 WHERE `MenuID`=6029; +UPDATE `gossip_menu` SET `TextID`=7181 WHERE `MenuID`=6030; + +-- Texts +DELETE FROM `creature_text` WHERE `CreatureID` IN (4709,4720); +INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(4709,0,0,'Hehehe! Things go boom!',12,0,100,11,0,0,1540,0,'Zamek'), +(4720,0,0,'What was that!',14,0,100,5,0,0,1541,0,'Rizzle Brassbolts'), +(4720,1,0,"Bloody... Must have been the goblins... Let's see how bad the damage is.",12,0,100,5,0,0,1542,0,'Rizzle Brassbolts'), +(4720,2,0,"Guess there's nothing more to be done. Blast!",12,0,100,6,0,0,1543,0,'Rizzle Brassbolts'); + +-- Waypoints +DELETE FROM `waypoints` WHERE `entry` IN (4709,4720); +INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES +(4709, 1,-6237.13,-3911.58,-60.5103,'Zamek'), +(4709, 2,-6257.43,-3879.56,-58.8595,'Zamek'), +(4709, 3,-6267.61,-3850.91,-58.7503,'Zamek'), +(4709, 4,-6266.24,-3846.35,-58.7503,'Zamek'), +(4709, 5,-6267.61,-3850.91,-58.7503,'Zamek'), +(4709, 6,-6257.43,-3879.56,-58.8595,'Zamek'), +(4709, 7,-6237.13,-3911.58,-60.5103,'Zamek'), +(4709, 8,-6226.13,-3944.94,-58.6251,'Zamek'), +(4720, 1,-6243.39,-3845.91,-58.7498,'Rizzle Brassbolts'), +(4720, 2,-6250.63,-3847.35,-58.7491,'Rizzle Brassbolts'), +(4720, 3,-6255.06,-3853.64,-58.7491,'Rizzle Brassbolts'), +(4720, 4,-6262.2, -3851.84,-58.7491,'Rizzle Brassbolts'), +(4720, 5,-6266.24,-3846.35,-58.7503,'Rizzle Brassbolts'), +(4720, 6,-6262.2, -3851.84,-58.7491,'Rizzle Brassbolts'), +(4720, 7,-6255.06,-3853.64,-58.7491,'Rizzle Brassbolts'), +(4720, 8,-6250.63,-3847.35,-58.7491,'Rizzle Brassbolts'), +(4720, 9,-6243.39,-3845.91,-58.7498,'Rizzle Brassbolts'), +(4720,10,-6236.99,-3831.23,-58.1364,'Rizzle Brassbolts'); + +-- Zamek +DELETE FROM `smart_scripts` WHERE `entryorguid`=4709 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=470900 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(4709,0,0,0,20,0,100,0,1191,0,0,0,53,1,4709,0,0,0,0,1,0,0,0,0,0,0,0,"Zamek - On Quest 'Zamek's Distraction' Finished - Start Waypoint"), +(4709,0,1,0,20,0,100,0,1191,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Zamek - On Quest 'Zamek's Distraction' Finished - Remove NPC Flag Questgiver"), +(4709,0,2,0,40,0,100,0,4,4709,0,0,80,470900,0,0,0,0,0,1,0,0,0,0,0,0,0,'Zamek - On Waypoint 4 Reached - Run Script'), +(4709,0,3,0,40,0,100,0,8,4709,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Zamek - On Waypoint 8 Reached - Set Orientation'), +(470900,9,0,0,0,0,100,0,0,0,0,0,54,7000,0,0,0,0,0,1,0,0,0,0,0,0,0,'Zamek - On Script - Pause Waypoint'), +(470900,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,8,0,0,0,0,0,0,0.943443,'Zamek - On Script - Set Orientation'), +(470900,9,2,0,0,0,100,0,2000,2000,0,0,50,144065,8,0,0,0,0,8,0,0,0,-6265.67,-3845.57,-58.75,0.943443,"Zamek - On Script - Summon Gameobject 'Explosive Charge'"), +(470900,9,3,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Zamek - On Script - Say Line 0'), +(470900,9,4,0,0,0,100,0,7000,7000,0,0,9,0,0,0,0,0,0,20,144065,0,0,0,0,0,0,"Zamek - On Script - Activate Gameobject 'Explosive Charge'"), +(470900,9,5,0,0,0,100,0,1000,1000,0,0,45,1,1,0,0,0,0,19,4720,0,0,0,0,0,0,'Zamek - On Script - Set Data to Rizzle Brassbolts'), +(470900,9,6,0,0,0,100,0,60000,60000,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'Zamek - On Script - Add NPC Flag Questgiver'); + +-- Rizzle Brassbolts +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=4720; +DELETE FROM `smart_scripts` WHERE `entryorguid`=4720 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (472000,472001) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(4720,0,0,0,38,0,100,0,1,1,0,0,80,472000,0,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Data Set - Run Script'), +(4720,0,1,0,40,0,100,0,5,4720,0,0,80,472001,0,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Waypoint 5 Reached - Run Script'), +(4720,0,2,0,40,0,100,0,10,4720,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Waypoint 10 Reached - Set Orientation'), +(472000,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Script - Say Line 0'), +(472000,9,1,0,0,0,100,0,4000,4000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Script - Say Line 1'), +(472000,9,2,0,0,0,100,0,0,0,0,0,53,0,4720,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Script - Start Waypoint'), +(472000,9,3,0,0,0,100,0,0,0,0,0,41,0,60,0,0,0,0,14,17087,179888,0,0,0,0,0,"Rizzle Brassbolts - On Script - Despawn Gameobject 'Rizzle's Guarded Plans'"), +(472000,9,4,0,0,0,100,0,0,0,0,0,70,60,0,0,0,0,0,14,13621,20805,0,0,0,0,0,"Rizzle Brassbolts - On Script - Respawn Gameobject 'Rizzle's Unguarded Plans'"), +(472001,9,0,0,0,0,100,0,0,0,0,0,54,25000,0,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Script - Pause Waypoint'), +(472001,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,8,0,0,0,0,0,0,0.943443,'Rizzle Brassbolts - On Script - Set Orientation'), +(472001,9,2,0,0,0,100,0,20000,20000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'Rizzle Brassbolts - On Script - Say Line 2'); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_00_world_from_335_was_2018_03_06_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_00_world_from_335_was_2018_03_06_00_world.sql new file mode 100644 index 00000000000..1df33e4bcf8 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_00_world_from_335_was_2018_03_06_00_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_loot_template` SET `QuestRequired`=1 WHERE `Item` IN (24426,24427); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_01_world_from_335_was_2018_03_06_01_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_01_world_from_335_was_2018_03_06_01_world.sql new file mode 100644 index 00000000000..d37755f6d98 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_01_world_from_335_was_2018_03_06_01_world.sql @@ -0,0 +1,80 @@ +-- +-- Gnomeregan Evacuee +DELETE FROM `smart_scripts` WHERE `entryorguid`=7843 AND `source_type`=0 AND `id`=6; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7843,0,6,0,6,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Gnomeregan Evacuee - On Just Died - Say Line 0"); + +DELETE FROM `creature_text` WHERE `CreatureID`=7843; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(7843,0,0,"Aaaaahhh! So close to escaping.",12,7,100,0,0,0,3829,0,"Gnomeregan Evacuee"); + +-- Addled Leper +DELETE FROM `smart_scripts` WHERE `entryorguid`=6221 AND `source_type`=0 AND `id`=6; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6221,0,6,0,4,0,40,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Addled Leper - On Aggro - Say Line 0"); + +DELETE FROM `creature_text` WHERE `CreatureID`=6221; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(6221,0,0,"No gnome will be left behind.",12,7,100,0,0,0,2422,0,"Addled Leper"), +(6221,0,1,"The troggs...they never stop coming. Die trogg! Die!",12,7,100,0,0,0,2423,0,"Addled Leper"), +(6221,0,2,"This sickness clouds my vision, but I know you must be a trogg. Die foul invader!",12,7,100,0,0,0,2424,0,"Addled Leper"), +(6221,0,3,"A foul trogg if ever I saw one. Die!",12,7,100,0,0,0,2425,0,"Addled Leper"); + +-- Leprous Technician +DELETE FROM `smart_scripts` WHERE `entryorguid`=6222 AND `source_type`=0 AND `id`=5; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6222,0,5,0,4,0,20,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Leprous Technician - On Aggro - Say Line 1"); + +DELETE FROM `creature_text` WHERE `CreatureID`=6222 AND `GroupID`=1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(6222,1,0,"No gnome will be left behind.",12,7,100,0,0,0,2422,0,"Leprous Technician"), +(6222,1,1,"The troggs...they never stop coming. Die trogg! Die!",12,7,100,0,0,0,2423,0,"Leprous Technician"), +(6222,1,2,"This sickness clouds my vision, but I know you must be a trogg. Die foul invader!",12,7,100,0,0,0,2424,0,"Leprous Technician"), +(6222,1,3,"A foul trogg if ever I saw one. Die!",12,7,100,0,0,0,2425,0,"Leprous Technician"); + +-- Leprous Defender +DELETE FROM `smart_scripts` WHERE `entryorguid`=6223 AND `source_type`=0 AND `id`=5; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6223,0,5,0,4,0,20,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Leprous Defender - On Aggro - Say Line 1"); + +DELETE FROM `creature_text` WHERE `CreatureID`=6223 AND `GroupID`=1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(6223,1,0,"No gnome will be left behind.",12,7,100,0,0,0,2422,0,"Leprous Defender"), +(6223,1,1,"The troggs...they never stop coming. Die trogg! Die!",12,7,100,0,0,0,2423,0,"Leprous Defender"), +(6223,1,2,"This sickness clouds my vision, but I know you must be a trogg. Die foul invader!",12,7,100,0,0,0,2424,0,"Leprous Defender"), +(6223,1,3,"A foul trogg if ever I saw one. Die!",12,7,100,0,0,0,2425,0,"Leprous Defender"); + +-- Leprous Assistant +DELETE FROM `smart_scripts` WHERE `entryorguid`=7603 AND `source_type`=0 AND `id`=2; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7603,0,2,0,4,0,20,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Leprous Assistant - On Aggro - Say Line 1"); + +DELETE FROM `creature_text` WHERE `CreatureID`=7603 AND `GroupID`=1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(7603,1,0,"No gnome will be left behind.",12,7,100,0,0,0,2422,0,"Leprous Assistant"), +(7603,1,1,"The troggs...they never stop coming. Die trogg! Die!",12,7,100,0,0,0,2423,0,"Leprous Assistant"), +(7603,1,2,"This sickness clouds my vision, but I know you must be a trogg. Die foul invader!",12,7,100,0,0,0,2424,0,"Leprous Assistant"), +(7603,1,3,"A foul trogg if ever I saw one. Die!",12,7,100,0,0,0,2425,0,"Leprous Assistant"); + +-- Leprous Machinesmith +DELETE FROM `smart_scripts` WHERE `entryorguid`=6224 AND `source_type`=0 AND `id`=4; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6224,0,4,0,4,0,20,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Leprous Machinesmith - On Aggro - Say Line 1"); + +DELETE FROM `creature_text` WHERE `CreatureID`=6224 AND `GroupID`=1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(6224,1,0,"No gnome will be left behind.",12,7,100,0,0,0,2422,0,"Leprous Machinesmith"), +(6224,1,1,"The troggs...they never stop coming. Die trogg! Die!",12,7,100,0,0,0,2423,0,"Leprous Machinesmith"), +(6224,1,2,"This sickness clouds my vision, but I know you must be a trogg. Die foul invader!",12,7,100,0,0,0,2424,0,"Leprous Machinesmith"), +(6224,1,3,"A foul trogg if ever I saw one. Die!",12,7,100,0,0,0,2425,0,"Leprous Machinesmith"); + +-- Dark Iron Agent +DELETE FROM `smart_scripts` WHERE `entryorguid`=6212 AND `source_type`=0 AND `id`=1; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6212,0,1,0,4,0,20,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Dark Iron Agent - On Aggro - Say Line 1"); + +DELETE FROM `creature_text` WHERE `CreatureID`=6212 AND `GroupID`=1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(6212,1,0,"Never cross a Dark Iron, $C.",12,0,100,0,0,0,1934,0,"Dark Iron Agent"), +(6212,1,1,"Time to die, $C.",12,0,100,0,0,0,1935,0,"Dark Iron Agent"), +(6212,1,2,"Feel the power of the Dark Iron Dwarves!",12,0,100,0,0,0,1936,0,"Dark Iron Agent"); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_02_world_from_335_was_2018_03_06_02_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_02_world_from_335_was_2018_03_06_02_world_335.sql new file mode 100644 index 00000000000..39dcaadf247 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_02_world_from_335_was_2018_03_06_02_world_335.sql @@ -0,0 +1,351 @@ +/* +-- Quest "Escorting Erland" +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=435; + +-- Quest "Return to Quinn" +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=430; + +-- Quest "Ivar the Foul" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=425; + +-- Quest "Wand to Bethor" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=491; + +-- Quest "Supplying the Sepulcher" +DELETE FROM `quest_details` WHERE `ID`=6321; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(6321,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=6321; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=6321; + +-- Quest "Ride to the Undercity" +DELETE FROM `quest_details` WHERE `ID`=6323; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(6323,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=6323; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=6323; + +-- Quest "Michael Garrett" +DELETE FROM `quest_details` WHERE `ID`=6322; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(6322,1,0,0,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=6 WHERE `ID`=6322; + +-- Quest "Return to Podrig" +DELETE FROM `quest_details` WHERE `ID`=6324; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(6324,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=6324; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=6324; + +-- Quest "The Deathstalkers' Report" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=449; + +-- Quest "Speak with Renferrel" +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=3221; + +-- Quest "Delivery to Silverpine Forest" +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=445; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=445; + +-- Quest "Zinge's Delivery" +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=1359; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=1359; + +-- Quest "Sample for Helbrim" +DELETE FROM `quest_details` WHERE `ID`=1358; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(1358,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=1358; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=1358; + +-- Quest "The Dead Fields" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=437; + +-- Quest "Rot Hide Clues" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=439; + +-- Quest "Rot Hide Ichor" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=443; + +-- Quest "Rot Hide Origins" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=444; + +-- Quest "Thule Ravenclaw" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=446; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=446; + +-- Quest "Assault on Fenris Isle" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=442; + +-- Quest "The Engraved Ring" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=440; + +-- Quest "Raleigh and the Undercity" +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=441; +UPDATE `quest_offer_reward` SET `Emote1`=1, `Emote2`=1 WHERE `ID`=441; + +-- Quest "A Husband's Revenge" +DELETE FROM `quest_details` WHERE `ID`=530; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(530,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=530; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=530; + +-- Quest "Prove Your Worth" +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=421; + +-- Quest "Arugal's Folly" +DELETE FROM `quest_details` WHERE `ID`=422; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(422,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1 WHERE `ID`=422; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=422; + +-- Quest "Arugal's Folly (Part 2)" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=423; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=423; + +-- Quest "Arugal's Folly (Part 3)" +DELETE FROM `quest_details` WHERE `ID`=424; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(424,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=424; + +-- Quest "Arugal's Folly (Part 4)" +DELETE FROM `quest_details` WHERE `ID`=99; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(99,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=99; +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=99; + +-- Quest "Maps and Runes" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=478; + +-- Quest "Dalar's Analysis" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=481; + +-- Quest "Ambermill Investigations" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=479; + +-- Quest "The Weaver" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=480; + +-- Quest "A Recipe For Death" +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=66, `EmoteOnComplete`=66 WHERE `ID`=447; +UPDATE `quest_offer_reward` SET `Emote1`=273 WHERE `ID`=447; + +-- Quest "A Recipe For Death (Part 2)" +DELETE FROM `quest_details` WHERE `ID`=450; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(450,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1, `EmoteOnComplete`=1 WHERE `ID`=450; +UPDATE `quest_offer_reward` SET `Emote1`=5 WHERE `ID`=450; + +-- Quest "A Recipe For Death (Part 3)" +DELETE FROM `quest_details` WHERE `ID`=451; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(451,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=451; + +-- Quest "Arugal Must Die" +DELETE FROM `quest_details` WHERE `ID`=1014; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(1014,1,1,5,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1, `EmoteOnComplete`=1 WHERE `ID`=1014; +UPDATE `quest_offer_reward` SET `Emote1`=4 WHERE `ID`=1014; + +-- Quest "Journey to Hillsbrad Foothills" +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=493; +UPDATE `quest_offer_reward` SET `Emote1`=273 WHERE `ID`=493; + +-- Quest "Time To Strike" +DELETE FROM `quest_details` WHERE `ID`=494; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(494,5,1,0,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=6, `Emote2`=1 WHERE `ID`=494; + +-- Quest "Helcular's Revenge" +DELETE FROM `quest_details` WHERE `ID`=552; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(552,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=552; + +-- Quest "Helcular's Revenge (Part 2)" +DELETE FROM `quest_details` WHERE `ID`=553; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(553,1,0,0,0,0,0,0,0,0); + +-- Quest "Battle of Hillsbrad" +DELETE FROM `quest_details` WHERE `ID`=527; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(527,25,1,1,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=25 WHERE `ID`=527; + +-- Quest "Battle of Hillsbrad (Part 2)" +DELETE FROM `quest_details` WHERE `ID`=528; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(528,1,1,1,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=528; + +-- Quest "Battle of Hillsbrad (Part 3)" +DELETE FROM `quest_details` WHERE `ID`=529; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(529,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=529; +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=529; + +-- Quest "Battle of Hillsbrad (Part 4)" +DELETE FROM `quest_details` WHERE `ID`=532; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(532,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=532; +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=532; + +-- Quest "Battle of Hillsbrad (Part 5)" +DELETE FROM `quest_details` WHERE `ID`=539; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(539,1,1,1,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=539; + +-- Quest "Battle of Hillsbrad (Part 6)" +DELETE FROM `quest_details` WHERE `ID`=541; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(541,6,5,1,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=541; + +-- Quest "Battle of Hillsbrad (Part 7)" +DELETE FROM `quest_details` WHERE `ID`=14351; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(14351,1,66,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=5 WHERE `ID`=14351; +UPDATE `quest_offer_reward` SET `Emote1`=6, `Emote2`=1, `Emote3`=1 WHERE `ID`=14351; + +-- Quest "Bracers of Binding" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=557; + +-- Quest "Frostmaw" +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=1136; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=1136; + +-- Quest "The Rescue" +DELETE FROM `quest_details` WHERE `ID`=498; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(498,1,1,1,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=6, `Emote2`=5, `Emote3`=1 WHERE `ID`=498; + +-- Quest "Infiltration" +DELETE FROM `quest_details` WHERE `ID`=533; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(533,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=533; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=533; + +-- Quest "Gol'dir" +DELETE FROM `quest_details` WHERE `ID`=503; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(503,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=0 WHERE `ID`=503; +UPDATE `quest_offer_reward` SET `Emote1`=2, `Emote2`=1 WHERE `ID`=503; + +-- Quest "Blackmoore's Legacy" +DELETE FROM `quest_details` WHERE `ID`=506; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(506,1,1,1,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=5 WHERE `ID`=506; + +-- Quest "Lord Aliden Perenolde" +DELETE FROM `quest_details` WHERE `ID`=507; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(507,1,0,0,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=20 WHERE `ID`=507; + +-- Quest "Taretha's Gift" +UPDATE `quest_request_items` SET `EmoteOnComplete`=6 WHERE `ID`=508; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=508; + +-- Quest "WANTED: Syndicate Personnel" +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=549; + +-- Quest "WANTED: Baron Vardus" +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=566; +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=566; + +-- Quest "Dangerous!" +UPDATE `quest_offer_reward` SET `Emote1`=21 WHERE `ID`=567; + +-- Quest "Souvenirs of Death" +DELETE FROM `quest_details` WHERE `ID`=546; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(546,1,1,6,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=546; +UPDATE `quest_offer_reward` SET `Emote1`=4 WHERE `ID`=546; + +-- Quest "Humbert's Sword" +DELETE FROM `quest_details` WHERE `ID`=547; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(547,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=547; +UPDATE `quest_offer_reward` SET `Emote1`=4 WHERE `ID`=547; + +-- Quest "Soothing Turtle Bisque" +DELETE FROM `quest_details` WHERE `ID`=7321; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(7321,6,1,1,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6 WHERE `ID`=7321; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=7321; + +-- Quest "Elixir of Suffering" +DELETE FROM `quest_details` WHERE `ID`=496; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(496,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1 WHERE `ID`=496; +UPDATE `quest_offer_reward` SET `Emote1`=1 WHERE `ID`=496; + +-- Quest "Elixir of Suffering (Part 2)" +DELETE FROM `quest_details` WHERE `ID`=499; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(499,1,11,0,0,0,0,0,0,0); + +-- Quest "Elixir of Pain" +DELETE FROM `quest_details` WHERE `ID`=501; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(501,1,5,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1 WHERE `ID`=501; +UPDATE `quest_offer_reward` SET `Emote1`=4 WHERE `ID`=501; + +-- Quest "Elixir of Pain (Part 2)" +DELETE FROM `quest_details` WHERE `ID`=502; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(502,5,1,11,0,0,0,0,0,0); + +-- Quest "Elixir of Agony" +DELETE FROM `quest_details` WHERE `ID`=509; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(509,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6, `EmoteOnComplete`=6 WHERE `ID`=509; +UPDATE `quest_offer_reward` SET `Emote1`=1, `Emote2`=11 WHERE `ID`=509; + +-- Quest "Elixir of Agony (Part 2)" +DELETE FROM `quest_details` WHERE `ID`=513; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(513,1,0,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnComplete`=5 WHERE `ID`=513; +UPDATE `quest_offer_reward` SET `Emote1`=6, `Emote2`=1 WHERE `ID`=513; + +-- Quest "Elixir of Agony (Part 3)" +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1 WHERE `ID`=515; +UPDATE `quest_offer_reward` SET `Emote1`=5 WHERE `ID`=515; + +-- Quest "Elixir of Agony (Part 4)" +DELETE FROM `quest_details` WHERE `ID`=517; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(517,1,1,11,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1 WHERE `ID`=517; +UPDATE `quest_offer_reward` SET `Emote1`=5 WHERE `ID`=517; + +-- Quest "Elixir of Agony (Part 5)" +DELETE FROM `quest_details` WHERE `ID`=524; +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(524,1,1,11,0,0,0,0,0,0); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_03_world_from_335_was_2018_03_06_03_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_03_world_from_335_was_2018_03_06_03_world.sql new file mode 100644 index 00000000000..1552426bbc4 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_03_world_from_335_was_2018_03_06_03_world.sql @@ -0,0 +1,94 @@ +-- Stormwind City Guard +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (6800,6801,6802,6803,6804) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6800,9,0,0,0,0,100,0,0,0,0,0,103,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted On"), +(6800,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6800,9,2,0,0,0,100,0,2000,2000,0,0,5,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Wave'"), +(6800,9,3,0,0,0,100,0,4000,4000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6800,9,4,0,0,0,100,0,0,0,0,0,103,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted Off"), +(6801,9,0,0,0,0,100,0,0,0,0,0,103,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted On"), +(6801,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6801,9,2,0,0,0,100,0,2000,2000,0,0,5,66,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Salute'"), +(6801,9,3,0,0,0,100,0,4000,4000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6801,9,4,0,0,0,100,0,0,0,0,0,103,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted Off"), +(6802,9,0,0,0,0,100,0,0,0,0,0,103,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted On"), +(6802,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6802,9,2,0,0,0,100,0,2000,2000,0,0,5,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Bow'"), +(6802,9,3,0,0,0,100,0,4000,4000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6802,9,4,0,0,0,100,0,0,0,0,0,103,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted Off"), +(6803,9,0,0,0,0,100,0,0,0,0,0,103,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted On"), +(6803,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6803,9,2,0,0,0,100,0,2000,2000,0,0,5,23,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Flex'"), +(6803,9,3,0,0,0,100,0,4000,4000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6803,9,4,0,0,0,100,0,0,0,0,0,103,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted Off"), +(6804,9,0,0,0,0,100,0,0,0,0,0,103,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted On"), +(6804,9,1,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6804,9,2,0,0,0,100,0,2000,2000,0,0,5,25,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Play Emote 'Point'"), +(6804,9,3,0,0,0,100,0,4000,4000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Orientation"), +(6804,9,4,0,0,0,100,0,0,0,0,0,103,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Guard - On Script - Set Rooted Off"); + +-- Stormwind City Patroller +DELETE FROM `smart_scripts` WHERE `entryorguid`=1976 AND `source_type`=0 AND `id` IN (1,2,3,4,5,6,7,8,9,10,11); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(1976,0,1,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Stormwind City Patroller - In Combat - Cast 'Shoot'"), +(1976,0,2,0,9,0,100,0,0,5,11000,14000,11,12169,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - Within 0-5 Range - Cast 'Shield Block'"), +(1976,0,3,0,0,0,100,0,5000,9000,8000,13000,11,12170,0,0,0,0,0,2,0,0,0,0,0,0,0,"Stormwind City Patroller - In Combat - Cast 'Revenge'"), +(1976,0,4,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - On Received Emote 'Wave' - Run Script"), +(1976,0,5,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - On Received Emote 'Salute' - Run Script"), +(1976,0,6,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - On Received Emote 'Kiss' - Run Script"), +(1976,0,7,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - On Received Emote 'Shy' - Run Script"), +(1976,0,8,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - On Received Emote 'Rude' - Run Script"), +(1976,0,9,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - On Received Emote 'Chicken' - Run Script"), +(1976,0,10,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind City Patroller - On Received Emote 'Bow' - Run Script"); + +-- Stormwind Royal Guard +DELETE FROM `smart_scripts` WHERE `entryorguid`=1756 AND `source_type`=0 AND `id` IN (1,2,3,4,5,6,7,8,9,10); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(1756,0,1,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Stormwind Royal Guard - In Combat - Cast 'Shoot'"), +(1756,0,2,0,9,0,100,0,0,5,11000,14000,11,12169,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - Within 0-5 Range - Cast 'Shield Block'"), +(1756,0,3,0,0,0,100,0,5000,9000,8000,13000,11,12170,0,0,0,0,0,2,0,0,0,0,0,0,0,"Stormwind Royal Guard - In Combat - Cast 'Revenge'"), +(1756,0,4,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - On Received Emote 'Wave' - Run Script"), +(1756,0,5,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - On Received Emote 'Salute' - Run Script"), +(1756,0,6,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - On Received Emote 'Kiss' - Run Script"), +(1756,0,7,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - On Received Emote 'Shy' - Run Script"), +(1756,0,8,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - On Received Emote 'Rude' - Run Script"), +(1756,0,9,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - On Received Emote 'Chicken' - Run Script"), +(1756,0,10,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Royal Guard - On Received Emote 'Bow' - Run Script"); + +-- Orgrimmar Grunt +DELETE FROM `smart_scripts` WHERE `entryorguid`=3296 AND `source_type`=0 AND `id` IN (1,2,3,4,5,6,7,8,9,10,11); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(3296,0,1,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Orgrimmar Grunt - In Combat - Cast 'Shoot'"), +(3296,0,2,0,0,0,100,0,5000,9000,8000,13000,11,40505,0,0,0,0,0,2,0,0,0,0,0,0,0,"Orgrimmar Grunt - In Combat - Cast 'Cleave'"), +(3296,0,3,0,2,0,100,1,0,30,0,0,11,8599,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - Between 0-30% Health - Cast 'Enrage' (No Repeat)"), +(3296,0,4,0,2,0,100,1,0,30,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - Between 0-30% Health - Say Line 0 (No Repeat)"), +(3296,0,5,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - On Received Emote 'Wave' - Run Script"), +(3296,0,6,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - On Received Emote 'Salute' - Run Script"), +(3296,0,7,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - On Received Emote 'Kiss' - Run Script"), +(3296,0,8,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - On Received Emote 'Shy' - Run Script"), +(3296,0,9,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - On Received Emote 'Rude' - Run Script"), +(3296,0,10,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - On Received Emote 'Chicken' - Run Script"), +(3296,0,11,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orgrimmar Grunt - On Received Emote 'Bow' - Run Script"); + +DELETE FROM `creature_text` WHERE `CreatureID`=3296 AND `GroupID`=0; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(3296,0,0,"%s becomes enraged!",16,0,100,0,0,0,10677,0,"Orgrimmar Grunt"); + +-- Kor'kron Elite +DELETE FROM `smart_scripts` WHERE `entryorguid`=14304 AND `source_type`=0 AND `id` IN (1,2,3,4,5,6,7,8,9,10,11); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(14304,0,1,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Kor'kron Elite - In Combat - Cast 'Shoot'"), +(14304,0,2,0,0,0,100,0,5000,9000,8000,13000,11,40505,0,0,0,0,0,2,0,0,0,0,0,0,0,"Kor'kron Elite - In Combat - Cast 'Cleave'"), +(14304,0,3,0,2,0,100,0,0,30,120000,120000,11,8599,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - Between 0-30% Health - Cast 'Enrage'"), +(14304,0,4,0,2,0,100,1,0,30,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - Between 0-30% Health - Say Line 1 (No Repeat)"), +(14304,0,5,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - On Received Emote 'Wave' - Run Script"), +(14304,0,6,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - On Received Emote 'Salute' - Run Script"), +(14304,0,7,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - On Received Emote 'Kiss' - Run Script"), +(14304,0,8,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - On Received Emote 'Shy' - Run Script"), +(14304,0,9,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - On Received Emote 'Rude' - Run Script"), +(14304,0,10,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - On Received Emote 'Chicken' - Run Script"), +(14304,0,11,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kor'kron Elite - On Received Emote 'Bow' - Run Script"); + +DELETE FROM `creature_text` WHERE `CreatureID`=14304 AND `GroupID`=1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(14304,1,0,"%s becomes enraged!",16,0,100,0,0,0,10677,0,"Kor'kron Elite"); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_04_world_from_335_was_2018_03_06_04_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_04_world_from_335_was_2018_03_06_04_world.sql new file mode 100644 index 00000000000..49a1cc25ff0 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_04_world_from_335_was_2018_03_06_04_world.sql @@ -0,0 +1,122 @@ +-- Tarren Mill Deathguard +DELETE FROM `smart_scripts` WHERE `entryorguid`=2405 AND `source_type`=0 AND `id` IN (1,2,3,4,5,6,7,8,9,10); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2405,0,1,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Tarren Mill Deathguard - In Combat - Cast 'Shoot'"), +(2405,0,2,0,9,0,100,0,0,5,11000,14000,11,12169,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - Within 0-5 Range - Cast 'Shield Block'"), +(2405,0,3,0,0,0,100,0,5000,9000,8000,13000,11,12170,0,0,0,0,0,2,0,0,0,0,0,0,0,"Tarren Mill Deathguard - In Combat - Cast 'Revenge'"), +(2405,0,4,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - On Received Emote 'Wave' - Run Script"), +(2405,0,5,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - On Received Emote 'Salute' - Run Script"), +(2405,0,6,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - On Received Emote 'Kiss' - Run Script"), +(2405,0,7,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - On Received Emote 'Shy' - Run Script"), +(2405,0,8,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - On Received Emote 'Rude' - Run Script"), +(2405,0,9,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - On Received Emote 'Chicken' - Run Script"), +(2405,0,10,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Tarren Mill Deathguard - On Received Emote 'Bow' - Run Script"); + +UPDATE `creature_text` SET `Language`=33 WHERE `CreatureID`=2405; -- Fix language for Tarren Mill Deathguard's aggro text + +-- Hammerfall Guardian +DELETE FROM `smart_scripts` WHERE `entryorguid`=2621 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2621,0,0,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Hammerfall Guardian - In Combat - Cast 'Shoot'"), +(2621,0,1,0,9,0,100,0,0,5,11000,14000,11,12169,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - Within 0-5 Range - Cast 'Shield Block'"), +(2621,0,2,0,0,0,100,0,5000,9000,8000,13000,11,12170,0,0,0,0,0,2,0,0,0,0,0,0,0,"Hammerfall Guardian - In Combat - Cast 'Revenge'"), +(2621,0,3,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - On Received Emote 'Wave' - Run Script"), +(2621,0,4,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - On Received Emote 'Salute' - Run Script"), +(2621,0,5,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - On Received Emote 'Kiss' - Run Script"), +(2621,0,6,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - On Received Emote 'Shy' - Run Script"), +(2621,0,7,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - On Received Emote 'Rude' - Run Script"), +(2621,0,8,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - On Received Emote 'Chicken' - Run Script"), +(2621,0,9,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hammerfall Guardian - On Received Emote 'Bow' - Run Script"); + +-- Skyguard Windcharger +DELETE FROM `smart_scripts` WHERE `entryorguid`=23257 AND `source_type`=0 AND `id`=1; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(23257,0,1,0,9,0,100,0,0,20,12000,16000,11,12024,0,0,0,0,0,2,0,0,0,0,0,0,0,"Skyguard Windcharger - Within 0-20 Range - Cast 'Net'"); + +-- Stormwind Marine +DELETE FROM `smart_scripts` WHERE `entryorguid`=20556 AND `source_type`=0 AND `id` IN (2,3,4,5,6,7,8,9); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(20556,0,2,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Stormwind Marine - In Combat - Cast 'Shoot'"), +(20556,0,3,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Marine - On Received Emote 'Wave' - Run Script"), +(20556,0,4,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Marine - On Received Emote 'Salute' - Run Script"), +(20556,0,5,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Marine - On Received Emote 'Kiss' - Run Script"), +(20556,0,6,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Marine - On Received Emote 'Shy' - Run Script"), +(20556,0,7,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Marine - On Received Emote 'Rude' - Run Script"), +(20556,0,8,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Marine - On Received Emote 'Chicken' - Run Script"), +(20556,0,9,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stormwind Marine - On Received Emote 'Bow' - Run Script"); + +UPDATE `creature_template` SET `npcflag`=0, `IconName`=NULL WHERE `entry`=20556; -- They don't give directions and don't have gossip text + +-- Deathguard Elite +DELETE FROM `smart_scripts` WHERE `entryorguid`=7980 AND `source_type`=0 AND `id` IN (1,2,3,4,5,6,7,8,9,10); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7980,0,1,0,25,0,100,0,0,0,0,0,11,18950,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Reset - Cast 'Invisibility and Stealth Detection'"), +(7980,0,2,0,0,0,100,0,5000,7000,7000,10000,11,14516,0,0,0,0,0,2,0,0,0,0,0,0,0,"Deathguard Elite - In Combat - Cast 'Strike'"), +(7980,0,3,0,9,0,100,0,0,5,12000,16000,11,9080,0,0,0,0,0,2,0,0,0,0,0,0,0,"Deathguard Elite - Within 0-5 Range - Cast 'Hamstring'"), +(7980,0,4,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Received Emote 'Wave' - Run Script"), +(7980,0,5,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Received Emote 'Salute' - Run Script"), +(7980,0,6,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Received Emote 'Kiss' - Run Script"), +(7980,0,7,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Received Emote 'Shy' - Run Script"), +(7980,0,8,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Received Emote 'Rude' - Run Script"), +(7980,0,9,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Received Emote 'Chicken' - Run Script"), +(7980,0,10,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Deathguard Elite - On Received Emote 'Bow' - Run Script"); + +-- Mounted Ironforge Mountaineer +DELETE FROM `smart_scripts` WHERE `entryorguid`=12996 AND `source_type`=0 AND `id` IN (2,3,4,5,6,7,8,9); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(12996,0,2,0,22,0,100,0,101,5000,5000,0,80,6800,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mounted Ironforge Mountaineer - On Received Emote 'Wave' - Run Script"), +(12996,0,3,0,22,0,100,0,78,5000,5000,0,80,6801,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mounted Ironforge Mountaineer - On Received Emote 'Salute' - Run Script"), +(12996,0,4,0,22,0,100,0,58,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mounted Ironforge Mountaineer - On Received Emote 'Kiss' - Run Script"), +(12996,0,5,0,22,0,100,0,84,5000,5000,0,80,6803,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mounted Ironforge Mountaineer - On Received Emote 'Shy' - Run Script"), +(12996,0,6,0,22,0,100,0,77,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mounted Ironforge Mountaineer - On Received Emote 'Rude' - Run Script"), +(12996,0,7,0,22,0,100,0,22,5000,5000,0,80,6804,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mounted Ironforge Mountaineer - On Received Emote 'Chicken' - Run Script"), +(12996,0,8,0,22,0,100,0,17,5000,5000,0,80,6802,0,0,0,0,0,1,0,0,0,0,0,0,0,"Mounted Ironforge Mountaineer - On Received Emote 'Bow' - Run Script"); + +UPDATE `creature_template` SET `gossip_menu_id`=2121 WHERE `entry`=12996; -- Add gossip text + +-- Scout Stronghand +DELETE FROM `smart_scripts` WHERE `entryorguid`=14375 AND `source_type`=0 AND `id` IN (1,2,3); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(14375,0,1,0,9,0,100,0,0,30,8000,12000,11,14030,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Stronghand - Within 0-30 Range - Cast 'Hooked Net'"), +(14375,0,2,0,0,0,100,0,5000,7000,5000,9000,11,15572,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Stronghand - In Combat - Cast 'Sunder Armor'"), +(14375,0,3,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Stronghand - In Combat - Cast 'Shoot'"); + +-- Expedition Warden +DELETE FROM `smart_scripts` WHERE `entryorguid`=17855 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(17855,0,0,0,9,0,100,0,0,20,12000,16000,11,12024,0,0,0,0,0,2,0,0,0,0,0,0,0,"Expedition Warden - Within 0-20 Range - Cast 'Net'"), +(17855,0,1,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Expedition Warden - In Combat - Cast 'Shoot'"), +(17855,0,2,0,4,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Expedition Warden - On Aggro - Cast Say Line 0"); + +DELETE FROM `creature_text` WHERE `CreatureID`=17855; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(17855,0,0,"Taste blade, mongrel!",12,0,100,0,0,0,10950,0,"Expedition Warden"), +(17855,0,1,"Please tell me that you didn't just do what I think you just did. Please tell me that I'm not going to have to hurt you...",12,0,100,0,0,0,10951,0,"Expedition Warden"), +(17855,0,2,"As if we don't have enough problems, you go and create more!",12,0,100,0,0,0,10953,0,"Expedition Warden"), +(17855,0,3,"You dare spill blood on neutral ground? OUT! OUT, I SAY!",12,0,100,0,0,0,10948,0,"Expedition Warden"), +(17855,0,4,"We don't take kindly to miscreants, $r.",12,0,100,0,0,0,10949,0,"Expedition Warden"), +(17855,0,5,"Get a rope!",12,0,100,0,0,0,10952,0,"Expedition Warden"), +(17855,0,6,"Believe me when I tell you this: You're gonna wish you weren't born, sissy!",12,0,100,0,0,0,10954,0,"Expedition Warden"), +(17855,0,7,"Your actions shame us all, $c. I hurt inside as I beat you senseless.",12,0,100,0,0,0,10955,0,"Expedition Warden"); + +-- Scout Manslayer +DELETE FROM `smart_scripts` WHERE `entryorguid`=14376 AND `source_type`=0 AND `id` IN (1,2,3); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(14376,0,1,0,9,0,100,0,0,30,8000,12000,11,14030,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Manslayer - Within 0-30 Range - Cast 'Hooked Net'"), +(14376,0,2,0,0,0,100,0,5000,7000,5000,9000,11,15572,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Manslayer - In Combat - Cast 'Sunder Armor'"), +(14376,0,3,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Manslayer - In Combat - Cast 'Shoot'"); + +-- Scout Tharr +DELETE FROM `smart_scripts` WHERE `entryorguid`=14377 AND `source_type`=0 AND `id` IN (1,2,3); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(14377,0,1,0,9,0,100,0,0,30,8000,12000,11,14030,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Tharr - Within 0-30 Range - Cast 'Hooked Net'"), +(14377,0,2,0,0,0,100,0,5000,7000,5000,9000,11,15572,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Tharr - In Combat - Cast 'Sunder Armor'"), +(14377,0,3,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Scout Tharr - In Combat - Cast 'Shoot'"); + +-- Cenarion Hold Infantry +DELETE FROM `smart_scripts` WHERE `entryorguid`=15184 AND `source_type`=0 AND `id`=4; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(15184,0,4,0,0,0,100,0,0,0,2000,4000,11,6660,64,0,0,0,0,2,0,0,0,0,0,0,0,"Cenarion Hold Infantry - In Combat - Cast 'Shoot'"); + +UPDATE `creature_template` SET `flags_extra`=32768 WHERE `entry` IN (1756); +UPDATE `creature_template` SET `faction`=105 WHERE `entry` IN (3084); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_05_world_from_335_was_2018_03_06_05_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_05_world_from_335_was_2018_03_06_05_world_335.sql new file mode 100644 index 00000000000..73c42760fec --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_05_world_from_335_was_2018_03_06_05_world_335.sql @@ -0,0 +1,104 @@ +/* +-- Quest "A Fine Mess" +-- Pooling for Kernobee +SET @GUID := 64977; +SET @POOL := 385; +DELETE FROM `creature` WHERE `guid` BETWEEN @GUID+0 AND @GUID+6; +INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES +(@GUID+0,7850,90,0,0,1,1,0,0,-637.053,101.836,-194.48,4.76023,7200,0,0,896,0,0,0,0,0,"",0), +(@GUID+1,7850,90,0,0,1,1,0,0,-577.696,28.5626,-197.735,4.76023,7200,0,0,896,0,0,0,0,0,"",0), +(@GUID+2,7850,90,0,0,1,1,0,0,-618.832,153.15,-199.654,6.25451,7200,0,0,896,0,0,0,0,0,"",0), +(@GUID+3,7850,90,0,0,1,1,0,0,-600.079,15.9729,-179.679,5.47311,7200,0,0,896,0,0,0,0,0,"",0), +(@GUID+4,7850,90,0,0,1,1,0,0,-540.499,21.528,-179.737,1.53634,7200,0,0,896,0,0,0,0,0,"",0), +(@GUID+5,7850,90,0,0,1,1,0,0,-533.081,34.7292,-199.0739,1.89563,7200,0,0,896,0,0,0,0,0,"",0), +(@GUID+6,7850,90,0,0,1,1,0,0,-621.389,51.785,-199.647,5.47311,7200,0,0,896,0,0,0,0,0,"",0); + +DELETE FROM `pool_template` WHERE `entry`=@POOL; +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@POOL,1,"Kernobee"); + +DELETE FROM `pool_creature` WHERE `pool_entry`=@POOL; +INSERT INTO `pool_creature` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@GUID+0,@POOL,0,"Kernobee (7850) - Spawn 1"), +(@GUID+1,@POOL,0,"Kernobee (7850) - Spawn 2"), +(@GUID+2,@POOL,0,"Kernobee (7850) - Spawn 3"), +(@GUID+3,@POOL,0,"Kernobee (7850) - Spawn 4"), +(@GUID+4,@POOL,0,"Kernobee (7850) - Spawn 5"), +(@GUID+5,@POOL,0,"Kernobee (7850) - Spawn 6"), +(@GUID+6,@POOL,0,"Kernobee (7850) - Spawn 7"), +(30135,@POOL,0,"Kernobee (7850) - Spawn 8"); + +-- Texts +DELETE FROM `creature_text` WHERE `CreatureID` IN (7850,7897); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(7850,0,0,"I see the exit! Hurry, hurry!",12,0,100,5,0,0,3948,0,"Kernobee"), +(7850,1,0,"%s cheers!",16,0,100,4,0,0,3928,0,"Kernobee"), +(7850,2,0,"Thank you for rescuing me! Word of your deed will not go unnoticed.",12,0,100,0,0,0,3929,0,"Kernobee"), +(7850,3,0,"%s waves goodbye to everyone.",16,0,100,3,0,0,3930,0,"Kernobee"), +(7850,4,0,"Uh oh....",12,0,100,0,0,0,3953,0,"Kernobee"), +(7850,5,0,"Get me out of here!",12,0,100,5,0,0,3881,0,"Kernobee"), +(7897,0,0,"%s activates!",14,0,100,0,0,0,3926,0,"Alarm-a-bomb 2600"), +(7897,1,0,"Self-destruct sequence activated.",14,0,100,0,0,0,3927,0,"Alarm-a-bomb 2600"), +(7897,2,0,"Anti-escape countermeasures activated. Self-destruct in t-minus 20 seconds....",14,0,100,0,0,0,3949,0,"Alarm-a-bomb 2600"), +(7897,3,0,"Alarm-a-bomb unit 2600 has failed. Self-destruct override [ACTIVE]. Cooldown [ACTIVE].",14,0,100,0,0,0,3950,0,"Alarm-a-bomb 2600"); + +-- Kernobee +DELETE FROM `creature_addon` WHERE `guid`=30135; + +UPDATE `creature_template` SET `AIName`="SmartAI", `ScriptName`="" WHERE `entry`=7850; +DELETE FROM `smart_scripts` WHERE `entryorguid`=7850 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=785000 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7850,0,0,1,19,0,100,0,2904,0,0,0,29,2,180,0,0,0,0,7,0,0,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Start Follow Player"), +(7850,0,1,2,61,0,100,0,0,0,0,0,64,1,0,0,0,0,0,16,0,0,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Store Targetlist"), +(7850,0,2,3,61,0,100,0,0,0,0,0,91,7,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Remove Flag Standstate 'Dead'"), +(7850,0,3,4,61,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Remove Npc Flag Questgiver"), +(7850,0,4,5,61,0,100,0,0,0,0,0,19,768,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Remove Unit Flag 'Immune To NPCs' & 'Immune To Players'"), +(7850,0,5,6,61,0,100,0,0,0,0,0,2,250,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Set Faction 250"), +(7850,0,6,7,61,0,100,0,0,0,0,0,1,5,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Say Line 5"), +(7850,0,7,0,61,0,100,0,0,0,0,0,45,1,1,0,0,0,0,10,30134,7897,0,0,0,0,0,"Kernobee - On Quest 'A Fine Mess' Taken - Set Data to Alarm-a-bomb 2600"), +(7850,0,8,0,6,0,100,0,0,0,0,0,6,2904,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Death - Fail Quest 'A Fine Mess'"), +(7850,0,9,0,11,0,100,0,0,0,0,0,90,7,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Respawn - Add Flag Standstate 'Dead'"), +(7850,0,10,11,38,0,100,1,1,1,0,0,1,0,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Data Set - Say Line 0"), +(7850,0,11,12,61,0,100,0,0,0,0,0,29,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Data Set - Stop Follow"), +(7850,0,12,13,61,0,100,0,0,0,0,0,69,0,0,0,0,0,0,8,0,0,0,-337.215,-0.165544,-152.847,0,"Kernobee - On Data Set - Move to Position"), +(7850,0,13,0,61,0,100,0,0,0,0,0,80,785000,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Data Set - Run Script"), +(785000,9,0,0,0,0,100,0,11000,11000,0,0,15,2904,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Script - Quest Credit 'A Fine Mess'"), +(785000,9,1,0,0,0,100,0,0,0,0,0,45,3,3,0,0,0,0,19,7897,0,0,0,0,0,0,"Kernobee - On Script - Set Data to Alarm-a-bomb 2600"), +(785000,9,2,0,0,0,100,0,500,500,0,0,1,1,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Script - Say Line 1"), +(785000,9,3,0,0,0,100,0,4000,4000,0,0,66,0,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Script - Set Orientation"), +(785000,9,4,0,0,0,100,0,1000,1000,0,0,1,2,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Script - Say Line 2"), +(785000,9,5,0,0,0,100,0,5000,5000,0,0,1,3,0,0,0,0,0,12,1,0,0,0,0,0,0,"Kernobee - On Script - Say Line 3"), +(785000,9,6,0,0,0,100,0,3000,3000,0,0,69,0,0,0,0,0,0,8,0,0,0,-297.319,-7.321,-152.849,0,"Kernobee - On Script - Move to Position"), +(785000,9,7,0,0,0,100,0,2000,2000,0,0,41,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kernobee - On Script - Despawn"); + +-- Alarm-a-bomb 2600 +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=7897; +DELETE FROM `smart_scripts` WHERE `entryorguid`=7897 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (789700,789701) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(7897,0,0,0,38,0,100,0,1,1,0,0,80,789700,2,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Data Set - Run Script"), +(7897,0,1,0,38,0,100,1,1,1,0,0,29,2,270,0,0,0,0,19,7850,200,0,0,0,0,0,"Alarm-a-bomb 2600 - On Data Set - Start Follow Kernobee"), +(7897,0,2,0,38,1,100,1,2,2,0,0,45,1,1,0,0,0,0,19,7850,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Data Set - Set Data to Kernobee (Phase 1)"), +(7897,0,3,0,38,1,100,1,3,3,0,0,80,789701,2,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Data Set - Run Script (Phase 1)"), +(789700,9,0,0,0,0,100,0,0,0,0,0,22,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Set Event Phase 1"), +(789700,9,1,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Say Line 0"), +(789700,9,2,0,0,0,100,0,4000,4000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Say Line 1"), +(789700,9,3,0,0,0,100,0,276000,276000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Say Line 2"), +(789700,9,4,0,0,0,100,0,6000,6000,0,0,1,4,0,0,0,0,0,19,7850,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Say Line 4 (Kernobee)"), +(789700,9,5,0,0,0,100,0,14000,14000,0,0,11,9874,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Cast 'Self Destruct'"), +(789700,9,6,0,0,0,100,0,500,500,0,0,51,0,0,0,0,0,0,19,7850,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Kill Kernobee"), +(789700,9,7,0,0,0,100,0,0,0,0,0,37,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Kill Self"), +(789701,9,0,0,0,0,100,0,0,0,0,0,103,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Set Rooted On"), +(789701,9,1,0,0,0,100,0,0,0,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Say Line 3"), +(789701,9,2,0,0,0,100,0,12000,12000,0,0,41,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Alarm-a-bomb 2600 - On Script - Despawn"); + +-- Areatrigger +DELETE FROM `areatrigger_scripts` WHERE `entry`=1105; +INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES +(1105,"SmartTrigger"); + +DELETE FROM `smart_scripts` WHERE `entryorguid`=1105 AND `source_type`=2; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(1105,2,0,0,46,0,100,0,1105,0,0,0,45,2,2,0,0,0,0,10,30134,7897,0,0,0,0,0,"Areatrigger - On Trigger - Set Data to Alarm-a-bomb 2600"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_06_world_from_335_was_2018_03_06_06_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_06_world_from_335_was_2018_03_06_06_world.sql new file mode 100644 index 00000000000..24705a29709 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_06_06_world_from_335_was_2018_03_06_06_world.sql @@ -0,0 +1,3 @@ +DELETE FROM `command` WHERE `name`='server debug'; +INSERT INTO `command` (`name`, `permission`, `help`) VALUES +('server debug', 872, 'Syntax: .server debug\n\nShows detailed information about server setup, useful when reporting a bug'); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_08_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_08_00_world.sql new file mode 100644 index 00000000000..83f9ca2a582 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_08_00_world.sql @@ -0,0 +1,22 @@ +ALTER TABLE `creature` + ADD `phaseUseFlags` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `spawnMask`, + ADD `terrainSwapMap` int(11) NOT NULL DEFAULT '-1' AFTER `PhaseGroup`; + +ALTER TABLE `gameobject` + ADD `phaseUseFlags` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `spawnMask`, + ADD `terrainSwapMap` int(11) NOT NULL DEFAULT '-1' AFTER `PhaseGroup`; + +DROP TABLE `terrain_phase_info`; + +ALTER TABLE `transports` ADD `phaseUseFlags` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `name`; + +DELETE FROM `trinity_string` WHERE `entry` IN (101,178,179,180,181,182,183,184,185); +INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES +(101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\nX: %f Y: %f Z: %f Orientation: %f'), +(178,'grid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u MMap: %u)'), +(179,'PhaseShift:\n* Flags %u, PersonalGuid: %s'), +(180,'* Phases: %s'), +(181,'* VisibleMapIds: %s'), +(182,'* UiWorldMapAreaSwaps: %s'), +(183,'Cosmetic'), +(184,'Personal'); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_00_world.sql new file mode 100644 index 00000000000..3df6776e091 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_00_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature` SET `modelid` = 0 WHERE `id` = 30169; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_01_world_from_335_was_2018_03_07_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_01_world_from_335_was_2018_03_07_00_world.sql new file mode 100644 index 00000000000..31f35f76c1d --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_01_world_from_335_was_2018_03_07_00_world.sql @@ -0,0 +1,15 @@ +-- Veil Skith: Darkstone of Terokk +UPDATE `creature` SET `MovementType`=0, `spawndist`=0 WHERE `guid`=65930; +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (22288); +DELETE FROM `disables` WHERE `sourceType`=0 AND `entry` IN (38729,38736); +UPDATE `conditions` SET `SourceGroup`=1 WHERE `SourceEntry` IN (38729) AND `SourceTypeOrReferenceId`=13 AND `ConditionValue2`=185191; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (38729) AND `ConditionValue2`=22288; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (38736) AND `ConditionValue1`=185191; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,4,38729,0,0, 31,0,3,22288,0,0,0,'',''), +(13,1,38736,0,0, 30,0,185191,15,0,0,0,'',''); + +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=22288; +DELETE FROM `smart_scripts` WHERE (`entryorguid`=22288 AND `source_type`=0); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22288, 0, 0, 0, 8, 0, 100, 0, 38729, 0, 5000, 5000, 41, 0, 30, 0, 0, 0, 0, 20, 185191, 5, 0, 0, 0, 0, 0, "Terokk target - on spellhit - despawn gob"); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_02_world_from_335_was_2018_03_08_00_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_02_world_from_335_was_2018_03_08_00_world_335.sql new file mode 100644 index 00000000000..21e010a97b3 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_02_world_from_335_was_2018_03_08_00_world_335.sql @@ -0,0 +1,26 @@ +/* +-- +DELETE FROM `conditions` WHERE `SourceEntry` IN (28806) AND `SourceTypeOrReferenceId`=13 AND `ConditionValue1`=5; +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=17066 WHERE `SourceEntry` IN (29172) AND `SourceTypeOrReferenceId`=13; +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=17066 WHERE `SourceEntry` IN (29531) AND `SourceTypeOrReferenceId`=13; +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=17066 WHERE `SourceEntry` IN (29831) AND `SourceTypeOrReferenceId`=13; + +DELETE FROM `conditions` WHERE `SourceEntry` IN (30098) AND `SourceTypeOrReferenceId`=17; +DELETE FROM `conditions` WHERE `SourceEntry` IN (30098) AND `SourceTypeOrReferenceId`=13; +INSERT INTO conditions (SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName, COMMENT) VALUES +(13, 2, 30098, 0, 0, 31, 0, 3, 17253, 0, 0, 0, 0, "", ""), +(13, 2, 30098, 0, 0, 29, 0, 17233, 20, 0, 1, 0, 0, "", ""), +(13, 1, 30098, 0, 0, 31, 0, 5, 182483, 0, 0, 0, 0, "", ""), +(13, 4, 30098, 0, 0, 31, 0, 5, 181653, 0, 0, 0, 0, "", ""); + +DELETE FROM `conditions` WHERE `SourceEntry` IN (17233) AND `SourceTypeOrReferenceId`=22; +INSERT INTO conditions (SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName, COMMENT) VALUES +(22, 1, 17233, 0, 0, 6, 0, 67, 0, 0, 1, 0, 0, "", ""); + +UPDATE `event_scripts` SET `datalong2`=55000 WHERE `id`=10561; +DELETE FROM `smart_scripts` WHERE `entryorguid`=17253 AND `source_type`=0 AND `id`=6; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(17253, 0, 6, 0, 52, 0, 100, 0, 7, 17233, 0, 0, 32, 0, 0, 0, 0, 0, 0, 20, 182483, 20, 0, 0, 0, 0, 0, "Defile Uther's Tomb Trigger - On Text 7 Over - reset gob"); +UPDATE smart_scripts SET `target_o`=0.2935 WHERE `entryorguid`=17238 AND `source_type`=0 AND `id`=16; +UPDATE smart_scripts SET `target_type`=21, `target_param1`=50 WHERE `entryorguid`=1723801 AND `source_type`=9 AND `id`=1; +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_03_world_from_335_was_2018_03_08_01_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_03_world_from_335_was_2018_03_08_01_world.sql new file mode 100644 index 00000000000..733c143e6e3 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_03_world_from_335_was_2018_03_08_01_world.sql @@ -0,0 +1,7 @@ +-- +DELETE FROM `gameobject_template` WHERE `entry`=300077; +DELETE FROM `gameobject_template_addon` WHERE `entry`=300077; +UPDATE `gameobject` SET `id`=182140 WHERE `guid`=99918 AND `id`=300077; +UPDATE `gameobject` SET `id`=182141 WHERE `guid`=99919 AND `id`=300077; +UPDATE `gameobject` SET `id`=182142 WHERE `guid`=99920 AND `id`=300077; +UPDATE `gameobject` SET `id`=182143 WHERE `guid`=99921 AND `id`=300077; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_04_world_from_335_was_2018_03_08_02_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_04_world_from_335_was_2018_03_08_02_world.sql new file mode 100644 index 00000000000..0b6b72230f9 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_04_world_from_335_was_2018_03_08_02_world.sql @@ -0,0 +1,85 @@ +-- +DELETE FROM `creature` WHERE id=18109; +UPDATE `conditions` SET `SourceGroup`=2 WHERE `SourceEntry` IN (31927) AND `SourceTypeOrReferenceId`=13; + +-- Windyreed Quest Credit (Hut 01) SAI +SET @ENTRY := 18142; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +SET @SPELL_LIVING_FIRE := 31927; -- Living Fire +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY*100) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,8,0,100,0,@SPELL_LIVING_FIRE,0,20000,20000,80,@ENTRY*100,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - On Spellhit - Run Script"), +(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,11,31928,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - cast Living Fire"), +(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,33,@ENTRY,0,0,0,0,0,7,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - credit kill"), +(@ENTRY*100,9,2,0,0,0,100,0,7000,7000,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1850.186401,6378.753906,49.132702,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1843.883911,6373.384277,46.005417,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,4,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1845.056030,6383.819336,56.662624,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,5,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1845.103638,6391.827148,53.700901,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,6,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1831.184937,6391.026855,45.671902,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,7,0,0,0,100,0,2000,2000,0,0,51,0,0,0,0,0,0,10,60165,17139,0,0,0,0,0,"Windyreed Quest Credit - Script - Kill Creature Inside Burning Hut"); + +-- Windyreed Quest Credit (Hut 02) SAI +SET @ENTRY := 18143; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +SET @SPELL_LIVING_FIRE := 31927; -- Living Fire +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY*100) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,8,0,100,0,@SPELL_LIVING_FIRE,0,20000,20000,80,@ENTRY*100,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - On Spellhit - Run Script"), +(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,11,31928,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - cast Living Fire"), +(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,33,@ENTRY,0,0,0,0,0,7,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - credit kill"), +(@ENTRY*100,9,2,0,0,0,100,0,7000,7000,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1915.344116,6350.488770,52.229897,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1907.135986,6353.901367,48.899532,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,4,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1911.698730,6354.161133,58.254566,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,5,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1926.308350,6360.901855,57.298611,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,6,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1921.458862,6367.373047,59.892593,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,7,0,0,0,100,0,2000,2000,0,0,51,0,0,0,0,0,0,10,60159,17139,0,0,0,0,0,"Windyreed Quest Credit - Script - Kill Creature Inside Burning Hut"); + +-- Windyreed Quest Credit (Hut 03) SAI +SET @ENTRY := 18144; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +SET @SPELL_LIVING_FIRE := 31927; -- Living Fire +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY*100) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,8,0,100,0,@SPELL_LIVING_FIRE,0,20000,20000,80,@ENTRY*100,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - On Spellhit - Run Script"), +(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,11,31928,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - cast Living Fire"), +(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,33,@ENTRY,0,0,0,0,0,7,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - credit kill"), +(@ENTRY*100,9,2,0,0,0,100,0,7000,7000,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1969.078369,6278.307129,56.866646,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1977.147461,6277.312988,59.912029,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,5,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1974.763306,6269.175781,51.401920,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,6,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1970.424805,6273.501953,61.741539,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,7,0,0,0,100,0,2000,2000,0,0,51,0,0,0,0,0,0,10,60157,17139,0,0,0,0,0,"Windyreed Quest Credit - Script - Kill Creature Inside Burning Hut"); + +-- Windyreed Quest Credit (Big Hut) SAI +SET @ENTRY := 18110; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +SET @SPELL_LIVING_FIRE := 31927; -- Living Fire +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY*100) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,8,0,100,0,@SPELL_LIVING_FIRE,0,20000,20000,80,@ENTRY*100,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - On Spellhit - Run Script"), +(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,11,31928,0,0,0,0,0,1,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - cast Living Fire"), +(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,33,@ENTRY,0,0,0,0,0,7,0,0,0,0,0,0,0,"Windyreed Quest Credit - Script - credit kill"), +(@ENTRY*100,9,2,0,0,0,100,0,7000,7000,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1816.939941,6283.669922,61.357101,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1816.94,6283.67,61.3571,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,4,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1819.71,6305.89,63.4012,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,5,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1819.55,6298.08,73.4331,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,6,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1801.45,6308.03,59.2728,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,7,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1808.88,6307.05,72.4877,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,8,0,0,0,100,0,0,0,0,0,50,182146,20,0,0,0,0,8,0,0,0,-1794.54,6300.6,71.2263,0,"Windyreed Quest Credit - Script - Summon Hut Fire (Large)"), +(@ENTRY*100,9,9,0,0,0,100,0,2000,2000,0,0,51,0,0,0,0,0,0,10,60166,17139,0,0,0,0,0,"Windyreed Quest Credit - Script - Kill Creatures Inside Burning Hut"), +(@ENTRY*100,9,10,0,0,0,100,0,0,0,0,0,51,0,0,0,0,0,0,10,60167,17139,0,0,0,0,0,"Windyreed Quest Credit - Script - Kill Creatures Inside Burning Hut"); + +SET @ENTRY := 18109; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,1,54,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Living Fire - just summoned - Say text"), +(@ENTRY,0,1,0,61,0,100,0,0,0,0,0,89,7,0,0,0,0,0,1,0,0,0,0,0,0,0,"Living Fire - just summoned - start random movement"), +(@ENTRY,0,2,0,1,0,100,1,20000,20000,0,0,41,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Living Fire - ooc - despawn"); + +DELETE FROM `creature_text` WHERE `CreatureID`=@ENTRY; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(@ENTRY,0,0,"Burn! Burn! Burn!",12,12,100,0,0,0,14778,0,"Living Fire"); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_05_world_from_335_was_2018_03_08_03_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_05_world_from_335_was_2018_03_08_03_world.sql new file mode 100644 index 00000000000..e3358c05e93 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_05_world_from_335_was_2018_03_08_03_world.sql @@ -0,0 +1,4 @@ +DELETE FROM `conditions` WHERE `SourceEntry` IN (34387) AND `SourceTypeOrReferenceId`=13; +INSERT INTO conditions (SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName, COMMENT) VALUES +(13, 2, 34387, 0, 0, 31, 0, 3, 19652, 0, 0, 0, 0, "", ""), +(13, 2, 34387, 0, 1, 31, 0, 3, 19717, 0, 0, 0, 0, "", ""); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_06_world_from_335_was_2018_03_08_04_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_06_world_from_335_was_2018_03_08_04_world.sql new file mode 100644 index 00000000000..d8f83f2222c --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_06_world_from_335_was_2018_03_08_04_world.sql @@ -0,0 +1,18 @@ +-- +DELETE FROM `conditions` WHERE `SourceEntry` IN (36460) AND `SourceTypeOrReferenceId`=13; +INSERT INTO conditions (SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName, COMMENT) VALUES +(13, 4, 36460, 0, 0, 31, 0, 3, 21262, 0, 0, 0, 0, "", ""); + +SET @ENTRY := 21262; +UPDATE `creature_template` SET `AIName`='SmartAI', `flags_extra`=130 WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,1,8,0,100,0,36460,0,5000,5000,11,34815,0,0,0,0,0,1,0,0,0,0,0,0,0,"Equipement trigger - On Spellhit - Cast spell"), +(@ENTRY,0,1,2,61,0,100,0,0,0,0,0,41,0,0,0,0,0,0,20,183808,5,0,0,0,0,0,"Equipement trigger - On Spellhit - despawn gob"), +(@ENTRY,0,2,3,61,0,100,0,0,0,0,0,41,0,0,0,0,0,0,20,183807,5,0,0,0,0,0,"Equipement trigger - On Spellhit - despawn gob"), +(@ENTRY,0,3,4,61,0,100,0,0,0,0,0,41,0,0,0,0,0,0,20,183806,5,0,0,0,0,0,"Equipement trigger - On Spellhit - despawn gob"), +(@ENTRY,0,4,0,61,0,100,0,0,0,0,0,41,0,0,0,0,0,0,20,183805,5,0,0,0,0,0,"Equipement trigger - On Spellhit - despawn gob"); + +DELETE FROM `disables` WHERE `sourceType`=0 AND `entry` IN (36460); +INSERT INTO `disables`(`sourceType`,`entry`,`flags`,`comment`) VALUES +(0,36460,64,'Ignore LOS'); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_07_world_from_335_was_2018_03_08_05_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_07_world_from_335_was_2018_03_08_05_world.sql new file mode 100644 index 00000000000..bdca574f0ae --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_07_world_from_335_was_2018_03_08_05_world.sql @@ -0,0 +1,14 @@ +-- +DELETE FROM `conditions` WHERE `SourceEntry` IN (38250) AND `SourceTypeOrReferenceId`=13; +INSERT INTO conditions (SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName, COMMENT) VALUES +(13, 1, 38250, 0, 0, 31, 0, 3, 22058, 0, 0, 0, 0, "", ""); + +SET @ENTRY := 22061; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,25,0,100,0,0,0,0,0,11,38250,0,0,0,0,0,19,22058,0,0,0,0,0,0,"Shadowmoon Soulstealer - On reset - Cast spell"); + +UPDATE `creature_template_addon` SET `auras`='38376' WHERE `entry` IN (22058); +UPDATE `creature_template_addon` SET `emote`=468, `auras`='38442' WHERE `entry` IN (22081); +DELETE FROM `creature_addon` WHERE `guid` IN (77374, 77375, 77376, 77379, 77380, 77381, 77382, 77383, 77384, 77387, 77389, 77390, 77391, 77392, 77393, 77394); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_08_world_from_335_was_2018_03_08_06_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_08_world_from_335_was_2018_03_08_06_world.sql new file mode 100644 index 00000000000..480024a8e74 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_08_world_from_335_was_2018_03_08_06_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=22356 WHERE `SourceEntry` IN (38629) AND `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1 AND `ElseGroup`=0; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_09_world_from_335_was_2018_03_08_07_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_09_world_from_335_was_2018_03_08_07_world.sql new file mode 100644 index 00000000000..ce67a8f1940 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_09_world_from_335_was_2018_03_08_07_world.sql @@ -0,0 +1,3 @@ +-- +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=22395 WHERE `SourceEntry` IN (39124) AND `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1; +UPDATE `creature` SET `position_x`=-4543.57177, `position_y`=1022.8920, `position_z`=9.817793, `orientation`=3.930219 WHERE `id`=21797; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_10_world_from_335_was_2018_03_08_08_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_10_world_from_335_was_2018_03_08_08_world.sql new file mode 100644 index 00000000000..2c651fe4b98 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_10_world_from_335_was_2018_03_08_08_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=23037 WHERE `SourceEntry` IN (39974) AND `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_11_world_from_335_was_2018_03_08_09_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_11_world_from_335_was_2018_03_08_09_world.sql new file mode 100644 index 00000000000..2fe2522cb3b --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_11_world_from_335_was_2018_03_08_09_world.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM `creature` WHERE `guid`=64984; +INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES +(64984,23746,530,0,0,1,1,0,0,6718.222656, -7594.638672, 126.092712,0.413325,7200,0,0,0,0,0,0,0,0,"",0); +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=23746, `ConditionValue3`=64984 WHERE `SourceEntry` IN (42391) AND `SourceTypeOrReferenceId`=13; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_12_world_from_335_was_2018_03_08_10_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_12_world_from_335_was_2018_03_08_10_world.sql new file mode 100644 index 00000000000..a05484272ef --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_12_world_from_335_was_2018_03_08_10_world.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM `creature` WHERE `guid`=64985; +INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES +(64985,25114,530,0,0,1,1,0,0,12664.64160,-6986.25,15.608,1.622840,7200,0,0,0,0,0,0,0,0,"",0); +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=25114 WHERE `SourceEntry` IN (45149) AND `SourceTypeOrReferenceId`=13; \ No newline at end of file diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_13_world_from_335_was_2018_03_08_12_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_13_world_from_335_was_2018_03_08_12_world.sql new file mode 100644 index 00000000000..1f4c7555b93 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_13_world_from_335_was_2018_03_08_12_world.sql @@ -0,0 +1,3 @@ +-- +UPDATE `conditions` SET `ConditionValue1`=4, `ConditionValue2`=0 WHERE `SourceEntry` IN (45368,45371) AND `SourceTypeOrReferenceId`=13; +UPDATE `conditions` SET `ConditionValue1`=3, `ConditionValue2`=17066 WHERE `SourceEntry` IN (46852,46896) AND `SourceTypeOrReferenceId`=13; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_14_world_from_335_was_2018_03_08_13_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_14_world_from_335_was_2018_03_08_13_world.sql new file mode 100644 index 00000000000..f4b1c66649a --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_14_world_from_335_was_2018_03_08_13_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_addon` SET `bytes1`=33554432 WHERE `guid`= 128739; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_15_world_from_335_was_2018_03_09_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_15_world_from_335_was_2018_03_09_00_world.sql new file mode 100644 index 00000000000..254201d45d0 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_15_world_from_335_was_2018_03_09_00_world.sql @@ -0,0 +1,15 @@ +-- +DELETE FROM `conditions` WHERE `SourceEntry` IN (50790,50791,50802,50803,50825,50826) AND `SourceTypeOrReferenceId`=13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 50790, 0, 0, 31, 0, 3, 22515, 0, 0, 0, 0, "", ""), +(13, 1, 50791, 0, 0, 31, 0, 3, 22515, 0, 0, 0, 0, "", ""), +(13, 2, 50790, 0, 0, 31, 0, 5, 192163, 0, 0, 0, 0, "", ""), +(13, 2, 50791, 0, 0, 31, 0, 5, 192164, 0, 0, 0, 0, "", ""), +(13, 1, 50802, 0, 0, 31, 0, 3, 22515, 0, 0, 0, 0, "", ""), +(13, 1, 50803, 0, 0, 31, 0, 3, 22515, 0, 0, 0, 0, "", ""), +(13, 2, 50802, 0, 0, 31, 0, 5, 192163, 0, 0, 0, 0, "", ""), +(13, 2, 50803, 0, 0, 31, 0, 5, 192164, 0, 0, 0, 0, "", ""), +(13, 1, 50825, 0, 0, 31, 0, 3, 22515, 0, 0, 0, 0, "", ""), +(13, 1, 50826, 0, 0, 31, 0, 3, 22515, 0, 0, 0, 0, "", ""), +(13, 2, 50825, 0, 0, 31, 0, 5, 192163, 0, 0, 0, 0, "", ""), +(13, 2, 50826, 0, 0, 31, 0, 5, 192164, 0, 0, 0, 0, "", ""); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_16_world_from_335_was_2018_03_09_01_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_16_world_from_335_was_2018_03_09_01_world.sql new file mode 100644 index 00000000000..a5728690891 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_16_world_from_335_was_2018_03_09_01_world.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM `conditions` WHERE SourceEntry IN (44608) AND `SourceTypeOrReferenceId`=13; +UPDATE `conditions` SET `SourceGroup`=1 WHERE `SourceEntry` IN (44213,43986) AND `SourceTypeOrReferenceId`=13; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_17_world_from_335_was_2018_03_09_02_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_17_world_from_335_was_2018_03_09_02_world.sql new file mode 100644 index 00000000000..49a6e0d5446 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_17_world_from_335_was_2018_03_09_02_world.sql @@ -0,0 +1,69 @@ +-- +-- Shadowlord Deathwail +UPDATE `creature_addon` SET `mount`=20684 WHERE `guid`=77084; -- Fix mount + +/* +DELETE FROM `creature_template_movement` WHERE `CreatureId`=22006; -- Fix inhabit type +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`) VALUES +(22006,1,1,2,0); +*/ + +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=22006; +DELETE FROM `smart_scripts` WHERE `entryorguid`=22006 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22006,0,0,0,6,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Shadowlord Deathwail - On Just Died - Say Line 0"), +(22006,0,1,0,0,0,100,0,0,0,3000,5000,11,12471,64,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowlord Deathwail - In Combat - Cast 'Shadow Bolt'"), +(22006,0,2,0,0,0,100,0,5000,7000,15000,17000,11,15245,0,0,0,0,0,1,0,0,0,0,0,0,0,"Shadowlord Deathwail - In Combat - Cast 'Shadow Bolt Volley'"), +(22006,0,3,0,0,0,100,0,9000,12000,18000,24000,11,32709,0,0,0,0,0,5,0,0,0,0,0,0,0,"Shadowlord Deathwail - In Combat - Cast 'Death Coil'"), +(22006,0,4,0,0,0,100,0,14000,17000,22000,28000,11,27641,0,0,0,0,0,5,0,0,0,0,0,0,0,"Shadowlord Deathwail - In Combat - Cast 'Fear'"); + +DELETE FROM `creature_text` WHERE `CreatureID`=22006; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(22006,0,0,"Master... I've failed you...",14,0,100,0,0,0,19820,0,"Shadowlord Deathwail"); + +-- Shadowmoon Soulstealer +DELETE FROM `smart_scripts` WHERE `entryorguid`=22061 AND `source_type`=0 AND `id` IN (1,2); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22061,0,1,0,25,0,100,0,0,0,0,0,8,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Shadowmoon Soulstealer - On Reset - Set Reactstate Passive"), +(22061,0,2,0,4,0,100,0,0,0,0,0,11,38250,0,0,0,0,0,19,22058,0,0,0,0,0,0,"Shadowmoon Soulstealer - On Aggro - Cast 'Heart of Fury Siphon'"); + +-- Shadowmoon Darkweaver +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=22081; +DELETE FROM `smart_scripts` WHERE `entryorguid`=22081 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22081,0,0,0,0,0,100,0,0,0,3000,5000,11,9613,64,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowmoon Darkweaver - In Combat - Cast 'Shadow Bolt'"), +(22081,0,1,0,9,0,100,0,0,30,15000,18000,11,11962,0,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowmoon Darkweaver - Within 0-30 Range - Cast 'Immolate'"), +(22081,0,2,0,9,0,100,0,0,10,8000,11000,11,35373,0,0,0,0,0,1,0,0,0,0,0,0,0,"Shadowmoon Darkweaver - Within 0-10 Range - Cast 'Shadowfury'"); + +-- Shadowmoon Chosen +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=22084; +DELETE FROM `smart_scripts` WHERE `entryorguid`=22084 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22084,0,0,0,9,0,100,0,0,5,15000,17000,11,38618,0,0,0,0,0,1,0,0,0,0,0,0,0,"Shadowmoon Chosen - Within 0-5 Range - Cast 'Whirlwind'"), +(22084,0,1,0,0,0,100,0,8000,10000,18000,22000,11,10966,0,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowmoon Chosen - In Combat - Cast 'Uppercut'"); + +-- Shadowmoon Slayer +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=22082; +DELETE FROM `smart_scripts` WHERE `entryorguid`=22082 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22082,0,0,1,2,0,100,1,0,30,0,0,11,3019,0,0,0,0,0,1,0,0,0,0,0,0,0,"Shadowmoon Slayer - Between 0-30% Health - Cast 'Frenzy'"), +(22082,0,1,0,61,0,100,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Shadowmoon Slayer - Between 0-30% Health - Say Line 0"), +(22082,0,2,0,0,0,100,0,5000,7000,12000,15000,11,37577,0,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowmoon Slayer - In Combat - Cast 'Debilitating Strike'"); + +DELETE FROM `creature_text` WHERE `CreatureID`=22082; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(22082,0,0,"%s goes into a frenzy!",16,0,100,0,0,0,2384,0,"Shadowmoon Slayer"); + +-- Shadowsworn Drakonid +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=22072; +DELETE FROM `smart_scripts` WHERE `entryorguid`=22072 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22072,0,0,0,0,0,100,0,5000,7000,11000,13000,11,15496,0,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowsworn Drakonid - In Combat - Cast 'Cleave'"), +(22072,0,1,0,0,0,100,0,6000,8000,14000,16000,11,17547,0,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowsworn Drakonid - In Combat - Cast 'Mortal Strike'"), +(22072,0,2,0,0,0,100,0,9000,11000,18000,22000,11,16145,0,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowsworn Drakonid - In Combat - Cast 'Sunder Armor'"); + +-- Shadowmoon Retainer +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=22102; +DELETE FROM `smart_scripts` WHERE `entryorguid`=22102 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22102,0,0,0,0,0,100,0,0,0,2000,4000,11,15547,64,0,0,0,0,2,0,0,0,0,0,0,0,"Shadowmoon Retainer - In Combat - Cast 'Shoot'"); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_18_world_from_335_was_2018_03_09_04_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_18_world_from_335_was_2018_03_09_04_world.sql new file mode 100644 index 00000000000..14447f9ba8f --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_18_world_from_335_was_2018_03_09_04_world.sql @@ -0,0 +1,2 @@ +-- Ashtongue Deathsworn +UPDATE `smart_scripts` SET `event_type`=54, `comment`="Ashtongue Deathsworn - On Just Summoned - Start Waypoint" WHERE `entryorguid`=21701 AND `source_type`=0 AND `id`=0; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_19_world_from_335_was_2018_03_09_05_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_19_world_from_335_was_2018_03_09_05_world.sql new file mode 100644 index 00000000000..745051f2117 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_19_world_from_335_was_2018_03_09_05_world.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM `gameobject_template_addon` WHERE `entry` BETWEEN 300010 AND 300205; +DELETE FROM `gameobject_template` WHERE `entry` BETWEEN 300010 AND 300205; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_20_world_from_335_was_2018_03_09_06_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_20_world_from_335_was_2018_03_09_06_world_335.sql new file mode 100644 index 00000000000..bbe9b8709ae --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_20_world_from_335_was_2018_03_09_06_world_335.sql @@ -0,0 +1,36 @@ +/* +-- Rhapsody Shindigger +DELETE FROM `creature_text` WHERE `CreatureID`=5634; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(5634,0,0,"Time to brew up a Kalimdor Kocktail! Hiccup!",12,7,100,4,0,0,1950,0,"Rhapsody Shindigger"), +(5634,1,0,"That should do it! Hiccup!",12,7,100,0,0,0,1951,0,"Rhapsody Shindigger"), +(5634,2,0,"%s chugs his drink.",16,0,100,92,0,0,1952,0,"Rhapsody Shindigger"), +(5634,3,0,"Hiccup!",12,7,100,34,0,0,1953,0,"Rhapsody Shindigger"), +(5634,4,0,"Ok, who pushed me down? Was it you, $n? Someone turn the lights back on. Hiccup!",12,7,100,6,0,0,1954,0,"Rhapsody Shindigger"), +(5634,5,0,"One more sip of the ol' fire water and I'll be ready to talk. Hiccup! Cheers!",12,7,100,1,0,0,1955,0,"Rhapsody Shindigger"), +(5634,6,0,"So, $n, I'm ready to tell you what happened in the Swamp of Sorrows. Hiccup!",12,7,100,1,0,0,1956,0,"Rhapsody Shindigger"); + +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=5634; +DELETE FROM `smart_scripts` WHERE `entryorguid`=5634 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=563400 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(5634,0,0,0,20,0,100,0,1452,0,0,0,80,563400,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Quest 'Rhapsody's Kalimdor Kocktail' Finished - Run Script"), +(563400,9,0,0,0,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Remove Npc Flag Questgiver"), +(563400,9,1,0,0,0,100,0,0,0,0,0,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Set Emote State 0"), +(563400,9,2,0,0,0,100,0,1000,1000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Say Line 0"), +(563400,9,3,0,0,0,100,0,3000,3000,0,0,5,33,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Play Emote 33"), +(563400,9,4,0,0,0,100,0,2000,2000,0,0,17,133,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Set Emote State 133"), +(563400,9,5,0,0,0,100,0,8000,8000,0,0,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Set Emote State 0"), +(563400,9,6,0,0,0,100,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Say Line 1"), +(563400,9,7,0,0,0,100,0,3000,3000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Say Line 2"), +(563400,9,8,0,0,0,100,0,3000,3000,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Say Line 3"), +(563400,9,9,0,0,0,100,0,2000,2000,0,0,1,4,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Say Line 4"), +(563400,9,10,0,0,0,100,0,3500,3500,0,0,5,33,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Play Emote 33"), +(563400,9,11,0,0,0,100,0,1500,1500,0,0,1,5,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Say Line 5"), +(563400,9,12,0,0,0,100,0,4500,4500,0,0,5,92,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Play Emote 92"), +(563400,9,13,0,0,0,100,0,3000,3000,0,0,5,34,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Play Emote 34"), +(563400,9,14,0,0,0,100,0,2000,2000,0,0,1,6,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Say Line 6"), +(563400,9,15,0,0,0,100,0,3000,3500,0,0,5,33,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Play Emote 33"), +(563400,9,16,0,0,0,100,0,2000,2000,0,0,17,93,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Set Emote State 93"), +(563400,9,17,0,0,0,100,0,0,0,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Rhapsody Shindigger - On Script - Add Npc Flag Questgiver"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_21_world_from_335_was_2018_03_09_07_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_21_world_from_335_was_2018_03_09_07_world_335.sql new file mode 100644 index 00000000000..9ad0071afba --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_21_world_from_335_was_2018_03_09_07_world_335.sql @@ -0,0 +1,144 @@ +/* +-- Quest "The Prodigal Lich Returns" +UPDATE `creature_template` SET `speed_walk`=1 WHERE `entry`=5666; + +UPDATE `creature_text` SET `Emote`=0 WHERE `CreatureID`=1498 AND `GroupID`=0; +UPDATE `creature_text` SET `Emote`=2 WHERE `CreatureID`=5666 AND `GroupID` IN (0,2); + +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (149800,566600) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(149800,9,0,0,0,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Remove Npc Flag Questgiver"), +(149800,9,1,0,0,0,100,0,0,0,0,0,64,1,0,0,0,0,0,7,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Store Targetlist"), +(149800,9,2,0,0,0,100,0,0,0,0,0,11,7762,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Cast 'Summon Gunther's Visage'"), +(149800,9,3,0,0,0,100,0,2000,2000,0,0,12,5666,1,21000,0,0,0,8,0,0,0,1765.81,57.0857,-46.3189,1.591,"Bethor Iceshard - On Script - Summon Creature 'Gunther's Visage'"), +(149800,9,4,0,0,0,100,0,0,0,0,0,100,1,0,0,0,0,0,19,5666,0,0,0,0,0,0,"Bethor Iceshard - On Script - Send Targetlist to 'Guther's Visage'"), +(149800,9,5,0,0,0,100,0,3000,3000,0,0,66,0,0,0,0,0,0,19,5666,0,0,0,0,0,0,"Bethor Iceshard - On Script - Set Orientation"), +(149800,9,6,0,0,0,100,0,18000,18000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Set Orientation"), +(149800,9,7,0,0,0,100,0,0,0,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Add Npc Flag Questgiver"), +(566600,9,0,0,0,0,100,0,0,0,0,0,53,0,5666,0,0,0,0,1,0,0,0,0,0,0,0,"Gunther's Visage - On Script - Start Waypoint"), +(566600,9,1,0,0,0,100,0,4000,4000,0,0,1,0,0,0,0,0,0,12,1,0,0,0,0,0,0,"Gunther's Visage - On Script - Say Line 0"), +(566600,9,2,0,0,0,100,0,4000,4000,0,0,1,1,0,0,0,0,0,12,1,0,0,0,0,0,0,"Gunther's Visage - On Script - Say Line 1"), +(566600,9,3,0,0,0,100,0,5000,5000,0,0,66,0,0,0,0,0,0,12,1,0,0,0,0,0,0,"Gunther's Visage - On Script - Set Orientation"), +(566600,9,4,0,0,0,100,0,0,0,0,0,1,2,0,0,0,0,0,12,1,0,0,0,0,0,0,"Gunther's Visage - On Script - Say Line 2"), +(566600,9,5,0,0,0,100,0,5000,5000,0,0,1,0,0,0,0,0,0,19,1498,0,0,0,0,0,0,"Gunther's Visage - On Script - Say Line 0 (Bethor Iceshard)"); + +DELETE FROM `waypoints` WHERE `entry`=5666; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES +(5666,1,1766.04,62.8454,-46.3213,""); + +-- Quest "Rot Hide Origins" +DELETE FROM `smart_scripts` WHERE `entryorguid`=149801 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(149801,9,0,0,0,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Remove Npc Flag Questgiver"), +(149801,9,1,0,0,0,100,0,0,0,0,0,11,5017,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Cast 'Divining Trance'"), +(149801,9,2,0,0,0,100,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Say Line 1"), +(149801,9,3,0,0,0,100,0,7000,7000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Say Line 2"), +(149801,9,4,0,0,0,100,0,4000,4000,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Say Line 3"), +(149801,9,5,0,0,0,100,0,0,0,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bethor Iceshard - On Script - Add Npc Flag Questgiver"); + +-- Quest "The Mind's Eye" +DELETE FROM `smart_scripts` WHERE `entryorguid`=251900 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(251900,9,0,0,0,0,100,0,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kin'weelay - On Script - Remove Npc Flag Questgiver"), +(251900,9,1,0,0,0,100,0,0,0,0,0,0,90,8,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kin'weelay - On Script - Set Flag Standstate 'Kneel'"), +(251900,9,2,0,0,0,100,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kin'weelay - On Script - Say Line 0"), +(251900,9,3,0,0,0,100,0,3000,3000,0,0,0,11,2362,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kin'weelay - On Script - Cast Create Spellstone"), +(251900,9,4,0,0,0,100,0,6000,6000,0,0,0,91,8,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kin'weelay - On Script - Remove Flag Standstate 'Kneel'"), +(251900,9,5,0,0,0,100,0,2000,2000,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kin'weelay - On Script - Say Line 1"), +(251900,9,6,0,0,0,100,0,0,0,0,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kin'weelay - On Script - Add Npc Flag Questgiver"); + +-- Quest "Elixir of Suffering (Part 2)" +DELETE FROM `smart_scripts` WHERE `entryorguid`=2230 AND `source_type`=0; -- Umpi +DELETE FROM `smart_scripts` WHERE `entryorguid`=223000 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2230,0,0,0,20,0,100,512,499,0,0,0,80,223000,0,0,0,0,0,1,0,0,0,0,0,0,0,"Umpi - On Quest 'Elixir of Agony (Part 2)' Rewarded - Run Script"), +(2230,0,1,0,20,0,100,512,499,0,0,0,45,1,1,0,0,0,0,19,2216,0,0,0,0,0,0,"Umpi - On Quest 'Elixir of Agony (Part 2)' Rewarded - Set Data to Apothecary Lydon"), +(223000,9,0,0,0,0,100,0,1000,1000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Umpi - On Script - Say Line 0"), +(223000,9,1,0,0,0,100,0,0,0,0,0,11,3240,0,0,0,0,0,1,0,0,0,0,0,0,0,"Umpi - On Script - Cast 'Bloody Explosion'"); + +DELETE FROM `creature_text` WHERE `CreatureID`=2230; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(2230,0,0,"Croak!",12,0,100,0,0,0,579,0,"Umpi"); + +DELETE FROM `smart_scripts` WHERE `entryorguid`=2216 AND `source_type`=0 AND `id`=1; -- Apothecary Lydon +DELETE FROM `smart_scripts` WHERE `entryorguid`=221601 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2216,0,1,0,38,0,100,512,1,1,0,0,80,221601,0,0,0,0,0,1,0,0,0,0,0,0,0,"Apothecary Lydon - On Data Set - Run Script"), +(221601,9,0,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,8,0,0,0,0,0,0,4.15964,"Apothecary Lydon - On Script - Set Orientation"), +(221601,9,1,0,0,0,100,0,2000,2000,0,0,5,11,0,0,0,0,0,1,0,0,0,0,0,0,0,"Apothecary Lydon - On Script - Play Emote 'Laugh'"), +(221601,9,2,0,0,0,100,0,5000,5000,0,0,66,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Apothecary Lydon - On Script - Set Orientation"); + +-- Quest "Elixir of Pain (Part 2)" +DELETE FROM `smart_scripts` WHERE `entryorguid`=2274 AND `source_type`=0 AND `id` IN (0,1,2); -- Stanley +DELETE FROM `smart_scripts` WHERE `entryorguid`=227400 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2274,0,0,0,20,0,100,512,502,0,0,0,80,227400,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stanley - On Quest 'Elixir of Pain (Part 2)' Rewarded - Run Script"), +(227400,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stanley - On Script - Say Line 0"), +(227400,9,1,0,0,0,100,0,2000,2000,0,0,36,2275,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stanley - On Script - Update Template To 'Enraged Stanley'"), +(227400,9,2,0,0,0,100,0,0,0,0,0,3,2275,0,0,0,0,0,1,0,0,0,0,0,0,0,"Stanley - On Script - Morph To Creature 'Enraged Stanley'"), +(227400,9,3,0,0,0,100,0,0,0,0,0,49,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Stanley - On Script - Start Attacking"); + +DELETE FROM `creature_text` WHERE `CreatureID`=2274; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(2274,0,0,"%s sniffs the elixir then eagerly digs in!",16,0,100,0,0,0,580,0,"Stanley"); + +-- Quest "Elixir of Agony (Part 5)" +DELETE FROM `creature_text` WHERE `CreatureID`=2284 AND `GroupID` IN (2,3,4); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(2284,2,0,"%s raises his mug to his eye, and frowns.",16,0,100,0,0,0,561,0,"Captured Farmer"), +(2284,3,0,"%s swaggers heavily.",16,0,100,0,0,0,559,0,"Captured Farmer"), +(2284,4,0,"%s mumbles incoherent words.",16,0,100,1,0,0,560,0,"Captured Farmer"); + +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (172800,1589100,1589200,1589300) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(172800,9,0,0,0,0,100,0,0,0,0,0,50,1729,120,0,0,0,0,8,0,0,0,0.437117,-942.794,61.9384,-2.54818,"Dusty Rug - On Script - Summon Gameobject 'Tainted Keg'"), +(172800,9,1,0,0,0,100,0,0,0,0,0,45,1,1,0,0,0,0,9,2284,0,50,0,0,0,0,"Dusty Rug - On Script - Set Data 1 1"), +(172800,9,2,0,0,0,100,0,1000,1000,0,0,50,1730,119,0,0,0,0,8,0,0,0,0.437117,-942.794,61.9384,-2.54818,"Dusty Rug - On Script - Summon Gameobject 'Tainted Keg Smoke'"), +(1589100,9,0,0,0,0,100,0,3000,3000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Say Line 0"), +(1589100,9,1,0,0,0,100,0,0,0,0,0,69,0,0,0,0,0,0,8,0,0,0,0.426498,-944.53,61.9386,0,"Captured Farmer - On Script - Move To Position"), +(1589100,9,2,0,0,0,100,0,3000,3000,0,0,5,16,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Play Emote 'Kneel'"), +(1589100,9,3,0,0,0,100,0,1000,1000,0,0,5,26,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Play Emote 'Stand'"), +(1589100,9,4,0,0,0,100,0,3000,3000,0,0,17,418,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Set Emote State 'Eat'"), +(1589100,9,5,0,0,0,100,0,6000,6000,0,0,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Set Emote State 'None'"), +(1589100,9,6,0,0,0,100,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Say Line 2"), +(1589100,9,7,0,0,0,100,0,2000,2000,0,0,37,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Kill Self"), +(1589200,9,0,0,0,0,100,0,3000,3000,0,0,69,0,0,0,0,0,0,8,0,0,0,-1.4032,-942.653,61.9,0,"Captured Farmer - On Script - Move To Position"), +(1589200,9,1,0,0,0,100,0,3000,3000,0,0,5,16,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Play Emote 'Kneel'"), +(1589200,9,2,0,0,0,100,0,1000,1000,0,0,5,26,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Play Emote 'Stand'"), +(1589200,9,3,0,0,0,100,0,3000,3000,0,0,17,418,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Set Emote State 'Eat'"), +(1589200,9,4,0,0,0,100,0,6000,6000,0,0,17,64,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Set Emote State 'Stun'"), +(1589200,9,5,0,0,0,100,0,0,0,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Say Line 3"), +(1589200,9,6,0,0,0,100,0,4000,4000,0,0,37,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Kill Self"), +(1589300,9,0,0,0,0,100,0,3000,3000,0,0,69,0,0,0,0,0,0,8,0,0,0,0.446124,-941.072,61.91,0,"Captured Farmer - On Script - Move To Position"), +(1589300,9,1,0,0,0,100,0,3000,3000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Say Line 1"), +(1589300,9,2,0,0,0,100,0,0,0,0,0,5,16,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Play Emote 'Kneel'"), +(1589300,9,3,0,0,0,100,0,1000,1000,0,0,5,26,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Play Emote 'Stand'"), +(1589300,9,4,0,0,0,100,0,3000,3000,0,0,17,418,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Set Emote State 'Eat'"), +(1589300,9,5,0,0,0,100,0,7500,7500,0,0,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Set Emote State 'None'"), +(1589300,9,6,0,0,0,100,0,500,500,0,0,1,4,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Say Line 4"), +(1589300,9,7,0,0,0,100,0,3000,3000,0,0,37,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Farmer - On Script - Kill Self"); + +-- Quest "The Tower of Althalaxx (Part 4)" +DELETE FROM `smart_scripts` WHERE `entryorguid`=366300 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(366300,9,0,0,0,0,100,0,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Delgren the Purifier - On Script - Remove Npc Flag Questgiver"), +(366300,9,1,0,0,0,100,0,1000,1000,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 0"), +(366300,9,2,0,0,0,100,0,4000,4000,0,0,0,5,61,0,0,0,0,0,1,0,0,0,0,0,0,0,"Delgren the Purifier - On Script - Play Emote 61"), +(366300,9,3,0,0,0,100,0,0,0,0,0,0,50,19862,5,0,0,0,0,8,0,0,0,3186.81,189.953,4.57494,3.48778,"Delgren the Purifier - On Script - Summon Object 'Glowing Soulgem'"), +(366300,9,4,0,0,0,100,0,1000,1000,0,0,0,12,4509,8,0,0,0,0,8,0,0,0,3188.2,191.026,4.53698,3.6802,"Delgren the Purifier - On Script - Summon Sargath"), +(366300,9,5,0,0,0,100,0,3000,3000,0,0,0,1,0,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 0 (Sargath)"), +(366300,9,6,0,0,0,100,0,7000,7000,0,0,0,1,1,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 1 (Sargath)"), +(366300,9,7,0,0,0,100,0,7000,7000,0,0,0,1,2,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 2 (Sargath)"), +(366300,9,8,0,0,0,100,0,7000,7000,0,0,0,1,3,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 3 (Sargath)"), +(366300,9,9,0,0,0,100,0,7000,7000,0,0,0,1,4,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 4 (Sargath)"), +(366300,9,10,0,0,0,100,0,7000,7000,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 1"), +(366300,9,11,0,0,0,100,0,7000,7000,0,0,0,1,5,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 5 (Sargath)"), +(366300,9,12,0,0,0,100,0,7000,7000,0,0,0,1,6,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Say Line 6 (Sargath)"), +(366300,9,13,0,0,0,100,0,0,0,0,0,0,41,0,0,0,0,0,0,19,4509,0,0,0,0,0,0,"Delgren the Purifier - On Script - Despawn (Sargath)"), +(366300,9,14,0,0,0,100,0,1000,1000,0,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Delgren the Purifier - On Script - Add Npc Flag Questgiver"); + +-- Quest "Fields of Grief (Part 2)" +DELETE FROM `smart_scripts` WHERE `entryorguid`=1931 AND `source_type`=0 AND `id`=1; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(1931,0,1,0,20,0,100,512,407,0,0,0,59,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Captured Scarlet Zealot - On Quest 'Fields of Grief' Finished - Set Run Off"); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_22_world_from_335_was_2018_03_09_08_world_335.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_22_world_from_335_was_2018_03_09_08_world_335.sql new file mode 100644 index 00000000000..90ddb599efa --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_22_world_from_335_was_2018_03_09_08_world_335.sql @@ -0,0 +1,23 @@ +/* +-- Junior Apothecary Holland +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=10665; +DELETE FROM `smart_scripts` WHERE `entryorguid`=10665 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(10665,0,0,0,1,0,100,0,10000,20000,40000,60000,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Junior Apothecary Holland - Out of Combat - Say Line 0"); + +DELETE FROM `creature_text` WHERE `CreatureID`=10665; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(10665,0,0,"What could be taking so long?",12,1,100,0,0,0,5955,0,"Junior Apothecary Holland"), +(10665,0,1,"How long can it take to pick a handful of weeds?",12,1,100,0,0,0,5956,0,"Junior Apothecary Holland"), +(10665,0,2,"At this rate I could have gathered them myself!",12,1,100,0,0,0,5957,0,"Junior Apothecary Holland"), +(10665,0,3,"If you want something done right, do it yourself!",12,1,100,0,0,0,5958,0,"Junior Apothecary Holland"), +(10665,0,4,"As if I had all eternity.",12,1,100,0,0,0,5959,0,"Junior Apothecary Holland"), +(10665,0,5,"Ah, this must be him now... no? Bah!",12,1,100,0,0,0,5960,0,"Junior Apothecary Holland"), +(10665,0,6,"Maybe I should have just bought some off of Faruza?",12,1,100,0,0,0,5961,0,"Junior Apothecary Holland"), +(10665,0,7,"I had to go and requisition an Abomination... an Abomination!",12,1,100,0,0,0,5962,0,"Junior Apothecary Holland"); + +UPDATE `waypoint_data` SET `action`=0 WHERE `id`=284120; +UPDATE `waypoint_data` SET `delay`=0 WHERE `id`=284120 AND `point` IN (8,12); + +DELETE FROM `waypoint_scripts` WHERE `id` IN (22,1002,1003,1004,1005); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_23_world_from_335_was_2018_03_09_09_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_23_world_from_335_was_2018_03_09_09_world.sql new file mode 100644 index 00000000000..93d6e00b439 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_09_23_world_from_335_was_2018_03_09_09_world.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM `gameobject` WHERE `guid` BETWEEN 99928 AND 99934; +DELETE FROM `gameobject_addon` WHERE `guid` BETWEEN 99928 AND 99934; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_00_world_from_335_2018_03_10_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_00_world_from_335_2018_03_10_00_world.sql new file mode 100644 index 00000000000..3e7f934b11e --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_00_world_from_335_2018_03_10_00_world.sql @@ -0,0 +1,125 @@ +-- Duplicates removed +DELETE FROM `creature` WHERE `guid` IN (129516,129555,129532,129520,129556,129545); +DELETE FROM `creature_addon` WHERE `guid` IN (129516,129555,129532,129520,129556,129545); + +-- Death Knight Initiate +UPDATE `creature` SET `modelid`=0, `spawntimesecs` = 30 WHERE `id` = 28406; +UPDATE `creature_addon` SET `auras` = "" WHERE `guid` IN (129492,129493,129494,129495,129496,129497,129498,129499); +UPDATE `creature_addon` SET `path_id` = 1295170 WHERE `guid` IN (129517); +UPDATE `creature_addon` SET `path_id` = 1295180 WHERE `guid` IN (129518); +UPDATE `creature_addon` SET `path_id` = 1295290 WHERE `guid` IN (129529); +UPDATE `creature_addon` SET `path_id` = 1295300 WHERE `guid` IN (129530); +UPDATE `creature_addon` SET `path_id` = 1295310 WHERE `guid` IN (129531); +UPDATE `creature_addon` SET `path_id` = 1295440 WHERE `guid` IN (129544); +UPDATE `creature_addon` SET `path_id` = 1295460 WHERE `guid` IN (129546); +UPDATE `creature_addon` SET `path_id` = 1295470 WHERE `guid` IN (129547); +-- #1 +UPDATE `creature` SET `position_x` = 2409.489, `position_y` = -5729.18, `position_z` = 153.92, `orientation` = 3.8, `spawndist` = 0, `MovementType` = 2 WHERE `guid` = 129547; +DELETE FROM `waypoint_data` WHERE `id`= 1295470; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295470,1,2409.489,-5729.18,153.92,2000,0,3.8,100,0), +(1295470,2,2398.24,-5738.1,153.923,0,0,3.51732,100,0), +(1295470,3,2386.8,-5734.52,153.922,0,0,2.57013,100,0), +(1295470,4,2372.86,-5722.17,153.922,0,0,2.26872,100,0), +(1295470,5,2366.02,-5712.39,153.922,0,0,1.78963,100,0), +(1295470,6,2365.51,-5706.24,153.922,0,0,0.855789,100,0), +(1295470,7,2368.78,-5703.15,153.922,10000,0,0.690856,100,0), +(1295470,8,2358.21,-5706.16,153.922,0,0,2.85855,100,0), +(1295470,9,2341.04,-5689.82,153.922,0,0,2.3292,100,0), +(1295470,10,2313.73,-5661.47,152.761,0,0,2.56639,100,0), +(1295470,11,2296.29,-5652.93,147.341,0,0,2.88369,100,0), +(1295470,12,2278.16,-5647.89,143.137,0,0,2.9638,100,0), +(1295470,13,2255.96,-5645.48,136.996,0,0,3.24733,100,0), +(1295470,14,2234.36,-5647.77,130.968,0,0,3.42954,100,0), +(1295470,15,2209.59,-5657.5,122.594,0,0,3.76412,100,0), +(1295470,16,2188.9,-5675.6,113.179,0,0,3.89371,100,0), +(1295470,17,2163.24,-5699.88,104.99,1000,0,3.94476,100,0), +(1295470,18,2149.23,-5715.65,101.528,1000,1188,3.99581,100,0); +-- #2 +UPDATE `creature` SET `position_x` = 2455.27, `position_y` = -5523.46, `position_z` = 376.892, `orientation` = 5.96, `spawndist` = 0, `MovementType` = 2 WHERE `guid` = 129544; +DELETE FROM `waypoint_data` WHERE `id`= 1295440; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295440,1,2455.27,-5523.46,376.892,1000,0,5.96,100,0), +(1295440,2,2451.31,-5528.92,376.891,0,0,3.66393,100,0), +(1295440,3,2424.47,-5542.18,376.905,0,0,3.84064,100,0), +(1295440,4,2403.66,-5563.52,377.005,0,0,4.24905,100,0), +(1295440,5,2398.1,-5601.44,376.89,0,0,4.6064,100,0), +(1295440,6,2397.91,-5614.95,377.018,0,0,4.26946,100,0), +(1295440,7,2386.16,-5630.91,377.169,0,0,4.1116,100,0), +(1295440,8,2379.33,-5642.43,382.439,0,0,4.2137,100,0), +(1295440,9,2349.92,-5690.11,382.241,6000,1188,4.12338,100,0); +-- #3 +UPDATE `creature` SET `position_x` = 2416.227, `position_y` = -5557.54, `position_z` = 376.89, `orientation` = 1.72, `MovementType` = 2, `spawndist` = 0 WHERE `guid` = 129518; +DELETE FROM `waypoint_data` WHERE `id`= 1295180; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295180,1,2416.227,-5557.54,376.89,1000,0,1.72,100,0), +(1295180,2,2411.56,-5553.34,376.887,0,0,4.06137,100,0), +(1295180,3,2396.85,-5576.58,376.906,0,0,4.57353,100,0), +(1295180,4,2397.55,-5612.24,377.017,0,0,4.15728,100,0), +(1295180,5,2377.61,-5641.62,382.439,0,0,3.72139,100,0), +(1295180,6,2350.25,-5690.08,382.24,3000,1188,3.64364,100,0); +-- #4 +UPDATE `creature` SET `position_x` = 2523.21, `position_y` = -5628.21, `position_z` = 377.004, `orientation` = 1.93, `MovementType` = 2, `spawndist` = 0 WHERE `guid` = 129529; +DELETE FROM `waypoint_data` WHERE `id`= 1295290; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295290,1,2523.21,-5628.21,377.004,1000,0,1.93,100,0), +(1295290,2,2517.63,-5625.44,377.01,0,0,3.57347,100,0), +(1295290,3,2480.55,-5653.1,376.997,0,0,3.48315,100,0), +(1295290,4,2454.17,-5656.89,376.903,0,0,3.08653,100,0), +(1295290,5,2426.21,-5647.1,377.148,0,0,2.74566,100,0), +(1295290,6,2397.13,-5648.46,377.169,0,0,3.41325,100,0), +(1295290,7,2385.79,-5652.5,382.439,0,0,3.6638,100,0), +(1295290,8,2370,-5666.09,382.256,0,0,3.98424,100,0), +(1295290,9,2354.86,-5693.19,382.239,5000,1188,4.18451,100,0); +-- #5 +UPDATE `creature` SET `position_x` = 2477.05, `position_y` = -5647.81, `position_z` = 377.006, `orientation` = 5.92, `MovementType` = 2, `spawndist` = 0 WHERE `guid` = 129517; +DELETE FROM `waypoint_data` WHERE `id`= 1295170; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295170,1,2477.05,-5647.81,377.006,1000,0,5.92,100,0), +(1295170,2,2478.18,-5653.36,377.01,0,0,3.68083,100,0), +(1295170,3,2465.83,-5657.38,376.892,0,0,3.28028,100,0), +(1295170,4,2420.22,-5645.76,376.89,0,0,3.26536,100,0), +(1295170,5,2397.62,-5648.51,377.168,0,0,3.48684,100,0), +(1295170,6,2386.39,-5653.11,382.439,0,0,3.7311,100,0), +(1295170,7,2369.21,-5667.63,382.253,0,0,4.09474,100,0), +(1295170,8,2353.39,-5690.9,382.239,3000,1188,3.8222,100,0); +-- #6 +UPDATE `creature` SET `position_x` = 2413.64, `position_y` = -5737.27, `position_z` = 153.923, `orientation` = 3.86902, `MovementType` = 2, `spawndist` = 0 WHERE `guid` = 129546; +DELETE FROM `waypoint_data` WHERE `id`= 1295460; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295460,1,2413.64,-5737.27,153.923,1000,0,3.86902,100,0), +(1295460,2,2373.33,-5754.69,153.961,0,0,3.34356,100,0), +(1295460,3,2349.31,-5761.49,153.922,5000,0,1.76884,100,0), +(1295460,4,2367,-5771.87,151.392,0,0,6.06104,100,0), +(1295460,5,2380.8,-5774.62,154.028,0,0,6.11209,100,0), +(1295460,6,2416.41,-5776.45,148.509,0,0,6.01155,100,0), +(1295460,7,2430.24,-5787.44,140.563,0,0,5.40444,100,0), +(1295460,8,2437.59,-5808,127.202,0,0,4.96462,100,0), +(1295460,9,2441.6,-5832.16,117.571,0,0,4.86645,100,0), +(1295460,10,2430.39,-5856.4,107.743,1000,0,4.06142,100,0), +(1295460,11,2442.87,-5912.91,102.116,1000,1188,4.90965,100,0); +-- #7 +UPDATE `creature` SET `position_x` = 2352.14, `position_y` = -5757.91, `position_z` = 153.923, `MovementType` = 2, `spawndist` = 0 WHERE `guid` = 129531; +DELETE FROM `waypoint_data` WHERE `id`= 1295310; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295310,1,2352.14,-5757.91,153.923,1000,0,3.23752,100,0), +(1295310,2,2352.14,-5757.91,153.923,4000,0,3.23752,100,0), +(1295310,3,2341.61,-5727.9,153.922,0,0,1.55677,100,0), +(1295310,4,2342.13,-5697.18,153.922,0,0,1.84658,100,0), +(1295310,5,2317.47,-5651.82,151.422,0,0,2.33588,100,0), +(1295310,6,2297.54,-5644.36,147.052,0,0,2.94867,100,0), +(1295310,7,2245.47,-5638.62,135.882,0,0,3.22356,100,0), +(1295310,8,2205.02,-5658.24,121.031,0,0,3.8778,100,0), +(1295310,9,2161.18,-5703.33,104.27,1000,0,4.13698,100,0), +(1295310,10,2178.08,-5770.89,101.346,1000,1188,5.00484,100,0); +-- #8 +UPDATE `creature` SET `position_x` = 2368.652588, `position_y` = -5703.335449, `position_z` = 153.922272, `orientation` = 0.69, `MovementType` = 2, `spawndist` = 0 WHERE `guid` = 129530; +DELETE FROM `waypoint_data` WHERE `id`= 1295300; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `action`, `orientation`, `action_chance`, `move_type`) VALUES +(1295300,1,2368.652588,-5703.335449,153.922272,1000,0,0.69,100,0), +(1295300,2,2373.52,-5722.48,153.922,0,0,5.28585,100,0), +(1295300,3,2411.22,-5764.47,152.347,0,0,5.47748,100,0), +(1295300,4,2429.98,-5784.48,142.151,0,0,5.22694,100,0), +(1295300,5,2435.23,-5800.88,131.736,0,0,4.99918,100,0), +(1295300,6,2431.43,-5850.32,109.292,1000,0,4.36615,100,0), +(1295300,7,2417.03,-5895.6,104.705,1000,1188,4.31903,100,0); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_01_world_from_335_2018_03_10_01_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_01_world_from_335_2018_03_10_01_world.sql new file mode 100644 index 00000000000..f68bc3ccc07 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_01_world_from_335_2018_03_10_01_world.sql @@ -0,0 +1,2 @@ +-- +DELETE FROM `conditions` WHERE `SourceEntry` IN (52683) AND `SourceTypeOrReferenceId`=13 AND `ConditionValue2`=28897; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_02_world_from_335_2018_03_10_02_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_02_world_from_335_2018_03_10_02_world.sql new file mode 100644 index 00000000000..f6fc64c66c7 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_10_02_world_from_335_2018_03_10_02_world.sql @@ -0,0 +1,40 @@ +-- Quest King of the Mountain +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=16 AND `SourceEntry` IN (31784,31785); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(16,0,31784,0,0,23,0,4513,0,0,0,0,0,'','Geargrinder\'s Jumpbot - Dismount when player is outside intended zone Ymirhein'), +(16,0,31785,0,0,23,0,4513,0,0,0,0,0,'','Thunderbomb\'s Jumpbot - Dismount when player is outside intended zone Ymirhein'); + +DELETE FROM `creature_template_addon` WHERE `entry` IN(31784,31785); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES +(31784, 0, 0, 0, 1, 0, 4341), +(31785, 0, 0, 0, 1, 0, 4341); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN(4338,59643); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,59643,0,0,31,0,3,23837,0,0,0,0,'','Spell Plant Horde Battle Standard targets ELM General Purpose Bunny'), +(13,1,4338,0,0,31,0,3,23837,0,0,0,0,'','Spell Plant Alliance Battle Standard targets ELM General Purpose Bunny'); + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (31784,31785) AND `spell_id`=46598; +INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES +(31784, 46598, 1, 0), +(31785, 46598, 1, 0); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=18 AND `SourceGroup` IN (31784,31785) AND `SourceEntry` IN(59593,59656,46598); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(18, 31784, 59593, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Only player for SpellClick'), +(18, 31784, 46598, 0, 0, 31, 0, 3, 0, 0, 0, 0, 0, '', 'Only unit for SpellClick'), +(18, 31785, 59656, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Only player for SpellClick'), +(18, 31785, 46598, 0, 0, 31, 0, 3, 0, 0, 0, 0, 0, '', 'Only unit for SpellClick'); + +DELETE FROM `vehicle_template_accessory` WHERE `entry` IN(31784, 31785); +INSERT INTO `vehicle_template_accessory` (`entry`,`accessory_entry`,`seat_id`,`minion`,`description`,`summontype`,`summontimer`) VALUES +(31784,31801,1,1,'Geargrinder\'s Jumpbot',6,30000), +(31785,31801,1,1,'Thunderbomb\'s Jumpbot',6,30000); + +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_q13280_13283_jump_jets'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(4336,'spell_q13280_13283_jump_jets'); + +DELETE FROM `spell_proc` WHERE `SpellId`=4341; +INSERT INTO `spell_proc` (`SpellId`,`SchoolMask`,`SpellFamilyName`,`SpellFamilyMask0`,`SpellFamilyMask1`,`SpellFamilyMask2`,`ProcFlags`,`SpellTypeMask`,`SpellPhaseMask`,`HitMask`,`AttributesMask`,`ProcsPerMinute`,`Chance`,`Cooldown`,`Charges`) VALUES +(4341,0,0,0,0,0,4096,1,1,0,0,0,0,0,0); diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_00_world_from_335_2018_03_10_03_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_00_world_from_335_2018_03_10_03_world.sql new file mode 100644 index 00000000000..ed65852b8b3 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_00_world_from_335_2018_03_10_03_world.sql @@ -0,0 +1,21 @@ +/* +DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (2673, 2674, 17578, 16111, 24792, 32543, 32546, 32547, 32542, 32545, 30527, 31143, 31144, 31146, 32541, 32666, 32667); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`) VALUES +(2673, 1, 0, 0, 1), +(2674, 1, 0, 0, 1), +(17578, 1, 0, 0, 1), +(16111, 1, 0, 0, 1), +(24792, 1, 0, 0, 1), +(32543, 1, 0, 0, 1), +(32546, 1, 0, 0, 1), +(32547, 1, 0, 0, 1), +(32542, 1, 0, 0, 1), +(32545, 1, 0, 0, 1), +(30527, 1, 0, 0, 1), +(31143, 1, 0, 0, 1), +(31144, 1, 0, 0, 1), +(31146, 1, 0, 0, 1), +(32541, 1, 0, 0, 1), +(32666, 1, 0, 0, 1), +(32667, 1, 0, 0, 1); +*/ diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_01_world_from_335_2018_03_11_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_01_world_from_335_2018_03_11_00_world.sql new file mode 100644 index 00000000000..9bcf34f7114 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_01_world_from_335_2018_03_11_00_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `gameobject` SET `phaseMask`=1, `spawntimesecs`=-1 WHERE `id`=192538; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_02_world_from_335_2018_03_12_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_02_world_from_335_2018_03_12_00_world.sql new file mode 100644 index 00000000000..8bc1cad596d --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_12_02_world_from_335_2018_03_12_00_world.sql @@ -0,0 +1,11 @@ +-- +UPDATE `smart_scripts` SET `event_param5`=1 WHERE event_type=10 AND `source_type`=0; +UPDATE `smart_scripts` SET `event_param2`=30, `event_param5`=1 WHERE `entryorguid`=24248 AND `source_type`=0; +UPDATE `smart_scripts` SET `event_flags`=0 WHERE `entryorguid`=24938 AND event_type=10 AND `source_type`=0; +UPDATE `smart_scripts` SET `event_param1`=1 WHERE `entryorguid`in (27376,27378,27379,27381) AND event_type=10 AND `source_type`=0; +UPDATE `smart_scripts` SET `event_param1`=1, `event_param2`=20, `event_param5`=0 WHERE `entryorguid`=30313 AND `event_type`=10 AND `source_type`=0; +UPDATE `creature_template` SET `AIName`="" WHERE `entry`=32582; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (32582) AND `source_type`=0; +UPDATE `smart_scripts` SET `event_flags`=0, `event_param2`=10, `event_param3`=60000, `event_param4`=60000, `event_param5`=1 WHERE `entryorguid`=5917 AND `source_type`=0 AND `id`=0; +UPDATE `smart_scripts` SET `event_flags`=0, `event_param1`=1, `event_param2`=20, `event_param3`=40000, `event_param4`=60000, `event_param5`=1 WHERE `entryorguid`=9021 AND `source_type`=0 AND `id`=0; +UPDATE `smart_scripts` SET `event_param5`=0 WHERE `entryorguid` IN (27246, 2775, 23370, 23760, 24845, 23675, 23673, 23672, 24271, 24364, 24468, 24510, 24527, 24718, 24938,24979,25063,30313) AND event_type=10 AND `source_type`=0; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_00_world_from_335_2018_03_13_01_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_00_world_from_335_2018_03_13_01_world.sql new file mode 100644 index 00000000000..c051b060f83 --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_00_world_from_335_2018_03_13_01_world.sql @@ -0,0 +1,3 @@ +-- +UPDATE `creature_template_addon` SET `auras`="31261" WHERE `entry` IN (20561); +UPDATE `smart_scripts` SET `action_type`=41, `action_param1`=0 WHERE `entryorguid` IN (20561) AND `source_type`=0 AND `id`=2; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_01_world_from_335_2018_03_15_00_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_01_world_from_335_2018_03_15_00_world.sql new file mode 100644 index 00000000000..0ade27aee5a --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_01_world_from_335_2018_03_15_00_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `smart_scripts` SET `event_param1`=18000, `event_param2`=18000, `event_param3`=18000, `event_param4`=18000 WHERE `entryorguid` IN (-111996, -112005) AND `source_type`=0 AND `id`=0; diff --git a/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_02_world_from_335_2018_03_15_01_world.sql b/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_02_world_from_335_2018_03_15_01_world.sql new file mode 100644 index 00000000000..63a3150a7ed --- /dev/null +++ b/sql/old/4.3.4/world/27_2018_03_16/2018_03_15_02_world_from_335_2018_03_15_01_world.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_custom_attr` WHERE `entry`=6788; +INSERT INTO `spell_custom_attr` (`entry`, `attributes`) VALUES +(6788, 0x40); diff --git a/sql/updates/auth/4.3.4/2018_03_16_00_auth.sql b/sql/updates/auth/4.3.4/2018_03_16_00_auth.sql new file mode 100644 index 00000000000..1f10777e894 --- /dev/null +++ b/sql/updates/auth/4.3.4/2018_03_16_00_auth.sql @@ -0,0 +1,2 @@ +-- TDB 4.3.4-28 auth database +UPDATE `updates` SET `state`='ARCHIVED'; diff --git a/sql/updates/characters/4.3.4/2018_03_16_00_characters.sql b/sql/updates/characters/4.3.4/2018_03_16_00_characters.sql new file mode 100644 index 00000000000..dcb54742a20 --- /dev/null +++ b/sql/updates/characters/4.3.4/2018_03_16_00_characters.sql @@ -0,0 +1,2 @@ +-- TDB 4.3.4-28 characters database +UPDATE `updates` SET `state`='ARCHIVED'; diff --git a/sql/updates/world/4.3.4/2018_03_16_00_world.sql b/sql/updates/world/4.3.4/2018_03_16_00_world.sql new file mode 100644 index 00000000000..b1e6907dd19 --- /dev/null +++ b/sql/updates/world/4.3.4/2018_03_16_00_world.sql @@ -0,0 +1,3 @@ +UPDATE `version` SET `db_version`='TDB 434.28', `cache_id`=28 LIMIT 1; + +UPDATE `updates` SET `state`='ARCHIVED'; diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp index 750e155da87..f86cccbf0a9 100644 --- a/src/common/Collision/DynamicTree.cpp +++ b/src/common/Collision/DynamicTree.cpp @@ -142,11 +142,11 @@ void DynamicMapTree::update(uint32 t_diff) struct DynamicTreeIntersectionCallback { - DynamicTreeIntersectionCallback(std::set const& phases) : _didHit(false), _phases(phases) { } + DynamicTreeIntersectionCallback(PhaseShift const& phaseShift) : _didHit(false), _phaseShift(phaseShift) { } bool operator()(G3D::Ray const& r, GameObjectModel const& obj, float& distance) { - _didHit = obj.intersectRay(r, distance, true, _phases, VMAP::ModelIgnoreFlags::Nothing); + _didHit = obj.intersectRay(r, distance, true, _phaseShift, VMAP::ModelIgnoreFlags::Nothing); return _didHit; } @@ -154,20 +154,20 @@ struct DynamicTreeIntersectionCallback private: bool _didHit; - std::set _phases; + PhaseShift const& _phaseShift; }; -bool DynamicMapTree::getIntersectionTime(std::set const& phases, G3D::Ray const& ray, G3D::Vector3 const& endPos, float& maxDist) const +bool DynamicMapTree::getIntersectionTime(G3D::Ray const& ray, G3D::Vector3 const& endPos, PhaseShift const& phaseShift, float& maxDist) const { float distance = maxDist; - DynamicTreeIntersectionCallback callback(phases); + DynamicTreeIntersectionCallback callback(phaseShift); impl->intersectRay(ray, callback, distance, endPos); if (callback.didHit()) maxDist = distance; return callback.didHit(); } -bool DynamicMapTree::getObjectHitPos(std::set const& phases, G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist) const +bool DynamicMapTree::getObjectHitPos(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist, PhaseShift const& phaseShift) const { bool result = false; float maxDist = (endPos - startPos).magnitude(); @@ -182,7 +182,7 @@ bool DynamicMapTree::getObjectHitPos(std::set const& phases, G3D::Vector G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1 G3D::Ray ray(startPos, dir); float dist = maxDist; - if (getIntersectionTime(phases, ray, endPos, dist)) + if (getIntersectionTime(ray, endPos, phaseShift, dist)) { resultHitPos = startPos + dir * dist; if (modifyDist < 0) @@ -205,7 +205,7 @@ bool DynamicMapTree::getObjectHitPos(std::set const& phases, G3D::Vector return result; } -bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, std::set const& phases) const +bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, PhaseShift const& phaseShift) const { float maxDist = (endPos - startPos).magnitude(); @@ -213,17 +213,17 @@ bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 return true; G3D::Ray r(startPos, (endPos - startPos) / maxDist); - DynamicTreeIntersectionCallback callback(phases); + DynamicTreeIntersectionCallback callback(phaseShift); impl->intersectRay(r, callback, maxDist, endPos); return !callback.didHit(); } -float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, std::set const& phases) const +float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const { G3D::Vector3 v(x, y, z + 0.5f); G3D::Ray r(v, G3D::Vector3(0, 0, -1)); - DynamicTreeIntersectionCallback callback(phases); + DynamicTreeIntersectionCallback callback(phaseShift); impl->intersectZAllignedRay(r, callback, maxSearchDist); if (callback.didHit()) diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h index 7dd7b149088..4ae49c00595 100644 --- a/src/common/Collision/DynamicTree.h +++ b/src/common/Collision/DynamicTree.h @@ -29,6 +29,7 @@ namespace G3D } class GameObjectModel; +class PhaseShift; struct DynTreeImpl; class TC_COMMON_API DynamicMapTree @@ -40,11 +41,11 @@ public: DynamicMapTree(); ~DynamicMapTree(); - bool isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, std::set const& phases) const; - bool getIntersectionTime(std::set const& phases, G3D::Ray const& ray, G3D::Vector3 const& endPos, float& maxDist) const; - bool getObjectHitPos(std::set const& phases, G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist) const; + bool isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, PhaseShift const& phaseShift) const; + bool getIntersectionTime(G3D::Ray const& ray, G3D::Vector3 const& endPos, PhaseShift const& phaseShift, float& maxDist) const; + bool getObjectHitPos(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist, PhaseShift const& phaseShift) const; - float getHeight(float x, float y, float z, float maxSearchDist, std::set const& phases) const; + float getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const; void insert(const GameObjectModel&); void remove(const GameObjectModel&); diff --git a/src/common/Collision/Management/IVMapManager.h b/src/common/Collision/Management/IVMapManager.h index 3f5282c0e37..31ea635a091 100644 --- a/src/common/Collision/Management/IVMapManager.h +++ b/src/common/Collision/Management/IVMapManager.h @@ -126,7 +126,6 @@ namespace VMAP virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0; // get both area + liquid data in a single vmap lookup virtual void getAreaAndLiquidData(unsigned int mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const=0; - }; } diff --git a/src/common/Collision/Management/MMapFactory.cpp b/src/common/Collision/Management/MMapFactory.cpp index 240dbc60637..ed93d10bd1c 100644 --- a/src/common/Collision/Management/MMapFactory.cpp +++ b/src/common/Collision/Management/MMapFactory.cpp @@ -23,11 +23,11 @@ namespace MMAP { // ######################## MMapFactory ######################## // our global singleton copy - MMapManager* g_MMapManager = NULL; + MMapManager* g_MMapManager = nullptr; MMapManager* MMapFactory::createOrGetMMapManager() { - if (g_MMapManager == NULL) + if (g_MMapManager == nullptr) g_MMapManager = new MMapManager(); return g_MMapManager; @@ -38,7 +38,7 @@ namespace MMAP if (g_MMapManager) { delete g_MMapManager; - g_MMapManager = NULL; + g_MMapManager = nullptr; } } } diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp index e2d082474d6..c1f05becdd5 100644 --- a/src/common/Collision/Management/MMapManager.cpp +++ b/src/common/Collision/Management/MMapManager.cpp @@ -19,13 +19,12 @@ #include "MMapManager.h" #include "Log.h" #include "MMapFactory.h" -#include "Config.h" #include "MapDefines.h" namespace MMAP { - static char const* const MAP_FILE_NAME_FORMAT = "%s/mmaps/%03i.mmap"; - static char const* const TILE_FILE_NAME_FORMAT = "%s/mmaps/%03i%02i%02i.mmtile"; + static char const* const MAP_FILE_NAME_FORMAT = "%smmaps/%03i.mmap"; + static char const* const TILE_FILE_NAME_FORMAT = "%smmaps/%03i%02i%02i.mmtile"; // ######################## MMapManager ######################## MMapManager::~MMapManager() @@ -39,16 +38,13 @@ namespace MMAP void MMapManager::InitializeThreadUnsafe(std::unordered_map> const& mapData) { - // the caller must pass the list of all mapIds that will be used in the MMapManager lifetime - for (auto const& p : mapData) + childMapData = mapData; + // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime + for (std::pair> const& mapId : mapData) { - loadedMMaps.insert(MMapDataSet::value_type(p.first, nullptr)); - if (!p.second.empty()) - { - phaseMapData[p.first] = p.second; - for (uint32 phasedMapId : p.second) - _phaseTiles.insert(PhaseTileMap::value_type(phasedMapId, PhaseTileContainer())); - } + loadedMMaps.insert(MMapDataSet::value_type(mapId.first, nullptr)); + for (uint32 childMapId : mapId.second) + parentMapData[childMapId] = mapId.first; } thread_safe_environment = false; @@ -64,7 +60,7 @@ namespace MMAP return itr; } - bool MMapManager::loadMapData(uint32 mapId) + bool MMapManager::loadMapData(std::string const& basePath, uint32 mapId) { // we already have this map loaded? MMapDataSet::iterator itr = loadedMMaps.find(mapId); @@ -82,7 +78,7 @@ namespace MMAP } // load and init dtNavMesh - read parameters from file - std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", ".").c_str(), mapId); + std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, basePath.c_str(), mapId); FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { @@ -111,7 +107,7 @@ namespace MMAP TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId); // store inside our map list - MMapData* mmap_data = new MMapData(mesh, mapId); + MMapData* mmap_data = new MMapData(mesh); itr->second = mmap_data; return true; @@ -122,10 +118,25 @@ namespace MMAP return uint32(x << 16 | y); } - bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y) + bool MMapManager::loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y) + { + if (!loadMapImpl(basePath, mapId, x, y)) + return false; + + bool success = true; + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + if (!loadMapImpl(basePath, childMapId, x, y)) + success = false; + + return success; + } + + bool MMapManager::loadMapImpl(std::string const& basePath, uint32 mapId, int32 x, int32 y) { // make sure the mmap is loaded and ready to load tiles - if (!loadMapData(mapId)) + if (!loadMapData(basePath, mapId)) return false; // get this mmap data @@ -138,8 +149,18 @@ namespace MMAP return false; // load this tile :: mmaps/MMMXXYY.mmtile - std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", ".").c_str(), mapId, x, y); + std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, basePath.c_str(), mapId, x, y); FILE* file = fopen(fileName.c_str(), "rb"); + if (!file) + { + auto parentMapItr = parentMapData.find(mapId); + if (parentMapItr != parentMapData.end()) + { + fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, basePath.c_str(), parentMapItr->second, x, y); + file = fopen(fileName.c_str(), "rb"); + } + } + if (!file) { TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName.c_str()); @@ -191,118 +212,71 @@ namespace MMAP dtTileRef tileRef = 0; // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed - if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, 0, 0, &tileRef))) + if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))) { mmap->loadedTileRefs.insert(std::pair(packedGridPos, tileRef)); ++loadedTiles; TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i, %02i] into %03i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y); - - PhaseChildMapContainer::const_iterator phasedMaps = phaseMapData.find(mapId); - if (phasedMaps != phaseMapData.end()) - { - mmap->AddBaseTile(packedGridPos, data, fileHeader, fileHeader.size); - LoadPhaseTiles(phasedMaps, x, y); - } - return true; } - - TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); - dtFree(data); - return false; - } - - PhasedTile* MMapManager::LoadTile(uint32 mapId, int32 x, int32 y) - { - // load this tile :: mmaps/MMMXXYY.mmtile - std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", ".").c_str(), mapId, x, y); - - FILE* file = fopen(fileName.c_str(), "rb"); - if (!file) + else { - // Not all tiles have phased versions, don't flood this msg - //TC_LOG_DEBUG("phase", "MMAP:LoadTile: Could not open mmtile file '%s'", fileName); - return NULL; - } - - PhasedTile* pTile = new PhasedTile(); - - // read header - if (fread(&pTile->fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || pTile->fileHeader.mmapMagic != MMAP_MAGIC) - { - TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y); - fclose(file); - delete pTile; - return nullptr; - } - - if (pTile->fileHeader.mmapVersion != MMAP_VERSION) - { - TC_LOG_ERROR("phase", "MMAP:LoadTile: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", - mapId, x, y, pTile->fileHeader.mmapVersion, MMAP_VERSION); - fclose(file); - delete pTile; - return nullptr; - } - - pTile->data = (unsigned char*)dtAlloc(pTile->fileHeader.size, DT_ALLOC_PERM); - ASSERT(pTile->data); - - size_t result = fread(pTile->data, pTile->fileHeader.size, 1, file); - if (!result) - { - TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y); - fclose(file); - delete pTile; - return nullptr; - } - - fclose(file); - - return pTile; - } - - void MMapManager::LoadPhaseTiles(PhaseChildMapContainer::const_iterator phasedMapData, int32 x, int32 y) - { - TC_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loading phased mmtiles for map %u, x: %i, y: %i", phasedMapData->first, x, y); - - uint32 packedGridPos = packTileID(x, y); - - for (uint32 phaseMapId : phasedMapData->second) - { - // only a few tiles have terrain swaps, do not write error for them - if (PhasedTile* data = LoadTile(phaseMapId, x, y)) - { - TC_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loaded phased %03u%02i%02i.mmtile for root phase map %u", phaseMapId, x, y, phasedMapData->first); - _phaseTiles[phaseMapId][packedGridPos] = data; - } + TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); + dtFree(data); + return false; } } - void MMapManager::UnloadPhaseTile(PhaseChildMapContainer::const_iterator phasedMapData, int32 x, int32 y) + bool MMapManager::loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId) { - TC_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloading phased mmtile for map %u, x: %i, y: %i", phasedMapData->first, x, y); + if (!loadMapInstanceImpl(basePath, mapId, instanceId)) + return false; - uint32 packedGridPos = packTileID(x, y); + bool success = true; + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + if (!loadMapInstanceImpl(basePath, childMapId, instanceId)) + success = false; - for (uint32 phaseMapId : phasedMapData->second) + return success; + } + + bool MMapManager::loadMapInstanceImpl(std::string const& basePath, uint32 mapId, uint32 instanceId) + { + if (!loadMapData(basePath, mapId)) + return false; + + MMapData* mmap = loadedMMaps[mapId]; + if (mmap->navMeshQueries.find(instanceId) != mmap->navMeshQueries.end()) + return true; + + // allocate mesh query + dtNavMeshQuery* query = dtAllocNavMeshQuery(); + ASSERT(query); + if (dtStatusFailed(query->init(mmap->navMesh, 1024))) { - auto phasedTileItr = _phaseTiles.find(phaseMapId); - if (phasedTileItr == _phaseTiles.end()) - continue; - - auto dataItr = phasedTileItr->second.find(packedGridPos); - if (dataItr != phasedTileItr->second.end()) - { - TC_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloaded phased %04u%02i%02i.mmtile for root phase map %u", phaseMapId, x, y, phasedMapData->first); - dtFree(dataItr->second->data); - delete dataItr->second; - phasedTileItr->second.erase(dataItr); - } + dtFreeNavMeshQuery(query); + TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + return false; } + + TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + mmap->navMeshQueries.insert(std::pair(instanceId, query)); + return true; } bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) + { + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + unloadMapImpl(childMapId, x, y); + + return unloadMapImpl(mapId, x, y); + } + + bool MMapManager::unloadMapImpl(uint32 mapId, int32 x, int32 y) { // check if we have this map loaded MMapDataSet::const_iterator itr = GetMMapData(mapId); @@ -317,18 +291,16 @@ namespace MMAP // check if we have this tile loaded uint32 packedGridPos = packTileID(x, y); - if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end()) + auto tileRefItr = mmap->loadedTileRefs.find(packedGridPos); + if (tileRefItr == mmap->loadedTileRefs.end()) { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y); return false; } - dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos]; - // unload, and mark as non loaded - unsigned char* data = NULL; - if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, &data, NULL))) + if (dtStatusFailed(mmap->navMesh->removeTile(tileRefItr->second, nullptr, nullptr))) { // this is technically a memory leak // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used @@ -338,18 +310,9 @@ namespace MMAP } else { - mmap->loadedTileRefs.erase(packedGridPos); + mmap->loadedTileRefs.erase(tileRefItr); --loadedTiles; - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); - - PhaseChildMapContainer::const_iterator phasedMaps = phaseMapData.find(mapId); - if (phasedMaps != phaseMapData.end()) - { - mmap->DeleteBaseTile(packedGridPos); - UnloadPhaseTile(phasedMaps, x, y); - } - else - dtFree(data); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %04i[%02i, %02i] from %03i", mapId, x, y, mapId); return true; } @@ -357,6 +320,16 @@ namespace MMAP } bool MMapManager::unloadMap(uint32 mapId) + { + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + unloadMapImpl(childMapId); + + return unloadMapImpl(mapId); + } + + bool MMapManager::unloadMapImpl(uint32 mapId) { MMapDataSet::iterator itr = loadedMMaps.find(mapId); if (itr == loadedMMaps.end() || !itr->second) @@ -372,19 +345,10 @@ namespace MMAP { uint32 x = (i->first >> 16); uint32 y = (i->first & 0x0000FFFF); - unsigned char* data = NULL; - if (dtStatusFailed(mmap->navMesh->removeTile(i->second, &data, NULL))) + if (dtStatusFailed(mmap->navMesh->removeTile(i->second, nullptr, nullptr))) TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y); else { - PhaseChildMapContainer::const_iterator phasedMaps = phaseMapData.find(mapId); - if (phasedMaps != phaseMapData.end()) - { - mmap->DeleteBaseTile(i->first); - UnloadPhaseTile(phasedMaps, x, y); - } - else - dtFree(data); --loadedTiles; TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); } @@ -424,187 +388,25 @@ namespace MMAP return true; } - dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId, TerrainSet swaps) + dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId) { MMapDataSet::const_iterator itr = GetMMapData(mapId); if (itr == loadedMMaps.end()) - return NULL; + return nullptr; - return itr->second->GetNavMesh(swaps); + return itr->second->navMesh; } - dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId, TerrainSet swaps) + dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId) { - MMapDataSet::const_iterator itr = GetMMapData(mapId); + auto itr = GetMMapData(mapId); if (itr == loadedMMaps.end()) - return NULL; + return nullptr; - MMapData* mmap = itr->second; - if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) - { - // allocate mesh query - dtNavMeshQuery* query = dtAllocNavMeshQuery(); - ASSERT(query); - if (dtStatusFailed(query->init(mmap->GetNavMesh(swaps), 1024))) - { - dtFreeNavMeshQuery(query); - TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); - return NULL; - } + auto queryItr = itr->second->navMeshQueries.find(instanceId); + if (queryItr == itr->second->navMeshQueries.end()) + return nullptr; - TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); - mmap->navMeshQueries.insert(std::pair(instanceId, query)); - } - - return mmap->navMeshQueries[instanceId]; - } - - MMapData::MMapData(dtNavMesh* mesh, uint32 mapId) - { - navMesh = mesh; - _mapId = mapId; - } - - MMapData::~MMapData() - { - for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i) - dtFreeNavMeshQuery(i->second); - - dtFreeNavMesh(navMesh); - } - - void MMapData::RemoveSwap(PhasedTile* ptile, uint32 swap, uint32 packedXY) - { - uint32 x = (packedXY >> 16); - uint32 y = (packedXY & 0x0000FFFF); - - if (loadedPhasedTiles[swap].find(packedXY) == loadedPhasedTiles[swap].end()) - { - TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: mmtile %03u[%02i, %02i] unload skipped, due to not loaded", swap, x, y); - return; - } - dtMeshHeader* header = (dtMeshHeader*)ptile->data; - - // remove old tile - if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], NULL, NULL))) - TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not unload phased %03u%02i%02i.mmtile from navmesh", swap, x, y); - else - { - TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Unloaded phased %03u%02i%02i.mmtile from navmesh", swap, x, y); - - // restore base tile - if (dtStatusSucceed(navMesh->addTile(_baseTiles[packedXY]->data, _baseTiles[packedXY]->dataSize, 0, 0, &loadedTileRefs[packedXY]))) - TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Loaded base mmtile %03u[%02i, %02i] into %03i[%02i, %02i]", _mapId, x, y, _mapId, header->x, header->y); - else - TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not load base %03u%02i%02i.mmtile to navmesh", _mapId, x, y); - } - - loadedPhasedTiles[swap].erase(packedXY); - - if (loadedPhasedTiles[swap].empty()) - { - _activeSwaps.erase(swap); - TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Fully removed swap %u from map %u", swap, _mapId); - } - } - - void MMapData::AddSwap(PhasedTile* ptile, uint32 swap, uint32 packedXY) - { - uint32 x = (packedXY >> 16); - uint32 y = (packedXY & 0x0000FFFF); - - if (loadedTileRefs.find(packedXY) == loadedTileRefs.end()) - { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %03u[%02i, %02i] load skipped, due to not loaded base tile on map %u", swap, x, y, _mapId); - return; - } - if (loadedPhasedTiles[swap].find(packedXY) != loadedPhasedTiles[swap].end()) - { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: WARNING! phased mmtile %03u[%02i, %02i] load skipped, due to already loaded on map %u", swap, x, y, _mapId); - return; - } - - dtMeshHeader* header = (dtMeshHeader*)ptile->data; - - const dtMeshTile* oldTile = navMesh->getTileByRef(loadedTileRefs[packedXY]); - - if (!oldTile) - { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %03u[%02i, %02i] load skipped, due to not loaded base tile ref on map %u", swap, x, y, _mapId); - return; - } - - // header xy is based on the swap map's tile set, wich doesn't have all the same tiles as root map, so copy the xy from the orignal header - header->x = oldTile->header->x; - header->y = oldTile->header->y; - - // remove old tile - if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], NULL, NULL))) - TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not unload %03u%02i%02i.mmtile from navmesh", _mapId, x, y); - else - { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: Unloaded %03u%02i%02i.mmtile from navmesh", _mapId, x, y); - - _activeSwaps.insert(swap); - loadedPhasedTiles[swap].insert(packedXY); - - // add new swapped tile - if (dtStatusSucceed(navMesh->addTile(ptile->data, ptile->fileHeader.size, 0, 0, &loadedTileRefs[packedXY]))) - TC_LOG_DEBUG("phase", "MMapData::AddSwap: Loaded phased mmtile %03u[%02i, %02i] into %03i[%02i, %02i]", swap, x, y, _mapId, header->x, header->y); - else - TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not load %03u%02i%02i.mmtile to navmesh", swap, x, y); - } - } - - dtNavMesh* MMapData::GetNavMesh(TerrainSet swaps) - { - std::set activeSwaps = _activeSwaps; // _activeSwaps is modified inside RemoveSwap - for (uint32 swap : activeSwaps) - { - if (!swaps.count(swap)) // swap not active - { - if (PhaseTileContainer const* ptc = MMAP::MMapFactory::createOrGetMMapManager()->GetPhaseTileContainer(swap)) - for (PhaseTileContainer::const_iterator itr = ptc->begin(); itr != ptc->end(); ++itr) - RemoveSwap(itr->second, swap, itr->first); // remove swap - } - } - - // for each of the calling unit's terrain swaps - for (uint32 swap : swaps) - { - if (!_activeSwaps.count(swap)) // swap not active - { - // for each of the terrain swap's xy tiles - if (PhaseTileContainer const* ptc = MMAP::MMapFactory::createOrGetMMapManager()->GetPhaseTileContainer(swap)) - for (PhaseTileContainer::const_iterator itr = ptc->begin(); itr != ptc->end(); ++itr) - AddSwap(itr->second, swap, itr->first); // add swap - } - } - - return navMesh; - } - - void MMapData::AddBaseTile(uint32 packedGridPos, unsigned char* data, MmapTileHeader const& fileHeader, int32 dataSize) - { - auto itr = _baseTiles.find(packedGridPos); - if (itr == _baseTiles.end()) - { - PhasedTile* pt = new PhasedTile(); - pt->data = data; - pt->fileHeader = fileHeader; - pt->dataSize = dataSize; - _baseTiles[packedGridPos] = pt; - } - } - - void MMapData::DeleteBaseTile(uint32 packedGridPos) - { - auto itr = _baseTiles.find(packedGridPos); - if (itr != _baseTiles.end()) - { - dtFree(itr->second->data); - delete itr->second; - _baseTiles.erase(itr); - } + return queryItr->second; } } diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h index 27133ed3e04..a4859ecee49 100644 --- a/src/common/Collision/Management/MMapManager.h +++ b/src/common/Collision/Management/MMapManager.h @@ -22,10 +22,8 @@ #include "Define.h" #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" -#include "MapDefines.h" #include #include -#include #include // move map related classes @@ -34,57 +32,25 @@ namespace MMAP typedef std::unordered_map MMapTileSet; typedef std::unordered_map NavMeshQuerySet; - - typedef std::set TerrainSet; - - struct NavMeshHolder + // dummy struct to hold map's mmap data + struct TC_COMMON_API MMapData { - // Pre-built navMesh - dtNavMesh* navMesh; + MMapData(dtNavMesh* mesh) : navMesh(mesh) { } + ~MMapData() + { + for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i) + dtFreeNavMeshQuery(i->second); - // List of terrain swap map ids used to build the navMesh - TerrainSet terrainIds; - - MMapTileSet loadedTileRefs; - }; - - struct PhasedTile - { - unsigned char* data; - MmapTileHeader fileHeader; - int32 dataSize; - }; - - typedef std::unordered_map PhaseTileContainer; - typedef std::unordered_map PhaseTileMap; - - - typedef std::unordered_map TerrainSetMap; - - class TC_COMMON_API MMapData - { - public: - MMapData(dtNavMesh* mesh, uint32 mapId); - ~MMapData(); - - dtNavMesh* GetNavMesh(TerrainSet swaps); - - void AddBaseTile(uint32 packedGridPos, unsigned char* data, MmapTileHeader const& fileHeader, int32 dataSize); - void DeleteBaseTile(uint32 packedGridPos); + if (navMesh) + dtFreeNavMesh(navMesh); + } // we have to use single dtNavMeshQuery for every instance, since those are not thread safe NavMeshQuerySet navMeshQueries; // instanceId to query dtNavMesh* navMesh; - MMapTileSet loadedTileRefs; - TerrainSetMap loadedPhasedTiles; - private: - uint32 _mapId; - PhaseTileContainer _baseTiles; - std::set _activeSwaps; - void RemoveSwap(PhasedTile* ptile, uint32 swap, uint32 packedXY); - void AddSwap(PhasedTile* tile, uint32 swap, uint32 packedXY); + MMapTileSet loadedTileRefs; // maps [map grid coords] to [dtTile] }; @@ -99,40 +65,33 @@ namespace MMAP ~MMapManager(); void InitializeThreadUnsafe(std::unordered_map> const& mapData); - bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y); + bool loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y); + bool loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId); bool unloadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId); bool unloadMapInstance(uint32 mapId, uint32 instanceId); // the returned [dtNavMeshQuery const*] is NOT threadsafe - dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId, TerrainSet swaps); - dtNavMesh const* GetNavMesh(uint32 mapId, TerrainSet swaps); + dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId); + dtNavMesh const* GetNavMesh(uint32 mapId); uint32 getLoadedTilesCount() const { return loadedTiles; } uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); } - - typedef std::unordered_map> PhaseChildMapContainer; - void LoadPhaseTiles(PhaseChildMapContainer::const_iterator phasedMapData, int32 x, int32 y); - void UnloadPhaseTile(PhaseChildMapContainer::const_iterator phasedMapData, int32 x, int32 y); - PhaseTileContainer const* GetPhaseTileContainer(uint32 mapId) const - { - auto itr = _phaseTiles.find(mapId); - if (itr != _phaseTiles.end()) - return &itr->second; - return nullptr; - } - private: - bool loadMapData(uint32 mapId); + bool loadMapData(std::string const& basePath, uint32 mapId); + bool loadMapImpl(std::string const& basePath, uint32 mapId, int32 x, int32 y); + bool loadMapInstanceImpl(std::string const& basePath, uint32 mapId, uint32 instanceId); + bool unloadMapImpl(uint32 mapId, int32 x, int32 y); + bool unloadMapImpl(uint32 mapId); uint32 packTileID(int32 x, int32 y); MMapDataSet::const_iterator GetMMapData(uint32 mapId) const; MMapDataSet loadedMMaps; - PhaseChildMapContainer phaseMapData; uint32 loadedTiles; bool thread_safe_environment; - PhasedTile* LoadTile(uint32 mapId, int32 x, int32 y); - PhaseTileMap _phaseTiles; + + std::unordered_map> childMapData; + std::unordered_map parentMapData; }; } diff --git a/src/common/Collision/Management/VMapManager2.cpp b/src/common/Collision/Management/VMapManager2.cpp index 297e4053098..1239a27d66c 100644 --- a/src/common/Collision/Management/VMapManager2.cpp +++ b/src/common/Collision/Management/VMapManager2.cpp @@ -40,23 +40,35 @@ namespace VMAP thread_safe_environment = true; } - VMapManager2::~VMapManager2(void) + VMapManager2::~VMapManager2() { - for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i) - { + for (auto i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i) delete i->second; - } - for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i) - { + + for (auto i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i) delete i->second.getModel(); - } + } + + InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const + { + // return the iterator if found or end() if not found/NULL + auto itr = iInstanceMapTrees.find(mapId); + if (itr != iInstanceMapTrees.cend() && !itr->second) + itr = iInstanceMapTrees.cend(); + + return itr; } void VMapManager2::InitializeThreadUnsafe(std::unordered_map> const& mapData) { // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime - for (auto const& p : mapData) - iInstanceMapTrees.insert(InstanceTreeMap::value_type(p.first, nullptr)); + iChildMapData = mapData; + for (std::pair> const& mapId : mapData) + { + iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId.first, nullptr)); + for (uint32 childMapId : mapId.second) + iParentMapData[childMapId] = mapId.first; + } thread_safe_environment = false; } @@ -87,8 +99,15 @@ namespace VMAP int result = VMAP_LOAD_RESULT_IGNORED; if (isMapLoadingEnabled()) { - if (_loadMap(mapId, basePath, x, y)) + if (loadSingleMap(mapId, basePath, x, y)) + { result = VMAP_LOAD_RESULT_OK; + auto childMaps = iChildMapData.find(mapId); + if (childMaps != iChildMapData.end()) + for (uint32 childMapId : childMaps->second) + if (!loadSingleMap(childMapId, basePath, x, y)) + result = VMAP_LOAD_RESULT_ERROR; + } else result = VMAP_LOAD_RESULT_ERROR; } @@ -96,27 +115,17 @@ namespace VMAP return result; } - InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const - { - // return the iterator if found or end() if not found/NULL - InstanceTreeMap::const_iterator itr = iInstanceMapTrees.find(mapId); - if (itr != iInstanceMapTrees.cend() && !itr->second) - itr = iInstanceMapTrees.cend(); - - return itr; - } - // load one tile (internal use only) - bool VMapManager2::_loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY) + bool VMapManager2::loadSingleMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY) { - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + auto instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree == iInstanceMapTrees.end()) { if (thread_safe_environment) instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr)).first; else ASSERT(false, "Invalid mapId %u tile [%u, %u] passed to VMapManager2 after startup in thread unsafe environment", - mapId, tileX, tileY); + mapId, tileX, tileY); } if (!instanceTree->second) @@ -134,12 +143,22 @@ namespace VMAP return instanceTree->second->LoadMapTile(tileX, tileY, this); } - void VMapManager2::unloadMap(unsigned int mapId) + void VMapManager2::unloadMap(unsigned int mapId, int x, int y) { - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + auto childMaps = iChildMapData.find(mapId); + if (childMaps != iChildMapData.end()) + for (uint32 childMapId : childMaps->second) + unloadSingleMap(childMapId, x, y); + + unloadSingleMap(mapId, x, y); + } + + void VMapManager2::unloadSingleMap(uint32 mapId, int x, int y) + { + auto instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree != iInstanceMapTrees.end() && instanceTree->second) { - instanceTree->second->UnloadMap(this); + instanceTree->second->UnloadMapTile(x, y, this); if (instanceTree->second->numLoadedTiles() == 0) { delete instanceTree->second; @@ -148,12 +167,22 @@ namespace VMAP } } - void VMapManager2::unloadMap(unsigned int mapId, int x, int y) + void VMapManager2::unloadMap(unsigned int mapId) { - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + auto childMaps = iChildMapData.find(mapId); + if (childMaps != iChildMapData.end()) + for (uint32 childMapId : childMaps->second) + unloadSingleMap(childMapId); + + unloadSingleMap(mapId); + } + + void VMapManager2::unloadSingleMap(uint32 mapId) + { + auto instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree != iInstanceMapTrees.end() && instanceTree->second) { - instanceTree->second->UnloadMapTile(x, y, this); + instanceTree->second->UnloadMap(this); if (instanceTree->second->numLoadedTiles() == 0) { delete instanceTree->second; @@ -167,15 +196,13 @@ namespace VMAP if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) return true; - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); + auto instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1); Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2); if (pos1 != pos2) - { return instanceTree->second->isInLineOfSight(pos1, pos2, ignoreFlags); - } } return true; @@ -189,7 +216,7 @@ namespace VMAP { if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); + auto instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1); @@ -219,7 +246,7 @@ namespace VMAP { if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT)) { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); + auto instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos = convertPositionToInternalRep(x, y, z); @@ -238,7 +265,7 @@ namespace VMAP { if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); + auto instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos = convertPositionToInternalRep(x, y, z); @@ -256,7 +283,7 @@ namespace VMAP { if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); + auto instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { LocationInfo info; @@ -290,7 +317,7 @@ namespace VMAP data.areaInfo = boost::in_place(adtId, rootId, groupId, flags); return; } - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); + auto instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { LocationInfo info; @@ -317,7 +344,7 @@ namespace VMAP //! Critical section, thread safe access to iLoadedModelFiles std::lock_guard lock(LoadedModelFilesLock); - ModelFileMap::iterator model = iLoadedModelFiles.find(filename); + auto model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) { WorldModel* worldmodel = new WorldModel(); @@ -343,7 +370,7 @@ namespace VMAP //! Critical section, thread safe access to iLoadedModelFiles std::lock_guard lock(LoadedModelFilesLock); - ModelFileMap::iterator model = iLoadedModelFiles.find(filename); + auto model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) { VMAP_ERROR_LOG("misc", "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str()); @@ -359,7 +386,7 @@ namespace VMAP LoadResult VMapManager2::existsMap(const char* basePath, unsigned int mapId, int x, int y) { - return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y); + return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y, this); } void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree) @@ -367,4 +394,13 @@ namespace VMAP instanceMapTree = iInstanceMapTrees; } + int32 VMapManager2::getParentMapId(uint32 mapId) const + { + auto itr = iParentMapData.find(mapId); + if (itr != iParentMapData.end()) + return int32(itr->second); + + return -1; + } + } // namespace VMAP diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h index 110f2bd12f2..3782e76001e 100644 --- a/src/common/Collision/Management/VMapManager2.h +++ b/src/common/Collision/Management/VMapManager2.h @@ -81,13 +81,12 @@ namespace VMAP // Tree to check collision ModelFileMap iLoadedModelFiles; InstanceTreeMap iInstanceMapTrees; + std::unordered_map> iChildMapData; + std::unordered_map iParentMapData; bool thread_safe_environment; // Mutex for iLoadedModelFiles std::mutex LoadedModelFilesLock; - bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY); - /* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */ - static uint32 GetLiquidFlagsDummy(uint32) { return 0; } static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; } @@ -99,13 +98,18 @@ namespace VMAP static std::string getMapFileName(unsigned int mapId); VMapManager2(); - ~VMapManager2(void); + ~VMapManager2(); void InitializeThreadUnsafe(std::unordered_map> const& mapData); + int loadMap(const char* pBasePath, unsigned int mapId, int x, int y) override; + bool loadSingleMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY); void unloadMap(unsigned int mapId, int x, int y) override; + void unloadSingleMap(uint32 mapId, int x, int y); + void unloadMap(unsigned int mapId) override; + void unloadSingleMap(uint32 mapId); bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, ModelIgnoreFlags ignoreFlags) override ; /** @@ -132,6 +136,8 @@ namespace VMAP void getInstanceMapTree(InstanceTreeMap &instanceMapTree); + int32 getParentMapId(uint32 mapId) const; + typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType); GetLiquidFlagsFn GetLiquidFlagsPtr; diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp index 5f85a08aaef..42489dda581 100644 --- a/src/common/Collision/Maps/MapTree.cpp +++ b/src/common/Collision/Maps/MapTree.cpp @@ -236,8 +236,26 @@ namespace VMAP return(height); } + StaticMapTree::TileFileOpenResult StaticMapTree::OpenMapTileFile(std::string const& basePath, uint32 mapID, uint32 tileX, uint32 tileY, VMapManager2* vm) + { + TileFileOpenResult result; + result.Name = basePath + getTileFileName(mapID, tileX, tileY); + result.File = fopen(result.Name.c_str(), "rb"); + if (!result.File) + { + int32 parentMapId = vm->getParentMapId(mapID); + if (parentMapId != -1) + { + result.Name = basePath + getTileFileName(parentMapId, tileX, tileY); + result.File = fopen(result.Name.c_str(), "rb"); + } + } + + return result; + } + //========================================================= - LoadResult StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY) + LoadResult StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY, VMapManager2* vm) { std::string basePath = vmapPath; if (basePath.length() > 0 && basePath[basePath.length()-1] != '/' && basePath[basePath.length()-1] != '\\') @@ -259,8 +277,7 @@ namespace VMAP } if (tiled) { - std::string tilefile = basePath + getTileFileName(mapID, tileX, tileY); - FILE* tf = fopen(tilefile.c_str(), "rb"); + FILE* tf = OpenMapTileFile(basePath, mapID, tileX, tileY, vm).File; if (!tf) result = LoadResult::FileNotFound; else @@ -321,6 +338,22 @@ namespace VMAP } } + if (success) + { + success = readChunk(rf, chunk, "SIDX", 4); + uint32 spawnIndicesSize = 0; + uint32 spawnId; + uint32 spawnIndex; + if (success && fread(&spawnIndicesSize, sizeof(uint32), 1, rf) != 1) success = false; + for (uint32 i = 0; i < spawnIndicesSize && success; ++i) + { + if (fread(&spawnId, sizeof(uint32), 1, rf) == 1 && fread(&spawnIndex, sizeof(uint32), 1, rf) == 1) + iSpawnIndices[spawnId] = spawnIndex; + else + success = false; + } + } + fclose(rf); return success; } @@ -359,22 +392,21 @@ namespace VMAP } bool result = true; - std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY); - FILE* tf = fopen(tilefile.c_str(), "rb"); - if (tf) + TileFileOpenResult fileResult = OpenMapTileFile(iBasePath, iMapID, tileX, tileY, vm); + if (fileResult.File) { char chunk[8]; - if (!readChunk(tf, chunk, VMAP_MAGIC, 8)) + if (!readChunk(fileResult.File, chunk, VMAP_MAGIC, 8)) result = false; uint32 numSpawns = 0; - if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1) + if (result && fread(&numSpawns, sizeof(uint32), 1, fileResult.File) != 1) result = false; for (uint32 i=0; isecond; if (!iLoadedSpawns.count(referencedVal)) { - if (referencedVal > iNTreeValues) + if (referencedVal >= iNTreeValues) { - VMAP_ERROR_LOG("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u) referenced in tile %s", referencedVal, iNTreeValues, tilefile.c_str()); + VMAP_ERROR_LOG("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u) referenced in tile %s", referencedVal, iNTreeValues, fileResult.Name.c_str()); continue; } @@ -414,7 +446,7 @@ namespace VMAP } } iLoadedTiles[packTileID(tileX, tileY)] = true; - fclose(tf); + fclose(fileResult.File); } else iLoadedTiles[packTileID(tileX, tileY)] = false; @@ -434,34 +466,33 @@ namespace VMAP } if (tile->second) // file associated with tile { - std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY); - FILE* tf = fopen(tilefile.c_str(), "rb"); - if (tf) + TileFileOpenResult fileResult = OpenMapTileFile(iBasePath, iMapID, tileX, tileY, vm); + if (fileResult.File) { bool result=true; char chunk[8]; - if (!readChunk(tf, chunk, VMAP_MAGIC, 8)) + if (!readChunk(fileResult.File, chunk, VMAP_MAGIC, 8)) result = false; uint32 numSpawns; - if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1) + if (fread(&numSpawns, sizeof(uint32), 1, fileResult.File) != 1) result = false; for (uint32 i=0; ireleaseModelInstance(spawn.name); // update tree - uint32 referencedNode; - - if (fread(&referencedNode, sizeof(uint32), 1, tf) != 1) + auto spawnIndex = iSpawnIndices.find(spawn.ID); + if (spawnIndex == iSpawnIndices.end()) result = false; else { + uint32 referencedNode = spawnIndex->second; if (!iLoadedSpawns.count(referencedNode)) VMAP_ERROR_LOG("misc", "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); else if (--iLoadedSpawns[referencedNode] == 0) @@ -472,7 +503,7 @@ namespace VMAP } } } - fclose(tf); + fclose(fileResult.File); } } iLoadedTiles.erase(tile); diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h index 0c99534dda9..7cc56813d9f 100644 --- a/src/common/Collision/Maps/MapTree.h +++ b/src/common/Collision/Maps/MapTree.h @@ -51,23 +51,32 @@ namespace VMAP BIH iTree; ModelInstance* iTreeValues; // the tree entries uint32 iNTreeValues; + std::unordered_map iSpawnIndices; // Store all the map tile idents that are loaded for that map // some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed // empty tiles have no tile file, hence map with bool instead of just a set (consistency check) loadedTileMap iLoadedTiles; + std::vector> iLoadedPrimaryTiles; // stores to invalidate tree values, unload map, and to be able to report errors loadedSpawnMap iLoadedSpawns; std::string iBasePath; + struct TileFileOpenResult + { + FILE* File; + std::string Name; + }; + private: + static TileFileOpenResult OpenMapTileFile(std::string const& basePath, uint32 mapID, uint32 tileX, uint32 tileY, VMapManager2* vm); bool getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags) const; //bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); } public: static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY); static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX<<16 | tileY; } - static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY) { tileX = ID>>16; tileY = ID&0xFF; } - static LoadResult CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY); + static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY) { tileX = ID >> 16; tileY = ID & 0xFF; } + static LoadResult CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY, VMapManager2* vm); StaticMapTree(uint32 mapID, const std::string &basePath); ~StaticMapTree(); diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp index 84e759383fb..00ac2b263f1 100644 --- a/src/common/Collision/Maps/TileAssembler.cpp +++ b/src/common/Collision/Maps/TileAssembler.cpp @@ -84,7 +84,7 @@ namespace VMAP if (entry->second.flags & MOD_M2) { if (!calculateTransformedBound(entry->second)) - break; + continue; } else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/ { @@ -92,7 +92,7 @@ namespace VMAP //entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f); entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f); } - mapSpawns.push_back(&(entry->second)); + mapSpawns.push_back(&entry->second); spawnedModelFiles.insert(entry->second.name); } @@ -110,10 +110,6 @@ namespace VMAP } // ===> possibly move this code to StaticMapTree class - std::map modelNodeIdx; - for (uint32 i=0; i(mapSpawns[i]->ID, i)); - // write map tree file std::stringstream mapfilename; mapfilename << iDestDir << '/' << std::setfill('0') << std::setw(3) << map_iter->first << ".vmtree"; @@ -139,7 +135,17 @@ namespace VMAP for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob) { - success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second]); + success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second.Id]); + } + + // spawn id to index map + if (success && fwrite("SIDX", 4, 1, mapfile) != 1) success = false; + uint32 mapSpawnsSize = mapSpawns.size(); + if (success && fwrite(&mapSpawnsSize, sizeof(uint32), 1, mapfile) != 1) success = false; + for (uint32 i = 0; i < mapSpawnsSize; ++i) + { + if (success && fwrite(&mapSpawns[i]->ID, sizeof(uint32), 1, mapfile) != 1) success = false; + if (success && fwrite(&i, sizeof(uint32), 1, mapfile) != 1) success = false; } fclose(mapfile); @@ -151,8 +157,9 @@ namespace VMAP TileMap::iterator tile; for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile) { - const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second]; - if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently... + if (tile->second.Flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently... + continue; + if (tile->second.Flags & MOD_PARENT_SPAWN) // tile belongs to parent map continue; uint32 nSpawns = tileEntries.count(tile->first); std::stringstream tilefilename; @@ -172,16 +179,12 @@ namespace VMAP { if (s) ++tile; - const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second]; + const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second.Id]; success = success && ModelSpawn::writeToFile(tilefile, spawn2); - // MapTree nodes to update when loading tile: - std::map::iterator nIdx = modelNodeIdx.find(spawn2.ID); - if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false; } fclose(tilefile); } } - // break; //test, extract only first map; TODO: remvoe this line } // add an object models, listed in temp_gameobject_models file @@ -238,9 +241,9 @@ namespace VMAP printf("spawning Map %u\n", mapID); mapData[mapID] = current = new MapSpawns(); } - else current = (*map_iter).second; + else current = map_iter->second; current->UniqueEntries.insert(pair(spawn.ID, spawn)); - current->TileEntries.insert(pair(StaticMapTree::packTileID(tileX, tileY), spawn.ID)); + current->TileEntries.insert(pair(StaticMapTree::packTileID(tileX, tileY), TileSpawn{ spawn.ID, spawn.flags })); } bool success = (ferror(dirf) == 0); fclose(dirf); diff --git a/src/common/Collision/Maps/TileAssembler.h b/src/common/Collision/Maps/TileAssembler.h index f370bb638ba..8c3b3f5b88d 100644 --- a/src/common/Collision/Maps/TileAssembler.h +++ b/src/common/Collision/Maps/TileAssembler.h @@ -52,8 +52,14 @@ namespace VMAP void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; } }; + struct TileSpawn + { + uint32 Id; + uint32 Flags; + }; + typedef std::map UniqueEntryMap; - typedef std::multimap TileMap; + typedef std::multimap TileMap; struct TC_COMMON_API MapSpawns { diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index 9643f029078..219026c12e5 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -152,12 +152,12 @@ GameObjectModel* GameObjectModel::Create(std::unique_ptr const& phases, VMAP::ModelIgnoreFlags ignoreFlags) const +bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const { if (!isCollisionEnabled() || !owner->IsSpawned()) return false; - if (!owner->IsInPhase(phases)) + if (!owner->IsInPhase(phaseShift)) return false; float time = ray.intersectionTime(iBound); diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index e0de8ea7a18..a8dd8547750 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -26,7 +26,6 @@ #include "Define.h" #include -#include namespace VMAP { @@ -35,6 +34,7 @@ namespace VMAP } class GameObject; +class PhaseShift; struct GameObjectDisplayInfoEntry; class TC_COMMON_API GameObjectModelOwnerBase @@ -42,7 +42,7 @@ class TC_COMMON_API GameObjectModelOwnerBase public: virtual bool IsSpawned() const { return false; } virtual uint32 GetDisplayId() const { return 0; } - virtual bool IsInPhase(std::set const& /*phases*/) const { return false; } + virtual bool IsInPhase(PhaseShift const& /*phaseShift*/) const { return false; } virtual G3D::Vector3 GetPosition() const { return G3D::Vector3::zero(); } virtual float GetOrientation() const { return 0.0f; } virtual float GetScale() const { return 1.0f; } @@ -66,7 +66,7 @@ public: void enableCollision(bool enable) { _collisionEnabled = enable; } bool isCollisionEnabled() const { return _collisionEnabled; } - bool intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, std::set const& phases, VMAP::ModelIgnoreFlags ignoreFlags) const; + bool intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const; static GameObjectModel* Create(std::unique_ptr modelOwner, std::string const& dataPath); diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h index 80118b9a9c2..1a9a2ab3fff 100644 --- a/src/common/Collision/Models/ModelInstance.h +++ b/src/common/Collision/Models/ModelInstance.h @@ -36,8 +36,9 @@ namespace VMAP enum ModelFlags { MOD_M2 = 1, - MOD_WORLDSPAWN = 1<<1, - MOD_HAS_BOUND = 1<<2 + MOD_WORLDSPAWN = 1 << 1, + MOD_HAS_BOUND = 1 << 2, + MOD_PARENT_SPAWN = 1 << 3 }; class TC_COMMON_API ModelSpawn diff --git a/src/common/Collision/VMapDefinitions.h b/src/common/Collision/VMapDefinitions.h index 22885ec3855..5410eb2130c 100644 --- a/src/common/Collision/VMapDefinitions.h +++ b/src/common/Collision/VMapDefinitions.h @@ -25,8 +25,8 @@ namespace VMAP { - const char VMAP_MAGIC[] = "VMAP_4.4"; - const char RAW_VMAP_MAGIC[] = "VMAP044"; // used in extracted vmap files with raw data + const char VMAP_MAGIC[] = "VMAP_4.5"; + const char RAW_VMAP_MAGIC[] = "VMAP045"; // used in extracted vmap files with raw data const char GAMEOBJECT_MODELS[] = "GameObjectModels.dtree"; // defined in TileAssembler.cpp currently... diff --git a/src/common/Cryptography/ARC4.cpp b/src/common/Cryptography/ARC4.cpp index cc10dc39c9c..a5e77e92646 100644 --- a/src/common/Cryptography/ARC4.cpp +++ b/src/common/Cryptography/ARC4.cpp @@ -18,34 +18,34 @@ #include "ARC4.h" -ARC4::ARC4(uint32 len) : m_ctx() +ARC4::ARC4(uint32 len) : m_ctx(EVP_CIPHER_CTX_new()) { - EVP_CIPHER_CTX_init(&m_ctx); - EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL); - EVP_CIPHER_CTX_set_key_length(&m_ctx, len); + EVP_CIPHER_CTX_init(m_ctx); + EVP_EncryptInit_ex(m_ctx, EVP_rc4(), nullptr, nullptr, nullptr); + EVP_CIPHER_CTX_set_key_length(m_ctx, len); } -ARC4::ARC4(uint8 *seed, uint32 len) : m_ctx() +ARC4::ARC4(uint8* seed, uint32 len) : m_ctx(EVP_CIPHER_CTX_new()) { - EVP_CIPHER_CTX_init(&m_ctx); - EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL); - EVP_CIPHER_CTX_set_key_length(&m_ctx, len); - EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL); + EVP_CIPHER_CTX_init(m_ctx); + EVP_EncryptInit_ex(m_ctx, EVP_rc4(), nullptr, nullptr, nullptr); + EVP_CIPHER_CTX_set_key_length(m_ctx, len); + EVP_EncryptInit_ex(m_ctx, nullptr, nullptr, seed, nullptr); } ARC4::~ARC4() { - EVP_CIPHER_CTX_cleanup(&m_ctx); + EVP_CIPHER_CTX_free(m_ctx); } -void ARC4::Init(uint8 *seed) +void ARC4::Init(uint8* seed) { - EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL); + EVP_EncryptInit_ex(m_ctx, nullptr, nullptr, seed, nullptr); } -void ARC4::UpdateData(int len, uint8 *data) +void ARC4::UpdateData(int len, uint8* data) { int outlen = 0; - EVP_EncryptUpdate(&m_ctx, data, &outlen, data, len); - EVP_EncryptFinal_ex(&m_ctx, data, &outlen); + EVP_EncryptUpdate(m_ctx, data, &outlen, data, len); + EVP_EncryptFinal_ex(m_ctx, data, &outlen); } diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h index 4f7fba1f31d..629be510bbc 100644 --- a/src/common/Cryptography/ARC4.h +++ b/src/common/Cryptography/ARC4.h @@ -19,19 +19,19 @@ #ifndef _AUTH_SARC4_H #define _AUTH_SARC4_H -#include #include "Define.h" +#include class TC_COMMON_API ARC4 { public: ARC4(uint32 len); - ARC4(uint8 *seed, uint32 len); + ARC4(uint8* seed, uint32 len); ~ARC4(); - void Init(uint8 *seed); - void UpdateData(int len, uint8 *data); + void Init(uint8* seed); + void UpdateData(int len, uint8* data); private: - EVP_CIPHER_CTX m_ctx; + EVP_CIPHER_CTX* m_ctx; }; #endif diff --git a/src/common/Cryptography/HmacHash.cpp b/src/common/Cryptography/HmacHash.cpp index f12fb0f26d1..a0ad8356ef9 100644 --- a/src/common/Cryptography/HmacHash.cpp +++ b/src/common/Cryptography/HmacHash.cpp @@ -20,44 +20,58 @@ #include "BigNumber.h" #include "Common.h" -template -HmacHash::HmacHash(uint32 len, uint8 *seed) +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L +HMAC_CTX* HMAC_CTX_new() { - HMAC_CTX_init(&_ctx); - HMAC_Init_ex(&_ctx, seed, len, HashCreator(), NULL); + HMAC_CTX *ctx = new HMAC_CTX(); + HMAC_CTX_init(ctx); + return ctx; +} + +void HMAC_CTX_free(HMAC_CTX* ctx) +{ + HMAC_CTX_cleanup(ctx); + delete ctx; +} +#endif + +template +HmacHash::HmacHash(uint32 len, uint8 const* seed) : _ctx(HMAC_CTX_new()) +{ + HMAC_Init_ex(_ctx, seed, len, HashCreator(), nullptr); memset(_digest, 0, DigestLength); } template HmacHash::~HmacHash() { - HMAC_CTX_cleanup(&_ctx); + HMAC_CTX_free(_ctx); } template -void HmacHash::UpdateData(const std::string &str) +void HmacHash::UpdateData(std::string const& str) { - HMAC_Update(&_ctx, (uint8 const*)str.c_str(), str.length()); + HMAC_Update(_ctx, reinterpret_cast(str.c_str()), str.length()); } template -void HmacHash::UpdateData(const uint8* data, size_t len) +void HmacHash::UpdateData(uint8 const* data, size_t len) { - HMAC_Update(&_ctx, data, len); + HMAC_Update(_ctx, data, len); } template void HmacHash::Finalize() { uint32 length = 0; - HMAC_Final(&_ctx, _digest, &length); + HMAC_Final(_ctx, _digest, &length); ASSERT(length == DigestLength); } template uint8* HmacHash::ComputeHash(BigNumber* bn) { - HMAC_Update(&_ctx, bn->AsByteArray().get(), bn->GetNumBytes()); + HMAC_Update(_ctx, bn->AsByteArray().get(), bn->GetNumBytes()); Finalize(); return _digest; } diff --git a/src/common/Cryptography/HmacHash.h b/src/common/Cryptography/HmacHash.h index bf744e5b91b..a8c2eee6f09 100644 --- a/src/common/Cryptography/HmacHash.h +++ b/src/common/Cryptography/HmacHash.h @@ -34,7 +34,7 @@ template class TC_COMMON_API HmacHash { public: - HmacHash(uint32 len, uint8 *seed); + HmacHash(uint32 len, uint8 const* seed); ~HmacHash(); void UpdateData(std::string const& str); void UpdateData(uint8 const* data, size_t len); @@ -43,7 +43,7 @@ class TC_COMMON_API HmacHash uint8* GetDigest() { return _digest; } uint32 GetLength() const { return DigestLength; } private: - HMAC_CTX _ctx; + HMAC_CTX* _ctx; uint8 _digest[DigestLength]; }; diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/common/DataStores/DBCFileLoader.cpp similarity index 100% rename from src/server/shared/DataStores/DBCFileLoader.cpp rename to src/common/DataStores/DBCFileLoader.cpp diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/common/DataStores/DBCFileLoader.h similarity index 92% rename from src/server/shared/DataStores/DBCFileLoader.h rename to src/common/DataStores/DBCFileLoader.h index 708a34156ba..1b675452aae 100644 --- a/src/server/shared/DataStores/DBCFileLoader.h +++ b/src/common/DataStores/DBCFileLoader.h @@ -22,7 +22,7 @@ #include "Utilities/ByteConverter.h" #include -class TC_SHARED_API DBCFileLoader +class TC_COMMON_API DBCFileLoader { public: DBCFileLoader(); @@ -47,6 +47,13 @@ class TC_SHARED_API DBCFileLoader EndianConvert(val); return val; } + int32 getInt(size_t field) const + { + assert(field < file.fieldCount); + int32 val = *reinterpret_cast(offset + file.GetOffset(field)); + EndianConvert(val); + return val; + } uint8 getUInt8(size_t field) const { assert(field < file.fieldCount); diff --git a/src/common/Debugging/WheatyExceptionReport.cpp b/src/common/Debugging/WheatyExceptionReport.cpp index 657ce5886ad..b2f3c692dcd 100644 --- a/src/common/Debugging/WheatyExceptionReport.cpp +++ b/src/common/Debugging/WheatyExceptionReport.cpp @@ -55,6 +55,7 @@ inline LPTSTR ErrorMessage(DWORD dw) TCHAR WheatyExceptionReport::m_szLogFileName[MAX_PATH]; TCHAR WheatyExceptionReport::m_szDumpFileName[MAX_PATH]; LPTOP_LEVEL_EXCEPTION_FILTER WheatyExceptionReport::m_previousFilter; +_invalid_parameter_handler WheatyExceptionReport::m_previousCrtHandler; HANDLE WheatyExceptionReport::m_hReportFile; HANDLE WheatyExceptionReport::m_hDumpFile; HANDLE WheatyExceptionReport::m_hProcess; @@ -75,6 +76,7 @@ WheatyExceptionReport::WheatyExceptionReport() // Constructor { // Install the unhandled exception filter function m_previousFilter = SetUnhandledExceptionFilter(WheatyUnhandledExceptionFilter); + m_previousCrtHandler = _set_invalid_parameter_handler(WheatyCrtHandler); m_hProcess = GetCurrentProcess(); stackOverflowException = false; alreadyCrashed = false; @@ -95,6 +97,8 @@ WheatyExceptionReport::~WheatyExceptionReport() { if (m_previousFilter) SetUnhandledExceptionFilter(m_previousFilter); + if (m_previousCrtHandler) + _set_invalid_parameter_handler(m_previousCrtHandler); ClearSymbols(); } @@ -183,6 +187,11 @@ PEXCEPTION_POINTERS pExceptionInfo) return EXCEPTION_EXECUTE_HANDLER/*EXCEPTION_CONTINUE_SEARCH*/; } +void __cdecl WheatyExceptionReport::WheatyCrtHandler(wchar_t const* /*expression*/, wchar_t const* /*function*/, wchar_t const* /*file*/, unsigned int /*line*/, uintptr_t /*pReserved*/) +{ + RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, nullptr); +} + BOOL WheatyExceptionReport::_GetProcessorName(TCHAR* sProcessorName, DWORD maxcount) { if (!sProcessorName) diff --git a/src/common/Debugging/WheatyExceptionReport.h b/src/common/Debugging/WheatyExceptionReport.h index 6c2406882c4..42d4d3e0a2a 100644 --- a/src/common/Debugging/WheatyExceptionReport.h +++ b/src/common/Debugging/WheatyExceptionReport.h @@ -155,6 +155,8 @@ class WheatyExceptionReport static LONG WINAPI WheatyUnhandledExceptionFilter( PEXCEPTION_POINTERS pExceptionInfo); + static void __cdecl WheatyCrtHandler(wchar_t const* expression, wchar_t const* function, wchar_t const* file, unsigned int line, uintptr_t pReserved); + static void printTracesForAllThreads(bool); private: // where report info is extracted and generated @@ -192,6 +194,7 @@ class WheatyExceptionReport static TCHAR m_szLogFileName[MAX_PATH]; static TCHAR m_szDumpFileName[MAX_PATH]; static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter; + static _invalid_parameter_handler m_previousCrtHandler; static HANDLE m_hReportFile; static HANDLE m_hDumpFile; static HANDLE m_hProcess; diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp index 3e578cf1ee8..4ed5b69997d 100644 --- a/src/common/GitRevision.cpp +++ b/src/common/GitRevision.cpp @@ -21,6 +21,16 @@ char const* GitRevision::GetCMakeCommand() return _CMAKE_COMMAND; } +char const* GitRevision::GetCMakeVersion() +{ + return _CMAKE_VERSION; +} + +char const* GitRevision::GetHostOSVersion() +{ + return _CMAKE_HOST_SYSTEM; +} + char const* GitRevision::GetBuildDirectory() { return _BUILD_DIRECTORY; diff --git a/src/common/GitRevision.h b/src/common/GitRevision.h index b4e29cbd545..131078ce860 100644 --- a/src/common/GitRevision.h +++ b/src/common/GitRevision.h @@ -27,6 +27,8 @@ namespace GitRevision TC_COMMON_API char const* GetDate(); TC_COMMON_API char const* GetBranch(); TC_COMMON_API char const* GetCMakeCommand(); + TC_COMMON_API char const* GetCMakeVersion(); + TC_COMMON_API char const* GetHostOSVersion(); TC_COMMON_API char const* GetBuildDirectory(); TC_COMMON_API char const* GetSourceDirectory(); TC_COMMON_API char const* GetMySQLExecutable(); diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h index db762a67d07..c6c9c58b253 100644 --- a/src/common/Utilities/Containers.h +++ b/src/common/Utilities/Containers.h @@ -132,7 +132,7 @@ namespace Trinity * Note: container cannot be empty */ template - auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container)) + inline auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container)) { std::vector weights; weights.reserve(Size(container)); @@ -175,7 +175,7 @@ namespace Trinity * @return true if containers have a common element, false otherwise. */ template - bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) + inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) { while (first1 != last1 && first2 != last2) { @@ -190,6 +190,37 @@ namespace Trinity return false; } + /** + * @fn bool Trinity::Containers::Intersects(Iterator first1, Iterator last1, Iterator first2, Iterator last2, Predicate&& equalPred) + * + * @brief Checks if two SORTED containers have a common element + * + * @param first1 Iterator pointing to start of the first container + * @param last1 Iterator pointing to end of the first container + * @param first2 Iterator pointing to start of the second container + * @param last2 Iterator pointing to end of the second container + * @param equalPred Additional predicate to exclude elements + * + * @return true if containers have a common element, false otherwise. + */ + template + inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Predicate&& equalPred) + { + while (first1 != last1 && first2 != last2) + { + if (*first1 < *first2) + ++first1; + else if (*first2 < *first1) + ++first2; + else if (!equalPred(*first1, *first2)) + ++first1, ++first2; + else + return true; + } + + return false; + } + /** * Returns a pointer to mapped value (or the value itself if map stores pointers) */ @@ -201,7 +232,7 @@ namespace Trinity } template class M, class... Rest> - void MultimapErasePair(M& multimap, K const& key, V const& value) + inline void MultimapErasePair(M& multimap, K const& key, V const& value) { auto range = multimap.equal_range(key); for (auto itr = range.first; itr != range.second; ) diff --git a/src/common/Utilities/EnumClassFlag.h b/src/common/Utilities/EnumClassFlag.h new file mode 100644 index 00000000000..68ee56edb07 --- /dev/null +++ b/src/common/Utilities/EnumClassFlag.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008-2018 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef EnumClassFlag_h__ +#define EnumClassFlag_h__ + +#include + +template +class EnumClassFlag +{ + static_assert(std::is_enum::value, "EnumClassFlag must be used only with enums"); + +public: + /*implicit*/ EnumClassFlag(T value) : _value(value) { } + + EnumClassFlag& operator&=(EnumClassFlag right) + { + _value = static_cast(static_cast>(_value) & static_cast>(right._value)); + return *this; + } + + friend EnumClassFlag operator&(EnumClassFlag left, EnumClassFlag right) + { + return left &= right; + } + + EnumClassFlag operator|=(EnumClassFlag right) + { + _value = static_cast(static_cast>(_value) | static_cast>(right._value)); + return *this; + } + + friend EnumClassFlag operator|(EnumClassFlag left, EnumClassFlag right) + { + return left |= right; + } + + EnumClassFlag operator~() const + { + return static_cast(~static_cast>(_value)); + } + + void RemoveFlag(EnumClassFlag flag) + { + _value = static_cast(static_cast>(_value) & ~static_cast>(flag._value)); + } + + bool HasFlag(T flag) const + { + return (static_cast>(_value) & static_cast>(flag)) != 0; + } + + operator T() const + { + return _value; + } + + std::underlying_type_t AsUnderlyingType() const + { + return static_cast>(_value); + } + +private: + T _value; +}; + +#endif // EnumClassFlag_h__ diff --git a/src/server/database/Updater/DBUpdater.cpp b/src/server/database/Updater/DBUpdater.cpp index 0edaed763bb..75abd9bcd0f 100644 --- a/src/server/database/Updater/DBUpdater.cpp +++ b/src/server/database/Updater/DBUpdater.cpp @@ -288,7 +288,7 @@ bool DBUpdater::Populate(DatabaseWorkerPool& pool) case LOCATION_DOWNLOAD: { std::string const filename = base.filename().generic_string(); - std::string const workdir = boost::filesystem::current_path().generic_string().c_str(); + std::string const workdir = boost::filesystem::current_path().generic_string(); TC_LOG_ERROR("sql.updates", ">> File \"%s\" is missing, download it from \"https://t.me/trinitycorelegacy\"" \ " Mirror: \"https://github.com/TrinityCoreLegacy/TrinityCore/releases\"" \ " uncompress it and place the file \"%s\" in the directory \"%s\".", filename.c_str(), filename.c_str(), workdir.c_str()); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index d7c0e079108..d071fed08bd 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -29,6 +29,7 @@ #include "Language.h" #include "ObjectDefines.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "SmartAI.h" @@ -1130,7 +1131,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - (*itr)->SetInPhase(e.action.ingamePhaseId.id, true, e.action.ingamePhaseId.apply == 1); + { + if (e.action.ingamePhaseId.apply == 1) + PhasingHandler::AddPhase(*itr, e.action.ingamePhaseId.id, true); + else + PhasingHandler::RemovePhase(*itr, e.action.ingamePhaseId.id, true); + } delete targets; break; @@ -1142,11 +1148,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!targets) break; - std::set const& phases = GetPhasesForGroup(e.action.ingamePhaseGroup.groupId); - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - for (auto phase : phases) - (*itr)->SetInPhase(phase, true, e.action.ingamePhaseGroup.apply == 1); + { + if (e.action.ingamePhaseGroup.apply == 1) + PhasingHandler::AddPhaseGroup(*itr, e.action.ingamePhaseGroup.groupId, true); + else + PhasingHandler::RemovePhaseGroup(*itr, e.action.ingamePhaseGroup.groupId, true); + } delete targets; break; @@ -3424,6 +3432,8 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if ((e.event.los.noHostile && !me->IsHostileTo(unit)) || (!e.event.los.noHostile && me->IsHostileTo(unit))) { + if (e.event.los.playerOnly && unit->GetTypeId() != TYPEID_PLAYER) + return; RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); ProcessAction(e, unit); } @@ -3444,6 +3454,8 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if ((e.event.los.noHostile && !me->IsHostileTo(unit)) || (!e.event.los.noHostile && me->IsHostileTo(unit))) { + if (e.event.los.playerOnly && unit->GetTypeId() != TYPEID_PLAYER) + return; RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); ProcessAction(e, unit); } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index f0f5f9d5c83..833cc9a3145 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1337,7 +1337,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } - if (phaseGroup && GetPhasesForGroup(phaseGroup).empty()) + if (phaseGroup && GetPhasesForGroup(phaseGroup)) { TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_GROUP uses invalid phase group id %u for creature %u, skipped", phaseGroup, e.entryOrGuid); return false; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index a00f2bfbd63..bd06e946341 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -232,6 +232,7 @@ struct SmartEvent uint32 maxDist; uint32 cooldownMin; uint32 cooldownMax; + uint32 playerOnly; } los; struct diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 4d0bdfc6a30..6fccd412164 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -767,6 +767,9 @@ enum RBACPermissions RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING_LOCALE = 867, RBAC_PERM_COMMAND_MODIFY_POWER = 868, // reserved RBAC_PERM_COMMAND_DEBUG_SEND_PLAYER_CHOICE = 869, // reserved + RBAC_PERM_COMMAND_DEBUG_THREATINFO = 870, + RBAC_PERM_COMMAND_DEBUG_INSTANCESPAWN = 871, + RBAC_PERM_COMMAND_SERVER_DEBUG = 872, // // IF YOU ADD NEW PERMISSIONS, ADD THEM IN MASTER BRANCH AS WELL! // diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index c3c7eb6a0d2..e98f94629f4 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1837,7 +1837,7 @@ void Battleground::SetBgRaid(uint32 TeamID, Group* bg_raid) WorldSafeLocsEntry const* Battleground::GetClosestGraveYard(Player* player) { - return sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam()); + return sObjectMgr->GetClosestGraveYard(*player, player->GetTeam(), player); } void Battleground::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 0c4deab3b3f..9b563b716c0 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -1208,7 +1208,7 @@ LocaleConstant ChatHandler::GetSessionDbcLocale() const return m_session->GetSessionDbcLocale(); } -int ChatHandler::GetSessionDbLocaleIndex() const +LocaleConstant ChatHandler::GetSessionDbLocaleIndex() const { return m_session->GetSessionDbLocaleIndex(); } @@ -1304,7 +1304,7 @@ LocaleConstant CliHandler::GetSessionDbcLocale() const return sWorld->GetDefaultDbcLocale(); } -int CliHandler::GetSessionDbLocaleIndex() const +LocaleConstant CliHandler::GetSessionDbLocaleIndex() const { return sObjectMgr->GetDBCLocaleIndex(); } diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 7b6cb6ebe91..ef6c5b2c66f 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -112,7 +112,7 @@ class TC_GAME_API ChatHandler virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); } virtual bool needReportToTarget(Player* chr) const; virtual LocaleConstant GetSessionDbcLocale() const; - virtual int GetSessionDbLocaleIndex() const; + virtual LocaleConstant GetSessionDbLocaleIndex() const; bool HasLowerSecurity(Player* target, ObjectGuid guid, bool strong = false); bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false); @@ -178,7 +178,7 @@ class TC_GAME_API CliHandler : public ChatHandler std::string GetNameLink() const override; bool needReportToTarget(Player* chr) const override; LocaleConstant GetSessionDbcLocale() const override; - int GetSessionDbLocaleIndex() const override; + LocaleConstant GetSessionDbLocaleIndex() const override; private: void* m_callbackArg; diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 9f2a16f3a90..e3a656d9ea6 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -21,6 +21,7 @@ #include "GameEventMgr.h" #include "InstanceScript.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "Pet.h" #include "ReputationMgr.h" @@ -402,7 +403,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const } case CONDITION_PHASEID: { - condMeets = object->IsInPhase(ConditionValue1); + condMeets = object->GetPhaseShift().HasPhase(ConditionValue1); break; } case CONDITION_TITLE: @@ -430,7 +431,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const } case CONDITION_TERRAIN_SWAP: { - condMeets = object->IsInTerrainSwap(ConditionValue1); + condMeets = object->GetPhaseShift().HasVisibleMapId(ConditionValue1); break; } case CONDITION_REALM_ACHIEVEMENT: @@ -1040,17 +1041,7 @@ void ConditionMgr::LoadConditions(bool isReload) sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists(); - TC_LOG_INFO("misc", "Re-Loading `terrain_phase_info` Table for Conditions!"); - sObjectMgr->LoadTerrainPhaseInfo(); - - TC_LOG_INFO("misc", "Re-Loading `terrain_swap_defaults` Table for Conditions!"); - sObjectMgr->LoadTerrainSwapDefaults(); - - TC_LOG_INFO("misc", "Re-Loading `terrain_worldmap` Table for Conditions!"); - sObjectMgr->LoadTerrainWorldMaps(); - - TC_LOG_INFO("misc", "Re-Loading `phase_area` Table for Conditions!"); - sObjectMgr->LoadAreaPhases(); + sObjectMgr->UnloadPhaseConditions(); } QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, " @@ -1337,17 +1328,44 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const std::list sharedMasks; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - // check if effect is already a part of some shared mask - bool found = false; - for (std::list::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr) + // additional checks by condition type + if (conditionEffMask & (1 << i)) { - if ((1<ConditionType) { - found = true; - break; + case CONDITION_OBJECT_ENTRY_GUID: + { + uint32 implicitTargetMask = GetTargetFlagMask(spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(spellInfo->Effects[i].TargetB.GetObjectType()); + if ((implicitTargetMask & TARGET_FLAG_UNIT_MASK) && cond->ConditionValue1 != TYPEID_UNIT && cond->ConditionValue1 != TYPEID_PLAYER) + { + TC_LOG_ERROR("sql.sql", "%s in `condition` table - spell %u EFFECT_%u - " + "target requires ConditionValue1 to be either TYPEID_UNIT (%u) or TYPEID_PLAYER (%u)", cond->ToString().c_str(), spellInfo->Id, uint32(i), uint32(TYPEID_UNIT), uint32(TYPEID_PLAYER)); + return false; + } + + if ((implicitTargetMask & TARGET_FLAG_GAMEOBJECT_MASK) && cond->ConditionValue1 != TYPEID_GAMEOBJECT) + { + TC_LOG_ERROR("sql.sql", "%s in `condition` table - spell %u EFFECT_%u - " + "target requires ConditionValue1 to be TYPEID_GAMEOBJECT (%u)", cond->ToString().c_str(), spellInfo->Id, uint32(i), uint32(TYPEID_GAMEOBJECT)); + return false; + } + + if ((implicitTargetMask & TARGET_FLAG_CORPSE_MASK) && cond->ConditionValue1 != TYPEID_CORPSE) + { + TC_LOG_ERROR("sql.sql", "%s in `condition` table - spell %u EFFECT_%u - " + "target requires ConditionValue1 to be TYPEID_CORPSE (%u)", cond->ToString().c_str(), spellInfo->Id, uint32(i), uint32(TYPEID_CORPSE)); + return false; + } + break; + } + default: + break; } } - if (found) + + // check if effect is already a part of some shared mask + auto itr = std::find_if(sharedMasks.begin(), sharedMasks.end(), [i](uint32 mask) { return !!(mask & (1 << i)); }); + if (itr != sharedMasks.end()) continue; // build new shared mask with found effect @@ -1361,14 +1379,14 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const sharedMasks.push_back(sharedMask); } - for (std::list::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr) + for (uint32 effectMask : sharedMasks) { // some effect indexes should have same data - if (uint32 commonMask = *itr & conditionEffMask) + if (uint32 commonMask = effectMask & conditionEffMask) { uint8 firstEffIndex = 0; for (; firstEffIndex < MAX_SPELL_EFFECTS; ++firstEffIndex) - if ((1<= MAX_SPELL_EFFECTS) @@ -1381,7 +1399,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const if (sharedList) { // we have overlapping masks in db - if (conditionEffMask != *itr) + if (conditionEffMask != effectMask) { TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - " "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->ToString().c_str(), cond->SourceGroup); @@ -1396,7 +1414,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const bool assigned = false; for (uint8 i = firstEffIndex; i < MAX_SPELL_EFFECTS; ++i) { - if ((1<Effects[i].ImplicitTargetConditions = sharedList; assigned = true; @@ -1417,24 +1435,32 @@ bool ConditionMgr::addToPhases(Condition* cond) const { if (!cond->SourceEntry) { - PhaseInfo& p = sObjectMgr->GetAreaPhasesForLoading(); - for (auto phaseItr = p.begin(); phaseItr != p.end(); ++phaseItr) + if (PhaseInfoStruct const* phaseInfo = sObjectMgr->GetPhaseInfo(cond->SourceGroup)) { - for (PhaseInfoStruct& phase : phaseItr->second) + bool found = false; + for (uint32 areaId : phaseInfo->Areas) { - if (phase.Id == cond->SourceGroup) + if (std::vector* phases = const_cast*>(sObjectMgr->GetPhasesForArea(areaId))) { - phase.Conditions.push_back(cond); - return true; + for (PhaseAreaInfo& phase : *phases) + { + if (phase.PhaseInfo->Id == cond->SourceGroup) + { + phase.Conditions.push_back(cond); + found = true; + } + } } } + if (found) + return true; } } - else if (std::vector* phases = sObjectMgr->GetPhasesForAreaForLoading(cond->SourceEntry)) + else if (std::vector* phases = const_cast*>(sObjectMgr->GetPhasesForArea(cond->SourceEntry))) { - for (PhaseInfoStruct& phase : *phases) + for (PhaseAreaInfo& phase : *phases) { - if (phase.Id == cond->SourceGroup) + if (phase.PhaseInfo->Id == cond->SourceGroup) { phase.Conditions.push_back(cond); return true; @@ -1809,6 +1835,14 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: case CONDITION_SOURCE_TYPE_NONE: + break; + case CONDITION_SOURCE_TYPE_GRAVEYARD: + if (!sWorldSafeLocsStore.LookupEntry(cond->SourceEntry)) + { + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in WorldSafeLocs, ignoring.", cond->ToString().c_str()); + return false; + } + break; default: break; } diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index af15d3947ce..7c586027aab 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -137,7 +137,8 @@ enum ConditionSourceType CONDITION_SOURCE_TYPE_SPELL_PROC = 24, CONDITION_SOURCE_TYPE_TERRAIN_SWAP = 25, CONDITION_SOURCE_TYPE_PHASE = 26, - CONDITION_SOURCE_TYPE_MAX = 27 // MAX + CONDITION_SOURCE_TYPE_GRAVEYARD = 27, + CONDITION_SOURCE_TYPE_MAX = 28 // MAX }; enum RelationType diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 21f2a4a5d68..e8a8c2f70a3 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -466,6 +466,23 @@ enum MountCapabilityFlags MOUNT_CAPABIILTY_FLAG_IGNORE_RESTRICTIONS = 0x20, }; +enum PhaseEntryFlags : uint16 +{ + PHASE_FLAG_NORMAL = 0x08, + PHASE_FLAG_COSMETIC = 0x10, + PHASE_FLAG_PERSONAL = 0x20 +}; + +// PhaseUseFlags fields in different DBCs +enum PhaseUseFlagsValues : uint8 +{ + PHASE_USE_FLAGS_NONE = 0x0, + PHASE_USE_FLAGS_ALWAYS_VISIBLE = 0x1, + PHASE_USE_FLAGS_INVERSE = 0x2, + + PHASE_USE_FLAGS_ALL = PHASE_USE_FLAGS_ALWAYS_VISIBLE | PHASE_USE_FLAGS_INVERSE +}; + enum SkillRaceClassInfoFlags { SKILL_FLAG_NO_SKILLUP_MESSAGE = 0x2, diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 240dc156ed3..6a608eff843 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -558,7 +558,7 @@ void LoadDBCStores(const std::string& dataPath) for (uint32 i = 0; i < sPhaseGroupStore.GetNumRows(); ++i) if (PhaseGroupEntry const* group = sPhaseGroupStore.LookupEntry(i)) if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseId)) - sPhasesByGroup[group->GroupId].insert(phase->ID); + sPhasesByGroup[group->GroupId].push_back(phase->ID); LoadDBC(availableDbcLocales, bad_dbc_files, sPowerDisplayStore, dbcPath, "PowerDisplay.dbc"); @@ -1360,9 +1360,9 @@ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, u return NULL; } -std::set const& GetPhasesForGroup(uint32 group) +std::vector const* GetPhasesForGroup(uint32 group) { - return sPhasesByGroup[group]; + return &sPhasesByGroup[group]; } ResponseCodes ValidateName(std::wstring const& name, LocaleConstant locale) diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 05833b05528..448a64759ee 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -81,7 +81,7 @@ TC_GAME_API LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty diffic uint32 GetDefaultMapLight(uint32 mapId); -TC_GAME_API std::set const& GetPhasesForGroup(uint32 group); +TC_GAME_API std::vector const* GetPhasesForGroup(uint32 group); typedef std::unordered_multimap SkillRaceClassInfoMap; typedef std::pair SkillRaceClassInfoBounds; @@ -254,7 +254,7 @@ TC_GAME_API extern DBCStorage sUnitPowerBarStore; TC_GAME_API extern DBCStorage sVehicleStore; TC_GAME_API extern DBCStorage sVehicleSeatStore; TC_GAME_API extern DBCStorage sWMOAreaTableStore; -//TC_GAME_API extern DBCStorage sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates +TC_GAME_API extern DBCStorage sWorldMapAreaStore; TC_GAME_API extern DBCStorage sWorldMapOverlayStore; TC_GAME_API extern DBCStorage sWorldSafeLocsStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index b06220cecf2..33288f6cc12 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -688,9 +688,9 @@ struct AreaTriggerEntry float x; // 2 m_x float y; // 3 m_y float z; // 4 m_z - //uint32 // 5 - //uint32 // 6 - //uint32 // 7 + uint32 PhaseUseFlags; // 5 PhaseUseFlags + uint32 PhaseID; // 6 PhaseID + uint32 PhaseGroupID; // 7 PhaseGroupID float radius; // 8 m_radius float box_x; // 9 m_box_length float box_y; // 10 m_box_width @@ -1601,7 +1601,7 @@ struct PhaseEntry { uint32 ID; // 0 char* Name; // 1 - uint32 flag; // 2 + uint32 Flags; // 2 }; struct PhaseGroupEntry @@ -2734,5 +2734,5 @@ typedef std::vector TaxiPathNodesByPath; #define TaxiMaskSize 114 typedef uint8 TaxiMask[TaxiMaskSize]; -typedef std::unordered_map> PhaseGroupContainer; +typedef std::unordered_map> PhaseGroupContainer; #endif diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index b782b104b3b..0c0a1a1e7cb 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -30,7 +30,7 @@ char const AchievementCriteriafmt[] = "niiiliiiisiiiiixxiiiiii"; char const AreaTableEntryfmt[] = "niiiixxxxxisiiiiiffiixxxxx"; char const AreaGroupEntryfmt[] = "niiiiiii"; char const AreaPOIEntryfmt[] = "niiiiiiiiiiiffixixxixx"; -char const AreaTriggerEntryfmt[] = "nifffxxxfffff"; +char const AreaTriggerEntryfmt[] = "nifffiiifffff"; char const ArmorLocationfmt[] = "nfffff"; char const AuctionHouseEntryfmt[] = "niiix"; char const BankBagSlotPricesEntryfmt[] = "ni"; diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index e362e1d5557..42e78d066d9 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -16,6 +16,7 @@ */ #include "ObjectAccessor.h" +#include "PhasingHandler.h" #include "Unit.h" #include "SpellInfo.h" #include "Log.h" @@ -78,7 +79,7 @@ bool AreaTrigger::CreateAreaTrigger(uint32 guidlow, uint32 triggerEntry, Unit* c SetFloatValue(AREATRIGGER_FINAL_POS + 1, pos.GetPositionY()); SetFloatValue(AREATRIGGER_FINAL_POS + 2, pos.GetPositionZ()); - CopyPhaseFrom(caster); + PhasingHandler::InheritPhaseShift(this, caster); if (!GetMap()->AddToMap(this)) return false; diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index f7be38c88ea..83df48db009 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -22,6 +22,7 @@ #include "Player.h" #include "UpdateMask.h" #include "ObjectAccessor.h" +#include "PhasingHandler.h" #include "DatabaseEnv.h" #include "World.h" @@ -86,7 +87,7 @@ bool Corpse::Create(ObjectGuid::LowType guidlow, Player* owner) _cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY()); - CopyPhaseFrom(owner); + PhasingHandler::InheritPhaseShift(this, owner); return true; } @@ -116,12 +117,12 @@ void Corpse::SaveToDB() stmt->setUInt32(index++, GetInstanceId()); // instanceId trans->Append(stmt); - for (uint32 phaseId : GetPhases()) + for (PhaseShift::PhaseRef const& phase : GetPhaseShift().GetPhases()) { index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_PHASES); stmt->setUInt32(index++, GetOwnerGUID().GetCounter()); // OwnerGuid - stmt->setUInt32(index++, phaseId); // PhaseId + stmt->setUInt32(index++, phase.Id); // PhaseId trans->Append(stmt); } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 9a037781bec..1c3ed3dd08d 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -37,6 +37,7 @@ #include "LootMgr.h" #include "MoveSpline.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "PoolMgr.h" #include "QuestDef.h" @@ -888,12 +889,11 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 /*phaseMask* ASSERT(map); SetMap(map); - if (data && data->phaseid) - SetInPhase(data->phaseid, false, true); - - if (data && data->phaseGroup) - for (auto ph : GetPhasesForGroup(data->phaseGroup)) - SetInPhase(ph, false, true); + if (data) + { + PhasingHandler::InitDbPhaseShift(GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup); + PhasingHandler::InitDbVisibleMapId(GetPhaseShift(), data->terrainSwapMap); + } CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); if (!cinfo) @@ -1157,7 +1157,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) data.unit_flags = unit_flags; data.dynamicflags = dynamicflags; - data.phaseid = GetDBPhase() > 0 ? GetDBPhase() : 0; + data.phaseId = GetDBPhase() > 0 ? GetDBPhase() : 0; data.phaseGroup = GetDBPhase() < 0 ? abs(GetDBPhase()) : 0; // update in DB @@ -1176,7 +1176,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) stmt->setUInt16(index++, uint16(mapid)); stmt->setUInt8(index++, spawnMask); stmt->setUInt32(index++, GetPhaseMask()); - stmt->setUInt32(index++, data.phaseid); + stmt->setUInt32(index++, data.phaseId); stmt->setUInt32(index++, data.phaseGroup); stmt->setUInt32(index++, displayId); stmt->setInt32(index++, int32(GetCurrentEquipmentId())); @@ -1437,7 +1437,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad m_deathState = DEAD; if (CanFly()) { - float tz = map->GetHeight(GetPhases(), data->posX, data->posY, data->posZ, true, MAX_FALL_DISTANCE); + float tz = map->GetHeight(GetPhaseShift(), data->posX, data->posY, data->posZ, true, MAX_FALL_DISTANCE); if (data->posZ - tz > 0.1f && Trinity::IsValidMapCoord(tz)) Relocate(data->posX, data->posY, tz); } @@ -2701,7 +2701,7 @@ void Creature::UpdateMovementFlags() return; // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc) - float ground = GetFloorZ(); + float ground = GetMap()->GetHeight(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); bool isInAir = (G3D::fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index eb500405d9b..bad63dbd7c8 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -274,7 +274,8 @@ struct CreatureData CreatureData() : id(0), mapid(0), phaseMask(0), displayid(0), equipmentId(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), spawndist(0.0f), currentwaypoint(0), curhealth(0), curmana(0), movementType(0), - spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), phaseid(0), phaseGroup(0), ScriptId(0), dbData(true) { } + spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), phaseUseFlags(0), + phaseId(0), phaseGroup(0), terrainSwapMap(-1), ScriptId(0), dbData(true) { } uint32 id; // entry in creature_template uint16 mapid; uint32 phaseMask; @@ -294,8 +295,10 @@ struct CreatureData uint32 npcflag; uint32 unit_flags; // enum UnitFlags mask values uint32 dynamicflags; - uint32 phaseid; + uint8 phaseUseFlags; + uint32 phaseId; uint32 phaseGroup; + int32 terrainSwapMap; uint32 ScriptId; bool dbData; }; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 3da93a3553a..6ae70163840 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -27,6 +27,7 @@ #include "GroupMgr.h" #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" +#include "PhasingHandler.h" #include "PoolMgr.h" #include "ScriptMgr.h" #include "SpellMgr.h" @@ -907,15 +908,8 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, boo if (!Create(map->GenerateLowGuid(), entry, map, phaseMask, pos, data->rotation, animprogress, go_state, artKit)) return false; - if (data->phaseid) - SetInPhase(data->phaseid, false, true); - - if (data->phaseGroup) - { - // Set the gameobject in all the phases of the phasegroup - for (auto ph : GetPhasesForGroup(data->phaseGroup)) - SetInPhase(ph, false, true); - } + PhasingHandler::InitDbPhaseShift(GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup); + PhasingHandler::InitDbVisibleMapId(GetPhaseShift(), data->terrainSwapMap); if (data->spawntimesecs >= 0) { @@ -2476,7 +2470,6 @@ public: virtual bool IsSpawned() const override { return _owner->isSpawned(); } virtual uint32 GetDisplayId() const override { return _owner->GetDisplayId(); } - virtual bool IsInPhase(std::set const& phases) const override { return _owner->IsInPhase(phases); } virtual G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); } virtual float GetOrientation() const override { return _owner->GetOrientation(); } virtual float GetScale() const override { return _owner->GetObjectScale(); } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index c2076a13acf..5780342bab8 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -644,7 +644,8 @@ enum GOState struct GameObjectData { explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), - animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), phaseid(0), phaseGroup(0), ScriptId(0), dbData(true) { } + animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), phaseUseFlags(0), phaseId(0), + phaseGroup(0), terrainSwapMap(-1), ScriptId(0), dbData(true) { } uint32 id; // entry in gamobject_template uint16 mapid; uint32 phaseMask; @@ -658,8 +659,10 @@ struct GameObjectData GOState go_state; uint8 spawnMask; uint8 artKit; - uint32 phaseid; + uint8 phaseUseFlags; + uint32 phaseId; uint32 phaseGroup; + int32 terrainSwapMap; uint32 ScriptId; bool dbData; }; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index cd10148bbbe..d754ae9a583 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -45,6 +45,7 @@ #include "TemporarySummon.h" #include "Totem.h" #include "OutdoorPvPMgr.h" +#include "PhasingHandler.h" #include "MovementPacketBuilder.h" #include "DynamicTree.h" #include "Unit.h" @@ -1280,7 +1281,7 @@ void WorldObject::_Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32 void WorldObject::UpdatePositionData() { PositionFullTerrainStatus data; - GetMap()->GetFullTerrainStatusForPosition(GetPositionX(), GetPositionY(), GetPositionZ(), data); + GetMap()->GetFullTerrainStatusForPosition(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), data); ProcessPositionDataChanged(data); } @@ -1296,7 +1297,7 @@ void WorldObject::ProcessPositionDataChanged(PositionFullTerrainStatus const& da void WorldObject::AddToWorld() { Object::AddToWorld(); - GetBaseMap()->GetZoneAndAreaId(m_zoneId, m_areaId, GetPositionX(), GetPositionY(), GetPositionZ()); + GetBaseMap()->GetZoneAndAreaId(GetPhaseShift(), m_zoneId, m_areaId, GetPositionX(), GetPositionY(), GetPositionZ()); } void WorldObject::RemoveFromWorld() @@ -1446,7 +1447,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, LineOfSightChecks ch else GetHitSpherePointFor({ ox, oy, oz }, x, y, z); - return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhases(), checks, ignoreFlags); + return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, checks, ignoreFlags); } return true; @@ -1621,7 +1622,7 @@ Position WorldObject::GetRandomPoint(const Position &srcPos, float distance) con void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const { - float new_z = GetMap()->GetHeight(GetPhases(), x, y, z + 2.0f, true); + float new_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z + 2.0f, true); if (new_z > INVALID_HEIGHT) z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface } @@ -1643,8 +1644,8 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const bool canSwim = ToCreature()->CanSwim(); float ground_z = z; float max_z = canSwim - ? GetMap()->GetWaterOrGroundLevel(GetPhases(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK)) - : ((ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true))); + ? GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK)) + : ((ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true))); if (max_z > INVALID_HEIGHT) { if (z > max_z) @@ -1655,7 +1656,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const } else { - float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true); + float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true); if (z < ground_z) z = ground_z; } @@ -1667,7 +1668,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const if (!ToPlayer()->CanFly()) { float ground_z = z; - float max_z = GetMap()->GetWaterOrGroundLevel(GetPhases(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK)); + float max_z = GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK)); if (max_z > INVALID_HEIGHT) { if (z > max_z) @@ -1678,7 +1679,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const } else { - float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true); + float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true); if (z < ground_z) z = ground_z; } @@ -1686,7 +1687,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const } default: { - float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true); + float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true); if (ground_z > INVALID_HEIGHT) z = ground_z; break; @@ -2100,7 +2101,8 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert } // Set the summon to the summoner's phase - summon->CopyPhaseFrom(summoner); + if (summoner) + PhasingHandler::InheritPhaseShift(summon, summoner); summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); @@ -2204,7 +2206,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, G3D return nullptr; } - go->CopyPhaseFrom(this); + PhasingHandler::InheritPhaseShift(go, this); go->SetRespawnTime(respawnTime); if (GetTypeId() == TYPEID_PLAYER || (GetTypeId() == TYPEID_UNIT && summonType == GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)) //not sure how to handle this @@ -2430,8 +2432,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle) return; } - ground = GetMap()->GetHeight(GetPhases(), destx, desty, MAX_HEIGHT, true); - floor = GetMap()->GetHeight(GetPhases(), destx, desty, pos.m_positionZ, true); + ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true); + floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true); destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor; float step = dist/10.0f; @@ -2443,8 +2445,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle) { destx -= step * std::cos(angle); desty -= step * std::sin(angle); - ground = GetMap()->GetHeight(GetPhases(), destx, desty, MAX_HEIGHT, true); - floor = GetMap()->GetHeight(GetPhases(), destx, desty, pos.m_positionZ, true); + ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true); + floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true); destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor; } // we have correct destz now @@ -2464,8 +2466,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle) // @todo: replace with WorldObject::UpdateAllowedPositionZ float NormalizeZforCollision(WorldObject* obj, float x, float y, float z) { - float ground = obj->GetMap()->GetHeight(obj->GetPhases(), x, y, MAX_HEIGHT, true); - float floor = obj->GetMap()->GetHeight(obj->GetPhases(), x, y, z + 2.0f, true); + float ground = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, MAX_HEIGHT, true); + float floor = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, z + 2.0f, true); float helper = std::fabs(ground - z) <= std::fabs(floor - z) ? ground : floor; if (z > helper) // must be above ground { @@ -2475,7 +2477,7 @@ float NormalizeZforCollision(WorldObject* obj, float x, float y, float z) return z; } LiquidData liquid_status; - ZLiquidStatus res = obj->GetMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); + ZLiquidStatus res = obj->GetMap()->GetLiquidStatus(obj->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status); if (res && liquid_status.level > helper) // water must be above ground { if (liquid_status.level > z) // z is underwater @@ -2502,7 +2504,8 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float } destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ()); - bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f); + bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(PhasingHandler::GetTerrainMapId(GetPhaseShift(), GetMap(), pos.m_positionX, pos.m_positionY), + pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f); // collision occured if (col) @@ -2514,7 +2517,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float } // check dynamic collision - col = GetMap()->getObjectHitPos(GetPhases(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f); + col = GetMap()->getObjectHitPos(GetPhaseShift(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f); // Collided with a gameobject if (col) @@ -2557,165 +2560,6 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update) UpdateObjectVisibility(); } -bool WorldObject::HasInPhaseList(uint32 phase) -{ - return _phases.find(phase) != _phases.end(); -} - -// Updates Area based phases, does not remove phases from auras -// Phases from gm commands are not taken into calculations, they can be lost!! -void WorldObject::UpdateAreaPhase() -{ - bool updateNeeded = false; - PhaseInfo const& phases = sObjectMgr->GetAreaPhases(); - for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - { - uint32 areaId = itr->first; - for (PhaseInfoStruct const& phase : itr->second) - { - if (areaId == GetAreaId()) - { - if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions)) - { - // add new phase if condition passed, true if it wasnt added before - bool up = SetInPhase(phase.Id, false, true); - if (!updateNeeded && up) - updateNeeded = true; - } - else - { - // condition failed, remove phase, true if there was something removed - bool up = SetInPhase(phase.Id, false, false); - if (!updateNeeded && up) - updateNeeded = true; - } - } - else - { - // not in area, remove phase, true if there was something removed - bool up = SetInPhase(phase.Id, false, false); - if (!updateNeeded && up) - updateNeeded = true; - } - } - } - - // do not remove a phase if it would be removed by an area but we have the same phase from an aura - if (Unit* unit = ToUnit()) - { - Unit::AuraEffectList const& auraPhaseList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE); - for (Unit::AuraEffectList::const_iterator itr = auraPhaseList.begin(); itr != auraPhaseList.end(); ++itr) - { - uint32 phase = uint32((*itr)->GetMiscValueB()); - bool up = SetInPhase(phase, false, true); - if (!updateNeeded && up) - updateNeeded = true; - } - Unit::AuraEffectList const& auraPhaseGroupList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP); - for (Unit::AuraEffectList::const_iterator itr = auraPhaseGroupList.begin(); itr != auraPhaseGroupList.end(); ++itr) - { - bool up = false; - uint32 phaseGroup = uint32((*itr)->GetMiscValueB()); - std::set const& phases = GetPhasesForGroup(phaseGroup); - for (uint32 phase : phases) - up = SetInPhase(phase, false, true); - if (!updateNeeded && up) - updateNeeded = true; - } - } - - // only update visibility and send packets if there was a change in the phase list - if (updateNeeded && GetTypeId() == TYPEID_PLAYER && IsInWorld()) - ToPlayer()->GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps()); - - // only update visibilty once, to prevent objects appearing for a moment while adding in multiple phases - if (updateNeeded && IsInWorld()) - UpdateObjectVisibility(); -} - -bool WorldObject::SetInPhase(uint32 id, bool update, bool apply) -{ - if (id) - { - if (apply) - { - if (HasInPhaseList(id)) // do not run the updates if we are already in this phase - return false; - - _phases.insert(id); - } - else - { - // if area phase passes the condition we should not remove it (ie: if remove called from aura remove) - // this however breaks the .mod phase command, you wont be able to remove any area based phases with it - PhaseInfo const& phases = sObjectMgr->GetAreaPhases(); - for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - if (itr->first == GetAreaId() || itr->first == GetZoneId()) - for (PhaseInfoStruct const& phase : itr->second) - if (id == phase.Id) - if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions)) - return false; - - if (!HasInPhaseList(id)) // do not run the updates if we are not in this phase - return false; - - _phases.erase(id); - } - } - - RebuildTerrainSwaps(); - - if (update && IsInWorld()) - UpdateObjectVisibility(); - - return true; -} - -void WorldObject::CopyPhaseFrom(WorldObject* obj, bool update) -{ - if (!obj) - return; - - for (uint32 phase : obj->GetPhases()) - SetInPhase(phase, false, true); - - if (update && IsInWorld()) - UpdateObjectVisibility(); -} - -void WorldObject::ClearPhases(bool update) -{ - _phases.clear(); - - RebuildTerrainSwaps(); - - if (update && IsInWorld()) - UpdateObjectVisibility(); -} - -bool WorldObject::IsInPhase(std::set const& phases) const -{ - // PhaseId 169 is the default fallback phase - if (_phases.empty() && phases.empty()) - return true; - - if (_phases.empty() && phases.count(DEFAULT_PHASE) > 0) - return true; - - if (phases.empty() && _phases.count(DEFAULT_PHASE) > 0) - return true; - - return Trinity::Containers::Intersects(_phases.begin(), _phases.end(), phases.begin(), phases.end()); -} - -bool WorldObject::IsInPhase(WorldObject const* obj) const -{ - if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->IsGameMaster()) - return true; - - return IsInPhase(obj->GetPhases()); -} - void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/) { WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4 + 8); @@ -2882,7 +2726,7 @@ float WorldObject::GetFloorZ() const { if (!IsInWorld()) return m_staticFloorZ; - return std::max(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhases(), GetPositionX(), GetPositionY(), GetPositionZ())); + return std::max(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ())); } template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list&, uint32, float) const; @@ -2944,63 +2788,3 @@ void WorldObject::SetMeleeAnimKitId(uint16 animKitId) data << uint16(animKitId); SendMessageToSet(&data, true); } - -void WorldObject::RebuildTerrainSwaps() -{ - // Clear all terrain swaps, will be rebuilt below - // Reason for this is, multiple phases can have the same terrain swap, we should not remove the swap if another phase still use it - _terrainSwaps.clear(); - - // Check all applied phases for terrain swap and add it only once - for (uint32 phaseId : _phases) - { - if (std::vector const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId)) - { - for (uint32 const& swap : *swaps) - { - // only add terrain swaps for current map - MapEntry const* mapEntry = sMapStore.LookupEntry(swap); - if (!mapEntry || mapEntry->rootPhaseMap != int32(GetMapId())) - continue; - - if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this)) - _terrainSwaps.insert(swap); - } - } - } - - // get default terrain swaps, only for current map always - if (std::vector const* mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId())) - for (uint32 const& swap : *mapSwaps) - if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this)) - _terrainSwaps.insert(swap); - - // online players have a game client with world map display - if (GetTypeId() == TYPEID_PLAYER) - RebuildWorldMapAreaSwaps(); -} - -void WorldObject::RebuildWorldMapAreaSwaps() -{ - // Clear all world map area swaps, will be rebuilt below - _worldMapAreaSwaps.clear(); - - // get ALL default terrain swaps, if we are using it (condition is true) - // send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current - TerrainPhaseInfo const& defaults = sObjectMgr->GetDefaultTerrainSwapStore(); - for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr) - for (uint32 const& swap : itr->second) - if (std::vector const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap)) - if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this)) - for (uint32 worldMapAreaId : *uiMapSwaps) - _worldMapAreaSwaps.insert(worldMapAreaId); - - // Check all applied phases for world map area swaps - for (uint32 phaseId : _phases) - if (std::vector const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId)) - for (uint32 const& swap : *swaps) - if (std::vector const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap)) - if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this)) - for (uint32 worldMapAreaId : *uiMapSwaps) - _worldMapAreaSwaps.insert(worldMapAreaId); -} diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 27788e23306..70e4c68acb5 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -24,10 +24,10 @@ #include "UpdateMask.h" #include "GridReference.h" #include "ObjectDefines.h" +#include "PhaseShift.h" #include "Map.h" #include "ModelIgnoreFlags.h" -#include #include #include @@ -48,8 +48,6 @@ #define NOMINAL_MELEE_RANGE 5.0f #define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players -#define DEFAULT_PHASE 169 - enum TempSummonType { TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears @@ -485,21 +483,16 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation uint32 GetInstanceId() const { return m_InstanceId; } virtual void SetPhaseMask(uint32 newPhaseMask, bool update); - virtual bool SetInPhase(uint32 id, bool update, bool apply); - void CopyPhaseFrom(WorldObject* obj, bool update = false); - void UpdateAreaPhase(); - void ClearPhases(bool update = false); - void RebuildTerrainSwaps(); - void RebuildWorldMapAreaSwaps(); - bool HasInPhaseList(uint32 phase); + bool IsInPhase(WorldObject const* obj) const + { + return GetPhaseShift().CanSee(obj->GetPhaseShift()); + } + + PhaseShift& GetPhaseShift() { return _phaseShift; } + PhaseShift const& GetPhaseShift() const { return _phaseShift; } + PhaseShift& GetSuppressedPhaseShift() { return _suppressedPhaseShift; } + PhaseShift const& GetSuppressedPhaseShift() const { return _suppressedPhaseShift; } uint32 GetPhaseMask() const { return m_phaseMask; } - bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); } - bool IsInPhase(std::set const& phases) const; - bool IsInPhase(WorldObject const* obj) const; - bool IsInTerrainSwap(uint32 terrainSwap) const { return _terrainSwaps.find(terrainSwap) != _terrainSwaps.end(); } - std::set const& GetPhases() const { return _phases; } - std::set const& GetTerrainSwaps() const { return _terrainSwaps; } - std::set const& GetWorldMapAreaSwaps() const { return _worldMapAreaSwaps; } int32 GetDBPhase() { return _dbPhase; } // if negative it is used as PhaseGroupId @@ -699,9 +692,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation //uint32 m_mapId; // object at map with map_id uint32 m_InstanceId; // in map copy with instance id uint32 m_phaseMask; // in area phase state - std::set _phases; - std::set _terrainSwaps; - std::set _worldMapAreaSwaps; + PhaseShift _phaseShift; + PhaseShift _suppressedPhaseShift; // contains phases for current area but not applied due to conditions int32 _dbPhase; uint16 m_notifyflags; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index f841946b71e..fbedb7b3479 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -21,6 +21,7 @@ #include "Log.h" #include "WorldPacket.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "SpellMgr.h" #include "Pet.h" #include "Formulas.h" @@ -179,7 +180,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c if (!Create(guid, map, petEntry, petId)) return false; - CopyPhaseFrom(owner); + PhasingHandler::InheritPhaseShift(this, owner); setPetType(petType); SetFaction(owner->GetFaction()); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ca8299a1696..abd947dcd98 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -65,6 +65,7 @@ #include "OutdoorPvP.h" #include "OutdoorPvPMgr.h" #include "Pet.h" +#include "PhasingHandler.h" #include "QueryCallback.h" #include "QuestDef.h" #include "ReputationMgr.h" @@ -1951,7 +1952,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati } // remove arena spell coldowns/buffs now to also remove pet's cooldowns before it's temporarily unsummoned - if (mEntry->IsBattleArena()) + if (mEntry->IsBattleArena() && !IsGameMaster()) { RemoveArenaSpellCooldowns(true); RemoveArenaAuras(); @@ -2560,7 +2561,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, Gameo bool Player::IsUnderWater() const { return IsInWater() && - GetPositionZ() < (GetBaseMap()->GetWaterLevel(GetPositionX(), GetPositionY())-2); + GetPositionZ() < (GetBaseMap()->GetWaterLevel(GetPhaseShift(), GetPositionX(), GetPositionY())-2); } void Player::SetInWater(bool apply) @@ -2583,9 +2584,16 @@ void Player::SetInWater(bool apply) bool Player::IsInAreaTriggerRadius(const AreaTriggerEntry* trigger) const { - if (!trigger || GetMapId() != trigger->mapid) + if (!trigger) return false; + if (GetMapId() != trigger->mapid && !GetPhaseShift().HasVisibleMapId(trigger->mapid)) + return false; + + if (trigger->PhaseID || trigger->PhaseGroupID || trigger->PhaseUseFlags) + if (!PhasingHandler::InDbPhaseShift(this, trigger->PhaseUseFlags, trigger->PhaseID, trigger->PhaseGroupID)) + return false; + if (trigger->radius > 0.f) { // if we have radius check it @@ -2624,10 +2632,13 @@ void Player::SetGameMaster(bool on) getHostileRefManager().setOnlineOfflineState(false); CombatStopWithPets(); + PhasingHandler::SetAlwaysVisible(GetPhaseShift(), true); m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, GetSession()->GetSecurity()); } else { + PhasingHandler::SetAlwaysVisible(GetPhaseShift(), false); + m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON; SetFactionForRace(getRace()); RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); @@ -5143,7 +5154,7 @@ void Player::RepopAtGraveyard() if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) ClosestGrave = bf->GetClosestGraveYard(this); else - ClosestGrave = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()); + ClosestGrave = sObjectMgr->GetClosestGraveYard(*this, GetTeam(), this); } // stop countdown until repop @@ -6430,7 +6441,7 @@ void Player::CheckAreaExploreAndOutdoor() return; bool isOutdoor; - uint32 areaId = GetBaseMap()->GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor); + uint32 areaId = GetBaseMap()->GetAreaId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor); AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor) @@ -7353,7 +7364,7 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid) if (!sMapStore.LookupEntry(map)) return 0; - zone = sMapMgr->GetZoneId(map, posx, posy, posz); + zone = sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), map, posx, posy, posz); if (zone > 0) { @@ -7380,7 +7391,7 @@ void Player::UpdateArea(uint32 newArea) UpdatePvPState(true); UpdateAreaDependentAuras(newArea); - UpdateAreaPhase(); + PhasingHandler::OnAreaChange(this); // previously this was in UpdateZone (but after UpdateArea) so nothing will break pvpInfo.IsInNoPvPArea = false; @@ -7485,8 +7496,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) UpdateLocalChannels(newZone); UpdateZoneDependentAuras(newZone); - - UpdateAreaPhase(); } //If players are too far away from the duel flag... they lose the duel @@ -16040,7 +16049,7 @@ void Player::SendQuestUpdate(uint32 questId) } UpdateForQuestWorldObjects(); - SendUpdatePhasing(); + PhasingHandler::OnConditionChange(this); } QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver) @@ -17322,9 +17331,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) } _LoadCurrency(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CURRENCY)); - SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[40].GetUInt32()); - SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[41].GetUInt16()); - SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[42].GetUInt16()); + SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[45].GetUInt32()); + SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[46].GetUInt16()); + SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[47].GetUInt16()); _LoadBoundInstances(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES)); _LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES)); @@ -22587,7 +22596,7 @@ void Player::SetBattlegroundEntryPoint() // If map is dungeon find linked graveyard if (GetMap()->IsDungeon()) { - if (const WorldSafeLocsEntry* entry = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam())) + if (const WorldSafeLocsEntry* entry = sObjectMgr->GetClosestGraveYard(*this, GetTeam(), this)) m_bgData.joinPos = WorldLocation(entry->map_id, entry->x, entry->y, entry->z, 0.0f); else TC_LOG_ERROR("entities.player", "Player::SetBattlegroundEntryPoint: Dungeon (MapID: %u) has no linked graveyard, setting home location as entry point.", GetMapId()); @@ -23250,6 +23259,8 @@ void Player::SendInitialPacketsAfterAddToMap() else ClearQuestSharingInfo(); } + + PhasingHandler::OnMapChange(this); } void Player::SendUpdateToOutOfRangeGroupMembers() @@ -27327,7 +27338,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy return nullptr; } - pet->CopyPhaseFrom(this); + PhasingHandler::InheritPhaseShift(pet, this); pet->SetCreatorGUID(GetGUID()); pet->SetFaction(GetFaction()); @@ -27699,16 +27710,6 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext #undef REMOVE_VIOLATING_FLAGS } -void Player::SendUpdatePhasing() -{ - if (!IsInWorld()) - return; - - RebuildTerrainSwaps(); // to set default map swaps - - GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps()); -} - void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const { WorldPacket data(SMSG_SUPERCEDED_SPELL, 8); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 8394cdfead2..fff5bbf8ada 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2347,6 +2347,7 @@ class TC_GAME_API Player : public Unit, public GridObject // currently visible objects at player client GuidUnorderedSet m_clientGUIDs; + GuidUnorderedSet m_visibleTransports; bool HaveAtClient(Object const* u) const; @@ -2360,8 +2361,6 @@ class TC_GAME_API Player : public Unit, public GridObject void UpdateVisibilityOf(WorldObject* target); void UpdateTriggerVisibility(); - void SendUpdatePhasing(); - template void UpdateVisibilityOf(T* target, UpdateData& data, std::set& visibleNow); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index ba0524c2140..a85bcc4aa53 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -20,6 +20,7 @@ #include "Transport.h" #include "MapManager.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "ScriptMgr.h" #include "DBCStores.h" #include "GameObjectAI.h" @@ -326,13 +327,8 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c return NULL; } - if (data->phaseid) - creature->SetInPhase(data->phaseid, false, true); - else if (data->phaseGroup) - for (auto phase : GetPhasesForGroup(data->phaseGroup)) - creature->SetInPhase(phase, false, true); - else - creature->CopyPhaseFrom(this); + PhasingHandler::InitDbPhaseShift(creature->GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup); + PhasingHandler::InitDbVisibleMapId(creature->GetPhaseShift(), data->terrainSwapMap); if (!map->AddToMap(creature)) { @@ -377,6 +373,9 @@ GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectDat return NULL; } + PhasingHandler::InitDbPhaseShift(go->GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup); + PhasingHandler::InitDbVisibleMapId(go->GetPhaseShift(), data->terrainSwapMap); + if (!map->AddToMap(go)) { delete go; @@ -441,12 +440,6 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu } } - std::set phases; - if (summoner) - phases = summoner->GetPhases(); - else - phases = GetPhases(); // If there was no summoner, try to use the transport phases - TempSummon* summon = NULL; switch (mask) { @@ -477,8 +470,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu return NULL; } - for (uint32 phase : phases) - summon->SetInPhase(phase, false, true); + PhasingHandler::InheritPhaseShift(summon, summoner ? static_cast(summoner) : static_cast(this)); summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); @@ -515,6 +507,7 @@ void Transport::UpdatePosition(float x, float y, float z, float o) Cell oldCell(GetPositionX(), GetPositionY()); Relocate(x, y, z, o); + m_stationaryPosition.SetOrientation(o); UpdateModelPosition(); UpdatePassengerPositions(_passengers); @@ -627,6 +620,8 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl } else { + UpdatePosition(x, y, z, o); + // Teleport players, they need to know it for (PassengerSet::iterator itr = _passengers.begin(); itr != _passengers.end(); ++itr) { @@ -645,7 +640,6 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl } } - UpdatePosition(x, y, z, o); return false; } } diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 03bd3bcb2c7..b3bdcae034c 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -27,7 +27,7 @@ struct CreatureData; class TC_GAME_API Transport : public GameObject, public TransportBase { - friend Transport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*, uint32, uint32); + friend Transport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*, uint8, uint32, uint32); Transport(); public: diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index a7f84306a66..c827b31c517 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -46,6 +46,7 @@ #include "PassiveAI.h" #include "PetAI.h" #include "Pet.h" +#include "PhasingHandler.h" #include "Player.h" #include "PlayerAI.h" #include "QuestDef.h" @@ -3105,12 +3106,12 @@ bool Unit::isInAccessiblePlaceFor(Creature const* c) const bool Unit::IsInWater() const { - return GetBaseMap()->IsInWater(GetPositionX(), GetPositionY(), GetPositionZ()); + return GetBaseMap()->IsInWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); } bool Unit::IsUnderWater() const { - return GetBaseMap()->IsUnderWater(GetPositionX(), GetPositionY(), GetPositionZ()); + return GetBaseMap()->IsUnderWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); } void Unit::ProcessPositionDataChanged(PositionFullTerrainStatus const& data) @@ -3886,7 +3887,7 @@ void Unit::RemoveAurasWithAttribute(uint32 flags) } } -void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid) +void Unit::RemoveNotOwnSingleTargetAuras(bool onPhaseChange /*= false*/) { // single target auras from other casters // Iterate m_ownedAuras - aura is marked as single target in Unit::AddAura (and pushed to m_ownedAuras). @@ -3903,12 +3904,12 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid) if (aura->GetCasterGUID() != GetGUID() && aura->IsSingleTarget()) { - if (!newPhase && !phaseid) + if (!onPhaseChange) RemoveOwnedAura(iter); else { Unit* caster = aura->GetCaster(); - if (!caster || (newPhase && !caster->IsInPhase(newPhase)) || (!newPhase && !caster->IsInPhase(this))) + if (!caster || !caster->IsInPhase(this)) RemoveOwnedAura(iter); else ++iter; @@ -3923,7 +3924,7 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid) for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();) { Aura* aura = *iter; - if (aura->GetUnitOwner() != this && !aura->GetUnitOwner()->IsInPhase(newPhase)) + if (aura->GetUnitOwner() != this && (!onPhaseChange || !aura->GetUnitOwner()->IsInPhase(this))) { aura->Remove(); iter = scAuras.begin(); @@ -5532,7 +5533,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) //if (GetTypeId() == TYPEID_UNIT) // ToCreature()->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ()); - if (creature && !IsPet()) + if (creature && !IsControlledByPlayer()) { // should not let player enter combat by right clicking target - doesn't helps AddThreat(victim, 0.0f); @@ -8097,7 +8098,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const mountFlags = areaTable->MountFlags; LiquidData liquid; - ZLiquidStatus liquidStatus = GetMap()->GetLiquidStatus(GetPositionX(), GetPositionY(), GetPositionZ(), MAP_ALL_LIQUIDS, &liquid); + ZLiquidStatus liquidStatus = GetMap()->GetLiquidStatus(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), MAP_ALL_LIQUIDS, &liquid); isSubmerged = (liquidStatus & LIQUID_MAP_UNDER_WATER) != 0 || HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING); isInWater = (liquidStatus & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0; @@ -10015,15 +10016,6 @@ int32 Unit::GetCreatePowers(Powers power) const return 0; } -void Unit::AddToWorld() -{ - if (!IsInWorld()) - { - WorldObject::AddToWorld(); - } - RebuildTerrainSwaps(); -} - void Unit::RemoveFromWorld() { // cleanup @@ -11343,7 +11335,7 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) return false; } - pet->CopyPhaseFrom(this); + PhasingHandler::InheritPhaseShift(pet, this); pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); // this enables pet details window (Shift+P) @@ -12444,14 +12436,12 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, u return missChance; } -bool Unit::SetInPhase(uint32 id, bool update, bool apply) +void Unit::OnPhaseChange() { - bool res = WorldObject::SetInPhase(id, update, apply); - if (!IsInWorld()) - return res; + return; - if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout())) + if (GetTypeId() == TYPEID_UNIT || !ToPlayer()->GetSession()->PlayerLogout()) { HostileRefManager& refManager = getHostileRefManager(); HostileReference* ref = refManager.getFirst(); @@ -12481,19 +12471,6 @@ bool Unit::SetInPhase(uint32 id, bool update, bool apply) unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->IsInPhase(this)); } } - - for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) - if ((*itr)->GetTypeId() == TYPEID_UNIT) - (*itr)->SetInPhase(id, true, apply); - - for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i) - if (m_SummonSlot[i]) - if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i])) - summon->SetInPhase(id, true, apply); - - RemoveNotOwnSingleTargetAuras(0, true); - - return res; } void Unit::UpdateObjectVisibility(bool forced) @@ -13274,7 +13251,7 @@ void Unit::_ExitVehicle(Position const* exitPosition) Movement::MoveSplineInit init(this); // Creatures without inhabit type air should begin falling after exiting the vehicle - if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f) + if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f) init.SetFall(); init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false); @@ -13564,8 +13541,8 @@ void Unit::SendTeleportPacket(Position const& pos) data2.WriteBit(guid[0]); data2.WriteBit(guid[3]); data2.WriteBit(guid[2]); - data2.WriteBit(0); // unknown data2.WriteBit(uint64(transGuid)); + data2.WriteBit(bool(GetVehicle())); // unknown data2.WriteBit(guid[1]); if (transGuid) { diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index e8ab2baa4fc..ba8f25f0a72 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1309,7 +1309,6 @@ class TC_GAME_API Unit : public WorldObject UnitAI* GetAI() { return i_AI; } void SetAI(UnitAI* newAI) { i_AI = newAI; } - void AddToWorld() override; void RemoveFromWorld() override; void CleanupBeforeRemoveFromMap(bool finalCleanup); @@ -1795,7 +1794,7 @@ class TC_GAME_API Unit : public WorldObject void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit* stealer); void RemoveAurasDueToItemSpell(uint32 spellId, ObjectGuid castItemGuid); void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = NULL, bool negative = true, bool positive = true); - void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0, bool phaseid = false); + void RemoveNotOwnSingleTargetAuras(bool onPhaseChange = false); void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = 0); void RemoveAurasWithAttribute(uint32 flags); void RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID); @@ -1977,7 +1976,7 @@ class TC_GAME_API Unit : public WorldObject void SetVisible(bool x); // common function for visibility checks for player/creatures with detection code - bool SetInPhase(uint32 id, bool update, bool apply) override; + void OnPhaseChange(); void UpdateObjectVisibility(bool forced = true) override; SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index c57deb6290e..8c1da64918a 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -23,6 +23,7 @@ #include "BattlegroundMgr.h" #include "Chat.h" #include "Common.h" +#include "Containers.h" #include "CreatureAIFactory.h" #include "DatabaseEnv.h" #include "DB2Structure.h" @@ -39,6 +40,7 @@ #include "MapManager.h" #include "Object.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "PoolMgr.h" #include "ReputationMgr.h" #include "ScriptMgr.h" @@ -1682,7 +1684,7 @@ void ObjectMgr::LoadLinkedRespawn() } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded " UI64FMTD " linked respawns in %u ms", uint64(_linkedRespawnStore.size()), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %lu linked respawns in %u ms", uint64(_linkedRespawnStore.size()), GetMSTimeDiffToNow(oldMSTime)); } bool ObjectMgr::SetCreatureLinkedRespawn(ObjectGuid::LowType guidLow, ObjectGuid::LowType linkedGuidLow) @@ -1828,9 +1830,9 @@ void ObjectMgr::LoadCreatures() // 0 1 2 3 4 5 6 7 8 9 10 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, " // 11 12 13 14 15 16 17 18 19 20 21 22 - "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseid, " - // 23 24 - "creature.phasegroup, creature.ScriptName " + "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseUseFlags, " + // 23 24 25 26 + "creature.phaseid, creature.phasegroup, creature.terrainSwapMap, creature.ScriptName " "FROM creature " "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid " "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid"); @@ -1849,7 +1851,9 @@ void ObjectMgr::LoadCreatures() if (GetMapDifficultyData(i, Difficulty(k))) spawnMasks[i] |= (1 << k); - _creatureDataStore.rehash(result->GetRowCount()); + PhaseShift phaseShift; + + _creatureDataStore.reserve(result->GetRowCount()); do { @@ -1887,9 +1891,11 @@ void ObjectMgr::LoadCreatures() data.npcflag = fields[19].GetUInt32(); data.unit_flags = fields[20].GetUInt32(); data.dynamicflags = fields[21].GetUInt32(); - data.phaseid = fields[22].GetUInt32(); - data.phaseGroup = fields[23].GetUInt32(); - data.ScriptId = GetScriptId(fields[24].GetString()); + data.phaseUseFlags = fields[22].GetUInt8(); + data.phaseId = fields[23].GetUInt32(); + data.phaseGroup = fields[24].GetUInt32(); + data.terrainSwapMap = fields[25].GetInt32(); + data.ScriptId = GetScriptId(fields[26].GetString()); MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid); if (!mapEntry) @@ -1971,23 +1977,52 @@ void ObjectMgr::LoadCreatures() data.phaseMask = 1; } - if (data.phaseGroup && GetPhasesForGroup(data.phaseGroup).empty()) + if (data.phaseUseFlags & ~PHASE_USE_FLAGS_ALL) + { + TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.id); + data.phaseUseFlags &= PHASE_USE_FLAGS_ALL; + } + + if (data.phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && data.phaseUseFlags & PHASE_USE_FLAGS_INVERSE) + { + TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE," + " removing PHASE_USE_FLAGS_INVERSE.", guid, data.id); + data.phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE; + } + + if (data.phaseGroup && !GetPhasesForGroup(data.phaseGroup)) { TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: %u Entry: %u) with non-existing `phasegroup` (%u) set, `phasegroup` set to 0", guid, data.id, data.phaseGroup); data.phaseGroup = 0; } - if (data.phaseGroup && data.phaseid) + if (data.phaseGroup && data.phaseId) { TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id); data.phaseGroup = 0; } + if (data.terrainSwapMap != -1) + { + MapEntry const* terrainSwapEntry = sMapStore.LookupEntry(data.terrainSwapMap); + if (!terrainSwapEntry) + { + TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap); + data.terrainSwapMap = -1; + } + else if (terrainSwapEntry->rootPhaseMap != data.mapid) + { + TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap); + data.terrainSwapMap = -1; + } + } + if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA)) { uint32 zoneId = 0; uint32 areaId = 0; - sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); + PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap); + sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA); @@ -2141,8 +2176,8 @@ void ObjectMgr::LoadGameobjects() QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, " // 7 8 9 10 11 12 13 14 15 16 17 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, " - // 18 19 20 - "phaseid, phasegroup, ScriptName " + // 18 19 20 21 22 + "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName " "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid " "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid"); @@ -2160,7 +2195,9 @@ void ObjectMgr::LoadGameobjects() if (GetMapDifficultyData(i, Difficulty(k))) spawnMasks[i] |= (1 << k); - _gameObjectDataStore.rehash(result->GetRowCount()); + PhaseShift phaseShift; + + _gameObjectDataStore.reserve(result->GetRowCount()); do { @@ -2243,22 +2280,52 @@ void ObjectMgr::LoadGameobjects() data.phaseMask = fields[15].GetUInt32(); int16 gameEvent = fields[16].GetInt8(); uint32 PoolId = fields[17].GetUInt32(); - data.phaseid = fields[18].GetUInt32(); - data.phaseGroup = fields[19].GetUInt32(); + data.phaseUseFlags = fields[18].GetUInt8(); + data.phaseId = fields[19].GetUInt32(); + data.phaseGroup = fields[20].GetUInt32(); - if (data.phaseGroup && GetPhasesForGroup(data.phaseGroup).empty()) + if (data.phaseUseFlags & ~PHASE_USE_FLAGS_ALL) + { + TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.id); + data.phaseUseFlags &= PHASE_USE_FLAGS_ALL; + } + + if (data.phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && data.phaseUseFlags & PHASE_USE_FLAGS_INVERSE) + { + TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE," + " removing PHASE_USE_FLAGS_INVERSE.", guid, data.id); + data.phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE; + } + + if (data.phaseGroup && !GetPhasesForGroup(data.phaseGroup)) { TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: %u Entry: %u) with non-existing `phasegroup` (%u) set, `phasegroup` set to 0", guid, data.id, data.phaseGroup); data.phaseGroup = 0; } - if (data.phaseGroup && data.phaseid) + if (data.phaseGroup && data.phaseId) { TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id); data.phaseGroup = 0; } - data.ScriptId = GetScriptId(fields[20].GetString()); + data.terrainSwapMap = fields[21].GetInt32(); + if (data.terrainSwapMap != -1) + { + MapEntry const* terrainSwapEntry = sMapStore.LookupEntry(data.terrainSwapMap); + if (!terrainSwapEntry) + { + TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap); + data.terrainSwapMap = -1; + } + else if (terrainSwapEntry->rootPhaseMap != data.mapid) + { + TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap); + data.terrainSwapMap = -1; + } + } + + data.ScriptId = GetScriptId(fields[22].GetString()); if (std::abs(data.orientation) > 2 * float(M_PI)) { @@ -2306,7 +2373,8 @@ void ObjectMgr::LoadGameobjects() { uint32 zoneId = 0; uint32 areaId = 0; - sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); + PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap); + sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA); @@ -6267,10 +6335,14 @@ WorldSafeLocsEntry const* ObjectMgr::GetDefaultGraveYard(uint32 team) const else return nullptr; } -WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) const +WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& location, uint32 team, WorldObject* conditionObject) const { + float x, y, z; + location.GetPosition(x, y, z); + uint32 MapId = location.GetMapId(); + // search for zone associated closest graveyard - uint32 zoneId = sMapMgr->GetZoneId(MapId, x, y, z); + uint32 zoneId = sMapMgr->GetZoneId(conditionObject->GetPhaseShift(), MapId, x, y, z); if (!zoneId) { @@ -6314,24 +6386,30 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float MapEntry const* mapEntry = sMapStore.LookupEntry(MapId); + ConditionSourceInfo conditionSource(conditionObject); + for (; range.first != range.second; ++range.first) { GraveYardData const& data = range.first->second; - WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(data.safeLocId); - if (!entry) - { - TC_LOG_ERROR("sql.sql", "Table `graveyard_zone` has record for not existing graveyard (WorldSafeLocsID %u), skipped.", data.safeLocId); - continue; - } + WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.AssertEntry(data.safeLocId); // skip enemy faction graveyard // team == 0 case can be at call from .neargrave if (data.team != 0 && team != 0 && data.team != team) continue; + if (conditionObject) + { + if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_GRAVEYARD, data.safeLocId, conditionSource)) + continue; + + if (int16(entry->map_id) == mapEntry->rootPhaseMap && !conditionObject->GetPhaseShift().HasVisibleMapId(entry->map_id)) + continue; + } + // find now nearest graveyard at other map - if (MapId != entry->map_id) + if (MapId != entry->map_id && int16(entry->map_id) != mapEntry->rootPhaseMap) { // if find graveyard at different map from where entrance placed (or no entrance data), use any first if (!mapEntry @@ -9498,10 +9576,78 @@ void ObjectMgr::LoadFactionChangeTitles() TC_LOG_INFO("server.loading", ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadPhases() +{ + for (PhaseEntry const* phase : sPhaseStore) + _phaseInfoById.emplace(std::make_pair(phase->ID, PhaseInfoStruct{ phase->ID, std::unordered_set{} })); + + for (MapEntry const* map : sMapStore) + if (map->rootPhaseMap != -1) + _terrainSwapInfoById.emplace(std::make_pair(map->MapID, TerrainSwapInfo{ map->MapID, std::vector{} })); + + TC_LOG_INFO("server.loading", "Loading Terrain World Map definitions..."); + LoadTerrainWorldMaps(); + + TC_LOG_INFO("server.loading", "Loading Terrain Swap Default definitions..."); + LoadTerrainSwapDefaults(); + + TC_LOG_INFO("server.loading", "Loading Phase Area definitions..."); + LoadAreaPhases(); +} + +void ObjectMgr::UnloadPhaseConditions() +{ + for (auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr) + for (PhaseAreaInfo& phase : itr->second) + phase.Conditions.clear(); +} + +void ObjectMgr::LoadTerrainWorldMaps() +{ + uint32 oldMSTime = getMSTime(); + + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`"); + + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 mapId = fields[0].GetUInt32(); + uint32 worldMapArea = fields[1].GetUInt32(); + + if (!sMapStore.LookupEntry(mapId)) + { + TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId); + continue; + } + + if (!sWorldMapAreaStore.LookupEntry(worldMapArea)) + { + TC_LOG_ERROR("sql.sql", "WorldMapArea %u defined in `terrain_worldmap` does not exist, skipped.", worldMapArea); + continue; + } + + TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[mapId]; + terrainSwapInfo->Id = mapId; + terrainSwapInfo->UiWorldMapAreaIDSwaps.push_back(worldMapArea); + + ++count; + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadTerrainSwapDefaults() { - _terrainMapDefaultStore.clear(); - uint32 oldMSTime = getMSTime(); // 0 1 @@ -9534,7 +9680,9 @@ void ObjectMgr::LoadTerrainSwapDefaults() continue; } - _terrainMapDefaultStore[mapId].push_back(terrainSwap); + TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[terrainSwap]; + terrainSwapInfo->Id = terrainSwap; + _terrainSwapInfoByMap[mapId].push_back(terrainSwapInfo); ++count; } while (result->NextRow()); @@ -9542,88 +9690,8 @@ void ObjectMgr::LoadTerrainSwapDefaults() TC_LOG_INFO("server.loading", ">> Loaded %u terrain swap defaults in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadTerrainPhaseInfo() -{ - _terrainPhaseInfoStore.clear(); - - uint32 oldMSTime = getMSTime(); - - // 0 1 - QueryResult result = WorldDatabase.Query("SELECT Id, TerrainSwapMap FROM `terrain_phase_info`"); - - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 terrain phase infos. DB table `terrain_phase_info` is empty."); - return; - } - - uint32 count = 0; - do - { - Field* fields = result->Fetch(); - - uint32 phaseId = fields[0].GetUInt32(); - - PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId); - if (!phase) - { - TC_LOG_ERROR("sql.sql", "Phase %u defined in `terrain_phase_info` does not exist, skipped.", phaseId); - continue; - } - - uint32 terrainSwap = fields[1].GetUInt32(); - - _terrainPhaseInfoStore[phaseId].push_back(terrainSwap); - - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u terrain phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); -} - -void ObjectMgr::LoadTerrainWorldMaps() -{ - _terrainWorldMapStore.clear(); - - uint32 oldMSTime = getMSTime(); - - // 0 1 - QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`"); - - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty."); - return; - } - - uint32 count = 0; - do - { - Field* fields = result->Fetch(); - - uint32 mapId = fields[0].GetUInt32(); - - if (!sMapStore.LookupEntry(mapId)) - { - TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId); - continue; - } - - uint32 worldMapArea = fields[1].GetUInt32(); - - _terrainWorldMapStore[mapId].push_back(worldMapArea); - - ++count; - } while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); -} - void ObjectMgr::LoadAreaPhases() { - _phases.clear(); - uint32 oldMSTime = getMSTime(); // 0 1 @@ -9635,23 +9703,93 @@ void ObjectMgr::LoadAreaPhases() return; } + auto getOrCreatePhaseIfMissing = [this](uint32 phaseId) + { + PhaseInfoStruct* phaseInfo = &_phaseInfoById[phaseId]; + phaseInfo->Id = phaseId; + return phaseInfo; + }; + uint32 count = 0; do { Field* fields = result->Fetch(); - - PhaseInfoStruct phase; uint32 area = fields[0].GetUInt32(); + uint32 phaseId = fields[1].GetUInt32(); + if (!sAreaTableStore.LookupEntry(area)) + { + TC_LOG_ERROR("sql.sql", "Area %u defined in `phase_area` does not exist, skipped.", area); + continue; + } - phase.Id = fields[1].GetUInt32(); - _phases[area].push_back(phase); + if (!sPhaseStore.LookupEntry(phaseId)) + { + TC_LOG_ERROR("sql.sql", "Phase %u defined in `phase_area` does not exist, skipped.", phaseId); + continue; + } + + PhaseInfoStruct* phase = getOrCreatePhaseIfMissing(phaseId); + phase->Areas.insert(area); + _phaseInfoByArea[area].emplace_back(phase); ++count; } while (result->NextRow()); + for (auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr) + { + for (PhaseAreaInfo& phase : itr->second) + { + uint32 parentAreaId = itr->first; + do + { + AreaTableEntry const* area = sAreaTableStore.LookupEntry(parentAreaId); + if (!area) + break; + + parentAreaId = area->zone; + if (!parentAreaId) + break; + + if (std::vector* parentAreaPhases = Trinity::Containers::MapGetValuePtr(_phaseInfoByArea, parentAreaId)) + for (PhaseAreaInfo& parentAreaPhase : *parentAreaPhases) + if (parentAreaPhase.PhaseInfo->Id == phase.PhaseInfo->Id) + parentAreaPhase.SubAreaExclusions.insert(itr->first); + + } while (true); + } + } + TC_LOG_INFO("server.loading", ">> Loaded %u phase areas in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); } +bool PhaseInfoStruct::IsAllowedInArea(uint32 areaId) const +{ + return std::any_of(Areas.begin(), Areas.end(), [areaId](uint32 areaToCheck) + { + return IsInArea(areaId, areaToCheck); + }); +} + +PhaseInfoStruct const* ObjectMgr::GetPhaseInfo(uint32 phaseId) const +{ + return Trinity::Containers::MapGetValuePtr(_phaseInfoById, phaseId); +} + +std::vector const* ObjectMgr::GetPhasesForArea(uint32 areaId) const +{ + return Trinity::Containers::MapGetValuePtr(_phaseInfoByArea, areaId); +} + +TerrainSwapInfo const* ObjectMgr::GetTerrainSwapInfo(uint32 terrainSwapId) const +{ + return Trinity::Containers::MapGetValuePtr(_terrainSwapInfoById, terrainSwapId); +} + +std::vector const* ObjectMgr::GetTerrainSwapsForMap(uint32 mapId) const +{ + return Trinity::Containers::MapGetValuePtr(_terrainSwapInfoByMap, mapId); +} + GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) const { GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 3c16a08136b..7d443adc5f7 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -710,15 +710,28 @@ struct HotfixInfo typedef std::vector HotfixData; +struct TerrainSwapInfo +{ + uint32 Id; + std::vector UiWorldMapAreaIDSwaps; +}; + struct PhaseInfoStruct { uint32 Id; - ConditionContainer Conditions; + std::unordered_set Areas; + + bool IsAllowedInArea(uint32 areaId) const; }; -typedef std::unordered_map> TerrainPhaseInfo; // terrain swap -typedef std::unordered_map> TerrainUIPhaseInfo; // worldmaparea swap -typedef std::unordered_map> PhaseInfo; // phase +struct PhaseAreaInfo +{ + PhaseAreaInfo(PhaseInfoStruct const* phaseInfo) : PhaseInfo(phaseInfo) { } + + PhaseInfoStruct const* PhaseInfo; + std::unordered_set SubAreaExclusions; + ConditionContainer Conditions; +}; class PlayerDumpReader; @@ -843,7 +856,7 @@ class TC_GAME_API ObjectMgr QuestGreeting const* GetQuestGreeting(ObjectGuid guid) const; WorldSafeLocsEntry const* GetDefaultGraveYard(uint32 team) const; - WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) const; + WorldSafeLocsEntry const* GetClosestGraveYard(WorldLocation const& location, uint32 team, WorldObject* conditionObject) const; bool AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = true); void RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = false); void LoadGraveyardZones(); @@ -1066,7 +1079,8 @@ class TC_GAME_API ObjectMgr void LoadTrainerSpell(); void AddSpellToTrainer(uint32 ID, uint32 SpellID, uint32 MoneyCost, uint32 ReqSkillLine, uint32 ReqSkillRank, uint32 ReqLevel, uint32 Index); - void LoadTerrainPhaseInfo(); + void LoadPhases(); + void UnloadPhaseConditions(); void LoadTerrainSwapDefaults(); void LoadTerrainWorldMaps(); void LoadAreaPhases(); @@ -1338,36 +1352,6 @@ class TC_GAME_API ObjectMgr return _gossipMenuItemsStore.equal_range(uiMenuId); } - std::vector const* GetPhaseTerrainSwaps(uint32 phaseid) const - { - auto itr = _terrainPhaseInfoStore.find(phaseid); - return itr != _terrainPhaseInfoStore.end() ? &itr->second : nullptr; - } - std::vector const* GetDefaultTerrainSwaps(uint32 mapid) const - { - auto itr = _terrainMapDefaultStore.find(mapid); - return itr != _terrainMapDefaultStore.end() ? &itr->second : nullptr; - } - std::vector const* GetTerrainWorldMaps(uint32 terrainId) const - { - auto itr = _terrainWorldMapStore.find(terrainId); - return itr != _terrainWorldMapStore.end() ? &itr->second : nullptr; - } - std::vector const* GetPhasesForArea(uint32 area) const - { - auto itr = _phases.find(area); - return itr != _phases.end() ? &itr->second : nullptr; - } - TerrainPhaseInfo const& GetDefaultTerrainSwapStore() const { return _terrainMapDefaultStore; } - PhaseInfo const& GetAreaPhases() const { return _phases; } - // condition loading helpers - std::vector* GetPhasesForAreaForLoading(uint32 area) - { - auto itr = _phases.find(area); - return itr != _phases.end() ? &itr->second : nullptr; - } - PhaseInfo& GetAreaPhasesForLoading() { return _phases; } - // for wintergrasp only GraveYardContainer GraveYardStore; @@ -1486,10 +1470,18 @@ class TC_GAME_API ObjectMgr PageTextContainer _pageTextStore; InstanceTemplateContainer _instanceTemplateStore; - TerrainPhaseInfo _terrainPhaseInfoStore; - TerrainPhaseInfo _terrainMapDefaultStore; - TerrainUIPhaseInfo _terrainWorldMapStore; - PhaseInfo _phases; + public: + PhaseInfoStruct const* GetPhaseInfo(uint32 phaseId) const; + std::vector const* GetPhasesForArea(uint32 areaId) const; + TerrainSwapInfo const* GetTerrainSwapInfo(uint32 terrainSwapId) const; + std::vector const* GetTerrainSwapsForMap(uint32 mapId) const; + + private: + std::unordered_map _phaseInfoById; + std::unordered_map _terrainSwapInfoById; + std::unordered_map> _phaseInfoByArea; + std::unordered_map> _terrainSwapInfoByMap; + private: void LoadScripts(ScriptsType type); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 3ff20024d37..4039915efed 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -324,7 +324,7 @@ void MessageDistDelivererToHostile::Visit(PlayerMapType &m) for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { Player* target = iter->GetSource(); - if (!target->IsInPhase(i_phaseMask)) + if (!target->IsInPhase(i_source)) continue; if (target->GetExactDist2dSq(i_source) > i_distSq) @@ -349,7 +349,7 @@ void MessageDistDelivererToHostile::Visit(CreatureMapType &m) for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { Creature* target = iter->GetSource(); - if (!target->IsInPhase(i_phaseMask)) + if (!target->IsInPhase(i_source)) continue; if (target->GetExactDist2dSq(i_source) > i_distSq) @@ -371,7 +371,7 @@ void MessageDistDelivererToHostile::Visit(DynamicObjectMapType &m) for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { DynamicObject* target = iter->GetSource(); - if (!target->IsInPhase(i_phaseMask)) + if (!target->IsInPhase(i_source)) continue; if (target->GetExactDist2dSq(i_source) > i_distSq) diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 688f100e408..b24efc2cfa6 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -24,6 +24,7 @@ #include "Log.h" #include "ObjectMgr.h" #include "Pet.h" +#include "PhasingHandler.h" #include "Player.h" #include "SocialMgr.h" #include "SpellAuras.h" @@ -984,8 +985,6 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke if (mask == GROUP_UPDATE_FLAG_NONE) return; - std::set const& phases = player->GetPhases(); - if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); @@ -1207,12 +1206,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke } if (mask & GROUP_UPDATE_FLAG_PHASE) - { - *data << uint32(phases.empty() ? 8 : 0); - *data << uint32(phases.size()); - for (std::set::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - *data << uint16(*itr); - } + PhasingHandler::FillPartyMemberPhase(data, player->GetPhaseShift()); } /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ @@ -1236,7 +1230,6 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); - std::set const& phases = player->GetPhases(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related @@ -1257,7 +1250,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; - if (!phases.empty()) + if (!player->GetPhaseShift().GetPhases().empty()) updateFlags |= GROUP_UPDATE_FLAG_PHASE; uint16 playerStatus = MEMBER_STATUS_ONLINE; @@ -1385,12 +1378,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); if (updateFlags & GROUP_UPDATE_FLAG_PHASE) - { - data << uint32(phases.empty() ? 8 : 0); - data << uint32(phases.size()); - for (std::set::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - data << uint16(*itr); - } + PhasingHandler::FillPartyMemberPhase(&data, player->GetPhaseShift()); SendPacket(&data); } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index b7b0c0dede4..7fda4c868bc 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -732,15 +732,15 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) player->SendTransferAborted(entry->MapID, TRANSFER_ABORT_DIFFICULTY, player->GetDifficulty(entry->IsRaid())); break; case Map::CANNOT_ENTER_NOT_IN_RAID: - if (MapEntry const* entry = sMapStore.LookupEntry(at->target_mapId)) - { - char const* mapName = entry->name; - TC_LOG_DEBUG("maps", "MAP: Player '%s' must be in a raid group to enter instance '%s'", player->GetName().c_str(), mapName); - // probably there must be special opcode, because client has this string constant in GlobalStrings.lua - player->GetSession()->SendAreaTriggerMessage(player->GetSession()->GetTrinityString(LANG_INSTANCE_RAID_GROUP_ONLY), mapName); - } + { + WorldPacket data(SMSG_RAID_GROUP_ONLY, 4 + 4); + data << uint32(0); + data << uint32(2); // You must be in a raid group to enter this instance. + player->SendDirectMessage(&data); + TC_LOG_DEBUG("maps", "MAP: Player '%s' must be in a raid group to enter instance map %d", player->GetName().c_str(), at->target_mapId); reviveAtTrigger = true; break; + } case Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE: { WorldPacket data(SMSG_CORPSE_NOT_IN_INSTANCE); @@ -1603,54 +1603,6 @@ void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/) SendAccountDataTimes(GLOBAL_CACHE_MASK); } -void WorldSession::SendSetPhaseShift(std::set const& phaseIds, std::set const& terrainswaps, std::set const& worldMapAreaSwaps) -{ - ObjectGuid guid = _player->GetGUID(); - - WorldPacket data(SMSG_SET_PHASE_SHIFT, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseIds.size() + 4 + terrainswaps.size() * 2); - data.WriteBit(guid[2]); - data.WriteBit(guid[3]); - data.WriteBit(guid[1]); - data.WriteBit(guid[6]); - data.WriteBit(guid[4]); - data.WriteBit(guid[5]); - data.WriteBit(guid[0]); - data.WriteBit(guid[7]); - - data.WriteByteSeq(guid[7]); - data.WriteByteSeq(guid[4]); - - data << uint32(worldMapAreaSwaps.size()) * 2; - for (auto mapSwap : worldMapAreaSwaps) - data << uint16(mapSwap); // WorldMapArea.dbc id (controls map display) - - data.WriteByteSeq(guid[1]); - - data << uint32(phaseIds.size() ? 0 : 8); // flags (not phasemask) - - data.WriteByteSeq(guid[2]); - data.WriteByteSeq(guid[6]); - - data << uint32(0); // Inactive terrain swaps - //for (uint8 i = 0; i < inactiveSwapsCount; ++i) - // data << uint16(0); - - data << uint32(phaseIds.size()) * 2; // Phase.dbc ids - for (std::set::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr) - data << uint16(*itr); - - data.WriteByteSeq(guid[3]); - data.WriteByteSeq(guid[0]); - - data << uint32(terrainswaps.size()) * 2; // Active terrain swaps - for (std::set::const_iterator itr = terrainswaps.begin(); itr != terrainswaps.end(); ++itr) - data << uint16(*itr); - - data.WriteByteSeq(guid[5]); - - SendPacket(&data); -} - // Battlefield and Battleground void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData) { diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 354a3376fdf..404f6d5f336 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -373,7 +373,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket) if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater()) { // now client not include swimming flag in case jumping under water - plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); + plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(plrMover->GetPhaseShift(), movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } uint32 mstime = GameTime::GetGameTimeMS(); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 41bbeea9550..676403aa1f1 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -404,8 +404,7 @@ void WorldSession::SendSpiritResurrect() WorldLocation corpseLocation = _player->GetCorpseLocation(); if (_player->HasCorpse()) { - corpseGrave = sObjectMgr->GetClosestGraveYard(corpseLocation.GetPositionX(), corpseLocation.GetPositionY(), - corpseLocation.GetPositionZ(), corpseLocation.GetMapId(), _player->GetTeam()); + corpseGrave = sObjectMgr->GetClosestGraveYard(corpseLocation, _player->GetTeam(), _player); } // now can spawn bones @@ -414,8 +413,7 @@ void WorldSession::SendSpiritResurrect() // teleport to nearest from corpse graveyard, if different from nearest to player ghost if (corpseGrave) { - WorldSafeLocsEntry const* ghostGrave = sObjectMgr->GetClosestGraveYard( - _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetMapId(), _player->GetTeam()); + WorldSafeLocsEntry const* ghostGrave = sObjectMgr->GetClosestGraveYard(*_player, _player->GetTeam(), _player); if (corpseGrave != ghostGrave) _player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 50737883200..618e73295bb 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -266,7 +266,7 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/) mapID = corpseMapEntry->entrance_map; x = corpseMapEntry->entrance_x; y = corpseMapEntry->entrance_y; - z = entranceMap->GetHeight(GetPlayer()->GetPhases(), x, y, MAX_HEIGHT); + z = entranceMap->GetHeight(GetPlayer()->GetPhaseShift(), x, y, MAX_HEIGHT); } } } diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 3a38c41bfae..2290fe42f48 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -27,6 +27,7 @@ #include "Map.h" #include "Player.h" #include "Pet.h" +#include "PhasingHandler.h" #include "WorldSession.h" #include "Opcodes.h" #include "ScriptReloadMgr.h" @@ -713,7 +714,7 @@ void InstanceScript::UpdatePhasing() Map::PlayerList const& players = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()) - player->SendUpdatePhasing(); + PhasingHandler::SendToPlayer(player); } void InstanceScript::UpdateCombatResurrection(uint32 diff) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 22a7bc098df..3a380be38db 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -31,6 +31,7 @@ #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Pet.h" +#include "PhasingHandler.h" #include "ScriptMgr.h" #include "Transport.h" #include "Vehicle.h" @@ -66,6 +67,9 @@ Map::~Map() if (!m_scriptSchedule.empty()) sMapMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size()); + if (m_parentMap == this) + delete m_childTerrainMaps; + MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); } @@ -129,7 +133,7 @@ void Map::LoadMMap(int gx, int gy) if (!DisableMgr::IsPathfindingEnabled(GetId())) return; - bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); + bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap(sWorld->GetDataPath(), GetId(), gx, gy); if (mmapLoadResult) TC_LOG_DEBUG("mmaps", "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); @@ -159,42 +163,65 @@ void Map::LoadVMap(int gx, int gy) void Map::LoadMap(int gx, int gy, bool reload) { - if (i_InstanceId != 0) + LoadMapImpl(this, gx, gy, reload); + for (Map* childBaseMap : *m_childTerrainMaps) + LoadMapImpl(childBaseMap, gx, gy, reload); +} + +void Map::LoadMapImpl(Map* map, int gx, int gy, bool reload) +{ + if (map->i_InstanceId != 0) { - if (GridMaps[gx][gy]) + if (map->GridMaps[gx][gy]) return; // load grid map for base map - if (!m_parentMap->GridMaps[gx][gy]) - m_parentMap->EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); + if (!map->m_parentMap->GridMaps[gx][gy]) + map->m_parentMap->EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); - ((MapInstanced*)(m_parentMap))->AddGridMapReference(GridCoord(gx, gy)); - GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy]; + map->m_parentMap->ToMapInstanced()->AddGridMapReference(GridCoord(gx, gy)); + map->GridMaps[gx][gy] = map->m_parentMap->GridMaps[gx][gy]; return; } - if (GridMaps[gx][gy] && !reload) + if (map->GridMaps[gx][gy] && !reload) return; //map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?) - if (GridMaps[gx][gy]) + if (map->GridMaps[gx][gy]) { - TC_LOG_DEBUG("maps", "Unloading previously loaded map %u before reloading.", GetId()); - sScriptMgr->OnUnloadGridMap(this, GridMaps[gx][gy], gx, gy); + TC_LOG_DEBUG("maps", "Unloading previously loaded map %u before reloading.", map->GetId()); + sScriptMgr->OnUnloadGridMap(map, map->GridMaps[gx][gy], gx, gy); - delete (GridMaps[gx][gy]); - GridMaps[gx][gy]=NULL; + delete map->GridMaps[gx][gy]; + map->GridMaps[gx][gy] = nullptr; } // map file name - std::string fileName = Trinity::StringFormat("%smaps/%03u%02u%02u.map", sWorld->GetDataPath().c_str(), GetId(), gx, gy); + std::string fileName = Trinity::StringFormat("%smaps/%03u%02u%02u.map", sWorld->GetDataPath().c_str(), map->GetId(), gx, gy); TC_LOG_DEBUG("maps", "Loading map %s", fileName.c_str()); // loading data - GridMaps[gx][gy] = new GridMap(); - if (!GridMaps[gx][gy]->loadData(fileName.c_str())) + map->GridMaps[gx][gy] = new GridMap(); + if (!map->GridMaps[gx][gy]->loadData(fileName.c_str())) TC_LOG_ERROR("maps", "Error loading map file: %s", fileName.c_str()); - sScriptMgr->OnLoadGridMap(this, GridMaps[gx][gy], gx, gy); + sScriptMgr->OnLoadGridMap(map, map->GridMaps[gx][gy], gx, gy); +} + +void Map::UnloadMap(Map* map, int gx, int gy) +{ + if (map->i_InstanceId == 0) + { + if (map->GridMaps[gx][gy]) + { + map->GridMaps[gx][gy]->unloadData(); + delete map->GridMaps[gx][gy]; + } + } + else + static_cast(map->m_parentMap)->RemoveGridMapReference(GridCoord(gx, gy)); + + map->GridMaps[gx][gy] = nullptr; } void Map::LoadMapAndVMap(int gx, int gy) @@ -217,10 +244,10 @@ void Map::LoadAllCells() void Map::InitStateMachine() { - si_GridStates[GRID_STATE_INVALID] = new InvalidState; - si_GridStates[GRID_STATE_ACTIVE] = new ActiveState; - si_GridStates[GRID_STATE_IDLE] = new IdleState; - si_GridStates[GRID_STATE_REMOVAL] = new RemovalState; + si_GridStates[GRID_STATE_INVALID] = new InvalidState(); + si_GridStates[GRID_STATE_ACTIVE] = new ActiveState(); + si_GridStates[GRID_STATE_IDLE] = new IdleState(); + si_GridStates[GRID_STATE_REMOVAL] = new RemovalState(); } void Map::DeleteStateMachine() @@ -240,20 +267,32 @@ m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transpo i_gridExpiry(expiry), i_scriptLock(false), _defaultLight(GetDefaultMapLight(id)) { - m_parentMap = (_parent ? _parent : this); - for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) + if (_parent) { - for (unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) + m_parentMap = _parent; + m_childTerrainMaps = m_parentMap->m_childTerrainMaps; + } + else + { + m_parentMap = this; + m_childTerrainMaps = new std::vector(); + } + + for (uint32 x = 0; x < MAX_NUMBER_OF_GRIDS; ++x) + { + for (uint32 y = 0; y < MAX_NUMBER_OF_GRIDS; ++y) { //z code - GridMaps[idx][j] =NULL; - setNGrid(NULL, idx, j); + GridMaps[x][y] = nullptr; + setNGrid(nullptr, x, y); } } //lets initialize visibility distance for map Map::InitVisibilityDistance(); + MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), GetId(), i_InstanceId); + sScriptMgr->OnCreateMap(this); } @@ -536,8 +575,7 @@ bool Map::AddPlayerToMap(Player* player) player->m_clientGUIDs.clear(); player->UpdateObjectVisibility(false); - - player->SendUpdatePhasing(); + PhasingHandler::SendToPlayer(player); if (player->IsAlive()) ConvertCorpseToBones(player->GetGUID()); @@ -600,8 +638,6 @@ bool Map::AddToMap(T* obj) if (obj->isActiveObject()) AddToActive(obj); - obj->RebuildTerrainSwaps(); - //something, such as vehicle, needs to be update immediately //also, trigger needs to cast spell, if not update, cannot see visual obj->UpdateObjectVisibilityOnCreate(); @@ -634,6 +670,7 @@ bool Map::AddToMap(Transport* obj) { UpdateData data(GetId()); obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); + itr->GetSource()->m_visibleTransports.insert(obj->GetGUID()); WorldPacket packet; data.BuildPacket(&packet); itr->GetSource()->SendDirectMessage(&packet); @@ -932,8 +969,13 @@ void Map::RemoveFromMap(Transport* obj, bool remove) WorldPacket packet; data.BuildPacket(&packet); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { if (itr->GetSource()->GetTransport() != obj) + { itr->GetSource()->SendDirectMessage(&packet); + itr->GetSource()->m_visibleTransports.erase(obj->GetGUID()); + } + } } if (_transportsUpdateIter != _transports.end()) @@ -1596,20 +1638,16 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) // delete grid map, but don't delete if it is from parent map (and thus only reference) //+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps { + for (Map* childBaseMap : *m_childTerrainMaps) + UnloadMap(childBaseMap, gx, gy); + + UnloadMap(this, gx, gy); + if (i_InstanceId == 0) { - if (GridMaps[gx][gy]) - { - GridMaps[gx][gy]->unloadData(); - delete GridMaps[gx][gy]; - } VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gx, gy); MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId(), gx, gy); } - else - ((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridCoord(gx, gy)); - - GridMaps[gx][gy] = NULL; } TC_LOG_DEBUG("maps", "Unloading grid[%u, %u] for map %u finished", x, y, GetId()); return true; @@ -1693,6 +1731,7 @@ GridMap::GridMap() _liquidEntry = nullptr; _liquidFlags = nullptr; _liquidMap = nullptr; + _fileExists = false; } GridMap::~GridMap() @@ -1711,6 +1750,8 @@ bool GridMap::loadData(const char* filename) if (!in) return true; + _fileExists = true; + if (fread(&header, sizeof(header), 1, in) != 1) { fclose(in); @@ -1765,6 +1806,7 @@ void GridMap::unloadData() _liquidFlags = nullptr; _liquidMap = nullptr; _gridGetHeight = &GridMap::getHeightFromFlat; + _fileExists = false; } bool GridMap::loadAreaData(FILE* in, uint32 offset, uint32 /*size*/) @@ -2239,18 +2281,44 @@ inline GridMap* Map::GetGrid(float x, float y) return GridMaps[gx][gy]; } -float Map::GetWaterOrGroundLevel(std::set const& phases, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const +GridMap* Map::GetGrid(uint32 mapId, float x, float y) +{ + if (GetId() == mapId) + return GetGrid(x, y); + + // half opt method + int gx = (int)(CENTER_GRID_ID - x / SIZE_OF_GRIDS); //grid x + int gy = (int)(CENTER_GRID_ID - y / SIZE_OF_GRIDS); //grid y + + // ensure GridMap is loaded + EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); + + GridMap* grid = GridMaps[gx][gy]; + auto childMapItr = std::find_if(m_childTerrainMaps->begin(), m_childTerrainMaps->end(), [mapId](Map* childTerrainMap) { return childTerrainMap->GetId() == mapId; }); + if (childMapItr != m_childTerrainMaps->end() && (*childMapItr)->GridMaps[gx][gy]->fileExists()) + grid = (*childMapItr)->GridMaps[gx][gy]; + + return grid; +} + +bool Map::HasGrid(uint32 mapId, int32 gx, int32 gy) const +{ + auto childMapItr = std::find_if(m_childTerrainMaps->begin(), m_childTerrainMaps->end(), [mapId](Map* childTerrainMap) { return childTerrainMap->GetId() == mapId; }); + return childMapItr != m_childTerrainMaps->end() && (*childMapItr)->GridMaps[gx][gy] && (*childMapItr)->GridMaps[gx][gy]->fileExists(); +} + +float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const { if (const_cast(this)->GetGrid(x, y)) { // we need ground level (including grid height version) for proper return water level in point - float ground_z = GetHeight(phases, x, y, z, true, 50.0f); + float ground_z = GetHeight(phaseShift, x, y, z, true, 50.0f); if (ground) *ground = ground_z; LiquidData liquid_status; - ZLiquidStatus res = GetLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status); + ZLiquidStatus res = GetLiquidStatus(phaseShift, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status); switch (res) { case LIQUID_MAP_ABOVE_WATER: @@ -2265,11 +2333,12 @@ float Map::GetWaterOrGroundLevel(std::set const& phases, float x, float return VMAP_INVALID_HEIGHT_VALUE; } -float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const +float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const { // find raw .map surface under Z coordinates float mapHeight = VMAP_INVALID_HEIGHT_VALUE; - if (GridMap* gmap = const_cast(this)->GetGrid(x, y)) + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y); + if (GridMap* gmap = const_cast(this)->GetGrid(terrainMapId, x, y)) { float gridHeight = gmap->getHeight(x, y); // look from a bit higher pos to find the floor, ignore under surface case @@ -2282,7 +2351,7 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float { VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); if (vmgr->isHeightCalcEnabled()) - vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor + vmapHeight = vmgr->getHeight(terrainMapId, x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor } // mapHeight set for any above raw ground Z or <= INVALID_HEIGHT @@ -2331,13 +2400,13 @@ inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, in return outdoor; } -bool Map::IsOutdoors(float x, float y, float z) const +bool Map::IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const { uint32 mogpFlags; int32 adtId, rootId, groupId; // no wmo found? -> outside by default - if (!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) + if (!GetAreaInfo(phaseShift, x, y, z, mogpFlags, adtId, rootId, groupId)) return true; AreaTableEntry const* atEntry = nullptr; @@ -2350,14 +2419,15 @@ bool Map::IsOutdoors(float x, float y, float z) const return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry); } -bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const +bool Map::GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const { float vmap_z = z; + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y); VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); - if (vmgr->getAreaInfo(GetId(), x, y, vmap_z, flags, adtId, rootId, groupId)) + if (vmgr->getAreaInfo(terrainMapId, x, y, vmap_z, flags, adtId, rootId, groupId)) { // check if there's terrain between player height and object height - if (GridMap* gmap = const_cast(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast(this)->GetGrid(terrainMapId, x, y)) { float _mapheight = gmap->getHeight(x, y); // z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice... @@ -2369,29 +2439,31 @@ bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, in return false; } -uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const +uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors) const { uint32 mogpFlags; int32 adtId, rootId, groupId; WMOAreaTableEntry const* wmoEntry = nullptr; AreaTableEntry const* atEntry = nullptr; bool haveAreaInfo = false; + uint32 areaId = 0; - if (GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) + if (GetAreaInfo(phaseShift, x, y, z, mogpFlags, adtId, rootId, groupId)) { haveAreaInfo = true; wmoEntry = GetWMOAreaTableEntryByTripple(rootId, adtId, groupId); if (wmoEntry) + { + areaId = wmoEntry->areaId; atEntry = sAreaTableStore.LookupEntry(wmoEntry->areaId); + + } } - uint32 areaId = 0; - if (atEntry) - areaId = atEntry->ID; - else + if (!areaId) { - if (GridMap* gmap = const_cast(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast(this)->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y)) areaId = gmap->getArea(x, y); // this used while not all *.map files generated (instances) @@ -2409,9 +2481,9 @@ uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const return areaId; } -uint32 Map::GetZoneId(float x, float y, float z) const +uint32 Map::GetZoneId(PhaseShift const& phaseShift, float x, float y, float z) const { - uint32 areaId = GetAreaId(x, y, z); + uint32 areaId = GetAreaId(phaseShift, x, y, z); if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId)) if (area->zone) return area->zone; @@ -2419,30 +2491,31 @@ uint32 Map::GetZoneId(float x, float y, float z) const return areaId; } -void Map::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const +void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z) const { - areaid = zoneid = GetAreaId(x, y, z); + areaid = zoneid = GetAreaId(phaseShift, x, y, z); if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaid)) if (area->zone) zoneid = area->zone; } -uint8 Map::GetTerrainType(float x, float y) const +uint8 Map::GetTerrainType(PhaseShift const& phaseShift, float x, float y) const { - if (GridMap* gmap = const_cast(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast(this)->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y)) return gmap->getTerrainType(x, y); else return 0; } -ZLiquidStatus Map::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const +ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const { ZLiquidStatus result = LIQUID_MAP_NO_WATER; VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); float liquid_level = INVALID_HEIGHT; float ground_level = INVALID_HEIGHT; uint32 liquid_type = 0; - if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y); + if (vmgr->GetLiquidLevel(terrainMapId, x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) { TC_LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type); // Check water level and ground level @@ -2461,7 +2534,7 @@ ZLiquidStatus Map::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp if (liquid_type && liquid_type < 21) { - if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(x, y, z))) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(phaseShift, x, y, z))) { uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType]; if (!overrideLiquid && area->zone) @@ -2499,7 +2572,7 @@ ZLiquidStatus Map::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp } } - if (GridMap* gmap = const_cast(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast(this)->GetGrid(terrainMapId, x, y)) { LiquidData map_data; ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data); @@ -2520,16 +2593,17 @@ ZLiquidStatus Map::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp return result; } -void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType) const +void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType) const { VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); VMAP::AreaAndLiquidData vmapData; - vmgr->getAreaAndLiquidData(GetId(), x, y, z, reqLiquidType, vmapData); + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y); + vmgr->getAreaAndLiquidData(terrainMapId, x, y, z, reqLiquidType, vmapData); if (vmapData.areaInfo) data.areaInfo = boost::in_place(vmapData.areaInfo->adtId, vmapData.areaInfo->rootId, vmapData.areaInfo->groupId, vmapData.areaInfo->mogpFlags); float mapHeight = VMAP_INVALID_HEIGHT; - GridMap* gmap = const_cast(this)->GetGrid(x, y); + GridMap* gmap = const_cast(this)->GetGrid(terrainMapId, x, y); if (gmap) mapHeight = gmap->getHeight(x, y); @@ -2621,32 +2695,32 @@ void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFul } } -float Map::GetWaterLevel(float x, float y) const +float Map::GetWaterLevel(PhaseShift const& phaseShift, float x, float y) const { - if (GridMap* gmap = const_cast(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast(this)->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y)) return gmap->getLiquidLevel(x, y); else return 0; } -bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, std::set const& phases, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const +bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const { if ((checks & LINEOFSIGHT_CHECK_VMAP) - && !VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2, ignoreFlags)) + && !VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(PhasingHandler::GetTerrainMapId(phaseShift, this, x1, y1), x1, y1, z1, x2, y2, z2, ignoreFlags)) return false; if (sWorld->getBoolConfig(CONFIG_CHECK_GOBJECT_LOS) && (checks & LINEOFSIGHT_CHECK_GOBJECT) - && !_dynamicTree.isInLineOfSight({x1, y1, z1}, {x2, y2, z2}, phases)) + && !_dynamicTree.isInLineOfSight({x1, y1, z1}, {x2, y2, z2}, phaseShift)) return false; return true; } -bool Map::getObjectHitPos(std::set const& phases, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) +bool Map::getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) { G3D::Vector3 startPos(x1, y1, z1); G3D::Vector3 dstPos(x2, y2, z2); G3D::Vector3 resultPos; - bool result = _dynamicTree.getObjectHitPos(phases, startPos, dstPos, resultPos, modifyDist); + bool result = _dynamicTree.getObjectHitPos(startPos, dstPos, resultPos, modifyDist, phaseShift); rx = resultPos.x; ry = resultPos.y; @@ -2654,21 +2728,21 @@ bool Map::getObjectHitPos(std::set const& phases, float x1, float y1, fl return result; } -float Map::GetHeight(std::set const& phases, float x, float y, float z, bool vmap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const +float Map::GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const { - return std::max(GetHeight(x, y, z, vmap, maxSearchDist), GetGameObjectFloor(phases, x, y, z, maxSearchDist)); + return std::max(GetStaticHeight(phaseShift, x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift)); } -bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const +bool Map::IsInWater(PhaseShift const& phaseShift, float x, float y, float pZ, LiquidData* data) const { LiquidData liquid_status; LiquidData* liquid_ptr = data ? data : &liquid_status; - return (GetLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0; + return (GetLiquidStatus(phaseShift, x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0; } -bool Map::IsUnderWater(float x, float y, float z) const +bool Map::IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const { - return (GetLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0; + return (GetLiquidStatus(phaseShift, x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0; } bool Map::CheckGridIntegrity(Creature* c, bool moved) const @@ -2703,6 +2777,7 @@ void Map::SendInitSelf(Player* player) if (Transport* transport = player->GetTransport()) { transport->BuildCreateUpdateBlockForPlayer(&data, player); + player->m_visibleTransports.insert(transport->GetGUID()); } // build data for self presence in world at own client (one time for map) @@ -2710,9 +2785,9 @@ void Map::SendInitSelf(Player* player) // build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map if (Transport* transport = player->GetTransport()) - for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr) - if (player != (*itr) && player->HaveAtClient(*itr)) - (*itr)->BuildCreateUpdateBlockForPlayer(&data, player); + for (WorldObject* passenger : transport->GetPassengers()) + if (player != passenger && player->HaveAtClient(passenger)) + passenger->BuildCreateUpdateBlockForPlayer(&data, player); WorldPacket packet; data.BuildPacket(&packet); @@ -2723,9 +2798,14 @@ void Map::SendInitTransports(Player* player) { // Hack to send out transports UpdateData transData(player->GetMapId()); - for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i) - if (*i != player->GetTransport() && player->IsInPhase(*i)) - (*i)->BuildCreateUpdateBlockForPlayer(&transData, player); + for (Transport* transport : _transports) + { + if (transport != player->GetTransport() && player->IsInPhase(transport)) + { + transport->BuildCreateUpdateBlockForPlayer(&transData, player); + player->m_visibleTransports.insert(transport->GetGUID()); + } + } WorldPacket packet; transData.BuildPacket(&packet); @@ -2736,28 +2816,40 @@ void Map::SendRemoveTransports(Player* player) { // Hack to send out transports UpdateData transData(player->GetMapId()); - for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i) - if (*i != player->GetTransport()) - (*i)->BuildOutOfRangeUpdateBlock(&transData); + for (Transport* transport : _transports) + { + if (transport != player->GetTransport()) + { + transport->BuildOutOfRangeUpdateBlock(&transData); + player->m_visibleTransports.erase(transport->GetGUID()); + } + } WorldPacket packet; transData.BuildPacket(&packet); player->GetSession()->SendPacket(&packet); } -void Map::SendUpdateTransportVisibility(Player* player, std::set const& previousPhases) +void Map::SendUpdateTransportVisibility(Player* player) { // Hack to send out transports UpdateData transData(player->GetMapId()); - for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i) + for (Transport* transport : _transports) { - if (*i == player->GetTransport()) - continue; - - if (player->IsInPhase(*i) && !Trinity::Containers::Intersects(previousPhases.begin(), previousPhases.end(), (*i)->GetPhases().begin(), (*i)->GetPhases().end())) - (*i)->BuildCreateUpdateBlockForPlayer(&transData, player); - else if (!player->IsInPhase(*i)) - (*i)->BuildOutOfRangeUpdateBlock(&transData); + auto transportItr = player->m_visibleTransports.find(transport->GetGUID()); + if (player->IsInPhase(transport)) + { + if (transportItr == player->m_visibleTransports.end()) + { + transport->BuildCreateUpdateBlockForPlayer(&transData, player); + player->m_visibleTransports.insert(transport->GetGUID()); + } + } + else if (transportItr != player->m_visibleTransports.end()) + { + transport->BuildOutOfRangeUpdateBlock(&transData); + player->m_visibleTransports.erase(transportItr); + } } WorldPacket packet; @@ -3775,8 +3867,8 @@ void Map::LoadCorpseData() continue; } - for (auto phaseId : phases[guid]) - corpse->SetInPhase(phaseId, false, true); + for (uint32 phaseId : phases[guid]) + PhasingHandler::AddPhase(corpse, phaseId, false); AddCorpse(corpse); } while (result->NextRow()); @@ -3861,7 +3953,7 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i)) bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0); - bones->CopyPhaseFrom(corpse); + PhasingHandler::InheritPhaseShift(bones, corpse); AddCorpse(bones); @@ -3903,7 +3995,7 @@ void Map::RemoveOldCorpses() void Map::SendZoneDynamicInfo(Player* player) { - uint32 zoneId = GetZoneId(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + uint32 zoneId = GetZoneId(player->GetPhaseShift(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); ZoneDynamicInfoMap::const_iterator itr = _zoneDynamicInfo.find(zoneId); if (itr == _zoneDynamicInfo.end()) return; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index d42cb18a6ee..5eb6502032a 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -42,6 +42,7 @@ class InstanceScript; class Group; class InstanceSave; class Object; +class PhaseShift; class WorldObject; class TempSummon; class Player; @@ -214,7 +215,7 @@ class TC_GAME_API GridMap uint8 _liquidOffY; uint8 _liquidWidth; uint8 _liquidHeight; - + bool _fileExists; bool loadAreaData(FILE* in, uint32 offset, uint32 size); bool loadHeightData(FILE* in, uint32 offset, uint32 size); @@ -239,6 +240,7 @@ public: float getLiquidLevel(float x, float y) const; uint8 getTerrainType(float x, float y) const; ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0); + bool fileExists() const { return _fileExists; } }; #pragma pack(push, 1) @@ -348,6 +350,7 @@ class TC_GAME_API Map : public GridRefManager time_t GetGridExpiry(void) const { return i_gridExpiry; } uint32 GetId(void) const { return i_mapEntry->MapID; } + bool HasGrid(uint32 mapId, int32 gx, int32 gy) const; static bool ExistMap(uint32 mapid, int gx, int gy); static bool ExistVMap(uint32 mapid, int gx, int gy); @@ -355,25 +358,27 @@ class TC_GAME_API Map : public GridRefManager static void DeleteStateMachine(); Map const* GetParent() const { return m_parentMap; } + void AddChildTerrainMap(Map* map) { m_childTerrainMaps->push_back(map); } + void UnlinkAllChildTerrainMaps() { m_childTerrainMaps->clear(); } // some calls like isInWater should not use vmaps due to processor power // can return INVALID_HEIGHT if under z+2 z coord not found height - float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; + float GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; - void GetFullTerrainStatusForPosition(float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS) const; - ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const; + void GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS) const; + ZLiquidStatus GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const; - bool GetAreaInfo(float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const; - uint32 GetAreaId(float x, float y, float z, bool *isOutdoors = nullptr) const; - uint32 GetZoneId(float x, float y, float z) const; - void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const; + bool GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const; + uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors = nullptr) const; + uint32 GetZoneId(PhaseShift const& phaseShift, float x, float y, float z) const; + void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z) const; - bool IsOutdoors(float x, float y, float z) const; + bool IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const; - uint8 GetTerrainType(float x, float y) const; - float GetWaterLevel(float x, float y) const; - bool IsInWater(float x, float y, float z, LiquidData* data = nullptr) const; - bool IsUnderWater(float x, float y, float z) const; + uint8 GetTerrainType(PhaseShift const& phaseShift, float x, float y) const; + float GetWaterLevel(PhaseShift const& phaseShift, float x, float y) const; + bool IsInWater(PhaseShift const& phaseShift, float x, float y, float z, LiquidData* data = nullptr) const; + bool IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const; void MoveAllCreaturesInMoveList(); void MoveAllGameObjectsInMoveList(); @@ -514,18 +519,18 @@ class TC_GAME_API Map : public GridRefManager BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast(this); else return NULL; } BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast(this); return NULL; } - float GetWaterOrGroundLevel(std::set const& phases, float x, float y, float z, float* ground = nullptr, bool swim = false) const; - float GetHeight(std::set const& phases, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; - bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, std::set const& phases, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const; + float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false) const; + float GetHeight(PhaseShift const& phaseShifts, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; + bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const; void Balance() { _dynamicTree.balance(); } void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); } void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); } bool ContainsGameObjectModel(const GameObjectModel& model) const { return _dynamicTree.contains(model);} - float GetGameObjectFloor(std::set phases, float x, float y, float z, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const + float GetGameObjectFloor(PhaseShift const& phaseShift, float x, float y, float z, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { - return _dynamicTree.getHeight(x, y, z, maxSearchDist, phases); + return _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift); } - bool getObjectHitPos(std::set const& phases, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist); + bool getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist); virtual uint32 GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return 0; } /* @@ -568,7 +573,7 @@ class TC_GAME_API Map : public GridRefManager void SendInitTransports(Player* player); void SendRemoveTransports(Player* player); - void SendUpdateTransportVisibility(Player* player, std::set const& previousPhases); + void SendUpdateTransportVisibility(Player* player); void SendZoneDynamicInfo(Player* player); void SetZoneMusic(uint32 zoneId, uint32 musicId); @@ -606,8 +611,11 @@ class TC_GAME_API Map : public GridRefManager void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); void LoadMap(int gx, int gy, bool reload = false); + static void LoadMapImpl(Map* map, int gx, int gy, bool reload); + static void UnloadMap(Map* map, int gx, int gy); void LoadMMap(int gx, int gy); GridMap* GetGrid(float x, float y); + GridMap* GetGrid(uint32 mapId, float x, float y); void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; } @@ -654,8 +662,6 @@ class TC_GAME_API Map : public GridRefManager void setNGrid(NGridType* grid, uint32 x, uint32 y); void ScriptsProcess(); - void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff); - void SendObjectUpdates(); protected: @@ -700,6 +706,7 @@ class TC_GAME_API Map : public GridRefManager //used for fast base_map (e.g. MapInstanced class object) search for //InstanceMaps and BattlegroundMaps... Map* m_parentMap; + std::vector* m_childTerrainMaps; NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; GridMap* GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index a3bf5179a61..f34349496d0 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -56,10 +56,15 @@ void MapManager::Initialize() m_updater.activate(num_threads); } +void MapManager::InitializeParentMapData(std::unordered_map> const& mapData) +{ + _parentMapData = mapData; +} + void MapManager::InitializeVisibilityDistanceInfo() { - for (MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) - (*iter).second->InitVisibilityDistance(); + for (auto iter = i_maps.begin(); iter != i_maps.end(); ++iter) + iter->second->InitVisibilityDistance(); } MapManager* MapManager::instance() @@ -72,29 +77,46 @@ Map* MapManager::CreateBaseMap(uint32 id) { Map* map = FindBaseMap(id); - if (map == NULL) + if (!map) { - std::lock_guard lock(_mapsLock); - - MapEntry const* entry = sMapStore.LookupEntry(id); - ASSERT(entry); - - if (entry->Instanceable()) - map = new MapInstanced(id, i_gridCleanUpDelay); - else + MapEntry const* entry = sMapStore.AssertEntry(id); + if (entry->rootPhaseMap != -1) { - map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); - map->LoadRespawnTimes(); - map->LoadCorpseData(); + CreateBaseMap(entry->rootPhaseMap); + + // must have been created by parent map + map = FindBaseMap(id); + return ASSERT_NOTNULL(map); } - i_maps[id] = map; + std::lock_guard lock(_mapsLock); + map = CreateBaseMap_i(entry); } ASSERT(map); return map; } +Map* MapManager::CreateBaseMap_i(MapEntry const* mapEntry) +{ + Map* map; + if (mapEntry->Instanceable()) + map = new MapInstanced(mapEntry->MapID, i_gridCleanUpDelay); + else + { + map = new Map(mapEntry->MapID, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); + map->LoadRespawnTimes(); + map->LoadCorpseData(); + } + + i_maps[mapEntry->MapID] = map; + + for (uint32 childMapId : _parentMapData[mapEntry->MapID]) + map->AddChildTerrainMap(CreateBaseMap_i(sMapStore.AssertEntry(childMapId))); + + return map; +} + Map* MapManager::FindBaseNonInstanceMap(uint32 mapId) const { Map* map = FindBaseMap(mapId); @@ -258,6 +280,10 @@ bool MapManager::IsValidMAP(uint32 mapid, bool startUp) void MapManager::UnloadAll() { + // first unlink child maps + for (auto iter = i_maps.begin(); iter != i_maps.end(); ++iter) + iter->second->UnlinkAllChildTerrainMaps(); + for (MapMapType::iterator iter = i_maps.begin(); iter != i_maps.end();) { iter->second->UnloadAll(); diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index ca75b7382f3..12cf7c0c9cd 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -26,6 +26,7 @@ #include "MapUpdater.h" #include +class PhaseShift; class Transport; struct TransportCreatureProto; @@ -39,23 +40,24 @@ class TC_GAME_API MapManager Map* CreateMap(uint32 mapId, Player* player, uint32 loginInstanceId=0); Map* FindMap(uint32 mapId, uint32 instanceId) const; - uint32 GetAreaId(uint32 mapid, float x, float y, float z) const + uint32 GetAreaId(PhaseShift const& phaseShift, uint32 mapid, float x, float y, float z) const { Map const* m = const_cast(this)->CreateBaseMap(mapid); - return m->GetAreaId(x, y, z); + return m->GetAreaId(phaseShift, x, y, z); } - uint32 GetZoneId(uint32 mapid, float x, float y, float z) const + uint32 GetZoneId(PhaseShift const& phaseShift, uint32 mapid, float x, float y, float z) const { Map const* m = const_cast(this)->CreateBaseMap(mapid); - return m->GetZoneId(x, y, z); + return m->GetZoneId(phaseShift, x, y, z); } - void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) + void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) { Map const* m = const_cast(this)->CreateBaseMap(mapid); - m->GetZoneAndAreaId(zoneid, areaid, x, y, z); + m->GetZoneAndAreaId(phaseShift, zoneid, areaid, x, y, z); } void Initialize(void); + void InitializeParentMapData(std::unordered_map> const& mapData); void Update(uint32); void SetGridCleanUpDelay(uint32 t) @@ -142,8 +144,10 @@ class TC_GAME_API MapManager return (iter == i_maps.end() ? NULL : iter->second); } - MapManager(const MapManager &); - MapManager& operator=(const MapManager &); + Map* CreateBaseMap_i(MapEntry const* mapEntry); + + MapManager(MapManager const&) = delete; + MapManager& operator=(MapManager const&) = delete; std::mutex _mapsLock; uint32 i_gridCleanUpDelay; @@ -156,6 +160,9 @@ class TC_GAME_API MapManager // atomic op counter for active scripts amount std::atomic _scheduledScripts; + + // parent map links + std::unordered_map> _parentMapData; }; template diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index cd3bdb5902c..7f260e42639 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -20,6 +20,7 @@ #include "InstanceScript.h" #include "MoveSpline.h" #include "MapManager.h" +#include "PhasingHandler.h" TransportTemplate::~TransportTemplate() { @@ -354,7 +355,7 @@ void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, animNode.Path[timeSeg] = node; } -Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= NULL*/, uint32 phaseid /*= 0*/, uint32 phasegroup /*= 0*/) +Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= nullptr*/, uint8 phaseUseFlags /*= 0*/, uint32 phaseId /*= 0*/, uint32 phaseGroupId /*= 0*/) { // instance case, execute GetGameObjectEntry hook if (map) @@ -395,12 +396,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid return NULL; } - if (phaseid) - trans->SetInPhase(phaseid, false, true); - - if (phasegroup) - for (auto ph : GetPhasesForGroup(phasegroup)) - trans->SetInPhase(ph, false, true); + PhasingHandler::InitDbPhaseShift(trans->GetPhaseShift(), phaseUseFlags, phaseId, phaseGroupId); if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId)) { @@ -431,7 +427,7 @@ void TransportMgr::SpawnContinentTransports() uint32 oldMSTime = getMSTime(); - QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseid, phasegroup FROM transports"); + QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseUseFlags, phaseid, phasegroup FROM transports"); uint32 count = 0; if (result) @@ -441,12 +437,50 @@ void TransportMgr::SpawnContinentTransports() Field* fields = result->Fetch(); ObjectGuid::LowType guid = fields[0].GetUInt32(); uint32 entry = fields[1].GetUInt32(); - uint32 phaseid = fields[2].GetUInt32(); - uint32 phasegroup = fields[3].GetUInt32(); + uint8 phaseUseFlags = fields[2].GetUInt8(); + uint32 phaseId = fields[3].GetUInt32(); + uint32 phaseGroupId = fields[4].GetUInt32(); + + if (phaseUseFlags & ~PHASE_USE_FLAGS_ALL) + { + TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: %u Entry: %u) with unknown `phaseUseFlags` set, removed unknown value.", guid, entry); + phaseUseFlags &= PHASE_USE_FLAGS_ALL; + } + + if (phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && phaseUseFlags & PHASE_USE_FLAGS_INVERSE) + { + TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: %u Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE," + " removing PHASE_USE_FLAGS_INVERSE.", guid, entry); + phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE; + } + + if (phaseGroupId && phaseId) + { + TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, entry); + phaseGroupId = 0; + } + + if (phaseId) + { + if (!sPhaseStore.LookupEntry(phaseId)) + { + TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: %u Entry: %u) with `phaseid` %u does not exist, set to 0", guid, entry, phaseId); + phaseId = 0; + } + } + + if (phaseGroupId) + { + if (!GetPhasesForGroup(phaseGroupId)) + { + TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: %u Entry: %u) with `phaseGroup` %u does not exist, set to 0", guid, entry, phaseGroupId); + phaseGroupId = 0; + } + } if (TransportTemplate const* tInfo = GetTransportTemplate(entry)) if (!tInfo->inInstance) - if (CreateTransport(entry, guid, nullptr, phaseid, phasegroup)) + if (CreateTransport(entry, guid, nullptr, phaseUseFlags, phaseId, phaseGroupId)) ++count; } while (result->NextRow()); diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index 4038d213b38..14025b0fc3c 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -108,7 +108,7 @@ class TC_GAME_API TransportMgr void LoadTransportTemplates(); // Creates a transport using given GameObject template entry - Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = nullptr, uint32 phaseid = 0, uint32 phasegroup = 0); + Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = nullptr, uint8 phaseUseFlags = 0, uint32 phaseId = 0, uint32 phaseGroupId = 0); // Spawns all continent transports, used at core startup void SpawnContinentTransports(); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index d4440de644d..51792371ab0 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -213,7 +213,13 @@ enum TrinityStrings LANG_INVALID_GAMEOBJECT_TYPE = 176, LANG_GAMEOBJECT_DAMAGED = 177, LANG_GRID_POSITION = 178, - // 179-185 used in 6.x branch + LANG_PHASESHIFT_STATUS = 179, + LANG_PHASESHIFT_PHASES = 180, + LANG_PHASESHIFT_VISIBLE_MAP_IDS = 181, + LANG_PHASESHIFT_UI_WORLD_MAP_AREA_SWAPS = 182, + LANG_PHASE_FLAG_COSMETIC = 183, + LANG_PHASE_FLAG_PERSONAL = 184, + // 185 not used LANG_TRANSPORT_POSITION = 186, LANG_PARTIAL_GROUP_SUMMON = 187, // Room for more level 1 188-199 not used @@ -975,7 +981,7 @@ enum TrinityStrings LANG_COMMAND_NO_FROZEN_PLAYERS = 5004, LANG_COMMAND_LIST_FREEZE = 5005, LANG_COMMAND_PERMA_FROZEN_PLAYER = 5006, - LANG_INSTANCE_RAID_GROUP_ONLY = 5007, + // = 5007, unused LANG_INSTANCE_CLOSED = 5008, LANG_COMMAND_PLAYED_TO_ALL = 5009, LANG_NPCINFO_LINKGUID = 5010, diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 0a0a0a90399..418d0ff945c 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -486,7 +486,7 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool if (_owner->IsFlying()) point.z = z; else - point.z = _owner->GetMap()->GetHeight(_owner->GetPhases(), point.x, point.y, z); + point.z = _owner->GetMap()->GetHeight(_owner->GetPhaseShift(), point.x, point.y, z); init.Path().push_back(point); } @@ -569,7 +569,7 @@ void MotionMaster::ResumeSplineChain(SplineChainResumeInfo const& info) void MotionMaster::MoveFall(uint32 id /*=0*/) { // use larger distance for vmap height search than in most other cases - float tz = _owner->GetMap()->GetHeight(_owner->GetPhases(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE); + float tz = _owner->GetMap()->GetHeight(_owner->GetPhaseShift(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE); if (tz <= INVALID_HEIGHT) { TC_LOG_DEBUG("misc", "MotionMaster::MoveFall: unable to retrieve a proper height at map %u (x: %f, y: %f, z: %f).", diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 8fdbd03ec86..0de1fd19870 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -24,6 +24,7 @@ #include "PathGenerator.h" #include "MoveSplineInit.h" #include "MoveSpline.h" +#include "PhasingHandler.h" #include "FleeingMovementGenerator.h" #define MIN_QUIET_DISTANCE 28.0f @@ -115,8 +116,13 @@ void FleeingMovementGenerator::SetTargetLocation(T* owner) GetPoint(owner, destination); // Add LOS check for target point - Position currentPosition = owner->GetPosition(); - if (!VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetMapId(), currentPosition.m_positionX, currentPosition.m_positionY, currentPosition.m_positionZ + 1.0f, destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ() + 1.0f, VMAP::ModelIgnoreFlags::Nothing)) + Position mypos = owner->GetPosition(); + bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight( + PhasingHandler::GetTerrainMapId(owner->GetPhaseShift(), owner->GetMap(), mypos.m_positionX, mypos.m_positionY), + mypos.m_positionX, mypos.m_positionY, mypos.m_positionZ + 2.0f, destination.m_positionX, destination.m_positionY, + destination.m_positionZ + 2.0f, VMAP::ModelIgnoreFlags::Nothing); + + if (!isInLOS) { _timer.Reset(200); return; diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index d2379f806a6..8bd2b5dc9ea 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -63,7 +63,7 @@ void RandomMovementGenerator::_setRandomLocation(Creature* creature) // Limit height change const float distanceZ = float(rand_norm()) * travelDistZ/2.0f; destZ = respZ + distanceZ; - float levelZ = map->GetWaterOrGroundLevel(creature->GetPhases(), destX, destY, destZ-2.5f); + float levelZ = map->GetWaterOrGroundLevel(creature->GetPhaseShift(), destX, destY, destZ-2.5f); // Problem here, we must fly above the ground and water, not under. Let's try on next tick if (levelZ >= destZ) @@ -77,17 +77,17 @@ void RandomMovementGenerator::_setRandomLocation(Creature* creature) // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. - destZ = map->GetHeight(creature->GetPhases(), destX, destY, respZ+travelDistZ-2.0f, false); + destZ = map->GetHeight(creature->GetPhaseShift(), destX, destY, respZ+travelDistZ-2.0f, false); if (std::fabs(destZ - respZ) > travelDistZ) // Map check { // Vmap Horizontal or above - destZ = map->GetHeight(creature->GetPhases(), destX, destY, respZ - 2.0f, true); + destZ = map->GetHeight(creature->GetPhaseShift(), destX, destY, respZ - 2.0f, true); if (std::fabs(destZ - respZ) > travelDistZ) { // Vmap Higher - destZ = map->GetHeight(creature->GetPhases(), destX, destY, respZ+travelDistZ-2.0f, true); + destZ = map->GetHeight(creature->GetPhaseShift(), destX, destY, respZ+travelDistZ-2.0f, true); // let's forget this bad coords where a z cannot be find and retry at next tick if (std::fabs(destZ - respZ) > travelDistZ) diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index f5e603e25d6..d2b413ca0c1 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -72,10 +72,7 @@ bool TargetedMovementGenerator::DoUpdate(T* owner, uint32 diff) transport->CalculatePassengerPosition(destination.x, destination.y, destination.z); // First check distance - if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly()) - targetMoved = !GetTarget()->IsInDist(destination.x, destination.y, destination.z, distance); - else - targetMoved = !GetTarget()->IsInDist2d(destination.x, destination.y, distance); + targetMoved = !GetTarget()->IsInDist(destination.x, destination.y, destination.z, distance); // then, if the target is in range, check also Line of Sight. if (!targetMoved) diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 694c350b81b..f8b12913984 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -27,6 +27,7 @@ #include "DetourCommon.h" #include "DetourNavMeshQuery.h" #include "Metric.h" +#include "PhasingHandler.h" ////////////////// PathGenerator ////////////////// PathGenerator::PathGenerator(const Unit* owner) : @@ -39,12 +40,12 @@ PathGenerator::PathGenerator(const Unit* owner) : TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUID().GetCounter()); - uint32 mapId = _sourceUnit->GetMapId(); - if (DisableMgr::IsPathfindingEnabled(mapId)) + uint32 mapId = PhasingHandler::GetTerrainMapId(_sourceUnit->GetPhaseShift(), _sourceUnit->GetMap(), _sourceUnit->GetPositionX(), _sourceUnit->GetPositionY()); + if (DisableMgr::IsPathfindingEnabled(_sourceUnit->GetMapId())) { MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); - _navMesh = mmap->GetNavMesh(mapId, _sourceUnit->GetTerrainSwaps()); - _navMeshQuery = mmap->GetNavMeshQuery(mapId, _sourceUnit->GetInstanceId(), _sourceUnit->GetTerrainSwaps()); + _navMesh = mmap->GetNavMesh(mapId); + _navMeshQuery = mmap->GetNavMeshQuery(mapId, _sourceUnit->GetInstanceId()); } CreateFilter(); @@ -185,7 +186,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con // Check both start and end points, if they're both in water, then we can *safely* let the creature move for (uint32 i = 0; i < _pathPoints.size(); ++i) { - ZLiquidStatus status = _sourceUnit->GetBaseMap()->GetLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); + ZLiquidStatus status = _sourceUnit->GetBaseMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); // One of the points is not in the water, cancel movement. if (status == LIQUID_MAP_NO_WATER) { @@ -211,7 +212,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con Creature* owner = (Creature*)_sourceUnit; G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos; - if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) + if (_sourceUnit->GetBaseMap()->IsUnderWater(_sourceUnit->GetPhaseShift(), p.x, p.y, p.z)) { TC_LOG_DEBUG("maps", "++ BuildPolyPath :: underWater case\n"); if (owner->CanSwim()) @@ -648,7 +649,7 @@ void PathGenerator::UpdateFilter() NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) { LiquidData data; - ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); + ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &data); if (liquidStatus == LIQUID_MAP_NO_WATER) return NAV_GROUND; diff --git a/src/server/game/Phasing/PhaseShift.cpp b/src/server/game/Phasing/PhaseShift.cpp new file mode 100644 index 00000000000..b2885ae15bb --- /dev/null +++ b/src/server/game/Phasing/PhaseShift.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2008-2018 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "PhaseShift.h" +#include "Containers.h" + +bool PhaseShift::AddPhase(uint32 phaseId, PhaseFlags flags, std::vector const* areaConditions, int32 references /*= 1*/) +{ + auto insertResult = Phases.emplace(phaseId, flags, nullptr); + ModifyPhasesReferences(insertResult.first, references); + if (areaConditions) + insertResult.first->AreaConditions = areaConditions; + + return insertResult.second; +} + +PhaseShift::EraseResult PhaseShift::RemovePhase(uint32 phaseId) +{ + auto itr = Phases.find(PhaseRef(phaseId, PhaseFlags::None, nullptr)); + if (itr != Phases.end()) + { + ModifyPhasesReferences(itr, -1); + if (!itr->References) + return { Phases.erase(itr), true }; + return { itr, false }; + } + return { Phases.end(), false }; +} + +bool PhaseShift::AddVisibleMapId(uint32 visibleMapId, TerrainSwapInfo const* visibleMapInfo, int32 references /*= 1*/) +{ + auto insertResult = VisibleMapIds.emplace(visibleMapId, VisibleMapIdRef{ 0, visibleMapInfo }); + insertResult.first->second.References += references; + return insertResult.second; +} + +PhaseShift::EraseResult PhaseShift::RemoveVisibleMapId(uint32 visibleMapId) +{ + auto itr = VisibleMapIds.find(visibleMapId); + if (itr != VisibleMapIds.end()) + { + if (!--itr->second.References) + return { VisibleMapIds.erase(itr), true }; + return { itr, false }; + } + return { VisibleMapIds.end(), false }; +} + +bool PhaseShift::AddUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId, int32 references /*= 1*/) +{ + auto insertResult = UiWorldMapAreaIdSwaps.emplace(uiWorldMapAreaId, UiWorldMapAreaIdSwapRef{ 0 }); + insertResult.first->second.References += references; + return insertResult.second; +} + +PhaseShift::EraseResult PhaseShift::RemoveUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId) +{ + auto itr = UiWorldMapAreaIdSwaps.find(uiWorldMapAreaId); + if (itr != UiWorldMapAreaIdSwaps.end()) + { + if (!--itr->second.References) + return { UiWorldMapAreaIdSwaps.erase(itr), true }; + return { itr, false }; + } + return { UiWorldMapAreaIdSwaps.end(), false }; +} + +void PhaseShift::Clear() +{ + ClearPhases(); + PersonalGuid.Clear(); + VisibleMapIds.clear(); + UiWorldMapAreaIdSwaps.clear(); +} + +void PhaseShift::ClearPhases() +{ + Flags &= EnumClassFlag(PhaseShiftFlags::AlwaysVisible) | PhaseShiftFlags::Inverse; + Phases.clear(); + NonCosmeticReferences = 0; + CosmeticReferences = 0; + DefaultReferences = 0; + UpdateUnphasedFlag(); +} + +bool PhaseShift::CanSee(PhaseShift const& other) const +{ + if (Flags.HasFlag(PhaseShiftFlags::Unphased) && other.Flags.HasFlag(PhaseShiftFlags::Unphased)) + return true; + if (Flags.HasFlag(PhaseShiftFlags::AlwaysVisible) || other.Flags.HasFlag(PhaseShiftFlags::AlwaysVisible)) + return true; + if (Flags.HasFlag(PhaseShiftFlags::Inverse) && other.Flags.HasFlag(PhaseShiftFlags::Inverse)) + return true; + + PhaseFlags excludePhasesWithFlag = PhaseFlags::None; + if (Flags.HasFlag(PhaseShiftFlags::NoCosmetic) && other.Flags.HasFlag(PhaseShiftFlags::NoCosmetic)) + excludePhasesWithFlag = PhaseFlags::Cosmetic; + + if (!Flags.HasFlag(PhaseShiftFlags::Inverse) && !other.Flags.HasFlag(PhaseShiftFlags::Inverse)) + { + ObjectGuid ownerGuid = PersonalGuid; + ObjectGuid otherPersonalGuid = other.PersonalGuid; + return Trinity::Containers::Intersects(Phases.begin(), Phases.end(), other.Phases.begin(), other.Phases.end(), + [&ownerGuid, &otherPersonalGuid, excludePhasesWithFlag](PhaseRef const& myPhase, PhaseRef const& /*otherPhase*/) + { + return !myPhase.Flags.HasFlag(excludePhasesWithFlag) && (!myPhase.Flags.HasFlag(PhaseFlags::Personal) || ownerGuid == otherPersonalGuid); + }); + } + + auto checkInversePhaseShift = [excludePhasesWithFlag](PhaseShift const& phaseShift, PhaseShift const& excludedPhaseShift) + { + if (phaseShift.Flags.HasFlag(PhaseShiftFlags::Unphased) && !excludedPhaseShift.Flags.HasFlag(PhaseShiftFlags::InverseUnphased)) + return true; + + for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end(); ++itr) + { + if (itr->Flags.HasFlag(excludePhasesWithFlag)) + continue; + + auto itr2 = std::find(excludedPhaseShift.Phases.begin(), excludedPhaseShift.Phases.end(), *itr); + if (itr2 == excludedPhaseShift.Phases.end() || itr2->Flags.HasFlag(excludePhasesWithFlag)) + return true; + } + + return false; + }; + + if (other.Flags.HasFlag(PhaseShiftFlags::Inverse)) + return checkInversePhaseShift(*this, other); + + return checkInversePhaseShift(other, *this); +} + +void PhaseShift::ModifyPhasesReferences(PhaseContainer::iterator itr, int32 references) +{ + itr->References += references; + + if (!IsDbPhaseShift) + { + if (itr->Flags.HasFlag(PhaseFlags::Cosmetic)) + CosmeticReferences += references; + else if (itr->Id != DEFAULT_PHASE) + NonCosmeticReferences += references; + else + DefaultReferences += references; + + if (CosmeticReferences) + Flags |= PhaseShiftFlags::NoCosmetic; + else + Flags &= ~EnumClassFlag(PhaseShiftFlags::NoCosmetic); + + UpdateUnphasedFlag(); + } +} + +void PhaseShift::UpdateUnphasedFlag() +{ + EnumClassFlag unphasedFlag = !Flags.HasFlag(PhaseShiftFlags::Inverse) ? PhaseShiftFlags::Unphased : PhaseShiftFlags::InverseUnphased; + Flags &= ~EnumClassFlag(!Flags.HasFlag(PhaseShiftFlags::Inverse) ? PhaseShiftFlags::InverseUnphased : PhaseShiftFlags::Unphased); + if (NonCosmeticReferences && !DefaultReferences) + Flags &= ~unphasedFlag; + else + Flags |= unphasedFlag; +} diff --git a/src/server/game/Phasing/PhaseShift.h b/src/server/game/Phasing/PhaseShift.h new file mode 100644 index 00000000000..8755868ae9d --- /dev/null +++ b/src/server/game/Phasing/PhaseShift.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2008-2018 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef PhaseShift_h__ +#define PhaseShift_h__ + +#include "Define.h" +#include "EnumClassFlag.h" +#include "ObjectGuid.h" +#include +#include + +class PhasingHandler; +struct Condition; +struct TerrainSwapInfo; + +#define DEFAULT_PHASE 169 + +enum class PhaseShiftFlags : uint32 +{ + None = 0x00, + AlwaysVisible = 0x01, // Ignores all phasing, can see everything and be seen by everything + Inverse = 0x02, // By default having at least one shared phase for two objects means they can see each other + // this flag makes objects see each other if they have at least one non-shared phase + InverseUnphased = 0x04, + Unphased = 0x08, + NoCosmetic = 0x10 // This flag ignores shared cosmetic phases (two players that both have shared cosmetic phase but no other phase cannot see each other) +}; + +enum class PhaseFlags : uint16 +{ + None = 0x0, + Cosmetic = 0x1, + Personal = 0x2 +}; + +class TC_GAME_API PhaseShift +{ +public: + struct PhaseRef + { + PhaseRef(uint32 id, PhaseFlags flags, std::vector const* conditions) + : Id(id), Flags(flags), References(0), AreaConditions(conditions) { } + + uint16 Id; + EnumClassFlag Flags; + int32 References; + std::vector const* AreaConditions; + bool operator<(PhaseRef const& right) const { return Id < right.Id; } + bool operator==(PhaseRef const& right) const { return Id == right.Id; } + }; + struct VisibleMapIdRef + { + int32 References = 0; + TerrainSwapInfo const* VisibleMapInfo = nullptr; + }; + struct UiWorldMapAreaIdSwapRef + { + int32 References = 0; + }; + template + struct EraseResult + { + typename Container::iterator Iterator; + bool Erased; + }; + typedef boost::container::flat_set PhaseContainer; + typedef std::map VisibleMapIdContainer; + typedef std::map UiWorldMapAreaIdSwapContainer; + + bool AddPhase(uint32 phaseId, PhaseFlags flags, std::vector const* areaConditions, int32 references = 1); + EraseResult RemovePhase(uint32 phaseId); + bool HasPhase(uint32 phaseId) const { return Phases.find(PhaseRef(phaseId, PhaseFlags::None, nullptr)) != Phases.end(); } + PhaseContainer const& GetPhases() const { return Phases; } + + bool AddVisibleMapId(uint32 visibleMapId, TerrainSwapInfo const* visibleMapInfo, int32 references = 1); + EraseResult RemoveVisibleMapId(uint32 visibleMapId); + bool HasVisibleMapId(uint32 visibleMapId) const { return VisibleMapIds.find(visibleMapId) != VisibleMapIds.end(); } + VisibleMapIdContainer const& GetVisibleMapIds() const { return VisibleMapIds; } + + bool AddUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId, int32 references = 1); + EraseResult RemoveUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId); + bool HasUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId) const { return UiWorldMapAreaIdSwaps.find(uiWorldMapAreaId) != UiWorldMapAreaIdSwaps.end(); } + UiWorldMapAreaIdSwapContainer const& GetUiWorldMapAreaIdSwaps() const { return UiWorldMapAreaIdSwaps; } + + void Clear(); + void ClearPhases(); + + bool CanSee(PhaseShift const& other) const; + +protected: + friend class PhasingHandler; + + EnumClassFlag Flags = PhaseShiftFlags::Unphased; + ObjectGuid PersonalGuid; + PhaseContainer Phases; + VisibleMapIdContainer VisibleMapIds; + UiWorldMapAreaIdSwapContainer UiWorldMapAreaIdSwaps; + + void ModifyPhasesReferences(PhaseContainer::iterator itr, int32 references); + void UpdateUnphasedFlag(); + int32 NonCosmeticReferences = 0; + int32 CosmeticReferences = 0; + int32 DefaultReferences = 0; + bool IsDbPhaseShift = false; +}; + +#endif // PhaseShift_h__ diff --git a/src/server/game/Phasing/PhasingHandler.cpp b/src/server/game/Phasing/PhasingHandler.cpp new file mode 100644 index 00000000000..bd65b93175a --- /dev/null +++ b/src/server/game/Phasing/PhasingHandler.cpp @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2008-2018 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "PhasingHandler.h" +#include "Chat.h" +#include "ConditionMgr.h" +#include "Creature.h" +#include "DBCStores.h" +#include "Language.h" +#include "Map.h" +#include "ObjectMgr.h" +#include "PhaseShift.h" +#include "Player.h" +#include "SpellAuraEffects.h" + +namespace +{ +PhaseShift const Empty; + +inline PhaseFlags GetPhaseFlags(uint32 phaseId) +{ + if (PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId)) + { + if (phase->Flags & PHASE_FLAG_COSMETIC) + return PhaseFlags::Cosmetic; + + if (phase->Flags & PHASE_FLAG_PERSONAL) + return PhaseFlags::Personal; + } + + return PhaseFlags::None; +} + +template +inline void ForAllControlled(Unit* unit, Func&& func) +{ + for (Unit* controlled : unit->m_Controlled) + if (controlled->GetTypeId() != TYPEID_PLAYER) + func(controlled); + + for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i) + if (!unit->m_SummonSlot[i].IsEmpty()) + if (Creature* summon = unit->GetMap()->GetCreature(unit->m_SummonSlot[i])) + func(summon); +} +} + +void PhasingHandler::AddPhase(WorldObject* object, uint32 phaseId, bool updateVisibility) +{ + bool changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr); + + if (Unit* unit = object->ToUnit()) + { + unit->OnPhaseChange(); + ForAllControlled(unit, [&](Unit* controlled) + { + AddPhase(controlled, phaseId, updateVisibility); + }); + unit->RemoveNotOwnSingleTargetAuras(true); + } + + UpdateVisibilityIfNeeded(object, updateVisibility, changed); +} + +void PhasingHandler::RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility) +{ + bool changed = object->GetPhaseShift().RemovePhase(phaseId).Erased; + + if (Unit* unit = object->ToUnit()) + { + unit->OnPhaseChange(); + ForAllControlled(unit, [&](Unit* controlled) + { + RemovePhase(controlled, phaseId, updateVisibility); + }); + unit->RemoveNotOwnSingleTargetAuras(true); + } + + UpdateVisibilityIfNeeded(object, updateVisibility, changed); +} + +void PhasingHandler::AddPhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility) +{ + std::vector const* phasesInGroup = GetPhasesForGroup(phaseGroupId); + if (!phasesInGroup) + return; + + bool changed = false; + for (uint32 phaseId : *phasesInGroup) + changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed; + + if (Unit* unit = object->ToUnit()) + { + unit->OnPhaseChange(); + ForAllControlled(unit, [&](Unit* controlled) + { + AddPhaseGroup(controlled, phaseGroupId, updateVisibility); + }); + unit->RemoveNotOwnSingleTargetAuras(true); + } + + UpdateVisibilityIfNeeded(object, updateVisibility, changed); +} + +void PhasingHandler::RemovePhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility) +{ + std::vector const* phasesInGroup = GetPhasesForGroup(phaseGroupId); + if (!phasesInGroup) + return; + + bool changed = false; + for (uint32 phaseId : *phasesInGroup) + changed = object->GetPhaseShift().RemovePhase(phaseId).Erased || changed; + + if (Unit* unit = object->ToUnit()) + { + unit->OnPhaseChange(); + ForAllControlled(unit, [&](Unit* controlled) + { + RemovePhaseGroup(controlled, phaseGroupId, updateVisibility); + }); + unit->RemoveNotOwnSingleTargetAuras(true); + } + + UpdateVisibilityIfNeeded(object, updateVisibility, changed); +} + +void PhasingHandler::AddVisibleMapId(WorldObject* object, uint32 visibleMapId) +{ + TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId); + bool changed = object->GetPhaseShift().AddVisibleMapId(visibleMapId, terrainSwapInfo); + + for (uint32 uiWorldMapAreaIDSwap : terrainSwapInfo->UiWorldMapAreaIDSwaps) + changed = object->GetPhaseShift().AddUiWorldMapAreaIdSwap(uiWorldMapAreaIDSwap) || changed; + + if (Unit* unit = object->ToUnit()) + { + ForAllControlled(unit, [&](Unit* controlled) + { + AddVisibleMapId(controlled, visibleMapId); + }); + } + + UpdateVisibilityIfNeeded(object, false, changed); +} + +void PhasingHandler::RemoveVisibleMapId(WorldObject* object, uint32 visibleMapId) +{ + TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId); + bool changed = object->GetPhaseShift().RemoveVisibleMapId(visibleMapId).Erased; + + for (uint32 uiWorldMapAreaIDSwap : terrainSwapInfo->UiWorldMapAreaIDSwaps) + changed = object->GetPhaseShift().RemoveUiWorldMapAreaIdSwap(uiWorldMapAreaIDSwap).Erased || changed; + + if (Unit* unit = object->ToUnit()) + { + ForAllControlled(unit, [&](Unit* controlled) + { + RemoveVisibleMapId(controlled, visibleMapId); + }); + } + + UpdateVisibilityIfNeeded(object, false, changed); +} + +void PhasingHandler::ResetPhaseShift(WorldObject* object) +{ + object->GetPhaseShift().Clear(); + object->GetSuppressedPhaseShift().Clear(); +} + +void PhasingHandler::InheritPhaseShift(WorldObject* target, WorldObject const* source) +{ + if (!source) + return; + + target->GetPhaseShift() = source->GetPhaseShift(); + target->GetSuppressedPhaseShift() = source->GetSuppressedPhaseShift(); +} + +void PhasingHandler::OnMapChange(WorldObject* object) +{ + PhaseShift& phaseShift = object->GetPhaseShift(); + PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift(); + ConditionSourceInfo srcInfo = ConditionSourceInfo(object); + + object->GetPhaseShift().VisibleMapIds.clear(); + object->GetPhaseShift().UiWorldMapAreaIdSwaps.clear(); + object->GetSuppressedPhaseShift().VisibleMapIds.clear(); + + if (std::vector const* visibleMapIds = sObjectMgr->GetTerrainSwapsForMap(object->GetMapId())) + { + for (TerrainSwapInfo const* visibleMapInfo : *visibleMapIds) + { + if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, visibleMapInfo->Id, srcInfo)) + { + phaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo); + for (uint32 uiWorldMapAreaIdSwap : visibleMapInfo->UiWorldMapAreaIDSwaps) + phaseShift.AddUiWorldMapAreaIdSwap(uiWorldMapAreaIdSwap); + } + else + suppressedPhaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo); + } + } + + UpdateVisibilityIfNeeded(object, false, true); +} + +void PhasingHandler::OnAreaChange(WorldObject* object) +{ + PhaseShift& phaseShift = object->GetPhaseShift(); + PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift(); + PhaseShift::PhaseContainer oldPhases = std::move(phaseShift.Phases); // for comparison + ConditionSourceInfo srcInfo = ConditionSourceInfo(object); + + object->GetPhaseShift().ClearPhases(); + object->GetSuppressedPhaseShift().ClearPhases(); + + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(object->GetAreaId()); + while (areaEntry) + { + if (std::vector const* newAreaPhases = sObjectMgr->GetPhasesForArea(areaEntry->ID)) + { + for (PhaseAreaInfo const& phaseArea : *newAreaPhases) + { + if (phaseArea.SubAreaExclusions.find(areaEntry->ID) != phaseArea.SubAreaExclusions.end()) + continue; + + uint32 phaseId = phaseArea.PhaseInfo->Id; + if (sConditionMgr->IsObjectMeetToConditions(srcInfo, phaseArea.Conditions)) + phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), &phaseArea.Conditions); + else + suppressedPhaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), &phaseArea.Conditions); + } + } + + areaEntry = sAreaTableStore.LookupEntry(areaEntry->zone); + } + + bool changed = phaseShift.Phases != oldPhases; + if (Unit* unit = object->ToUnit()) + { + for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE)) + { + uint32 phaseId = uint32(aurEff->GetMiscValueB()); + changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed; + } + + for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP)) + if (std::vector const* phasesInGroup = GetPhasesForGroup(uint32(aurEff->GetMiscValueB()))) + for (uint32 phaseId : *phasesInGroup) + changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed; + + if (changed) + unit->OnPhaseChange(); + + ForAllControlled(unit, [&](Unit* controlled) + { + InheritPhaseShift(controlled, unit); + }); + + if (changed) + unit->RemoveNotOwnSingleTargetAuras(true); + } + + UpdateVisibilityIfNeeded(object, true, changed); +} + +void PhasingHandler::OnConditionChange(WorldObject* object) +{ + PhaseShift& phaseShift = object->GetPhaseShift(); + PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift(); + PhaseShift newSuppressions; + ConditionSourceInfo srcInfo = ConditionSourceInfo(object); + bool changed = false; + + for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end();) + { + if (itr->AreaConditions && !sConditionMgr->IsObjectMeetToConditions(srcInfo, *itr->AreaConditions)) + { + newSuppressions.AddPhase(itr->Id, itr->Flags, itr->AreaConditions, itr->References); + itr = phaseShift.Phases.erase(itr); + } + else + ++itr; + } + + for (auto itr = suppressedPhaseShift.Phases.begin(); itr != suppressedPhaseShift.Phases.end();) + { + if (sConditionMgr->IsObjectMeetToConditions(srcInfo, *ASSERT_NOTNULL(itr->AreaConditions))) + { + changed = phaseShift.AddPhase(itr->Id, itr->Flags, itr->AreaConditions, itr->References) || changed; + itr = suppressedPhaseShift.Phases.erase(itr); + } + else + ++itr; + } + + for (auto itr = phaseShift.VisibleMapIds.begin(); itr != phaseShift.VisibleMapIds.end();) + { + if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo)) + { + newSuppressions.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References); + for (uint32 uiWorldMapAreaIdSwap : itr->second.VisibleMapInfo->UiWorldMapAreaIDSwaps) + changed = phaseShift.RemoveUiWorldMapAreaIdSwap(uiWorldMapAreaIdSwap).Erased || changed; + + itr = phaseShift.VisibleMapIds.erase(itr); + } + else + ++itr; + } + + for (auto itr = suppressedPhaseShift.VisibleMapIds.begin(); itr != suppressedPhaseShift.VisibleMapIds.end();) + { + if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo)) + { + changed = phaseShift.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References) || changed; + for (uint32 uiWorldMapAreaIdSwap : itr->second.VisibleMapInfo->UiWorldMapAreaIDSwaps) + changed = phaseShift.AddUiWorldMapAreaIdSwap(uiWorldMapAreaIdSwap) || changed; + + itr = suppressedPhaseShift.VisibleMapIds.erase(itr); + } + else + ++itr; + } + + Unit* unit = object->ToUnit(); + if (unit) + { + for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE)) + { + uint32 phaseId = uint32(aurEff->GetMiscValueB()); + auto eraseResult = newSuppressions.RemovePhase(phaseId); + // if condition was met previously there is nothing to erase + if (eraseResult.Iterator != newSuppressions.Phases.end() || eraseResult.Erased) + phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr); + } + + for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP)) + { + if (std::vector const* phasesInGroup = GetPhasesForGroup(uint32(aurEff->GetMiscValueB()))) + { + for (uint32 phaseId : *phasesInGroup) + { + auto eraseResult = newSuppressions.RemovePhase(phaseId); + // if condition was met previously there is nothing to erase + if (eraseResult.Iterator != newSuppressions.Phases.end() || eraseResult.Erased) + phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr); + } + } + } + } + + changed = changed || !newSuppressions.Phases.empty() || !newSuppressions.VisibleMapIds.empty(); + for (auto itr = newSuppressions.Phases.begin(); itr != newSuppressions.Phases.end(); ++itr) + suppressedPhaseShift.AddPhase(itr->Id, itr->Flags, itr->AreaConditions, itr->References); + + for (auto itr = newSuppressions.VisibleMapIds.begin(); itr != newSuppressions.VisibleMapIds.end(); ++itr) + suppressedPhaseShift.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References); + + if (unit) + { + if (changed) + unit->OnPhaseChange(); + + ForAllControlled(unit, [&](Unit* controlled) + { + InheritPhaseShift(controlled, unit); + }); + + if (changed) + unit->RemoveNotOwnSingleTargetAuras(true); + } + + UpdateVisibilityIfNeeded(object, true, changed); +} + +void PhasingHandler::SendToPlayer(Player const* player, PhaseShift const& phaseShift) +{ + ObjectGuid guid = player->GetGUID(); + + WorldPacket data(SMSG_SET_PHASE_SHIFT, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseShift.Phases.size() + 4 + phaseShift.VisibleMapIds.size() * 2); + data.WriteBit(guid[2]); + data.WriteBit(guid[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[6]); + data.WriteBit(guid[4]); + data.WriteBit(guid[5]); + data.WriteBit(guid[0]); + data.WriteBit(guid[7]); + + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[4]); + + data << uint32(phaseShift.UiWorldMapAreaIdSwaps.size()) * 2; + for (auto itr = phaseShift.UiWorldMapAreaIdSwaps.begin(); itr != phaseShift.UiWorldMapAreaIdSwaps.end(); ++itr) + data << uint16(itr->first); // WorldMapArea.dbc id (controls map display) + + data.WriteByteSeq(guid[1]); + + data << uint32(phaseShift.Flags.AsUnderlyingType()); // flags + + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[6]); + + data << uint32(0); // Inactive terrain swaps + //for (uint8 i = 0; i < inactiveSwapsCount; ++i) + // data << uint16(0); + + data << uint32(phaseShift.Phases.size()) * 2; // Phase.dbc ids + for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end(); ++itr) + data << uint16(itr->Id); + + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[0]); + + data << uint32(phaseShift.VisibleMapIds.size()) * 2; // Active terrain swaps + for (auto itr = phaseShift.VisibleMapIds.begin(); itr != phaseShift.VisibleMapIds.end(); ++itr) + data << uint16(itr->first); + + data.WriteByteSeq(guid[5]); + + player->SendDirectMessage(&data); +} + +void PhasingHandler::SendToPlayer(Player const* player) +{ + SendToPlayer(player, player->GetPhaseShift()); +} + +void PhasingHandler::FillPartyMemberPhase(WorldPacket* data, PhaseShift const& phaseShift) +{ + *data << uint32(phaseShift.Flags.AsUnderlyingType()); + *data << uint32(phaseShift.Phases.size()); + for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end(); ++itr) + *data << uint16(itr->Id); +} + +PhaseShift const& PhasingHandler::GetEmptyPhaseShift() +{ + return Empty; +} + +void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId) +{ + phaseShift.IsDbPhaseShift = true; + + EnumClassFlag flags = PhaseShiftFlags::None; + if (phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE) + flags = flags | PhaseShiftFlags::AlwaysVisible | PhaseShiftFlags::Unphased; + if (phaseUseFlags & PHASE_USE_FLAGS_INVERSE) + flags |= PhaseShiftFlags::Inverse; + + if (phaseId) + phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr); + else if (std::vector const* phasesInGroup = GetPhasesForGroup(phaseGroupId)) + for (uint32 phaseInGroup : *phasesInGroup) + phaseShift.AddPhase(phaseInGroup, GetPhaseFlags(phaseInGroup), nullptr); + + if (phaseShift.Phases.empty() || phaseShift.HasPhase(DEFAULT_PHASE)) + { + if (flags.HasFlag(PhaseShiftFlags::Inverse)) + flags |= PhaseShiftFlags::InverseUnphased; + else + flags |= PhaseShiftFlags::Unphased; + } + + phaseShift.Flags = flags; +} + +void PhasingHandler::InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId) +{ + phaseShift.VisibleMapIds.clear(); + if (visibleMapId != -1) + phaseShift.AddVisibleMapId(visibleMapId, sObjectMgr->GetTerrainSwapInfo(visibleMapId)); +} + +bool PhasingHandler::InDbPhaseShift(WorldObject const* object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId) +{ + PhaseShift phaseShift; + InitDbPhaseShift(phaseShift, phaseUseFlags, phaseId, phaseGroupId); + return object->GetPhaseShift().CanSee(phaseShift); +} + +uint32 PhasingHandler::GetTerrainMapId(PhaseShift const& phaseShift, Map const* map, float x, float y) +{ + if (phaseShift.VisibleMapIds.empty()) + return map->GetId(); + + if (phaseShift.VisibleMapIds.size() == 1) + return phaseShift.VisibleMapIds.begin()->first; + + GridCoord gridCoord = Trinity::ComputeGridCoord(x, y); + int32 gx = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.x_coord; + int32 gy = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.y_coord; + + int32 gxbegin = std::max(gx - 1, 0); + int32 gxend = std::min(gx + 1, MAX_NUMBER_OF_GRIDS); + int32 gybegin = std::max(gy - 1, 0); + int32 gyend = std::min(gy + 1, MAX_NUMBER_OF_GRIDS); + + for (auto itr = phaseShift.VisibleMapIds.rbegin(); itr != phaseShift.VisibleMapIds.rend(); ++itr) + for (int32 gxi = gxbegin; gxi < gxend; ++gxi) + for (int32 gyi = gybegin; gyi < gyend; ++gyi) + if (map->HasGrid(itr->first, gxi, gyi)) + return itr->first; + + return map->GetId(); +} + +void PhasingHandler::SetAlwaysVisible(PhaseShift& phaseShift, bool apply) +{ + if (apply) + phaseShift.Flags |= PhaseShiftFlags::AlwaysVisible; + else + phaseShift.Flags &= ~EnumClassFlag(PhaseShiftFlags::AlwaysVisible); +} + +void PhasingHandler::SetInversed(PhaseShift& phaseShift, bool apply) +{ + if (apply) + phaseShift.Flags |= PhaseShiftFlags::Inverse; + else + phaseShift.Flags &= ~EnumClassFlag(PhaseShiftFlags::Inverse); + + phaseShift.UpdateUnphasedFlag(); +} + +void PhasingHandler::PrintToChat(ChatHandler* chat, PhaseShift const& phaseShift) +{ + chat->PSendSysMessage(LANG_PHASESHIFT_STATUS, phaseShift.Flags.AsUnderlyingType(), phaseShift.PersonalGuid.ToString().c_str()); + if (!phaseShift.Phases.empty()) + { + std::ostringstream phases; + std::string cosmetic = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_COSMETIC, chat->GetSessionDbLocaleIndex()); + std::string personal = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_PERSONAL, chat->GetSessionDbLocaleIndex()); + for (PhaseShift::PhaseRef const& phase : phaseShift.Phases) + { + phases << phase.Id; + if (phase.Flags.HasFlag(PhaseFlags::Cosmetic)) + phases << ' ' << '(' << cosmetic << ')'; + if (phase.Flags.HasFlag(PhaseFlags::Personal)) + phases << ' ' << '(' << personal << ')'; + phases << ", "; + } + + chat->PSendSysMessage(LANG_PHASESHIFT_PHASES, phases.str().c_str()); + } + + if (!phaseShift.VisibleMapIds.empty()) + { + std::ostringstream visibleMapIds; + for (PhaseShift::VisibleMapIdContainer::value_type const& visibleMapId : phaseShift.VisibleMapIds) + visibleMapIds << visibleMapId.first << ',' << ' '; + + chat->PSendSysMessage(LANG_PHASESHIFT_VISIBLE_MAP_IDS, visibleMapIds.str().c_str()); + } + + if (!phaseShift.UiWorldMapAreaIdSwaps.empty()) + { + std::ostringstream uiWorldMapAreaIdSwaps; + for (PhaseShift::UiWorldMapAreaIdSwapContainer::value_type const& uiWorldMapAreaIdSwap : phaseShift.UiWorldMapAreaIdSwaps) + uiWorldMapAreaIdSwaps << uiWorldMapAreaIdSwap.first << ',' << ' '; + + chat->PSendSysMessage(LANG_PHASESHIFT_UI_WORLD_MAP_AREA_SWAPS, uiWorldMapAreaIdSwaps.str().c_str()); + } +} + +std::string PhasingHandler::FormatPhases(PhaseShift const& phaseShift) +{ + std::ostringstream phases; + for (PhaseShift::PhaseRef const& phase : phaseShift.Phases) + phases << phase.Id << ','; + + return phases.str(); +} + +void PhasingHandler::UpdateVisibilityIfNeeded(WorldObject* object, bool updateVisibility, bool changed) +{ + if (changed && object->IsInWorld()) + { + if (Player* player = object->ToPlayer()) + SendToPlayer(player); + + if (updateVisibility) + { + if (Player* player = object->ToPlayer()) + player->GetMap()->SendUpdateTransportVisibility(player); + + object->UpdateObjectVisibility(); + } + } +} diff --git a/src/server/game/Phasing/PhasingHandler.h b/src/server/game/Phasing/PhasingHandler.h new file mode 100644 index 00000000000..ba88d2f895d --- /dev/null +++ b/src/server/game/Phasing/PhasingHandler.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008-2018 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef PhasingHandler_h__ +#define PhasingHandler_h__ + +#include "Define.h" +#include + +class ChatHandler; +class Map; +class PhaseShift; +class Player; +class WorldObject; + +class TC_GAME_API PhasingHandler +{ +public: + static void AddPhase(WorldObject* object, uint32 phaseId, bool updateVisibility); + static void RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility); + static void AddPhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility); + static void RemovePhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility); + + static void AddVisibleMapId(WorldObject* object, uint32 visibleMapId); + static void RemoveVisibleMapId(WorldObject* object, uint32 visibleMapId); + + static void ResetPhaseShift(WorldObject* object); + static void InheritPhaseShift(WorldObject* target, WorldObject const* source); + + static void OnMapChange(WorldObject* object); + static void OnAreaChange(WorldObject* object); + static void OnConditionChange(WorldObject* object); + + static void SendToPlayer(Player const* player, PhaseShift const& phaseShift); + static void SendToPlayer(Player const* player); + static void FillPartyMemberPhase(WorldPacket* data, PhaseShift const& phaseShift); + + static PhaseShift const& GetEmptyPhaseShift(); + static void InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId); + static void InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId); + static bool InDbPhaseShift(WorldObject const* object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId); + + static uint32 GetTerrainMapId(PhaseShift const& phaseShift, Map const* map, float x, float y); + + static void SetAlwaysVisible(PhaseShift& phaseShift, bool apply); + static void SetInversed(PhaseShift& phaseShift, bool apply); + + static void PrintToChat(ChatHandler* chat, PhaseShift const& phaseShift); + static std::string FormatPhases(PhaseShift const& phaseShift); + +private: + static void UpdateVisibilityIfNeeded(WorldObject* object, bool updateVisibility, bool changed); +}; + +#endif // PhasingHandler_h__ diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index f7b34b5e249..8ac314fc552 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -298,7 +298,6 @@ class TC_GAME_API WorldSession void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName); void SendPartyResult(PartyOperation operation, std::string const& member, PartyResult res, uint32 val = 0); void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3); - void SendSetPhaseShift(std::set const& phaseIds, std::set const& terrainswaps, std::set const& worldMapAreaSwaps); void SendQueryTimeResponse(); void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0); diff --git a/src/server/game/Skills/Archaeology/ArchaeologySites.cpp b/src/server/game/Skills/Archaeology/ArchaeologySites.cpp index 23be86a883f..ec1edcf7ba3 100644 --- a/src/server/game/Skills/Archaeology/ArchaeologySites.cpp +++ b/src/server/game/Skills/Archaeology/ArchaeologySites.cpp @@ -119,7 +119,7 @@ void Archaeology::UseSite() float x = _player->GetPositionX() + cos(o) * 2.0f; float y = _player->GetPositionY() + sin(o) * 2.0f; float z = _player->GetPositionZ(); - float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhases(), x, y, z, &ground, _player->IsInWater()); + float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhaseShift(), x, y, z, &ground, _player->IsInWater()); G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(angle, 0.f, 0.f); if (std::abs(z - ground) < 1.5f) @@ -140,7 +140,7 @@ void Archaeology::UseSite() float x = _player->GetPositionX() + cos(o) * 2.0f; float y = _player->GetPositionY() + sin(o) * 2.0f; float z = _player->GetPositionZ(); - float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhases(), x, y, z, &ground, _player->IsInWater()); + float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhaseShift(), x, y, z, &ground, _player->IsInWater()); // Spawn object _player->SummonGameObject(goId, Position(x, y, ground, o), G3D::Quat(), 60); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index fc4f8f0ff2f..9c972139b44 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -22,6 +22,7 @@ #include "Log.h" #include "ObjectMgr.h" #include "SpellMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "Unit.h" #include "ObjectAccessor.h" @@ -1703,27 +1704,17 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app Unit* target = aurApp->GetTarget(); - std::set const& oldPhases = target->GetPhases(); - target->SetInPhase(GetMiscValueB(), false, apply); - - // call functions which may have additional effects after chainging state of unit - // phase auras normally not expected at BG but anyway better check if (apply) { + PhasingHandler::AddPhase(target, uint32(GetMiscValueB()), true); + + // call functions which may have additional effects after chainging state of unit + // phase auras normally not expected at BG but anyway better check // drop flag at invisibiliy in bg target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } - - if (Player* player = target->ToPlayer()) - { - if (player->IsInWorld()) - player->GetMap()->SendUpdateTransportVisibility(player, oldPhases); - player->SendUpdatePhasing(); - } - - // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases) - if (target->IsVisible()) - target->UpdateObjectVisibility(); + else + PhasingHandler::RemovePhase(target, uint32(GetMiscValueB()), true); } void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1733,29 +1724,19 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo Unit* target = aurApp->GetTarget(); - std::set const& oldPhases = target->GetPhases(); - std::set const& phases = GetPhasesForGroup(GetMiscValueB()); - for (auto phase : phases) - target->SetInPhase(phase, false, apply); + PhasingHandler::AddPhaseGroup(target, uint32(GetMiscValueB()), true); - // call functions which may have additional effects after chainging state of unit - // phase auras normally not expected at BG but anyway better check if (apply) { + PhasingHandler::AddPhaseGroup(target, uint32(GetMiscValueB()), true); + + // call functions which may have additional effects after chainging state of unit + // phase auras normally not expected at BG but anyway better check // drop flag at invisibiliy in bg target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } - - if (Player* player = target->ToPlayer()) - { - if (player->IsInWorld()) - player->GetMap()->SendUpdateTransportVisibility(player, oldPhases); - player->SendUpdatePhasing(); - } - - // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases) - if (target->IsVisible()) - target->UpdateObjectVisibility(); + else + PhasingHandler::RemovePhaseGroup(target, uint32(GetMiscValueB()), true); } /**********************/ @@ -3897,13 +3878,14 @@ void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const* aurApp, u target->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float(GetAmount()), apply); } -void AuraEffect::HandleModHitChance(AuraApplication const* aurApp, uint8 mode, bool apply) const +void AuraEffect::HandleModHitChance(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const { if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT))) return; Unit* target = aurApp->GetTarget(); + // handle stack rules if (target->GetTypeId() == TYPEID_PLAYER) { target->ToPlayer()->UpdateMeleeHitChances(); @@ -3911,8 +3893,9 @@ void AuraEffect::HandleModHitChance(AuraApplication const* aurApp, uint8 mode, b } else { - target->m_modMeleeHitChance += (apply) ? GetAmount() : (-GetAmount()); - target->m_modRangedHitChance += (apply) ? GetAmount() : (-GetAmount()); + float value = target->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); + target->m_modMeleeHitChance = value; + target->m_modRangedHitChance = value; } } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 077d51eef90..d68ff6aeba4 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -976,8 +976,20 @@ bool Aura::CanBeSaved() const // Check if aura is single target, not only spell info if (GetCasterGUID() != GetOwner()->GetGUID()) - if (GetSpellInfo()->IsSingleTarget() || IsSingleTarget()) + { + // owner == caster for area auras, check for possible bad data in DB + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (!GetSpellInfo()->Effects[i].IsEffect()) + continue; + + if (GetSpellInfo()->Effects[i].IsTargetingArea() || GetSpellInfo()->Effects[i].IsAreaAuraEffect()) + return false; + } + + if (IsSingleTarget() || GetSpellInfo()->IsSingleTarget()) return false; + } // Can't be saved - aura handler relies on calculated amount and changes it if (HasEffectType(SPELL_AURA_CONVERT_RUNE)) @@ -2325,6 +2337,9 @@ void UnitAura::FillTargetMap(std::unordered_map& targets, Unit* ca units.push_back(GetUnitOwner()); else { + ASSERT(caster, "Area aura (Id: %u) has nullptr caster (%s)", m_spellInfo->Id, GetCasterGUID().ToString().c_str()); + ASSERT(GetCasterGUID() == GetUnitOwner()->GetGUID(), "Area aura (Id: %u) has owner (%s) different to caster (%s)", m_spellInfo->Id, GetUnitOwner()->GetGUID().ToString().c_str(), GetCasterGUID().ToString().c_str()); + // skip area update if owner is not in world! if (!GetUnitOwner()->IsInWorld()) continue; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a5a0f23725c..b289c048c0f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1303,10 +1303,10 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici float angle = float(rand_norm()) * static_cast(M_PI * 35.0f / 180.0f) - static_cast(M_PI * 17.5f / 180.0f); m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle); - float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhases(), x, y, z, true, 50.0f); + float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseShift(), x, y, z, true, 50.0f); float liquidLevel = VMAP_INVALID_HEIGHT_VALUE; LiquidData liquidData; - if (m_caster->GetMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData)) + if (m_caster->GetMap()->GetLiquidStatus(m_caster->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquidData)) liquidLevel = liquidData.level; if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level @@ -5042,11 +5042,11 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint if (m_caster->GetTypeId() == TYPEID_PLAYER && VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled()) { if (m_spellInfo->HasAttribute(SPELL_ATTR0_OUTDOORS_ONLY) && - !m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) + !m_caster->GetMap()->IsOutdoors(m_caster->GetPhaseShift(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) return SPELL_FAILED_ONLY_OUTDOORS; if (m_spellInfo->HasAttribute(SPELL_ATTR0_INDOORS_ONLY) && - m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) + m_caster->GetMap()->IsOutdoors(m_caster->GetPhaseShift(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) return SPELL_FAILED_ONLY_INDOORS; } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 406de6f7225..3ebcfefb607 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -25,6 +25,7 @@ #include "World.h" #include "ObjectMgr.h" #include "SpellMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "SkillExtraItems.h" #include "Unit.h" @@ -3165,7 +3166,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) return; } - pGameObj->CopyPhaseFrom(m_caster); + PhasingHandler::InheritPhaseShift(pGameObj, m_caster); int32 duration = m_spellInfo->GetDuration(); @@ -3184,6 +3185,8 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) if (GameObject* linkedTrap = pGameObj->GetLinkedTrap()) { + PhasingHandler::InheritPhaseShift(linkedTrap, m_caster); + linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0); linkedTrap->SetSpellId(m_spellInfo->Id); @@ -3773,7 +3776,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) return; } - pGameObj->CopyPhaseFrom(m_caster); + PhasingHandler::InheritPhaseShift(pGameObj, m_caster); pGameObj->SetFaction(m_caster->GetFaction()); pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1); @@ -4134,7 +4137,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) return; } - go->CopyPhaseFrom(m_caster); + PhasingHandler::InheritPhaseShift(go, m_caster); //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); int32 duration = m_spellInfo->GetDuration(); @@ -4848,7 +4851,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) return; } - pGameObj->CopyPhaseFrom(m_caster); + PhasingHandler::InheritPhaseShift(pGameObj, m_caster); int32 duration = m_spellInfo->GetDuration(); @@ -4908,6 +4911,8 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) if (GameObject* linkedTrap = pGameObj->GetLinkedTrap()) { + PhasingHandler::InheritPhaseShift(linkedTrap, m_caster); + linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); //linkedTrap->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); linkedTrap->SetSpellId(m_spellInfo->Id); @@ -5742,7 +5747,7 @@ void Spell::EffectUpdatePlayerPhase(SpellEffIndex /*effIndex*/) if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - unitTarget->UpdateAreaPhase(); + PhasingHandler::OnConditionChange(unitTarget); } void Spell::EffectUpdateZoneAurasAndPhases(SpellEffIndex /*effIndex*/) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 2c474523b3f..81da7b3e566 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1818,6 +1818,7 @@ void SpellMgr::LoadSpellProcs() bool addTriggerFlag = false; uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE; + uint32 nonProcMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (!spellInfo->Effects[i].IsEffect()) @@ -1828,7 +1829,11 @@ void SpellMgr::LoadSpellProcs() continue; if (!isTriggerAura[auraName]) + { + // explicitly disable non proccing auras to avoid losing charges on self proc + nonProcMask |= 1 << i; continue; + } procSpellTypeMask |= spellTypeMask[auraName]; if (isAlwaysTriggeredAura[auraName]) @@ -1848,7 +1853,6 @@ void SpellMgr::LoadSpellProcs() break; } } - break; } if (!procSpellTypeMask) @@ -1911,6 +1915,8 @@ void SpellMgr::LoadSpellProcs() procEntry.AttributesMask |= PROC_ATTR_REQ_EXP_OR_HONOR; if (addTriggerFlag) procEntry.AttributesMask |= PROC_ATTR_TRIGGERED_CAN_PROC; + if (nonProcMask) + procEntry.AttributesMask |= nonProcMask * PROC_ATTR_DISABLE_EFF_0; procEntry.ProcsPerMinute = 0; procEntry.Chance = spellInfo->ProcChance; @@ -4297,6 +4303,13 @@ void SpellMgr::LoadSpellInfoCorrections() if (spellInfo->IsPassive() && GetTalentSpellCost(i)) if (spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET) spellInfo->Effects[j].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER); + + // Area auras may not target area (they're self cast) + if (spellInfo->Effects[j].IsAreaAuraEffect() && spellInfo->Effects[j].IsTargetingArea()) + { + spellInfo->Effects[j].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER); + spellInfo->Effects[j].TargetB = SpellImplicitTargetInfo(0); + } } // disable proc for magnet auras, they're handled differently @@ -4339,6 +4352,9 @@ void SpellMgr::LoadSpellInfoCorrections() if (SummonPropertiesEntry* properties = const_cast(sSummonPropertiesStore.LookupEntry(628))) // Hungry Plaguehound properties->Category = SUMMON_CATEGORY_PET; + if (LockEntry* entry = const_cast(sLockStore.LookupEntry(36))) // 3366 Opening, allows to open without proper key + entry->Type[2] = LOCK_KEY_NONE; + TC_LOG_INFO("server.loading", ">> Loaded SpellInfo corrections in %u ms", GetMSTimeDiffToNow(oldMSTime)); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index c614657273d..9da562d7e46 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1505,11 +1505,13 @@ void World::SetInitialWorldSettings() std::unordered_map> mapData; for (MapEntry const* mapEntry : sMapStore) { - mapData.insert(std::unordered_map>::value_type(mapEntry->MapID, std::vector())); + mapData.emplace(std::piecewise_construct, std::forward_as_tuple(mapEntry->MapID), std::forward_as_tuple()); if (mapEntry->rootPhaseMap != -1) mapData[mapEntry->rootPhaseMap].push_back(mapEntry->MapID); } + sMapMgr->InitializeParentMapData(mapData); + if (VMAP::VMapManager2* vmmgr2 = dynamic_cast(VMAP::VMapFactory::createOrGetVMapManager())) vmmgr2->InitializeThreadUnsafe(mapData); @@ -1889,17 +1891,7 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions LoadWorldStates(); - TC_LOG_INFO("server.loading", "Loading Terrain Phase definitions..."); - sObjectMgr->LoadTerrainPhaseInfo(); - - TC_LOG_INFO("server.loading", "Loading Terrain Swap Default definitions..."); - sObjectMgr->LoadTerrainSwapDefaults(); - - TC_LOG_INFO("server.loading", "Loading Terrain World Map definitions..."); - sObjectMgr->LoadTerrainWorldMaps(); - - TC_LOG_INFO("server.loading", "Loading Phase Area definitions..."); - sObjectMgr->LoadAreaPhases(); + sObjectMgr->LoadPhases(); TC_LOG_INFO("server.loading", "Loading Conditions..."); sConditionMgr->LoadConditions(); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index c454957e1f2..c5743927072 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -24,6 +24,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "BattlefieldMgr.h" #include "BattlegroundMgr.h" #include "Chat.h" @@ -979,7 +980,7 @@ public: return false; } - v->CopyPhaseFrom(handler->GetSession()->GetPlayer()); + PhasingHandler::InheritPhaseShift(v, handler->GetSession()->GetPlayer()); map->AddToMap(v->ToCreature()); @@ -1008,22 +1009,20 @@ public: if (!t) return false; - std::set terrainswap; - std::set phaseId; - std::set worldMapSwap; + PhaseShift phaseShift; if (uint32 ut = (uint32)atoi(t)) - terrainswap.insert(ut); + phaseShift.AddVisibleMapId(ut, nullptr); if (p) if (uint32 up = (uint32)atoi(p)) - phaseId.insert(up); + phaseShift.AddPhase(up, PhaseFlags::None, nullptr); if (m) if (uint32 um = (uint32)atoi(m)) - worldMapSwap.insert(um); + phaseShift.AddUiWorldMapAreaIdSwap(um); - handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap, worldMapSwap); + PhasingHandler::SendToPlayer(handler->GetSession()->GetPlayer(), phaseShift); return true; } @@ -1462,15 +1461,8 @@ public: std::stringstream phases; - for (uint32 phase : target->GetPhases()) - { - phases << phase << " "; - } + PhasingHandler::PrintToChat(handler, target->GetPhaseShift()); - if (!phases.str().empty()) - handler->PSendSysMessage("Target's current phases: %s", phases.str().c_str()); - else - handler->SendSysMessage("Target is not phased"); return true; } @@ -1590,7 +1582,7 @@ public: if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId())) nearestLoc = bf->GetClosestGraveYard(player); else - nearestLoc = sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam()); + nearestLoc = sObjectMgr->GetClosestGraveYard(*player, player->GetTeam(), player); } } else diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 8224b83a33d..f5d05e927db 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -24,6 +24,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "MapManager.h" #include "TicketMgr.h" #include "Chat.h" @@ -245,7 +246,7 @@ public: player->SaveRecallPosition(); Map const* map = sMapMgr->CreateBaseMap(mapId); - float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + float z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y)); player->TeleportTo(mapId, x, y, z, player->GetOrientation()); return true; @@ -465,7 +466,7 @@ public: else player->SaveRecallPosition(); - float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + float z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y)); player->TeleportTo(zoneEntry->mapid, x, y, z, player->GetOrientation()); return true; @@ -513,7 +514,7 @@ public: return false; } Map const* map = sMapMgr->CreateBaseMap(mapId); - z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y)); } // stop flight if need diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 3ad09017315..620b626aa8e 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -31,6 +31,7 @@ EndScriptData */ #include "Language.h" #include "Player.h" #include "Opcodes.h" +#include "PhasingHandler.h" class gobject_commandscript : public CommandScript { @@ -147,7 +148,7 @@ public: return false; } - object->CopyPhaseFrom(player); + PhasingHandler::InheritPhaseShift(object, player); if (spawntimeSecs) { diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp index e65e21728c9..34114729807 100644 --- a/src/server/scripts/Commands/cs_group.cpp +++ b/src/server/scripts/Commands/cs_group.cpp @@ -21,6 +21,7 @@ #include "LFG.h" #include "Player.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "GroupMgr.h" #include "ScriptMgr.h" @@ -331,7 +332,6 @@ public: { // Get ALL the variables! Player* playerTarget; - uint32 phase = 0; ObjectGuid guidTarget; std::string nameTarget; std::string zoneName; @@ -412,11 +412,12 @@ public: // Check if iterator is online. If is... Player* p = ObjectAccessor::FindPlayer((*itr).guid); + std::string phases; if (p) { // ... than, it prints information like "is online", where he is, etc... onlineState = "online"; - phase = (!p->IsGameMaster() ? p->GetPhaseMask() : -1); + phases = PhasingHandler::FormatPhases(p->GetPhaseShift()); LocaleConstant localeConstant = handler->GetSessionDbcLocale(); AreaTableEntry const* area = sAreaTableStore.LookupEntry(p->GetAreaId()); @@ -432,12 +433,11 @@ public: // ... else, everything is set to offline or neutral values. zoneName = ""; onlineState = "Offline"; - phase = 0; } // Now we can print those informations for every single member of each group! handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, - zoneName.c_str(), phase, slot.guid.GetCounter(), flags.c_str(), + zoneName.c_str(), phases.c_str(), slot.guid.GetCounter(), flags.c_str(), lfg::GetRolesString(slot.roles).c_str()); } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index a105bee1f9d..e86ba856f82 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -32,6 +32,7 @@ #include "WeatherMgr.h" #include "Player.h" #include "Pet.h" +#include "PhasingHandler.h" #include "LFG.h" #include "GroupMgr.h" #include "MMapFactory.h" @@ -238,8 +239,8 @@ public: Map2ZoneCoordinates(zoneX, zoneY, zoneId); Map const* map = object->GetMap(); - float groundZ = map->GetHeight(object->GetPhases(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); - float floorZ = map->GetHeight(object->GetPhases(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); + float groundZ = map->GetHeight(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); + float floorZ = map->GetHeight(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); @@ -248,11 +249,11 @@ public: uint32 haveMap = Map::ExistMap(mapId, gridX, gridY) ? 1 : 0; uint32 haveVMap = Map::ExistVMap(mapId, gridX, gridY) ? 1 : 0; - uint32 haveMMap = (DisableMgr::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId(), handler->GetSession()->GetPlayer()->GetTerrainSwaps())) ? 1 : 0; + uint32 haveMMap = (DisableMgr::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0; if (haveVMap) { - if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) + if (map->IsOutdoors(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) handler->PSendSysMessage(LANG_GPS_POSITION_OUTDOORS); else handler->PSendSysMessage(LANG_GPS_POSITION_INDOORS); @@ -266,7 +267,6 @@ public: mapId, (mapEntry ? mapEntry->name : unknown), zoneId, (zoneEntry ? zoneEntry->area_name : unknown), areaId, (areaEntry ? areaEntry->area_name : unknown), - object->GetPhaseMask(), StringJoin(object->GetPhases(), ", ").c_str(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation()); if (Transport* transport = object->GetTransport()) handler->PSendSysMessage(LANG_TRANSPORT_POSITION, @@ -277,25 +277,12 @@ public: zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap); LiquidData liquidStatus; - ZLiquidStatus status = map->GetLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); + ZLiquidStatus status = map->GetLiquidStatus(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); if (status) handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); - if (!object->GetTerrainSwaps().empty()) - { - std::stringstream ss; - for (uint32 swap : object->GetTerrainSwaps()) - ss << swap << " "; - handler->PSendSysMessage("Target's active terrain swaps: %s", ss.str().c_str()); - } - if (!object->GetWorldMapAreaSwaps().empty()) - { - std::stringstream ss; - for (uint32 swap : object->GetWorldMapAreaSwaps()) - ss << swap << " "; - handler->PSendSysMessage("Target's active world map area swaps: %s", ss.str().c_str()); - } + PhasingHandler::PrintToChat(handler, object->GetPhaseShift()); return true; } @@ -453,8 +440,8 @@ public: target->GetContactPoint(_player, x, y, z); _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); - - _player->CopyPhaseFrom(target, true); + PhasingHandler::InheritPhaseShift(_player, target); + _player->UpdateObjectVisibility(); } else { @@ -584,7 +571,8 @@ public: float x, y, z; _player->GetClosePoint(x, y, z, target->GetObjectSize()); target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation()); - target->SetPhaseMask(_player->GetPhaseMask(), true); + PhasingHandler::InheritPhaseShift(target, handler->GetSession()->GetPlayer()); + target->UpdateObjectVisibility(); } else { @@ -1088,7 +1076,7 @@ public: Player* player = handler->GetSession()->GetPlayer(); uint32 zone_id = player->GetZoneId(); - WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team); + WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard(*player, team, nullptr); if (graveyard) { uint32 graveyardId = graveyard->ID; @@ -1611,7 +1599,6 @@ public: // Position data print uint32 mapId; uint32 areaId; - std::set phases; std::string areaName = handler->GetTrinityString(LANG_UNKNOWN); std::string zoneName = handler->GetTrinityString(LANG_UNKNOWN); @@ -1643,7 +1630,6 @@ public: areaId = target->GetAreaId(); alive = target->IsAlive() ? handler->GetTrinityString(LANG_YES) : handler->GetTrinityString(LANG_NO); gender = target->getGender(); - phases = target->GetPhases(); } // get additional information from DB else @@ -1830,9 +1816,9 @@ public: // Output XII. LANG_PINFO_CHR_ALIVE handler->PSendSysMessage(LANG_PINFO_CHR_ALIVE, alive.c_str()); - // Output XIII. LANG_PINFO_CHR_PHASES - if (target && !phases.empty()) - handler->PSendSysMessage(LANG_PINFO_CHR_PHASES, StringJoin(phases, ", ").c_str()); + // Output XIII. phases + if (target) + PhasingHandler::PrintToChat(handler, target->GetPhaseShift()); // Output XIV. LANG_PINFO_CHR_MONEY uint32 gold = money / GOLD; diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 5babfe82484..1877041e138 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -30,6 +30,7 @@ #include "Player.h" #include "PointMovementGenerator.h" #include "PathGenerator.h" +#include "PhasingHandler.h" #include "MMapFactory.h" #include "Map.h" #include "TargetedMovementGenerator.h" @@ -62,7 +63,7 @@ public: static bool HandleMmapPathCommand(ChatHandler* handler, char const* args) { - if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId(), handler->GetSession()->GetPlayer()->GetTerrainSwaps())) + if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) { handler->PSendSysMessage("NavMesh not loaded for current map."); return true; @@ -130,12 +131,16 @@ public: int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; + float x, y, z; + player->GetPosition(x, y, z); + handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gx, gy); handler->PSendSysMessage("gridloc [%i, %i]", gy, gx); // calculate navmesh tile location - dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId(), handler->GetSession()->GetPlayer()->GetTerrainSwaps()); - dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId(), handler->GetSession()->GetPlayer()->GetTerrainSwaps()); + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), x, y); + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId()); if (!navmesh || !navmeshquery) { handler->PSendSysMessage("NavMesh not loaded for current map."); @@ -143,8 +148,6 @@ public: } float const* min = navmesh->getParams()->orig; - float x, y, z; - player->GetPosition(x, y, z); float location[VERTEX_SIZE] = { y, z, x }; float extents[VERTEX_SIZE] = { 3.0f, 5.0f, 3.0f }; @@ -185,9 +188,10 @@ public: static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/) { - uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId(); - dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid, handler->GetSession()->GetPlayer()->GetTerrainSwaps()); - dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(mapid, handler->GetSession()->GetPlayer()->GetInstanceId(), handler->GetSession()->GetPlayer()->GetTerrainSwaps()); + Player* player = handler->GetSession()->GetPlayer(); + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), player->GetPositionX(), player->GetPositionY()); + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId()); if (!navmesh || !navmeshquery) { handler->PSendSysMessage("NavMesh not loaded for current map."); @@ -210,14 +214,15 @@ public: static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/) { - uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId(); + Player* player = handler->GetSession()->GetPlayer(); + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), player->GetPositionX(), player->GetPositionY()); handler->PSendSysMessage("mmap stats:"); - handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis"); + handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(player->GetMapId()) ? "en" : "dis"); MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager(); handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount()); - dtNavMesh const* navmesh = manager->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId(), handler->GetSession()->GetPlayer()->GetTerrainSwaps()); + dtNavMesh const* navmesh = manager->GetNavMesh(terrainMapId); if (!navmesh) { handler->PSendSysMessage("NavMesh not loaded for current map."); diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index d7a8f3e2ca4..0f30a37d782 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -27,6 +27,7 @@ EndScriptData */ #include "ObjectMgr.h" #include "Opcodes.h" #include "Pet.h" +#include "PhasingHandler.h" #include "Player.h" #include "ReputationMgr.h" #include "ScriptMgr.h" @@ -828,9 +829,18 @@ public: if (!*args) return false; - uint32 phaseId = uint32(atoul(args)); + char* phaseText = strtok((char*)args, " "); + if (!phaseText) + return false; - if (!sPhaseStore.LookupEntry(phaseId)) + uint32 phaseId = uint32(strtoul(phaseText, nullptr, 10)); + uint32 visibleMapId = 0; + + char* visibleMapIdText = strtok(nullptr, " "); + if (visibleMapIdText) + visibleMapId = uint32(strtoul(visibleMapIdText, nullptr, 10)); + + if (phaseId && !sPhaseStore.LookupEntry(phaseId)) { handler->SendSysMessage(LANG_PHASE_NOTFOUND); handler->SetSentErrorMessage(true); @@ -838,13 +848,29 @@ public: } Unit* target = handler->getSelectedUnit(); - if (!target) - target = handler->GetSession()->GetPlayer(); + if (visibleMapId) + { + MapEntry const* visibleMap = sMapStore.LookupEntry(visibleMapId); + if (!visibleMap || visibleMap->rootPhaseMap != int32(target->GetMapId())) + { + handler->SendSysMessage(LANG_PHASE_NOTFOUND); + handler->SetSentErrorMessage(true); + return false; + } - target->SetInPhase(phaseId, true, !target->IsInPhase(phaseId)); + if (!target->GetPhaseShift().HasVisibleMapId(visibleMapId)) + PhasingHandler::AddVisibleMapId(target, visibleMapId); + else + PhasingHandler::RemoveVisibleMapId(target, visibleMapId); + } - if (target->GetTypeId() == TYPEID_PLAYER) - target->ToPlayer()->SendUpdatePhasing(); + if (phaseId) + { + if (!target->GetPhaseShift().HasPhase(phaseId)) + PhasingHandler::AddPhase(target, phaseId, true); + else + PhasingHandler::RemovePhase(target, phaseId, true); + } return true; } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 250d6c798c2..6b2480b45ef 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -32,6 +32,7 @@ EndScriptData */ #include "CreatureAI.h" #include "Player.h" #include "Pet.h" +#include "PhasingHandler.h" template struct EnumName @@ -287,8 +288,7 @@ public: return false; } - //creature->CopyPhaseFrom(chr); // creature is not directly added to world, only to db, so this is useless here - + PhasingHandler::InheritPhaseShift(creature, chr); creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); ObjectGuid::LowType db_guid = creature->GetSpawnId(); @@ -718,18 +718,8 @@ public: if (CreatureData const* data = sObjectMgr->GetCreatureData(target->GetSpawnId())) { - handler->PSendSysMessage(LANG_NPCINFO_PHASES, data->phaseid, data->phaseGroup); - if (data->phaseGroup) - { - std::set _phases = target->GetPhases(); - - if (!_phases.empty()) - { - handler->PSendSysMessage(LANG_NPCINFO_PHASE_IDS); - for (uint32 phaseId : _phases) - handler->PSendSysMessage("%u", phaseId); - } - } + handler->PSendSysMessage(LANG_NPCINFO_PHASES, data->phaseId, data->phaseGroup); + PhasingHandler::PrintToChat(handler, target->GetPhaseShift()); } handler->PSendSysMessage(LANG_NPCINFO_ARMOR, target->GetArmor()); @@ -1078,12 +1068,8 @@ public: return false; } - creature->ClearPhases(); - - for (uint32 id : GetPhasesForGroup(phaseGroupId)) - creature->SetInPhase(id, false, true); // don't send update here for multiple phases, only send it once after adding all phases - - creature->UpdateObjectVisibility(); + PhasingHandler::ResetPhaseShift(creature); + PhasingHandler::AddPhaseGroup(creature, phaseGroupId, true); creature->SetDBPhase(-int(phaseGroupId)); creature->SaveToDB(); @@ -1114,8 +1100,8 @@ public: return false; } - creature->ClearPhases(); - creature->SetInPhase(phaseID, true, true); + PhasingHandler::ResetPhaseShift(creature); + PhasingHandler::AddPhase(creature, phaseID, true); creature->SetDBPhase(phaseID); creature->SaveToDB(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 7e6ddb25064..2c4221203eb 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -1142,15 +1142,6 @@ public: return true; } - - static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/) - { - TC_LOG_INFO("misc", "Reloading terrain_phase_info table..."); - sObjectMgr->LoadTerrainPhaseInfo(); - handler->SendGlobalGMSysMessage("Terrain phase infos reloaded."); - return true; - } - static bool HandleReloadRBACCommand(ChatHandler* handler, const char* /*args*/) { TC_LOG_INFO("misc", "Reloading RBAC tables..."); diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 037f5f87f7a..bc75249276a 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -22,16 +22,31 @@ Comment: All server related commands Category: commandscripts EndScriptData */ +#include "ScriptMgr.h" #include "Chat.h" #include "Config.h" +#include "DatabaseEnv.h" +#include "DatabaseLoader.h" +#include "GameTime.h" +#include "GitRevision.h" #include "Language.h" +#include "Log.h" #include "ObjectAccessor.h" #include "Player.h" -#include "ScriptMgr.h" -#include "GitRevision.h" -#include "Util.h" -#include "GameTime.h" +#include "RBAC.h" +#include "Realm.h" #include "UpdateTime.h" +#include "Util.h" +#include "VMapFactory.h" +#include "World.h" +#include "WorldSession.h" + +#include + +#include +#include +#include +#include class server_commandscript : public CommandScript { @@ -77,6 +92,7 @@ public: static std::vector serverCommandTable = { { "corpses", rbac::RBAC_PERM_COMMAND_SERVER_CORPSES, true, &HandleServerCorpsesCommand, "" }, + { "debug", rbac::RBAC_PERM_COMMAND_SERVER_DEBUG, true, &HandleServerDebugCommand, "" }, { "exit", rbac::RBAC_PERM_COMMAND_SERVER_EXIT, true, &HandleServerExitCommand, "" }, { "idlerestart", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, nullptr, "", serverIdleRestartCommandTable }, { "idleshutdown", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, nullptr, "", serverIdleShutdownCommandTable }, @@ -102,6 +118,136 @@ public: return true; } + static bool HandleServerDebugCommand(ChatHandler* handler, char const* /*args*/) + { + uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD)); + std::string dbPortOutput; + + { + uint16 dbPort = 0; + if (QueryResult res = LoginDatabase.PQuery("SELECT port FROM realmlist WHERE id = %u", realm.Id.Realm)) + dbPort = (*res)[0].GetUInt16(); + + if (dbPort) + dbPortOutput = Trinity::StringFormat("Realmlist (Realm Id: %u) configured in port %" PRIu16, realm.Id.Realm, dbPort); + else + dbPortOutput = Trinity::StringFormat("Realm Id: %u not found in `realmlist` table. Please check your setup", realm.Id.Realm); + } + + handler->PSendSysMessage("%s", GitRevision::GetFullVersion()); + handler->PSendSysMessage("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + handler->PSendSysMessage("Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); + handler->PSendSysMessage("Using MySQL version: %s", MYSQL_SERVER_VERSION); + handler->PSendSysMessage("Using CMake version: %s", GitRevision::GetCMakeVersion()); + + handler->PSendSysMessage("Compiled on: %s", GitRevision::GetHostOSVersion()); + + uint32 updateFlags = sConfigMgr->GetIntDefault("Updates.EnableDatabases", DatabaseLoader::DATABASE_NONE); + if (!updateFlags) + handler->SendSysMessage("Automatic database updates are disabled for all databases!"); + else + { + static char const* const databaseNames[3 /*TOTAL_DATABASES*/] = + { + "Auth", + "Characters", + "World" + }; + + std::string availableUpdateDatabases; + for (uint32 i = 0; i < 3 /* TOTAL_DATABASES*/; ++i) + { + if (!(updateFlags & (1 << i))) + continue; + + availableUpdateDatabases += databaseNames[i]; + if (i != 3 /*TOTAL_DATABASES*/ - 1) + availableUpdateDatabases += ", "; + } + + handler->PSendSysMessage("Automatic database updates are enabled for the following databases: %s", availableUpdateDatabases.c_str()); + } + + handler->PSendSysMessage("Worldserver listening connections on port %" PRIu16, worldPort); + handler->PSendSysMessage("%s", dbPortOutput.c_str()); + + bool vmapIndoorCheck = sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK); + bool vmapLOSCheck = VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled(); + bool vmapHeightCheck = VMAP::VMapFactory::createOrGetVMapManager()->isHeightCalcEnabled(); + + bool mmapEnabled = sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS); + + std::string dataDir = sWorld->GetDataPath(); + std::vector subDirs; + subDirs.emplace_back("maps"); + if (vmapIndoorCheck || vmapLOSCheck || vmapHeightCheck) + { + handler->PSendSysMessage("VMAPs status: Enabled. LineOfSight: %i, getHeight: %i, indoorCheck: %i", vmapLOSCheck, vmapHeightCheck, vmapIndoorCheck); + subDirs.emplace_back("vmaps"); + } + else + handler->SendSysMessage("VMAPs status: Disabled"); + + if (mmapEnabled) + { + handler->SendSysMessage("MMAPs status: Enabled"); + subDirs.emplace_back("mmaps"); + } + else + handler->SendSysMessage("MMAPs status: Disabled"); + + for (std::string const& subDir : subDirs) + { + boost::filesystem::path mapPath(dataDir); + mapPath.append(subDir); + + if (!boost::filesystem::exists(mapPath)) + { + handler->PSendSysMessage("%s directory doesn't exist!. Using path: %s", subDir.c_str(), mapPath.generic_string().c_str()); + continue; + } + + auto end = boost::filesystem::directory_iterator(); + std::size_t folderSize = std::accumulate(boost::filesystem::directory_iterator(mapPath), end, std::size_t(0), [](std::size_t val, boost::filesystem::path const& mapFile) + { + if (boost::filesystem::is_regular_file(mapFile)) + val += boost::filesystem::file_size(mapFile); + return val; + }); + + handler->PSendSysMessage("%s directory located in %s. Total size: " SZFMTD " bytes", subDir.c_str(), mapPath.generic_string().c_str(), folderSize); + } + + LocaleConstant defaultLocale = sWorld->GetDefaultDbcLocale(); + uint32 availableLocalesMask = (1 << defaultLocale); + + for (uint8 i = 0; i < TOTAL_LOCALES; ++i) + { + LocaleConstant locale = static_cast(i); + if (locale == defaultLocale) + continue; + + if (sWorld->GetAvailableDbcLocale(locale) != defaultLocale) + availableLocalesMask |= (1 << locale); + } + + std::string availableLocales; + for (uint8 i = 0; i < TOTAL_LOCALES; ++i) + { + if (!(availableLocalesMask & (1 << i))) + continue; + + availableLocales += localeNames[i]; + if (i != TOTAL_LOCALES - 1) + availableLocales += " "; + } + + handler->PSendSysMessage("Using %s DBC Locale as default. All available DBC locales: %s", localeNames[defaultLocale], availableLocales.c_str()); + + handler->PSendSysMessage("Using World DB: %s", sWorld->GetDBVersion()); + return true; + } + static bool HandleServerInfoCommand(ChatHandler* handler, char const* /*args*/) { uint32 playersNum = sWorld->GetPlayerCount(); @@ -113,7 +259,7 @@ public: std::string uptime = secsToTimeString(GameTime::GetUptime()); uint32 updateTime = sWorldUpdateTime.GetLastUpdateTime(); - handler->SendSysMessage(GitRevision::GetFullVersion()); + handler->PSendSysMessage("%s", GitRevision::GetFullVersion()); handler->PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum); handler->PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); handler->PSendSysMessage(LANG_UPTIME, uptime.c_str()); diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index be818f6ff42..4eb2c7da7c4 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -27,6 +27,7 @@ EndScriptData */ #include "Language.h" #include "MapManager.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "ScriptMgr.h" @@ -202,7 +203,7 @@ public: SQLTransaction dummy; Player::SavePositionInDB(WorldLocation(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation), - sMapMgr->GetZoneId(tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy); + sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy); } return true; diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 4327ac4c52c..5b1decd2984 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -25,6 +25,7 @@ EndScriptData */ #include "Chat.h" #include "Language.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "ScriptMgr.h" #include "WaypointManager.h" @@ -667,7 +668,7 @@ public: return false; } - wpCreature->CopyPhaseFrom(chr); + PhasingHandler::InheritPhaseShift(wpCreature, chr); wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); @@ -881,7 +882,7 @@ public: return false; } - wpCreature->CopyPhaseFrom(chr); + PhasingHandler::InheritPhaseShift(wpCreature, chr); // Set "wpguid" column to the visual waypoint stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); @@ -945,7 +946,7 @@ public: return false; } - creature->CopyPhaseFrom(chr); + PhasingHandler::InheritPhaseShift(creature, chr); creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) @@ -996,7 +997,7 @@ public: return false; } - creature->CopyPhaseFrom(chr); + PhasingHandler::InheritPhaseShift(creature, chr); creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 4a0a96092b6..023c71f7d35 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -1172,7 +1172,7 @@ public: float x, y, z; me->GetPosition(x, y, z); - z = me->GetMap()->GetHeight(me->GetPhases(), x, y, z); + z = me->GetMap()->GetHeight(me->GetPhaseShift(), x, y, z); me->GetMotionMaster()->MovePoint(0, x, y, z); me->SetPosition(x, y, z, 0); } @@ -1290,7 +1290,7 @@ public: { float x, y, z; me->GetPosition(x, y, z); - z = me->GetMap()->GetHeight(me->GetPhases(), x, y, z); + z = me->GetMap()->GetHeight(me->GetPhaseShift(), x, y, z); me->GetMotionMaster()->MovePoint(0, x, y, z); me->SetPosition(x, y, z, 0); hyjal_trashAI::JustDied(killer); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp index 09c79fd51dc..789dd0189a5 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp @@ -270,7 +270,7 @@ public: Position pos = me->GetRandomNearPosition(10.0f); //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY)); if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) return summon; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp index e54b10a5922..36a53162a23 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp @@ -305,7 +305,7 @@ public: Position pos = me->GetRandomNearPosition(10.0f); //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY)); if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) if (Unit* temp = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MEDIVH))) diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp index ab3c6fdd4f6..d8eb7629658 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp @@ -543,7 +543,7 @@ public: float x = caster->GetPositionX() + dist * std::cos(angle); float y = caster->GetPositionY() + dist * std::sin(angle); - float z = caster->GetMap()->GetHeight(caster->GetPhases(), x, y, caster->GetPositionZ()); + float z = caster->GetMap()->GetHeight(caster->GetPhaseShift(), x, y, caster->GetPositionZ()); const_cast(GetExplTargetDest())->Relocate(x, y, z); GetHitDest()->Relocate(x, y, z); diff --git a/src/server/scripts/Kalimdor/LostCityOfTheTolvir/boss_high_prophet_barim.cpp b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/boss_high_prophet_barim.cpp index 1da7989686b..cb6b0a966e1 100644 --- a/src/server/scripts/Kalimdor/LostCityOfTheTolvir/boss_high_prophet_barim.cpp +++ b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/boss_high_prophet_barim.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "lost_city_of_the_tolvir.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "ScriptedCreature.h" #include "SpellAuraEffects.h" @@ -289,8 +290,7 @@ public: if (Creature* barim = _instance->GetCreature(DATA_HIGH_PROPHET_BARIM)) barim->AI()->JustSummoned(me); - for (uint32 id : GetPhasesForGroup(PHASE_GROUP_ENCOUNTER_1)) - me->SetInPhase(id, false, true); + PhasingHandler::AddPhaseGroup(me, PHASE_GROUP_ENCOUNTER_1, true); DoCastSelf(SPELL_REPENTANCE_SCRIPT_1, true); _events.ScheduleEvent(EVENT_COPY_WEAPON, Seconds(2)); @@ -439,7 +439,7 @@ public: me->SetReactState(REACT_PASSIVE); DoZoneInCombat(); DoCastSelf(SPELL_BIRTH, true); - me->SetInPhase(PHASE_ID_REPENTANCE, true, false); + PhasingHandler::AddPhase(me, PHASE_ID_REPENTANCE, true); } void JustEngagedWith(Unit* /*who*/) override @@ -455,8 +455,7 @@ public: if (Creature* barim = _instance->GetCreature(DATA_HIGH_PROPHET_BARIM)) barim->AI()->JustSummoned(summon); - for (uint32 id : GetPhasesForGroup(PHASE_GROUP_ENCOUNTER_1)) - summon->SetInPhase(id, false, true); + PhasingHandler::AddPhaseGroup(summon, PHASE_GROUP_ENCOUNTER_1, true); } void JustDied(Unit* /*killer*/) override diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp index 29611c23cd9..6aad1be5363 100644 --- a/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp +++ b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp @@ -268,7 +268,7 @@ class boss_high_priestess_azil : public CreatureScript me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_CASTING_VISUAL); me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_ENERGY_SHIELD); Position pos = me->GetPosition(); - pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); me->GetMotionMaster()->MovePoint(POINT_GROUND, pos); break; } diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp index cd34681aa33..d1dbe8a65ac 100644 --- a/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp +++ b/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp @@ -266,7 +266,7 @@ class boss_slabhide : public CreatureScript case EVENT_LAND: { Position pos = me->GetPosition(); - pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_LAND, pos); break; } @@ -479,7 +479,7 @@ public: { Unit* caster = GetCaster(); Position pos = caster->GetPosition(); - pos.m_positionZ = caster->GetMap()->GetHeight(caster->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 100.0f); + pos.m_positionZ = caster->GetMap()->GetHeight(caster->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 100.0f); dest.Relocate(pos); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp index 4a651769fd9..0a3c2086d67 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp @@ -88,7 +88,7 @@ class boss_amanitar : public CreatureScript for (uint8 i = 0; i < 30; ++i) { Position pos = me->GetRandomNearPosition(30.0f); - pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), MAX_HEIGHT) + 2.0f; + pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), MAX_HEIGHT) + 2.0f; if (Creature* trigger = me->SummonCreature(NPC_TRIGGER, pos)) { diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp index b1423e8aa91..af5dc4f8f43 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp @@ -22,6 +22,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ahnkahet.h" +#include "PhasingHandler.h" #include "Player.h" #include "SpellInfo.h" @@ -142,7 +143,7 @@ public: // clone player->CastSpell(summon, SPELL_CLONE_PLAYER, true); // phase the summon - summon->SetInPhase(spellInfo->Effects[EFFECT_0].MiscValueB, true, true); + PhasingHandler::AddPhase(summon, spellInfo->Effects[EFFECT_0].MiscValueB, true); } } ++insanityHandled; @@ -168,9 +169,9 @@ public: instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT); // Visible for all players in insanity - me->SetInPhase(169, true, true); for (uint32 i = 173; i <= 177; ++i) - me->SetInPhase(i, true, true); + PhasingHandler::AddPhase(me, i, false); + PhasingHandler::AddPhase(me, 169, true); ResetPlayersPhase(); @@ -208,7 +209,7 @@ public: return; else { - nextPhase = *visage->GetPhases().begin(); + nextPhase = visage->GetPhaseShift().GetPhases().begin()->Id; break; } } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index fe2bdd35bf4..bea95c5fce3 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -627,7 +627,7 @@ class npc_frost_sphere : public CreatureScript if (me->GetHealth() <= damage) { damage = 0; - float floorZ = me->GetMap()->GetHeight(me->GetPhases(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + float floorZ = me->GetMap()->GetHeight(me->GetPhaseShift(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); if (fabs(me->GetPositionZ() - floorZ) < 0.1f) { // we are close to the ground diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index ee9092c97ec..30fc14ed5a8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -804,7 +804,7 @@ class boss_prince_valanar_icc : public CreatureScript { float x, y, z; summon->GetPosition(x, y, z); - float ground_Z = summon->GetMap()->GetHeight(summon->GetPhases(), x, y, z, true, 500.0f); + float ground_Z = summon->GetMap()->GetHeight(summon->GetPhaseShift(), x, y, z, true, 500.0f); summon->GetMotionMaster()->MovePoint(POINT_KINETIC_BOMB_IMPACT, x, y, ground_Z); summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); break; @@ -1046,7 +1046,7 @@ class npc_kinetic_bomb : public CreatureScript me->SetReactState(REACT_PASSIVE); me->GetPosition(_x, _y, _groundZ); me->DespawnOrUnsummon(60000); - _groundZ = me->GetMap()->GetHeight(me->GetPhases(), _x, _y, _groundZ, true, 500.0f); + _groundZ = me->GetMap()->GetHeight(me->GetPhaseShift(), _x, _y, _groundZ, true, 500.0f); } void DoAction(int32 action) override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index 717e2e2ace9..04f016e2fbb 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -17,6 +17,7 @@ #include "ObjectMgr.h" #include "ScriptMgr.h" +#include "PhasingHandler.h" #include "ScriptedCreature.h" #include "SpellAuraEffects.h" #include "Cell.h" @@ -636,7 +637,7 @@ class npc_the_lich_king_controller : public CreatureScript void JustSummoned(Creature* summon) override { // must not be in dream phase - summon->SetInPhase(173, true, false); + PhasingHandler::RemovePhase(summon, 173, true); if (summon->GetEntry() != NPC_SUPPRESSER) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) summon->AI()->AttackStart(target); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp index 74da0607518..586eb7b2751 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp @@ -294,10 +294,7 @@ class boss_sapphiron : public CreatureScript events.ScheduleEvent(EVENT_TAIL, randtime(Seconds(7), Seconds(10)), 0, PHASE_GROUND); return; case EVENT_DRAIN: - if (events.IsInPhase(PHASE_FLIGHT)) - _delayedDrain = true; - else - CastDrain(); + CastDrain(); return; case EVENT_BLIZZARD: DoCastAOE(SPELL_SUMMON_BLIZZARD); @@ -399,6 +396,9 @@ class boss_sapphiron : public CreatureScript me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); return; + case EVENT_DRAIN: + _delayedDrain = true; + break; } } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 8dd67e1ff5e..1b6a8c26b3a 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -778,7 +778,7 @@ class boss_flame_leviathan_safety_container : public CreatureScript { float x, y, z; me->GetPosition(x, y, z); - z = me->GetMap()->GetHeight(me->GetPhases(), x, y, z); + z = me->GetMap()->GetHeight(me->GetPhaseShift(), x, y, z); me->GetMotionMaster()->MovePoint(0, x, y, z); me->SetPosition(x, y, z, 0); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index a063663f74e..8f7f6492c4c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -872,7 +872,7 @@ class boss_sara : public CreatureScript float angle = frand(0.0f, 2.0f * float(M_PI)); pos.m_positionX = YoggSaronSpawnPos.GetPositionX() + radius * cosf(angle); pos.m_positionY = YoggSaronSpawnPos.GetPositionY() + radius * sinf(angle); - pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), YoggSaronSpawnPos.GetPositionZ() + 5.0f); + pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), YoggSaronSpawnPos.GetPositionZ() + 5.0f); me->SummonCreature(NPC_DEATH_RAY, pos, TEMPSUMMON_TIMED_DESPAWN, 20000); } break; diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index f933cc5de86..5a4a0bd9d08 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -38,6 +38,7 @@ EndContentData */ #include "ScriptedGossip.h" #include "ScriptedEscortAI.h" #include "ScriptedFollowerAI.h" +#include "PhasingHandler.h" #include "Player.h" #include "SpellInfo.h" #include "WorldSession.h" @@ -1689,7 +1690,7 @@ public: me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break; case 20: - me->SetInPhase(170, true, false); + PhasingHandler::RemovePhase(me, 170, true); Talk(SAY_5); me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); player->GroupEventHappens(QUEST_ESCAPING_THE_MIST, me); diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp index 7a1150af29c..a871f044bf9 100644 --- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp +++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp @@ -529,7 +529,7 @@ public: bird->KillSelf(); crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), - bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhases(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); + bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseShift(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); /// @todo Make crunchy perform emote eat when he reaches the bird break; diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp index 3a736f2f02f..6ea3fabb84a 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "OutdoorPvPSI.h" #include "WorldPacket.h" +#include "PhasingHandler.h" #include "Player.h" #include "GameObject.h" #include "MapManager.h" @@ -182,8 +183,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } - go->CopyPhaseFrom(player); - + PhasingHandler::InheritPhaseShift(go, player); go->SetRespawnTime(0); if (!map->AddToMap(go)) @@ -213,8 +213,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } - go->CopyPhaseFrom(player); - + PhasingHandler::InheritPhaseShift(go, player); go->SetRespawnTime(0); if (!map->AddToMap(go)) diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp index f3184bf7807..73029c4d58b 100644 --- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -75,7 +75,7 @@ public: void Reset() override { - ground = me->GetMap()->GetHeight(me->GetPhases(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZMinusOffset()); + ground = me->GetMap()->GetHeight(me->GetPhaseShift(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZMinusOffset()); SummonInfernal(); events.ScheduleEvent(EVENT_CAST_SUMMON_INFERNAL, urand(1000, 3000)); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 2e02e896e83..3445fac226d 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1000,36 +1000,57 @@ class spell_q12805_lifeblood_dummy : public SpellScriptLoader */ enum BattleStandard { - NPC_KING_OF_THE_MOUNTAINT_KC = 31766, + NPC_KING_OF_THE_MOUNTAINT_KC = 31766, + SPELL_PLANT_HORDE_BATTLE_STANDARD = 59643, + SPELL_HORDE_BATTLE_STANDARD_STATE = 59642, + SPELL_ALLIANCE_BATTLE_STANDARD_STATE = 4339, + SPELL_JUMP_ROCKET_BLAST = 4340 }; -class spell_q13280_13283_plant_battle_standard: public SpellScriptLoader +class spell_q13280_13283_plant_battle_standard : public SpellScript { - public: - spell_q13280_13283_plant_battle_standard() : SpellScriptLoader("spell_q13280_13283_plant_battle_standard") { } + PrepareSpellScript(spell_q13280_13283_plant_battle_standard); - class spell_q13280_13283_plant_battle_standard_SpellScript : public SpellScript - { - PrepareSpellScript(spell_q13280_13283_plant_battle_standard_SpellScript); + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + uint32 triggeredSpellID = SPELL_ALLIANCE_BATTLE_STANDARD_STATE; - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (caster->IsVehicle()) - if (Unit* player = caster->GetVehicleKit()->GetPassenger(0)) - player->ToPlayer()->KilledMonsterCredit(NPC_KING_OF_THE_MOUNTAINT_KC); - } + caster->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + if (caster->IsVehicle()) + if (Unit* player = caster->GetVehicleKit()->GetPassenger(0)) + player->ToPlayer()->KilledMonsterCredit(NPC_KING_OF_THE_MOUNTAINT_KC); - void Register() override - { - OnEffectHit += SpellEffectFn(spell_q13280_13283_plant_battle_standard_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + if (GetSpellInfo()->Id == SPELL_PLANT_HORDE_BATTLE_STANDARD) + triggeredSpellID = SPELL_HORDE_BATTLE_STANDARD_STATE; - SpellScript* GetSpellScript() const override - { - return new spell_q13280_13283_plant_battle_standard_SpellScript(); - } + target->RemoveAllAuras(); + target->CastSpell(target, triggeredSpellID, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_q13280_13283_plant_battle_standard::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +class spell_q13280_13283_jump_jets : public SpellScript +{ + PrepareSpellScript(spell_q13280_13283_jump_jets); + + void HandleCast() + { + Unit* caster = GetCaster(); + if (caster->IsVehicle()) + if (Unit* rocketBunny = caster->GetVehicleKit()->GetPassenger(1)) + rocketBunny->CastSpell(rocketBunny, SPELL_JUMP_ROCKET_BLAST, true); + } + + void Register() override + { + OnCast += SpellCastFn(spell_q13280_13283_jump_jets::HandleCast); + } }; enum ChumTheWaterSummons @@ -2897,7 +2918,8 @@ void AddSC_quest_spell_scripts() new spell_q12659_ahunaes_knife(); new spell_q9874_liquid_fire(); new spell_q12805_lifeblood_dummy(); - new spell_q13280_13283_plant_battle_standard(); + RegisterSpellScript(spell_q13280_13283_plant_battle_standard); + RegisterSpellScript(spell_q13280_13283_jump_jets); new spell_q14112_14145_chum_the_water(); new spell_q9452_cast_net(); new spell_q12279_cast_net(); diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 2709b43e22f..4bd2812f33a 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -28,6 +28,7 @@ set(mmap_gen_Includes ${CMAKE_SOURCE_DIR}/src/common/Collision/Management ${CMAKE_SOURCE_DIR}/src/common/Collision/Maps ${CMAKE_SOURCE_DIR}/src/common/Collision/Models + ${CMAKE_SOURCE_DIR}/src/common/DataStores ) include_directories(${mmap_gen_Includes}) diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 5e6b12d71ab..5cc935d6944 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -23,6 +23,8 @@ #include "DetourNavMesh.h" #include "IntermediateValues.h" #include "StringFormat.h" +#include "VMapFactory.h" +#include "VMapManager2.h" #include @@ -214,7 +216,7 @@ namespace MMAP _workerThreads.push_back(std::thread(&MapBuilder::WorkerThread, this)); } - m_tiles.sort([](MapTiles a, MapTiles b) + m_tiles.sort([](MapTiles const& a, MapTiles const& b) { return a.m_tiles->size() > b.m_tiles->size(); }); @@ -471,7 +473,12 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) { - std::set* tiles = getTileList(mapID); + // if map has a parent we use that to generate dtNavMeshParams - worldserver will load all missing tiles from that map + int32 navMeshParamsMapId = static_cast(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); + if (navMeshParamsMapId == -1) + navMeshParamsMapId = mapID; + + std::set* tiles = getTileList(navMeshParamsMapId); // old code for non-statically assigned bitmask sizes: ///*** calculate number of bits needed to store tiles & polys ***/ @@ -532,6 +539,7 @@ namespace MMAP if (!file) { dtFreeNavMesh(navMesh); + navMesh = nullptr; char message[1024]; sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName); perror(message); @@ -835,6 +843,7 @@ namespace MMAP // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile // is removed via removeTile() dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef); + if (!tileRef || dtResult != DT_SUCCESS) { printf("%s Failed adding tile to navmesh! \n", tileString.c_str()); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 4f553302c00..b14e2906853 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -101,7 +101,7 @@ namespace MMAP return LISTFILE_DIRECTORY_NOT_FOUND; do { - if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + if (strcmp(findFileInfo.cFileName, ".") != 0 && strcmp(findFileInfo.cFileName, "..") != 0) fileList.push_back(std::string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 0013b5e13f3..e6e48d9894d 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -16,11 +16,15 @@ * with this program. If not, see . */ -#include - -#include "PathCommon.h" #include "MapBuilder.h" +#include "PathCommon.h" #include "Timer.h" +#include "VMapFactory.h" +#include "VMapManager2.h" +#include "DBCFileLoader.h" +#include +#include +#include using namespace MMAP; @@ -34,6 +38,13 @@ bool checkDirectories(bool debugOutput) return false; } + dirFiles.clear(); + if (getDirContents(dirFiles, "dbc") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) + { + printf("'dbc' directory is empty or does not exist\n"); + return false; + } + dirFiles.clear(); if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { @@ -43,15 +54,24 @@ bool checkDirectories(bool debugOutput) dirFiles.clear(); if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) - return boost::filesystem::create_directory("mmaps"); + { + if (!boost::filesystem::create_directory("mmaps")) + { + printf("'mmaps' directory does not exist and failed to create it\n"); + return false; + } + } dirFiles.clear(); if (debugOutput) { if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) { - printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); - return false; + if (!boost::filesystem::create_directory("meshes")) + { + printf("'meshes' directory does not exist and failed to create it (no place to put debugOutput files)\n"); + return false; + } } } @@ -274,9 +294,32 @@ int main(int argc, char** argv) return 0; } + if (!checkDirectories(debugOutput)) return silent ? -3 : finish("Press ENTER to close...", -3); + std::string mapPath = (boost::filesystem::path("dbc") / "Map.dbc").string(); + + std::unordered_map> mapData; + { + DBCFileLoader* loader = new DBCFileLoader(); + char const* mapFmt = "nxxxxxxxxxxxxxxxxxxi"; + if (!loader->Load(mapPath.c_str(), mapFmt)) + { + delete loader; + return silent ? -4 : finish("Failed to load Map.dbc", -4); + } + for (uint32 x = 0; x < loader->GetNumRows(); ++x) + { + mapData.emplace(std::piecewise_construct, std::forward_as_tuple(loader->getRecord(x).getUInt(0)), std::forward_as_tuple()); + int16 parentMapId = int16(loader->getRecord(x).getUInt(19)); + if (parentMapId != -1) + mapData[parentMapId].push_back(loader->getRecord(x).getUInt(0)); + } + + static_cast(VMAP::VMapFactory::createOrGetVMapManager())->InitializeThreadUnsafe(mapData); + } + MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath); @@ -290,6 +333,8 @@ int main(int argc, char** argv) else builder.buildAllMaps(threads); + VMAP::VMapFactory::clear(); + if (!silent) printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start)); return 0; diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index a703382c8a3..b2e47022fe0 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -17,12 +17,11 @@ */ #include "TerrainBuilder.h" - #include "MapBuilder.h" - -#include "VMapManager2.h" #include "MapTree.h" #include "ModelInstance.h" +#include "VMapFactory.h" +#include "VMapManager2.h" // ****************************************** // Map file format defines @@ -137,6 +136,16 @@ namespace MMAP sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); FILE* mapFile = fopen(mapFileName, "rb"); + if (!mapFile) + { + int32 parentMapId = static_cast(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); + if (parentMapId != -1) + { + sprintf(mapFileName, "maps/%03u%02u%02u.map", parentMapId, tileY, tileX); + mapFile = fopen(mapFileName, "rb"); + } + } + if (!mapFile) return false; @@ -389,7 +398,6 @@ namespace MMAP useTerrain = true; useLiquid = true; uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; - // FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’" // if there is no liquid, don't use liquid if (!meshData.liquidVerts.size() || !ltriangles.size()) @@ -631,8 +639,8 @@ namespace MMAP /**************************************************************************/ bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) { - IVMapManager* vmapManager = new VMapManager2(); - int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); + VMapManager2* vmapManager = static_cast(VMapFactory::createOrGetVMapManager()); + int result = vmapManager->loadSingleMap(mapID, "vmaps", tileX, tileY); bool retval = false; do @@ -641,7 +649,7 @@ namespace MMAP break; InstanceTreeMap instanceTrees; - ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); + vmapManager->getInstanceMapTree(instanceTrees); if (!instanceTrees[mapID]) break; @@ -669,7 +677,7 @@ namespace MMAP worldModel->getGroupModels(groupModels); // all M2s need to have triangle indices reversed - bool isM2 = instance.name.find(".m2") != std::string::npos || instance.name.find(".M2") != std::string::npos; + bool isM2 = (instance.flags & MOD_M2) != 0; // transform data float scale = instance.iScale; @@ -778,8 +786,7 @@ namespace MMAP } while (false); - vmapManager->unloadMap(mapID, tileX, tileY); - delete vmapManager; + vmapManager->unloadSingleMap(mapID, tileX, tileY); return retval; } diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index d6a0a642bc0..516fcf3a86b 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -79,13 +79,18 @@ char* GetExtension(char* FileName) extern HANDLE WorldMpq; -ADTFile::ADTFile(char* filename) : ADT(WorldMpq, filename, false) +ADTFile::ADTFile(char* filename, bool cache) : ADT(WorldMpq, filename, false) { Adtfilename.append(filename); + cacheable = cache; + dirfileCache = nullptr; } -bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) +bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMapId) { + if (dirfileCache) + return initFromCache(map_num, tileX, tileY, originalMapId); + if (ADT.isEof ()) return false; @@ -107,14 +112,16 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) //printf("yMap = %s\n", yMap.c_str()); std::string dirname = std::string(szWorkDirWmo) + "/dir_bin"; - FILE *dirfile; - dirfile = fopen(dirname.c_str(), "ab"); + FILE* dirfile = fopen(dirname.c_str(), "ab"); if (!dirfile) { printf("Can't open dirfile!'%s'\n", dirname.c_str()); return false; } + if (cacheable) + dirfileCache = new std::vector(); + while (!ADT.isEof()) { char fourcc[5]; @@ -189,7 +196,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) { uint32 id; ADT.read(&id, 4); - ModelInstance inst(ADT, ModelInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile); + ModelInstance inst(ADT, ModelInstanceNames[id].c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); } delete[] ModelInstanceNames; ModelInstanceNames = NULL; @@ -204,7 +211,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) { uint32 id; ADT.read(&id, 4); - WMOInstance inst(ADT, WmoInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile); + WMOInstance inst(ADT, WmoInstanceNames[id].c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); } delete[] WmoInstanceNames; @@ -221,7 +228,37 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) return true; } +bool ADTFile::initFromCache(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMapId) +{ + if (dirfileCache->empty()) + return true; + + std::string dirname = std::string(szWorkDirWmo) + "/dir_bin"; + FILE* dirfile = fopen(dirname.c_str(), "ab"); + if (!dirfile) + { + printf("Can't open dirfile!'%s'\n", dirname.c_str()); + return false; + } + + for (ADTOutputCache const& cached : *dirfileCache) + { + fwrite(&map_num, sizeof(uint32), 1, dirfile); + fwrite(&tileX, sizeof(uint32), 1, dirfile); + fwrite(&tileY, sizeof(uint32), 1, dirfile); + uint32 flags = cached.Flags; + if (map_num != originalMapId) + flags |= MOD_PARENT_SPAWN; + fwrite(&flags, sizeof(uint32), 1, dirfile); + fwrite(cached.Data.data(), cached.Data.size(), 1, dirfile); + } + + fclose(dirfile); + return true; +} + ADTFile::~ADTFile() { ADT.close(); + delete dirfileCache; } diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h index 6567254108a..f1f42f3fd4e 100644 --- a/src/tools/vmap4_extractor/adtfile.h +++ b/src/tools/vmap4_extractor/adtfile.h @@ -106,31 +106,28 @@ struct MapChunkHeader uint32 effectId; }; +struct ADTOutputCache +{ + uint32 Flags; + std::vector Data; +}; class ADTFile { private: - //size_t mcnk_offsets[256], mcnk_sizes[256]; MPQFile ADT; - //mcell Mcell; std::string Adtfilename; + bool cacheable; + std::vector* dirfileCache; public: - ADTFile(char* filename); + ADTFile(char* filename, bool cache); ~ADTFile(); int nWMO; int nMDX; std::string* WmoInstanceNames; std::string* ModelInstanceNames; - bool init(uint32 map_num, uint32 tileX, uint32 tileY); - //void LoadMapChunks(); - - //uint32 wmo_count; -/* - const mcell& Getmcell() const - { - return Mcell; - } -*/ + bool init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMapId); + bool initFromCache(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMapId); }; char const* GetPlainName(char const* FileName); diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index 204bca77cad..d797a28a61f 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -19,6 +19,7 @@ #include "vmapexport.h" #include "model.h" #include "wmo.h" +#include "adtfile.h" #include "mpqfile.h" #include #include @@ -144,7 +145,7 @@ Vec3D fixCoordSystem2(Vec3D v) return Vec3D(v.x, v.z, v.y); } -ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile) +ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector* dirfileCache) : id(0), scale(0), flags(0) { float ff[3]; @@ -180,6 +181,8 @@ ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID uint32 flags = MOD_M2; if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN; + if (mapID != originalMapId) + flags |= MOD_PARENT_SPAWN; //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name fwrite(&mapID, sizeof(uint32), 1, pDirfile); @@ -195,6 +198,34 @@ ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID fwrite(&nlen, sizeof(uint32), 1, pDirfile); fwrite(ModelInstName, sizeof(char), nlen, pDirfile); + if (dirfileCache) + { + dirfileCache->emplace_back(); + ADTOutputCache& cacheModelData = dirfileCache->back(); + cacheModelData.Flags = flags & ~MOD_PARENT_SPAWN; + cacheModelData.Data.resize( + sizeof(uint16) + // adtId + sizeof(uint32) + // id + sizeof(float) * 3 + // pos + sizeof(float) * 3 + // rot + sizeof(float) + // sc + sizeof(uint32) + // nlen + nlen); // ModelInstName + + uint8* cacheData = cacheModelData.Data.data(); +#define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count; + + CACHE_WRITE(&adtId, sizeof(uint16), 1, cacheData); + CACHE_WRITE(&id, sizeof(uint32), 1, cacheData); + CACHE_WRITE(&pos, sizeof(float), 3, cacheData); + CACHE_WRITE(&rot, sizeof(float), 3, cacheData); + CACHE_WRITE(&sc, sizeof(float), 1, cacheData); + CACHE_WRITE(&nlen, sizeof(uint32), 1, cacheData); + CACHE_WRITE(ModelInstName, sizeof(char), nlen, cacheData); + +#undef CACHE_WRITE + } + /* int realx1 = (int) ((float) pos.x / 533.333333f); int realy1 = (int) ((float) pos.z / 533.333333f); int realx2 = (int) ((float) pos.x / 533.333333f); diff --git a/src/tools/vmap4_extractor/model.h b/src/tools/vmap4_extractor/model.h index fea5cb3f7a9..283279ea54a 100644 --- a/src/tools/vmap4_extractor/model.h +++ b/src/tools/vmap4_extractor/model.h @@ -24,6 +24,7 @@ #include class MPQFile; +struct ADTOutputCache; Vec3D fixCoordSystem(Vec3D v); @@ -59,7 +60,7 @@ public: float sc; ModelInstance() : id(0), scale(0), flags(0), sc(0.0f) {} - ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile); + ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector* dirfileCache); }; diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 33630d635b5..fbf6dff3230 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #ifdef _WIN32 #include @@ -103,15 +105,15 @@ TCHAR const* LocalesT[LOCALES_COUNT] = _T("itIT"), }; -typedef struct +struct map_info { char name[64]; - unsigned int id; -}map_id; + int32 parent_id; +}; -map_id * map_ids; +std::map map_ids; +std::unordered_set maps_that_are_parents; uint16 *LiqType = 0; -uint32 map_count; char output_path[128]="."; char input_path[1024]="."; bool preciseVectorData = false; @@ -120,7 +122,7 @@ bool preciseVectorData = false; //static const char * szWorkDirMaps = ".\\Maps"; const char* szWorkDirWmo = "./Buildings"; -const char* szRawVMAPMagic = "VMAP044"; +const char* szRawVMAPMagic = "VMAP045"; bool LoadLocaleMPQFile(int locale) { @@ -389,26 +391,49 @@ bool ExtractSingleWmo(std::string& fname) void ParsMapFiles() { - char fn[512]; - //char id_filename[64]; - char id[10]; - for (unsigned int i=0; i wdts; + auto getWDT = [&wdts](uint32 mapId) -> WDTFile* { - sprintf(id,"%03u",map_ids[i].id); - sprintf(fn,"World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name); - WDTFile WDT(fn,map_ids[i].name); - if (WDT.init(id, map_ids[i].id)) + auto itr = wdts.find(mapId); + if (itr == wdts.end()) { - printf("Processing Map %u\n[", map_ids[i].id); - for (int x=0; x<64; ++x) + char fn[512]; + char* name = map_ids[mapId].name; + sprintf(fn, "World\\Maps\\%s\\%s.wdt", name, name); + itr = wdts.emplace(std::piecewise_construct, std::forward_as_tuple(mapId), std::forward_as_tuple(fn, name, maps_that_are_parents.count(mapId) > 0)).first; + if (!itr->second.init(mapId)) { - for (int y=0; y<64; ++y) + wdts.erase(itr); + return nullptr; + } + } + + return &itr->second; + }; + + for (auto itr = map_ids.begin(); itr != map_ids.end(); ++itr) + { + if (WDTFile* WDT = getWDT(itr->first)) + { + WDTFile* parentWDT = itr->second.parent_id >= 0 ? getWDT(itr->second.parent_id) : nullptr; + printf("Processing Map %u\n[", itr->first); + for (int32 x = 0; x < 64; ++x) + { + for (int32 y = 0; y < 64; ++y) { - if (ADTFile *ADT = WDT.GetMap(x,y)) + bool success = false; + if (ADTFile* ADT = WDT->GetMap(x, y)) { - //sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!! - ADT->init(map_ids[i].id, x, y); - delete ADT; + success = ADT->init(itr->first, x, y, itr->first); + WDT->FreeADT(ADT); + } + if (!success && parentWDT) + { + if (ADTFile* ADT = parentWDT->GetMap(x, y)) + { + ADT->init(itr->first, x, y, itr->second.parent_id); + parentWDT->FreeADT(ADT); + } } } printf("#"); @@ -507,7 +532,7 @@ bool processArgv(int argc, char ** argv, const char *versionString) int main(int argc, char ** argv) { bool success=true; - const char *versionString = "V4.00 2012_02"; + const char *versionString = "V4.05 2018_03"; // Use command line arguments, when some if (!processArgv(argc, argv, versionString)) @@ -564,39 +589,36 @@ int main(int argc, char ** argv) //map.dbc if (success) { - DBCFile * dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc"); + DBCFile* dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc"); if (!dbc->open()) { delete dbc; printf("FATAL ERROR: Map.dbc not found in data file.\n"); return 1; } - map_count=dbc->getRecordCount (); - map_ids=new map_id[map_count]; - for (unsigned int x=0;xgetRecordCount(); ++x) { - map_ids[x].id = dbc->getRecord(x).getUInt(0); + map_info& m = map_ids[dbc->getRecord(x).getUInt(0)]; const char* map_name = dbc->getRecord(x).getString(1); - size_t max_map_name_length = sizeof(map_ids[x].name); + size_t max_map_name_length = sizeof(m.name); if (strlen(map_name) >= max_map_name_length) { - delete dbc; - delete[] map_ids; - printf("FATAL ERROR: Map name too long.\n"); - return 1; + printf("Fatal error: Map name too long!\n"); + exit(1); } - strncpy(map_ids[x].name, map_name, max_map_name_length); - map_ids[x].name[max_map_name_length - 1] = '\0'; - printf("Map - %s\n", map_ids[x].name); + strncpy(m.name, map_name, max_map_name_length); + m.name[max_map_name_length - 1] = '\0'; + m.parent_id = int16(dbc->getRecord(x).getInt(19)); + if (m.parent_id >= 0) + maps_that_are_parents.insert(m.parent_id); + + printf("Map - %s\n", m.name); } - delete dbc; ParsMapFiles(); - delete [] map_ids; - //nError = ERROR_SUCCESS; - // Extract models, listed in GameObjectDisplayInfo.dbc ExtractGameobjectModels(); } diff --git a/src/tools/vmap4_extractor/vmapexport.h b/src/tools/vmap4_extractor/vmapexport.h index a73d259d52b..c798fb496ba 100644 --- a/src/tools/vmap4_extractor/vmapexport.h +++ b/src/tools/vmap4_extractor/vmapexport.h @@ -24,8 +24,9 @@ enum ModelFlags { MOD_M2 = 1, - MOD_WORLDSPAWN = 1<<1, - MOD_HAS_BOUND = 1<<2 + MOD_WORLDSPAWN = 1 << 1, + MOD_HAS_BOUND = 1 << 2, + MOD_PARENT_SPAWN = 1 << 3 }; extern const char * szWorkDirWmo; diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 8948489a900..e5856d9aafa 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -33,60 +33,68 @@ char * wdtGetPlainName(char * FileName) extern HANDLE WorldMpq; -WDTFile::WDTFile(char* file_name, char* file_name1):WDT(WorldMpq, file_name) +WDTFile::WDTFile(char const* filePath, std::string mapName, bool cache) + : _file(WorldMpq, filePath), _mapName(std::move(mapName)) { - filename.append(file_name1,strlen(file_name1)); + if (cache) + { + _adtCache = std::make_unique(); + memset(_adtCache->file, 0, sizeof(_adtCache->file)); + } + else + _adtCache = nullptr; } -bool WDTFile::init(char* /*map_id*/, unsigned int mapID) +WDTFile::~WDTFile() = default; + +bool WDTFile::init(uint32 mapId) { - if (WDT.isEof()) - { - //printf("Can't find WDT file.\n"); + if (_file.isEof()) return false; - } char fourcc[5]; uint32 size; std::string dirname = std::string(szWorkDirWmo) + "/dir_bin"; - FILE *dirfile; - dirfile = fopen(dirname.c_str(), "ab"); + FILE* dirfile = fopen(dirname.c_str(), "ab"); if (!dirfile) { printf("Can't open dirfile!'%s'\n", dirname.c_str()); return false; } - while (!WDT.isEof()) + while (!_file.isEof()) { - WDT.read(fourcc,4); - WDT.read(&size, 4); + _file.read(fourcc, 4); + _file.read(&size, 4); flipcc(fourcc); fourcc[4] = 0; - size_t nextpos = WDT.getPos() + size; + size_t nextpos = _file.getPos() + size; - if (!strcmp(fourcc,"MAIN")) + if (!strcmp(fourcc, "MAIN")) { } - if (!strcmp(fourcc,"MWMO")) + if (!strcmp(fourcc, "MWMO")) { // global map objects if (size) { char *buf = new char[size]; - WDT.read(buf, size); - char *p=buf; - int q = 0; - gWmoInstansName = new std::string[size]; + _file.read(buf, size); + char *p = buf; while (p < buf + size) { - char* s=wdtGetPlainName(p); - FixNameCase(s,strlen(s)); - p=p+strlen(p)+1; - gWmoInstansName[q++] = s; + std::string path(p); + + char* s = wdtGetPlainName(p); + FixNameCase(s, strlen(s)); + FixNameSpaces(s, strlen(s)); + p = p + strlen(p) + 1; + _wmoNames.push_back(s); + + ExtractSingleWmo(path); } delete[] buf; } @@ -96,39 +104,45 @@ bool WDTFile::init(char* /*map_id*/, unsigned int mapID) // global wmo instance data if (size) { - gnWMO = (int)size / 64; + int32 gnWMO = (int)size / 64; for (int i = 0; i < gnWMO; ++i) { int id; - WDT.read(&id, 4); - WMOInstance inst(WDT,gWmoInstansName[id].c_str(), mapID, 65, 65, dirfile); + _file.read(&id, 4); + WMOInstance inst(_file, _wmoNames[id].c_str(), mapId, 65, 65, mapId, dirfile, nullptr); } - - delete[] gWmoInstansName; - gWmoInstansName = NULL; } } - WDT.seek((int)nextpos); + _file.seek((int)nextpos); } - WDT.close(); + _file.close(); fclose(dirfile); return true; } -WDTFile::~WDTFile(void) +ADTFile* WDTFile::GetMap(int32 x, int32 y) { - WDT.close(); -} + if (!(x >= 0 && y >= 0 && x < 64 && y < 64)) + return nullptr; -ADTFile* WDTFile::GetMap(int x, int z) -{ - if (!(x>=0 && z >= 0 && x<64 && z<64)) - return NULL; + if (_adtCache && _adtCache->file[x][y]) + return _adtCache->file[x][y].get(); char name[512]; - sprintf(name,"World\\Maps\\%s\\%s_%d_%d_obj0.adt", filename.c_str(), filename.c_str(), x, z); - return new ADTFile(name); + sprintf(name, "World\\Maps\\%s\\%s_%d_%d_obj0.adt", _mapName.c_str(), _mapName.c_str(), x, y); + ADTFile* adt = new ADTFile(name, _adtCache != nullptr); + if (_adtCache) + _adtCache->file[x][y].reset(adt); + return adt; +} + +void WDTFile::FreeADT(ADTFile* adt) +{ + if (_adtCache) + return; + + delete adt; } diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h index 49f10cf306c..4456da1d1d4 100644 --- a/src/tools/vmap4_extractor/wdtfile.h +++ b/src/tools/vmap4_extractor/wdtfile.h @@ -21,24 +21,32 @@ #include "mpqfile.h" #include +#include class ADTFile; class WDTFile { public: - WDTFile(char* file_name, char* file_name1); - ~WDTFile(void); + WDTFile(char const* file_name, std::string mapName, bool cache); + ~WDTFile(); + bool init(uint32 mapId); - bool init(char* map_id, unsigned int mapID); - ADTFile* GetMap(int x, int z); + ADTFile* GetMap(int32 x, int32 y); + void FreeADT(ADTFile* adt); std::string* gWmoInstansName; int gnWMO; private: - MPQFile WDT; - std::string filename; + MPQFile _file; + std::string _mapName; + std::vector _wmoNames; + struct ADTCache + { + std::unique_ptr file[64][64]; + }; + std::unique_ptr _adtCache; }; #endif diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 2b0bee9417b..dbfe3a9c8f5 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -18,6 +18,7 @@ #include "vmapexport.h" #include "wmo.h" +#include "adtfile.h" #include "vec3d.h" #include @@ -485,7 +486,7 @@ WMOGroup::~WMOGroup() delete [] LiquBytes; } -WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile) +WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector* dirfileCache) : currx(0), curry(0), wmo(NULL), doodadset(0), pos(), indx(0), id(0) { float ff[3]; @@ -549,7 +550,11 @@ WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint float scale = 1.0f; uint32 flags = MOD_HAS_BOUND; - if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN; + if (tileX == 65 && tileY == 65) + flags |= MOD_WORLDSPAWN; + if (mapID != originalMapId) + flags |= MOD_PARENT_SPAWN; + //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name fwrite(&mapID, sizeof(uint32), 1, pDirfile); fwrite(&tileX, sizeof(uint32), 1, pDirfile); @@ -562,10 +567,42 @@ WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint fwrite(&scale, sizeof(float), 1, pDirfile); fwrite(&pos2, sizeof(float), 3, pDirfile); fwrite(&pos3, sizeof(float), 3, pDirfile); - uint32 nlen=strlen(WmoInstName); + uint32 nlen = strlen(WmoInstName); fwrite(&nlen, sizeof(uint32), 1, pDirfile); fwrite(WmoInstName, sizeof(char), nlen, pDirfile); + if (dirfileCache) + { + dirfileCache->emplace_back(); + ADTOutputCache& cacheModelData = dirfileCache->back(); + cacheModelData.Flags = flags & ~MOD_PARENT_SPAWN; + cacheModelData.Data.resize( + sizeof(uint16) + // adtId + sizeof(uint32) + // id + sizeof(float) * 3 + // pos + sizeof(float) * 3 + // rot + sizeof(float) + // scale + sizeof(float) * 3 + // pos2 + sizeof(float) * 3 + // pos3 + sizeof(uint32) + // nlen + nlen); // WmoInstName + + uint8* cacheData = cacheModelData.Data.data(); +#define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count; + + CACHE_WRITE(&adtId, sizeof(uint16), 1, cacheData); + CACHE_WRITE(&id, sizeof(uint32), 1, cacheData); + CACHE_WRITE(&pos, sizeof(float), 3, cacheData); + CACHE_WRITE(&rot, sizeof(float), 3, cacheData); + CACHE_WRITE(&scale, sizeof(float), 1, cacheData); + CACHE_WRITE(&pos2, sizeof(float), 3, cacheData); + CACHE_WRITE(&pos3, sizeof(float), 3, cacheData); + CACHE_WRITE(&nlen, sizeof(uint32), 1, cacheData); + CACHE_WRITE(WmoInstName, sizeof(char), nlen, cacheData); + +#undef CACHE_WRITE + } + /* fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n", MapName, WmoInstName, diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h index a5c4e71d93c..d85b2fd2af7 100644 --- a/src/tools/vmap4_extractor/wmo.h +++ b/src/tools/vmap4_extractor/wmo.h @@ -42,6 +42,7 @@ enum MopyFlags class WMOInstance; class WMOManager; class MPQFile; +struct ADTOutputCache; /* for whatever reason a certain company just can't stick to one coordinate system... */ static inline Vec3D fixCoords(const Vec3D &v){ return Vec3D(v.z, v.x, v.y); } @@ -134,7 +135,7 @@ public: Vec3D pos2, pos3, rot; uint32 indx, id; - WMOInstance(MPQFile&f , char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile); + WMOInstance(MPQFile&f , char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector* dirfileCache); static void reset(); };