mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
[12774] Merged cmangos last changes, special thanks for xfurry, Dramacydal, cala, Schmoozerd,
I'm not taking any credits of this commit.
Implement spell effects 62042, 62278 and 64767
Also limit the targets for 62577 and 62603
----------
Update git_id to reflect recent sql formatting changes
----------
Update to a safer code version and also add GO caster scenarios
----------
Allow aura 62038 to stack at every 3 seconds
----------
Improve handling of TargetMMGen
This will have impact on Chase and Follow Movement.
----------
* Refactor code to check if a new position is required for the MMGen into the new function RequiresNewPosition
* Refactor code to get the current targeted distance into function GetDynamicTargetDistance
* Change ChaseMMGen (angle = 0.0f case) chase to best contact point, not zero angle.
Thanks to Cala and X-Savior for testing. Special thanks to cala for also suggesting improved values for the magic numbers
----------
Improve ObjectPosSelector
Now a spot already occupied by the searcher will be prefered
----------
Get rid of bounding radius in GetNearPoint[2D] and ObjectPosSelector
----------
This changes how ObjectPosSelector is used.
It changes the way how the functions Object::GetNearPoint and Object::GetNearPoint2d behave.
----------
So you need to check all places where these functions are used if they are still used correctly.
----------
Especially check your scripts!
----------
Remove not required duplicate indexes
----------
Implement TARGET_92 as TARGET_SUMMONER
This target is used only as TargetA and the related spells are used only by temporary summoned creatures
----------
Implement some spell effects used by Hodir in Ulduar
Dummy spells 62797, 63499, 63545 and 64543
Periodic dummy auras: 61968, 62038, 62039 and 65272
Limit targets for spells: 62797, 63545, 64543, 62476 and 62477
----------
Implement some spells used at Algalon encounter
Spell aura entries 64345, 62018 and 64412
Positive target exception for spell 64996
Aura stacking exception for spells 62169, 62168, 65250 and 64417
----------
Implement effect for spell 63633
----------
EventAI - Ingame output of script state
----------
With this the command .npc aiinfo will give more output about the current state.
Remark that this output is only given if the LogFilter for EventAIDev mode is disabled
----------
FindGit.cmake already ships with CMake
No reason for us to ship it too. Also, we had an outdated version which
had not been used anyway, because we set the include path in such a way,
that the CMake delivered version is always found first.
----------
FindOpenSSL.cmake already ships with CMake
No reason for us to ship it too. Also, we had an outdated version which
had not been used anyway, because we set the include path in such a way,
that the CMake delivered version is always found first.
----------
EventAI - Add more developing error output
----------
Fix some target-type handling for EventAI
Also increase log-output for bad target-types
----------
Fix crash due to bad compiler (author Xfurry)
----------
Add special condition id for Ulduar
Will be used to check the availability of the siege vehicles for players
----------
Update spells 62374 and 62907
* limit spell targets of spell 62374
* implement spell effect for spell 62907
----------
Remove effect for spell 64503
Will be handled in script library. For details please check 8502cdfa64
----------
Implement spells 64489 and 64673
Both are used by Auriaya (Ulduar)
----------
Implement some spells for Ignis the Furnace Master
Spell entries: 62717, 62381, 62488, 62707, 64475 and 64503
----------
Implement spells 61187 and 61190
----------
CMake: generic way to build a script library
Added new parameter INCLUDE_BINDINGS_DIR which can be set to the name of a
folder inside src/bindings/.
Includes the script library in src/bindings/ with the defined name.
The name must correspond to the name of the folder and the folder must contain
a valid CMakeLists.txt
Note: if you currently use a script library, you will probably get a merge
problem on src/bindings/CMakeLists.txt as you will have modified this file
manually. Please use the new version of this file and rerun CMake once with the
parameter -DINCLUDE_BINDINGS_DIR=ScriptDev2 (if you are not using SD2 but
another script library, replace ScriptDev2 with the name of the folder in
src/bindings/).
If you do not use a script library you should not have any merge problems
and you don't need to do anything.
----------
Add CMake source groups to target 'game'
This is the exact same grouping as it is currently in the VC 2012 files.
These groupings will have to be refactored at some point as they are not
very logical.
----------
Add CMake source groups to target 'framework'
This is the exact same grouping as it is currently in the VC 2012 files.
This is part of cmangos/issues#67
----------
Add CMake source groups to target 'shared'
This is the exact same grouping as it is currently in the VC 2012 files.
----------
Add new parameter 'expansion' to command 'account create'
----------
Update some Sunwell Plateau spells
Limit targets and allow positive effect for spell 46650
Implement effect for spells 46289 and 46637
Remove effect for spell 44845 - will be handled in script library
----------
Implement some custom use for Effect Activate Object spells
This will fix the summoning events for the Wind Stones, Ice Stones, Skettis bosses and quest 11865
----------
Sync mangos.sql with other versions
----------
Redump sql databases to unify formatting
The main reason for this was because classic/cata has updated the sql formatting and manually syncing would be a pain so redumping from master->tbc->classic->cata is easier.
Only the formatting was changed. The values were not changed at all.
mysqldump was used however manual modifications had to be done.
Dump the database:
C:/mysql/bin/mysqldump.exe mangos > sql/mangos.sql
Split insert values into multiple rows:
Replace "),(" with "),\n("
Replace "VALUES (" with "VALUES\n("
Remove the character sets by replacing them with an empty string
Custom formatting of mangos.sql:
Move db_version to the very top
Create all dbscripts_on_* tables based on dbscripts_on_creature_movement
Preserve our custom insert formatting of spell_affect (tbc/classic), spell_bonus_data, spell_chain, spell_elixir, spell_proc_event, spell_proc_item_enchant, spell_template, spell_threat
Remove autoincrement values from insert values of pet_name_generation and remove AUTO_INCREMENT=261 value from its table structure
Custom formatting of characters.sql:
Move character_db_version to the very top
Custom formatting of realmd.sql:
Move realmd_db_version to the very top
----------
Immediately remove corpses when ForcedDespawn is used
Thanks to Neotmiren for pointing, special thanks to cala for testing!
----------
Fix use of config values related to quest-status and level
This fixes use of negative value in config values Quests.LowLevelHideDiff and Quests.HighLevelHideDiff
Also add some documentation around the related code
Thanks to Neotmiren for pointing and to cala for testing.
----------
Loot-System: Fix reference loading check
This fixes a false error output for loot references that are only used with spell loot.
Thanks to X-Savior for properly reporting both error messages and use case
----------
Add missing spell 61437 to playercreate spells for bloodelves
Thanks to NeatElves for porting from TC and pointing to this
----------
Fix load bar step for alendarMgr::LoadCalendarsFromDB
----------
Cody Style Improvements
Also remove an unused variable (thanks to Den for this!)
----------
Implement the spells used in the Chess Event encounter
Combat spell entries: 37775, 37824, 39338, 39342, 39341, 39344, 45260
Melee spells: 37142, 37143, 37147, 37149, 37150, 37220, 37227, 37228, 37337, 37339, 37345, 37348
Chess movement spells: 30012, 32312, 37388, 30284, 37144, 37146, 37148, 37151, 37152, 37153
Aura stacking exception: 32261 and 39400
----------
And more hotfixes with these format strings
----------
Hotfix to recent text loading functions
----------
Use possible changed model names with vmap extraction
----------
Fix some warnings
----------
Store how many texts are loaded for validity checks. Use this with EventAI
----------
EventAI: Use generic DoDisplayText and loading of additional text data
----------
Add generic DoDisplayText function and use additional data of dbscripts table
----------
Add const-correctness to Text related functions
----------
Add database changes to support more data for DB Script texts
----------
Add stacking exception for spells 39993 and 40041
----------
Allow spell effect 86 - Activate Object to use the misc value
----------
Allow player pets to swim
----------
Enable resummoning of warlock pets
----------
Do not remove FLY auras on Evade
Also consider npcs which have SPELL_AURA_FLY as being able to fly
----------
EventAI: Improve code
* Drop rather pointless bool to check if the number of assigned events is empty
* Before the phase was resetted on death if and only if the npc has Events defined
* DoMeleeAttackIfReady could have been called even though combat state could have changed while processing events
----------
EventAI: Implement ACTION_T_SET_THROW_MASK (46)
This Action can be used to set which AIEvents should be thrown automatically, if you need more flexibility, you can always use the manual ACTION_TH_THROW_AI_EVENT version.
* Also clean some error-log output a bit.
----------
Forward original caster GUID to script library
----------
Fixup commit 12511 Thanks to Zakamurite for pointing
Also thanks to him for giving a helping hand in correcting the commit
----------
Implement some spells for Felmyst encounter
Spell entries: 45714, 45717 and 45918. Limit targets of spell 45391
Also add stacking exception for auras 45068 and 45582
----------
Fix invisible spirit healers & such on death near them
This fixes an issue that occurs if you die close to a spirit healer/guide.
----------
Fix take ammo for most ranged spells
Fix spells like Arcane Shot not taking ammo while they should
----------
Check cast spell 51690
----------
Fix SpellDamage modifier of SPELL_AURA_MOD_DAMAGE_DONE_CREATURE
This aura modifies a flat value, not a percent value.
----------
Implement proc effect of spells 67712, 67758
related to items 47316, 47477.
----------
Improve proc of spell 50421
----------
Add and implement server-side spell 23770
----------
EventAI: Improve TargetSelection related ErrorLog output
----------
DBScripts Engine: Change behaviour to search for a different npc when using buddy-search
With this an npc buddy will be interpreted as "another npc with entry"
Also toggle command 31 - TERMINATE_SCRIPT to also look only for other npcs of entry
----------
DBScripts Engine: Allow pets as buddy
Add new flag SCRIPT_FLAG_BUDDY_IS_PET (0x20) that will search not for a normal npc with buddy-search, but also for pets
----------
DBScripts Engine: Support buddy search by guid
* Add new `data_flags` flag SCRIPT_FLAG_BUDDY_BY_GUID (0x10)
If this flag is set, the content of `search_distance` is interpreted as db-guid of the requested buddy
* Also switch most error log output to DB-error log output (though this will include false positives)
----------
This commit is contained in:
parent
8f8068714c
commit
ae7348f6b0
73 changed files with 2633 additions and 1503 deletions
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# This code is part of MaNGOS. Contributor & Copyright details are in AUTHORS/THANKS.
|
||||
# This file is part of the MaNGOS Project. See AUTHORS file for Copyright information
|
||||
#
|
||||
# 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
|
||||
|
|
@ -16,11 +16,10 @@
|
|||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# CMake policies
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(MaNGOS)
|
||||
set(MANGOS_VERSION 0.18)
|
||||
set(MANGOS_VERSION 0.17)
|
||||
|
||||
set(CMAKE_MODULE_PATH
|
||||
${CMAKE_MODULE_PATH}
|
||||
|
|
@ -51,6 +50,10 @@ message(
|
|||
CMAKE_INSTALL_PREFIX Path where the server should be installed to
|
||||
PCH Use precompiled headers
|
||||
DEBUG Debug mode
|
||||
INCLUDE_BINDINGS_DIR Include a script library in src/bindings/ with the
|
||||
defined name. the name must corespond to the name of
|
||||
the folder and the folder must contain a valid
|
||||
CMakeLists.txt
|
||||
TBB_USE_EXTERNAL Use external TBB
|
||||
USE_STD_MALLOC Use standard malloc instead of TBB
|
||||
ACE_USE_EXTERNAL Use external ACE
|
||||
|
|
@ -94,9 +97,6 @@ endif()
|
|||
# find Git: used to get the revision number
|
||||
find_package(Git)
|
||||
|
||||
# find Git: used to get the revision number
|
||||
find_package(Git)
|
||||
|
||||
# check if the platform supports precomiled headers
|
||||
find_package(PCHSupport)
|
||||
|
||||
|
|
@ -218,6 +218,20 @@ endif()
|
|||
message(STATUS "MaNGOS-Core revision : ${GIT_REVISION}")
|
||||
message(STATUS "Install server to : ${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
if(DEFINED INCLUDE_BINDINGS_DIR AND INCLUDE_BINDINGS_DIR)
|
||||
# check if the directory exists
|
||||
if(NOT IS_DIRECTORY ${CMAKE_SOURCE_DIR}/src/bindings/${INCLUDE_BINDINGS_DIR})
|
||||
message(FATAL_ERROR "Could not find the script library which was supposed to be: " ${CMAKE_SOURCE_DIR}/src/bindings/${INCLUDE_BINDINGS_DIR})
|
||||
endif()
|
||||
# check if it really contains a CMakeLists.txt
|
||||
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/src/bindings/${INCLUDE_BINDINGS_DIR}/CMakeLists.txt)
|
||||
message(FATAL_ERROR "The script library does not contain a CMakeLists.txt!")
|
||||
endif()
|
||||
message(STATUS "Build script library : Yes (using ${INCLUDE_BINDINGS_DIR})")
|
||||
else()
|
||||
message(STATUS "Build script library : No")
|
||||
endif()
|
||||
|
||||
# if(CLI)
|
||||
# message(STATUS "Build with CLI : Yes (default)")
|
||||
# add_definitions(-DENABLE_CLI)
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
# The module defines the following variables:
|
||||
# GIT_EXECUTABLE - path to git command line client
|
||||
# GIT_FOUND - true if the command line client was found
|
||||
# Example usage:
|
||||
# find_package(Git)
|
||||
# if(GIT_FOUND)
|
||||
# message("git found: ${GIT_EXECUTABLE}")
|
||||
# endif()
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distributed this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Look for 'git' or 'eg' (easy git)
|
||||
#
|
||||
set(git_names git eg)
|
||||
|
||||
# Prefer .cmd variants on Windows unless running in a Makefile
|
||||
# in the MSYS shell.
|
||||
#
|
||||
if(WIN32)
|
||||
if(NOT CMAKE_GENERATOR MATCHES "MSYS")
|
||||
set(git_names git.cmd git eg.cmd eg)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(GIT_EXECUTABLE
|
||||
NAMES ${git_names}
|
||||
DOC "git command line client"
|
||||
)
|
||||
mark_as_advanced(GIT_EXECUTABLE)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set GIT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Git DEFAULT_MSG GIT_EXECUTABLE)
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
#
|
||||
# Find the OpenSSL client includes and library
|
||||
#
|
||||
|
||||
# This module defines
|
||||
# OPENSSL_INCLUDE_DIR, where to find openssl.h
|
||||
# OPENSSL_LIBRARIES, the libraries to link against to connect to MySQL
|
||||
# OPENSSL_FOUND, if false, you cannot build anything that requires MySQL.
|
||||
|
||||
# also defined, but not for general use are
|
||||
# OPENSSL_LIBRARY, where to find the MySQL library.
|
||||
|
||||
if( OPENSSL_INCLUDE_DIR AND OPENSSL_LIBRARIES )
|
||||
# in cache already
|
||||
set(OPENSSL_FOUND 1)
|
||||
else( OPENSSL_INCLUDE_DIR AND OPENSSL_LIBRARIES )
|
||||
set(OPENSSL_FOUND 0)
|
||||
|
||||
if(WIN32)
|
||||
if(PLATFORM MATCHES X64)
|
||||
set(TMP_OPENSSL_INCLUDE_DIR
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;InstallLocation]/include/openssl"
|
||||
)
|
||||
set(TMP_OPENSSL_LIBRARIES
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;InstallLocation]/lib"
|
||||
)
|
||||
else()
|
||||
set(TMP_OPENSSL_INCLUDE_DIR
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]/include/openssl"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]/include/openssl"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]/include/openssl"
|
||||
)
|
||||
set(TMP_OPENSSL_LIBRARIES
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]/lib"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_path(OPENSSL_INCLUDE_DIR
|
||||
NAMES
|
||||
ssl.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/include/openssl
|
||||
/usr/local/include
|
||||
/usr/local/include/openssl
|
||||
/usr/local/openssl/include
|
||||
${TMP_OPENSSL_INCLUDE_DIR}
|
||||
DOC
|
||||
"Specify the directory containing openssl.h."
|
||||
)
|
||||
|
||||
find_library(OPENSSL_LIBRARIES
|
||||
NAMES
|
||||
ssleay32
|
||||
ssl
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/lib/ssl
|
||||
/usr/local/lib
|
||||
/usr/local/lib/ssl
|
||||
/usr/local/ssl/lib
|
||||
${TMP_OPENSSL_LIBRARIES}
|
||||
DOC "Specify the OpenSSL library here."
|
||||
)
|
||||
|
||||
if( WIN32 )
|
||||
find_library(OPENSSL_EXTRA_LIBRARIES
|
||||
NAMES
|
||||
libeay32
|
||||
PATHS
|
||||
${TMP_OPENSSL_LIBRARIES}
|
||||
DOC
|
||||
"if more libraries are necessary to link in a OpenSSL client, specify them here."
|
||||
)
|
||||
endif( WIN32 )
|
||||
|
||||
if( UNIX )
|
||||
find_library(OPENSSL_EXTRA_LIBRARIES
|
||||
NAMES
|
||||
crypto
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/lib/ssl
|
||||
/usr/local/lib
|
||||
/usr/local/lib/ssl
|
||||
/usr/local/ssl/lib
|
||||
${TMP_OPENSSL_LIBRARIES}
|
||||
DOC "if more libraries are necessary to link in a OpenSSL client, specify them here."
|
||||
)
|
||||
endif()
|
||||
|
||||
if( OPENSSL_LIBRARIES )
|
||||
if( OPENSSL_INCLUDE_DIR )
|
||||
set( OPENSSL_FOUND 1 )
|
||||
message(STATUS "Found OpenSSL library: ${OPENSSL_LIBRARIES}")
|
||||
message(STATUS "Found OpenSSL headers: ${OPENSSL_INCLUDE_DIR}")
|
||||
else ( OPENSSL_INCLUDE_DIR )
|
||||
message(FATAL_ERROR "Could not find OpenSSL headers! Please install the development-headers")
|
||||
endif( OPENSSL_INCLUDE_DIR )
|
||||
else( OPENSSL_LIBRARIES )
|
||||
message(FATAL_ERROR "Could not find OpenSSL libraries! Please install the library before continuing")
|
||||
endif( OPENSSL_LIBRARIES )
|
||||
mark_as_advanced( OPENSSL_FOUND OPENSSL_LIBRARIES OPENSSL_EXTRA_LIBRARIES OPENSSL_INCLUDE_DIR )
|
||||
endif( OPENSSL_INCLUDE_DIR AND OPENSSL_LIBRARIES )
|
||||
|
|
@ -756,7 +756,7 @@ bool change_sql_database()
|
|||
fputs(buffer, fout);
|
||||
}
|
||||
|
||||
fprintf(fout, " `required_%s` bit(1) default NULL\n", last_sql_update[i]);
|
||||
fprintf(fout, " `required_%s` bit(1) DEFAULT NULL\n", last_sql_update[i]);
|
||||
|
||||
while (fgets(buffer, MAX_BUF, fin))
|
||||
fputs(buffer, fout);
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@ void fixname2(char* name, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
char* GetExtension(char* FileName)
|
||||
char const* GetExtension(char const* FileName)
|
||||
{
|
||||
char* szTemp;
|
||||
char const* szTemp;
|
||||
if ((szTemp = strrchr(FileName, '.')) != NULL)
|
||||
return szTemp;
|
||||
return NULL;
|
||||
|
|
@ -149,11 +149,11 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, StringSet& failed
|
|||
fixnamen(p, strlen(p));
|
||||
char* s = GetPlainName(p);
|
||||
fixname2(s, strlen(s));
|
||||
string path(p); // Store copy after name fixed
|
||||
|
||||
ModelInstansName[t++] = s;
|
||||
|
||||
string path(p);
|
||||
ExtractSingleModel(path, failedPaths);
|
||||
std::string fixedName;
|
||||
ExtractSingleModel(path, fixedName, failedPaths);
|
||||
ModelInstansName[t++] = fixedName;
|
||||
|
||||
p = p + strlen(p) + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class ADTFile
|
|||
|
||||
const char* GetPlainName(const char* FileName);
|
||||
char* GetPlainName(char* FileName);
|
||||
char* GetExtension(char* FileName);
|
||||
char const* GetExtension(char const* FileName);
|
||||
void fixnamen(char* name, size_t len);
|
||||
void fixname2(char* name, size_t len);
|
||||
//void fixMapNamen(char *name, size_t len);
|
||||
|
|
|
|||
|
|
@ -6,28 +6,30 @@
|
|||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
bool ExtractSingleModel(std::string& fname, StringSet& failedPaths)
|
||||
bool ExtractSingleModel(std::string& origPath, std::string& fixedName, StringSet& failedPaths)
|
||||
{
|
||||
char* ext = GetExtension(GetPlainName((char*)fname.c_str()));
|
||||
char const* ext = GetExtension(GetPlainName(origPath.c_str()));
|
||||
|
||||
// < 3.1.0 ADT MMDX section store filename.mdx filenames for corresponded .m2 file
|
||||
if (!strcmp(ext, ".mdx"))
|
||||
{
|
||||
// replace .mdx -> .m2
|
||||
fname.erase(fname.length() - 2, 2);
|
||||
fname.append("2");
|
||||
origPath.erase(origPath.length() - 2, 2);
|
||||
origPath.append("2");
|
||||
}
|
||||
// >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
|
||||
// nothing do
|
||||
|
||||
fixedName = GetPlainName(origPath.c_str());
|
||||
|
||||
std::string output(szWorkDirWmo); // Stores output filename (possible changed)
|
||||
output += "/";
|
||||
output += GetPlainName(fname.c_str());
|
||||
output += fixedName;
|
||||
|
||||
if (FileExists(output.c_str()))
|
||||
return true;
|
||||
|
||||
Model mdl(fname);
|
||||
Model mdl(origPath); // Possible changed fname
|
||||
if (!mdl.open(failedPaths))
|
||||
return false;
|
||||
|
||||
|
|
@ -65,11 +67,11 @@ void ExtractGameobjectModels()
|
|||
char* name = GetPlainName((char*)path.c_str());
|
||||
fixname2(name, strlen(name));
|
||||
|
||||
char* ch_ext = GetExtension(name);
|
||||
char const* ch_ext = GetExtension(name);
|
||||
if (!ch_ext)
|
||||
continue;
|
||||
|
||||
strToLower(ch_ext);
|
||||
//strToLower(ch_ext);
|
||||
|
||||
bool result = false;
|
||||
if (!strcmp(ch_ext, ".wmo"))
|
||||
|
|
@ -83,7 +85,8 @@ void ExtractGameobjectModels()
|
|||
}
|
||||
else //if (!strcmp(ch_ext, ".mdx") || !strcmp(ch_ext, ".m2"))
|
||||
{
|
||||
result = ExtractSingleModel(path, failedPaths);
|
||||
std::string fixedName;
|
||||
result = ExtractSingleModel(path, fixedName, failedPaths);
|
||||
}
|
||||
|
||||
if (result)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,12 @@ bool FileExists(const char* file);
|
|||
void strToLower(char* str);
|
||||
|
||||
bool ExtractSingleWmo(std::string& fname);
|
||||
bool ExtractSingleModel(std::string& fname, StringSet& failedPaths);
|
||||
|
||||
/* @param origPath = original path of the model, cleaned with fixnamen and fixname2
|
||||
* @param fixedName = will store the translated name (if changed)
|
||||
* @param failedPaths = Set to collect errors
|
||||
*/
|
||||
bool ExtractSingleModel(std::string& origPath, std::string& fixedName, StringSet& failedPaths);
|
||||
|
||||
void ExtractGameobjectModels();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# This code is part of MaNGOS. Contributor & Copyright details are in AUTHORS/THANKS.
|
||||
#
|
||||
# This file is part of the MaNGOS Project. See AUTHORS file for Copyright information
|
||||
#
|
||||
# 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
|
||||
|
|
@ -13,6 +14,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_E
|
|||
18 EVENT_T_TARGET_MANA ManaMax%, ManaMin%, RepeatMin, RepeatMax Expires when current target's Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4) If Event Conditions Are Still Met.
|
||||
21 EVENT_T_REACHED_HOME NONE Expires when a creature reaches it's home (spawn) location after evade. This is commonly used for NPC's who Stealth once reaching their Spawn Location
|
||||
22 EVENT_T_RECEIVE_EMOTE EmoteId, Condition, CondValue1, CondValue2 Expires when a creature receives an emote with emote text id ("enum TextEmotes" from SharedDefines.h in Mangos Source) in (Param1). Conditions can be defined (Param2) with optional values (Param3,Param4), see (enum ConditionType) in ObjectMgr.h (Mangos Source).
|
||||
23 EVENT_T_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a creature has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4) If Event Conditions Are Still Met.
|
||||
23 EVENT_T_AURA SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a creature has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4) If Event Conditions Are Still Met.
|
||||
24 EVENT_T_TARGET_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a target unit has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4) If Event Conditions Are Still Met.
|
||||
25 EVENT_T_SUMMONED_JUST_DIED CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (Param1) is die (Param1 = 0 means all spawns). Will repeat every (Param2) and (Param3).
|
||||
26 EVENT_T_SUMMONED_JUST_DESPAWN CreatureId, RepeatMin, RepeatMax Expires before creature with entry = (Param1) is despawn (Param1 = 0 means all spawns). Will repeat every (Param2) and (Param3).
|
||||
|
|
@ -374,7 +374,7 @@ Expires only when creature receive emote from player. Valid text emote id's are
|
|||
Event does not require any conditions to process, however many are expected to have condition.
|
||||
|
||||
---------------------------
|
||||
23 = EVENT_T_BUFFED :
|
||||
23 = EVENT_T_AURA:
|
||||
---------------------------
|
||||
Parameter 1: SpellId - This is the SpellID That the Aura Check will look for
|
||||
Parameter 2: Amount - This is the amount of SpellID's auras at creature required for event expire.
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ DROP TABLE IF EXISTS `character_db_version`;
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `character_db_version` (
|
||||
`required_12697_01_characters_characters` bit(1) default NULL
|
||||
`required_12774_01_characters_characters` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
|
@ -795,7 +795,6 @@ CREATE TABLE `character_queststatus_daily` (
|
|||
`guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`quest` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Quest Identifier',
|
||||
PRIMARY KEY (`guid`,`quest`),
|
||||
KEY `idx_guid` (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
|
@ -819,7 +818,6 @@ CREATE TABLE `character_queststatus_monthly` (
|
|||
`guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`quest` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Quest Identifier',
|
||||
PRIMARY KEY (`guid`,`quest`),
|
||||
KEY `idx_guid` (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
|
@ -843,7 +841,6 @@ CREATE TABLE `character_queststatus_weekly` (
|
|||
`guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`quest` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Quest Identifier',
|
||||
PRIMARY KEY (`guid`,`quest`),
|
||||
KEY `idx_guid` (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
|
@ -919,8 +916,6 @@ CREATE TABLE `character_social` (
|
|||
`flags` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Friend Flags',
|
||||
`note` varchar(48) NOT NULL DEFAULT '' COMMENT 'Friend Note',
|
||||
PRIMARY KEY (`guid`,`friend`,`flags`),
|
||||
KEY `guid` (`guid`),
|
||||
KEY `friend` (`friend`),
|
||||
KEY `guid_flags` (`guid`,`flags`),
|
||||
KEY `friend_flags` (`friend`,`flags`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System';
|
||||
|
|
@ -1048,7 +1043,6 @@ CREATE TABLE `character_talent` (
|
|||
`current_rank` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`spec` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`talent_id`,`spec`),
|
||||
KEY `guid_key` (`guid`),
|
||||
KEY `talent_key` (`talent_id`),
|
||||
KEY `spec_key` (`spec`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
|
@ -1455,7 +1449,6 @@ CREATE TABLE `guild_bank_eventlog` (
|
|||
`DestTabId` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Destination Tab Id',
|
||||
`TimeStamp` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Event UNIX time',
|
||||
PRIMARY KEY (`guildid`,`LogGuid`,`TabId`),
|
||||
KEY `guildid_key` (`guildid`),
|
||||
KEY `Idx_PlayerGuid` (`PlayerGuid`),
|
||||
KEY `Idx_LogGuid` (`LogGuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
|
@ -1484,7 +1477,6 @@ CREATE TABLE `guild_bank_item` (
|
|||
`item_guid` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`item_entry` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guildid`,`TabId`,`SlotId`),
|
||||
KEY `guildid_key` (`guildid`),
|
||||
KEY `Idx_item_guid` (`item_guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
|
@ -1511,8 +1503,7 @@ CREATE TABLE `guild_bank_right` (
|
|||
`rid` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`gbright` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`SlotPerDay` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guildid`,`TabId`,`rid`),
|
||||
KEY `guildid_key` (`guildid`)
|
||||
PRIMARY KEY (`guildid`,`TabId`,`rid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
|
@ -1538,8 +1529,7 @@ CREATE TABLE `guild_bank_tab` (
|
|||
`TabName` varchar(100) NOT NULL DEFAULT '',
|
||||
`TabIcon` varchar(100) NOT NULL DEFAULT '',
|
||||
`TabText` text,
|
||||
PRIMARY KEY (`guildid`,`TabId`),
|
||||
KEY `guildid_key` (`guildid`)
|
||||
PRIMARY KEY (`guildid`,`TabId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
|
@ -1611,7 +1601,6 @@ CREATE TABLE `guild_member` (
|
|||
`BankResetTimeTab5` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`BankRemSlotsTab5` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
UNIQUE KEY `guid_key` (`guid`),
|
||||
KEY `guildid_key` (`guildid`),
|
||||
KEY `guildid_rank_key` (`guildid`,`rank`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Guild System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
|
|
|||
110
sql/mangos.sql
110
sql/mangos.sql
|
|
@ -276,7 +276,7 @@ LOCK TABLES `command` WRITE;
|
|||
INSERT INTO `command` (`name`, `security`, `help`) VALUES
|
||||
('account',0,'Syntax: .account\r\n\r\nDisplay the access level of your account.'),
|
||||
('account characters',3,'Syntax: .account characters [#accountId|$accountName]\r\n\r\nShow list all characters for account selected by provided #accountId or $accountName, or for selected player in game.'),
|
||||
('account create',4,'Syntax: .account create $account $password\r\n\r\nCreate account and set password to it.'),
|
||||
('account create',4,'Syntax: .account create $account $password [$expansion]\r\n\r\nCreate account and set password to it. Optionally, you may also set another expansion for this account than the defined default value.'),
|
||||
('account delete',4,'Syntax: .account delete $account\r\n\r\nDelete account with all characters.'),
|
||||
('account lock',0,'Syntax: .account lock [on|off]\r\n\r\nAllow login from account only from current used IP or remove this requirement.'),
|
||||
('account onlinelist',4,'Syntax: .account onlinelist\r\n\r\nShow list of online accounts.'),
|
||||
|
|
@ -1002,13 +1002,13 @@ INSERT INTO `creature_model_info` (`modelid`, `bounding_radius`, `combat_reach`,
|
|||
(1479,0.306,1.5,1,1478,0),
|
||||
(1563,0.3519,1.5,0,1564,0),
|
||||
(1564,0.3519,1.5,1,1563,0),
|
||||
(6894,0.389,1.5,0,6895,0),
|
||||
(6895,0.389,1.5,1,6894,0),
|
||||
(10045,1,1.5,2,0,0),
|
||||
(15475,0.383,1.5,1,15476,0),
|
||||
(15476,0.383,1.5,0,15475,0),
|
||||
(16125,1,1.5,0,16126,0),
|
||||
(16126,1,1.5,1,16125,0),
|
||||
(6894,0.389,1.5,0,6895,0),
|
||||
(6895,0.389,1.5,1,6894,0),
|
||||
(29422,0.389,1.5,0,29423,0),
|
||||
(29423,0.389,1.5,1,29422,0);
|
||||
/*!40000 ALTER TABLE `creature_model_info` ENABLE KEYS */;
|
||||
|
|
@ -1355,6 +1355,11 @@ CREATE TABLE `db_script_string` (
|
|||
`content_loc6` text,
|
||||
`content_loc7` text,
|
||||
`content_loc8` text,
|
||||
`sound` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`type` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`language` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`emote` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`comment` text,
|
||||
PRIMARY KEY (`entry`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
|
@ -21320,6 +21325,18 @@ CREATE TABLE `spell_proc_event` (
|
|||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `spell_proc_event`
|
||||
--
|
||||
|
||||
LOCK TABLES `spell_proc_event` WRITE;
|
||||
/*!40000 ALTER TABLE `spell_proc_event` DISABLE KEYS */;
|
||||
INSERT INTO `spell_proc_event` VALUES
|
||||
(67712, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 2),
|
||||
(67758, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 2);
|
||||
/*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `spell_proc_item_enchant`
|
||||
--
|
||||
|
|
@ -21341,14 +21358,14 @@ CREATE TABLE `spell_proc_item_enchant` (
|
|||
LOCK TABLES `spell_proc_item_enchant` WRITE;
|
||||
/*!40000 ALTER TABLE `spell_proc_item_enchant` DISABLE KEYS */;
|
||||
INSERT INTO `spell_proc_item_enchant` (`entry`, `ppmRate`) VALUES
|
||||
(8034,9),
|
||||
(8680,8.5714),
|
||||
(13218,21.4286),
|
||||
(13897,6),
|
||||
(20004,6),
|
||||
(20005,1.6),
|
||||
(44525,3.4),
|
||||
(44578,3.4);
|
||||
(8034, 9), -- Frostbrand Weapon
|
||||
(8680, 8.5714), -- Instant Poison
|
||||
(13218, 21.4286), -- Wound Poison
|
||||
(13897, 6.0), -- Enchant Weapon - Fiery Weapon
|
||||
(20004, 6.0), -- Enchant Weapon - Lifestealing
|
||||
(20005, 1.6), -- Enchant Weapon - Icy Chill
|
||||
(44525, 3.4), -- Enchant Weapon - Icebreaker
|
||||
(44578, 3.4); -- Enchant Weapon - Lifeward
|
||||
/*!40000 ALTER TABLE `spell_proc_item_enchant` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
|
@ -21414,6 +21431,7 @@ CREATE TABLE `spell_template` (
|
|||
`attr` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`attr_ex` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`attr_ex2` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`attr_ex3` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`proc_flags` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`proc_chance` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`duration_index` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
|
|
@ -21435,40 +21453,42 @@ CREATE TABLE `spell_template` (
|
|||
LOCK TABLES `spell_template` WRITE;
|
||||
/*!40000 ALTER TABLE `spell_template` DISABLE KEYS */;
|
||||
INSERT INTO `spell_template` VALUES
|
||||
-- id attr attr_ex attr_ex2 proc_flags chnce dur ef0 tarA0 tarB0 rad aur misc miscB, trigger
|
||||
(21387, 0x00000140, 0x10000000, 0x00000000, 0x00000028, 15, 21, 6, 1, 0, 0, 42, 0, 0, 21388, 'Melt-Weapon trigger aura related used by Ragnaros'),
|
||||
(23363, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 101, 21, 76, 18, 0, 0, 0, 179804, 0, 0, 'Summon Drakonid Corpse Trigger'),
|
||||
(25192, 0x00000100, 0x00000000, 0x00000004, 0x00000000, 101, 21, 76, 18, 0, 0, 0, 180619, 0, 0, 'Summon Ossirian Crystal'),
|
||||
(26133, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 101, 21, 76, 18, 0, 0, 0, 180795, 0, 0, 'Summon Sandworm Base'),
|
||||
(34810, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 42, 0, 8, 0, 20083, 64, 0, 'Summon Summoned Bloodwarder Mender behind of the caster'),
|
||||
(34817, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 44, 0, 8, 0, 20078, 64, 0, 'Summon Summoned Bloodwarder Reservist right of the caster'),
|
||||
(34818, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 43, 0, 8, 0, 20078, 64, 0, 'Summon Summoned Bloodwarder Reservist left of the caster'),
|
||||
(34819, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 41, 0, 8, 0, 20078, 64, 0, 'Summon Summoned Bloodwarder Reservist front of the caster'),
|
||||
(35153, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 42, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge behind of the caster'),
|
||||
(35904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 44, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge right of the caster'),
|
||||
(35905, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 43, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge left of the caster'),
|
||||
(35906, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 41, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge front of the caster'),
|
||||
(37264, 0x00000180, 0x00000000, 0x00000004, 0x00000000, 101, 21, 28, 18, 0, 7, 0, 21729, 64, 0, 'Power Converters: Summon Electromental (from cata)'),
|
||||
(37278, 0x00000180, 0x00000000, 0x00000004, 0x00000000, 101, 21, 28, 18, 0, 1, 0, 21737, 64, 0, 'Power Converters: Summon Mini-Electromental (from cata)'),
|
||||
(37365, 0x00000180, 0x00000000, 0x00000004, 0x00000000, 101, 21, 28, 18, 0, 1, 0, 21757, 64, 0, 'Power Converters: Summon Big Flavor Electromental (from cata)'),
|
||||
(44920, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24941, 0, 0, 'Model - Shattered Sun Marksman - BE Male Tier 4'),
|
||||
(44924, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24945, 0, 0, 'Model - Shattered Sun Marksman - BE Female Tier 4'),
|
||||
(44928, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24949, 0, 0, 'Model - Shattered Sun Marksman - Draenei Male Tier 4'),
|
||||
(44932, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24953, 0, 0, 'Model - Shattered Sun Marksman - Draenei Female Tier 4'),
|
||||
(45158, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25119, 0, 0, 'Model - Shattered Sun Warrior - BE Female Tier 4'),
|
||||
(45162, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25123, 0, 0, 'Model - Shattered Sun Warrior - BE Male Tier 4'),
|
||||
(45166, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25127, 0, 0, 'Model - Shattered Sun Warrior - Draenei Female Tier 4'),
|
||||
(45170, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25131, 0, 0, 'Model - Shattered Sun Warrior - Draenei Male Tier 4'),
|
||||
(58630, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Mal\'Ganis'),
|
||||
(59046, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Tribunal of Ages'),
|
||||
(59450, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - The Four Horsemen'),
|
||||
(62388, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 4, 0, 0, 0, 'Aura required for Demonic Circle 48020'),
|
||||
(64899, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Hodir'),
|
||||
(64985, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Thorim'),
|
||||
(65074, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Freya'),
|
||||
(65195, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Assembly of Iron'),
|
||||
(68184, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Faction Champions'),
|
||||
(72845, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Pit of Saron - Don\'t Look Up');
|
||||
-- id attr attr_ex attr_ex2 attr_ex3 proc_flags chnce dur ef0 tarA0 tarB0 rad aur misc miscB, trigger
|
||||
(21387, 0x00000140, 0x10000000, 0x00000000, 0x00000000, 0x00000028, 15, 21, 6, 1, 0, 0, 42, 0, 0, 21388, 'Melt-Weapon trigger aura related used by Ragnaros'),
|
||||
(23363, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 76, 18, 0, 0, 0, 179804, 0, 0, 'Summon Drakonid Corpse Trigger'),
|
||||
(23770, 0x24800100, 0x10000088, 0x00000001, 0x00100000, 0x00000000, 101, 367, 6, 25, 0, 0, 4, 0, 0, 0, 'Sayge''s timer - Darkmoon Faire'),
|
||||
(25192, 0x00000100, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 101, 21, 76, 18, 0, 0, 0, 180619, 0, 0, 'Summon Ossirian Crystal'),
|
||||
(26133, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 76, 18, 0, 0, 0, 180795, 0, 0, 'Summon Sandworm Base'),
|
||||
(34810, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 42, 0, 8, 0, 20083, 64, 0, 'Summon Summoned Bloodwarder Mender behind of the caster'),
|
||||
(34817, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 44, 0, 8, 0, 20078, 64, 0, 'Summon Summoned Bloodwarder Reservist right of the caster'),
|
||||
(34818, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 43, 0, 8, 0, 20078, 64, 0, 'Summon Summoned Bloodwarder Reservist left of the caster'),
|
||||
(34819, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 41, 0, 8, 0, 20078, 64, 0, 'Summon Summoned Bloodwarder Reservist front of the caster'),
|
||||
(35153, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 42, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge behind of the caster'),
|
||||
(35904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 44, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge right of the caster'),
|
||||
(35905, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 43, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge left of the caster'),
|
||||
(35906, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 28, 41, 0, 8, 0, 20405, 64, 0, 'Summon Nether Charge front of the caster'),
|
||||
(37264, 0x00000180, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 101, 21, 28, 18, 0, 7, 0, 21729, 64, 0, 'Power Converters: Summon Electromental (from cata)'),
|
||||
(37278, 0x00000180, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 101, 21, 28, 18, 0, 1, 0, 21737, 64, 0, 'Power Converters: Summon Mini-Electromental (from cata)'),
|
||||
(37365, 0x00000180, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 101, 21, 28, 18, 0, 1, 0, 21757, 64, 0, 'Power Converters: Summon Big Flavor Electromental (from cata)'),
|
||||
(44920, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24941, 0, 0, 'Model - Shattered Sun Marksman - BE Male Tier 4'),
|
||||
(44924, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24945, 0, 0, 'Model - Shattered Sun Marksman - BE Female Tier 4'),
|
||||
(44928, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24949, 0, 0, 'Model - Shattered Sun Marksman - Draenei Male Tier 4'),
|
||||
(44932, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 24953, 0, 0, 'Model - Shattered Sun Marksman - Draenei Female Tier 4'),
|
||||
(45158, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25119, 0, 0, 'Model - Shattered Sun Warrior - BE Female Tier 4'),
|
||||
(45162, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25123, 0, 0, 'Model - Shattered Sun Warrior - BE Male Tier 4'),
|
||||
(45166, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25127, 0, 0, 'Model - Shattered Sun Warrior - Draenei Female Tier 4'),
|
||||
(45170, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 56, 25131, 0, 0, 'Model - Shattered Sun Warrior - Draenei Male Tier 4'),
|
||||
(50574, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 0, 90, 25, 0, 11, 0, 28042, 0, 0, 'Captain Brandon Kill Credit'),
|
||||
(58630, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Mal\'Ganis'),
|
||||
(59046, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Tribunal of Ages'),
|
||||
(59450, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - The Four Horsemen'),
|
||||
(62388, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 101, 21, 6, 1, 0, 0, 4, 0, 0, 0, 'Aura required for Demonic Circle 48020'),
|
||||
(64899, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Hodir'),
|
||||
(64985, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Thorim'),
|
||||
(65074, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Freya'),
|
||||
(65195, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Assembly of Iron'),
|
||||
(68184, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Faction Champions'),
|
||||
(72845, 0x00800180, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 101, 37, 6, 22, 7, 28, 4, 0, 0, 0, 'Achievement check - Pit of Saron - Don\'t Look Up');
|
||||
/*!40000 ALTER TABLE `spell_template` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
|
|
|||
15
sql/updates/12774_01_characters_characters.sql
Normal file
15
sql/updates/12774_01_characters_characters.sql
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
ALTER TABLE character_db_version CHANGE COLUMN required_12697_01_characters_characters required_12774_01_characters_characters bit;
|
||||
|
||||
ALTER TABLE character_queststatus_daily DROP INDEX idx_guid;
|
||||
ALTER TABLE character_queststatus_monthly DROP INDEX idx_guid;
|
||||
ALTER TABLE character_queststatus_weekly DROP INDEX idx_guid;
|
||||
ALTER TABLE character_social DROP INDEX friend;
|
||||
ALTER TABLE character_social DROP INDEX guid;
|
||||
ALTER TABLE character_talent DROP INDEX guid_key;
|
||||
ALTER TABLE guild_bank_eventlog DROP INDEX guildid_key;
|
||||
ALTER TABLE guild_bank_item DROP INDEX guildid_key;
|
||||
ALTER TABLE guild_bank_right DROP INDEX guildid_key;
|
||||
ALTER TABLE guild_bank_tab DROP INDEX guildid_key;
|
||||
ALTER TABLE guild_member DROP INDEX guildid_key;
|
||||
|
||||
ALTER TABLE playercreateinfo_action DROP INDEX playercreateinfo_race_class_index;
|
||||
211
sql/updates/12774_01_mangos.sql
Normal file
211
sql/updates/12774_01_mangos.sql
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_12662_01_mangos_hotfix_data required_12774_01_mangos bit;
|
||||
|
||||
ALTER TABLE spell_template ADD COLUMN attr_ex3 int(11) unsigned NOT NULL DEFAULT '0' AFTER attr_ex2;
|
||||
|
||||
DELETE FROM spell_template WHERE id=23770;
|
||||
INSERT INTO spell_template VALUES
|
||||
(23770, 0x24800100, 0x10000088, 0x00000001, 0x00100000, 0x00000000, 101, 367, 6, 25, 0, 0, 4, 0, 0, 0, 'Sayge''s timer - Darkmoon Faire');
|
||||
|
||||
DELETE FROM spell_proc_event WHERE entry IN (67712, 67758);
|
||||
INSERT INTO spell_proc_event VALUES
|
||||
(67712, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 2),
|
||||
(67758, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 2);
|
||||
|
||||
ALTER TABLE db_script_string ADD COLUMN sound mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER content_loc8;
|
||||
ALTER TABLE db_script_string ADD COLUMN type tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER sound;
|
||||
ALTER TABLE db_script_string ADD COLUMN language tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER type;
|
||||
ALTER TABLE db_script_string ADD COLUMN emote smallint(5) unsigned NOT NULL DEFAULT '0' AFTER language;
|
||||
ALTER TABLE db_script_string ADD COLUMN comment text AFTER emote;
|
||||
|
||||
-- Update Dbscript_string with the type and language from Dbscripts_on_*
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS db_script_temp AS
|
||||
-- dbscripts_on_creature_death
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_creature_death B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_creature_movement
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_creature_movement B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_event
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_event B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_gossip
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_gossip B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_go_template_use
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_go_template_use B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_go_use
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_go_use B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_quest_end
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_quest_end B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_quest_start
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_quest_start B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4)
|
||||
-- dbscripts_on_spell
|
||||
UNION ALL
|
||||
SELECT A.entry
|
||||
,A.content_default
|
||||
,A.content_loc1
|
||||
,A.content_loc2
|
||||
,A.content_loc3
|
||||
,A.content_loc4
|
||||
,A.content_loc5
|
||||
,A.content_loc6
|
||||
,A.content_loc7
|
||||
,A.content_loc8
|
||||
,0 AS sound
|
||||
,B.datalong AS type
|
||||
,B.datalong2 AS language
|
||||
,0 AS emote
|
||||
,NULL AS comment
|
||||
FROM db_script_string A
|
||||
INNER JOIN dbscripts_on_spell B ON (A.entry = B.dataint OR A.entry = B.dataint2 OR A.entry = B.dataint3 OR A.entry = B.dataint4);
|
||||
|
||||
-- Clean dbscript_string and insert the new updated values
|
||||
DELETE FROM db_script_string WHERE entry IN (SELECT DISTINCT entry FROM db_script_temp);
|
||||
INSERT INTO db_script_string SELECT * FROM db_script_temp GROUP BY entry;
|
||||
DROP TABLE IF EXISTS db_script_temp;
|
||||
|
||||
DELETE FROM playercreateinfo_spell WHERE race=10 AND Spell=61437;
|
||||
INSERT INTO playercreateinfo_spell (race, class, Spell, Note) VALUES
|
||||
(10,2,61437,'Opening'),
|
||||
(10,3,61437,'Opening'),
|
||||
(10,4,61437,'Opening'),
|
||||
(10,5,61437,'Opening'),
|
||||
(10,6,61437,'Opening'),
|
||||
(10,8,61437,'Opening'),
|
||||
(10,9,61437,'Opening');
|
||||
|
||||
UPDATE `command` SET help = 'Syntax: .account create $account $password [$expansion]\r\n\r\nCreate account and set password to it. Optionally, you may also set another expansion for this account than the defined default value.' WHERE name = 'account create';
|
||||
|
||||
ALTER TABLE playercreateinfo_action DROP INDEX playercreateinfo_race_class_index;
|
||||
|
||||
|
|
@ -17,5 +17,7 @@
|
|||
# Clone https://github.com/mangosthree/scripts here, and comment out
|
||||
# the next line and uncomment the last line.
|
||||
|
||||
# add_subdirectory(universal)
|
||||
if(INCLUDE_BINDINGS_DIR)
|
||||
add_subdirectory(${INCLUDE_BINDINGS_DIR})
|
||||
endif()
|
||||
# add_subdirectory(scripts)
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
# This code is part of MaNGOS. Contributor & Copyright details are in AUTHORS/THANKS.
|
||||
#
|
||||
# This file is part of the MaNGOS Project. See AUTHORS file for Copyright information
|
||||
#
|
||||
# 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
|
||||
|
|
@ -13,12 +14,16 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
set(LIBRARY_NAME framework)
|
||||
|
||||
set(LIBRARY_SRCS
|
||||
set(SRC_GRP_DYNAMIC
|
||||
Dynamic/FactoryHolder.h
|
||||
Dynamic/ObjectRegistry.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_GAMESYSTEM
|
||||
GameSystem/Grid.h
|
||||
GameSystem/GridLoader.h
|
||||
GameSystem/GridReference.h
|
||||
|
|
@ -27,51 +32,74 @@ set(LIBRARY_SRCS
|
|||
GameSystem/TypeContainer.h
|
||||
GameSystem/TypeContainerFunctions.h
|
||||
GameSystem/TypeContainerVisitor.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_PLATFORM
|
||||
Platform/CompilerDefs.h
|
||||
Platform/Define.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_POLICIES
|
||||
Policies/CreationPolicy.h
|
||||
Policies/MemoryManagement.cpp
|
||||
Policies/ObjectLifeTime.cpp
|
||||
Policies/ObjectLifeTime.h
|
||||
Policies/Singleton.h
|
||||
Policies/ThreadingModel.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_UTIL
|
||||
Utilities/ByteConverter.h
|
||||
Utilities/Callback.h
|
||||
Utilities/EventProcessor.cpp
|
||||
Utilities/EventProcessor.h
|
||||
Utilities/LinkedList.h
|
||||
Utilities/LinkedReference/Reference.h
|
||||
Utilities/LinkedReference/RefManager.h
|
||||
Utilities/TypeList.h
|
||||
Utilities/UnorderedMapSet.h
|
||||
)
|
||||
|
||||
source_group("Other"
|
||||
REGULAR_EXPRESSION .*
|
||||
set(SRC_GRP_LINKED_REFERENCE
|
||||
Utilities/LinkedReference/Reference.h
|
||||
Utilities/LinkedReference/RefManager.h
|
||||
)
|
||||
|
||||
source_group("GameSystem"
|
||||
REGULAR_EXPRESSION GameSystem
|
||||
)
|
||||
|
||||
source_group("Platform"
|
||||
REGULAR_EXPRESSION Platform
|
||||
)
|
||||
|
||||
source_group("Policies"
|
||||
REGULAR_EXPRESSION Policies
|
||||
)
|
||||
|
||||
source_group("Utilities"
|
||||
REGULAR_EXPRESSION Utilities
|
||||
)
|
||||
|
||||
source_group("LinkedReference"
|
||||
REGULAR_EXPRESSION LinkedReference
|
||||
set(LIBRARY_SRCS
|
||||
${SRC_GRP_DYNAMIC}
|
||||
${SRC_GRP_GAMESYSTEM}
|
||||
${SRC_GRP_PLATFORM}
|
||||
${SRC_GRP_POLICIES}
|
||||
${SRC_GRP_UTIL}
|
||||
${SRC_GRP_LINKED_REFERENCE}
|
||||
)
|
||||
|
||||
source_group("Dynamic"
|
||||
REGULAR_EXPRESSION Dynamic
|
||||
FILES
|
||||
${SRC_GRP_DYNAMIC}
|
||||
)
|
||||
|
||||
source_group("GameSystem"
|
||||
FILES
|
||||
${SRC_GRP_GAMESYSTEM}
|
||||
)
|
||||
|
||||
source_group("Platform"
|
||||
FILES
|
||||
${SRC_GRP_PLATFORM}
|
||||
)
|
||||
|
||||
source_group("Policies"
|
||||
FILES
|
||||
${SRC_GRP_POLICIES}
|
||||
)
|
||||
|
||||
source_group("Utilities"
|
||||
FILES
|
||||
${SRC_GRP_UTIL}
|
||||
)
|
||||
|
||||
source_group("Utilities\\LinkedReference"
|
||||
FILES
|
||||
${SRC_GRP_LINKED_REFERENCE}
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
|
|
|||
|
|
@ -55,6 +55,26 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
|
|||
return AOR_OK; // everything's fine
|
||||
}
|
||||
|
||||
AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, uint32 expansion)
|
||||
{
|
||||
if (utf8length(username) > MAX_ACCOUNT_STR)
|
||||
return AOR_NAME_TOO_LONG; // username's too long
|
||||
|
||||
normalizeString(username);
|
||||
normalizeString(password);
|
||||
|
||||
if (GetId(username))
|
||||
{
|
||||
return AOR_NAME_ALREDY_EXIST; // username does already exist
|
||||
}
|
||||
|
||||
if (!LoginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate,expansion) VALUES('%s','%s',NOW(),'%u')", username.c_str(), CalculateShaPassHash(username, password).c_str(), expansion))
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error
|
||||
LoginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
|
||||
|
||||
return AOR_OK; // everything's fine
|
||||
}
|
||||
|
||||
AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
|
||||
{
|
||||
QueryResult* result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%u'", accid);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class AccountMgr
|
|||
~AccountMgr();
|
||||
|
||||
AccountOpResult CreateAccount(std::string username, std::string password);
|
||||
AccountOpResult CreateAccount(std::string username, std::string password, uint32 expansion);
|
||||
AccountOpResult DeleteAccount(uint32 accid);
|
||||
AccountOpResult ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd);
|
||||
AccountOpResult ChangePassword(uint32 accid, std::string new_passwd);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# This code is part of MaNGOS. Contributor & Copyright details are in AUTHORS/THANKS.
|
||||
#
|
||||
# This file is part of the MaNGOS Project. See AUTHORS file for Copyright information
|
||||
#
|
||||
# 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
|
||||
|
|
@ -13,26 +14,34 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
set(LIBRARY_NAME game)
|
||||
|
||||
set(LIBRARY_SRCS
|
||||
AccountMgr.cpp
|
||||
AccountMgr.h
|
||||
AchievementMgr.cpp
|
||||
AchievementMgr.h
|
||||
AggressorAI.cpp
|
||||
AggressorAI.h
|
||||
ArenaTeam.cpp
|
||||
ArenaTeam.h
|
||||
ArenaTeamHandler.cpp
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vmap
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouseBot
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BattleGround
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/OutdoorPvP
|
||||
${CMAKE_SOURCE_DIR}/dep/include/g3dlite
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/
|
||||
${CMAKE_SOURCE_DIR}/dep/include
|
||||
${CMAKE_SOURCE_DIR}/src/shared
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/src/shared
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${ACE_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(SRC_GRP_AHBOT
|
||||
AuctionHouseBot/AuctionHouseBot.cpp
|
||||
AuctionHouseBot/AuctionHouseBot.h
|
||||
AuctionHouseHandler.cpp
|
||||
AuctionHouseMgr.cpp
|
||||
AuctionHouseMgr.h
|
||||
Bag.cpp
|
||||
Bag.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_BATTLEGROUND
|
||||
BattleGround/BattleGround.cpp
|
||||
BattleGround/BattleGround.h
|
||||
BattleGround/BattleGroundAA.cpp
|
||||
|
|
@ -64,27 +73,72 @@ set(LIBRARY_SRCS
|
|||
BattleGround/BattleGroundSA.h
|
||||
BattleGround/BattleGroundWS.cpp
|
||||
BattleGround/BattleGroundWS.h
|
||||
Calendar.cpp
|
||||
Calendar.h
|
||||
CalendarHandler.cpp
|
||||
Camera.cpp
|
||||
Camera.h
|
||||
Cell.h
|
||||
CellImpl.h
|
||||
Channel.cpp
|
||||
Channel.h
|
||||
ChannelHandler.cpp
|
||||
ChannelMgr.cpp
|
||||
ChannelMgr.h
|
||||
CharacterDatabaseCleaner.cpp
|
||||
CharacterDatabaseCleaner.h
|
||||
CharacterHandler.cpp
|
||||
Chat.cpp
|
||||
Chat.h
|
||||
ChatHandler.cpp
|
||||
CombatHandler.cpp
|
||||
)
|
||||
|
||||
set(SRC_GRP_CHAT_COMMANDS
|
||||
debugcmds.cpp
|
||||
Level0.cpp
|
||||
Level1.cpp
|
||||
Level2.cpp
|
||||
Level3.cpp
|
||||
)
|
||||
|
||||
set(SRC_GRP_MOTION_GEN
|
||||
ConfusedMovementGenerator.cpp
|
||||
ConfusedMovementGenerator.h
|
||||
FleeingMovementGenerator.cpp
|
||||
FleeingMovementGenerator.h
|
||||
HomeMovementGenerator.cpp
|
||||
HomeMovementGenerator.h
|
||||
IdleMovementGenerator.cpp
|
||||
IdleMovementGenerator.h
|
||||
MotionMaster.cpp
|
||||
MotionMaster.h
|
||||
MovementGenerator.cpp
|
||||
MovementGenerator.h
|
||||
MovementGeneratorImpl.h # TODO: this is not in the VC files - does it belong in here?
|
||||
PathFinder.cpp
|
||||
PathFinder.h
|
||||
PointMovementGenerator.cpp
|
||||
PointMovementGenerator.h
|
||||
RandomMovementGenerator.cpp
|
||||
RandomMovementGenerator.h
|
||||
TargetedMovementGenerator.cpp
|
||||
TargetedMovementGenerator.h
|
||||
WaypointMovementGenerator.cpp
|
||||
WaypointMovementGenerator.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_MOVEMENT
|
||||
movement/MovementStructures.h
|
||||
movement/MoveSpline.cpp
|
||||
movement/MoveSpline.h
|
||||
movement/MoveSplineFlag.h
|
||||
movement/MoveSplineInit.cpp
|
||||
movement/MoveSplineInit.h
|
||||
movement/MoveSplineInitArgs.h
|
||||
movement/packet_builder.cpp
|
||||
movement/packet_builder.h
|
||||
movement/spline.cpp
|
||||
movement/spline.h
|
||||
movement/spline.impl.h
|
||||
movement/typedefs.h
|
||||
movement/util.cpp
|
||||
)
|
||||
|
||||
set(SRC_GRP_OBJECT
|
||||
AggressorAI.cpp
|
||||
AggressorAI.h
|
||||
ArenaTeam.cpp
|
||||
ArenaTeam.h
|
||||
AuctionHouseMgr.cpp
|
||||
AuctionHouseMgr.h
|
||||
Bag.cpp
|
||||
Bag.h
|
||||
Calendar.cpp
|
||||
Calendar.h
|
||||
Camera.cpp
|
||||
Camera.h
|
||||
Corpse.cpp
|
||||
Corpse.h
|
||||
Creature.cpp
|
||||
|
|
@ -100,136 +154,69 @@ set(LIBRARY_SRCS
|
|||
CreatureEventAI.h
|
||||
CreatureEventAIMgr.cpp
|
||||
CreatureEventAIMgr.h
|
||||
CreatureLinkingMgr.cpp
|
||||
CreatureLinkingMgr.h
|
||||
DB2fmt.h
|
||||
DB2Stores.cpp
|
||||
DB2Stores.h
|
||||
DB2Structure.h
|
||||
DBCEnums.h
|
||||
DBCfmt.h
|
||||
DBCStores.cpp
|
||||
DBCStores.h
|
||||
DBCStructure.cpp
|
||||
DBCStructure.h
|
||||
debugcmds.cpp
|
||||
DuelHandler.cpp
|
||||
DynamicObject.cpp
|
||||
DynamicObject.h
|
||||
FleeingMovementGenerator.cpp
|
||||
FleeingMovementGenerator.h
|
||||
FollowerReference.cpp
|
||||
FollowerReference.h
|
||||
FollowerRefManager.h
|
||||
Formulas.h
|
||||
GameEventMgr.cpp
|
||||
GameEventMgr.h
|
||||
GameObject.cpp
|
||||
GameObject.h
|
||||
GMTicketHandler.cpp
|
||||
GMTicketMgr.cpp
|
||||
GMTicketMgr.h
|
||||
GossipDef.cpp
|
||||
GossipDef.h
|
||||
GridDefines.h
|
||||
GridMap.cpp
|
||||
GridMap.h
|
||||
GridNotifiers.cpp
|
||||
GridNotifiers.h
|
||||
GridNotifiersImpl.h
|
||||
GridStates.cpp
|
||||
GridStates.h
|
||||
Group.cpp
|
||||
Group.h
|
||||
GroupHandler.cpp
|
||||
GroupReference.cpp
|
||||
GroupReference.h
|
||||
GroupRefManager.h
|
||||
GuardAI.cpp
|
||||
GuardAI.h
|
||||
Guild.cpp
|
||||
Guild.h
|
||||
GuildHandler.cpp
|
||||
GuildMgr.cpp
|
||||
GuildMgr.h
|
||||
HomeMovementGenerator.cpp
|
||||
HomeMovementGenerator.h
|
||||
HostileRefManager.cpp
|
||||
HostileRefManager.h
|
||||
IdleMovementGenerator.cpp
|
||||
IdleMovementGenerator.h
|
||||
InstanceData.cpp
|
||||
InstanceData.h
|
||||
Item.cpp
|
||||
Item.h
|
||||
ItemEnchantmentMgr.cpp
|
||||
ItemEnchantmentMgr.h
|
||||
ItemHandler.cpp
|
||||
ItemPrototype.h
|
||||
Language.h
|
||||
Level0.cpp
|
||||
Level1.cpp
|
||||
Level2.cpp
|
||||
Level3.cpp
|
||||
LFGHandler.cpp
|
||||
LootHandler.cpp
|
||||
LootMgr.cpp
|
||||
LootMgr.h
|
||||
Mail.cpp
|
||||
Mail.h
|
||||
MailHandler.cpp
|
||||
Map.cpp
|
||||
Map.h
|
||||
MapManager.cpp
|
||||
MapManager.h
|
||||
MapPersistentStateMgr.cpp
|
||||
MapPersistentStateMgr.h
|
||||
MapReference.h
|
||||
MapRefManager.h
|
||||
MassMailMgr.cpp
|
||||
MassMailMgr.h
|
||||
MiscHandler.cpp
|
||||
MotionMaster.cpp
|
||||
MotionMaster.h
|
||||
MoveMap.cpp
|
||||
MoveMap.h
|
||||
MoveMapSharedDefines.h
|
||||
movement/MoveSpline.cpp
|
||||
movement/MoveSpline.h
|
||||
movement/MoveSplineFlag.h
|
||||
movement/MoveSplineInit.cpp
|
||||
movement/MoveSplineInit.h
|
||||
movement/MoveSplineInitArgs.h
|
||||
movement/packet_builder.cpp
|
||||
movement/packet_builder.h
|
||||
movement/spline.cpp
|
||||
movement/spline.h
|
||||
movement/spline.impl.h
|
||||
movement/typedefs.h
|
||||
movement/util.cpp
|
||||
MovementGenerator.cpp
|
||||
MovementGenerator.h
|
||||
MovementGeneratorImpl.h
|
||||
MovementHandler.cpp
|
||||
MovementStructures.h
|
||||
NPCHandler.cpp
|
||||
NPCHandler.h
|
||||
NullCreatureAI.cpp
|
||||
NullCreatureAI.h
|
||||
Object.cpp
|
||||
Object.h
|
||||
ObjectAccessor.cpp
|
||||
ObjectAccessor.h
|
||||
ObjectGridLoader.cpp
|
||||
ObjectGridLoader.h
|
||||
ObjectGuid.cpp
|
||||
ObjectGuid.h
|
||||
ObjectMgr.cpp
|
||||
ObjectMgr.h
|
||||
ObjectPosSelector.cpp
|
||||
ObjectPosSelector.h
|
||||
Opcodes.cpp
|
||||
Opcodes.h
|
||||
Pet.cpp
|
||||
Pet.h
|
||||
PetAI.cpp
|
||||
PetAI.h
|
||||
Player.cpp
|
||||
Player.h
|
||||
ReactorAI.cpp
|
||||
ReactorAI.h
|
||||
ReputationMgr.cpp
|
||||
ReputationMgr.h
|
||||
SocialMgr.cpp
|
||||
SocialMgr.h
|
||||
SpellMgr.cpp
|
||||
SpellMgr.h
|
||||
StatSystem.cpp
|
||||
TemporarySummon.cpp
|
||||
TemporarySummon.h
|
||||
Totem.cpp
|
||||
Totem.h
|
||||
TotemAI.cpp
|
||||
TotemAI.h
|
||||
TransportSystem.cpp
|
||||
TransportSystem.h
|
||||
Unit.cpp
|
||||
Unit.h
|
||||
UnitEvents.h
|
||||
UpdateFields.h
|
||||
UpdateMask.h
|
||||
Vehicle.cpp
|
||||
Vehicle.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_OUTDOOR_PVP
|
||||
OutdoorPvP/OutdoorPvP.cpp
|
||||
OutdoorPvP/OutdoorPvP.h
|
||||
OutdoorPvP/OutdoorPvPEP.cpp
|
||||
|
|
@ -248,84 +235,56 @@ set(LIBRARY_SRCS
|
|||
OutdoorPvP/OutdoorPvPTF.h
|
||||
OutdoorPvP/OutdoorPvPZM.cpp
|
||||
OutdoorPvP/OutdoorPvPZM.h
|
||||
Path.h
|
||||
PathFinder.cpp
|
||||
PathFinder.h
|
||||
pchdef.cpp
|
||||
pchdef.h
|
||||
Pet.cpp
|
||||
Pet.h
|
||||
PetAI.cpp
|
||||
PetAI.h
|
||||
PetHandler.cpp
|
||||
PetitionsHandler.cpp
|
||||
Player.cpp
|
||||
Player.h
|
||||
PlayerDump.cpp
|
||||
PlayerDump.h
|
||||
PointMovementGenerator.cpp
|
||||
PointMovementGenerator.h
|
||||
PoolManager.cpp
|
||||
PoolManager.h
|
||||
QueryHandler.cpp
|
||||
QuestDef.cpp
|
||||
QuestDef.h
|
||||
QuestHandler.cpp
|
||||
RandomMovementGenerator.cpp
|
||||
RandomMovementGenerator.h
|
||||
ReactorAI.cpp
|
||||
ReactorAI.h
|
||||
ReputationMgr.cpp
|
||||
ReputationMgr.h
|
||||
ScriptMgr.cpp
|
||||
ScriptMgr.h
|
||||
SharedDefines.h
|
||||
SkillDiscovery.cpp
|
||||
SkillDiscovery.h
|
||||
SkillExtraItems.cpp
|
||||
SkillExtraItems.h
|
||||
SkillHandler.cpp
|
||||
SocialMgr.cpp
|
||||
SocialMgr.h
|
||||
Spell.cpp
|
||||
Spell.h
|
||||
SpellAuraDefines.h
|
||||
SpellAuras.cpp
|
||||
SpellAuras.h
|
||||
SpellEffects.cpp
|
||||
SpellHandler.cpp
|
||||
SpellMgr.cpp
|
||||
SpellMgr.h
|
||||
SQLStorages.cpp
|
||||
SQLStorages.h
|
||||
StatSystem.cpp
|
||||
TargetedMovementGenerator.cpp
|
||||
TargetedMovementGenerator.h
|
||||
TaxiHandler.cpp
|
||||
TemporarySummon.cpp
|
||||
TemporarySummon.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_REFERENCES
|
||||
FollowerReference.cpp
|
||||
FollowerReference.h
|
||||
FollowerRefManager.h
|
||||
GroupReference.cpp
|
||||
GroupReference.h
|
||||
GroupRefManager.h
|
||||
HostileRefManager.cpp
|
||||
HostileRefManager.h
|
||||
MapReference.h
|
||||
MapRefManager.h
|
||||
ThreatManager.cpp
|
||||
ThreatManager.h
|
||||
Totem.cpp
|
||||
Totem.h
|
||||
TotemAI.cpp
|
||||
TotemAI.h
|
||||
TradeHandler.cpp
|
||||
Transports.cpp
|
||||
Transports.h
|
||||
TransportSystem.cpp
|
||||
TransportSystem.h
|
||||
Unit.cpp
|
||||
Unit.h
|
||||
UnitAuraProcHandler.cpp
|
||||
UnitEvents.h
|
||||
UpdateData.cpp
|
||||
UpdateData.h
|
||||
UpdateFields.h
|
||||
UpdateMask.h
|
||||
Vehicle.cpp
|
||||
Vehicle.h
|
||||
VehicleHandler.cpp
|
||||
)
|
||||
|
||||
set(SRC_GRP_SERVER
|
||||
DB2fmt.h
|
||||
DB2Stores.cpp
|
||||
DB2Stores.h
|
||||
DB2Structure.h
|
||||
DBCEnums.h
|
||||
DBCfmt.h
|
||||
DBCStores.cpp
|
||||
DBCStores.h
|
||||
DBCStructure.cpp
|
||||
DBCStructure.h
|
||||
Opcodes.cpp
|
||||
Opcodes.h
|
||||
SharedDefines.h
|
||||
SQLStorages.cpp
|
||||
SQLStorages.h
|
||||
WorldSession.cpp
|
||||
WorldSession.h
|
||||
WorldSocket.cpp
|
||||
WorldSocket.h
|
||||
WorldSocketMgr.cpp
|
||||
WorldSocketMgr.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_TOOL
|
||||
CharacterDatabaseCleaner.cpp
|
||||
CharacterDatabaseCleaner.h
|
||||
Language.h
|
||||
PlayerDump.cpp
|
||||
PlayerDump.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_VMAPS
|
||||
vmap/BIH.cpp
|
||||
vmap/BIH.h
|
||||
vmap/BIHWrap.h
|
||||
|
|
@ -349,79 +308,190 @@ set(LIBRARY_SRCS
|
|||
vmap/VMapTools.h
|
||||
vmap/WorldModel.cpp
|
||||
vmap/WorldModel.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_WORLD_HANDLERS
|
||||
AccountMgr.cpp
|
||||
AccountMgr.h
|
||||
AchievementMgr.cpp
|
||||
AchievementMgr.h
|
||||
ArenaTeamHandler.cpp
|
||||
AuctionHouseHandler.cpp
|
||||
CalendarHandler.cpp
|
||||
Cell.h
|
||||
CellImpl.h
|
||||
Channel.cpp
|
||||
Channel.h
|
||||
ChannelHandler.cpp
|
||||
ChannelMgr.cpp
|
||||
ChannelMgr.h
|
||||
CharacterHandler.cpp
|
||||
Chat.cpp
|
||||
Chat.h
|
||||
ChatHandler.cpp
|
||||
CombatHandler.cpp
|
||||
CreatureLinkingMgr.cpp
|
||||
CreatureLinkingMgr.h
|
||||
DuelHandler.cpp
|
||||
GameEventMgr.cpp
|
||||
GameEventMgr.h
|
||||
GMTicketHandler.cpp
|
||||
GossipDef.cpp
|
||||
GossipDef.h
|
||||
GridDefines.h
|
||||
GridMap.cpp
|
||||
GridMap.h
|
||||
GridNotifiers.cpp
|
||||
GridNotifiers.h
|
||||
GridNotifiersImpl.h
|
||||
GridStates.cpp
|
||||
GridStates.h
|
||||
Group.cpp
|
||||
Group.h
|
||||
GroupHandler.cpp
|
||||
GuildHandler.cpp
|
||||
GuildMgr.cpp
|
||||
GuildMgr.h
|
||||
InstanceData.cpp
|
||||
InstanceData.h
|
||||
ItemHandler.cpp
|
||||
LFGHandler.cpp
|
||||
LootHandler.cpp
|
||||
Mail.cpp
|
||||
Mail.h
|
||||
MailHandler.cpp
|
||||
Map.cpp
|
||||
Map.h
|
||||
MapManager.cpp
|
||||
MapManager.h
|
||||
MapPersistentStateMgr.cpp
|
||||
MapPersistentStateMgr.h
|
||||
MassMailMgr.cpp
|
||||
MassMailMgr.h
|
||||
MiscHandler.cpp
|
||||
MoveMap.cpp
|
||||
MoveMap.h
|
||||
MoveMapSharedDefines.h
|
||||
MovementHandler.cpp
|
||||
NPCHandler.cpp
|
||||
NPCHandler.h
|
||||
ObjectGridLoader.cpp
|
||||
ObjectGridLoader.h
|
||||
Path.h
|
||||
PetHandler.cpp
|
||||
PetitionsHandler.cpp
|
||||
PoolManager.cpp
|
||||
PoolManager.h
|
||||
QueryHandler.cpp
|
||||
QuestDef.cpp
|
||||
QuestDef.h
|
||||
QuestHandler.cpp
|
||||
ScriptMgr.cpp
|
||||
ScriptMgr.h
|
||||
SkillDiscovery.cpp
|
||||
SkillDiscovery.h
|
||||
SkillExtraItems.cpp
|
||||
SkillExtraItems.h
|
||||
SkillHandler.cpp
|
||||
Spell.cpp
|
||||
Spell.h
|
||||
SpellAuraDefines.h
|
||||
SpellAuras.cpp
|
||||
SpellAuras.h
|
||||
SpellEffects.cpp
|
||||
SpellHandler.cpp
|
||||
TaxiHandler.cpp
|
||||
TradeHandler.cpp
|
||||
Transports.cpp
|
||||
Transports.h
|
||||
UnitAuraProcHandler.cpp
|
||||
UpdateData.cpp
|
||||
UpdateData.h
|
||||
VehicleHandler.cpp
|
||||
VoiceChatHandler.cpp
|
||||
WaypointManager.cpp
|
||||
WaypointManager.h
|
||||
WaypointMovementGenerator.cpp
|
||||
WaypointMovementGenerator.h
|
||||
Weather.cpp
|
||||
Weather.h
|
||||
World.cpp
|
||||
World.h
|
||||
WorldSession.cpp
|
||||
WorldSession.h
|
||||
WorldSocket.cpp
|
||||
WorldSocket.h
|
||||
WorldSocketMgr.cpp
|
||||
WorldSocketMgr.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vmap
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouseBot
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BattleGround
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/OutdoorPvP
|
||||
${CMAKE_SOURCE_DIR}/dep/include/g3dlite
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/
|
||||
${CMAKE_SOURCE_DIR}/dep/include
|
||||
${CMAKE_SOURCE_DIR}/src/shared
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/src/shared
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${ACE_INCLUDE_DIR}
|
||||
set(LIBRARY_SRCS
|
||||
${SRC_GRP_AHBOT}
|
||||
${SRC_GRP_BATTLEGROUND}
|
||||
${SRC_GRP_CHAT_COMMANDS}
|
||||
${SRC_GRP_MOTION_GEN}
|
||||
${SRC_GRP_MOVEMENT}
|
||||
${SRC_GRP_OBJECT}
|
||||
${SRC_GRP_OUTDOOR_PVP}
|
||||
${SRC_GRP_REFERENCES}
|
||||
${SRC_GRP_SERVER}
|
||||
${SRC_GRP_TOOL}
|
||||
${SRC_GRP_VMAPS}
|
||||
${SRC_GRP_WORLD_HANDLERS}
|
||||
pchdef.cpp
|
||||
pchdef.h
|
||||
)
|
||||
|
||||
source_group("Object"
|
||||
REGULAR_EXPRESSION .*
|
||||
)
|
||||
|
||||
source_group("World/Handlers"
|
||||
# REGULAR_EXPRESSION Mgr|Handler|Manager|BattleGround|Cell|Channel|Chat|Gossip|Grid|Group|Instance|Mail|Map|Path|Pool|Quest|Script|Skill|Spell|Transports|Update|Weather|World
|
||||
REGULAR_EXPRESSION Mgr|Handler|Manager|Cell|Channel|Chat|Gossip|Grid|Instance|Map|Path|Pool|Script|Skill|Transports|Update|Weather|World
|
||||
)
|
||||
|
||||
source_group("Motion generators"
|
||||
REGULAR_EXPRESSION MoveMap|MoveMapSharedDefines|Generator|MotionMaster
|
||||
)
|
||||
|
||||
source_group("Server"
|
||||
REGULAR_EXPRESSION Socket|Session|Opcodes|DBC
|
||||
source_group("AhBot"
|
||||
FILES
|
||||
SharedDefines.h
|
||||
${SRC_GRP_AHBOT}
|
||||
)
|
||||
|
||||
source_group("BattleGround"
|
||||
FILES
|
||||
${SRC_GRP_BATTLEGROUND}
|
||||
)
|
||||
|
||||
source_group("Chat Commands"
|
||||
REGULAR_EXPRESSION Level[0-9]
|
||||
FILES
|
||||
debugcmds.cpp
|
||||
${SRC_GRP_CHAT_COMMANDS}
|
||||
)
|
||||
|
||||
source_group("Tool"
|
||||
REGULAR_EXPRESSION DatabaseCleaner|Language|PlayerDump
|
||||
)
|
||||
|
||||
source_group("References"
|
||||
REGULAR_EXPRESSION Reference|RefManager|ThreatManager
|
||||
source_group("Motion generators"
|
||||
FILES
|
||||
${SRC_GRP_MOTION_GEN}
|
||||
)
|
||||
|
||||
source_group("Movement"
|
||||
REGULAR_EXPRESSION spline|Spline|packet_builder
|
||||
FILES
|
||||
movement/typedefs.h
|
||||
movement/util.cpp
|
||||
${SRC_GRP_MOVEMENT}
|
||||
)
|
||||
|
||||
source_group("Object"
|
||||
FILES
|
||||
${SRC_GRP_OBJECT}
|
||||
)
|
||||
|
||||
source_group("Outdoor PvP"
|
||||
FILES
|
||||
${SRC_GRP_OUTDOOR_PVP}
|
||||
)
|
||||
|
||||
source_group("References"
|
||||
FILES
|
||||
${SRC_GRP_REFERENCES}
|
||||
)
|
||||
|
||||
source_group("Server"
|
||||
FILES
|
||||
${SRC_GRP_SERVER}
|
||||
)
|
||||
|
||||
source_group("Tool"
|
||||
FILES
|
||||
${SRC_GRP_TOOL}
|
||||
)
|
||||
|
||||
source_group("vmaps"
|
||||
FILES
|
||||
${SRC_GRP_VMAPS}
|
||||
)
|
||||
|
||||
source_group("World/Handlers"
|
||||
FILES
|
||||
${SRC_GRP_WORLD_HANDLERS}
|
||||
)
|
||||
|
||||
if(PCH)
|
||||
|
|
|
|||
|
|
@ -580,6 +580,7 @@ void CalendarMgr::LoadCalendarsFromDB()
|
|||
do
|
||||
{
|
||||
Field* field = eventsQuery->Fetch();
|
||||
bar.step();
|
||||
|
||||
uint64 eventId = field[0].GetUInt64();
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@
|
|||
#include "ObjectMgr.h"
|
||||
|
||||
Corpse::Corpse(CorpseType type) : WorldObject(),
|
||||
loot(this)
|
||||
loot(this),
|
||||
lootRecipient(NULL),
|
||||
lootForBody(false)
|
||||
{
|
||||
m_objectType |= TYPEMASK_CORPSE;
|
||||
m_objectTypeId = TYPEID_CORPSE;
|
||||
|
|
@ -40,8 +42,6 @@ Corpse::Corpse(CorpseType type) : WorldObject(),
|
|||
m_type = type;
|
||||
|
||||
m_time = time(NULL);
|
||||
|
||||
lootForBody = false;
|
||||
}
|
||||
|
||||
Corpse::~Corpse()
|
||||
|
|
|
|||
|
|
@ -189,9 +189,18 @@ void Creature::RemoveFromWorld()
|
|||
|
||||
void Creature::RemoveCorpse()
|
||||
{
|
||||
// since pool system can fail to roll unspawned object, this one can remain spawned, so must set respawn nevertheless
|
||||
if (uint16 poolid = sPoolMgr.IsPartOfAPool<Creature>(GetGUIDLow()))
|
||||
sPoolMgr.UpdatePool<Creature>(*GetMap()->GetPersistentState(), poolid, GetGUIDLow());
|
||||
|
||||
if (!IsInWorld()) // can be despawned by update pool
|
||||
return;
|
||||
|
||||
if ((getDeathState() != CORPSE && !m_isDeadByDefault) || (getDeathState() != ALIVE && m_isDeadByDefault))
|
||||
return;
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Removing corpse of %s ", GetGuidStr().c_str());
|
||||
|
||||
m_corpseDecayTimer = 0;
|
||||
SetDeathState(DEAD);
|
||||
UpdateObjectVisibility();
|
||||
|
|
@ -515,28 +524,19 @@ void Creature::Update(uint32 update_diff, uint32 diff)
|
|||
break;
|
||||
|
||||
if (m_corpseDecayTimer <= update_diff)
|
||||
{
|
||||
// since pool system can fail to roll unspawned object, this one can remain spawned, so must set respawn nevertheless
|
||||
if (uint16 poolid = sPoolMgr.IsPartOfAPool<Creature>(GetGUIDLow()))
|
||||
sPoolMgr.UpdatePool<Creature>(*GetMap()->GetPersistentState(), poolid, GetGUIDLow());
|
||||
|
||||
if (IsInWorld()) // can be despawned by update pool
|
||||
{
|
||||
RemoveCorpse();
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Removing corpse... %u ", GetEntry());
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_corpseDecayTimer -= update_diff;
|
||||
if (m_groupLootId)
|
||||
if (m_groupLootId) // Loot is stopped already if corpse got removed.
|
||||
{
|
||||
if (m_groupLootTimer <= update_diff)
|
||||
StopGroupLoot();
|
||||
else
|
||||
m_groupLootTimer -= update_diff;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -545,24 +545,13 @@ void Creature::Update(uint32 update_diff, uint32 diff)
|
|||
if (m_isDeadByDefault)
|
||||
{
|
||||
if (m_corpseDecayTimer <= update_diff)
|
||||
{
|
||||
// since pool system can fail to roll unspawned object, this one can remain spawned, so must set respawn nevertheless
|
||||
if (uint16 poolid = sPoolMgr.IsPartOfAPool<Creature>(GetGUIDLow()))
|
||||
sPoolMgr.UpdatePool<Creature>(*GetMap()->GetPersistentState(), poolid, GetGUIDLow());
|
||||
|
||||
if (IsInWorld()) // can be despawned by update pool
|
||||
{
|
||||
RemoveCorpse();
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Removing alive corpse... %u ", GetEntry());
|
||||
break;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_corpseDecayTimer -= update_diff;
|
||||
}
|
||||
}
|
||||
|
||||
Unit::Update(update_diff, diff);
|
||||
|
||||
|
|
@ -1549,6 +1538,9 @@ void Creature::SetDeathState(DeathState s)
|
|||
|
||||
void Creature::Respawn()
|
||||
{
|
||||
if (!IsInWorld()) // Could be removed as part of a pool (in which case respawn-time is handled with pool-system)
|
||||
return;
|
||||
|
||||
RemoveCorpse();
|
||||
|
||||
if (IsDespawned())
|
||||
|
|
@ -1568,11 +1560,14 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn)
|
|||
m_Events.AddEvent(pEvent, m_Events.CalculateTime(timeMSToDespawn));
|
||||
return;
|
||||
}
|
||||
if (IsDespawned())
|
||||
return;
|
||||
|
||||
if (isAlive())
|
||||
SetDeathState(JUST_DIED);
|
||||
|
||||
m_corpseDecayTimer = 1; // Properly remove corpse on next tick (also pool system requires Creature::Update call with CORPSE state
|
||||
RemoveCorpse();
|
||||
|
||||
SetHealth(0); // just for nice GM-mode view
|
||||
}
|
||||
|
||||
|
|
@ -1772,7 +1767,7 @@ void Creature::CallAssistance()
|
|||
if (!m_AlreadyCallAssistance && getVictim() && !isCharmed())
|
||||
{
|
||||
SetNoCallAssistance(true);
|
||||
AI()->SendAIEvent(AI_EVENT_CALL_ASSISTANCE, getVictim(), sWorld.getConfig(CONFIG_UINT32_CREATURE_FAMILY_ASSISTANCE_DELAY), sWorld.getConfig(CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS));
|
||||
AI()->SendAIEventAround(AI_EVENT_CALL_ASSISTANCE, getVictim(), sWorld.getConfig(CONFIG_UINT32_CREATURE_FAMILY_ASSISTANCE_DELAY), sWorld.getConfig(CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -511,8 +511,8 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
bool IsGuard() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GUARD; }
|
||||
|
||||
bool CanWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; }
|
||||
bool CanSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; }
|
||||
bool CanFly() const { return (GetCreatureInfo()->InhabitType & INHABIT_AIR) || (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE1_FLAG_UNK_2); }
|
||||
virtual bool CanSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; }
|
||||
bool CanFly() const { return (GetCreatureInfo()->InhabitType & INHABIT_AIR) || (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE1_FLAG_UNK_2) || HasAuraType(SPELL_AURA_FLY); }
|
||||
|
||||
bool IsTrainerOf(Player* player, bool msg) const;
|
||||
bool CanInteractWithBattleMaster(Player* player, bool msg) const;
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ class AiDelayEventAround : public BasicEvent
|
|||
uint32 m_miscValue;
|
||||
};
|
||||
|
||||
void CreatureAI::SendAIEvent(AIEventType eventType, Unit* pInvoker, uint32 uiDelay, float fRadius, uint32 miscValue /*=0*/) const
|
||||
void CreatureAI::SendAIEventAround(AIEventType eventType, Unit* pInvoker, uint32 uiDelay, float fRadius, uint32 miscValue /*=0*/) const
|
||||
{
|
||||
if (fRadius > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -63,13 +63,14 @@ enum AIEventType
|
|||
{
|
||||
// Usable with Event AI
|
||||
AI_EVENT_JUST_DIED = 0, // Sender = Killed Npc, Invoker = Killer
|
||||
AI_EVENT_CRITICAL_HEALTH = 1, // Sender = Hurt Npc, Invoker = DamageDealer
|
||||
AI_EVENT_LOST_HEALTH = 2, // Sender = Hurt Npc, Invoker = DamageDealer
|
||||
AI_EVENT_GOT_CCED = 3, // Sender = CCed Npc, Invoker = Caster that CCed
|
||||
AI_EVENT_CRITICAL_HEALTH = 1, // Sender = Hurt Npc, Invoker = DamageDealer - Expected to be sent by 10% health
|
||||
AI_EVENT_LOST_HEALTH = 2, // Sender = Hurt Npc, Invoker = DamageDealer - Expected to be sent by 50% health
|
||||
AI_EVENT_LOST_SOME_HEALTH = 3, // Sender = Hurt Npc, Invoker = DamageDealer - Expected to be sent by 90% health
|
||||
AI_EVENT_GOT_FULL_HEALTH = 4, // Sender = Healed Npc, Invoker = Healer
|
||||
AI_EVENT_CUSTOM_EVENTAI_A = 5, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
AI_EVENT_CUSTOM_EVENTAI_B = 6, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
MAXIMAL_AI_EVENT_EVENTAI = 7,
|
||||
AI_EVENT_GOT_CCED = 7, // Sender = CCed Npc, Invoker = Caster that CCed
|
||||
MAXIMAL_AI_EVENT_EVENTAI = 8,
|
||||
|
||||
// Internal Use
|
||||
AI_EVENT_CALL_ASSISTANCE = 10, // Sender = Attacked Npc, Invoker = Enemy
|
||||
|
|
@ -317,7 +318,7 @@ class MANGOS_DLL_SPEC CreatureAI
|
|||
* @param uiDelay delay time until the Event will be triggered
|
||||
* @param fRadius range in which for receiver is searched
|
||||
*/
|
||||
void SendAIEvent(AIEventType eventType, Unit* pInvoker, uint32 uiDelay, float fRadius, uint32 miscValue = 0) const;
|
||||
void SendAIEventAround(AIEventType eventType, Unit* pInvoker, uint32 uiDelay, float fRadius, uint32 miscValue = 0) const;
|
||||
|
||||
/**
|
||||
* Send an AI Event to a Creature
|
||||
|
|
|
|||
|
|
@ -59,6 +59,20 @@ void CreatureEventAI::GetAIInformation(ChatHandler& reader)
|
|||
reader.PSendSysMessage(LANG_NPC_EVENTAI_PHASE, (uint32)m_Phase);
|
||||
reader.PSendSysMessage(LANG_NPC_EVENTAI_MOVE, reader.GetOnOffStr(m_isCombatMovement));
|
||||
reader.PSendSysMessage(LANG_NPC_EVENTAI_COMBAT, reader.GetOnOffStr(m_MeleeEnabled));
|
||||
|
||||
if (sLog.HasLogFilter(LOG_FILTER_EVENT_AI_DEV)) // Give some more details if in EventAI Dev Mode
|
||||
return;
|
||||
|
||||
reader.PSendSysMessage("Current events of this creature:");
|
||||
for (CreatureEventAIList::const_iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
||||
{
|
||||
if (itr->Event.action[2].type != ACTION_T_NONE)
|
||||
reader.PSendSysMessage("%u Type%3u (%s) Timer(%3us) actions[type(param1)]: %2u(%5u) -- %2u(%u) -- %2u(%5u)", itr->Event.event_id, itr->Event.event_type, itr->Enabled ? "On" : "Off", itr->Time/1000, itr->Event.action[0].type, itr->Event.action[0].raw.param1, itr->Event.action[1].type, itr->Event.action[1].raw.param1, itr->Event.action[2].type, itr->Event.action[2].raw.param1);
|
||||
else if (itr->Event.action[1].type != ACTION_T_NONE)
|
||||
reader.PSendSysMessage("%u Type%3u (%s) Timer(%3us) actions[type(param1)]: %2u(%5u) -- %2u(%5u)", itr->Event.event_id, itr->Event.event_type, itr->Enabled ? "On" : "Off", itr->Time/1000, itr->Event.action[0].type, itr->Event.action[0].raw.param1, itr->Event.action[1].type, itr->Event.action[1].raw.param1);
|
||||
else
|
||||
reader.PSendSysMessage("%u Type%3u (%s) Timer(%3us) action[type(param1)]: %2u(%5u)", itr->Event.event_id, itr->Event.event_type, itr->Enabled ? "On" : "Off", itr->Time/1000, itr->Event.action[0].type, itr->Event.action[0].raw.param1);
|
||||
}
|
||||
}
|
||||
|
||||
// For Non Dungeon map only allow non-difficulty flags or EFLAG_DIFFICULTY_0 mode
|
||||
|
|
@ -68,7 +82,12 @@ inline bool IsEventFlagsFitForNormalMap(uint8 eFlags)
|
|||
(eFlags & EFLAG_DIFFICULTY_0);
|
||||
}
|
||||
|
||||
CreatureEventAI::CreatureEventAI(Creature* c) : CreatureAI(c)
|
||||
CreatureEventAI::CreatureEventAI(Creature* c) : CreatureAI(c),
|
||||
m_Phase(0),
|
||||
m_MeleeEnabled(true),
|
||||
m_InvinceabilityHpLevel(0),
|
||||
m_throwAIEventMask(0),
|
||||
m_throwAIEventStep(0)
|
||||
{
|
||||
// Need make copy for filter unneeded steps and safe in case table reload
|
||||
CreatureEventAI_Event_Map::const_iterator creatureEventsItr = sEventAIMgr.GetCreatureEventAIMap().find(m_creature->GetEntry());
|
||||
|
|
@ -94,7 +113,7 @@ CreatureEventAI::CreatureEventAI(Creature* c) : CreatureAI(c)
|
|||
}
|
||||
// EventMap had events but they were not added because they must be for instance
|
||||
if (events_count == 0)
|
||||
sLog.outError("CreatureEventAI: Creature %u has events but no events added to list because of instance flags.", m_creature->GetEntry());
|
||||
sLog.outErrorEventAI("Creature %u has events but no events added to list because of instance flags.", m_creature->GetEntry());
|
||||
else
|
||||
{
|
||||
m_CreatureEventAIList.reserve(events_count);
|
||||
|
|
@ -121,12 +140,6 @@ CreatureEventAI::CreatureEventAI(Creature* c) : CreatureAI(c)
|
|||
else
|
||||
sLog.outErrorEventAI("EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature->GetEntry());
|
||||
|
||||
m_bEmptyList = m_CreatureEventAIList.empty();
|
||||
m_Phase = 0;
|
||||
m_MeleeEnabled = true;
|
||||
|
||||
m_InvinceabilityHpLevel = 0;
|
||||
|
||||
// Handle Spawned Events, also calls Reset()
|
||||
JustRespawned();
|
||||
}
|
||||
|
|
@ -476,6 +489,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
DEBUG_FILTER_LOG(LOG_FILTER_EVENT_AI_DEV, "CreatureEventAI: Process action %u (script %u) triggered for %s (invoked by %s)",
|
||||
action.type, EventId, m_creature->GetGuidStr().c_str(), pActionInvoker ? pActionInvoker->GetGuidStr().c_str() : "<no invoker>");
|
||||
|
||||
bool reportTargetError = false;
|
||||
switch (action.type)
|
||||
{
|
||||
case ACTION_T_TEXT:
|
||||
|
|
@ -484,27 +498,27 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
if (!action.text.TextId[0])
|
||||
return;
|
||||
|
||||
int32 temp = 0;
|
||||
int32 textId = 0;
|
||||
|
||||
if (action.type == ACTION_T_TEXT)
|
||||
{
|
||||
if (action.text.TextId[1] && action.text.TextId[2])
|
||||
temp = action.text.TextId[urand(0, 2)];
|
||||
textId = action.text.TextId[urand(0, 2)];
|
||||
else if (action.text.TextId[1] && urand(0, 1))
|
||||
temp = action.text.TextId[1];
|
||||
textId = action.text.TextId[1];
|
||||
else
|
||||
temp = action.text.TextId[0];
|
||||
textId = action.text.TextId[0];
|
||||
}
|
||||
// ACTION_T_CHANCED_TEXT, chance hits
|
||||
else if (urand(0, 99) < action.chanced_text.chance)
|
||||
{
|
||||
if (action.chanced_text.TextId[0] && action.chanced_text.TextId[1])
|
||||
temp = action.chanced_text.TextId[urand(0, 1)];
|
||||
textId = action.chanced_text.TextId[urand(0, 1)];
|
||||
else
|
||||
temp = action.chanced_text.TextId[0];
|
||||
textId = action.chanced_text.TextId[0];
|
||||
}
|
||||
|
||||
if (temp)
|
||||
if (textId)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
|
||||
|
|
@ -526,7 +540,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
target = owner;
|
||||
}
|
||||
|
||||
DoScriptText(temp, m_creature, target);
|
||||
if (!DoDisplayText(m_creature, textId, target))
|
||||
sLog.outErrorEventAI("Error attempting to display text %i, used by script %u", textId, EventId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -590,9 +605,10 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
selectFlags = SELECT_FLAG_IN_LOS;
|
||||
}
|
||||
|
||||
Unit* target = GetTargetByType(action.cast.target, pActionInvoker, pAIEventSender, spellId, selectFlags);
|
||||
Unit* target = GetTargetByType(action.cast.target, pActionInvoker, pAIEventSender, reportTargetError, spellId, selectFlags);
|
||||
if (!target)
|
||||
{
|
||||
if (reportTargetError)
|
||||
sLog.outErrorEventAI("NULL target for ACTION_T_CAST creature entry %u casting spell id %u", m_creature->GetEntry(), action.cast.spellId);
|
||||
return;
|
||||
}
|
||||
|
|
@ -631,7 +647,9 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
}
|
||||
case ACTION_T_SUMMON:
|
||||
{
|
||||
Unit* target = GetTargetByType(action.summon.target, pActionInvoker, pAIEventSender);
|
||||
Unit* target = GetTargetByType(action.summon.target, pActionInvoker, pAIEventSender, reportTargetError);
|
||||
if (!target && reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_SUMMON(%u), target-type %u", EventId, action.type, action.summon.target);
|
||||
|
||||
Creature* pCreature = NULL;
|
||||
|
||||
|
|
@ -647,8 +665,10 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
break;
|
||||
}
|
||||
case ACTION_T_THREAT_SINGLE_PCT:
|
||||
if (Unit* target = GetTargetByType(action.threat_single_pct.target, pActionInvoker, pAIEventSender))
|
||||
if (Unit* target = GetTargetByType(action.threat_single_pct.target, pActionInvoker, pAIEventSender, reportTargetError))
|
||||
m_creature->getThreatManager().modifyThreatPercent(target, action.threat_single_pct.percent);
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_THREAT_SINGLE_PCT(%u), target-type %u", EventId, action.type, action.threat_single_pct.target);
|
||||
break;
|
||||
case ACTION_T_THREAT_ALL_PCT:
|
||||
{
|
||||
|
|
@ -659,36 +679,48 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
break;
|
||||
}
|
||||
case ACTION_T_QUEST_EVENT:
|
||||
if (Unit* target = GetTargetByType(action.quest_event.target, pActionInvoker, pAIEventSender))
|
||||
if (Unit* target = GetTargetByType(action.quest_event.target, pActionInvoker, pAIEventSender, reportTargetError))
|
||||
{
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)target)->AreaExploredOrEventHappens(action.quest_event.questId);
|
||||
}
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_QUEST_EVENT(%u), target-type %u", EventId, action.type, action.quest_event.target);
|
||||
|
||||
break;
|
||||
case ACTION_T_CAST_EVENT:
|
||||
if (Unit* target = GetTargetByType(action.cast_event.target, pActionInvoker, pAIEventSender, 0, SELECT_FLAG_PLAYER))
|
||||
if (Unit* target = GetTargetByType(action.cast_event.target, pActionInvoker, pAIEventSender, reportTargetError, 0, SELECT_FLAG_PLAYER))
|
||||
{
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)target)->CastedCreatureOrGO(action.cast_event.creatureId, m_creature->GetObjectGuid(), action.cast_event.spellId);
|
||||
}
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_CST_EVENT(%u), target-type %u", EventId, action.type, action.cast_event.target);
|
||||
break;
|
||||
case ACTION_T_SET_UNIT_FIELD:
|
||||
{
|
||||
Unit* target = GetTargetByType(action.set_unit_field.target, pActionInvoker, pAIEventSender);
|
||||
Unit* target = GetTargetByType(action.set_unit_field.target, pActionInvoker, pAIEventSender, reportTargetError);
|
||||
|
||||
// not allow modify important for integrity object fields
|
||||
if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END)
|
||||
return;
|
||||
|
||||
if (target)
|
||||
target->SetUInt32Value(action.set_unit_field.field, action.set_unit_field.value);
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_SET_UNIT_FIELD(%u), target-type %u", EventId, action.type, action.set_unit_field.target);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_T_SET_UNIT_FLAG:
|
||||
if (Unit* target = GetTargetByType(action.unit_flag.target, pActionInvoker, pAIEventSender))
|
||||
if (Unit* target = GetTargetByType(action.unit_flag.target, pActionInvoker, pAIEventSender, reportTargetError))
|
||||
target->SetFlag(UNIT_FIELD_FLAGS, action.unit_flag.value);
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_SET_UNIT_FLAG(%u), target-type %u", EventId, action.type, action.unit_flag.target);
|
||||
break;
|
||||
case ACTION_T_REMOVE_UNIT_FLAG:
|
||||
if (Unit* target = GetTargetByType(action.unit_flag.target, pActionInvoker, pAIEventSender))
|
||||
if (Unit* target = GetTargetByType(action.unit_flag.target, pActionInvoker, pAIEventSender, reportTargetError))
|
||||
target->RemoveFlag(UNIT_FIELD_FLAGS, action.unit_flag.value);
|
||||
break;
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_REMOVE_UNIT_FLAG(%u), target-type %u", EventId, action.type, action.unit_flag.target);
|
||||
case ACTION_T_AUTO_ATTACK:
|
||||
m_MeleeEnabled = action.auto_attack.state != 0;
|
||||
break;
|
||||
|
|
@ -746,8 +778,10 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
break;
|
||||
}
|
||||
case ACTION_T_REMOVEAURASFROMSPELL:
|
||||
if (Unit* target = GetTargetByType(action.remove_aura.target, pActionInvoker, pAIEventSender))
|
||||
if (Unit* target = GetTargetByType(action.remove_aura.target, pActionInvoker, pAIEventSender, reportTargetError))
|
||||
target->RemoveAurasDueToSpell(action.remove_aura.spellId);
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_REMOVEAURASFROMSPELL(%u), target-type %u", EventId, action.type, action.remove_aura.target);
|
||||
break;
|
||||
case ACTION_T_RANGED_MOVEMENT:
|
||||
m_attackDistance = (float)action.ranged_movement.distance;
|
||||
|
|
@ -775,7 +809,9 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
break;
|
||||
case ACTION_T_SUMMON_ID:
|
||||
{
|
||||
Unit* target = GetTargetByType(action.summon_id.target, pActionInvoker, pAIEventSender);
|
||||
Unit* target = GetTargetByType(action.summon_id.target, pActionInvoker, pAIEventSender, reportTargetError);
|
||||
if (!target && reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_SUMMON_ID(%u), target-type %u", EventId, action.type, action.summon_id.target);
|
||||
|
||||
CreatureEventAI_Summon_Map::const_iterator i = sEventAIMgr.GetCreatureEventAISummonMap().find(action.summon_id.spawnId);
|
||||
if (i == sEventAIMgr.GetCreatureEventAISummonMap().end())
|
||||
|
|
@ -804,10 +840,14 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
else
|
||||
{
|
||||
// if not available, use pActionInvoker
|
||||
if (Unit* pTarget = GetTargetByType(action.killed_monster.target, pActionInvoker, 0, SELECT_FLAG_PLAYER))
|
||||
if (Unit* pTarget = GetTargetByType(action.killed_monster.target, pActionInvoker, pAIEventSender, reportTargetError, 0, SELECT_FLAG_PLAYER))
|
||||
{
|
||||
if (Player* pPlayer2 = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
pPlayer2->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, m_creature);
|
||||
}
|
||||
else if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %u - NULL target for ACTION_T_KILLED_MONSTER(%u), target-type %u", EventId, action.type, action.killed_monster.target);
|
||||
}
|
||||
break;
|
||||
case ACTION_T_SET_INST_DATA:
|
||||
{
|
||||
|
|
@ -823,9 +863,10 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
}
|
||||
case ACTION_T_SET_INST_DATA64:
|
||||
{
|
||||
Unit* target = GetTargetByType(action.set_inst_data64.target, pActionInvoker, pAIEventSender);
|
||||
Unit* target = GetTargetByType(action.set_inst_data64.target, pActionInvoker, pAIEventSender, reportTargetError);
|
||||
if (!target)
|
||||
{
|
||||
if (reportTargetError)
|
||||
sLog.outErrorEventAI("Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature->GetEntry());
|
||||
return;
|
||||
}
|
||||
|
|
@ -911,7 +952,12 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
}
|
||||
case ACTION_T_THROW_AI_EVENT:
|
||||
{
|
||||
SendAIEvent(AIEventType(action.throwEvent.eventType), pActionInvoker, 0, action.throwEvent.radius);
|
||||
SendAIEventAround(AIEventType(action.throwEvent.eventType), pActionInvoker, 0, action.throwEvent.radius);
|
||||
break;
|
||||
}
|
||||
case ACTION_T_SET_THROW_MASK:
|
||||
{
|
||||
m_throwAIEventMask = action.setThrowMask.eventTypeMask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -921,9 +967,6 @@ void CreatureEventAI::JustRespawned() // NOTE that this is
|
|||
{
|
||||
Reset();
|
||||
|
||||
if (m_bEmptyList)
|
||||
return;
|
||||
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
{
|
||||
// Reset generic timer
|
||||
|
|
@ -943,8 +986,7 @@ void CreatureEventAI::Reset()
|
|||
m_EventUpdateTime = EVENT_UPDATE_TIME;
|
||||
m_EventDiff = 0;
|
||||
|
||||
if (m_bEmptyList)
|
||||
return;
|
||||
m_throwAIEventStep = 0;
|
||||
|
||||
// Reset all events to enabled
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
|
|
@ -969,15 +1011,12 @@ void CreatureEventAI::Reset()
|
|||
}
|
||||
|
||||
void CreatureEventAI::JustReachedHome()
|
||||
{
|
||||
if (!m_bEmptyList)
|
||||
{
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
{
|
||||
if ((*i).Event.event_type == EVENT_T_REACHED_HOME)
|
||||
ProcessEvent(*i);
|
||||
}
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
|
@ -1015,10 +1054,10 @@ void CreatureEventAI::JustDied(Unit* killer)
|
|||
m_creature->SendZoneUnderAttackMessage(pKiller);
|
||||
}
|
||||
|
||||
if (m_bEmptyList)
|
||||
return;
|
||||
if (m_throwAIEventMask & (1 << AI_EVENT_JUST_DIED))
|
||||
SendAIEventAround(AI_EVENT_JUST_DIED, killer, 0, AIEVENT_DEFAULT_THROW_RADIUS);
|
||||
|
||||
// Handle Evade events
|
||||
// Handle On Death events
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
{
|
||||
if ((*i).Event.event_type == EVENT_T_DEATH)
|
||||
|
|
@ -1031,7 +1070,7 @@ void CreatureEventAI::JustDied(Unit* killer)
|
|||
|
||||
void CreatureEventAI::KilledUnit(Unit* victim)
|
||||
{
|
||||
if (m_bEmptyList || victim->GetTypeId() != TYPEID_PLAYER)
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
|
|
@ -1043,9 +1082,6 @@ void CreatureEventAI::KilledUnit(Unit* victim)
|
|||
|
||||
void CreatureEventAI::JustSummoned(Creature* pUnit)
|
||||
{
|
||||
if (m_bEmptyList || !pUnit)
|
||||
return;
|
||||
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
{
|
||||
if ((*i).Event.event_type == EVENT_T_SUMMONED_UNIT)
|
||||
|
|
@ -1055,9 +1091,6 @@ void CreatureEventAI::JustSummoned(Creature* pUnit)
|
|||
|
||||
void CreatureEventAI::SummonedCreatureJustDied(Creature* pUnit)
|
||||
{
|
||||
if (m_bEmptyList || !pUnit)
|
||||
return;
|
||||
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
{
|
||||
if ((*i).Event.event_type == EVENT_T_SUMMONED_JUST_DIED)
|
||||
|
|
@ -1067,9 +1100,6 @@ void CreatureEventAI::SummonedCreatureJustDied(Creature* pUnit)
|
|||
|
||||
void CreatureEventAI::SummonedCreatureDespawn(Creature* pUnit)
|
||||
{
|
||||
if (m_bEmptyList || !pUnit)
|
||||
return;
|
||||
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
{
|
||||
if ((*i).Event.event_type == EVENT_T_SUMMONED_JUST_DESPAWN)
|
||||
|
|
@ -1079,8 +1109,7 @@ void CreatureEventAI::SummonedCreatureDespawn(Creature* pUnit)
|
|||
|
||||
void CreatureEventAI::ReceiveAIEvent(AIEventType eventType, Creature* pSender, Unit* pInvoker, uint32 miscValue)
|
||||
{
|
||||
if (m_bEmptyList || !pSender)
|
||||
return;
|
||||
MANGOS_ASSERT(pSender);
|
||||
|
||||
for (CreatureEventAIList::iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
||||
{
|
||||
|
|
@ -1093,8 +1122,6 @@ void CreatureEventAI::ReceiveAIEvent(AIEventType eventType, Creature* pSender, U
|
|||
void CreatureEventAI::EnterCombat(Unit* enemy)
|
||||
{
|
||||
// Check for on combat start events
|
||||
if (!m_bEmptyList)
|
||||
{
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
{
|
||||
CreatureEventAI_Event const& event = (*i).Event;
|
||||
|
|
@ -1116,7 +1143,6 @@ void CreatureEventAI::EnterCombat(Unit* enemy)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_EventUpdateTime = EVENT_UPDATE_TIME;
|
||||
m_EventDiff = 0;
|
||||
|
|
@ -1143,7 +1169,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit* who)
|
|||
return;
|
||||
|
||||
// Check for OOC LOS Event
|
||||
if (!m_bEmptyList && !m_creature->getVictim())
|
||||
if (!m_creature->getVictim())
|
||||
{
|
||||
for (CreatureEventAIList::iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
||||
{
|
||||
|
|
@ -1192,10 +1218,6 @@ void CreatureEventAI::MoveInLineOfSight(Unit* who)
|
|||
|
||||
void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
|
||||
{
|
||||
|
||||
if (m_bEmptyList)
|
||||
return;
|
||||
|
||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||
if ((*i).Event.event_type == EVENT_T_SPELLHIT)
|
||||
// If spell id matches (or no spell id) & if spell school matches (or no spell school)
|
||||
|
|
@ -1209,8 +1231,6 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
|||
// Check if we are in combat (also updates calls threat update code)
|
||||
bool Combat = m_creature->SelectHostileTarget() && m_creature->getVictim();
|
||||
|
||||
if (!m_bEmptyList)
|
||||
{
|
||||
// Events are only updated once every EVENT_UPDATE_TIME ms to prevent lag with large amount of events
|
||||
if (m_EventUpdateTime < diff)
|
||||
{
|
||||
|
|
@ -1263,20 +1283,19 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_EventDiff = 0;
|
||||
m_EventUpdateTime = EVENT_UPDATE_TIME;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EventDiff += diff;
|
||||
m_EventUpdateTime -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
// Melee Auto-Attack (recheck m_creature->getVictim in case of combat state was changed while processing events)
|
||||
if (Combat && m_MeleeEnabled)
|
||||
if (Combat && m_MeleeEnabled && m_creature->getVictim())
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
|
|
@ -1308,33 +1327,63 @@ inline int32 CreatureEventAI::GetRandActionParam(uint32 rnd, int32 param1, int32
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoker, Creature* pAIEventSender, uint32 forSpellId, uint32 selectFlags)
|
||||
inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoker, Creature* pAIEventSender, bool& isError, uint32 forSpellId, uint32 selectFlags)
|
||||
{
|
||||
Unit* resTarget;
|
||||
switch (Target)
|
||||
{
|
||||
case TARGET_T_SELF:
|
||||
return m_creature;
|
||||
case TARGET_T_HOSTILE:
|
||||
return m_creature->getVictim();
|
||||
resTarget = m_creature->getVictim();
|
||||
if (!resTarget)
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_HOSTILE_SECOND_AGGRO:
|
||||
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1, forSpellId, selectFlags);
|
||||
resTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1, forSpellId, selectFlags);
|
||||
if (!resTarget && ((forSpellId == 0 && selectFlags == 0 && m_creature->getThreatManager().getThreatList().size() > 1) || m_creature->getThreatManager().getThreatList().empty()))
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_HOSTILE_LAST_AGGRO:
|
||||
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO, 0, forSpellId, selectFlags);
|
||||
resTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO, 0, forSpellId, selectFlags);
|
||||
if (!resTarget && m_creature->getThreatManager().getThreatList().empty())
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_HOSTILE_RANDOM:
|
||||
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, forSpellId, selectFlags);
|
||||
resTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, forSpellId, selectFlags);
|
||||
if (!resTarget && m_creature->getThreatManager().getThreatList().empty())
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_HOSTILE_RANDOM_NOT_TOP:
|
||||
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, forSpellId, selectFlags);
|
||||
resTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, forSpellId, selectFlags);
|
||||
if (!resTarget && ((forSpellId == 0 && selectFlags == 0 && m_creature->getThreatManager().getThreatList().size() > 1) || m_creature->getThreatManager().getThreatList().empty()))
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_HOSTILE_RANDOM_PLAYER:
|
||||
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, forSpellId, SELECT_FLAG_PLAYER | selectFlags);
|
||||
resTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, forSpellId, SELECT_FLAG_PLAYER | selectFlags);
|
||||
if (!resTarget)
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER:
|
||||
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, forSpellId, SELECT_FLAG_PLAYER | selectFlags);
|
||||
resTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, forSpellId, SELECT_FLAG_PLAYER | selectFlags);
|
||||
if (!resTarget && ((forSpellId == 0 && selectFlags == 0 && m_creature->getThreatManager().getThreatList().size() > 1) || m_creature->getThreatManager().getThreatList().empty()))
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_ACTION_INVOKER:
|
||||
if (!pActionInvoker)
|
||||
isError = true;
|
||||
return pActionInvoker;
|
||||
case TARGET_T_ACTION_INVOKER_OWNER:
|
||||
return pActionInvoker ? pActionInvoker->GetCharmerOrOwnerOrSelf() : NULL;
|
||||
resTarget = pActionInvoker ? pActionInvoker->GetCharmerOrOwnerOrSelf() : NULL;
|
||||
if (!resTarget)
|
||||
isError = true;
|
||||
return resTarget;
|
||||
case TARGET_T_EVENT_SENDER:
|
||||
if (!pAIEventSender)
|
||||
isError = true;
|
||||
return pAIEventSender;
|
||||
default:
|
||||
isError = true;
|
||||
return NULL;
|
||||
};
|
||||
}
|
||||
|
|
@ -1371,85 +1420,8 @@ void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, flo
|
|||
//*********************************
|
||||
//*** Functions used globally ***
|
||||
|
||||
void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
|
||||
{
|
||||
if (!pSource)
|
||||
{
|
||||
sLog.outErrorEventAI("DoScriptText entry %i, invalid Source pointer.", textEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
if (textEntry >= 0)
|
||||
{
|
||||
sLog.outErrorEventAI("DoScriptText with source entry %u (TypeId=%u, guid=%u) attempts to process text entry %i, but text entry must be negative.", pSource->GetEntry(), pSource->GetTypeId(), pSource->GetGUIDLow(), textEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
CreatureEventAI_TextMap::const_iterator i = sEventAIMgr.GetCreatureEventAITextMap().find(textEntry);
|
||||
|
||||
if (i == sEventAIMgr.GetCreatureEventAITextMap().end())
|
||||
{
|
||||
sLog.outErrorEventAI("DoScriptText with source entry %u (TypeId=%u, guid=%u) could not find text entry %i.", pSource->GetEntry(), pSource->GetTypeId(), pSource->GetGUIDLow(), textEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "CreatureEventAI: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u", textEntry, (*i).second.SoundId, (*i).second.Type, (*i).second.Language, (*i).second.Emote);
|
||||
|
||||
if ((*i).second.SoundId)
|
||||
{
|
||||
if (GetSoundEntriesStore()->LookupEntry((*i).second.SoundId))
|
||||
pSource->PlayDirectSound((*i).second.SoundId);
|
||||
else
|
||||
sLog.outErrorEventAI("DoScriptText entry %i tried to process invalid sound id %u.", textEntry, (*i).second.SoundId);
|
||||
}
|
||||
|
||||
if ((*i).second.Emote)
|
||||
{
|
||||
if (pSource->GetTypeId() == TYPEID_UNIT || pSource->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Unit*)pSource)->HandleEmote((*i).second.Emote);
|
||||
}
|
||||
else
|
||||
sLog.outErrorEventAI("DoScriptText entry %i tried to process emote for invalid TypeId (%u).", textEntry, pSource->GetTypeId());
|
||||
}
|
||||
|
||||
switch ((*i).second.Type)
|
||||
{
|
||||
case CHAT_TYPE_SAY:
|
||||
pSource->MonsterSay(textEntry, (*i).second.Language, target);
|
||||
break;
|
||||
case CHAT_TYPE_YELL:
|
||||
pSource->MonsterYell(textEntry, (*i).second.Language, target);
|
||||
break;
|
||||
case CHAT_TYPE_TEXT_EMOTE:
|
||||
pSource->MonsterTextEmote(textEntry, target);
|
||||
break;
|
||||
case CHAT_TYPE_BOSS_EMOTE:
|
||||
pSource->MonsterTextEmote(textEntry, target, true);
|
||||
break;
|
||||
case CHAT_TYPE_WHISPER:
|
||||
{
|
||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||
pSource->MonsterWhisper(textEntry, target);
|
||||
else sLog.outErrorEventAI("DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry);
|
||||
} break;
|
||||
case CHAT_TYPE_BOSS_WHISPER:
|
||||
{
|
||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||
pSource->MonsterWhisper(textEntry, target, true);
|
||||
else sLog.outErrorEventAI("DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry);
|
||||
} break;
|
||||
case CHAT_TYPE_ZONE_YELL:
|
||||
pSource->MonsterYellToZone(textEntry, (*i).second.Language, target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
|
||||
{
|
||||
if (m_bEmptyList)
|
||||
return;
|
||||
|
||||
for (CreatureEventAIList::iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
||||
{
|
||||
if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE)
|
||||
|
|
@ -1467,7 +1439,9 @@ void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
|
|||
}
|
||||
}
|
||||
|
||||
void CreatureEventAI::DamageTaken(Unit* /*done_by*/, uint32& damage)
|
||||
#define HEALTH_STEPS 3
|
||||
|
||||
void CreatureEventAI::DamageTaken(Unit* dealer, uint32& damage)
|
||||
{
|
||||
if (m_InvinceabilityHpLevel > 0 && m_creature->GetHealth() < m_InvinceabilityHpLevel + damage)
|
||||
{
|
||||
|
|
@ -1476,6 +1450,46 @@ void CreatureEventAI::DamageTaken(Unit* /*done_by*/, uint32& damage)
|
|||
else
|
||||
damage = m_creature->GetHealth() - m_InvinceabilityHpLevel;
|
||||
}
|
||||
|
||||
uint32 step = m_throwAIEventStep != 100 ? m_throwAIEventStep : 0;
|
||||
if (step < HEALTH_STEPS)
|
||||
{
|
||||
// Throw at 90%, 50% and 10% health
|
||||
float healthSteps[HEALTH_STEPS] = { 90.0f, 50.0f, 10.0f };
|
||||
float newHealthPercent = (m_creature->GetHealth() - damage) * 100.0f / m_creature->GetMaxHealth();
|
||||
AIEventType sendEvent[HEALTH_STEPS] = { AI_EVENT_LOST_SOME_HEALTH, AI_EVENT_LOST_HEALTH, AI_EVENT_CRITICAL_HEALTH };
|
||||
|
||||
if (newHealthPercent > healthSteps[step])
|
||||
return; // Not reached the next mark
|
||||
|
||||
// search for highest reached mark (with actual event attached)
|
||||
for (uint32 i = HEALTH_STEPS - 1; i > step; --i)
|
||||
{
|
||||
if (newHealthPercent < healthSteps[i] && (m_throwAIEventMask & (1 << sendEvent[i])))
|
||||
{
|
||||
step = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_throwAIEventMask & (1 << sendEvent[step]))
|
||||
SendAIEventAround(sendEvent[step], dealer, 0, AIEVENT_DEFAULT_THROW_RADIUS);
|
||||
|
||||
m_throwAIEventStep = step + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureEventAI::HealedBy(Unit* healer, uint32& healedAmount)
|
||||
{
|
||||
if (m_throwAIEventStep == 100)
|
||||
return;
|
||||
|
||||
if (m_creature->GetHealth() + healedAmount >= m_creature->GetMaxHealth())
|
||||
{
|
||||
if (m_throwAIEventMask & (1 << AI_EVENT_GOT_FULL_HEALTH))
|
||||
SendAIEventAround(AI_EVENT_GOT_FULL_HEALTH, healer, 0, AIEVENT_DEFAULT_THROW_RADIUS);
|
||||
m_throwAIEventStep = 100;
|
||||
}
|
||||
}
|
||||
|
||||
bool CreatureEventAI::SpawnedEventConditionsCheck(CreatureEventAI_Event const& event)
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ enum EventAI_ActionType
|
|||
ACTION_T_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to unmount)
|
||||
ACTION_T_CHANCED_TEXT = 44, // Chance to display the text, TextId1, optionally TextId2. If more than just -TextId1 is defined, randomize. Negative values.
|
||||
ACTION_T_THROW_AI_EVENT = 45, // EventType, Radius, unused
|
||||
ACTION_T_SET_THROW_MASK = 46, // EventTypeMask, unused, unused
|
||||
ACTION_T_END,
|
||||
};
|
||||
|
||||
|
|
@ -132,15 +133,13 @@ enum Target
|
|||
TARGET_T_HOSTILE_RANDOM_NOT_TOP = 5, // Any random target except top threat
|
||||
|
||||
// Invoker targets (if pet then returns pet owner)
|
||||
TARGET_T_ACTION_INVOKER = 6, // Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
|
||||
TARGET_T_ACTION_INVOKER_OWNER = 7, // Unit who is responsible for Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
|
||||
TARGET_T_ACTION_INVOKER = 6, // Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF, EVENT_T_RECEIVE_EMOTE, EVENT_T_RECEIVE_AI_EVENT)
|
||||
TARGET_T_ACTION_INVOKER_OWNER = 7, // Unit who is responsible for Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF, EVENT_T_RECEIVE_EMOTE, EVENT_T_RECEIVE_AI_EVENT)
|
||||
TARGET_T_EVENT_SENDER = 10, // Unit who sent an AIEvent that was received with EVENT_T_RECEIVE_AI_EVENT
|
||||
|
||||
// Hostile targets (including pets)
|
||||
TARGET_T_HOSTILE_RANDOM_PLAYER = 8, // Just any random player on our threat list
|
||||
TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER = 9, // Any random player from threat list except top threat
|
||||
|
||||
TARGET_T_END
|
||||
TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER = 9 // Any random player from threat list except top threat
|
||||
};
|
||||
|
||||
enum EventFlags
|
||||
|
|
@ -164,17 +163,6 @@ enum SpawnedEventMode
|
|||
SPAWNED_EVENT_ZONE = 2
|
||||
};
|
||||
|
||||
// String text additional data, used in (CreatureEventAI)
|
||||
struct StringTextData
|
||||
{
|
||||
uint32 SoundId;
|
||||
uint8 Type;
|
||||
uint32 Language;
|
||||
uint32 Emote;
|
||||
};
|
||||
// Text Maps
|
||||
typedef UNORDERED_MAP<int32, StringTextData> CreatureEventAI_TextMap;
|
||||
|
||||
struct CreatureEventAI_Action
|
||||
{
|
||||
EventAI_ActionType type: 16;
|
||||
|
|
@ -402,6 +390,13 @@ struct CreatureEventAI_Action
|
|||
uint32 radius;
|
||||
uint32 unused;
|
||||
} throwEvent;
|
||||
// ACTION_T_SET_THROW_MASK = 46
|
||||
struct
|
||||
{
|
||||
uint32 eventTypeMask;
|
||||
uint32 unused1;
|
||||
uint32 unused2;
|
||||
} setThrowMask;
|
||||
// RAW
|
||||
struct
|
||||
{
|
||||
|
|
@ -412,6 +407,8 @@ struct CreatureEventAI_Action
|
|||
};
|
||||
};
|
||||
|
||||
#define AIEVENT_DEFAULT_THROW_RADIUS 30.0f
|
||||
|
||||
struct CreatureEventAI_Event
|
||||
{
|
||||
uint32 event_id;
|
||||
|
|
@ -620,6 +617,7 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
|||
void MoveInLineOfSight(Unit* who) override;
|
||||
void SpellHit(Unit* pUnit, const SpellEntry* pSpell) override;
|
||||
void DamageTaken(Unit* done_by, uint32& damage) override;
|
||||
void HealedBy(Unit* healer, uint32& healedAmount) override;
|
||||
void UpdateAI(const uint32 diff) override;
|
||||
bool IsVisible(Unit*) const override;
|
||||
void ReceiveEmote(Player* pPlayer, uint32 text_emote) override;
|
||||
|
|
@ -633,9 +631,8 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
|||
void ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker, Creature* pAIEventSender);
|
||||
inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
|
||||
inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3);
|
||||
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker, Creature* pAIEventSender, uint32 forSpellId = 0, uint32 selectFlags = 0);
|
||||
|
||||
void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target);
|
||||
/// If the bool& param is true, an error should be reported
|
||||
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker, Creature* pAIEventSender, bool& isError, uint32 forSpellId = 0, uint32 selectFlags = 0);
|
||||
|
||||
bool SpawnedEventConditionsCheck(CreatureEventAI_Event const& event);
|
||||
|
||||
|
|
@ -655,6 +652,11 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
|||
uint8 m_Phase; // Current phase, max 32 phases
|
||||
bool m_MeleeEnabled; // If we allow melee auto attack
|
||||
uint32 m_InvinceabilityHpLevel; // Minimal health level allowed at damage apply
|
||||
|
||||
uint32 m_throwAIEventMask; // Automatically throw AIEvents that are encoded into this mask
|
||||
// Note that Step 100 means that AI_EVENT_GOT_FULL_HEALTH was sent
|
||||
// Steps 0..2 correspond to AI_EVENT_LOST_SOME_HEALTH(90%), AI_EVENT_LOST_HEALTH(50%), AI_EVENT_CRITICAL_HEALTH(10%)
|
||||
uint32 m_throwAIEventStep; // Used for damage taken/ received heal
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,93 +34,24 @@ INSTANTIATE_SINGLETON_1(CreatureEventAIMgr);
|
|||
// -------------------
|
||||
void CreatureEventAIMgr::LoadCreatureEventAI_Texts(bool check_entry_use)
|
||||
{
|
||||
// Drop Existing Text Map, only done once and we are ready to add data from multiple sources.
|
||||
m_CreatureEventAI_TextMap.clear();
|
||||
|
||||
// Load EventAI Text
|
||||
sObjectMgr.LoadMangosStrings(WorldDatabase, "creature_ai_texts", MIN_CREATURE_AI_TEXT_STRING_ID, MAX_CREATURE_AI_TEXT_STRING_ID);
|
||||
|
||||
// Gather Additional data from EventAI Texts
|
||||
QueryResult* result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
|
||||
|
||||
sLog.outString("Loading EventAI Texts additional data...");
|
||||
if (result)
|
||||
{
|
||||
BarGoLink bar(result->GetRowCount());
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
Field* fields = result->Fetch();
|
||||
StringTextData temp;
|
||||
|
||||
int32 i = fields[0].GetInt32();
|
||||
temp.SoundId = fields[1].GetInt32();
|
||||
temp.Type = fields[2].GetInt32();
|
||||
temp.Language = fields[3].GetInt32();
|
||||
temp.Emote = fields[4].GetInt32();
|
||||
|
||||
// range negative
|
||||
if (i > MIN_CREATURE_AI_TEXT_STRING_ID || i <= MAX_CREATURE_AI_TEXT_STRING_ID)
|
||||
{
|
||||
sLog.outErrorEventAI("CreatureEventAI: Entry %i in table `creature_ai_texts` is not in valid range(%d-%d)", i, MIN_CREATURE_AI_TEXT_STRING_ID, MAX_CREATURE_AI_TEXT_STRING_ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
// range negative (don't must be happen, loaded from same table)
|
||||
if (!sObjectMgr.GetMangosStringLocale(i))
|
||||
{
|
||||
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` not found", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (temp.SoundId)
|
||||
{
|
||||
if (!sSoundEntriesStore.LookupEntry(temp.SoundId))
|
||||
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` has Sound %u but sound does not exist.", i, temp.SoundId);
|
||||
}
|
||||
|
||||
if (!GetLanguageDescByID(temp.Language))
|
||||
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.", i, temp.Language);
|
||||
|
||||
if (temp.Type > CHAT_TYPE_ZONE_YELL)
|
||||
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.", i, temp.Type);
|
||||
|
||||
if (temp.Emote)
|
||||
{
|
||||
if (!sEmotesStore.LookupEntry(temp.Emote))
|
||||
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` has Emote %u but emote does not exist.", i, temp.Emote);
|
||||
}
|
||||
|
||||
m_CreatureEventAI_TextMap[i] = temp;
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
sObjectMgr.LoadMangosStrings(WorldDatabase, "creature_ai_texts", MIN_CREATURE_AI_TEXT_STRING_ID, MAX_CREATURE_AI_TEXT_STRING_ID, true);
|
||||
if (check_entry_use)
|
||||
CheckUnusedAITexts();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u additional CreatureEventAI Texts data.", count);
|
||||
}
|
||||
else
|
||||
{
|
||||
BarGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 additional CreatureEventAI Texts data. DB table `creature_ai_texts` is empty.");
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureEventAIMgr::CheckUnusedAITexts()
|
||||
{
|
||||
if (m_usedTextsAmount == sObjectMgr.GetLoadedStringsCount(MIN_CREATURE_AI_TEXT_STRING_ID))
|
||||
return;
|
||||
|
||||
sLog.outString("Checking EventAI for unused texts, this might take a while");
|
||||
|
||||
std::set<int32> idx_set;
|
||||
// check not used strings this is negative range
|
||||
for (CreatureEventAI_TextMap::const_iterator itr = m_CreatureEventAI_TextMap.begin(); itr != m_CreatureEventAI_TextMap.end(); ++itr)
|
||||
idx_set.insert(itr->first);
|
||||
for (int32 i = MAX_CREATURE_AI_TEXT_STRING_ID + 1; i <= MIN_CREATURE_AI_TEXT_STRING_ID; ++i)
|
||||
if (sObjectMgr.GetMangosStringLocale(i))
|
||||
idx_set.insert(i);
|
||||
|
||||
for (CreatureEventAI_Event_Map::const_iterator itr = m_CreatureEventAI_Event_Map.begin(); itr != m_CreatureEventAI_Event_Map.end(); ++itr)
|
||||
{
|
||||
|
|
@ -153,6 +84,73 @@ void CreatureEventAIMgr::CheckUnusedAITexts()
|
|||
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` but not used in EventAI scripts.", *itr);
|
||||
}
|
||||
|
||||
/// Helper function to check if a target-suite is suitable for the event-type
|
||||
bool IsValidTargetType(EventAI_Type eventType, EventAI_ActionType actionType, uint32 targetType, uint32 eventId, uint8 action)
|
||||
{
|
||||
switch (targetType)
|
||||
{
|
||||
case TARGET_T_SELF:
|
||||
if (actionType == ACTION_T_QUEST_EVENT || actionType == ACTION_T_CAST_EVENT || actionType == ACTION_T_QUEST_EVENT_ALL || actionType == ACTION_T_KILLED_MONSTER)
|
||||
{
|
||||
sLog.outErrorEventAI("Event %u Action%u uses incorrect Target type %u for event-type %u (must target player)", eventId, action, targetType, eventType);
|
||||
return false;
|
||||
}
|
||||
return true; // Can always be used
|
||||
case TARGET_T_HOSTILE_RANDOM:
|
||||
case TARGET_T_HOSTILE_RANDOM_NOT_TOP:
|
||||
if (actionType == ACTION_T_QUEST_EVENT || actionType == ACTION_T_CAST_EVENT || actionType == ACTION_T_QUEST_EVENT_ALL || actionType == ACTION_T_KILLED_MONSTER)
|
||||
sLog.outErrorEventAI("Event %u Action%u uses LIKELY bad Target type %u for event-type %u (must target player)", eventId, action, targetType, eventType);
|
||||
// no break, check if valid at all
|
||||
case TARGET_T_HOSTILE:
|
||||
case TARGET_T_HOSTILE_SECOND_AGGRO:
|
||||
case TARGET_T_HOSTILE_LAST_AGGRO:
|
||||
case TARGET_T_HOSTILE_RANDOM_PLAYER:
|
||||
case TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER:
|
||||
switch (eventType)
|
||||
{
|
||||
case EVENT_T_TIMER_OOC:
|
||||
case EVENT_T_OOC_LOS:
|
||||
case EVENT_T_REACHED_HOME:
|
||||
sLog.outErrorEventAI("Event %u Action%u uses incorrect Target type %u for event-type %u (cannot be used OOC)", eventId, action, targetType, eventType);
|
||||
return false;
|
||||
case EVENT_T_TIMER_GENERIC:
|
||||
sLog.outErrorEventAI("Event %u Action%u uses LIKELY incorrect Target type %u for event-type %u (cannot be used OOC)", eventId, action, targetType, eventType);
|
||||
return true; // Does not need to be an error
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
case TARGET_T_ACTION_INVOKER: // Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF, EVENT_T_RECEIVE_EMOTE, EVENT_T_RECEIVE_AI_EVENT)
|
||||
case TARGET_T_ACTION_INVOKER_OWNER: // Unit who is responsible for Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF, EVENT_T_RECEIVE_EMOTE, EVENT_T_RECEIVE_AI_EVENT)
|
||||
switch (eventType)
|
||||
{
|
||||
case EVENT_T_AGGRO:
|
||||
case EVENT_T_KILL:
|
||||
case EVENT_T_DEATH:
|
||||
case EVENT_T_SPELLHIT:
|
||||
case EVENT_T_OOC_LOS:
|
||||
case EVENT_T_FRIENDLY_HP:
|
||||
case EVENT_T_FRIENDLY_IS_CC:
|
||||
case EVENT_T_FRIENDLY_MISSING_BUFF:
|
||||
case EVENT_T_RECEIVE_EMOTE:
|
||||
case EVENT_T_RECEIVE_AI_EVENT:
|
||||
return true;
|
||||
default:
|
||||
sLog.outErrorEventAI("Event %u Action%u uses incorrect Target type %u for event-type %u", eventId, action, targetType, eventType);
|
||||
return false;
|
||||
}
|
||||
case TARGET_T_EVENT_SENDER: // Unit who sent an AIEvent that was received with EVENT_T_RECEIVE_AI_EVENT
|
||||
if (eventType != EVENT_T_RECEIVE_AI_EVENT)
|
||||
{
|
||||
sLog.outErrorEventAI("Event %u Action%u uses incorrect Target type %u for event-type %u", eventId, action, targetType, eventType);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
sLog.outErrorEventAI("Event %u Action%u uses incorrect Target type", eventId, action);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------
|
||||
void CreatureEventAIMgr::LoadCreatureEventAI_Summons(bool check_entry_use)
|
||||
{
|
||||
|
|
@ -248,6 +246,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
{
|
||||
// Drop Existing EventAI List
|
||||
m_CreatureEventAI_Event_Map.clear();
|
||||
std::set<int32> usedTextIds;
|
||||
|
||||
// Gather event data
|
||||
QueryResult* result = WorldDatabase.Query("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
|
||||
|
|
@ -492,13 +491,13 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
// Sender-Creature does not exist in database
|
||||
if (temp.receiveAIEvent.senderEntry && !sCreatureStorage.LookupEntry<CreatureInfo>(temp.receiveAIEvent.senderEntry))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u has nonexisting creature (%u) defined for event RECEIVE_AI_EVENT, skipping.", i, temp.receiveAIEvent.senderEntry);
|
||||
sLog.outErrorEventAI("Event %u has nonexisting creature (%u) defined for event RECEIVE_AI_EVENT, skipping.", i, temp.receiveAIEvent.senderEntry);
|
||||
continue;
|
||||
}
|
||||
// Event-Type is not defined
|
||||
if (temp.receiveAIEvent.eventType >= MAXIMAL_AI_EVENT_EVENTAI)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u has unfitting event-type (%u) defined for event RECEIVE_AI_EVENT (must be less than %u), skipping.", i, temp.receiveAIEvent.eventType, MAXIMAL_AI_EVENT_EVENTAI);
|
||||
sLog.outErrorEventAI("Event %u has unfitting event-type (%u) defined for event RECEIVE_AI_EVENT (must be less than %u), skipping.", i, temp.receiveAIEvent.eventType, MAXIMAL_AI_EVENT_EVENTAI);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
@ -556,11 +555,13 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
sLog.outErrorEventAI("Event %u Action %u param%d references out-of-range entry (%i) in texts table.", i, j + 1, k + 1, action.text.TextId[k]);
|
||||
action.text.TextId[k] = 0;
|
||||
}
|
||||
else if (m_CreatureEventAI_TextMap.find(action.text.TextId[k]) == m_CreatureEventAI_TextMap.end())
|
||||
else if (!sObjectMgr.GetMangosStringLocale(action.text.TextId[k]))
|
||||
{
|
||||
sLog.outErrorEventAI("Event %u Action %u param%d references non-existing entry (%i) in texts table.", i, j + 1, k + 1, action.text.TextId[k]);
|
||||
action.text.TextId[k] = 0;
|
||||
}
|
||||
else
|
||||
usedTextIds.insert(action.text.TextId[k]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -641,12 +642,17 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
|
||||
action.cast.castFlags |= CAST_TRIGGERED;
|
||||
|
||||
if (action.cast.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.cast.target, i, j + 1);
|
||||
|
||||
// Some Advanced target type checks - Can have false positives
|
||||
if (!sLog.HasLogFilter(LOG_FILTER_EVENT_AI_DEV) && spell)
|
||||
{
|
||||
// spell must be cast on self, but is not
|
||||
if ((IsOnlySelfTargeting(spell) || spell->rangeIndex == SPELL_RANGE_IDX_SELF_ONLY) && action.cast.target != TARGET_T_SELF && !(action.cast.castFlags & CAST_FORCE_TARGET_SELF))
|
||||
sLog.outErrorEventAI("Event %u Action %u uses SpellID %u that must be self cast (target is %u)", i, j + 1, action.cast.spellId, action.cast.target);
|
||||
|
||||
// TODO: spell must be cast on enemy, but is not
|
||||
|
||||
// used TARGET_T_ACTION_INVOKER, but likely should be _INVOKER_OWNER instead
|
||||
if (action.cast.target == TARGET_T_ACTION_INVOKER &&
|
||||
(IsSpellHaveEffect(spell, SPELL_EFFECT_QUEST_COMPLETE) || IsSpellHaveEffect(spell, SPELL_EFFECT_CREATE_RANDOM_ITEM) || IsSpellHaveEffect(spell, SPELL_EFFECT_DUMMY)
|
||||
|
|
@ -664,14 +670,12 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.summon.creatureId))
|
||||
sLog.outErrorEventAI("Event %u Action %u uses nonexistent creature entry %u.", i, j + 1, action.summon.creatureId);
|
||||
|
||||
if (action.summon.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.summon.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_THREAT_SINGLE_PCT:
|
||||
if (std::abs(action.threat_single_pct.percent) > 100)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses invalid percent value %u.", i, j + 1, action.threat_single_pct.percent);
|
||||
if (action.threat_single_pct.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.threat_single_pct.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_THREAT_ALL_PCT:
|
||||
if (std::abs(action.threat_all_pct.percent) > 100)
|
||||
|
|
@ -686,28 +690,23 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
else
|
||||
sLog.outErrorEventAI("Event %u Action %u uses nonexistent Quest entry %u.", i, j + 1, action.quest_event.questId);
|
||||
|
||||
if (action.quest_event.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
|
||||
IsValidTargetType(temp.event_type, action.type, action.quest_event.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_CAST_EVENT:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.cast_event.creatureId))
|
||||
sLog.outErrorEventAI("Event %u Action %u uses nonexistent creature entry %u.", i, j + 1, action.cast_event.creatureId);
|
||||
if (!sSpellStore.LookupEntry(action.cast_event.spellId))
|
||||
sLog.outErrorEventAI("Event %u Action %u uses nonexistent SpellID %u.", i, j + 1, action.cast_event.spellId);
|
||||
if (action.cast_event.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.cast_event.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_SET_UNIT_FIELD:
|
||||
if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j + 1);
|
||||
if (action.set_unit_field.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.set_unit_field.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_SET_UNIT_FLAG:
|
||||
case ACTION_T_REMOVE_UNIT_FLAG:
|
||||
if (action.unit_flag.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.unit_flag.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_SET_PHASE:
|
||||
if (action.set_phase.phase >= MAX_PHASE)
|
||||
|
|
@ -737,8 +736,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
case ACTION_T_REMOVEAURASFROMSPELL:
|
||||
if (!sSpellStore.LookupEntry(action.remove_aura.spellId))
|
||||
sLog.outErrorEventAI("Event %u Action %u uses nonexistent SpellID %u.", i, j + 1, action.remove_aura.spellId);
|
||||
if (action.remove_aura.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.remove_aura.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_RANDOM_PHASE: // PhaseId1, PhaseId2, PhaseId3
|
||||
if (action.random_phase.phase1 >= MAX_PHASE)
|
||||
|
|
@ -763,16 +761,14 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
case ACTION_T_SUMMON_ID:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.summon_id.creatureId))
|
||||
sLog.outErrorEventAI("Event %u Action %u uses nonexistent creature entry %u.", i, j + 1, action.summon_id.creatureId);
|
||||
if (action.summon_id.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.summon_id.target, i, j + 1);
|
||||
if (m_CreatureEventAI_Summon_Map.find(action.summon_id.spawnId) == m_CreatureEventAI_Summon_Map.end())
|
||||
sLog.outErrorEventAI("Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j + 1, action.summon_id.spawnId);
|
||||
break;
|
||||
case ACTION_T_KILLED_MONSTER:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.killed_monster.creatureId))
|
||||
sLog.outErrorEventAI("Event %u Action %u uses nonexistent creature entry %u.", i, j + 1, action.killed_monster.creatureId);
|
||||
if (action.killed_monster.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.killed_monster.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_SET_INST_DATA:
|
||||
if (!(temp.event_flags & EFLAG_DIFFICULTY_ALL))
|
||||
|
|
@ -783,8 +779,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
case ACTION_T_SET_INST_DATA64:
|
||||
if (!(temp.event_flags & EFLAG_DIFFICULTY_ALL))
|
||||
sLog.outErrorEventAI("Event %u Action %u. Cannot set instance data without difficulty event flags.", i, j + 1);
|
||||
if (action.set_inst_data64.target >= TARGET_T_END)
|
||||
sLog.outErrorEventAI("Event %u Action %u uses incorrect Target type", i, j + 1);
|
||||
IsValidTargetType(temp.event_type, action.type, action.set_inst_data64.target, i, j + 1);
|
||||
break;
|
||||
case ACTION_T_UPDATE_TEMPLATE:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.update_template.creatureId))
|
||||
|
|
@ -851,20 +846,27 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
case ACTION_T_THROW_AI_EVENT:
|
||||
if (action.throwEvent.eventType >= MAXIMAL_AI_EVENT_EVENTAI)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid event type %u (must be less than %u), skipping", i, j + 1, action.throwEvent.eventType, MAXIMAL_AI_EVENT_EVENTAI);
|
||||
sLog.outErrorEventAI("Event %u Action %u uses invalid event type %u (must be less than %u), skipping", i, j + 1, action.throwEvent.eventType, MAXIMAL_AI_EVENT_EVENTAI);
|
||||
continue;
|
||||
}
|
||||
if (action.throwEvent.radius > SIZE_OF_GRIDS)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses unexpectedly huge radius %u (expected to be less than %f)", i, j + 1, action.throwEvent.radius, SIZE_OF_GRIDS);
|
||||
sLog.outErrorEventAI("Event %u Action %u uses unexpectedly huge radius %u (expected to be less than %f)", i, j + 1, action.throwEvent.radius, SIZE_OF_GRIDS);
|
||||
|
||||
if (action.throwEvent.radius == 0)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses unexpected radius 0 (set to %f of CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS)", i, j + 1, sWorld.getConfig(CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS));
|
||||
sLog.outErrorEventAI("Event %u Action %u uses unexpected radius 0 (set to %f of CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS)", i, j + 1, sWorld.getConfig(CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS));
|
||||
action.throwEvent.radius = uint32(sWorld.getConfig(CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ACTION_T_SET_THROW_MASK:
|
||||
if (action.setThrowMask.eventTypeMask & ~((1 << MAXIMAL_AI_EVENT_EVENTAI) - 1))
|
||||
{
|
||||
sLog.outErrorEventAI("Event %u Action %u uses invalid AIEvent-typemask %u (must be smaller than %u)", i, j + 1, action.setThrowMask.eventTypeMask, MAXIMAL_AI_EVENT_EVENTAI << 1);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorEventAI("Event %u Action %u have currently not checked at load action type (%u). Need check code update?", i, j + 1, temp.action[j].type);
|
||||
break;
|
||||
|
|
@ -878,6 +880,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
|||
while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
m_usedTextsAmount = usedTextIds.size();
|
||||
|
||||
// post check
|
||||
for (uint32 i = 1; i < sCreatureStorage.GetMaxEntry(); ++i)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
class CreatureEventAIMgr
|
||||
{
|
||||
public:
|
||||
CreatureEventAIMgr() {};
|
||||
CreatureEventAIMgr() : m_usedTextsAmount(0) {};
|
||||
~CreatureEventAIMgr() {};
|
||||
|
||||
void LoadCreatureEventAI_Texts(bool check_entry_use);
|
||||
|
|
@ -34,7 +34,6 @@ class CreatureEventAIMgr
|
|||
|
||||
CreatureEventAI_Event_Map const& GetCreatureEventAIMap() const { return m_CreatureEventAI_Event_Map; }
|
||||
CreatureEventAI_Summon_Map const& GetCreatureEventAISummonMap() const { return m_CreatureEventAI_Summon_Map; }
|
||||
CreatureEventAI_TextMap const& GetCreatureEventAITextMap() const { return m_CreatureEventAI_TextMap; }
|
||||
|
||||
private:
|
||||
void CheckUnusedAITexts();
|
||||
|
|
@ -42,7 +41,8 @@ class CreatureEventAIMgr
|
|||
|
||||
CreatureEventAI_Event_Map m_CreatureEventAI_Event_Map;
|
||||
CreatureEventAI_Summon_Map m_CreatureEventAI_Summon_Map;
|
||||
CreatureEventAI_TextMap m_CreatureEventAI_TextMap;
|
||||
|
||||
uint32 m_usedTextsAmount;
|
||||
};
|
||||
|
||||
#define sEventAIMgr MaNGOS::Singleton<CreatureEventAIMgr>::Instance()
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ namespace MaNGOS
|
|||
|
||||
struct MANGOS_DLL_DECL MessageDeliverer
|
||||
{
|
||||
Player& i_player;
|
||||
Player const& i_player;
|
||||
WorldPacket* i_message;
|
||||
bool i_toSelf;
|
||||
MessageDeliverer(Player& pl, WorldPacket* msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {}
|
||||
MessageDeliverer(Player const& pl, WorldPacket* msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {}
|
||||
void Visit(CameraMapType& m);
|
||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||
};
|
||||
|
|
@ -81,7 +81,7 @@ namespace MaNGOS
|
|||
{
|
||||
uint32 i_phaseMask;
|
||||
WorldPacket* i_message;
|
||||
explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket* msg)
|
||||
explicit ObjectMessageDeliverer(WorldObject const& obj, WorldPacket* msg)
|
||||
: i_phaseMask(obj.GetPhaseMask()), i_message(msg) {}
|
||||
void Visit(CameraMapType& m);
|
||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||
|
|
@ -89,13 +89,13 @@ namespace MaNGOS
|
|||
|
||||
struct MANGOS_DLL_DECL MessageDistDeliverer
|
||||
{
|
||||
Player& i_player;
|
||||
Player const& i_player;
|
||||
WorldPacket* i_message;
|
||||
bool i_toSelf;
|
||||
bool i_ownTeamOnly;
|
||||
float i_dist;
|
||||
|
||||
MessageDistDeliverer(Player& pl, WorldPacket* msg, float dist, bool to_self, bool ownTeamOnly)
|
||||
MessageDistDeliverer(Player const& pl, WorldPacket* msg, float dist, bool to_self, bool ownTeamOnly)
|
||||
: i_player(pl), i_message(msg), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly), i_dist(dist) {}
|
||||
void Visit(CameraMapType& m);
|
||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||
|
|
@ -103,10 +103,10 @@ namespace MaNGOS
|
|||
|
||||
struct MANGOS_DLL_DECL ObjectMessageDistDeliverer
|
||||
{
|
||||
WorldObject& i_object;
|
||||
WorldObject const& i_object;
|
||||
WorldPacket* i_message;
|
||||
float i_dist;
|
||||
ObjectMessageDistDeliverer(WorldObject& obj, WorldPacket* msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {}
|
||||
ObjectMessageDistDeliverer(WorldObject const& obj, WorldPacket* msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {}
|
||||
void Visit(CameraMapType& m);
|
||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||
};
|
||||
|
|
@ -1127,12 +1127,13 @@ namespace MaNGOS
|
|||
class NearestCreatureEntryWithLiveStateInObjectRangeCheck
|
||||
{
|
||||
public:
|
||||
NearestCreatureEntryWithLiveStateInObjectRangeCheck(WorldObject const& obj, uint32 entry, bool onlyAlive, bool onlyDead, float range)
|
||||
: i_obj(obj), i_entry(entry), i_onlyAlive(onlyAlive), i_onlyDead(onlyDead), i_range(range) {}
|
||||
NearestCreatureEntryWithLiveStateInObjectRangeCheck(WorldObject const& obj, uint32 entry, bool onlyAlive, bool onlyDead, float range, bool excludeSelf = false)
|
||||
: i_obj(obj), i_entry(entry), i_onlyAlive(onlyAlive), i_onlyDead(onlyDead), i_excludeSelf(excludeSelf), i_range(range) {}
|
||||
WorldObject const& GetFocusObject() const { return i_obj; }
|
||||
bool operator()(Creature* u)
|
||||
{
|
||||
if (u->GetEntry() == i_entry && ((i_onlyAlive && u->isAlive()) || (i_onlyDead && u->IsCorpse()) || (!i_onlyAlive && !i_onlyDead)) && i_obj.IsWithinDistInMap(u, i_range))
|
||||
if (u->GetEntry() == i_entry && ((i_onlyAlive && u->isAlive()) || (i_onlyDead && u->IsCorpse()) || (!i_onlyAlive && !i_onlyDead))
|
||||
&& (!i_excludeSelf || &i_obj != u) && i_obj.IsWithinDistInMap(u, i_range))
|
||||
{
|
||||
i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check
|
||||
return true;
|
||||
|
|
@ -1145,6 +1146,7 @@ namespace MaNGOS
|
|||
uint32 i_entry;
|
||||
bool i_onlyAlive;
|
||||
bool i_onlyDead;
|
||||
bool i_excludeSelf;
|
||||
float i_range;
|
||||
|
||||
// prevent clone this object
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ enum InstanceConditionIDs // Suggested values
|
|||
// to check water event in SSC
|
||||
INSTANCE_CONDITION_ID_LURKER = 21217,
|
||||
INSTANCE_CONDITION_ID_SCALDING_WATER = 37284,
|
||||
// to check vehicles in Ulduar
|
||||
INSTANCE_CONDITION_ID_ULDUAR = 33113,
|
||||
};
|
||||
|
||||
class MANGOS_DLL_SPEC InstanceData
|
||||
|
|
|
|||
|
|
@ -1545,6 +1545,7 @@ void LoadLootTemplates_Reference()
|
|||
LootTemplates_Prospecting.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Mail.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Reference.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Spell.CheckLootRefs(&ids_set);
|
||||
|
||||
// output error for any still listed ids (not referenced from any loot table)
|
||||
LootTemplates_Reference.ReportUnusedIds(ids_set);
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ Map::Add(T* obj)
|
|||
UpdateObjectVisibility(obj, cell, p);
|
||||
}
|
||||
|
||||
void Map::MessageBroadcast(Player* player, WorldPacket* msg, bool to_self)
|
||||
void Map::MessageBroadcast(Player const* player, WorldPacket* msg, bool to_self)
|
||||
{
|
||||
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
||||
|
||||
|
|
@ -363,7 +363,7 @@ void Map::MessageBroadcast(Player* player, WorldPacket* msg, bool to_self)
|
|||
cell.Visit(p, message, *this, *player, GetVisibilityDistance());
|
||||
}
|
||||
|
||||
void Map::MessageBroadcast(WorldObject* obj, WorldPacket* msg)
|
||||
void Map::MessageBroadcast(WorldObject const* obj, WorldPacket* msg)
|
||||
{
|
||||
CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
|
||||
|
||||
|
|
@ -386,7 +386,7 @@ void Map::MessageBroadcast(WorldObject* obj, WorldPacket* msg)
|
|||
cell.Visit(p, message, *this, *obj, GetVisibilityDistance());
|
||||
}
|
||||
|
||||
void Map::MessageDistBroadcast(Player* player, WorldPacket* msg, float dist, bool to_self, bool own_team_only)
|
||||
void Map::MessageDistBroadcast(Player const* player, WorldPacket* msg, float dist, bool to_self, bool own_team_only)
|
||||
{
|
||||
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
||||
|
||||
|
|
@ -407,7 +407,7 @@ void Map::MessageDistBroadcast(Player* player, WorldPacket* msg, float dist, boo
|
|||
cell.Visit(p, message, *this, *player, dist);
|
||||
}
|
||||
|
||||
void Map::MessageDistBroadcast(WorldObject* obj, WorldPacket* msg, float dist)
|
||||
void Map::MessageDistBroadcast(WorldObject const* obj, WorldPacket* msg, float dist)
|
||||
{
|
||||
CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
|
||||
|
||||
|
|
@ -1866,7 +1866,7 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
|
|||
class StaticMonsterChatBuilder
|
||||
{
|
||||
public:
|
||||
StaticMonsterChatBuilder(CreatureInfo const* cInfo, ChatMsg msgtype, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid = 0)
|
||||
StaticMonsterChatBuilder(CreatureInfo const* cInfo, ChatMsg msgtype, int32 textId, uint32 language, Unit const* target, uint32 senderLowGuid = 0)
|
||||
: i_cInfo(cInfo), i_msgtype(msgtype), i_textId(textId), i_language(language), i_target(target)
|
||||
{
|
||||
// 0 lowguid not used in core, but accepted fine in this case by client
|
||||
|
|
@ -1888,7 +1888,7 @@ class StaticMonsterChatBuilder
|
|||
ChatMsg i_msgtype;
|
||||
int32 i_textId;
|
||||
uint32 i_language;
|
||||
Unit* i_target;
|
||||
Unit const* i_target;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1900,7 +1900,7 @@ class StaticMonsterChatBuilder
|
|||
* @param language language of the text
|
||||
* @param target, can be NULL
|
||||
*/
|
||||
void Map::MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit* target)
|
||||
void Map::MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit const* target) const
|
||||
{
|
||||
if (guid.IsAnyTypeCreature())
|
||||
{
|
||||
|
|
@ -1931,7 +1931,7 @@ void Map::MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit*
|
|||
* @param senderLowGuid provide way proper show yell for near spawned creature with known lowguid,
|
||||
* 0 accepted by client else if this not important
|
||||
*/
|
||||
void Map::MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid /*= 0*/)
|
||||
void Map::MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit const* target, uint32 senderLowGuid /*= 0*/) const
|
||||
{
|
||||
StaticMonsterChatBuilder say_build(cinfo, CHAT_MSG_MONSTER_YELL, textId, language, target, senderLowGuid);
|
||||
MaNGOS::LocalizedPacketDo<StaticMonsterChatBuilder> say_do(say_build);
|
||||
|
|
@ -1947,7 +1947,7 @@ void Map::MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 langu
|
|||
* @param soundId Played Sound
|
||||
* @param zoneId Id of the Zone to which the sound should be restricted
|
||||
*/
|
||||
void Map::PlayDirectSoundToMap(uint32 soundId, uint32 zoneId /*=0*/)
|
||||
void Map::PlayDirectSoundToMap(uint32 soundId, uint32 zoneId /*=0*/) const
|
||||
{
|
||||
WorldPacket data(SMSG_PLAY_SOUND, 4);
|
||||
data << uint32(soundId);
|
||||
|
|
|
|||
|
|
@ -123,10 +123,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
|
|||
|
||||
virtual void Update(const uint32&);
|
||||
|
||||
void MessageBroadcast(Player*, WorldPacket*, bool to_self);
|
||||
void MessageBroadcast(WorldObject*, WorldPacket*);
|
||||
void MessageDistBroadcast(Player*, WorldPacket*, float dist, bool to_self, bool own_team_only = false);
|
||||
void MessageDistBroadcast(WorldObject*, WorldPacket*, float dist);
|
||||
void MessageBroadcast(Player const*, WorldPacket*, bool to_self);
|
||||
void MessageBroadcast(WorldObject const*, WorldPacket*);
|
||||
void MessageDistBroadcast(Player const*, WorldPacket*, float dist, bool to_self, bool own_team_only = false);
|
||||
void MessageDistBroadcast(WorldObject const*, WorldPacket*, float dist);
|
||||
|
||||
float GetVisibilityDistance() const { return m_VisibleDistance; }
|
||||
// function for setting up visibility distance for maps on per-type/per-Id basis
|
||||
|
|
@ -266,9 +266,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
|
|||
InstanceData* GetInstanceData() const { return i_data; }
|
||||
uint32 GetScriptId() const { return i_script_id; }
|
||||
|
||||
void MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit* target);
|
||||
void MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid = 0);
|
||||
void PlayDirectSoundToMap(uint32 soundId, uint32 zoneId = 0);
|
||||
void MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit const* target) const;
|
||||
void MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit const* target, uint32 senderLowGuid = 0) const;
|
||||
void PlayDirectSoundToMap(uint32 soundId, uint32 zoneId = 0) const;
|
||||
|
||||
// Dynamic VMaps
|
||||
float GetHeight(uint32 phasemask, float x, float y, float z) const;
|
||||
|
|
|
|||
|
|
@ -1240,10 +1240,11 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool
|
|||
|
||||
bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const
|
||||
{
|
||||
if (!IsInMap(obj)) return false;
|
||||
if (!IsInMap(obj))
|
||||
return false;
|
||||
float ox, oy, oz;
|
||||
obj->GetPosition(ox, oy, oz);
|
||||
return(IsWithinLOS(ox, oy, oz));
|
||||
return IsWithinLOS(ox, oy, oz);
|
||||
}
|
||||
|
||||
bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
|
||||
|
|
@ -1511,21 +1512,21 @@ bool WorldObject::IsPositionValid() const
|
|||
return MaNGOS::IsValidMapCoord(m_position.x, m_position.y, m_position.z, m_position.o);
|
||||
}
|
||||
|
||||
void WorldObject::MonsterSay(const char* text, uint32 language, Unit* target)
|
||||
void WorldObject::MonsterSay(const char* text, uint32 language, Unit const* target) const
|
||||
{
|
||||
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
||||
BuildMonsterChat(&data, GetObjectGuid(), CHAT_MSG_MONSTER_SAY, text, language, GetName(), target ? target->GetObjectGuid() : ObjectGuid(), target ? target->GetName() : "");
|
||||
SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY), true);
|
||||
}
|
||||
|
||||
void WorldObject::MonsterYell(const char* text, uint32 language, Unit* target)
|
||||
void WorldObject::MonsterYell(const char* text, uint32 language, Unit const* target) const
|
||||
{
|
||||
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
||||
BuildMonsterChat(&data, GetObjectGuid(), CHAT_MSG_MONSTER_YELL, text, language, GetName(), target ? target->GetObjectGuid() : ObjectGuid(), target ? target->GetName() : "");
|
||||
SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_YELL), true);
|
||||
}
|
||||
|
||||
void WorldObject::MonsterTextEmote(const char* text, Unit* target, bool IsBossEmote)
|
||||
void WorldObject::MonsterTextEmote(const char* text, Unit const* target, bool IsBossEmote) const
|
||||
{
|
||||
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
||||
BuildMonsterChat(&data, GetObjectGuid(), IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, text, LANG_UNIVERSAL,
|
||||
|
|
@ -1533,7 +1534,7 @@ void WorldObject::MonsterTextEmote(const char* text, Unit* target, bool IsBossEm
|
|||
SendMessageToSetInRange(&data, sWorld.getConfig(IsBossEmote ? CONFIG_FLOAT_LISTEN_RANGE_YELL : CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE), true);
|
||||
}
|
||||
|
||||
void WorldObject::MonsterWhisper(const char* text, Unit* target, bool IsBossWhisper)
|
||||
void WorldObject::MonsterWhisper(const char* text, Unit const* target, bool IsBossWhisper) const
|
||||
{
|
||||
if (!target || target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
|
@ -1549,7 +1550,7 @@ namespace MaNGOS
|
|||
class MonsterChatBuilder
|
||||
{
|
||||
public:
|
||||
MonsterChatBuilder(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, Unit* target)
|
||||
MonsterChatBuilder(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, Unit const* target)
|
||||
: i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_target(target) {}
|
||||
void operator()(WorldPacket& data, int32 loc_idx)
|
||||
{
|
||||
|
|
@ -1563,11 +1564,11 @@ namespace MaNGOS
|
|||
ChatMsg i_msgtype;
|
||||
int32 i_textId;
|
||||
uint32 i_language;
|
||||
Unit* i_target;
|
||||
Unit const* i_target;
|
||||
};
|
||||
} // namespace MaNGOS
|
||||
|
||||
void WorldObject::MonsterSay(int32 textId, uint32 language, Unit* target)
|
||||
void WorldObject::MonsterSay(int32 textId, uint32 language, Unit const* target) const
|
||||
{
|
||||
float range = sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY);
|
||||
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId, language, target);
|
||||
|
|
@ -1576,7 +1577,7 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, Unit* target)
|
|||
Cell::VisitWorldObjects(this, say_worker, range);
|
||||
}
|
||||
|
||||
void WorldObject::MonsterYell(int32 textId, uint32 language, Unit* target)
|
||||
void WorldObject::MonsterYell(int32 textId, uint32 language, Unit const* target) const
|
||||
{
|
||||
float range = sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_YELL);
|
||||
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId, language, target);
|
||||
|
|
@ -1585,7 +1586,7 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, Unit* target)
|
|||
Cell::VisitWorldObjects(this, say_worker, range);
|
||||
}
|
||||
|
||||
void WorldObject::MonsterYellToZone(int32 textId, uint32 language, Unit* target)
|
||||
void WorldObject::MonsterYellToZone(int32 textId, uint32 language, Unit const* target) const
|
||||
{
|
||||
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId, language, target);
|
||||
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
|
||||
|
|
@ -1598,7 +1599,7 @@ void WorldObject::MonsterYellToZone(int32 textId, uint32 language, Unit* target)
|
|||
say_do(itr->getSource());
|
||||
}
|
||||
|
||||
void WorldObject::MonsterTextEmote(int32 textId, Unit* target, bool IsBossEmote)
|
||||
void WorldObject::MonsterTextEmote(int32 textId, Unit const* target, bool IsBossEmote) const
|
||||
{
|
||||
float range = sWorld.getConfig(IsBossEmote ? CONFIG_FLOAT_LISTEN_RANGE_YELL : CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE);
|
||||
|
||||
|
|
@ -1608,7 +1609,7 @@ void WorldObject::MonsterTextEmote(int32 textId, Unit* target, bool IsBossEmote)
|
|||
Cell::VisitWorldObjects(this, say_worker, range);
|
||||
}
|
||||
|
||||
void WorldObject::MonsterWhisper(int32 textId, Unit* target, bool IsBossWhisper)
|
||||
void WorldObject::MonsterWhisper(int32 textId, Unit const* target, bool IsBossWhisper) const
|
||||
{
|
||||
if (!target || target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
|
@ -1647,21 +1648,21 @@ void WorldObject::BuildMonsterChat(WorldPacket* data, ObjectGuid senderGuid, uin
|
|||
}
|
||||
}
|
||||
|
||||
void WorldObject::SendMessageToSet(WorldPacket* data, bool /*bToSelf*/)
|
||||
void WorldObject::SendMessageToSet(WorldPacket* data, bool /*bToSelf*/) const
|
||||
{
|
||||
// if object is in world, map for it already created!
|
||||
if (IsInWorld())
|
||||
GetMap()->MessageBroadcast(this, data);
|
||||
}
|
||||
|
||||
void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*bToSelf*/)
|
||||
void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*bToSelf*/) const
|
||||
{
|
||||
// if object is in world, map for it already created!
|
||||
if (IsInWorld())
|
||||
GetMap()->MessageDistBroadcast(this, data, dist);
|
||||
}
|
||||
|
||||
void WorldObject::SendMessageToSetExcept(WorldPacket* data, Player const* skipped_receiver)
|
||||
void WorldObject::SendMessageToSetExcept(WorldPacket* data, Player const* skipped_receiver) const
|
||||
{
|
||||
// if object is in world, map for it already created!
|
||||
if (IsInWorld())
|
||||
|
|
@ -1750,6 +1751,9 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
|
|||
return pCreature;
|
||||
}
|
||||
|
||||
// how much space should be left in front of/ behind a mob that already uses a space
|
||||
#define OCCUPY_POS_DEPTH_FACTOR 1.8f
|
||||
|
||||
namespace MaNGOS
|
||||
{
|
||||
class NearUsedPosDo
|
||||
|
|
@ -1796,16 +1800,19 @@ namespace MaNGOS
|
|||
// we must add used pos that can fill places around center
|
||||
void add(WorldObject* u, float x, float y) const
|
||||
{
|
||||
// dist include size of u and i_object
|
||||
float dx = i_object.GetPositionX() - x;
|
||||
float dy = i_object.GetPositionY() - y;
|
||||
float dist2d = sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
float delta = i_selector.m_searcherSize + u->GetObjectBoundingRadius();
|
||||
// It is ok for the objects to require a bit more space
|
||||
float delta = u->GetObjectBoundingRadius();
|
||||
if (i_selector.m_searchPosFor && i_selector.m_searchPosFor != u)
|
||||
delta += i_selector.m_searchPosFor->GetObjectBoundingRadius();
|
||||
|
||||
// u is too nearest/far away to i_object
|
||||
if (dist2d < i_selector.m_searcherDist - delta ||
|
||||
dist2d >= i_selector.m_searcherDist + delta)
|
||||
delta *= OCCUPY_POS_DEPTH_FACTOR; // Increase by factor
|
||||
|
||||
// u is too near/far away from i_object. Do not consider it to occupy space
|
||||
if (fabs(i_selector.m_searcherDist - dist2d) > delta)
|
||||
return;
|
||||
|
||||
float angle = i_object.GetAngle(u) - i_absAngle;
|
||||
|
|
@ -1816,7 +1823,7 @@ namespace MaNGOS
|
|||
else if (angle < -M_PI_F)
|
||||
angle += 2.0f * M_PI_F;
|
||||
|
||||
i_selector.AddUsedArea(u->GetObjectBoundingRadius(), angle, dist2d);
|
||||
i_selector.AddUsedArea(u, angle, dist2d);
|
||||
}
|
||||
private:
|
||||
WorldObject const& i_object;
|
||||
|
|
@ -1830,8 +1837,8 @@ namespace MaNGOS
|
|||
|
||||
void WorldObject::GetNearPoint2D(float& x, float& y, float distance2d, float absAngle) const
|
||||
{
|
||||
x = GetPositionX() + (GetObjectBoundingRadius() + distance2d) * cos(absAngle);
|
||||
y = GetPositionY() + (GetObjectBoundingRadius() + distance2d) * sin(absAngle);
|
||||
x = GetPositionX() + distance2d * cos(absAngle);
|
||||
y = GetPositionY() + distance2d * sin(absAngle);
|
||||
|
||||
MaNGOS::NormalizeMapCoord(x);
|
||||
MaNGOS::NormalizeMapCoord(y);
|
||||
|
|
@ -1839,7 +1846,7 @@ void WorldObject::GetNearPoint2D(float& x, float& y, float distance2d, float abs
|
|||
|
||||
void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_bounding_radius, float distance2d, float absAngle) const
|
||||
{
|
||||
GetNearPoint2D(x, y, distance2d + searcher_bounding_radius, absAngle);
|
||||
GetNearPoint2D(x, y, distance2d, absAngle);
|
||||
const float init_z = z = GetPositionZ();
|
||||
|
||||
// if detection disabled, return first point
|
||||
|
|
@ -1860,14 +1867,14 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
|||
const float dist = distance2d + searcher_bounding_radius + GetObjectBoundingRadius();
|
||||
|
||||
// prepare selector for work
|
||||
ObjectPosSelector selector(GetPositionX(), GetPositionY(), dist, searcher_bounding_radius);
|
||||
ObjectPosSelector selector(GetPositionX(), GetPositionY(), distance2d, searcher_bounding_radius, searcher);
|
||||
|
||||
// adding used positions around object
|
||||
{
|
||||
MaNGOS::NearUsedPosDo u_do(*this, searcher, absAngle, selector);
|
||||
MaNGOS::WorldObjectWorker<MaNGOS::NearUsedPosDo> worker(this, u_do);
|
||||
|
||||
Cell::VisitAllObjects(this, worker, distance2d + searcher_bounding_radius);
|
||||
Cell::VisitAllObjects(this, worker, dist);
|
||||
}
|
||||
|
||||
// maybe can just place in primary position
|
||||
|
|
@ -1892,7 +1899,7 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
|||
// select in positions after current nodes (selection one by one)
|
||||
while (selector.NextAngle(angle)) // angle for free pos
|
||||
{
|
||||
GetNearPoint2D(x, y, distance2d + searcher_bounding_radius, absAngle + angle);
|
||||
GetNearPoint2D(x, y, distance2d, absAngle + angle);
|
||||
z = GetPositionZ();
|
||||
|
||||
if (searcher)
|
||||
|
|
@ -1924,7 +1931,7 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
|||
// select in positions after current nodes (selection one by one)
|
||||
while (selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem
|
||||
{
|
||||
GetNearPoint2D(x, y, distance2d + searcher_bounding_radius, absAngle + angle);
|
||||
GetNearPoint2D(x, y, distance2d, absAngle + angle);
|
||||
z = GetPositionZ();
|
||||
|
||||
if (searcher)
|
||||
|
|
@ -1954,7 +1961,7 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
|||
UpdateVisibilityAndView();
|
||||
}
|
||||
|
||||
void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/)
|
||||
void WorldObject::PlayDistanceSound(uint32 sound_id, Player const* target /*= NULL*/) const
|
||||
{
|
||||
WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4 + 8);
|
||||
data << uint32(sound_id);
|
||||
|
|
@ -1966,7 +1973,7 @@ void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/)
|
|||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= NULL*/)
|
||||
void WorldObject::PlayDirectSound(uint32 sound_id, Player const* target /*= NULL*/) const
|
||||
{
|
||||
WorldPacket data(SMSG_PLAY_SOUND, 4);
|
||||
data << uint32(sound_id);
|
||||
|
|
|
|||
|
|
@ -457,17 +457,37 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
|||
void GetPosition(WorldLocation& loc) const
|
||||
{ loc.mapid = m_mapId; GetPosition(loc.coord_x, loc.coord_y, loc.coord_z); loc.orientation = GetOrientation(); }
|
||||
float GetOrientation() const { return m_position.o; }
|
||||
void GetNearPoint2D(float& x, float& y, float distance, float absAngle) const;
|
||||
/// Gives a 2d-point in distance distance2d in direction absAngle around the current position (point-to-point)
|
||||
void GetNearPoint2D(float& x, float& y, float distance2d, float absAngle) const;
|
||||
/** Gives a "free" spot for searcher in distance distance2d in direction absAngle on "good" height
|
||||
* @param searcher - for whom a spot is searched for
|
||||
* @param x, y, z - position for the found spot of the searcher
|
||||
* @param searcher_bounding_radius - how much space the searcher will require
|
||||
* @param distance2d - distance between the middle-points
|
||||
* @param absAngle - angle in which the spot is preferred
|
||||
*/
|
||||
void GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_bounding_radius, float distance2d, float absAngle) const;
|
||||
void GetClosePoint(float& x, float& y, float& z, float bounding_radius, float distance2d = 0, float angle = 0, const WorldObject* obj = NULL) const
|
||||
/** Gives a "free" spot for a searcher on the distance (including bounding-radius calculation)
|
||||
* @param x, y, z - position for the found spot
|
||||
* @param bounding_radius - radius for the searcher
|
||||
* @param distance2d - range in which to find a free spot. Default = 0.0f (which usually means the units will have contact)
|
||||
* @param angle - direction in which to look for a free spot. Default = 0.0f (direction in which 'this' is looking
|
||||
* @param obj - for whom to look for a spot. Default = NULL
|
||||
*/
|
||||
void GetClosePoint(float& x, float& y, float& z, float bounding_radius, float distance2d = 0.0f, float angle = 0.0f, const WorldObject* obj = NULL) const
|
||||
{
|
||||
// angle calculated from current orientation
|
||||
GetNearPoint(obj, x, y, z, bounding_radius, distance2d, GetOrientation() + angle);
|
||||
GetNearPoint(obj, x, y, z, bounding_radius, distance2d + GetObjectBoundingRadius() + bounding_radius, GetOrientation() + angle);
|
||||
}
|
||||
/** Gives a "free" spot for a searcher in contact-range of "this" (including bounding-radius calculation)
|
||||
* @param x, y, z - position for the found spot
|
||||
* @param obj - for whom to find a contact position. The position will be searched in direction from 'this' towards 'obj'
|
||||
* @param distance2d - distance which 'obj' and 'this' should have beetween their bounding radiuses. Default = CONTACT_DISTANCE
|
||||
*/
|
||||
void GetContactPoint(const WorldObject* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const
|
||||
{
|
||||
// angle to face `obj` to `this` using distance includes size of `obj`
|
||||
GetNearPoint(obj, x, y, z, obj->GetObjectBoundingRadius(), distance2d, GetAngle(obj));
|
||||
GetNearPoint(obj, x, y, z, obj->GetObjectBoundingRadius(), distance2d + GetObjectBoundingRadius() + obj->GetObjectBoundingRadius(), GetAngle(obj));
|
||||
}
|
||||
|
||||
virtual float GetObjectBoundingRadius() const { return DEFAULT_WORLD_OBJECT_SIZE; }
|
||||
|
|
@ -537,23 +557,23 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
|||
|
||||
virtual void CleanupsBeforeDelete(); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
|
||||
|
||||
virtual void SendMessageToSet(WorldPacket* data, bool self);
|
||||
virtual void SendMessageToSetInRange(WorldPacket* data, float dist, bool self);
|
||||
void SendMessageToSetExcept(WorldPacket* data, Player const* skipped_receiver);
|
||||
virtual void SendMessageToSet(WorldPacket* data, bool self) const;
|
||||
virtual void SendMessageToSetInRange(WorldPacket* data, float dist, bool self) const;
|
||||
void SendMessageToSetExcept(WorldPacket* data, Player const* skipped_receiver) const;
|
||||
|
||||
void MonsterSay(const char* text, uint32 language, Unit* target = NULL);
|
||||
void MonsterYell(const char* text, uint32 language, Unit* target = NULL);
|
||||
void MonsterTextEmote(const char* text, Unit* target, bool IsBossEmote = false);
|
||||
void MonsterWhisper(const char* text, Unit* target, bool IsBossWhisper = false);
|
||||
void MonsterSay(int32 textId, uint32 language, Unit* target = NULL);
|
||||
void MonsterYell(int32 textId, uint32 language, Unit* target = NULL);
|
||||
void MonsterTextEmote(int32 textId, Unit* target, bool IsBossEmote = false);
|
||||
void MonsterWhisper(int32 textId, Unit* receiver, bool IsBossWhisper = false);
|
||||
void MonsterYellToZone(int32 textId, uint32 language, Unit* target);
|
||||
void MonsterSay(const char* text, uint32 language, Unit const* target = NULL) const;
|
||||
void MonsterYell(const char* text, uint32 language, Unit const* target = NULL) const;
|
||||
void MonsterTextEmote(const char* text, Unit const* target, bool IsBossEmote = false) const;
|
||||
void MonsterWhisper(const char* text, Unit const* target, bool IsBossWhisper = false) const;
|
||||
void MonsterSay(int32 textId, uint32 language, Unit const* target = NULL) const;
|
||||
void MonsterYell(int32 textId, uint32 language, Unit const* target = NULL) const;
|
||||
void MonsterTextEmote(int32 textId, Unit const* target, bool IsBossEmote = false) const;
|
||||
void MonsterWhisper(int32 textId, Unit const* receiver, bool IsBossWhisper = false) const;
|
||||
void MonsterYellToZone(int32 textId, uint32 language, Unit const* target) const;
|
||||
static void BuildMonsterChat(WorldPacket* data, ObjectGuid senderGuid, uint8 msgtype, char const* text, uint32 language, char const* name, ObjectGuid targetGuid, char const* targetName);
|
||||
|
||||
void PlayDistanceSound(uint32 sound_id, Player* target = NULL);
|
||||
void PlayDirectSound(uint32 sound_id, Player* target = NULL);
|
||||
void PlayDistanceSound(uint32 sound_id, Player const* target = NULL) const;
|
||||
void PlayDirectSound(uint32 sound_id, Player const* target = NULL) const;
|
||||
|
||||
void SendObjectDeSpawnAnim(ObjectGuid guid);
|
||||
void SendGameObjectCustomAnim(ObjectGuid guid, uint32 animId = 0);
|
||||
|
|
|
|||
|
|
@ -153,7 +153,8 @@ ObjectMgr::ObjectMgr() :
|
|||
m_MailIds("Mail ids"),
|
||||
m_PetNumbers("Pet numbers"),
|
||||
m_FirstTemporaryCreatureGuid(1),
|
||||
m_FirstTemporaryGameObjectGuid(1)
|
||||
m_FirstTemporaryGameObjectGuid(1),
|
||||
DBCLocaleIndex(LOCALE_enUS)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -7655,7 +7656,27 @@ void ObjectMgr::LoadGameObjectForQuests()
|
|||
sLog.outString(">> Loaded %u GameObjects for quests", count);
|
||||
}
|
||||
|
||||
bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value)
|
||||
inline void _DoStringError(int32 entry, char const* text, ...)
|
||||
{
|
||||
MANGOS_ASSERT(text);
|
||||
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
va_start(ap, text);
|
||||
vsnprintf(buf, 256, text, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (entry <= MAX_CREATURE_AI_TEXT_STRING_ID) // script library error
|
||||
sLog.outErrorScriptLib("%s", buf);
|
||||
else if (entry <= MIN_CREATURE_AI_TEXT_STRING_ID) // eventAI error
|
||||
sLog.outErrorEventAI("%s", buf);
|
||||
else if (entry < MIN_DB_SCRIPT_STRING_ID) // mangos string error
|
||||
sLog.outError("%s", buf);
|
||||
else // if (entry > MIN_DB_SCRIPT_STRING_ID) // DB script text error
|
||||
sLog.outErrorDb("DB-SCRIPTS: %s", buf);
|
||||
}
|
||||
|
||||
bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value, bool extra_content)
|
||||
{
|
||||
int32 start_value = min_value;
|
||||
int32 end_value = max_value;
|
||||
|
|
@ -7691,8 +7712,10 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
|
|||
++itr;
|
||||
}
|
||||
|
||||
QueryResult* result = db.PQuery("SELECT entry,content_default,content_loc1,content_loc2,content_loc3,content_loc4,content_loc5,content_loc6,content_loc7,content_loc8 FROM %s", table);
|
||||
sLog.outString("Loading texts from %s%s", table, extra_content ? ", with additional data" : "");
|
||||
|
||||
QueryResult* result = db.PQuery("SELECT entry,content_default,content_loc1,content_loc2,content_loc3,content_loc4,content_loc5,content_loc6,content_loc7,content_loc8 %s FROM %s",
|
||||
extra_content ? ",sound,type,language,emote" : "", table);
|
||||
if (!result)
|
||||
{
|
||||
BarGoLink bar(1);
|
||||
|
|
@ -7720,12 +7743,12 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
|
|||
|
||||
if (entry == 0)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` contain reserved entry 0, ignored.", table);
|
||||
_DoStringError(start_value, "Table `%s` contain reserved entry 0, ignored.", table);
|
||||
continue;
|
||||
}
|
||||
else if (entry < start_value || entry >= end_value)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.", table, entry, min_value, max_value);
|
||||
_DoStringError(start_value, "Table `%s` contain entry %i out of allowed range (%d - %d), ignored.", table, entry, min_value, max_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -7733,7 +7756,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
|
|||
|
||||
if (!data.Content.empty())
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` contain data for already loaded entry %i (from another table?), ignored.", table, entry);
|
||||
_DoStringError(entry, "Table `%s` contain data for already loaded entry %i (from another table?), ignored.", table, entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -7759,6 +7782,39 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load additional string content if necessary
|
||||
if (extra_content)
|
||||
{
|
||||
data.SoundId = fields[10].GetUInt32();
|
||||
data.Type = fields[11].GetUInt32();
|
||||
data.Language = fields[12].GetUInt32();
|
||||
data.Emote = fields[13].GetUInt32();
|
||||
|
||||
if (data.SoundId && !sSoundEntriesStore.LookupEntry(data.SoundId))
|
||||
{
|
||||
_DoStringError(entry, "Entry %i in table `%s` has soundId %u but sound does not exist.", entry, table, data.SoundId);
|
||||
data.SoundId = 0;
|
||||
}
|
||||
|
||||
if (!GetLanguageDescByID(data.Language))
|
||||
{
|
||||
_DoStringError(entry, "Entry %i in table `%s` using Language %u but Language does not exist.", entry, table, data.Language);
|
||||
data.Language = LANG_UNIVERSAL;
|
||||
}
|
||||
|
||||
if (data.Type > CHAT_TYPE_ZONE_YELL)
|
||||
{
|
||||
_DoStringError(entry, "Entry %i in table `%s` has Type %u but this Chat Type does not exist.", entry, table, data.Type);
|
||||
data.Type = CHAT_TYPE_SAY;
|
||||
}
|
||||
|
||||
if (data.Emote && !sEmotesStore.LookupEntry(data.Emote))
|
||||
{
|
||||
_DoStringError(entry, "Entry %i in table `%s` has Emote %u but emote does not exist.", entry, table, data.Emote);
|
||||
data.Emote = EMOTE_ONESHOT_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
|
|
@ -7768,7 +7824,10 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
|
|||
if (min_value == MIN_MANGOS_STRING_ID)
|
||||
sLog.outString(">> Loaded %u MaNGOS strings from table %s", count, table);
|
||||
else
|
||||
sLog.outString(">> Loaded %u string templates from %s", count, table);
|
||||
sLog.outString(">> Loaded %u %s templates from %s", count, extra_content ? "text" : "string", table);
|
||||
sLog.outString();
|
||||
|
||||
m_loadedStringCount[min_value] = count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -7785,14 +7844,7 @@ const char* ObjectMgr::GetMangosString(int32 entry, int locale_idx) const
|
|||
return msl->Content[0].c_str();
|
||||
}
|
||||
|
||||
if (entry > MIN_DB_SCRIPT_STRING_ID)
|
||||
sLog.outErrorDb("Entry %i not found in `db_script_string` table.", entry);
|
||||
else if (entry > 0)
|
||||
sLog.outErrorDb("Entry %i not found in `mangos_string` table.", entry);
|
||||
else if (entry > MAX_CREATURE_AI_TEXT_STRING_ID)
|
||||
sLog.outErrorEventAI("Entry %i not found in `creature_ai_texts` table.", entry);
|
||||
else
|
||||
sLog.outErrorScriptLib("String entry %i not found in Database.", entry);
|
||||
_DoStringError(entry, "Entry %i not found but requested", entry);
|
||||
return "<error>";
|
||||
}
|
||||
|
||||
|
|
@ -9816,7 +9868,7 @@ void ObjectMgr::GetNpcTextLocaleStrings0(uint32 entry, int32 loc_idx, std::strin
|
|||
}
|
||||
|
||||
// Functions for scripting access
|
||||
bool LoadMangosStrings(DatabaseType& db, char const* table, int32 start_value, int32 end_value)
|
||||
bool LoadMangosStrings(DatabaseType& db, char const* table, int32 start_value, int32 end_value, bool extra_content)
|
||||
{
|
||||
// MAX_DB_SCRIPT_STRING_ID is max allowed negative value for scripts (scrpts can use only more deep negative values
|
||||
// start/end reversed for negative values
|
||||
|
|
@ -9826,7 +9878,7 @@ bool LoadMangosStrings(DatabaseType& db, char const* table, int32 start_value, i
|
|||
return false;
|
||||
}
|
||||
|
||||
return sObjectMgr.LoadMangosStrings(db, table, start_value, end_value);
|
||||
return sObjectMgr.LoadMangosStrings(db, table, start_value, end_value, extra_content);
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureTemplateSpells()
|
||||
|
|
@ -9854,6 +9906,11 @@ void ObjectMgr::LoadCreatureTemplateSpells()
|
|||
}
|
||||
}
|
||||
|
||||
MangosStringLocale const* GetMangosStringData(int32 entry)
|
||||
{
|
||||
return sObjectMgr.GetMangosStringLocale(entry);
|
||||
}
|
||||
|
||||
CreatureInfo const* GetCreatureTemplateStore(uint32 entry)
|
||||
{
|
||||
return sCreatureStorage.LookupEntry<CreatureInfo>(entry);
|
||||
|
|
@ -9903,6 +9960,87 @@ bool FindCreatureData::operator()(CreatureDataPair const& dataPair)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DoDisplayText(WorldObject* source, int32 entry, Unit const* target /*=NULL*/)
|
||||
{
|
||||
MangosStringLocale const* data = sObjectMgr.GetMangosStringLocale(entry);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
_DoStringError(entry, "DoScriptText with source %s could not find text entry %i.", source->GetGuidStr().c_str(), entry);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data->SoundId)
|
||||
{
|
||||
if (data->Type == CHAT_TYPE_ZONE_YELL)
|
||||
source->GetMap()->PlayDirectSoundToMap(data->SoundId, source->GetZoneId());
|
||||
else if (data->Type == CHAT_TYPE_WHISPER || data->Type == CHAT_TYPE_BOSS_WHISPER)
|
||||
{
|
||||
// An error will be displayed for the text
|
||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||
source->PlayDirectSound(data->SoundId, (Player const*)target);
|
||||
}
|
||||
else
|
||||
source->PlayDirectSound(data->SoundId);
|
||||
}
|
||||
|
||||
if (data->Emote)
|
||||
{
|
||||
if (source->GetTypeId() == TYPEID_UNIT || source->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Unit*)source)->HandleEmote(data->Emote);
|
||||
}
|
||||
else
|
||||
{
|
||||
_DoStringError(entry, "DoDisplayText entry %i tried to process emote for invalid source %s", entry, source->GetGuidStr().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (data->Type)
|
||||
{
|
||||
case CHAT_TYPE_SAY:
|
||||
source->MonsterSay(entry, data->Language, target);
|
||||
break;
|
||||
case CHAT_TYPE_YELL:
|
||||
source->MonsterYell(entry, data->Language, target);
|
||||
break;
|
||||
case CHAT_TYPE_TEXT_EMOTE:
|
||||
source->MonsterTextEmote(entry, target);
|
||||
break;
|
||||
case CHAT_TYPE_BOSS_EMOTE:
|
||||
source->MonsterTextEmote(entry, target, true);
|
||||
break;
|
||||
case CHAT_TYPE_WHISPER:
|
||||
{
|
||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||
source->MonsterWhisper(entry, target);
|
||||
else
|
||||
{
|
||||
_DoStringError(entry, "DoDisplayText entry %i cannot whisper without target unit (TYPEID_PLAYER).", entry);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHAT_TYPE_BOSS_WHISPER:
|
||||
{
|
||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||
source->MonsterWhisper(entry, target, true);
|
||||
else
|
||||
{
|
||||
_DoStringError(entry, "DoDisplayText entry %i cannot whisper without target unit (TYPEID_PLAYER).", entry);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHAT_TYPE_ZONE_YELL:
|
||||
source->MonsterYellToZone(entry, data->Language, target);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureDataPair const* FindCreatureData::GetResult() const
|
||||
{
|
||||
if (i_spawnedData)
|
||||
|
|
|
|||
|
|
@ -128,7 +128,13 @@ static_assert(MAX_DB_SCRIPT_STRING_ID < ACE_INT32_MAX, "Must scope with int32 ra
|
|||
|
||||
struct MangosStringLocale
|
||||
{
|
||||
MangosStringLocale() : SoundId(0), Type(0), Language(0), Emote(0) { }
|
||||
|
||||
std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index
|
||||
uint32 SoundId;
|
||||
uint8 Type;
|
||||
uint32 Language;
|
||||
uint32 Emote; // 0 -> default, i -> i-1 locale index
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32, CreatureData> CreatureDataMap;
|
||||
|
|
@ -705,8 +711,8 @@ class ObjectMgr
|
|||
void LoadCreatureQuestRelations();
|
||||
void LoadCreatureInvolvedRelations();
|
||||
|
||||
bool LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value);
|
||||
bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase, "mangos_string", MIN_MANGOS_STRING_ID, MAX_MANGOS_STRING_ID); }
|
||||
bool LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value, bool extra_content);
|
||||
bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase, "mangos_string", MIN_MANGOS_STRING_ID, MAX_MANGOS_STRING_ID, false); }
|
||||
void LoadCreatureLocales();
|
||||
void LoadCreatureTemplates();
|
||||
void LoadCreatures();
|
||||
|
|
@ -956,6 +962,14 @@ class ObjectMgr
|
|||
return &itr->second;
|
||||
}
|
||||
|
||||
uint32 GetLoadedStringsCount(int32 minEntry) const
|
||||
{
|
||||
std::map<int32, uint32>::const_iterator itr = m_loadedStringCount.find(minEntry);
|
||||
if (itr != m_loadedStringCount.end())
|
||||
return itr->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* GetMangosString(int32 entry, int locale_idx) const;
|
||||
const char* GetMangosStringForDBCLocale(int32 entry) const { return GetMangosString(entry, DBCLocaleIndex); }
|
||||
int32 GetDBCLocaleIndex() const { return DBCLocaleIndex; }
|
||||
|
|
@ -1264,6 +1278,7 @@ class ObjectMgr
|
|||
NpcTextLocaleMap mNpcTextLocaleMap;
|
||||
PageTextLocaleMap mPageTextLocaleMap;
|
||||
MangosStringLocaleMap mMangosStringLocaleMap;
|
||||
std::map<int32 /*minEntryOfBracket*/, uint32 /*count*/> m_loadedStringCount;
|
||||
GossipMenuItemsLocaleMap mGossipMenuItemsLocaleMap;
|
||||
PointOfInterestLocaleMap mPointOfInterestLocaleMap;
|
||||
DungeonEncounterMap m_DungeonEncounters;
|
||||
|
|
@ -1281,9 +1296,13 @@ class ObjectMgr
|
|||
|
||||
#define sObjectMgr MaNGOS::Singleton<ObjectMgr>::Instance()
|
||||
|
||||
/// generic text function
|
||||
MANGOS_DLL_SPEC bool DoDisplayText(WorldObject* source, int32 entry, Unit const* target = NULL);
|
||||
|
||||
// scripting access functions
|
||||
MANGOS_DLL_SPEC bool LoadMangosStrings(DatabaseType& db, char const* table, int32 start_value = MAX_CREATURE_AI_TEXT_STRING_ID, int32 end_value = std::numeric_limits<int32>::min());
|
||||
MANGOS_DLL_SPEC bool LoadMangosStrings(DatabaseType& db, char const* table, int32 start_value = MAX_CREATURE_AI_TEXT_STRING_ID, int32 end_value = std::numeric_limits<int32>::min(), bool extra_content = false);
|
||||
MANGOS_DLL_SPEC CreatureInfo const* GetCreatureTemplateStore(uint32 entry);
|
||||
MANGOS_DLL_SPEC Quest const* GetQuestTemplateStore(uint32 entry);
|
||||
MANGOS_DLL_SPEC MangosStringLocale const* GetMangosStringData(int32 entry);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,20 +19,25 @@
|
|||
#include "ObjectPosSelector.h"
|
||||
#include "Object.h"
|
||||
|
||||
ObjectPosSelector::ObjectPosSelector(float x, float y, float dist, float searcher_size) :
|
||||
m_centerX(x), m_centerY(y), m_searcherDist(dist), m_searcherSize(searcher_size)
|
||||
// The bigger this value, the more space npcs require around their target
|
||||
#define OCCUPY_POS_ANGLE_ATAN_FACTOR 1.8f
|
||||
|
||||
ObjectPosSelector::ObjectPosSelector(float x, float y, float dist, float searchedForSize, WorldObject const* searchPosFor) :
|
||||
m_centerX(x), m_centerY(y), m_searcherDist(dist), m_searchPosFor(searchPosFor)
|
||||
{
|
||||
// if size == 0, m_anglestep will become 0 -> freeze
|
||||
if (m_searcherSize == 0.0f)
|
||||
m_searcherSize = DEFAULT_WORLD_OBJECT_SIZE;
|
||||
if (searchedForSize == 0.0f)
|
||||
searchedForSize = DEFAULT_WORLD_OBJECT_SIZE;
|
||||
|
||||
m_searcherHalfSize = asin(m_searcherSize / m_searcherDist);
|
||||
// undefined behaviour
|
||||
if (m_searcherDist == 0.0f)
|
||||
m_searcherDist = DEFAULT_WORLD_OBJECT_SIZE;
|
||||
|
||||
m_searchedForReqHAngle = atan(OCCUPY_POS_ANGLE_ATAN_FACTOR * searchedForSize / m_searcherDist);
|
||||
|
||||
// Really init in InitilizeAngle
|
||||
m_nextUsedAreaItr[USED_POS_PLUS] = m_UsedAreaLists[USED_POS_PLUS].begin();
|
||||
m_nextUsedAreaItr[USED_POS_MINUS] = m_UsedAreaLists[USED_POS_MINUS].begin();
|
||||
m_nextUsedAreaStart[USED_POS_PLUS] = 0.0f;
|
||||
m_nextUsedAreaStart[USED_POS_MINUS] = 0.0f;
|
||||
m_stepAngle[USED_POS_PLUS] = 0.0f;
|
||||
m_stepAngle[USED_POS_MINUS] = 0.0f;
|
||||
}
|
||||
|
|
@ -41,27 +46,27 @@ ObjectPosSelector::ObjectPosSelector(float x, float y, float dist, float searche
|
|||
* Add used area (circle) near target object excluded from possible searcher position
|
||||
*
|
||||
*
|
||||
* @param size Size of used circle
|
||||
* @param obj Object that occupies area
|
||||
* @param angle Angle of used circle center point from target-searcher line
|
||||
* @param dist Distance from target object center point to used circle center point
|
||||
*
|
||||
* Used circles data stored as projections to searcher dist size circle as angle coordinate and half angle size
|
||||
*/
|
||||
void ObjectPosSelector::AddUsedArea(float size, float angle, float dist)
|
||||
void ObjectPosSelector::AddUsedArea(WorldObject const* obj, float angle, float dist)
|
||||
{
|
||||
float sr_dist = size + m_searcherSize;
|
||||
|
||||
// by Law of cosines, angle of searcher/used centers
|
||||
float sr_angle = acos((m_searcherDist * m_searcherDist + dist * dist - sr_dist * sr_dist) / (2 * m_searcherDist * dist));
|
||||
MANGOS_ASSERT(obj);
|
||||
|
||||
// skip some unexpected results.
|
||||
if (!finite(sr_angle) || sr_angle <= 0)
|
||||
if (dist == 0.0f)
|
||||
return;
|
||||
|
||||
// (half) angle that obj occupies
|
||||
float sr_angle = atan(OCCUPY_POS_ANGLE_ATAN_FACTOR * obj->GetObjectBoundingRadius() / dist);
|
||||
|
||||
if (angle >= 0)
|
||||
m_UsedAreaLists[USED_POS_PLUS].insert(UsedArea(angle, sr_angle));
|
||||
m_UsedAreaLists[USED_POS_PLUS].insert(UsedArea(angle, OccupiedArea(sr_angle, obj)));
|
||||
else
|
||||
m_UsedAreaLists[USED_POS_MINUS].insert(UsedArea(-angle, sr_angle));
|
||||
m_UsedAreaLists[USED_POS_MINUS].insert(UsedArea(-angle, OccupiedArea(sr_angle, obj)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,23 +80,10 @@ void ObjectPosSelector::AddUsedArea(float size, float angle, float dist)
|
|||
*/
|
||||
bool ObjectPosSelector::CheckAngle(UsedArea const& usedArea, UsedAreaSide side, float angle) const
|
||||
{
|
||||
float used_offset = usedArea.second.angleOffset;
|
||||
float used_angle = usedArea.first * SignOf(side);
|
||||
float used_offset = usedArea.second;
|
||||
|
||||
return fabs(used_angle - angle) > used_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check searcher circle not intercepting with used circle at side (only start angle provided)
|
||||
*
|
||||
* @param side Side of used circle
|
||||
* @param angle Checked angle at side, positive always
|
||||
*
|
||||
* @return true, if used circle not intercepted with searcher circle in terms projection angles
|
||||
*/
|
||||
bool ObjectPosSelector::CheckSideAngle(UsedAreaSide side, float angle) const
|
||||
{
|
||||
return angle + m_searcherHalfSize < m_nextUsedAreaStart[side];
|
||||
// check first left/right used angles if exists
|
||||
return fabs(used_angle - angle) > used_offset || (m_searchPosFor && usedArea.second.occupyingObj == m_searchPosFor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,53 +113,17 @@ void ObjectPosSelector::InitializeAngle()
|
|||
void ObjectPosSelector::InitializeAngle(UsedAreaSide side)
|
||||
{
|
||||
m_nextUsedAreaItr[side] = m_UsedAreaLists[side].begin();
|
||||
UpdateNextAreaStart(side);
|
||||
|
||||
// if another side not alow use 0.0f angle calculate possible value in 0..m_searcherHalfSize range
|
||||
// if another side not alow use 0.0f angle calculate possible value in 0..m_searchedForReqHAngle range
|
||||
if (!m_UsedAreaLists[~side].empty())
|
||||
{
|
||||
UsedArea const& otherArea = *m_UsedAreaLists[~side].begin();
|
||||
|
||||
// if other are near start
|
||||
if (otherArea.first < otherArea.second)
|
||||
m_stepAngle[side] = otherArea.second - otherArea.first;
|
||||
else
|
||||
m_stepAngle[side] = std::max(m_searchedForReqHAngle + otherArea.second.angleOffset - otherArea.first, 0.0f);
|
||||
}
|
||||
else // Other side empty. start from 0
|
||||
m_stepAngle[side] = 0.0f;
|
||||
}
|
||||
else
|
||||
m_stepAngle[side] = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update next used area start angle for current m_nextUsedAreaItr value at side
|
||||
*/
|
||||
void ObjectPosSelector::UpdateNextAreaStart(UsedAreaSide side)
|
||||
{
|
||||
// not last next area at side
|
||||
if (m_nextUsedAreaItr[side] != m_UsedAreaLists[side].end())
|
||||
{
|
||||
m_nextUsedAreaStart[side] = m_nextUsedAreaItr[side]->first - m_nextUsedAreaItr[side]->second + m_searcherHalfSize;
|
||||
return;
|
||||
}
|
||||
|
||||
// last area at side and not another side areas
|
||||
if (m_UsedAreaLists[~side].empty())
|
||||
{
|
||||
m_nextUsedAreaStart[side] = M_PI_F + m_searcherHalfSize + 0.01f;
|
||||
return;
|
||||
}
|
||||
|
||||
UsedArea const& lastArea = *m_UsedAreaLists[~side].rbegin();
|
||||
|
||||
// another side have used area near to end (near to PI)
|
||||
if (lastArea.first + lastArea.second > M_PI_F - m_searcherHalfSize)
|
||||
{
|
||||
m_nextUsedAreaStart[side] = M_PI_F + (M_PI_F - lastArea.first - lastArea.second) + m_searcherHalfSize;
|
||||
return;
|
||||
}
|
||||
|
||||
// last area and fail find any used area at another side, prepare fake data as stopper
|
||||
m_nextUsedAreaStart[side] = M_PI_F + m_searcherHalfSize + 0.01f;
|
||||
// As m_stepAngle will be incremented first in ::NextSideAngle
|
||||
m_stepAngle[side] -= m_searchedForReqHAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -215,33 +171,34 @@ bool ObjectPosSelector::NextAngle(float& angle)
|
|||
bool ObjectPosSelector::NextSideAngle(UsedAreaSide side, float& angle)
|
||||
{
|
||||
// next possible angle
|
||||
m_stepAngle[side] += (m_searcherHalfSize + 0.01);
|
||||
m_stepAngle[side] += (m_searchedForReqHAngle + 0.01);
|
||||
|
||||
// prevent jump to another side
|
||||
if (m_stepAngle[side] > M_PI_F)
|
||||
return false;
|
||||
|
||||
// update angle at attempt jump after next used area
|
||||
while (m_stepAngle[side] <= M_PI_F && m_stepAngle[side] + m_searcherHalfSize >= m_nextUsedAreaStart[side])
|
||||
{
|
||||
// no used area for pass
|
||||
// no used area anymore on this side
|
||||
if (m_nextUsedAreaItr[side] == m_UsedAreaLists[side].end())
|
||||
{
|
||||
m_stepAngle[side] = M_PI_F + m_searcherHalfSize;// prevent continue search at side
|
||||
return false;
|
||||
angle = m_stepAngle[side] * SignOf(side);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Already occupied and no better found
|
||||
if ((m_searchPosFor && m_nextUsedAreaItr[side]->second.occupyingObj == m_searchPosFor) ||
|
||||
// Next occupied is too far away
|
||||
(m_stepAngle[side] + m_searchedForReqHAngle < m_nextUsedAreaItr[side]->first - m_nextUsedAreaItr[side]->second.angleOffset))
|
||||
{
|
||||
angle = m_stepAngle[side] * SignOf(side);
|
||||
return true;
|
||||
}
|
||||
|
||||
// angle set at first possible pos after passed m_nextUsedAreaItr
|
||||
m_stepAngle[side] = m_nextUsedAreaItr[side]->first + m_nextUsedAreaItr[side]->second;
|
||||
m_stepAngle[side] = m_nextUsedAreaItr[side]->first + m_nextUsedAreaItr[side]->second.angleOffset;
|
||||
|
||||
++m_nextUsedAreaItr[side];
|
||||
UpdateNextAreaStart(side);
|
||||
}
|
||||
|
||||
angle = m_stepAngle[side] * SignOf(side);
|
||||
|
||||
// if next node not allow use selected angle, mark and fail
|
||||
return CheckSideAngle(side, m_stepAngle[side]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include<map>
|
||||
|
||||
class WorldObject;
|
||||
|
||||
enum UsedAreaSide { USED_POS_PLUS, USED_POS_MINUS };
|
||||
|
||||
inline UsedAreaSide operator ~(UsedAreaSide side)
|
||||
|
|
@ -37,12 +39,19 @@ inline float SignOf(UsedAreaSide side)
|
|||
|
||||
struct ObjectPosSelector
|
||||
{
|
||||
typedef std::multimap<float, float> UsedAreaList; // angle pos -> angle offset
|
||||
struct OccupiedArea
|
||||
{
|
||||
OccupiedArea(float _angleOffset, WorldObject const* obj) : angleOffset(_angleOffset), occupyingObj(obj) {}
|
||||
float angleOffset;
|
||||
WorldObject const* occupyingObj;
|
||||
};
|
||||
// angle pos -> OccupiedArea
|
||||
typedef std::multimap<float, OccupiedArea> UsedAreaList;
|
||||
typedef UsedAreaList::value_type UsedArea;
|
||||
|
||||
ObjectPosSelector(float x, float y, float dist, float searcher_size);
|
||||
ObjectPosSelector(float x, float y, float dist, float searchedForSize, WorldObject const* searchPosFor);
|
||||
|
||||
void AddUsedArea(float size, float angle, float dist);
|
||||
void AddUsedArea(WorldObject const* obj, float angle, float dist);
|
||||
|
||||
bool CheckOriginalAngle() const;
|
||||
|
||||
|
|
@ -52,22 +61,20 @@ struct ObjectPosSelector
|
|||
bool NextUsedAngle(float& angle);
|
||||
|
||||
bool CheckAngle(UsedArea const& usedArea, UsedAreaSide side, float angle) const;
|
||||
bool CheckSideAngle(UsedAreaSide side, float angle) const;
|
||||
void InitializeAngle(UsedAreaSide side);
|
||||
void UpdateNextAreaStart(UsedAreaSide side);
|
||||
bool NextSideAngle(UsedAreaSide side, float& angle);
|
||||
|
||||
float m_centerX;
|
||||
float m_centerY;
|
||||
float m_searcherDist; // distance for searching pos (including searcher size and target object size)
|
||||
float m_searcherSize; // searcher object radius
|
||||
float m_searcherHalfSize; // angle size/2 of searcher object (at dist distance)
|
||||
float m_searcherDist; // distance for searching pos
|
||||
float m_searchedForReqHAngle; // angle size/2 of searcher object (at dist distance)
|
||||
|
||||
UsedAreaList m_UsedAreaLists[2]; // list left/right side used angles (with angle size)
|
||||
|
||||
UsedAreaList::const_iterator m_nextUsedAreaItr[2]; // next used used areas for check at left/right side, possible angles selected in range m_smallStepAngle..m_nextUsedAreaItr
|
||||
float m_nextUsedAreaStart[2]; // cached angle for next used area from m_nextUsedAreaItr or another side
|
||||
|
||||
float m_stepAngle[2]; // current checked angle position at sides (less m_nextUsedArea), positive value
|
||||
|
||||
WorldObject const* m_searchPosFor; // For whom a position is searched (can be NULL)
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -162,6 +162,15 @@ class MANGOS_DLL_SPEC Pet : public Creature
|
|||
return m_autospells[pos];
|
||||
}
|
||||
|
||||
bool CanSwim() const override
|
||||
{
|
||||
Unit const* owner = GetOwner();
|
||||
if (owner)
|
||||
return owner->GetTypeId() == TYPEID_PLAYER ? true : ((Creature const*)owner)->CanSwim();
|
||||
else
|
||||
return Creature::CanSwim();
|
||||
}
|
||||
|
||||
void RegenerateAll(uint32 update_diff) override; // overwrite Creature::RegenerateAll
|
||||
void Regenerate(Powers power);
|
||||
void GivePetXP(uint32 xp);
|
||||
|
|
|
|||
|
|
@ -5005,6 +5005,7 @@ void Player::RepopAtGraveyard()
|
|||
// and don't show spirit healer location
|
||||
if (ClosestGrave)
|
||||
{
|
||||
bool updateVisibility = IsInWorld() && GetMapId() == ClosestGrave->map_id;
|
||||
TeleportTo(ClosestGrave->map_id, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, GetOrientation());
|
||||
if (isDead()) // not send if alive, because it used in TeleportTo()
|
||||
{
|
||||
|
|
@ -5015,6 +5016,8 @@ void Player::RepopAtGraveyard()
|
|||
data << ClosestGrave->z;
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
if (updateVisibility && IsInWorld())
|
||||
UpdateVisibilityAndView();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6191,7 +6194,7 @@ void Player::SaveRecallPosition()
|
|||
m_recallO = GetOrientation();
|
||||
}
|
||||
|
||||
void Player::SendMessageToSet(WorldPacket* data, bool self)
|
||||
void Player::SendMessageToSet(WorldPacket* data, bool self) const
|
||||
{
|
||||
if (IsInWorld())
|
||||
GetMap()->MessageBroadcast(this, data, false);
|
||||
|
|
@ -6202,7 +6205,7 @@ void Player::SendMessageToSet(WorldPacket* data, bool self)
|
|||
GetSession()->SendPacket(data);
|
||||
}
|
||||
|
||||
void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self)
|
||||
void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self) const
|
||||
{
|
||||
if (IsInWorld())
|
||||
GetMap()->MessageDistBroadcast(this, data, dist, false);
|
||||
|
|
@ -6211,7 +6214,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self)
|
|||
GetSession()->SendPacket(data);
|
||||
}
|
||||
|
||||
void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only)
|
||||
void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only) const
|
||||
{
|
||||
if (IsInWorld())
|
||||
GetMap()->MessageDistBroadcast(this, data, dist, false, own_team_only);
|
||||
|
|
@ -6220,7 +6223,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, b
|
|||
GetSession()->SendPacket(data);
|
||||
}
|
||||
|
||||
void Player::SendDirectMessage(WorldPacket* data)
|
||||
void Player::SendDirectMessage(WorldPacket* data) const
|
||||
{
|
||||
GetSession()->SendPacket(data);
|
||||
}
|
||||
|
|
@ -13394,6 +13397,11 @@ Quest const* Player::GetNextQuest(ObjectGuid guid, Quest const* pQuest)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player could see a start quest
|
||||
* Basic Quest-taking requirements: Class, Race, Skill, Quest-Line, ...
|
||||
* Check if the quest-level is not too high (related config value CONFIG_INT32_QUEST_HIGH_LEVEL_HIDE_DIFF)
|
||||
*/
|
||||
bool Player::CanSeeStartQuest(Quest const* pQuest) const
|
||||
{
|
||||
if (SatisfyQuestClass(pQuest, false) && SatisfyQuestRace(pQuest, false) && SatisfyQuestSkill(pQuest, false) &&
|
||||
|
|
@ -13403,7 +13411,10 @@ bool Player::CanSeeStartQuest(Quest const* pQuest) const
|
|||
SatisfyQuestMonth(pQuest, false) &&
|
||||
pQuest->IsActive())
|
||||
{
|
||||
return int32(getLevel()) + sWorld.getConfig(CONFIG_INT32_QUEST_HIGH_LEVEL_HIDE_DIFF) >= int32(pQuest->GetMinLevel());
|
||||
int32 highLevelDiff = sWorld.getConfig(CONFIG_INT32_QUEST_HIGH_LEVEL_HIDE_DIFF);
|
||||
if (highLevelDiff < 0)
|
||||
return true;
|
||||
return getLevel() + uint32(highLevelDiff) >= pQuest->GetMinLevel();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1863,10 +1863,10 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
bool SetPosition(float x, float y, float z, float orientation, bool teleport = false);
|
||||
void UpdateUnderwaterState(Map* m, float x, float y, float z);
|
||||
|
||||
void SendMessageToSet(WorldPacket* data, bool self) override;// overwrite Object::SendMessageToSet
|
||||
void SendMessageToSetInRange(WorldPacket* data, float fist, bool self) override;
|
||||
void SendMessageToSet(WorldPacket* data, bool self) const override;// overwrite Object::SendMessageToSet
|
||||
void SendMessageToSetInRange(WorldPacket* data, float fist, bool self) const override;
|
||||
// overwrite Object::SendMessageToSetInRange
|
||||
void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only);
|
||||
void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only) const;
|
||||
|
||||
Corpse* GetCorpse() const;
|
||||
void SpawnCorpseBones();
|
||||
|
|
@ -2037,7 +2037,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
void SendInitWorldStates(uint32 zone, uint32 area);
|
||||
void SendUpdateWorldState(uint32 Field, uint32 Value);
|
||||
void SendDirectMessage(WorldPacket* data);
|
||||
void SendDirectMessage(WorldPacket* data) const;
|
||||
void FillBGWeekendWorldStates(WorldPacket& data, uint32& count);
|
||||
|
||||
void SendAurasForTarget(Unit* target);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,8 @@ enum __QuestGiverStatus
|
|||
DIALOG_STATUS_AVAILABLE_REP = 0x080,
|
||||
DIALOG_STATUS_AVAILABLE = 0x100,
|
||||
DIALOG_STATUS_REWARD2 = 0x200, // no yellow dot on minimap
|
||||
DIALOG_STATUS_REWARD = 0x400 // yellow dot on minimap
|
||||
DIALOG_STATUS_REWARD = 0x400, // yellow dot on minimap
|
||||
DIALOG_STATUS_UNDEFINED = 0xFFFF, // Used as result for unassigned ScriptCall
|
||||
};
|
||||
|
||||
// values based at QuestInfo.dbc
|
||||
|
|
|
|||
|
|
@ -501,12 +501,20 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* What - if any - kind of explanation mark or question-mark should a quest-giver display for a player
|
||||
* @param pPlayer - for whom
|
||||
* @param questgiver - from whom
|
||||
* @param defstatus - initial set status (usually it will be called with DIALOG_STATUS_NONE) - must not be DIALOG_STATUS_UNDEFINED
|
||||
*/
|
||||
uint32 WorldSession::getDialogStatus(Player* pPlayer, Object* questgiver, uint32 defstatus)
|
||||
{
|
||||
MANGOS_ASSERT(defstatus != DIALOG_STATUS_UNDEFINED);
|
||||
|
||||
uint32 dialogStatus = defstatus;
|
||||
|
||||
QuestRelationsMapBounds rbounds;
|
||||
QuestRelationsMapBounds irbounds;
|
||||
QuestRelationsMapBounds rbounds; // QuestRelations (quest-giver)
|
||||
QuestRelationsMapBounds irbounds; // InvolvedRelations (quest-finisher)
|
||||
|
||||
switch (questgiver->GetTypeId())
|
||||
{
|
||||
|
|
@ -528,9 +536,10 @@ uint32 WorldSession::getDialogStatus(Player* pPlayer, Object* questgiver, uint32
|
|||
return DIALOG_STATUS_NONE;
|
||||
}
|
||||
|
||||
// Check markings for quest-finisher
|
||||
for (QuestRelationsMap::const_iterator itr = irbounds.first; itr != irbounds.second; ++itr)
|
||||
{
|
||||
uint32 dialogStatusNew = 0;
|
||||
uint32 dialogStatusNew = DIALOG_STATUS_NONE;
|
||||
uint32 quest_id = itr->second;
|
||||
Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id);
|
||||
|
||||
|
|
@ -554,9 +563,10 @@ uint32 WorldSession::getDialogStatus(Player* pPlayer, Object* questgiver, uint32
|
|||
dialogStatus = dialogStatusNew;
|
||||
}
|
||||
|
||||
// check markings for quest-giver
|
||||
for (QuestRelationsMap::const_iterator itr = rbounds.first; itr != rbounds.second; ++itr)
|
||||
{
|
||||
uint32 dialogStatusNew = 0;
|
||||
uint32 dialogStatusNew = DIALOG_STATUS_NONE;
|
||||
uint32 quest_id = itr->second;
|
||||
Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id);
|
||||
|
||||
|
|
@ -565,24 +575,25 @@ uint32 WorldSession::getDialogStatus(Player* pPlayer, Object* questgiver, uint32
|
|||
|
||||
QuestStatus status = pPlayer->GetQuestStatus(quest_id);
|
||||
|
||||
if (status == QUEST_STATUS_NONE)
|
||||
if (status == QUEST_STATUS_NONE) // For all other cases the mark is handled either at some place else, or with involved-relations already
|
||||
{
|
||||
if (pPlayer->CanSeeStartQuest(pQuest))
|
||||
{
|
||||
if (pPlayer->SatisfyQuestLevel(pQuest, false))
|
||||
{
|
||||
int32 lowLevelDiff = sWorld.getConfig(CONFIG_INT32_QUEST_LOW_LEVEL_HIDE_DIFF);
|
||||
if (pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
|
||||
{
|
||||
dialogStatusNew = DIALOG_STATUS_REWARD_REP;
|
||||
}
|
||||
else if (int32(pPlayer->getLevel()) <= int32(pPlayer->GetQuestLevelForPlayer(pQuest)) + sWorld.getConfig(CONFIG_INT32_QUEST_LOW_LEVEL_HIDE_DIFF))
|
||||
else if (lowLevelDiff < 0 || pPlayer->getLevel() <= pPlayer->GetQuestLevelForPlayer(pQuest) + uint32(lowLevelDiff))
|
||||
{
|
||||
if (pQuest->HasQuestFlag(QUEST_FLAGS_DAILY) || pQuest->HasQuestFlag(QUEST_FLAGS_WEEKLY))
|
||||
dialogStatusNew = DIALOG_STATUS_AVAILABLE_REP;
|
||||
else
|
||||
dialogStatusNew = DIALOG_STATUS_AVAILABLE;
|
||||
}
|
||||
else
|
||||
else // player level much higher then quest-level
|
||||
dialogStatusNew = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ const char WorldTemplatesrcfmt[] = "is";
|
|||
const char WorldTemplatedstfmt[] = "ii";
|
||||
const char ConditionsSrcFmt[] = "iiii";
|
||||
const char ConditionsDstFmt[] = "iiii";
|
||||
const char SpellTemplatesrcfmt[] = "iiiiiiiiiiiiiiix";
|
||||
const char SpellTemplatesrcfmt[] = "iiiiiiiiiiiiiiiix";
|
||||
// 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 185
|
||||
const char SpellTemplatedstfmt[] = "ixxxiiixxxxxxxxxxxxxxxxxxxxxxxxxiixxxxixxxxxxFxxxxxxxxxxxxxxxxxxxxxxixxxxxFFFxxxxxxixxixxixxixxxxxFFFxxxxxxixxixxixxFFFxxxxxxxxxxxxxppppppppppppppppppppppppppppppppxxxxxxxxxxxFFFxxxxxx";
|
||||
const char SpellTemplatedstfmt[] = "ixxxiiiixxxxxxxxxxxxxxxxxxxxxxxxiixxxxixxxxxxFxxxxxxxxxxxxxxxxxxxxxxixxxxxFFFxxxxxxixxixxixxixxxxxFFFxxxxxxixxixxixxFFFxxxxxxxxxxxxxppppppppppppppppppppppppppppppppxxxxxxxxxxxFFFxxxxxx";
|
||||
// Id attr proc DurationIndex Effect0 tarA0 effectAura0 triggerSpell0 SpellName[16] Rank[16]
|
||||
const char VehicleAccessorySrcFmt[] = "iiix";
|
||||
const char VehicleAccessoryDstFmt[] = "iii";
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
tmp.raw.data[0] = fields[3].GetUInt32();
|
||||
tmp.raw.data[1] = fields[4].GetUInt32();
|
||||
tmp.buddyEntry = fields[5].GetUInt32();
|
||||
tmp.searchRadius = fields[6].GetUInt32();
|
||||
tmp.searchRadiusOrGuid = fields[6].GetUInt32();
|
||||
tmp.data_flags = fields[7].GetUInt8();
|
||||
tmp.textId[0] = fields[8].GetInt32();
|
||||
tmp.textId[1] = fields[9].GetInt32();
|
||||
|
|
@ -184,7 +184,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
tmp.o = fields[15].GetFloat();
|
||||
|
||||
// generic command args check
|
||||
if (tmp.buddyEntry) // Check Buddy args
|
||||
if (tmp.buddyEntry && !(tmp.data_flags & SCRIPT_FLAG_BUDDY_BY_GUID))
|
||||
{
|
||||
if (tmp.IsCreatureBuddy() && !ObjectMgr::GetCreatureTemplate(tmp.buddyEntry))
|
||||
{
|
||||
|
|
@ -196,7 +196,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
sLog.outErrorDb("Table `%s` has buddyEntry = %u in command %u for script id %u, but this gameobject_template does not exist, skipping.", tablename, tmp.buddyEntry, tmp.command, tmp.id);
|
||||
continue;
|
||||
}
|
||||
if (!tmp.searchRadius)
|
||||
if (!tmp.searchRadiusOrGuid)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has searchRadius = 0 in command %u for script id %u for buddy %u, skipping.", tablename, tmp.command, tmp.id, tmp.buddyEntry);
|
||||
continue;
|
||||
|
|
@ -205,7 +205,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
|
||||
if (tmp.data_flags) // Check flags
|
||||
{
|
||||
if (tmp.data_flags & ~(SCRIPT_FLAG_COMMAND_ADDITIONAL * 2 - 1))
|
||||
if (tmp.data_flags & ~MAX_SCRIPT_FLAG_VALID)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has invalid data_flags %u in command %u for script id %u, skipping.", tablename, tmp.data_flags, tmp.command, tmp.id);
|
||||
continue;
|
||||
|
|
@ -220,24 +220,43 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
sLog.outErrorDb("Table `%s` has buddy required in data_flags %u in command %u for script id %u, but no buddy defined, skipping.", tablename, tmp.data_flags, tmp.command, tmp.id);
|
||||
continue;
|
||||
}
|
||||
if (tmp.data_flags & SCRIPT_FLAG_BUDDY_BY_GUID) // Check guid
|
||||
{
|
||||
if (tmp.IsCreatureBuddy())
|
||||
{
|
||||
CreatureData const* data = sObjectMgr.GetCreatureData(tmp.searchRadiusOrGuid);
|
||||
if (!data)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but no npc spawned with guid %u, skipping.", tablename, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid);
|
||||
continue;
|
||||
}
|
||||
if (data->id != tmp.buddyEntry)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but spawned npc with guid %u has entry %u, expected buddy_entry is %u, skipping.", tablename, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid, data->id, tmp.buddyEntry);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObjectData const* data = sObjectMgr.GetGOData(tmp.searchRadiusOrGuid);
|
||||
if (!data)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has go-buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but no go spawned with guid %u, skipping.", tablename, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid);
|
||||
continue;
|
||||
}
|
||||
if (data->id != tmp.buddyEntry)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has go-buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but spawned go with guid %u has entry %u, expected buddy_entry is %u, skipping.", tablename, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid, data->id, tmp.buddyEntry);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (tmp.command)
|
||||
{
|
||||
case SCRIPT_COMMAND_TALK: // 0
|
||||
{
|
||||
if (tmp.talk.chatType > CHAT_TYPE_ZONE_YELL)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has invalid CHAT_TYPE_ (datalong = %u) in SCRIPT_COMMAND_TALK for script id %u", tablename, tmp.talk.chatType, tmp.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GetLanguageDescByID(tmp.talk.language))
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_TALK for script id %u, but this language does not exist.", tablename, tmp.talk.language, tmp.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tmp.textId[0] == 0)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has invalid talk text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u", tablename, tmp.textId[0], tmp.id);
|
||||
|
|
@ -806,7 +825,7 @@ void ScriptMgr::LoadCreatureDeathScripts()
|
|||
|
||||
void ScriptMgr::LoadDbScriptStrings()
|
||||
{
|
||||
sObjectMgr.LoadMangosStrings(WorldDatabase, "db_script_string", MIN_DB_SCRIPT_STRING_ID, MAX_DB_SCRIPT_STRING_ID);
|
||||
sObjectMgr.LoadMangosStrings(WorldDatabase, "db_script_string", MIN_DB_SCRIPT_STRING_ID, MAX_DB_SCRIPT_STRING_ID, true);
|
||||
|
||||
std::set<int32> ids;
|
||||
|
||||
|
|
@ -894,7 +913,7 @@ bool ScriptAction::GetScriptCommandObject(const ObjectGuid guid, bool includeIte
|
|||
// else no break, but display error message
|
||||
}
|
||||
default:
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u with unsupported guid %s, skipping", m_table, m_script->id, m_script->command, guid.GetString().c_str());
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u with unsupported guid %s, skipping", m_table, m_script->id, m_script->command, guid.GetString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -911,10 +930,37 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* pOrigSource, WorldObject
|
|||
WorldObject* pBuddy = NULL;
|
||||
|
||||
if (m_script->buddyEntry)
|
||||
{
|
||||
if (m_script->data_flags & SCRIPT_FLAG_BUDDY_BY_GUID)
|
||||
{
|
||||
if (m_script->IsCreatureBuddy())
|
||||
{
|
||||
CreatureInfo const* cinfo = ObjectMgr::GetCreatureTemplate(m_script->buddyEntry);
|
||||
pBuddy = m_map->GetCreature(cinfo->GetObjectGuid(m_script->searchRadiusOrGuid));
|
||||
|
||||
if (pBuddy && !((Creature*)pBuddy)->isAlive())
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u by guid %u but buddy is dead, skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry, m_script->searchRadiusOrGuid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// GameObjectInfo const* ginfo = ObjectMgr::GetGameObjectInfo(m_script->buddyEntry);
|
||||
pBuddy = m_map->GetGameObject(ObjectGuid(HIGHGUID_GAMEOBJECT, m_script->buddyEntry, m_script->searchRadiusOrGuid));
|
||||
}
|
||||
// TODO Maybe load related grid if not already done? How to handle multi-map case?
|
||||
if (!pBuddy)
|
||||
{
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u by guid %u not loaded in map %u (data-flags %u), skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry, m_script->searchRadiusOrGuid, m_map->GetId(), m_script->data_flags);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // Buddy by entry
|
||||
{
|
||||
if (!pOrigSource && !pOrigTarget)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u called without buddy %u, but no source for search available, skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u called without buddy %u, but no source for search available, skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -923,33 +969,46 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* pOrigSource, WorldObject
|
|||
if (pSearcher->GetTypeId() == TYPEID_PLAYER && pOrigTarget && pOrigTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
pSearcher = pOrigTarget;
|
||||
|
||||
|
||||
if (m_script->IsCreatureBuddy())
|
||||
{
|
||||
Creature* pCreatureBuddy = NULL;
|
||||
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSearcher, m_script->buddyEntry, true, false, m_script->searchRadius);
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSearcher, m_script->buddyEntry, true, false, m_script->searchRadiusOrGuid, true);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreatureBuddy, u_check);
|
||||
|
||||
Cell::VisitGridObjects(pSearcher, searcher, m_script->searchRadius);
|
||||
if (m_script->data_flags & SCRIPT_FLAG_BUDDY_IS_PET)
|
||||
Cell::VisitWorldObjects(pSearcher, searcher, m_script->searchRadiusOrGuid);
|
||||
else // Normal Creature
|
||||
Cell::VisitGridObjects(pSearcher, searcher, m_script->searchRadiusOrGuid);
|
||||
|
||||
pBuddy = pCreatureBuddy;
|
||||
|
||||
// TODO: Remove this extra check output after a while - it might have false effects
|
||||
if (!pBuddy && pSearcher->GetEntry() == m_script->buddyEntry)
|
||||
{
|
||||
sLog.outErrorDb(" DB-SCRIPTS: WARNING: Process table `%s` id %u, command %u has no OTHER buddy %u found - maybe you need to update the script?", m_table, m_script->id, m_script->command, m_script->buddyEntry);
|
||||
pBuddy = pSearcher;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject* pGOBuddy = NULL;
|
||||
|
||||
MaNGOS::NearestGameObjectEntryInObjectRangeCheck u_check(*pSearcher, m_script->buddyEntry, m_script->searchRadius);
|
||||
MaNGOS::NearestGameObjectEntryInObjectRangeCheck u_check(*pSearcher, m_script->buddyEntry, m_script->searchRadiusOrGuid);
|
||||
MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> searcher(pGOBuddy, u_check);
|
||||
|
||||
Cell::VisitGridObjects(pSearcher, searcher, m_script->searchRadius);
|
||||
Cell::VisitGridObjects(pSearcher, searcher, m_script->searchRadiusOrGuid);
|
||||
pBuddy = pGOBuddy;
|
||||
}
|
||||
|
||||
if (!pBuddy)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u not found in range %u of searcher %s (data-flags %u), skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry, m_script->searchRadius, pSearcher->GetGuidStr().c_str(), m_script->data_flags);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u has buddy %u not found in range %u of searcher %s (data-flags %u), skipping.", m_table, m_script->id, m_script->command, m_script->buddyEntry, m_script->searchRadiusOrGuid, pSearcher->GetGuidStr().c_str(), m_script->data_flags);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_script->data_flags & SCRIPT_FLAG_BUDDY_AS_TARGET)
|
||||
{
|
||||
|
|
@ -976,7 +1035,7 @@ bool ScriptAction::LogIfNotCreature(WorldObject* pWorldObject)
|
|||
{
|
||||
if (!pWorldObject || pWorldObject->GetTypeId() != TYPEID_UNIT)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non-creature, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non-creature, skipping.", m_table, m_script->id, m_script->command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -985,7 +1044,7 @@ bool ScriptAction::LogIfNotUnit(WorldObject* pWorldObject)
|
|||
{
|
||||
if (!pWorldObject || !pWorldObject->isType(TYPEMASK_UNIT))
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non-unit, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non-unit, skipping.", m_table, m_script->id, m_script->command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -994,7 +1053,7 @@ bool ScriptAction::LogIfNotGameObject(WorldObject* pWorldObject)
|
|||
{
|
||||
if (!pWorldObject || pWorldObject->GetTypeId() != TYPEID_GAMEOBJECT)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non-gameobject, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non-gameobject, skipping.", m_table, m_script->id, m_script->command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -1005,7 +1064,7 @@ Player* ScriptAction::GetPlayerTargetOrSourceAndLog(WorldObject* pSource, WorldO
|
|||
{
|
||||
if ((!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER) && (!pSource || pSource->GetTypeId() != TYPEID_PLAYER))
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non player, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u call for non player, skipping.", m_table, m_script->id, m_script->command);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1046,7 +1105,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
{
|
||||
if (!pSource)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u found no worldobject as source, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u found no worldobject as source, skipping.", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1067,42 +1126,9 @@ bool ScriptAction::HandleScriptStep()
|
|||
textId = m_script->textId[urand(0, i - 1)];
|
||||
}
|
||||
|
||||
switch (m_script->talk.chatType)
|
||||
{
|
||||
case CHAT_TYPE_SAY:
|
||||
pSource->MonsterSay(textId, m_script->talk.language, unitTarget);
|
||||
break;
|
||||
case CHAT_TYPE_YELL:
|
||||
pSource->MonsterYell(textId, m_script->talk.language, unitTarget);
|
||||
break;
|
||||
case CHAT_TYPE_TEXT_EMOTE:
|
||||
pSource->MonsterTextEmote(textId, unitTarget);
|
||||
break;
|
||||
case CHAT_TYPE_BOSS_EMOTE:
|
||||
pSource->MonsterTextEmote(textId, unitTarget, true);
|
||||
break;
|
||||
case CHAT_TYPE_WHISPER:
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u attempt to whisper (%u) to %s, skipping.", m_table, m_script->id, m_script->command, m_script->talk.chatType, unitTarget ? unitTarget->GetGuidStr().c_str() : "<no target>");
|
||||
break;
|
||||
}
|
||||
pSource->MonsterWhisper(textId, unitTarget);
|
||||
break;
|
||||
case CHAT_TYPE_BOSS_WHISPER:
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u attempt to whisper (%u) to %s, skipping.", m_table, m_script->id, m_script->command, m_script->talk.chatType, unitTarget ? unitTarget->GetGuidStr().c_str() : "<no target>");
|
||||
break;
|
||||
}
|
||||
pSource->MonsterWhisper(textId, unitTarget, true);
|
||||
break;
|
||||
case CHAT_TYPE_ZONE_YELL:
|
||||
pSource->MonsterYellToZone(textId, m_script->talk.language, unitTarget);
|
||||
break;
|
||||
default:
|
||||
break; // must be already checked at load
|
||||
}
|
||||
if (!DoDisplayText(pSource, textId, unitTarget))
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, could not display text %i properly", m_table, m_script->id, textId);
|
||||
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_EMOTE: // 1
|
||||
|
|
@ -1116,12 +1142,12 @@ bool ScriptAction::HandleScriptStep()
|
|||
case SCRIPT_COMMAND_FIELD_SET: // 2
|
||||
if (!pSourceOrItem)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u call for NULL object.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u call for NULL object.", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
if (m_script->setField.fieldId <= OBJECT_FIELD_ENTRY || m_script->setField.fieldId >= pSourceOrItem->GetValuesCount())
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u call for wrong field %u (max count: %u) in %s.",
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u call for wrong field %u (max count: %u) in %s.",
|
||||
m_table, m_script->id, m_script->command, m_script->setField.fieldId, pSourceOrItem->GetValuesCount(), pSourceOrItem->GetGuidStr().c_str());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1161,12 +1187,12 @@ bool ScriptAction::HandleScriptStep()
|
|||
case SCRIPT_COMMAND_FLAG_SET: // 4
|
||||
if (!pSourceOrItem)
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_FLAG_SET (script id %u) call for NULL object.", m_script->id);
|
||||
sLog.outErrorDb("SCRIPT_COMMAND_FLAG_SET (script id %u) call for NULL object.", m_script->id);
|
||||
break;
|
||||
}
|
||||
if (m_script->setFlag.fieldId <= OBJECT_FIELD_ENTRY || m_script->setFlag.fieldId >= pSourceOrItem->GetValuesCount())
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_FLAG_SET (script id %u) call for wrong field %u (max count: %u) in %s.",
|
||||
sLog.outErrorDb("SCRIPT_COMMAND_FLAG_SET (script id %u) call for wrong field %u (max count: %u) in %s.",
|
||||
m_script->id, m_script->setFlag.fieldId, pSourceOrItem->GetValuesCount(), pSourceOrItem->GetGuidStr().c_str());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1175,12 +1201,12 @@ bool ScriptAction::HandleScriptStep()
|
|||
case SCRIPT_COMMAND_FLAG_REMOVE: // 5
|
||||
if (!pSourceOrItem)
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE (script id %u) call for NULL object.", m_script->id);
|
||||
sLog.outErrorDb("SCRIPT_COMMAND_FLAG_REMOVE (script id %u) call for NULL object.", m_script->id);
|
||||
break;
|
||||
}
|
||||
if (m_script->removeFlag.fieldId <= OBJECT_FIELD_ENTRY || m_script->removeFlag.fieldId >= pSourceOrItem->GetValuesCount())
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE (script id %u) call for wrong field %u (max count: %u) in %s.",
|
||||
sLog.outErrorDb("SCRIPT_COMMAND_FLAG_REMOVE (script id %u) call for wrong field %u (max count: %u) in %s.",
|
||||
m_script->id, m_script->removeFlag.fieldId, pSourceOrItem->GetValuesCount(), pSourceOrItem->GetGuidStr().c_str());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1210,7 +1236,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
// if we have a distance, we must have a worldobject
|
||||
if (m_script->questExplored.distance != 0 && !pWorldObject)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u called without source worldobject, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u called without source worldobject, skipping.", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1245,7 +1271,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
creatureEntry = pRewardSource->GetEntry();
|
||||
else
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u called for dynamic killcredit without creature partner, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u called for dynamic killcredit without creature partner, skipping.", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1286,7 +1312,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
|
||||
if (!pGo)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for gameobject(guid: %u, buddyEntry: %u).", m_table, m_script->id, m_script->command, m_script->respawnGo.goGuid, m_script->buddyEntry);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for gameobject(guid: %u, buddyEntry: %u).", m_table, m_script->id, m_script->command, m_script->respawnGo.goGuid, m_script->buddyEntry);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1295,7 +1321,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON ||
|
||||
pGo->GetGoType() == GAMEOBJECT_TYPE_TRAP)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u can not be used with gameobject of type %u (guid: %u, buddyEntry: %u).", m_table, m_script->id, m_script->command, uint32(pGo->GetGoType()), m_script->respawnGo.goGuid, m_script->buddyEntry);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u can not be used with gameobject of type %u (guid: %u, buddyEntry: %u).", m_table, m_script->id, m_script->command, uint32(pGo->GetGoType()), m_script->respawnGo.goGuid, m_script->buddyEntry);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1311,7 +1337,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
{
|
||||
if (!pSource)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u found no worldobject as source, skipping.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u found no worldobject as source, skipping.", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1323,7 +1349,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
Creature* pCreature = pSource->SummonCreature(m_script->summonCreature.creatureEntry, x, y, z, o, m_script->summonCreature.despawnDelay ? TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN : TEMPSUMMON_DEAD_DESPAWN, m_script->summonCreature.despawnDelay, (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL) ? true : false);
|
||||
if (!pCreature)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for creature (entry: %u).", m_table, m_script->id, m_script->command, m_script->summonCreature.creatureEntry);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for creature (entry: %u).", m_table, m_script->id, m_script->command, m_script->summonCreature.creatureEntry);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1354,13 +1380,13 @@ bool ScriptAction::HandleScriptStep()
|
|||
|
||||
if (!pDoor)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for gameobject(guid: %u, buddyEntry: %u).", m_table, m_script->id, m_script->command, m_script->changeDoor.goGuid, m_script->buddyEntry);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for gameobject(guid: %u, buddyEntry: %u).", m_table, m_script->id, m_script->command, m_script->changeDoor.goGuid, m_script->buddyEntry);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pDoor->GetGoType() != GAMEOBJECT_TYPE_DOOR)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for non-door(GoType: %u).", m_table, m_script->id, m_script->command, pDoor->GetGoType());
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for non-door(GoType: %u).", m_table, m_script->id, m_script->command, pDoor->GetGoType());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1415,7 +1441,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
{
|
||||
if (!pSource)
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u could not find proper source", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u could not find proper source", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1584,7 +1610,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
|
||||
if (pAttacker->IsFriendlyTo(unitTarget))
|
||||
{
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u attacker is friendly to target, can not attack (Attacker: %s, Target: %s)", m_table, m_script->id, m_script->command, pAttacker->GetGuidStr().c_str(), unitTarget->GetGuidStr().c_str());
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u attacker is friendly to target, can not attack (Attacker: %s, Target: %s)", m_table, m_script->id, m_script->command, pAttacker->GetGuidStr().c_str(), unitTarget->GetGuidStr().c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1670,18 +1696,18 @@ bool ScriptAction::HandleScriptStep()
|
|||
pSearcher = pTarget;
|
||||
|
||||
Creature* pCreatureBuddy = NULL;
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSearcher, m_script->terminateScript.npcEntry, true, false, m_script->terminateScript.searchDist);
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSearcher, m_script->terminateScript.npcEntry, true, false, m_script->terminateScript.searchDist, true);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreatureBuddy, u_check);
|
||||
Cell::VisitGridObjects(pSearcher, searcher, m_script->terminateScript.searchDist);
|
||||
|
||||
if (!(m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL) && !pCreatureBuddy)
|
||||
{
|
||||
DEBUG_LOG("DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc %u was not found alive)", m_table, m_script->id, m_script->terminateScript.npcEntry);
|
||||
DEBUG_LOG("DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched other npc %u was not found alive)", m_table, m_script->id, m_script->terminateScript.npcEntry);
|
||||
result = true;
|
||||
}
|
||||
else if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL && pCreatureBuddy)
|
||||
{
|
||||
DEBUG_LOG("DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched npc %u was found alive)", m_table, m_script->id, m_script->terminateScript.npcEntry);
|
||||
DEBUG_LOG("DB-SCRIPTS: Process table `%s` id %u, terminate further steps of this script! (as searched other npc %u was found alive)", m_table, m_script->id, m_script->terminateScript.npcEntry);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1764,7 +1790,7 @@ bool ScriptAction::HandleScriptStep()
|
|||
return terminateResult;
|
||||
}
|
||||
default:
|
||||
sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.", m_table, m_script->id, m_script->command);
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2023,7 +2049,7 @@ bool ScriptMgr::OnQuestRewarded(Player* pPlayer, GameObject* pGameObject, Quest
|
|||
uint32 ScriptMgr::GetDialogStatus(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (!m_pGetNPCDialogStatus)
|
||||
return 100;
|
||||
return DIALOG_STATUS_UNDEFINED;
|
||||
|
||||
return m_pGetNPCDialogStatus(pPlayer, pCreature);
|
||||
}
|
||||
|
|
@ -2031,7 +2057,7 @@ uint32 ScriptMgr::GetDialogStatus(Player* pPlayer, Creature* pCreature)
|
|||
uint32 ScriptMgr::GetDialogStatus(Player* pPlayer, GameObject* pGameObject)
|
||||
{
|
||||
if (!m_pGetGODialogStatus)
|
||||
return 100;
|
||||
return DIALOG_STATUS_UNDEFINED;
|
||||
|
||||
return m_pGetGODialogStatus(pPlayer, pGameObject);
|
||||
}
|
||||
|
|
@ -2056,24 +2082,24 @@ bool ScriptMgr::OnProcessEvent(uint32 eventId, Object* pSource, Object* pTarget,
|
|||
return m_pOnProcessEvent != NULL && m_pOnProcessEvent(eventId, pSource, pTarget, isStart);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget)
|
||||
bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
return m_pOnEffectDummyCreature != NULL && m_pOnEffectDummyCreature(pCaster, spellId, effIndex, pTarget);
|
||||
return m_pOnEffectDummyCreature != NULL && m_pOnEffectDummyCreature(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget)
|
||||
bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
return m_pOnEffectDummyGO != NULL && m_pOnEffectDummyGO(pCaster, spellId, effIndex, pTarget);
|
||||
return m_pOnEffectDummyGO != NULL && m_pOnEffectDummyGO(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Item* pTarget)
|
||||
bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Item* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
return m_pOnEffectDummyItem != NULL && m_pOnEffectDummyItem(pCaster, spellId, effIndex, pTarget);
|
||||
return m_pOnEffectDummyItem != NULL && m_pOnEffectDummyItem(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnEffectScriptEffect(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget)
|
||||
bool ScriptMgr::OnEffectScriptEffect(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
return m_pOnEffectScriptEffectCreature != NULL && m_pOnEffectScriptEffectCreature(pCaster, spellId, effIndex, pTarget);
|
||||
return m_pOnEffectScriptEffectCreature != NULL && m_pOnEffectScriptEffectCreature(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnAuraDummy(Aura const* pAura, bool apply)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ class WorldObject;
|
|||
enum ScriptCommand // resSource, resTarget are the resulting Source/ Target after buddy search is done
|
||||
{
|
||||
SCRIPT_COMMAND_TALK = 0, // resSource = WorldObject, resTarget = Unit/none
|
||||
// datalong1 (see enum ChatType for supported CHAT_TYPE_'s), datalong2 = language
|
||||
// dataint = text entry from db_script_string -table. dataint2-4 optional for random selected texts.
|
||||
SCRIPT_COMMAND_EMOTE = 1, // resSource = Unit, resTarget = Unit/none
|
||||
// datalong1 = emote_id
|
||||
|
|
@ -112,7 +111,10 @@ enum ScriptInfoDataFlags
|
|||
SCRIPT_FLAG_REVERSE_DIRECTION = 0x02, // t* -> s* (* result after previous flag is evaluated)
|
||||
SCRIPT_FLAG_SOURCE_TARGETS_SELF = 0x04, // s* -> s* (* result after previous flag is evaluated)
|
||||
SCRIPT_FLAG_COMMAND_ADDITIONAL = 0x08, // command dependend
|
||||
SCRIPT_FLAG_BUDDY_BY_GUID = 0x10, // take the buddy by guid
|
||||
SCRIPT_FLAG_BUDDY_IS_PET = 0x20, // buddy is a pet
|
||||
};
|
||||
#define MAX_SCRIPT_FLAG_VALID (2 * SCRIPT_FLAG_BUDDY_IS_PET - 1)
|
||||
|
||||
struct ScriptInfo
|
||||
{
|
||||
|
|
@ -122,11 +124,7 @@ struct ScriptInfo
|
|||
|
||||
union
|
||||
{
|
||||
struct // SCRIPT_COMMAND_TALK (0)
|
||||
{
|
||||
uint32 chatType; // datalong
|
||||
uint32 language; // datalong2
|
||||
} talk;
|
||||
// datalong unused // SCRIPT_COMMAND_TALK (0)
|
||||
|
||||
struct // SCRIPT_COMMAND_EMOTE (1)
|
||||
{
|
||||
|
|
@ -188,7 +186,8 @@ struct ScriptInfo
|
|||
uint32 despawnDelay; // datalong2
|
||||
} summonCreature;
|
||||
|
||||
// SCRIPT_COMMAND_OPEN_DOOR (11)
|
||||
// datalong unused // SCRIPT_COMMAND_OPEN_DOOR (11)
|
||||
|
||||
struct // SCRIPT_COMMAND_CLOSE_DOOR (12)
|
||||
{
|
||||
uint32 goGuid; // datalong
|
||||
|
|
@ -273,11 +272,7 @@ struct ScriptInfo
|
|||
uint32 empty; // datalong2
|
||||
} run;
|
||||
|
||||
struct // SCRIPT_COMMAND_ATTACK_START (26)
|
||||
{
|
||||
uint32 empty1; // datalong
|
||||
uint32 empty2; // datalong2
|
||||
} attack;
|
||||
// datalong unused // SCRIPT_COMMAND_ATTACK_START (26)
|
||||
|
||||
struct // SCRIPT_COMMAND_GO_LOCK_STATE (27)
|
||||
{
|
||||
|
|
@ -335,8 +330,8 @@ struct ScriptInfo
|
|||
};
|
||||
|
||||
// Buddy system (entry can be npc or go entry, depending on command)
|
||||
uint32 buddyEntry; // datalong3 -> buddy_entry
|
||||
uint32 searchRadius; // datalong4 -> search_radius
|
||||
uint32 buddyEntry; // buddy_entry
|
||||
uint32 searchRadiusOrGuid; // search_radius (can also be guid in case of SCRIPT_FLAG_BUDDY_BY_GUID)
|
||||
uint8 data_flags; // data_flags
|
||||
|
||||
int32 textId[MAX_TEXT_ID]; // dataint to dataint4
|
||||
|
|
@ -515,10 +510,10 @@ class ScriptMgr
|
|||
bool OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets);
|
||||
bool OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* atEntry);
|
||||
bool OnProcessEvent(uint32 eventId, Object* pSource, Object* pTarget, bool isStart);
|
||||
bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget);
|
||||
bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget);
|
||||
bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Item* pTarget);
|
||||
bool OnEffectScriptEffect(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget);
|
||||
bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid);
|
||||
bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget, ObjectGuid originalCasterGuid);
|
||||
bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Item* pTarget, ObjectGuid originalCasterGuid);
|
||||
bool OnEffectScriptEffect(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid);
|
||||
bool OnAuraDummy(Aura const* pAura, bool apply);
|
||||
|
||||
private:
|
||||
|
|
@ -569,10 +564,10 @@ class ScriptMgr
|
|||
bool (MANGOS_IMPORT* m_pOnItemUse)(Player*, Item*, SpellCastTargets const&);
|
||||
bool (MANGOS_IMPORT* m_pOnAreaTrigger)(Player*, AreaTriggerEntry const*);
|
||||
bool (MANGOS_IMPORT* m_pOnProcessEvent)(uint32, Object*, Object*, bool);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectDummyCreature)(Unit*, uint32, SpellEffectIndex, Creature*);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectDummyGO)(Unit*, uint32, SpellEffectIndex, GameObject*);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectDummyItem)(Unit*, uint32, SpellEffectIndex, Item*);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectScriptEffectCreature)(Unit*, uint32, SpellEffectIndex, Creature*);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectDummyCreature)(Unit*, uint32, SpellEffectIndex, Creature*, ObjectGuid);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectDummyGO)(Unit*, uint32, SpellEffectIndex, GameObject*, ObjectGuid);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectDummyItem)(Unit*, uint32, SpellEffectIndex, Item*, ObjectGuid);
|
||||
bool (MANGOS_IMPORT* m_pOnEffectScriptEffectCreature)(Unit*, uint32, SpellEffectIndex, Creature*, ObjectGuid);
|
||||
bool (MANGOS_IMPORT* m_pOnAuraDummy)(Aura const*, bool);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1467,7 +1467,7 @@ enum Targets
|
|||
TARGET_DIRECTLY_FORWARD = 89,
|
||||
TARGET_NONCOMBAT_PET = 90,
|
||||
TARGET_91 = 91,
|
||||
TARGET_92 = 92,
|
||||
TARGET_SUMMONER = 92,
|
||||
TARGET_CONTROLLED_VEHICLE = 94,
|
||||
TARGET_95 = 95,
|
||||
TARGET_VEHICLE_PASSENGER_0 = 96,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "DB2Stores.h"
|
||||
#include "SQLStorages.h"
|
||||
#include "Vehicle.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "SQLStorages.h"
|
||||
|
||||
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
|
||||
|
|
@ -1749,8 +1750,9 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
|
||||
float x, y;
|
||||
float z = m_caster->GetPositionZ();
|
||||
// Ignore the BOUNDING_RADIUS for spells with radius (add a small value to prevent < 0 rounding errors)
|
||||
m_caster->GetNearPoint2D(x, y, radius > 0.001f ? radius - m_caster->GetObjectBoundingRadius() + 0.01f : 2.0f, angle);
|
||||
// Do not search for a free spot. TODO: Should there be searched for a free spot. There was once a discussion that in case this space was impossible (LOS) m_caster's position should be used.
|
||||
// TODO Bring this back to memory and search for it!
|
||||
m_caster->GetNearPoint2D(x, y, radius, angle);
|
||||
m_caster->UpdateAllowedPositionZ(x, y, z);
|
||||
m_targets.setDestination(x, y, z);
|
||||
|
||||
|
|
@ -2251,6 +2253,20 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
if (target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->IsPet() && ((Pet*)target)->getPetType() == MINI_PET)
|
||||
targetUnitMap.push_back(target);
|
||||
break;
|
||||
case TARGET_SUMMONER:
|
||||
{
|
||||
WorldObject* caster = GetAffectiveCasterObject();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->IsTemporarySummon())
|
||||
targetUnitMap.push_back(((TemporarySummon*)(Creature*)caster)->GetSummoner());
|
||||
else if (caster->GetTypeId() == TYPEID_GAMEOBJECT && !((GameObject*)caster)->HasStaticDBSpawnData())
|
||||
targetUnitMap.push_back(((GameObject*)caster)->GetOwner());
|
||||
else
|
||||
sLog.outError("SPELL: Spell ID %u with target ID %u was used by non temporary summon object %s.", m_spellInfo->Id, targetMode, caster->GetGuidStr().c_str());
|
||||
break;
|
||||
}
|
||||
case TARGET_CONTROLLED_VEHICLE:
|
||||
if (m_caster->IsBoarded() && m_caster->GetTransportInfo()->IsOnVehicle())
|
||||
targetUnitMap.push_back((Unit*)m_caster->GetTransportInfo()->GetTransport());
|
||||
|
|
@ -2732,7 +2748,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
}
|
||||
|
||||
float x, y;
|
||||
m_caster->GetNearPoint2D(x, y, radius, angle);
|
||||
m_caster->GetNearPoint2D(x, y, radius + m_caster->GetObjectBoundingRadius(), angle);
|
||||
m_targets.setDestination(x, y, m_caster->GetPositionZ());
|
||||
}
|
||||
|
||||
|
|
@ -2767,7 +2783,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
}
|
||||
|
||||
float x, y;
|
||||
currentTarget->GetNearPoint2D(x, y, radius, angle);
|
||||
currentTarget->GetNearPoint2D(x, y, radius + currentTarget->GetObjectBoundingRadius(), angle);
|
||||
m_targets.setDestination(x, y, currentTarget->GetPositionZ());
|
||||
}
|
||||
break;
|
||||
|
|
@ -3438,6 +3454,7 @@ void Spell::cast(bool skipCheck)
|
|||
|
||||
TakePower();
|
||||
TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
|
||||
TakeAmmo();
|
||||
|
||||
SendCastResult(castResult);
|
||||
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
|
||||
|
|
@ -3484,6 +3501,34 @@ void Spell::cast(bool skipCheck)
|
|||
SetExecutedCurrently(false);
|
||||
}
|
||||
|
||||
void Spell::TakeAmmo()
|
||||
{
|
||||
// take ammo
|
||||
if (m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Item* pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK, true, false);
|
||||
|
||||
// wands don't have ammo
|
||||
if (!pItem || pItem->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
|
||||
return;
|
||||
|
||||
if (pItem->GetProto()->InventoryType == INVTYPE_THROWN)
|
||||
{
|
||||
if (pItem->GetMaxStackCount() == 1)
|
||||
{
|
||||
// decrease durability for non-stackable throw weapon
|
||||
((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
|
||||
}
|
||||
else
|
||||
{
|
||||
// decrease items amount for stackable throw weapon
|
||||
uint32 count = 1;
|
||||
((Player*)m_caster)->DestroyItemCount(pItem, count, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::handle_immediate()
|
||||
{
|
||||
// process immediate effects (items, ground, etc.) also initialize some variables
|
||||
|
|
@ -5600,6 +5645,19 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
if (m_caster->IsInWater())
|
||||
return SPELL_FAILED_ONLY_ABOVEWATER;
|
||||
}
|
||||
else if (m_spellInfo->Id == 51690) // Killing Spree
|
||||
{
|
||||
UnitList targets;
|
||||
|
||||
float radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
|
||||
|
||||
MaNGOS::AnyUnfriendlyVisibleUnitInObjectRangeCheck unitCheck(m_caster, m_caster, radius);
|
||||
MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyVisibleUnitInObjectRangeCheck> checker(targets, unitCheck);
|
||||
Cell::VisitAllObjects(m_caster, checker, radius);
|
||||
|
||||
if (targets.empty())
|
||||
return SPELL_FAILED_OUT_OF_RANGE;
|
||||
}
|
||||
else if (m_spellInfo->Id == 68996) // Two forms
|
||||
{
|
||||
if (m_caster->isInCombat())
|
||||
|
|
@ -7884,11 +7942,16 @@ void Spell::GetSpellRangeAndRadius(SpellEffectEntry const* spellEffect, float& r
|
|||
case 30769: // Pick Red Riding Hood (Karazhan, Big Bad Wolf)
|
||||
case 30835: // Infernal Relay (Karazhan, Prince Malchezaar)
|
||||
case 31347: // Doom (Hyjal Summit, Azgalor)
|
||||
case 32312: // Move 1 (Karazhan, Chess Event)
|
||||
case 33711: // Murmur's Touch (Shadow Labyrinth, Murmur)
|
||||
case 37388: // Move 2 (Karazhan, Chess Event)
|
||||
case 38794: // Murmur's Touch (h) (Shadow Labyrinth, Murmur)
|
||||
case 39338: // Karazhan - Chess, Medivh CHEAT: Hand of Medivh, Target Horde
|
||||
case 39342: // Karazhan - Chess, Medivh CHEAT: Hand of Medivh, Target Alliance
|
||||
case 40834: // Agonizing Flames (BT, Illidan Stormrage)
|
||||
case 41537: // Summon Enslaved Soul (BT, Reliquary of Souls)
|
||||
case 44869: // Spectral Blast (SWP, Kalecgos)
|
||||
case 45391: // Summon Demonic Vapor (SWP, Felmyst)
|
||||
case 45785: // Sinister Reflection Clone (SWP, Kil'jaeden)
|
||||
case 45892: // Sinister Reflection (SWP, Kil'jaeden)
|
||||
case 45976: // Open Portal (SWP, M'uru)
|
||||
|
|
@ -7911,16 +7974,22 @@ void Spell::GetSpellRangeAndRadius(SpellEffectEntry const* spellEffect, float& r
|
|||
case 62042: // Stormhammer (Ulduar, Thorim)
|
||||
case 62166: // Stone Grip (Ulduar, Kologarn)
|
||||
case 62301: // Cosmic Smash (Ulduar, Algalon)
|
||||
case 62374: // Pursued (Ulduar, Flame Leviathan)
|
||||
case 62488: // Activate Construct (Ulduar, Ignis)
|
||||
case 62577: // Blizzard (Ulduar, Thorim)
|
||||
case 62603: // Blizzard (h) (Ulduar, Thorim)
|
||||
case 62797: // Storm Cloud (Ulduar, Hodir)
|
||||
case 63018: // Searing Light (Ulduar, XT-002)
|
||||
case 63024: // Gravity Bomb (Ulduar, XT-002)
|
||||
case 63387: // Rapid Burst
|
||||
case 63545: // Icicle (Ulduar, Hodir)
|
||||
case 63795: // Psychosis (Ulduar, Yogg-Saron)
|
||||
case 63820: // Summon Scrap Bot Trigger (Ulduar, Mimiron) use for Scrap Bots, hits npc 33856
|
||||
case 64218: // Overcharge (VoA, Emalon)
|
||||
case 64234: // Gravity Bomb (h) (Ulduar, XT-002)
|
||||
case 64425: // Summon Scrap Bot Trigger (Ulduar, Mimiron) use for Assault Bots, hits npc 33856
|
||||
case 64531: // Rapid Burst (h)
|
||||
case 64543: // Melt Ice (Ulduar, Hodir)
|
||||
case 65121: // Searing Light (h) (Ulduar, XT-002)
|
||||
case 65301: // Psychosis (Ulduar, Yogg-Saron)
|
||||
case 65872: // Pursuing Spikes (ToCrusader, Anub'arak)
|
||||
|
|
@ -7965,6 +8034,7 @@ void Spell::GetSpellRangeAndRadius(SpellEffectEntry const* spellEffect, float& r
|
|||
break;
|
||||
case 10258: // Awaken Vault Warder (Uldaman)
|
||||
case 28542: // Life Drain (Naxx, Sapphiron)
|
||||
case 62476: // Icicle (Ulduar, Hodir)
|
||||
case 66013: // Penetrating Cold (10 man) (ToCrusader, Anub'arak)
|
||||
case 67755: // Nerubian Burrower (Mode 1) (ToCrusader, Anub'arak)
|
||||
case 67756: // Nerubian Burrower (Mode 2) (ToCrusader, Anub'arak)
|
||||
|
|
@ -7980,6 +8050,8 @@ void Spell::GetSpellRangeAndRadius(SpellEffectEntry const* spellEffect, float& r
|
|||
case 29213: // Curse of the Plaguebringer (Naxx, Noth the Plaguebringer)
|
||||
case 30004: // Flame Wreath (Karazhan, Shade of Aran)
|
||||
case 31298: // Sleep (Hyjal Summit, Anetheron)
|
||||
case 39341: // Karazhan - Chess, Medivh CHEAT: Fury of Medivh, Target Horde
|
||||
case 39344: // Karazhan - Chess, Medivh CHEAT: Fury of Medivh, Target Alliance
|
||||
case 39992: // Needle Spine Targeting (BT, Warlord Najentus)
|
||||
case 40869: // Fatal Attraction (BT, Mother Shahraz)
|
||||
case 41303: // Soul Drain (BT, Reliquary of Souls)
|
||||
|
|
@ -7988,6 +8060,7 @@ void Spell::GetSpellRangeAndRadius(SpellEffectEntry const* spellEffect, float& r
|
|||
case 54522: // Summon Ghouls On Scarlet Crusade
|
||||
case 60936: // Surge of Power (h) (Malygos)
|
||||
case 61693: // Arcane Storm (Malygos)
|
||||
case 62477: // Icicle (h) (Ulduar, Hodir)
|
||||
case 63981: // StoneGrip (h) (Ulduar, Kologarn)
|
||||
case 64598: // Cosmic Smash (h) (Ulduar, Algalon)
|
||||
case 64620: // Summon Fire Bot Trigger (Ulduar, Mimiron) hits npc 33856
|
||||
|
|
@ -8001,6 +8074,7 @@ void Spell::GetSpellRangeAndRadius(SpellEffectEntry const* spellEffect, float& r
|
|||
break;
|
||||
case 37676: // Insidious Whisper (SSC, Leotheras the Blind)
|
||||
case 38028: // Watery Grave (SSC, Morogrim Tidewalker)
|
||||
case 46650: // Open Brutallus Back Door (SWP, Felmyst)
|
||||
case 67757: // Nerubian Burrower (Mode 3) (ToCrusader, Anub'arak)
|
||||
case 71221: // Gas spore (Mode 1) (ICC, Festergut)
|
||||
unMaxTargets = 4;
|
||||
|
|
|
|||
|
|
@ -388,6 +388,7 @@ class Spell
|
|||
void cast(bool skipCheck = false);
|
||||
void finish(bool ok = true);
|
||||
void TakePower();
|
||||
void TakeAmmo();
|
||||
void TakeReagents();
|
||||
void TakeCastItem();
|
||||
|
||||
|
|
|
|||
|
|
@ -1793,8 +1793,9 @@ void Aura::TriggerSpell()
|
|||
// // Shield Level 3
|
||||
// case 63132: break;
|
||||
// // Food
|
||||
// case 64345: break;
|
||||
// // Remove Player from Phase
|
||||
case 64345: // Remove Player from Phase
|
||||
target->RemoveSpellsCausingAura(SPELL_AURA_PHASE);
|
||||
return;
|
||||
// case 64445: break;
|
||||
// // Food
|
||||
// case 65418: break;
|
||||
|
|
@ -2186,7 +2187,7 @@ void Aura::TriggerSpell()
|
|||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
if (triggerTarget->GetTypeId() != TYPEID_UNIT || !sScriptMgr.OnEffectDummy(caster, GetId(), GetEffIndex(), (Creature*)triggerTarget))
|
||||
if (triggerTarget->GetTypeId() != TYPEID_UNIT || !sScriptMgr.OnEffectDummy(caster, GetId(), GetEffIndex(), (Creature*)triggerTarget, ObjectGuid()))
|
||||
sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?", GetId(), GetEffIndex());
|
||||
}
|
||||
}
|
||||
|
|
@ -2372,6 +2373,11 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
case 58600: // Restricted Flight Area
|
||||
target->MonsterWhisper(LANG_NO_FLY_ZONE, target, true);
|
||||
return;
|
||||
case 61187: // Twilight Shift (single target)
|
||||
case 61190: // Twilight Shift (many targets)
|
||||
target->RemoveAurasDueToSpell(57620);
|
||||
target->CastSpell(target, 61885, true, NULL, this);
|
||||
return;
|
||||
case 62061: // Festive Holiday Mount
|
||||
if (target->HasAuraType(SPELL_AURA_MOUNTED))
|
||||
// Reindeer Transformation
|
||||
|
|
@ -2817,6 +2823,11 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
target->CastSpell(target, 47287, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
case 46637: // Break Ice
|
||||
{
|
||||
target->CastSpell(target, 46638, true);
|
||||
return;
|
||||
}
|
||||
case 48385: // Create Spirit Fount Beam
|
||||
{
|
||||
target->CastSpell(target, target->GetMap()->IsRegularDifficulty() ? 48380 : 59320, true);
|
||||
|
|
@ -8014,6 +8025,19 @@ void Aura::PeriodicDummyTick()
|
|||
return;
|
||||
// // Panda
|
||||
// case 19230: break;
|
||||
case 30019: // Control Piece
|
||||
{
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Unit* chessPiece = target->GetCharm();
|
||||
if (!chessPiece)
|
||||
{
|
||||
target->CastSpell(target, 30529, true);
|
||||
target->RemoveAurasDueToSpell(30019);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// // Gossip NPC Periodic - Talk
|
||||
// case 33208: break;
|
||||
// // Gossip NPC Periodic - Despawn
|
||||
|
|
@ -8259,11 +8283,41 @@ void Aura::PeriodicDummyTick()
|
|||
case 2: target->CastSpell(target, 55739, true); break;
|
||||
}
|
||||
return;
|
||||
case 61968: // Flash Freeze
|
||||
{
|
||||
if (GetAuraTicks() == 1 && !target->HasAura(62464))
|
||||
target->CastSpell(target, 61970, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
case 62018: // Collapse
|
||||
{
|
||||
// lose 1% of health every second
|
||||
target->DealDamage(target, target->GetMaxHealth() * .01, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false);
|
||||
return;
|
||||
}
|
||||
case 62019: // Rune of Summoning
|
||||
{
|
||||
target->CastSpell(target, 62020, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
case 62038: // Biting Cold
|
||||
{
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
// if player is moving remove one aura stack
|
||||
if (((Player*)target)->isMoving())
|
||||
target->RemoveAuraHolderFromStack(62039);
|
||||
// otherwise add one aura stack each 3 seconds
|
||||
else if (GetAuraTicks() % 3 && !target->HasAura(62821))
|
||||
target->CastSpell(target, 62039, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
case 62039: // Biting Cold
|
||||
{
|
||||
target->CastSpell(target, 62188, true);
|
||||
return;
|
||||
}
|
||||
case 62566: // Healthy Spore Summon Periodic
|
||||
{
|
||||
target->CastSpell(target, 62582, true);
|
||||
|
|
@ -8272,6 +8326,15 @@ void Aura::PeriodicDummyTick()
|
|||
target->CastSpell(target, 62593, true);
|
||||
return;
|
||||
}
|
||||
case 62717: // Slag Pot
|
||||
{
|
||||
target->CastSpell(target, target->GetMap()->IsRegularDifficulty() ? 65722 : 65723, true, NULL, this);
|
||||
|
||||
// cast Slag Imbued if the target survives up to the last tick
|
||||
if (GetAuraTicks() == 10)
|
||||
target->CastSpell(target, 63536, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
case 64217: // Overcharged
|
||||
{
|
||||
if (GetHolder()->GetStackAmount() >= 10)
|
||||
|
|
@ -8281,6 +8344,39 @@ void Aura::PeriodicDummyTick()
|
|||
}
|
||||
return;
|
||||
}
|
||||
case 64412: // Phase Punch
|
||||
{
|
||||
if (SpellAuraHolder* phaseAura = target->GetSpellAuraHolder(64412))
|
||||
{
|
||||
uint32 uiAuraId = 0;
|
||||
switch (phaseAura->GetStackAmount())
|
||||
{
|
||||
case 1: uiAuraId = 64435; break;
|
||||
case 2: uiAuraId = 64434; break;
|
||||
case 3: uiAuraId = 64428; break;
|
||||
case 4: uiAuraId = 64421; break;
|
||||
case 5: uiAuraId = 64417; break;
|
||||
}
|
||||
|
||||
if (uiAuraId && !target->HasAura(uiAuraId))
|
||||
{
|
||||
target->CastSpell(target, uiAuraId, true, NULL, this);
|
||||
|
||||
// remove original aura if phased
|
||||
if (uiAuraId == 64417)
|
||||
{
|
||||
target->RemoveAurasDueToSpell(64412);
|
||||
target->CastSpell(target, 62169, true, NULL, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 65272: // Shatter Chest
|
||||
{
|
||||
target->CastSpell(target, 62501, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
case 66118: // Leeching Swarm
|
||||
case 67630: // Leeching Swarm
|
||||
case 68646: // Leeching Swarm
|
||||
|
|
@ -8537,7 +8633,7 @@ void Aura::PeriodicDummyTick()
|
|||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
if (target && target->GetTypeId() == TYPEID_UNIT)
|
||||
sScriptMgr.OnEffectDummy(caster, GetId(), GetEffIndex(), (Creature*)target);
|
||||
sScriptMgr.OnEffectDummy(caster, GetId(), GetEffIndex(), (Creature*)target, ObjectGuid());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1365,6 +1365,16 @@ void Spell::EffectDummy(SpellEffectEntry const* effect)
|
|||
unitTarget->CastSpell(unitTarget, unitTarget->GetMap()->IsRegularDifficulty() ? 32302 : 38382, true);
|
||||
return;
|
||||
}
|
||||
case 32312: // Move 1 (Chess event AI short distance move)
|
||||
case 37388: // Move 2 (Chess event AI long distance move)
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
// cast generic move spell
|
||||
m_caster->CastSpell(unitTarget, 30012, true);
|
||||
return;
|
||||
}
|
||||
case 33060: // Make a Wish
|
||||
{
|
||||
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
|
|
@ -1700,21 +1710,6 @@ void Spell::EffectDummy(SpellEffectEntry const* effect)
|
|||
m_caster->CastSpell(unitTarget, 44455, true, m_CastItem);
|
||||
return;
|
||||
}
|
||||
case 44845: // Spectral Realm
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
// teleport all targets which have the spectral realm aura
|
||||
if (unitTarget->HasAura(46021))
|
||||
{
|
||||
unitTarget->RemoveAurasDueToSpell(46021);
|
||||
unitTarget->CastSpell(unitTarget, 46020, true);
|
||||
unitTarget->CastSpell(unitTarget, 44867, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case 44869: // Spectral Blast
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
|
|
@ -1961,6 +1956,14 @@ void Spell::EffectDummy(SpellEffectEntry const* effect)
|
|||
m_caster->CastSpell(unitTarget, 46359, true);
|
||||
return;
|
||||
}
|
||||
case 46289: // Negative Energy
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, 46285, true);
|
||||
return;
|
||||
}
|
||||
case 46430: // Synch Health
|
||||
{
|
||||
if (!unitTarget)
|
||||
|
|
@ -2728,6 +2731,47 @@ void Spell::EffectDummy(SpellEffectEntry const* effect)
|
|||
unitTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
return;
|
||||
}
|
||||
case 62278: // Lightning Orb Charger
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(m_caster, 62466, true);
|
||||
unitTarget->CastSpell(unitTarget, 62279, true);
|
||||
return;
|
||||
}
|
||||
case 62797: // Storm Cloud
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, m_caster->GetMap()->IsRegularDifficulty() ? 65123 : 65133, true);
|
||||
return;
|
||||
}
|
||||
case 62907: // Freya's Ward
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
m_caster->CastSpell(unitTarget, effect->CalculateSimpleValue(), true);
|
||||
return;
|
||||
}
|
||||
case 63499: // Dispel Magic
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
unitTarget->RemoveAurasDueToSpell(effect->CalculateSimpleValue());
|
||||
return;
|
||||
}
|
||||
case 63545: // Icicle
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, effect->CalculateSimpleValue(), true);
|
||||
}
|
||||
case 63820: // Summon Scrap Bot Trigger (Ulduar - Mimiron) for Scrap Bots
|
||||
case 64425: // Summon Scrap Bot Trigger (Ulduar - Mimiron) for Assault Bots
|
||||
case 64620: // Summon Fire Bot Trigger (Ulduar - Mimiron) for Fire Bots
|
||||
|
|
@ -2750,6 +2794,31 @@ void Spell::EffectDummy(SpellEffectEntry const* effect)
|
|||
m_caster->SetFacingTo(frand(0, M_PI_F * 2));
|
||||
return;
|
||||
}
|
||||
case 64489: // Feral Rush
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, 64496, true);
|
||||
return;
|
||||
}
|
||||
case 64543: // Melt Ice
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, effect->CalculateSimpleValue(), true);
|
||||
m_caster->CastSpell(m_caster, 64540, true);
|
||||
return;
|
||||
}
|
||||
case 64673: // Feral Rush (h)
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, 64674, true);
|
||||
return;
|
||||
}
|
||||
case 64981: // Summon Random Vanquished Tentacle
|
||||
{
|
||||
uint32 spell_id = 0;
|
||||
|
|
@ -3055,6 +3124,35 @@ void Spell::EffectDummy(SpellEffectEntry const* effect)
|
|||
m_caster->CastCustomSpell(unitTarget, 23885, &damage, NULL, NULL, true, NULL);
|
||||
return;
|
||||
}
|
||||
case 30012: // Move
|
||||
{
|
||||
if (!unitTarget || unitTarget->HasAura(39400))
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(m_caster, 30253, true);
|
||||
}
|
||||
case 30284: // Change Facing
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(m_caster, 30270, true);
|
||||
return;
|
||||
}
|
||||
case 37144: // Move (Chess event player knight move)
|
||||
case 37146: // Move (Chess event player pawn move)
|
||||
case 37148: // Move (Chess event player queen move)
|
||||
case 37151: // Move (Chess event player rook move)
|
||||
case 37152: // Move (Chess event player bishop move)
|
||||
case 37153: // Move (Chess event player king move)
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
// cast generic move spell
|
||||
m_caster->CastSpell(unitTarget, 30012, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -3678,11 +3776,11 @@ void Spell::EffectDummy(SpellEffectEntry const* effect)
|
|||
// So called only for not processed cases
|
||||
bool libraryResult = false;
|
||||
if (gameObjTarget)
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), gameObjTarget);
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), gameObjTarget, m_originalCasterGUID);
|
||||
else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT)
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), (Creature*)unitTarget);
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), (Creature*)unitTarget, m_originalCasterGUID);
|
||||
else if (itemTarget)
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), itemTarget);
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), itemTarget, m_originalCasterGUID);
|
||||
|
||||
if (libraryResult || !unitTarget)
|
||||
return;
|
||||
|
|
@ -3812,10 +3910,6 @@ void Spell::EffectTriggerSpell(SpellEffectEntry const* effect)
|
|||
m_caster->CastSpell(unitTarget, spellId, true);
|
||||
return;
|
||||
}
|
||||
// just skip
|
||||
case 23770: // Sayge's Dark Fortune of *
|
||||
// not exist, common cooldown can be implemented in scripts if need.
|
||||
return;
|
||||
case 29284: // Brittle Armor - (need add max stack of 24575 Brittle Armor)
|
||||
m_caster->CastSpell(unitTarget, 24575, true, m_CastItem, NULL, m_originalCasterGUID);
|
||||
return;
|
||||
|
|
@ -6284,7 +6378,7 @@ void Spell::EffectSummonPet(SpellEffectEntry const* effect)
|
|||
// if pet requested type already exist
|
||||
if (OldSummon)
|
||||
{
|
||||
if (petentry == 0 || OldSummon->GetEntry() == petentry)
|
||||
if ((petentry == 0 || OldSummon->GetEntry() == petentry) && OldSummon->getPetType() != SUMMON_PET)
|
||||
{
|
||||
// pet in corpse state can't be summoned
|
||||
if (OldSummon->isDead())
|
||||
|
|
@ -6759,31 +6853,6 @@ void Spell::EffectWeaponDmg(SpellEffectEntry const* effect)
|
|||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_caster)->AddComboPoints(unitTarget, 1);
|
||||
}
|
||||
|
||||
// take ammo
|
||||
if (m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Item* pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK, true, false);
|
||||
|
||||
// wands don't have ammo
|
||||
if (!pItem || pItem->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
|
||||
return;
|
||||
|
||||
if (pItem->GetProto()->InventoryType == INVTYPE_THROWN)
|
||||
{
|
||||
if (pItem->GetMaxStackCount() == 1)
|
||||
{
|
||||
// decrease durability for non-stackable throw weapon
|
||||
((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
|
||||
}
|
||||
else
|
||||
{
|
||||
// decrease items amount for stackable throw weapon
|
||||
uint32 count = 1;
|
||||
((Player*)m_caster)->DestroyItemCount(pItem, count, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectThreat(SpellEffectEntry const* /*effect*/)
|
||||
|
|
@ -7217,7 +7286,7 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
float angle = unitTarget->GetOrientation();
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
unitTarget->GetNearPoint(unitTarget, x, y, z, unitTarget->GetObjectBoundingRadius(), 5.0f, angle + i * M_PI_F / 2);
|
||||
unitTarget->GetNearPoint(unitTarget, x, y, z, unitTarget->GetObjectBoundingRadius(), INTERACTION_DISTANCE, angle + i * M_PI_F / 2);
|
||||
unitTarget->SummonCreature(16119, x, y, z, angle, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 10 * MINUTE * IN_MILLISECONDS);
|
||||
}
|
||||
return;
|
||||
|
|
@ -7347,6 +7416,25 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
unitTarget->RemoveAurasAtMechanicImmunity(IMMUNE_TO_ROOT_AND_SNARE_MASK, 30918, true);
|
||||
break;
|
||||
}
|
||||
case 37142: // Karazhan - Chess NPC Action: Melee Attack: Conjured Water Elemental
|
||||
case 37143: // Karazhan - Chess NPC Action: Melee Attack: Charger
|
||||
case 37147: // Karazhan - Chess NPC Action: Melee Attack: Human Cleric
|
||||
case 37149: // Karazhan - Chess NPC Action: Melee Attack: Human Conjurer
|
||||
case 37150: // Karazhan - Chess NPC Action: Melee Attack: King Llane
|
||||
case 37220: // Karazhan - Chess NPC Action: Melee Attack: Summoned Daemon
|
||||
case 32227: // Karazhan - Chess NPC Action: Melee Attack: Footman
|
||||
case 32228: // Karazhan - Chess NPC Action: Melee Attack: Grunt
|
||||
case 37337: // Karazhan - Chess NPC Action: Melee Attack: Orc Necrolyte
|
||||
case 37339: // Karazhan - Chess NPC Action: Melee Attack: Orc Wolf
|
||||
case 37345: // Karazhan - Chess NPC Action: Melee Attack: Orc Warlock
|
||||
case 37348: // Karazhan - Chess NPC Action: Melee Attack: Warchief Blackhand
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, 32247, true);
|
||||
return;
|
||||
}
|
||||
case 32301: // Ping Shirrak
|
||||
{
|
||||
if (!unitTarget)
|
||||
|
|
@ -7372,7 +7460,7 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
float x, y, z;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
m_caster->GetNearPoint(m_caster, x, y, z, 0, 5.0f, M_PI_F * .5f * i + M_PI_F * .25f);
|
||||
m_caster->GetNearPoint(m_caster, x, y, z, 0.0f, INTERACTION_DISTANCE, M_PI_F * .5f * i + M_PI_F * .25f);
|
||||
m_caster->SummonCreature(21002, x, y, z, 0, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 30000);
|
||||
}
|
||||
return;
|
||||
|
|
@ -7385,6 +7473,22 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
unitTarget->CastSpell(unitTarget, urand(0, 1) ? 37429 : 37430, true);
|
||||
return;
|
||||
}
|
||||
case 37775: // Karazhan - Chess NPC Action - Poison Cloud
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, 37469, true);
|
||||
return;
|
||||
}
|
||||
case 37824: // Karazhan - Chess NPC Action - Shadow Mend
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, 37456, true);
|
||||
return;
|
||||
}
|
||||
case 38358: // Tidal Surge
|
||||
{
|
||||
if (!unitTarget)
|
||||
|
|
@ -7393,6 +7497,24 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
unitTarget->CastSpell(unitTarget, 38353, true, NULL, NULL, m_caster->GetObjectGuid());
|
||||
return;
|
||||
}
|
||||
case 39338: // Karazhan - Chess, Medivh CHEAT: Hand of Medivh, Target Horde
|
||||
case 39342: // Karazhan - Chess, Medivh CHEAT: Hand of Medivh, Target Alliance
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, 39339, true);
|
||||
return;
|
||||
}
|
||||
case 39341: // Karazhan - Chess, Medivh CHEAT: Fury of Medivh, Target Horde
|
||||
case 39344: // Karazhan - Chess, Medivh CHEAT: Fury of Medivh, Target Alliance
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
m_caster->CastSpell(unitTarget, effect->CalculateSimpleValue(), true);
|
||||
return;
|
||||
}
|
||||
case 41055: // Copy Weapon
|
||||
{
|
||||
if (m_caster->GetTypeId() != TYPEID_UNIT || !unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
|
|
@ -7538,9 +7660,10 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
}
|
||||
|
||||
// Teleport target to the spectral realm, add debuff and force faction
|
||||
unitTarget->CastSpell(unitTarget, 44852, true);
|
||||
unitTarget->CastSpell(unitTarget, 46019, true);
|
||||
unitTarget->CastSpell(unitTarget, 46021, true);
|
||||
unitTarget->CastSpell(unitTarget, 44845, true);
|
||||
unitTarget->CastSpell(unitTarget, 44852, true);
|
||||
return;
|
||||
}
|
||||
case 45141: // Burn
|
||||
|
|
@ -7600,6 +7723,14 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
unitTarget->CastSpell(unitTarget, 45236, true, NULL, NULL, m_caster->GetObjectGuid());
|
||||
return;
|
||||
}
|
||||
case 45260: // Karazhan - Chess - Force Player to Kill Bunny
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(unitTarget, 45259, true);
|
||||
return;
|
||||
}
|
||||
case 45668: // Ultra-Advanced Proto-Typical Shortening Blaster
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT)
|
||||
|
|
@ -7704,6 +7835,22 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
m_caster->SetDisplayId(display_id);
|
||||
return;
|
||||
}
|
||||
case 45714: // Fog of Corruption (caster inform)
|
||||
{
|
||||
if (!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(m_caster, effect->CalculateSimpleValue(), true);
|
||||
return;
|
||||
}
|
||||
case 45717: // Fog of Corruption (player buff)
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(unitTarget, 45726, true);
|
||||
return;
|
||||
}
|
||||
case 45785: // Sinister Reflection Clone
|
||||
{
|
||||
if (!unitTarget)
|
||||
|
|
@ -7730,6 +7877,15 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
unitTarget->CastSpell(unitTarget, 45891, true, NULL, NULL, m_caster->GetObjectGuid());
|
||||
return;
|
||||
}
|
||||
case 45918: // Soul Sever
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || !unitTarget->HasAura(45717))
|
||||
return;
|
||||
|
||||
// kill all charmed targets
|
||||
unitTarget->CastSpell(unitTarget, 45917, true);
|
||||
return;
|
||||
}
|
||||
case 45958: // Signal Alliance
|
||||
{
|
||||
// "escort" aura not present, so let nothing happen
|
||||
|
|
@ -8438,6 +8594,37 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
|
||||
return;
|
||||
}
|
||||
case 62042: // Stormhammer
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(unitTarget, 62470, true);
|
||||
unitTarget->CastSpell(m_caster, 64909, true);
|
||||
return;
|
||||
}
|
||||
case 62381: // Chill
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
unitTarget->RemoveAurasDueToSpell(62373);
|
||||
unitTarget->CastSpell(unitTarget, 62382, true);
|
||||
return;
|
||||
}
|
||||
case 62488: // Activate Construct
|
||||
{
|
||||
if (!unitTarget || !unitTarget->HasAura(62468))
|
||||
return;
|
||||
|
||||
unitTarget->RemoveAurasDueToSpell(62468);
|
||||
unitTarget->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
unitTarget->CastSpell(unitTarget, 64474, true);
|
||||
|
||||
if (m_caster->getVictim())
|
||||
((Creature*)unitTarget)->AI()->AttackStart(m_caster->getVictim());
|
||||
return;
|
||||
}
|
||||
case 62524: // Attuned to Nature 2 Dose Reduction
|
||||
case 62525: // Attuned to Nature 10 Dose Reduction
|
||||
case 62521: // Attuned to Nature 25 Dose Reduction
|
||||
|
|
@ -8479,6 +8666,23 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
|
||||
return;
|
||||
}
|
||||
case 62707: // Grab
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
unitTarget->CastSpell(unitTarget, 62708, true);
|
||||
return;
|
||||
}
|
||||
case 63633: // Summon Rubble
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
unitTarget->CastSpell(unitTarget, effect->CalculateSimpleValue(), true);
|
||||
return;
|
||||
}
|
||||
case 64456: // Feral Essence Application Removal
|
||||
{
|
||||
if (!unitTarget)
|
||||
|
|
@ -8488,6 +8692,29 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
unitTarget->RemoveAuraHolderFromStack(spellId);
|
||||
return;
|
||||
}
|
||||
case 64475: // Strength of the Creator
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
unitTarget->RemoveAuraHolderFromStack(64473);
|
||||
return;
|
||||
}
|
||||
case 64767: // Stormhammer
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
if (Creature* target = (Creature*)unitTarget)
|
||||
{
|
||||
target->AI()->EnterEvadeMode();
|
||||
target->CastSpell(target, 62470, true);
|
||||
target->CastSpell(m_caster, 64909, true);
|
||||
target->CastSpell(target, 64778, true);
|
||||
target->ForcedDespawn(10000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 66477: // Bountiful Feast
|
||||
{
|
||||
if (!unitTarget)
|
||||
|
|
@ -9057,7 +9284,7 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect)
|
|||
// So called only for not processed cases
|
||||
if (unitTarget->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if (sScriptMgr.OnEffectScriptEffect(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), (Creature*)unitTarget))
|
||||
if (sScriptMgr.OnEffectScriptEffect(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), (Creature*)unitTarget, m_originalCasterGUID))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -9230,7 +9457,7 @@ static ScriptInfo generateActivateCommand()
|
|||
si.command = SCRIPT_COMMAND_ACTIVATE_OBJECT;
|
||||
si.id = 0;
|
||||
si.buddyEntry = 0;
|
||||
si.searchRadius = 0;
|
||||
si.searchRadiusOrGuid = 0;
|
||||
si.data_flags = 0x00;
|
||||
return si;
|
||||
}
|
||||
|
|
@ -9240,11 +9467,145 @@ void Spell::EffectActivateObject(SpellEffectEntry const* effect)
|
|||
if (!gameObjTarget)
|
||||
return;
|
||||
|
||||
uint32 misc_value = uint32(effect->EffectMiscValue);
|
||||
|
||||
switch (misc_value)
|
||||
{
|
||||
case 1: // GO simple use
|
||||
case 2: // unk - 2 spells
|
||||
case 4: // unk - 1 spell
|
||||
case 5: // GO trap usage
|
||||
case 7: // unk - 2 spells
|
||||
case 8: // GO usage with TargetB = none or random
|
||||
case 10: // GO explosions
|
||||
case 11: // unk - 1 spell
|
||||
case 19: // unk - 1 spell
|
||||
case 20: // unk - 2 spells
|
||||
{
|
||||
static ScriptInfo activateCommand = generateActivateCommand();
|
||||
|
||||
int32 delay_secs = effect->CalculateSimpleValue();
|
||||
|
||||
gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
|
||||
break;
|
||||
}
|
||||
case 3: // GO custom anim - found mostly in Lunar Fireworks spells
|
||||
gameObjTarget->SendGameObjectCustomAnim(gameObjTarget->GetObjectGuid());
|
||||
break;
|
||||
case 12: // GO state active alternative - found mostly in Simon Game spells
|
||||
gameObjTarget->UseDoorOrButton(0, true);
|
||||
break;
|
||||
case 13: // GO state ready - found only in Simon Game spells
|
||||
gameObjTarget->ResetDoorOrButton();
|
||||
break;
|
||||
case 15: // GO destroy
|
||||
gameObjTarget->SetLootState(GO_JUST_DEACTIVATED);
|
||||
break;
|
||||
case 16: // GO custom use - found mostly in Wind Stones spells, Simon Game spells and other GO target summoning spells
|
||||
{
|
||||
switch (m_spellInfo->Id)
|
||||
{
|
||||
case 24734: // Summon Templar Random
|
||||
case 24744: // Summon Templar (fire)
|
||||
case 24756: // Summon Templar (air)
|
||||
case 24758: // Summon Templar (earth)
|
||||
case 24760: // Summon Templar (water)
|
||||
case 24763: // Summon Duke Random
|
||||
case 24765: // Summon Duke (fire)
|
||||
case 24768: // Summon Duke (air)
|
||||
case 24770: // Summon Duke (earth)
|
||||
case 24772: // Summon Duke (water)
|
||||
case 24784: // Summon Royal Random
|
||||
case 24786: // Summon Royal (fire)
|
||||
case 24788: // Summon Royal (air)
|
||||
case 24789: // Summon Royal (earth)
|
||||
case 24790: // Summon Royal (water)
|
||||
{
|
||||
uint32 npcEntry = 0;
|
||||
uint32 templars[] = {15209, 15211, 15212, 15307};
|
||||
uint32 dukes[] = {15206, 15207, 15208, 15220};
|
||||
uint32 royals[] = {15203, 15204, 15205, 15305};
|
||||
|
||||
switch (m_spellInfo->Id)
|
||||
{
|
||||
case 24734: npcEntry = templars[urand(0, 3)]; break;
|
||||
case 24763: npcEntry = dukes[urand(0, 3)]; break;
|
||||
case 24784: npcEntry = royals[urand(0, 3)]; break;
|
||||
case 24744: npcEntry = 15209; break;
|
||||
case 24756: npcEntry = 15212; break;
|
||||
case 24758: npcEntry = 15307; break;
|
||||
case 24760: npcEntry = 15211; break;
|
||||
case 24765: npcEntry = 15206; break;
|
||||
case 24768: npcEntry = 15220; break;
|
||||
case 24770: npcEntry = 15208; break;
|
||||
case 24772: npcEntry = 15207; break;
|
||||
case 24786: npcEntry = 15203; break;
|
||||
case 24788: npcEntry = 15204; break;
|
||||
case 24789: npcEntry = 15205; break;
|
||||
case 24790: npcEntry = 15305; break;
|
||||
}
|
||||
|
||||
gameObjTarget->SummonCreature(npcEntry, gameObjTarget->GetPositionX(), gameObjTarget->GetPositionY(), gameObjTarget->GetPositionZ(), gameObjTarget->GetAngle(m_caster), TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, MINUTE * IN_MILLISECONDS);
|
||||
gameObjTarget->SetLootState(GO_JUST_DEACTIVATED);
|
||||
break;
|
||||
}
|
||||
case 40176: // Simon Game pre-game Begin, blue
|
||||
case 40177: // Simon Game pre-game Begin, green
|
||||
case 40178: // Simon Game pre-game Begin, red
|
||||
case 40179: // Simon Game pre-game Begin, yellow
|
||||
case 40283: // Simon Game END, blue
|
||||
case 40284: // Simon Game END, green
|
||||
case 40285: // Simon Game END, red
|
||||
case 40286: // Simon Game END, yellow
|
||||
case 40494: // Simon Game, switched ON
|
||||
case 40495: // Simon Game, switched OFF
|
||||
case 40512: // Simon Game, switch...disable Off switch
|
||||
gameObjTarget->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT);
|
||||
break;
|
||||
case 40632: // Summon Gezzarak the Huntress
|
||||
case 40640: // Summon Karrog
|
||||
case 40642: // Summon Darkscreecher Akkarai
|
||||
case 40644: // Summon Vakkiz the Windrager
|
||||
case 41004: // Summon Terokk
|
||||
gameObjTarget->SetLootState(GO_JUST_DEACTIVATED);
|
||||
break;
|
||||
case 46085: // Place Fake Fur
|
||||
{
|
||||
float x, y, z;
|
||||
gameObjTarget->GetClosePoint(x, y, z, gameObjTarget->GetObjectBoundingRadius(), 2 * INTERACTION_DISTANCE, frand(0, M_PI_F * 2));
|
||||
|
||||
// Note: event script is implemented in script library
|
||||
gameObjTarget->SummonCreature(25835, x, y, z, gameObjTarget->GetOrientation(), TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 15000);
|
||||
gameObjTarget->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
|
||||
break;
|
||||
}
|
||||
case 46592: // Summon Ahune Lieutenant
|
||||
{
|
||||
uint32 npcEntry = 0;
|
||||
|
||||
switch (gameObjTarget->GetEntry())
|
||||
{
|
||||
case 188049: npcEntry = 26116; break; // Frostwave Lieutenant (Ashenvale)
|
||||
case 188137: npcEntry = 26178; break; // Hailstone Lieutenant (Desolace)
|
||||
case 188138: npcEntry = 26204; break; // Chillwind Lieutenant (Stranglethorn)
|
||||
case 188148: npcEntry = 26214; break; // Frigid Lieutenant (Searing Gorge)
|
||||
case 188149: npcEntry = 26215; break; // Glacial Lieutenant (Silithus)
|
||||
case 188150: npcEntry = 26216; break; // Glacial Templar (Hellfire Peninsula)
|
||||
}
|
||||
|
||||
gameObjTarget->SummonCreature(npcEntry, gameObjTarget->GetPositionX(), gameObjTarget->GetPositionY(), gameObjTarget->GetPositionZ(), gameObjTarget->GetAngle(m_caster), TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, MINUTE * IN_MILLISECONDS);
|
||||
gameObjTarget->SetLootState(GO_JUST_DEACTIVATED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 17: // GO unlock - found mostly in Simon Game spells
|
||||
gameObjTarget->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Spell::EffectActivateObject called with unknown misc value. Spell Id %u", m_spellInfo->Id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectApplyGlyph(SpellEffectEntry const* effect)
|
||||
|
|
@ -9540,7 +9901,7 @@ void Spell::EffectLeapForward(SpellEffectEntry const* effect)
|
|||
if (unitTarget->IsTaxiFlying())
|
||||
return;
|
||||
|
||||
if (m_spellInfo->rangeIndex == 1) // self range
|
||||
if (m_spellInfo->rangeIndex == SPELL_RANGE_IDX_SELF_ONLY)
|
||||
{
|
||||
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex()));
|
||||
|
||||
|
|
@ -9935,7 +10296,7 @@ void Spell::EffectTransmitted(SpellEffectEntry const* effect)
|
|||
// calculate angle variation for roughly equal dimensions of target area
|
||||
float max_angle = (max_dis - min_dis) / (max_dis + m_caster->GetObjectBoundingRadius());
|
||||
float angle_offset = max_angle * (rand_norm_f() - 0.5f);
|
||||
m_caster->GetNearPoint2D(fx, fy, dis, m_caster->GetOrientation() + angle_offset);
|
||||
m_caster->GetNearPoint2D(fx, fy, dis + m_caster->GetObjectBoundingRadius(), m_caster->GetOrientation() + angle_offset);
|
||||
|
||||
GridMapLiquidData liqData;
|
||||
if (!m_caster->GetTerrain()->IsInWater(fx, fy, m_caster->GetPositionZ() + 1.f, &liqData))
|
||||
|
|
|
|||
|
|
@ -749,6 +749,8 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex)
|
|||
return false;
|
||||
case 10258: // Awaken Vault Warder
|
||||
case 18153: // Kodo Kombobulator
|
||||
case 32312: // Move 1
|
||||
case 37388: // Move 2
|
||||
case 49634: // Sergeant's Flare
|
||||
case 54530: // Opening
|
||||
case 62105: // To'kini's Blowgun
|
||||
|
|
@ -757,6 +759,18 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case SPELL_EFFECT_SCRIPT_EFFECT:
|
||||
// some explicitly required script effect sets
|
||||
switch (spellproto->Id)
|
||||
{
|
||||
case 46650: // Open Brutallus Back Door
|
||||
case 62488: // Activate Construct
|
||||
case 64503: // Water
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// always positive effects (check before target checks that provided non-positive result in some case for positive effects)
|
||||
case SPELL_EFFECT_HEAL:
|
||||
case SPELL_EFFECT_LEARN_SPELL:
|
||||
|
|
@ -797,6 +811,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex)
|
|||
case 27202:
|
||||
case 27203:
|
||||
case 47669:
|
||||
case 64996: // Reorigination
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -2164,6 +2179,40 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
|
|||
(spellInfo_2->Id == 57598 && spellInfo_1->Id == 57560))
|
||||
return false;
|
||||
|
||||
// Shard of Flame and Mote of Flame
|
||||
if ((spellInfo_1->SpellIconID == 2302 && spellInfo_1->SpellVisual[0] == 0) ||
|
||||
(spellInfo_2->SpellIconID == 2302 && spellInfo_2->SpellVisual[0] == 0))
|
||||
return false;
|
||||
|
||||
// Felblaze Visual and Fog of Corruption
|
||||
if ((spellInfo_1->Id == 45068 && spellInfo_2->Id == 45582) ||
|
||||
(spellInfo_2->Id == 45068 && spellInfo_1->Id == 45582))
|
||||
return false;
|
||||
|
||||
// Simon Game START timer, (DND) and Simon Game Pre-game timer
|
||||
if ((spellInfo_1->Id == 39993 && spellInfo_2->Id == 40041) ||
|
||||
(spellInfo_2->Id == 39993 && spellInfo_1->Id == 40041))
|
||||
return false;
|
||||
|
||||
// Karazhan - Chess: Is Square OCCUPIED aura Karazhan - Chess: Create Move Marker
|
||||
if ((spellInfo_1->Id == 39400 && spellInfo_2->Id == 32261) ||
|
||||
(spellInfo_2->Id == 39400 && spellInfo_1->Id == 32261))
|
||||
return false;
|
||||
|
||||
// Black Hole (damage) and Black Hole (phase)
|
||||
if ((spellInfo_1->Id == 62169 && spellInfo_2->Id == 62168) ||
|
||||
(spellInfo_2->Id == 62169 && spellInfo_1->Id == 62168))
|
||||
return false;
|
||||
|
||||
// Black Hole (damage) and Worm Hole (phase)
|
||||
if ((spellInfo_1->Id == 62169 && spellInfo_2->Id == 65250) ||
|
||||
(spellInfo_2->Id == 62169 && spellInfo_1->Id == 65250))
|
||||
return false;
|
||||
|
||||
// Black Hole (damage) and Phase Punch (phase)
|
||||
if ((spellInfo_1->Id == 62169 && spellInfo_2->Id == 64417) ||
|
||||
(spellInfo_2->Id == 62169 && spellInfo_1->Id == 64417))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_MAGE:
|
||||
|
|
|
|||
|
|
@ -43,23 +43,23 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T& owner, bool up
|
|||
// Can happen for example if no path was created on MMGen-Initialize because of the owner being stunned
|
||||
if (updateDestination || !i_path)
|
||||
{
|
||||
owner.GetPosition(x, y, z);
|
||||
|
||||
// prevent redundant micro-movement for pets, other followers.
|
||||
if (i_offset && i_target->IsWithinDistInMap(&owner, 2 * i_offset))
|
||||
if (!RequiresNewPosition(owner, x, y, z))
|
||||
{
|
||||
if (!owner.movespline->Finalized())
|
||||
return;
|
||||
|
||||
owner.GetPosition(x, y, z);
|
||||
}
|
||||
else if (!i_offset)
|
||||
// Chase Movement and angle == 0 case: Chase to current angle
|
||||
else if (this->GetMovementGeneratorType() == CHASE_MOTION_TYPE && i_angle == 0.0f)
|
||||
{
|
||||
// to nearest contact position
|
||||
i_target->GetContactPoint(&owner, x, y, z);
|
||||
i_target->GetNearPoint(&owner, x, y, z, owner.GetObjectBoundingRadius(), this->GetDynamicTargetDistance(owner, false), i_target->GetAngle(&owner));
|
||||
}
|
||||
// Targeted movement to at i_offset distance from target and i_angle from target facing
|
||||
else
|
||||
{
|
||||
// to at i_offset distance from target and i_angle from target facing
|
||||
i_target->GetClosePoint(x, y, z, owner.GetObjectBoundingRadius(), i_offset, i_angle, &owner);
|
||||
i_target->GetNearPoint(&owner, x, y, z, owner.GetObjectBoundingRadius(), this->GetDynamicTargetDistance(owner, false), i_target->GetOrientation() + i_angle);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -131,16 +131,10 @@ bool TargetedMovementGeneratorMedium<T, D>::Update(T& owner, const uint32& time_
|
|||
i_recheckDistance.Update(time_diff);
|
||||
if (i_recheckDistance.Passed())
|
||||
{
|
||||
i_recheckDistance.Reset(100);
|
||||
|
||||
// More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
float allowed_dist = owner.GetObjectBoundingRadius() + sWorld.getConfig(CONFIG_FLOAT_RATE_TARGET_POS_RECALCULATION_RANGE);
|
||||
i_recheckDistance.Reset(this->GetMovementGeneratorType() == FOLLOW_MOTION_TYPE ? 50 : 100);
|
||||
G3D::Vector3 dest = owner.movespline->FinalDestination();
|
||||
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->CanFly())
|
||||
targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist);
|
||||
else
|
||||
targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist);
|
||||
targetMoved = RequiresNewPosition(owner, dest.x, dest.y, dest.z);
|
||||
}
|
||||
|
||||
if (m_speedChanged || targetMoved)
|
||||
|
|
@ -166,6 +160,15 @@ bool TargetedMovementGeneratorMedium<T, D>::IsReachable() const
|
|||
return (i_path) ? (i_path->getPathType() & PATHFIND_NORMAL) : true;
|
||||
}
|
||||
|
||||
template<class T, typename D>
|
||||
bool TargetedMovementGeneratorMedium<T, D>::RequiresNewPosition(T& owner, float x, float y, float z) const
|
||||
{
|
||||
// More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->CanFly())
|
||||
return !i_target->IsWithinDist3d(x, y, z, this->GetDynamicTargetDistance(owner, true));
|
||||
else
|
||||
return !i_target->IsWithinDist2d(x, y, this->GetDynamicTargetDistance(owner, true));
|
||||
}
|
||||
|
||||
//-----------------------------------------------//
|
||||
template<class T>
|
||||
|
|
@ -220,6 +223,19 @@ void ChaseMovementGenerator<T>::Reset(T& owner)
|
|||
Initialize(owner);
|
||||
}
|
||||
|
||||
// Chase-Movement: These factors depend on combat-reach distance
|
||||
#define CHASE_DEFAULT_RANGE_FACTOR 0.5f
|
||||
#define CHASE_RECHASE_RANGE_FACTOR 0.75f
|
||||
|
||||
template<class T>
|
||||
float ChaseMovementGenerator<T>::GetDynamicTargetDistance(T& owner, bool forRangeCheck) const
|
||||
{
|
||||
if (!forRangeCheck)
|
||||
return this->i_offset + CHASE_DEFAULT_RANGE_FACTOR * this->i_target->GetCombatReach(&owner);
|
||||
|
||||
return CHASE_RECHASE_RANGE_FACTOR * this->i_target->GetCombatReach(&owner) - this->i_target->GetObjectBoundingRadius();
|
||||
}
|
||||
|
||||
//-----------------------------------------------//
|
||||
template<class T>
|
||||
void FollowMovementGenerator<T>::_clearUnitStateMove(T& u) { u.clearUnitState(UNIT_STAT_FOLLOW_MOVE); }
|
||||
|
|
@ -293,6 +309,28 @@ void FollowMovementGenerator<T>::Reset(T& owner)
|
|||
Initialize(owner);
|
||||
}
|
||||
|
||||
// This factor defines how much of the bounding-radius (as measurement of size) will be used for recalculating a new following position
|
||||
// The smaller, the more micro movement, the bigger, possibly no proper movement updates
|
||||
#define FOLLOW_RECALCULATE_FACTOR 0.1f
|
||||
// This factor defines when the distance of a follower will have impact onto following-position updates
|
||||
#define FOLLOW_DIST_GAP_FOR_DIST_FACTOR 3.0f
|
||||
// This factor defines how much of the follow-distance will be used as sloppyness value (if the above distance is exceeded)
|
||||
#define FOLLOW_DIST_RECALCULATE_FACTOR 0.1f
|
||||
|
||||
template<class T>
|
||||
float FollowMovementGenerator<T>::GetDynamicTargetDistance(T& owner, bool forRangeCheck) const
|
||||
{
|
||||
if (!forRangeCheck)
|
||||
return this->i_offset + owner.GetObjectBoundingRadius() + this->i_target->GetObjectBoundingRadius();
|
||||
|
||||
float allowed_dist = sWorld.getConfig(CONFIG_FLOAT_RATE_TARGET_POS_RECALCULATION_RANGE) - this->i_target->GetObjectBoundingRadius();
|
||||
allowed_dist += FOLLOW_RECALCULATE_FACTOR * (owner.GetObjectBoundingRadius() + this->i_target->GetObjectBoundingRadius());
|
||||
if (this->i_offset > FOLLOW_DIST_GAP_FOR_DIST_FACTOR)
|
||||
allowed_dist += FOLLOW_DIST_RECALCULATE_FACTOR * this->i_offset;
|
||||
|
||||
return allowed_dist;
|
||||
}
|
||||
|
||||
//-----------------------------------------------//
|
||||
template void TargetedMovementGeneratorMedium<Player, ChaseMovementGenerator<Player> >::_setTargetLocation(Player&, bool);
|
||||
template void TargetedMovementGeneratorMedium<Player, FollowMovementGenerator<Player> >::_setTargetLocation(Player&, bool);
|
||||
|
|
@ -319,6 +357,8 @@ template void ChaseMovementGenerator<Player>::Interrupt(Player&);
|
|||
template void ChaseMovementGenerator<Creature>::Interrupt(Creature&);
|
||||
template void ChaseMovementGenerator<Player>::Reset(Player&);
|
||||
template void ChaseMovementGenerator<Creature>::Reset(Creature&);
|
||||
template float ChaseMovementGenerator<Creature>::GetDynamicTargetDistance(Creature&, bool) const;
|
||||
template float ChaseMovementGenerator<Player>::GetDynamicTargetDistance(Player&, bool) const;
|
||||
|
||||
template void FollowMovementGenerator<Player>::_clearUnitStateMove(Player& u);
|
||||
template void FollowMovementGenerator<Creature>::_addUnitStateMove(Creature& u);
|
||||
|
|
@ -328,3 +368,5 @@ template void FollowMovementGenerator<Player>::Interrupt(Player&);
|
|||
template void FollowMovementGenerator<Creature>::Interrupt(Creature&);
|
||||
template void FollowMovementGenerator<Player>::Reset(Player&);
|
||||
template void FollowMovementGenerator<Creature>::Reset(Creature&);
|
||||
template float FollowMovementGenerator<Creature>::GetDynamicTargetDistance(Creature&, bool) const;
|
||||
template float FollowMovementGenerator<Player>::GetDynamicTargetDistance(Player&, bool) const;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ class MANGOS_DLL_SPEC TargetedMovementGeneratorMedium
|
|||
|
||||
protected:
|
||||
void _setTargetLocation(T&, bool updateDestination);
|
||||
bool RequiresNewPosition(T& owner, float x, float y, float z) const;
|
||||
virtual float GetDynamicTargetDistance(T& owner, bool forRangeCheck) const { return i_offset; }
|
||||
|
||||
ShortTimeTracker i_recheckDistance;
|
||||
float i_offset;
|
||||
|
|
@ -73,8 +75,6 @@ template<class T>
|
|||
class MANGOS_DLL_SPEC ChaseMovementGenerator : public TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >
|
||||
{
|
||||
public:
|
||||
ChaseMovementGenerator(Unit& target)
|
||||
: TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >(target) {}
|
||||
ChaseMovementGenerator(Unit& target, float offset, float angle)
|
||||
: TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >(target, offset, angle) {}
|
||||
~ChaseMovementGenerator() {}
|
||||
|
|
@ -91,6 +91,9 @@ class MANGOS_DLL_SPEC ChaseMovementGenerator : public TargetedMovementGeneratorM
|
|||
bool EnableWalking() const { return false;}
|
||||
bool _lostTarget(T& u) const;
|
||||
void _reachTarget(T&);
|
||||
|
||||
protected:
|
||||
float GetDynamicTargetDistance(T& owner, bool forRangeCheck) const override;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
|
@ -115,8 +118,12 @@ class MANGOS_DLL_SPEC FollowMovementGenerator : public TargetedMovementGenerator
|
|||
bool EnableWalking() const;
|
||||
bool _lostTarget(T&) const { return false; }
|
||||
void _reachTarget(T&) {}
|
||||
|
||||
private:
|
||||
void _updateSpeed(T& u);
|
||||
|
||||
protected:
|
||||
float GetDynamicTargetDistance(T& owner, bool forRangeCheck) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ class MANGOS_DLL_SPEC ThreatContainer
|
|||
|
||||
bool isDirty() const { return iDirty; }
|
||||
|
||||
bool empty() const { return(iThreatList.empty()); }
|
||||
bool empty() const { return iThreatList.empty(); }
|
||||
|
||||
HostileReference* getMostHated() { return iThreatList.empty() ? NULL : iThreatList.front(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
#include "movement/MoveSplineInit.h"
|
||||
#include "movement/MoveSpline.h"
|
||||
#include "CreatureLinkingMgr.h"
|
||||
#include "MovementStructures.h"
|
||||
#include "movement/MovementStructures.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
|
@ -5170,7 +5170,7 @@ void Unit::RemoveAllAurasOnEvade()
|
|||
for (SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();)
|
||||
{
|
||||
SpellEntry const* proto = iter->second->GetSpellProto();
|
||||
if (!IsSpellHaveAura(proto, SPELL_AURA_CONTROL_VEHICLE))
|
||||
if (!IsSpellHaveAura(proto, SPELL_AURA_CONTROL_VEHICLE) && !IsSpellHaveAura(proto, SPELL_AURA_FLY))
|
||||
{
|
||||
RemoveSpellAuraHolder(iter->second, AURA_REMOVE_BY_DEFAULT);
|
||||
iter = m_spellAuraHolders.begin();
|
||||
|
|
@ -6620,6 +6620,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u
|
|||
return owner->SpellDamageBonusDone(pVictim, spellProto, pdamage, damagetype);
|
||||
}
|
||||
|
||||
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
|
||||
float DoneTotalMod = 1.0f;
|
||||
int32 DoneTotal = 0;
|
||||
|
||||
|
|
@ -6641,20 +6642,14 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u
|
|||
}
|
||||
}
|
||||
|
||||
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
|
||||
// Add flat bonus from spell damage versus
|
||||
DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
|
||||
AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
|
||||
for (AuraList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i)
|
||||
if (creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
|
||||
DoneTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
|
||||
|
||||
AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
|
||||
for (AuraList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i)
|
||||
{
|
||||
if (creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
|
||||
DoneTotalMod += ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
|
||||
}
|
||||
// Add pct bonus from spell damage versus
|
||||
DoneTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS, creatureTypeMask);
|
||||
|
||||
// Add flat bonus from spell damage creature
|
||||
DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE, creatureTypeMask);
|
||||
|
||||
if (getPowerType() == POWER_MANA)
|
||||
{
|
||||
|
|
@ -6672,7 +6667,9 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u
|
|||
|
||||
// done scripted mod (take it from owner)
|
||||
Unit* owner = GetOwner();
|
||||
if (!owner) owner = this;
|
||||
if (!owner)
|
||||
owner = this;
|
||||
|
||||
AuraList const& mOverrideClassScript = owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
|
||||
for (AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -518,8 +518,6 @@ enum UnitMoveType
|
|||
|
||||
#define MAX_MOVE_TYPE 9
|
||||
|
||||
extern float baseMoveSpeed[MAX_MOVE_TYPE];
|
||||
|
||||
enum CombatRating
|
||||
{
|
||||
CR_WEAPON_SKILL = 0,
|
||||
|
|
|
|||
|
|
@ -2883,6 +2883,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
switch (auraSpellInfo->GetSpellFamilyName())
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
{
|
||||
switch (auraSpellInfo->Id)
|
||||
{
|
||||
// case 191: // Elemental Response
|
||||
|
|
@ -3067,7 +3068,9 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_MAGE:
|
||||
{
|
||||
if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed
|
||||
{
|
||||
switch (auraSpellInfo->Id)
|
||||
|
|
@ -3096,7 +3099,9 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
return SPELL_AURA_PROC_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
{
|
||||
// Deep Wounds (replace triggered spells to directly apply DoT), dot spell have familyflags
|
||||
if (auraClassOptions && auraClassOptions->SpellFamilyFlags == UI64LIT(0x0) && auraSpellInfo->SpellIconID == 243)
|
||||
{
|
||||
|
|
@ -3110,9 +3115,9 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
|
||||
switch (auraSpellInfo->Id)
|
||||
{
|
||||
case 12834: basepoints[0] = int32(weaponDamage * 16 / 100); break;
|
||||
case 12849: basepoints[0] = int32(weaponDamage * 32 / 100); break;
|
||||
case 12867: basepoints[0] = int32(weaponDamage * 48 / 100); break;
|
||||
case 12834: basepoints[EFFECT_INDEX_0] = int32(weaponDamage * 16 / 100); break;
|
||||
case 12849: basepoints[EFFECT_INDEX_0] = int32(weaponDamage * 32 / 100); break;
|
||||
case 12867: basepoints[EFFECT_INDEX_0] = int32(weaponDamage * 48 / 100); break;
|
||||
// Impossible case
|
||||
default:
|
||||
sLog.outError("Unit::HandleProcTriggerSpellAuraProc: DW unknown spell rank %u", auraSpellInfo->Id);
|
||||
|
|
@ -3120,7 +3125,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
}
|
||||
|
||||
// 1 tick/sec * 6 sec = 6 ticks
|
||||
basepoints[0] /= 6;
|
||||
basepoints[EFFECT_INDEX_0] /= 6;
|
||||
|
||||
trigger_spell_id = 12721;
|
||||
break;
|
||||
|
|
@ -3132,8 +3137,14 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
return SPELL_AURA_PROC_FAILED;
|
||||
}
|
||||
else if (auraSpellInfo->Id == 50421) // Scent of Blood
|
||||
{
|
||||
RemoveAuraHolderFromStack(50421);
|
||||
trigger_spell_id = 50422;
|
||||
target = this;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
{
|
||||
// Drain Soul
|
||||
|
|
@ -3169,14 +3180,13 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
return SPELL_AURA_PROC_FAILED;
|
||||
switch (GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
|
||||
{
|
||||
case SPELL_SCHOOL_NORMAL:
|
||||
return SPELL_AURA_PROC_FAILED; // ignore
|
||||
case SPELL_SCHOOL_HOLY: trigger_spell_id = 54370; break;
|
||||
case SPELL_SCHOOL_FIRE: trigger_spell_id = 54371; break;
|
||||
case SPELL_SCHOOL_NATURE: trigger_spell_id = 54375; break;
|
||||
case SPELL_SCHOOL_FROST: trigger_spell_id = 54372; break;
|
||||
case SPELL_SCHOOL_SHADOW: trigger_spell_id = 54374; break;
|
||||
case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break;
|
||||
case SPELL_SCHOOL_NORMAL: // ignore
|
||||
default:
|
||||
return SPELL_AURA_PROC_FAILED;
|
||||
}
|
||||
|
|
@ -3417,6 +3427,29 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
trigger_spell_id = 54843;
|
||||
target = pVictim;
|
||||
}
|
||||
// Item - Coliseum 25 Normal and Heroic Caster Trinket
|
||||
else if (auraSpellInfo->Id == 67712 || auraSpellInfo->Id == 67758)
|
||||
{
|
||||
if (!pVictim || !pVictim->isAlive())
|
||||
return SPELL_AURA_PROC_FAILED;
|
||||
|
||||
uint32 castSpell = auraSpellInfo->Id == 67758 ? 67759 : 67713;
|
||||
|
||||
// stacking
|
||||
CastSpell(this, castSpell, true, NULL, triggeredByAura);
|
||||
|
||||
// counting
|
||||
Aura* dummy = GetDummyAura(castSpell);
|
||||
|
||||
// release at 3 aura in stack (count contained in basepoint of trigger aura)
|
||||
if (!dummy || dummy->GetStackAmount() < uint32(triggerAmount))
|
||||
return SPELL_AURA_PROC_FAILED;
|
||||
|
||||
RemoveAurasDueToSpell(castSpell);
|
||||
trigger_spell_id = castSpell + 1;
|
||||
target = pVictim;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
|
|
@ -3530,6 +3563,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
// All ok. Check current trigger spell
|
||||
SpellEntry const* triggerEntry = sSpellStore.LookupEntry(trigger_spell_id);
|
||||
if (!triggerEntry)
|
||||
|
|
|
|||
|
|
@ -718,7 +718,6 @@ void World::LoadConfigSettings(bool reload)
|
|||
|
||||
setConfig(CONFIG_UINT32_WORLD_BOSS_LEVEL_DIFF, "WorldBossLevelDiff", 3);
|
||||
|
||||
// note: disable value (-1) will assigned as 0xFFFFFFF, to prevent overflow at calculations limit it to max possible player level MAX_LEVEL(100)
|
||||
setConfigMinMax(CONFIG_INT32_QUEST_LOW_LEVEL_HIDE_DIFF, "Quests.LowLevelHideDiff", 4, -1, MAX_LEVEL);
|
||||
setConfigMinMax(CONFIG_INT32_QUEST_HIGH_LEVEL_HIDE_DIFF, "Quests.HighLevelHideDiff", 7, -1, MAX_LEVEL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* This code is part of MaNGOS. Contributor & Copyright details are in AUTHORS/THANKS.
|
||||
* This file is part of the MaNGOS Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* 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
|
||||
|
|
@ -82,9 +82,9 @@ namespace VMAP
|
|||
*/
|
||||
void setEnableHeightCalc(bool pVal) { iEnableHeightCalc = pVal; }
|
||||
|
||||
bool isLineOfSightCalcEnabled() const { return(iEnableLineOfSightCalc); }
|
||||
bool isHeightCalcEnabled() const { return(iEnableHeightCalc); }
|
||||
bool isMapLoadingEnabled() const { return(iEnableLineOfSightCalc || iEnableHeightCalc); }
|
||||
bool isLineOfSightCalcEnabled() const { return iEnableLineOfSightCalc; }
|
||||
bool isHeightCalcEnabled() const { return iEnableHeightCalc; }
|
||||
bool isMapLoadingEnabled() const { return iEnableLineOfSightCalc || iEnableHeightCalc; }
|
||||
|
||||
virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0;
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ namespace VMAP
|
|||
{
|
||||
height = pPos.z - maxDist;
|
||||
}
|
||||
return(height);
|
||||
return height;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace VMAP
|
|||
{
|
||||
Vector3 out = pIn * iScale;
|
||||
out = iRotation * out;
|
||||
return(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ namespace VMAP
|
|||
pId = atoi(idString.c_str());
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
//===============================================
|
||||
|
|
@ -106,7 +106,7 @@ namespace VMAP
|
|||
|
||||
bool VMapFactory::checkSpellForLoS(unsigned int pSpellId)
|
||||
{
|
||||
return(!iIgnoreSpellIds->containsKey(pSpellId));
|
||||
return !iIgnoreSpellIds->containsKey(pSpellId);
|
||||
}
|
||||
|
||||
//===============================================
|
||||
|
|
|
|||
|
|
@ -480,7 +480,12 @@ bool ChatHandler::HandleAccountCreateCommand(char* args)
|
|||
std::string account_name = szAcc;
|
||||
std::string password = szPassword;
|
||||
|
||||
AccountOpResult result = sAccountMgr.CreateAccount(account_name, password);
|
||||
AccountOpResult result;
|
||||
uint32 expansion = 0;
|
||||
if(ExtractUInt32(&args, expansion))
|
||||
result = sAccountMgr.CreateAccount(account_name, password, expansion);
|
||||
else
|
||||
result = sAccountMgr.CreateAccount(account_name, password);
|
||||
switch (result)
|
||||
{
|
||||
case AOR_OK:
|
||||
|
|
|
|||
|
|
@ -1,22 +1,6 @@
|
|||
# This code is part of MaNGOS. Contributor & Copyright details are in AUTHORS/THANKS.
|
||||
#
|
||||
# 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
set(LIBRARY_NAME shared)
|
||||
|
||||
set(LIBRARY_SRCS
|
||||
set(SRC_GRP_AUTH
|
||||
Auth/AuthCrypt.cpp
|
||||
Auth/AuthCrypt.h
|
||||
Auth/BigNumber.cpp
|
||||
|
|
@ -28,12 +12,14 @@ set(LIBRARY_SRCS
|
|||
Auth/SARC4.h
|
||||
Auth/Sha1.cpp
|
||||
Auth/Sha1.h
|
||||
ByteBuffer.cpp
|
||||
ByteBuffer.h
|
||||
Common.cpp
|
||||
Common.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_CONFIG
|
||||
Config/Config.cpp
|
||||
Config/Config.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_DATABASE
|
||||
Database/Database.cpp
|
||||
Database/Database.h
|
||||
Database/DatabaseEnv.h
|
||||
|
|
@ -42,12 +28,6 @@ set(LIBRARY_SRCS
|
|||
Database/DatabaseMysql.h
|
||||
Database/DatabasePostgre.cpp
|
||||
Database/DatabasePostgre.h
|
||||
Database/DB2FileLoader.cpp
|
||||
Database/DB2FileLoader.h
|
||||
Database/DB2Store.h
|
||||
Database/DBCFileLoader.cpp
|
||||
Database/DBCFileLoader.h
|
||||
Database/DBCStore.h
|
||||
Database/Field.cpp
|
||||
Database/Field.h
|
||||
Database/PGSQLDelayThread.h
|
||||
|
|
@ -65,21 +45,82 @@ set(LIBRARY_SRCS
|
|||
Database/SQLStorage.cpp
|
||||
Database/SQLStorage.h
|
||||
Database/SQLStorageImpl.h
|
||||
Errors.h
|
||||
LockedQueue.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_DATABASE_DBC
|
||||
Database/DB2FileLoader.cpp
|
||||
Database/DB2FileLoader.h
|
||||
Database/DB2Store.h
|
||||
Database/DBCFileLoader.cpp
|
||||
Database/DBCFileLoader.h
|
||||
Database/DBCStore.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_LOG
|
||||
Log.cpp
|
||||
Log.h
|
||||
)
|
||||
|
||||
set(SRC_GRP_UTIL
|
||||
ByteBuffer.cpp
|
||||
ByteBuffer.h
|
||||
Errors.h
|
||||
# dep/include/mersennetwister/MersenneTwister.h is part of this group in the VC 2012 file but it is not part of src/shared, so it is omitted here
|
||||
ProgressBar.cpp
|
||||
ProgressBar.h
|
||||
Timer.h
|
||||
Util.cpp
|
||||
Util.h
|
||||
WorldPacket.h
|
||||
)
|
||||
|
||||
|
||||
set(LIBRARY_SRCS
|
||||
${SRC_GRP_AUTH}
|
||||
${SRC_GRP_CONFIG}
|
||||
${SRC_GRP_DATABASE}
|
||||
${SRC_GRP_DATABASE_DBC}
|
||||
${SRC_GRP_LOG}
|
||||
${SRC_GRP_UTIL}
|
||||
Common.cpp
|
||||
Common.h
|
||||
LockedQueue.h
|
||||
revision_nr.h
|
||||
revision_sql.h
|
||||
SystemConfig.h
|
||||
Threading.cpp
|
||||
Threading.h
|
||||
Timer.h
|
||||
Util.cpp
|
||||
Util.h
|
||||
WorldPacket.h
|
||||
)
|
||||
|
||||
|
||||
source_group("Auth"
|
||||
FILES
|
||||
${SRC_GRP_AUTH}
|
||||
)
|
||||
|
||||
source_group("Config"
|
||||
FILES
|
||||
${SRC_GRP_CONFIG}
|
||||
)
|
||||
|
||||
source_group("Database"
|
||||
FILES
|
||||
${SRC_GRP_DATABASE}
|
||||
)
|
||||
|
||||
source_group("Database\\DataStores"
|
||||
FILES
|
||||
${SRC_GRP_DATABASE_DBC}
|
||||
)
|
||||
|
||||
source_group("Log"
|
||||
FILES
|
||||
${SRC_GRP_LOG}
|
||||
)
|
||||
|
||||
source_group("Util"
|
||||
FILES
|
||||
${SRC_GRP_UTIL}
|
||||
)
|
||||
|
||||
# OS specific files
|
||||
|
|
@ -99,29 +140,6 @@ else()
|
|||
)
|
||||
endif()
|
||||
|
||||
source_group("Util"
|
||||
REGULAR_EXPRESSION .*
|
||||
)
|
||||
|
||||
# TODO: really needed?
|
||||
foreach(SRC ${LIBRARY_SRCS})
|
||||
get_filename_component(PTH ${SRC} PATH)
|
||||
if(PTH)
|
||||
if(NOT XCODE) # FIXME: Xcode Generator has bug with nested dirs
|
||||
string(REPLACE "/" "\\\\" PTH ${PTH})
|
||||
endif()
|
||||
source_group(${PTH} FILES ${SRC})
|
||||
endif()
|
||||
endforeach(SRC)
|
||||
|
||||
source_group("DataStores"
|
||||
REGULAR_EXPRESSION DBC
|
||||
)
|
||||
|
||||
source_group("Log"
|
||||
REGULAR_EXPRESSION Log
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/include
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_12697_01_characters_characters"
|
||||
#define REVISION_DB_MANGOS "required_12662_01_mangos_hotfix_data"
|
||||
#define REVISION_DB_CHARACTERS "required_12774_01_characters_characters"
|
||||
#define REVISION_DB_MANGOS "required_12774_01_mangos"
|
||||
#define REVISION_DB_REALMD "required_c12484_02_realmd_account_access"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue