Merge branch 'master' of git@github.com:mangos/mangos.git into procflag

This commit is contained in:
DiSlord 2008-12-12 01:34:09 +03:00
commit 6c02f00a93
115 changed files with 3209 additions and 1482 deletions

View file

@ -17,3 +17,4 @@
debug debug
release release
*.user *.user
*.ilk

View file

@ -39,7 +39,7 @@ enum Extract
}; };
int extract = EXTRACT_MAP | EXTRACT_DBC; int extract = EXTRACT_MAP | EXTRACT_DBC;
static char* const langs[]={"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; static char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
#define LANG_COUNT 12 #define LANG_COUNT 12
#define ADT_RES 64 #define ADT_RES 64
@ -55,9 +55,9 @@ void CreateDir( const std::string& Path )
bool FileExists( const char* FileName ) bool FileExists( const char* FileName )
{ {
if( FILE* fp = fopen( FileName, "rb" ) ) if(FILE* fp = fopen( FileName, "rb" ))
{ {
fclose( fp ); fclose(fp);
return true; return true;
} }
@ -222,15 +222,15 @@ void ExtractDBCFiles(int locale, bool basicLocale)
string filename = path; string filename = path;
filename += (iter->c_str() + strlen("DBFilesClient\\")); filename += (iter->c_str() + strlen("DBFilesClient\\"));
FILE *output=fopen(filename.c_str(),"wb"); FILE *output=fopen(filename.c_str(), "wb");
if(!output) if(!output)
{ {
printf("Can't create the output file '%s'\n",filename.c_str()); printf("Can't create the output file '%s'\n", filename.c_str());
continue; continue;
} }
MPQFile m(iter->c_str()); MPQFile m(iter->c_str());
if(!m.isEof()) if(!m.isEof())
fwrite(m.getPointer(),1,m.getSize(),output); fwrite(m.getPointer(), 1, m.getSize(), output);
fclose(output); fclose(output);
++count; ++count;
@ -242,7 +242,7 @@ void LoadLocaleMPQFiles(int const locale)
{ {
char filename[512]; char filename[512];
sprintf(filename,"%s/Data/%s/locale-%s.MPQ",input_path,langs[locale],langs[locale]); sprintf(filename,"%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]);
new MPQArchive(filename); new MPQArchive(filename);
for(int i = 1; i < 5; ++i) for(int i = 1; i < 5; ++i)
@ -251,7 +251,7 @@ void LoadLocaleMPQFiles(int const locale)
if(i > 1) if(i > 1)
sprintf(ext, "-%i", i); sprintf(ext, "-%i", i);
sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ",input_path,langs[locale],langs[locale],ext); sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ", input_path, langs[locale], langs[locale], ext);
if(FileExists(filename)) if(FileExists(filename))
new MPQArchive(filename); new MPQArchive(filename);
} }
@ -261,9 +261,9 @@ void LoadCommonMPQFiles()
{ {
char filename[512]; char filename[512];
sprintf(filename,"%s/Data/common.MPQ",input_path); sprintf(filename,"%s/Data/common.MPQ", input_path);
new MPQArchive(filename); new MPQArchive(filename);
sprintf(filename,"%s/Data/expansion.MPQ",input_path); sprintf(filename,"%s/Data/expansion.MPQ", input_path);
new MPQArchive(filename); new MPQArchive(filename);
for(int i = 1; i < 5; ++i) for(int i = 1; i < 5; ++i)
@ -272,7 +272,7 @@ void LoadCommonMPQFiles()
if(i > 1) if(i > 1)
sprintf(ext, "-%i", i); sprintf(ext, "-%i", i);
sprintf(filename,"%s/Data/patch%s.MPQ",input_path,ext); sprintf(filename,"%s/Data/patch%s.MPQ", input_path, ext);
if(FileExists(filename)) if(FileExists(filename))
new MPQArchive(filename); new MPQArchive(filename);
} }
@ -306,12 +306,12 @@ int main(int argc, char * arg[])
if((extract & EXTRACT_DBC) == 0) if((extract & EXTRACT_DBC) == 0)
{ {
FirstLocale=i; FirstLocale = i;
break; break;
} }
//Extract DBC files //Extract DBC files
if(FirstLocale<0) if(FirstLocale < 0)
{ {
ExtractDBCFiles(i, true); ExtractDBCFiles(i, true);
FirstLocale = i; FirstLocale = i;
@ -324,7 +324,7 @@ int main(int argc, char * arg[])
} }
} }
if(FirstLocale<0) if(FirstLocale < 0)
{ {
printf("No locales detected\n"); printf("No locales detected\n");
return 0; return 0;

View file

@ -76,7 +76,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zlib.lib" AdditionalDependencies="zlib.lib"
OutputFile="ad debug.exe" OutputFile="ad debug.exe"
LinkIncremental="1" LinkIncremental="0"
SuppressStartupBanner="true" SuppressStartupBanner="true"
AdditionalLibraryDirectories="./debug/" AdditionalLibraryDirectories="./debug/"
IgnoreDefaultLibraryNames="LIBCD.lib" IgnoreDefaultLibraryNames="LIBCD.lib"
@ -171,7 +171,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zlib.lib" AdditionalDependencies="zlib.lib"
OutputFile="./ad.exe" OutputFile="./ad.exe"
LinkIncremental="1" LinkIncremental="0"
SuppressStartupBanner="true" SuppressStartupBanner="true"
AdditionalLibraryDirectories="./release/" AdditionalLibraryDirectories="./release/"
IgnoreDefaultLibraryNames="LIBC.lib" IgnoreDefaultLibraryNames="LIBC.lib"

View file

@ -79,7 +79,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zlib.lib" AdditionalDependencies="zlib.lib"
OutputFile="ad debug.exe" OutputFile="ad debug.exe"
LinkIncremental="1" LinkIncremental="0"
SuppressStartupBanner="true" SuppressStartupBanner="true"
AdditionalLibraryDirectories="./debug" AdditionalLibraryDirectories="./debug"
IgnoreDefaultLibraryNames="LIBCD.lib" IgnoreDefaultLibraryNames="LIBCD.lib"
@ -176,7 +176,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zlib.lib" AdditionalDependencies="zlib.lib"
OutputFile="./ad.exe" OutputFile="./ad.exe"
LinkIncremental="1" LinkIncremental="0"
SuppressStartupBanner="true" SuppressStartupBanner="true"
AdditionalLibraryDirectories="./release" AdditionalLibraryDirectories="./release"
IgnoreDefaultLibraryNames="LIBC.lib" IgnoreDefaultLibraryNames="LIBC.lib"

View file

@ -80,7 +80,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zlib.lib" AdditionalDependencies="zlib.lib"
OutputFile="ad debug.exe" OutputFile="ad debug.exe"
LinkIncremental="1" LinkIncremental="0"
SuppressStartupBanner="true" SuppressStartupBanner="true"
AdditionalLibraryDirectories="./debug/" AdditionalLibraryDirectories="./debug/"
IgnoreDefaultLibraryNames="LIBCD.lib" IgnoreDefaultLibraryNames="LIBCD.lib"
@ -175,7 +175,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zlib.lib" AdditionalDependencies="zlib.lib"
OutputFile="./ad.exe" OutputFile="./ad.exe"
LinkIncremental="1" LinkIncremental="0"
SuppressStartupBanner="true" SuppressStartupBanner="true"
AdditionalLibraryDirectories="./release/" AdditionalLibraryDirectories="./release/"
IgnoreDefaultLibraryNames="LIBC.lib" IgnoreDefaultLibraryNames="LIBC.lib"

Binary file not shown.

16
contrib/vmap_assembler/.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
#
# NOTE! Don't add files that are generated in specific
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
# NOTE! Please use 'git-ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# MaNGOS generated files at Windows build
#
*.ncb
*.suo
Release
Debug

13
contrib/vmap_assembler/VC71/.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
#
# NOTE! Don't add files that are generated in specific
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
# NOTE! Please use 'git-ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# MaNGOS generated files at Windows build
#
*.user

13
contrib/vmap_assembler/VC80/.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
#
# NOTE! Don't add files that are generated in specific
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
# NOTE! Please use 'git-ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# MaNGOS generated files at Windows build
#
*.user

13
contrib/vmap_assembler/VC90/.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
#
# NOTE! Don't add files that are generated in specific
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
# NOTE! Please use 'git-ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# MaNGOS generated files at Windows build
#
*.user

View file

@ -0,0 +1,455 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="vmap_assembler"
ProjectGUID="{572FFF74-480C-4472-8ABF-81733BB4049D}"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\Debug"
IntermediateDirectory="..\Debug\obj"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/vmap_assembler.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/vmap_assembler.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\Release"
IntermediateDirectory="..\Release\obj"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/vmap_assembler.exe"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\..\vmap_assembler.cpp"
>
</File>
</Filter>
<Filter
Name="vmaplib"
>
<File
RelativePath="..\..\..\src\shared\vmap\AABSPTree.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\BaseModel.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\BaseModel.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\CoordModelMapping.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\CoordModelMapping.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\DebugCmdLogger.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\DebugCmdLogger.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\ManagedModelContainer.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\ManagedModelContainer.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\ModelContainer.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\ModelContainer.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\NodeValueAccess.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\ShortBox.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\ShortVector.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\SubModel.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\SubModel.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\TileAssembler.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\TileAssembler.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\TreeNode.cpp"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\TreeNode.h"
>
</File>
<File
RelativePath="..\..\..\src\shared\vmap\VMapTools.h"
>
</File>
</Filter>
<Filter
Name="g3dlite"
>
<File
RelativePath="..\..\..\dep\src\g3dlite\AABox.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\AABox.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\AABSPTree.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Array.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\Box.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Box.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\CollisionDetection.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\CoordinateFrame.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\Crypto.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Crypto.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\debug.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\format.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\format.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\g3dmath.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\g3dmath.inl"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\GCamera.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Line.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\Matrix3.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Matrix3.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\Plane.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Plane.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\platform.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Quat.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Quat.inl"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Ray.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\RegistryUtil.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Sphere.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\stringutils.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\System.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\System.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Table.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\Triangle.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Triangle.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2.inl"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2int16.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\Vector3.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3.inl"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3int16.h"
>
</File>
<File
RelativePath="..\..\..\dep\src\g3dlite\Vector4.cpp"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector4.h"
>
</File>
<File
RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector4.inl"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmap_assembler", "VC90\vmap_assembler.vcproj", "{572FFF74-480C-4472-8ABF-81733BB4049D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.ActiveCfg = Debug|Win32
{572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.Build.0 = Debug|Win32
{572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.ActiveCfg = Release|Win32
{572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmapExtractor", "vmapExtractor_VC90.vcproj", "{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug Ansi Static|Win32 = Debug Ansi Static|Win32
Release Ansi Static|Win32 = Release Ansi Static|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Debug Ansi Static|Win32.ActiveCfg = Debug Ansi Static|Win32
{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Debug Ansi Static|Win32.Build.0 = Debug Ansi Static|Win32
{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Release Ansi Static|Win32.ActiveCfg = Release Ansi Static|Win32
{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Release Ansi Static|Win32.Build.0 = Release Ansi Static|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,999 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="vmapExtractor"
ProjectGUID="{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug Ansi Static|Win32"
OutputDirectory=".\bin\Win32\DebugAS"
IntermediateDirectory=".\bin\Win32\DebugAS"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\bin\StormLibTest\Win32\DebugAS/StormLibTest.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/wd 4996"
Optimization="0"
AdditionalIncludeDirectories=".\stormlib"
PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=""
AssemblerListingLocation=".\bin\Win32\DebugAS/"
ObjectFile=".\bin\Win32\DebugAS/"
ProgramDataBaseFileName=".\bin\Win32\DebugAS/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1029"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\bin\Win32\DebugAS\vmapextract_v2.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\bin\Win32\DebugAS/StormLib.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release Ansi Static|Win32"
OutputDirectory=".\bin\Win32\ReleaseAS"
IntermediateDirectory=".\bin\Win32\ReleaseAS"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\bin\StormLibTest\Win32\ReleaseAS/StormLibTest.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/wd 4996"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories=".\stormlib"
PreprocessorDefinitions="NDEBUG;_CONSOLE;WIN32"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=""
AssemblerListingLocation=".\bin\Win32\ReleaseAS/"
ObjectFile=".\bin\Win32\ReleaseAS/"
ProgramDataBaseFileName=".\bin\Win32\ReleaseAS/"
WarningLevel="4"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1029"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\bin\Win32\ReleaseAS\vmapextract_v2.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\bin\Win32\ReleaseAS/StormLib.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<Filter
Name="pklib"
>
<File
RelativePath="stormlib\pklib\crc32.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\pklib\explode.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\pklib\implode.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\pklib\pklib.h"
>
</File>
</Filter>
<Filter
Name="zlib"
>
<Filter
Name="Zlib Headers"
>
<File
RelativePath="stormlib\zlib\zconf.h"
>
</File>
<File
RelativePath="stormlib\zlib\zlib.h"
>
</File>
</Filter>
<Filter
Name="Zlib Sources"
>
<File
RelativePath="stormlib\zlib\adler32.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\deflate.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\infblock.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\infcodes.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\inffast.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\inflate.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\inftrees.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\infutil.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\trees.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\zlib\zmemory.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
<Filter
Name="huffman"
>
<File
RelativePath="stormlib\huffman\huff.cpp"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\huffman\huff.h"
>
</File>
</Filter>
<Filter
Name="wave"
>
<File
RelativePath="stormlib\wave\wave.cpp"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\wave\wave.h"
>
</File>
</Filter>
<Filter
Name="bzip2"
Filter="*.h;*.c"
>
<File
RelativePath="stormlib\bzip2\blocksort.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\bzip2\bzlib.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\bzip2\compress.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\bzip2\crctable.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\bzip2\decompress.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\bzip2\huffman.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="stormlib\bzip2\randtable.c"
>
<FileConfiguration
Name="Debug Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
WarningLevel="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Ansi Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
WarningLevel="3"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="vmap"
>
<File
RelativePath=".\vmapextract\adtfile.cpp"
>
</File>
<File
RelativePath=".\vmapextract\adtfile.h"
>
</File>
<File
RelativePath=".\vmapextract\dbcfile.cpp"
>
</File>
<File
RelativePath=".\vmapextract\dbcfile.h"
>
</File>
<File
RelativePath=".\vmapextract\model.cpp"
>
</File>
<File
RelativePath=".\vmapextract\model.h"
>
</File>
<File
RelativePath=".\vmapextract\modelheaders.h"
>
</File>
<File
RelativePath=".\vmapextract\mpq.cpp"
>
</File>
<File
RelativePath=".\vmapextract\mpq.h"
>
</File>
<File
RelativePath=".\vmapextract\vec3d.h"
>
</File>
<File
RelativePath=".\vmapextract\vmapexport.cpp"
>
</File>
<File
RelativePath=".\vmapextract\wdtfile.cpp"
>
</File>
<File
RelativePath=".\vmapextract\wdtfile.h"
>
</File>
<File
RelativePath=".\vmapextract\wmo.cpp"
>
</File>
<File
RelativePath=".\vmapextract\wmo.h"
>
</File>
</Filter>
<Filter
Name="stormlib"
>
<File
RelativePath=".\stormlib\SCommon.cpp"
>
</File>
<File
RelativePath=".\stormlib\SCommon.h"
>
</File>
<File
RelativePath=".\stormlib\SCompression.cpp"
>
</File>
<File
RelativePath=".\stormlib\SFileCompactArchive.cpp"
>
</File>
<File
RelativePath=".\stormlib\SFileCreateArchiveEx.cpp"
>
</File>
<File
RelativePath=".\stormlib\SFileExtractFile.cpp"
>
</File>
<File
RelativePath=".\stormlib\SFileFindFile.cpp"
>
</File>
<File
RelativePath=".\stormlib\SFileOpenArchive.cpp"
>
</File>
<File
RelativePath=".\stormlib\SFileOpenFileEx.cpp"
>
</File>
<File
RelativePath=".\stormlib\SFileReadFile.cpp"
>
</File>
<File
RelativePath=".\stormlib\SListFile.cpp"
>
</File>
<File
RelativePath=".\stormlib\StormDll.h"
>
</File>
<File
RelativePath=".\stormlib\StormLib.h"
>
</File>
<File
RelativePath=".\stormlib\StormPort.h"
>
</File>
<File
RelativePath=".\stormlib\StormPortLinux.cpp"
>
</File>
<File
RelativePath=".\stormlib\StormPortMac.cpp"
>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -86,8 +86,8 @@ public:
MTRand( const uint32& oneSeed ); // initialize with a simple uint32 MTRand( const uint32& oneSeed ); // initialize with a simple uint32
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
MTRand(); // auto-initialize with /dev/urandom or time() and clock() MTRand(); // auto-initialize with /dev/urandom or time() and clock()
MTRand(const MTRand&); // prevent copy constructor MTRand(const MTRand&); // prevent copy constructor
MTRand& operator=(const MTRand&); // no-op operator= MTRand& operator=(const MTRand&); // no-op operator=
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned // Do NOT use for CRYPTOGRAPHY without securely hashing several returned
// values together, otherwise the generator state can be learned after // values together, otherwise the generator state can be learned after

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`; DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` ( CREATE TABLE `character_db_version` (
`required_2008_11_12_01_character_character_aura` bit(1) default NULL `required_2008_12_03_01_character_guild_member` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
-- --
@ -249,6 +249,7 @@ CREATE TABLE `character_aura` (
`caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier',
`spell` int(11) unsigned NOT NULL default '0', `spell` int(11) unsigned NOT NULL default '0',
`effect_index` int(11) unsigned NOT NULL default '0', `effect_index` int(11) unsigned NOT NULL default '0',
`stackcount` int(11) NOT NULL default '1',
`amount` int(11) NOT NULL default '0', `amount` int(11) NOT NULL default '0',
`maxduration` int(11) NOT NULL default '0', `maxduration` int(11) NOT NULL default '0',
`remaintime` int(11) NOT NULL default '0', `remaintime` int(11) NOT NULL default '0',
@ -938,7 +939,7 @@ CREATE TABLE `guild_member` (
`BankRemSlotsTab5` int(11) unsigned NOT NULL default '0', `BankRemSlotsTab5` int(11) unsigned NOT NULL default '0',
KEY `guildid_key` (`guildid`), KEY `guildid_key` (`guildid`),
KEY `guildid_rank_key` (`guildid`,`rank`), KEY `guildid_rank_key` (`guildid`,`rank`),
KEY `guid_key` (`guid`) UNIQUE KEY `guid_key` (`guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Guild System'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Guild System';
-- --
@ -1125,6 +1126,7 @@ CREATE TABLE `pet_aura` (
`caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier',
`spell` int(11) unsigned NOT NULL default '0', `spell` int(11) unsigned NOT NULL default '0',
`effect_index` int(11) unsigned NOT NULL default '0', `effect_index` int(11) unsigned NOT NULL default '0',
`stackcount` int(11) NOT NULL default '1',
`amount` int(11) NOT NULL default '0', `amount` int(11) NOT NULL default '0',
`maxduration` int(11) NOT NULL default '0', `maxduration` int(11) NOT NULL default '0',
`remaintime` int(11) NOT NULL default '0', `remaintime` int(11) NOT NULL default '0',

View file

@ -22,7 +22,7 @@
DROP TABLE IF EXISTS `db_version`; DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` ( CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`required_2008_11_18_02_mangos_mangos_string` bit(1) default NULL `required_2008_11_29_02_mangos_spell_elixir` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -8073,435 +8073,6 @@ CREATE TABLE `playercreateinfo_item` (
LOCK TABLES `playercreateinfo_item` WRITE; LOCK TABLES `playercreateinfo_item` WRITE;
/*!40000 ALTER TABLE `playercreateinfo_item` DISABLE KEYS */; /*!40000 ALTER TABLE `playercreateinfo_item` DISABLE KEYS */;
INSERT INTO `playercreateinfo_item` VALUES
(1,1,38,1),
(1,1,39,1),
(1,1,40,1),
(1,1,25,1),
(1,1,2362,1),
(1,1,117,4),
(1,1,6948,1),
(1,1,14646,1),
(1,2,45,1),
(1,2,44,1),
(1,2,43,1),
(1,2,2361,1),
(1,2,6948,1),
(1,2,159,2),
(1,2,2070,4),
(1,2,14646,1),
(1,4,49,1),
(1,4,48,1),
(1,4,47,1),
(1,4,2092,1),
(1,4,2947,100),
(1,4,2070,4),
(1,4,6948,1),
(1,4,14646,1),
(1,5,53,1),
(1,5,6098,1),
(1,5,52,1),
(1,5,51,1),
(1,5,36,1),
(1,5,159,2),
(1,5,2070,4),
(1,5,6948,1),
(1,5,14646,1),
(1,8,6096,1),
(1,8,56,1),
(1,8,1395,1),
(1,8,55,1),
(1,8,35,1),
(1,8,2070,4),
(1,8,159,2),
(1,8,6948,1),
(1,8,14646,1),
(1,9,6097,1),
(1,9,57,1),
(1,9,1396,1),
(1,9,59,1),
(1,9,2092,1),
(1,9,4604,4),
(1,9,159,2),
(1,9,6948,1),
(1,9,14646,1),
(2,1,6125,1),
(2,1,139,1),
(2,1,140,1),
(2,1,12282,1),
(2,1,6948,1),
(2,1,117,4),
(2,1,14649,1),
(2,3,127,1),
(2,3,6126,1),
(2,3,6127,1),
(2,3,37,1),
(2,3,2504,1),
(2,3,159,2),
(2,3,117,4),
(2,3,6948,1),
(2,3,14649,1),
(2,3,2512,200),
(2,3,2101,1),
(2,4,2105,1),
(2,4,120,1),
(2,4,121,1),
(2,4,2092,1),
(2,4,25861,100),
(2,4,117,4),
(2,4,6948,1),
(2,4,14649,1),
(2,7,154,1),
(2,7,153,1),
(2,7,36,1),
(2,7,6948,1),
(2,7,117,4),
(2,7,159,2),
(2,7,14649,1),
(2,9,6129,1),
(2,9,1396,1),
(2,9,59,1),
(2,9,2092,1),
(2,9,6948,1),
(2,9,117,4),
(2,9,159,2),
(2,9,14649,1),
(3,1,38,1),
(3,1,39,1),
(3,1,40,1),
(3,1,12282,1),
(3,1,6948,1),
(3,1,117,4),
(3,1,14647,1),
(3,2,45,1),
(3,2,44,1),
(3,2,43,1),
(3,2,2361,1),
(3,2,4540,4),
(3,2,159,2),
(3,2,6948,1),
(3,2,14647,1),
(3,3,148,1),
(3,3,147,1),
(3,3,129,1),
(3,3,37,1),
(3,3,2508,1),
(3,3,159,2),
(3,3,117,4),
(3,3,6948,1),
(3,3,14647,1),
(3,3,2516,200),
(3,3,2102,1),
(3,4,49,1),
(3,4,48,1),
(3,4,47,1),
(3,4,2092,1),
(3,4,25861,100),
(3,4,4540,4),
(3,4,6948,1),
(3,4,14647,1),
(3,5,53,1),
(3,5,6098,1),
(3,5,52,1),
(3,5,51,1),
(3,5,36,1),
(3,5,159,2),
(3,5,4540,4),
(3,5,6948,1),
(3,5,14647,1),
(4,1,38,1),
(4,1,39,1),
(4,1,40,1),
(4,1,25,1),
(4,1,2362,1),
(4,1,117,4),
(4,1,6948,1),
(4,1,14648,1),
(4,3,148,1),
(4,3,147,1),
(4,3,129,1),
(4,3,2092,1),
(4,3,2504,1),
(4,3,159,2),
(4,3,117,4),
(4,3,6948,1),
(4,3,14648,1),
(4,3,2512,200),
(4,3,2101,1),
(4,4,49,1),
(4,4,48,1),
(4,4,47,1),
(4,4,2092,1),
(4,4,2947,100),
(4,4,4540,4),
(4,4,6948,1),
(4,4,14648,1),
(4,5,53,1),
(4,5,6119,1),
(4,5,52,1),
(4,5,51,1),
(4,5,36,1),
(4,5,2070,4),
(4,5,159,2),
(4,5,6948,1),
(4,5,14648,1),
(4,11,6123,1),
(4,11,44,1),
(4,11,3661,1),
(4,11,159,2),
(4,11,4536,4),
(4,11,6948,1),
(4,11,14648,1),
(5,1,6125,1),
(5,1,139,1),
(5,1,140,1),
(5,1,25,1),
(5,1,2362,1),
(5,1,4604,4),
(5,1,6948,1),
(5,1,14651,1),
(5,4,2105,1),
(5,4,120,1),
(5,4,121,1),
(5,4,2092,1),
(5,4,2947,100),
(5,4,4604,4),
(5,4,6948,1),
(5,4,14651,1),
(5,5,53,1),
(5,5,6144,1),
(5,5,52,1),
(5,5,51,1),
(5,5,36,1),
(5,5,4604,4),
(5,5,159,2),
(5,5,6948,1),
(5,5,14651,1),
(5,8,6096,1),
(5,8,6140,1),
(5,8,1395,1),
(5,8,55,1),
(5,8,35,1),
(5,8,4604,4),
(5,8,159,2),
(5,8,6948,1),
(5,8,14651,1),
(5,9,6129,1),
(5,9,1396,1),
(5,9,59,1),
(5,9,2092,1),
(5,9,4604,4),
(5,9,159,2),
(5,9,6948,1),
(5,9,14651,1),
(6,1,6125,1),
(6,1,139,1),
(6,1,2361,1),
(6,1,6948,1),
(6,1,4540,4),
(6,1,14650,1),
(6,3,127,1),
(6,3,6126,1),
(6,3,37,1),
(6,3,2508,1),
(6,3,159,2),
(6,3,117,4),
(6,3,6948,1),
(6,3,14650,1),
(6,3,2516,200),
(6,3,2102,1),
(6,7,154,1),
(6,7,153,1),
(6,7,36,1),
(6,7,6948,1),
(6,7,4604,4),
(6,7,159,2),
(6,7,14650,1),
(6,11,6139,1),
(6,11,6124,1),
(6,11,35,1),
(6,11,159,2),
(6,11,4536,4),
(6,11,6948,1),
(6,11,14650,1),
(7,1,38,1),
(7,1,39,1),
(7,1,40,1),
(7,1,25,1),
(7,1,2362,1),
(7,1,117,4),
(7,1,6948,1),
(7,1,14647,1),
(7,4,49,1),
(7,4,48,1),
(7,4,47,1),
(7,4,2092,1),
(7,4,2947,100),
(7,4,117,4),
(7,4,6948,1),
(7,4,14647,1),
(7,8,6096,1),
(7,8,56,1),
(7,8,1395,1),
(7,8,55,1),
(7,8,35,1),
(7,8,4536,4),
(7,8,159,2),
(7,8,6948,1),
(7,8,14647,1),
(7,9,6097,1),
(7,9,57,1),
(7,9,1396,1),
(7,9,59,1),
(7,9,2092,1),
(7,9,159,2),
(7,9,4604,4),
(7,9,6948,1),
(7,9,14647,1),
(8,1,6125,1),
(8,1,139,1),
(8,1,140,1),
(8,1,37,1),
(8,1,2362,1),
(8,1,25861,100),
(8,1,117,4),
(8,1,6948,1),
(8,1,14649,1),
(8,3,127,1),
(8,3,6126,1),
(8,3,6127,1),
(8,3,37,1),
(8,3,2504,1),
(8,3,4604,4),
(8,3,159,2),
(8,3,2512,200),
(8,3,2101,1),
(8,3,14649,1),
(8,3,6948,1),
(8,4,2105,1),
(8,4,120,1),
(8,4,121,1),
(8,4,2092,1),
(8,4,25861,100),
(8,4,117,4),
(8,4,6948,1),
(8,4,14649,1),
(8,5,53,1),
(8,5,6144,1),
(8,5,52,1),
(8,5,36,1),
(8,5,4540,4),
(8,5,159,2),
(8,5,6948,1),
(8,5,14649,1),
(8,7,6134,1),
(8,7,6135,1),
(8,7,36,1),
(8,7,117,4),
(8,7,159,2),
(8,7,6948,1),
(8,7,14649,1),
(8,8,6096,1),
(8,8,6140,1),
(8,8,1395,1),
(8,8,55,1),
(8,8,35,1),
(8,8,117,4),
(8,8,159,2),
(8,8,6948,1),
(8,8,14649,1),
(10,2,159,5),
(10,2,2070,5),
(10,2,6948,1),
(10,2,23346,1),
(10,2,24143,1),
(10,2,24145,1),
(10,2,24146,1),
(10,3,159,5),
(10,3,2101,1),
(10,3,2512,200),
(10,3,6948,1),
(10,3,20857,5),
(10,3,20899,1),
(10,3,20900,1),
(10,3,20901,1),
(10,3,20980,1),
(10,3,20982,1),
(10,4,3111,100),
(10,4,6948,1),
(10,4,20857,10),
(10,4,20896,1),
(10,4,20897,1),
(10,4,20898,1),
(10,4,20982,1),
(10,5,51,1),
(10,5,52,1),
(10,5,53,1),
(10,5,159,5),
(10,5,6948,1),
(10,5,20891,1),
(10,5,20981,5),
(10,8,35,1),
(10,8,159,5),
(10,8,6096,1),
(10,8,6948,1),
(10,8,20857,5),
(10,8,20893,1),
(10,8,20894,1),
(10,8,20895,1),
(10,9,59,1),
(10,9,159,5),
(10,9,1396,1),
(10,9,6948,1),
(10,9,20857,5),
(10,9,20892,1),
(10,9,20983,1),
(11,1,4540,5),
(11,1,6948,1),
(11,1,23346,1),
(11,1,23473,1),
(11,1,23474,1),
(11,1,23475,1),
(11,2,159,5),
(11,2,2361,1),
(11,2,4540,5),
(11,2,6948,1),
(11,2,23476,1),
(11,2,23476,1),
(11,2,23477,1),
(11,3,25,1),
(11,3,159,5),
(11,3,2101,1),
(11,3,2504,1),
(11,3,2512,200),
(11,3,4540,5),
(11,3,6948,1),
(11,3,23344,1),
(11,3,23345,1),
(11,3,23348,1),
(11,5,36,1),
(11,5,59,1),
(11,5,159,5),
(11,5,1396,1),
(11,5,4540,5),
(11,5,6097,1),
(11,5,6948,1),
(11,5,23322,1),
(11,7,36,1),
(11,7,159,5),
(11,7,4540,5),
(11,7,6948,1),
(11,7,23344,1),
(11,7,23345,1),
(11,7,23348,1),
(11,8,35,1),
(11,8,159,5),
(11,8,4540,5),
(11,8,6948,1),
(11,8,23473,1),
(11,8,23475,1),
(11,8,23478,1),
(11,8,23479,1);
/*!40000 ALTER TABLE `playercreateinfo_item` ENABLE KEYS */; /*!40000 ALTER TABLE `playercreateinfo_item` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@ -14170,6 +13741,7 @@ INSERT INTO `spell_elixir` VALUES
(41610,0xB), (41610,0xB),
(41611,0xB), (41611,0xB),
(42735,0x3), (42735,0x3),
(45373,0x1),
(46837,0xB), (46837,0xB),
(46839,0xB); (46839,0xB);
/*!40000 ALTER TABLE `spell_elixir` ENABLE KEYS */; /*!40000 ALTER TABLE `spell_elixir` ENABLE KEYS */;
@ -15160,7 +14732,7 @@ INSERT INTO `spell_proc_event` VALUES
(34950,0,0,0,0,0x0000000000000000,0x00400000,0,0), (34950,0,0,0,0,0x0000000000000000,0x00400000,0,0),
(34954,0,0,0,0,0x0000000000000000,0x00400000,0,0), (34954,0,0,0,0,0x0000000000000000,0x00400000,0,0),
(35077,0,0,0,0,0x0000000000000000,0x00008000,0,60), (35077,0,0,0,0,0x0000000000000000,0x00008000,0,60),
(35080,0,0,0,0,0x0000000000000000,0x00000001,0,60), (35080,0,0,0,0,0x0000000000000000,0x00080001,0,60),
(35083,0,0,0,0,0x0000000000000000,0x00020000,0,60), (35083,0,0,0,0,0x0000000000000000,0x00020000,0,60),
(35086,0,0,0,0,0x0000000000000000,0x08020000,0,60), (35086,0,0,0,0,0x0000000000000000,0x08020000,0,60),
(35100,0,0,0,0,0x0000000000000000,0x00080000,0,0), (35100,0,0,0,0,0x0000000000000000,0x00080000,0,0),

View file

@ -0,0 +1,3 @@
ALTER TABLE db_version CHANGE COLUMN required_2008_11_18_02_mangos_mangos_string required_2008_11_27_01_mangos_playercreateinfo_item bit;
TRUNCATE TABLE playercreateinfo_item;

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_2008_11_27_01_mangos_playercreateinfo_item required_2008_11_29_01_mangos_spell_proc_event bit;
DELETE FROM spell_proc_event where entry = 35080;
INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES
(35080,0,0,0,0,0x0000000000000000,0x00080001,0,60);

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_2008_11_29_01_mangos_spell_proc_event required_2008_11_29_02_mangos_spell_elixir bit;
DELETE FROM `spell_elixir` WHERE `entry` = 45373;
INSERT INTO `spell_elixir` VALUES
(45373,0x1);

View file

@ -0,0 +1,3 @@
ALTER TABLE character_db_version CHANGE COLUMN required_2008_11_12_01_character_character_aura required_2008_12_03_01_character_guild_member bit;
ALTER TABLE `guild_member` DROP INDEX `guid_key` ,
ADD UNIQUE `guid_key` ( `guid` );

View file

@ -137,6 +137,10 @@ pkgdata_DATA = \
2008_11_16_01_mangos_command.sql \ 2008_11_16_01_mangos_command.sql \
2008_11_18_01_mangos_creature_movement.sql \ 2008_11_18_01_mangos_creature_movement.sql \
2008_11_18_02_mangos_mangos_string.sql \ 2008_11_18_02_mangos_mangos_string.sql \
2008_11_27_01_mangos_playercreateinfo_item.sql \
2008_11_29_01_mangos_spell_proc_event.sql \
2008_11_29_02_mangos_spell_elixir.sql \
2008_12_03_01_character_guild_member.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -255,4 +259,8 @@ EXTRA_DIST = \
2008_11_16_01_mangos_command.sql \ 2008_11_16_01_mangos_command.sql \
2008_11_18_01_mangos_creature_movement.sql \ 2008_11_18_01_mangos_creature_movement.sql \
2008_11_18_02_mangos_mangos_string.sql \ 2008_11_18_02_mangos_mangos_string.sql \
2008_11_27_01_mangos_playercreateinfo_item.sql \
2008_11_29_01_mangos_spell_proc_event.sql \
2008_11_29_02_mangos_spell_elixir.sql \
2008_12_03_01_character_guild_member.sql \
README README

View file

@ -44,6 +44,11 @@ class LinkedListElement
LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; } LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; } LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
LinkedListElement * nocheck_next() { return iNext; }
LinkedListElement const* nocheck_next() const { return iNext; }
LinkedListElement * nocheck_prev() { return iPrev; }
LinkedListElement const* nocheck_prev() const { return iPrev; }
void delink() void delink()
{ {
if(isInList()) if(isInList())
@ -134,7 +139,10 @@ class LinkedListHead
typedef ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef ptrdiff_t distance_type; typedef ptrdiff_t distance_type;
typedef _Ty* pointer; typedef _Ty* pointer;
typedef _Ty const* const_pointer;
typedef _Ty& reference; typedef _Ty& reference;
typedef _Ty const & const_reference;
Iterator() : _Ptr(0) Iterator() : _Ptr(0)
{ // construct with null node pointer { // construct with null node pointer
@ -144,6 +152,17 @@ class LinkedListHead
{ // construct with node pointer _Pnode { // construct with node pointer _Pnode
} }
Iterator& operator=(Iterator const &_Right)
{
return (*this) = _Right._Ptr;
}
Iterator& operator=(const_pointer const &_Right)
{
_Ptr = (pointer)_Right;
return (*this);
}
reference operator*() reference operator*()
{ // return designated value { // return designated value
return *_Ptr; return *_Ptr;
@ -200,6 +219,17 @@ class LinkedListHead
return (!(*this == _Right)); return (!(*this == _Right));
} }
bool operator==(const_reference _Right) const
{ // test for reference equality
return (_Ptr == &_Right);
}
bool operator!=(const_reference _Right) const
{ // test for reference equality
return (_Ptr != &_Right);
}
pointer _Mynode() pointer _Mynode()
{ // return node pointer { // return node pointer
return (_Ptr); return (_Ptr);

View file

@ -71,9 +71,15 @@ template <class TO, class FROM> class Reference : public LinkedListElement
return iRefTo != NULL; return iRefTo != NULL;
} }
Reference<TO,FROM>* next() { return((Reference<TO,FROM>*)LinkedListElement::next()); } Reference<TO,FROM> * next() { return((Reference<TO,FROM> *) LinkedListElement::next()); }
Reference<TO,FROM>const* next() const { return((Reference<TO,FROM> const*)LinkedListElement::next()); } Reference<TO,FROM> const * next() const { return((Reference<TO,FROM> const *) LinkedListElement::next()); }
Reference<TO,FROM>* prev() { return((Reference<TO,FROM>*)LinkedListElement::prev()); } Reference<TO,FROM> * prev() { return((Reference<TO,FROM> *) LinkedListElement::prev()); }
Reference<TO,FROM> const * prev() const { return((Reference<TO,FROM> const *) LinkedListElement::prev()); }
Reference<TO,FROM> * nocheck_next() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_next()); }
Reference<TO,FROM> const * nocheck_next() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_next()); }
Reference<TO,FROM> * nocheck_prev() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_prev()); }
Reference<TO,FROM> const * nocheck_prev() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_prev()); }
inline TO* operator ->() const { return iRefTo; } inline TO* operator ->() const { return iRefTo; }
inline TO* getTarget() const { return iRefTo; } inline TO* getTarget() const { return iRefTo; }

View file

@ -55,7 +55,7 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
return AOR_NAME_ALREDY_EXIST; // username does already exist return AOR_NAME_ALREDY_EXIST; // username does already exist
} }
if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1(CONCAT('%s',':','%s')),NOW())", username.c_str(), username.c_str(), password.c_str())) if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1("_CONCAT3_("'%s'","':'","'%s'")"),NOW())", username.c_str(), username.c_str(), password.c_str()))
return AOR_DB_INTERNAL_ERROR; // unexpected error 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"); 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");
@ -127,7 +127,7 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
loginDatabase.escape_string(new_uname); loginDatabase.escape_string(new_uname);
loginDatabase.escape_string(new_passwd); loginDatabase.escape_string(new_passwd);
if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1(CONCAT('%s',':','%s')) WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid)) if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1("_CONCAT3_("'%s'","':'","'%s'")") WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK; return AOR_OK;
@ -146,7 +146,7 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
normilizeString(new_passwd); normilizeString(new_passwd);
loginDatabase.escape_string(new_passwd); loginDatabase.escape_string(new_passwd);
if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1(CONCAT(username,':','%s')) WHERE id='%d'", new_passwd.c_str(), accid)) if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")") WHERE id='%d'", new_passwd.c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK; return AOR_OK;
@ -197,7 +197,7 @@ bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
normilizeString(passwd); normilizeString(passwd);
loginDatabase.escape_string(passwd); loginDatabase.escape_string(passwd);
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", accid, passwd.c_str()); QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")")", accid, passwd.c_str());
if (result) if (result)
{ {
delete result; delete result;

View file

@ -47,15 +47,23 @@ AggressorAI::MoveInLineOfSight(Unit *u)
if( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE ) if( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return; return;
if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() && if( !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) && ( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
u->isInAccessablePlaceFor(&i_creature) ) u->isInAccessablePlaceFor(&i_creature) )
{ {
float attackRadius = i_creature.GetAttackDistance(u); float attackRadius = i_creature.GetAttackDistance(u);
if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.IsWithinLOSInMap(u) ) if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.IsWithinLOSInMap(u) )
{ {
AttackStart(u); if(!i_creature.getVictim())
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); {
AttackStart(u);
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
}
else if(sMapStore.LookupEntry(i_creature.GetMapId())->IsDungeon())
{
u->SetInCombatWith(&i_creature);
i_creature.AddThreat(u, 0.0f);
}
} }
} }
} }

View file

@ -22,21 +22,21 @@
ArenaTeam::ArenaTeam() ArenaTeam::ArenaTeam()
{ {
Id = 0; Id = 0;
Type = 0; Type = 0;
Name = ""; Name = "";
CaptainGuid = 0; CaptainGuid = 0;
BackgroundColor = 0; // background BackgroundColor = 0; // background
EmblemStyle = 0; // icon EmblemStyle = 0; // icon
EmblemColor = 0; // icon color EmblemColor = 0; // icon color
BorderStyle = 0; // border BorderStyle = 0; // border
BorderColor = 0; // border color BorderColor = 0; // border color
stats.games = 0; stats.games_week = 0;
stats.played = 0; stats.games_season = 0;
stats.rank = 0; stats.rank = 0;
stats.rating = 1500; stats.rating = 1500;
stats.wins = 0; stats.wins_week = 0;
stats.wins2 = 0; stats.wins_season = 0;
} }
ArenaTeam::~ArenaTeam() ArenaTeam::~ArenaTeam()
@ -51,7 +51,7 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist
return false; return false;
sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid)); sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid));
CaptainGuid = captainGuid; CaptainGuid = captainGuid;
Name = ArenaTeamName; Name = ArenaTeamName;
@ -69,7 +69,7 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
"VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')", "VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor); Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor);
CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES " CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
"('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games,stats.wins,stats.played,stats.wins2,stats.rank); "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games_week,stats.wins_week,stats.games_season,stats.wins_season,stats.rank);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction();
@ -122,13 +122,14 @@ bool ArenaTeam::AddMember(uint64 PlayerGuid)
Player::RemovePetitionsAndSigns(PlayerGuid, GetType()); Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
ArenaTeamMember newmember; ArenaTeamMember newmember;
newmember.name = plName; newmember.name = plName;
newmember.guid = PlayerGuid; newmember.guid = PlayerGuid;
newmember.Class = plClass; newmember.Class = plClass;
newmember.played_season = 0; newmember.games_season = 0;
newmember.played_week = 0; newmember.games_week = 0;
newmember.wons_season = 0; newmember.wins_season = 0;
newmember.wons_week = 0; newmember.wins_week = 0;
newmember.personal_rating = 1500;
members.push_back(newmember); members.push_back(newmember);
CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid)); CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid));
@ -137,19 +138,23 @@ bool ArenaTeam::AddMember(uint64 PlayerGuid)
{ {
pl->SetInArenaTeam(Id, GetSlot()); pl->SetInArenaTeam(Id, GetSlot());
pl->SetArenaTeamIdInvited(0); pl->SetArenaTeamIdInvited(0);
// hide promote/remove buttons
if(CaptainGuid != PlayerGuid)
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
} }
else else
{ {
Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), Id, PlayerGuid); Tokens tokens;
} if(Player::LoadValuesArrayFromDB(tokens,PlayerGuid))
{
Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), Id);
// hide promote/remove buttons
if(CaptainGuid != PlayerGuid)
Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
// hide promote/remove buttons Player::SaveValuesArrayInDB(tokens,PlayerGuid);
if(CaptainGuid != PlayerGuid) }
{
if(pl)
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
else
Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, PlayerGuid);
} }
return true; return true;
} }
@ -192,12 +197,12 @@ void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId)
Field *fields = result->Fetch(); Field *fields = result->Fetch();
stats.rating = fields[0].GetUInt32(); stats.rating = fields[0].GetUInt32();
stats.games = fields[1].GetUInt32(); stats.games_week = fields[1].GetUInt32();
stats.wins = fields[2].GetUInt32(); stats.wins_week = fields[2].GetUInt32();
stats.played = fields[3].GetUInt32(); stats.games_season = fields[3].GetUInt32();
stats.wins2 = fields[4].GetUInt32(); stats.wins_season = fields[4].GetUInt32();
stats.rank = fields[5].GetUInt32(); stats.rank = fields[5].GetUInt32();
delete result; delete result;
} }
@ -216,10 +221,10 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
ArenaTeamMember newmember; ArenaTeamMember newmember;
newmember.guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); newmember.guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
LoadPlayerStats(&newmember); LoadPlayerStats(&newmember);
newmember.played_week = fields[1].GetUInt32(); newmember.games_week = fields[1].GetUInt32();
newmember.wons_week = fields[2].GetUInt32(); newmember.wins_week = fields[2].GetUInt32();
newmember.played_season = fields[3].GetUInt32(); newmember.games_season = fields[3].GetUInt32();
newmember.wons_season = fields[4].GetUInt32(); newmember.wins_season = fields[4].GetUInt32();
members.push_back(newmember); members.push_back(newmember);
}while( result->NextRow() ); }while( result->NextRow() );
delete result; delete result;
@ -337,11 +342,11 @@ void ArenaTeam::Roster(WorldSession *session)
data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
data << uint8(pl->getLevel()); // unknown, probably level data << uint8(pl->getLevel()); // unknown, probably level
data << uint8(pl->getClass()); // class data << uint8(pl->getClass()); // class
data << uint32(itr->played_week); // played this week data << uint32(itr->games_week); // played this week
data << uint32(itr->wons_week); // wins this week data << uint32(itr->wins_week); // wins this week
data << uint32(itr->played_season); // played this season data << uint32(itr->games_season); // played this season
data << uint32(itr->wons_season); // wins this season data << uint32(itr->wins_season); // wins this season
data << uint32(0); // personal rating? data << uint32(itr->personal_rating); // personal rating
} }
else else
{ {
@ -351,11 +356,11 @@ void ArenaTeam::Roster(WorldSession *session)
data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
data << uint8(0); // unknown, level? data << uint8(0); // unknown, level?
data << uint8(itr->Class); // class data << uint8(itr->Class); // class
data << uint32(itr->played_week); // played this week data << uint32(itr->games_week); // played this week
data << uint32(itr->wons_week); // wins this week data << uint32(itr->wins_week); // wins this week
data << uint32(itr->played_season); // played this season data << uint32(itr->games_season); // played this season
data << uint32(itr->wons_season); // wins this season data << uint32(itr->wins_season); // wins this season
data << uint32(0); // personal rating? data << uint32(itr->personal_rating); // personal rating
} }
} }
session->SendPacket(&data); session->SendPacket(&data);
@ -382,25 +387,29 @@ void ArenaTeam::Stats(WorldSession *session)
WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7); WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
data << uint32(GetId()); // arena team id data << uint32(GetId()); // arena team id
data << uint32(stats.rating); // rating data << uint32(stats.rating); // rating
data << uint32(stats.games); // games data << uint32(stats.games_week); // games this week
data << uint32(stats.wins); // wins data << uint32(stats.wins_week); // wins this week
data << uint32(stats.played); // played data << uint32(stats.games_season); // played this season
data << uint32(stats.wins2); // wins(again o_O) data << uint32(stats.wins_season); // wins this season
data << uint32(stats.rank); // rank data << uint32(stats.rank); // rank
session->SendPacket(&data); session->SendPacket(&data);
} }
void ArenaTeam::InspectStats(WorldSession *session, uint64 guid) void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
{ {
ArenaTeamMember* member = GetMember(guid);
if(!member)
return;
WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6); WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6);
data << uint64(guid); // player guid data << uint64(guid); // player guid
data << uint8(GetSlot()); // slot (0...2) data << uint8(GetSlot()); // slot (0...2)
data << uint32(GetId()); // arena team id data << uint32(GetId()); // arena team id
data << uint32(stats.rating); // rating data << uint32(stats.rating); // rating
data << uint32(stats.games); // games data << uint32(stats.games_season); // season played
data << uint32(stats.wins); // wins data << uint32(stats.wins_season); // season wins
data << uint32(stats.played); // played (count of all games, that played...) data << member->games_season; // played (count of all games, that the inspected member participated...)
data << uint32(0); // 2.3.3 personal rating? data << member->personal_rating; // personal rating
session->SendPacket(&data); session->SendPacket(&data);
} }
@ -423,20 +432,20 @@ void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
stats.rating = value; stats.rating = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId()); CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId());
break; break;
case STAT_TYPE_GAMES: case STAT_TYPE_GAMES_WEEK:
stats.games = value; stats.games_week = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId()); CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId());
break; break;
case STAT_TYPE_WINS: case STAT_TYPE_WINS_WEEK:
stats.wins = value; stats.wins_week = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId()); CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId());
break; break;
case STAT_TYPE_PLAYED: case STAT_TYPE_GAMES_SEASON:
stats.played = value; stats.games_season = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId()); CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId());
break; break;
case STAT_TYPE_WINS2: case STAT_TYPE_WINS_SEASON:
stats.wins2 = value; stats.wins_season = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId()); CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId());
break; break;
case STAT_TYPE_RANK: case STAT_TYPE_RANK:
@ -463,7 +472,7 @@ uint8 ArenaTeam::GetSlot() const
void ArenaTeam::BroadcastPacket(WorldPacket *packet) void ArenaTeam::BroadcastPacket(WorldPacket *packet)
{ {
for (MemberList::iterator itr = members.begin(); itr != members.end(); itr++) for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{ {
Player *player = objmgr.GetPlayer(itr->guid); Player *player = objmgr.GetPlayer(itr->guid);
if(player) if(player)
@ -493,24 +502,35 @@ bool ArenaTeam::HaveMember( uint64 guid ) const
return false; return false;
} }
void ArenaTeam::FinishWeek()
{
stats.games_week = 0; // played this week
stats.wins_week = 0; // wins this week
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{
itr->games_week = 0;
itr->wins_week = 0;
}
}
/* /*
arenateam fields (id from 2.3.3 client): arenateam fields (id from 2.3.3 client):
1414 - arena team id 2v2 1414 - arena team id 2v2
1415 - 0=captain, 1=member 1415 - 0=captain, 1=member
1416 - played this season 1416 - played this week
1417 - played this week 1417 - played this season
1418 - unk 1418 - unk
1419 - unk 1419 - personal arena rating
1420 - arena team id 3v3 1420 - arena team id 3v3
1421 - 0=captain, 1=member 1421 - 0=captain, 1=member
1422 - played this season 1422 - played this week
1423 - played this week 1423 - played this season
1424 - unk 1424 - unk
1425 - unk 1425 - personal arena rating
1426 - arena team id 5v5 1426 - arena team id 5v5
1427 - 0=captain, 1=member 1427 - 0=captain, 1=member
1428 - played this season 1428 - played this week
1429 - played this week 1429 - played this season
1430 - unk 1430 - unk
1431 - unk 1431 - personal arena rating
*/ */

View file

@ -66,12 +66,12 @@ ERR_ARENA_TEAM_LEVEL_TOO_LOW_I
enum ArenaTeamStatTypes enum ArenaTeamStatTypes
{ {
STAT_TYPE_RATING = 0, STAT_TYPE_RATING = 0,
STAT_TYPE_GAMES = 1, STAT_TYPE_GAMES_WEEK = 1,
STAT_TYPE_WINS = 2, STAT_TYPE_WINS_WEEK = 2,
STAT_TYPE_PLAYED = 3, STAT_TYPE_GAMES_SEASON = 3,
STAT_TYPE_WINS2 = 4, STAT_TYPE_WINS_SEASON = 4,
STAT_TYPE_RANK = 5 STAT_TYPE_RANK = 5
}; };
enum ArenaTeamTypes enum ArenaTeamTypes
@ -88,19 +88,20 @@ struct ArenaTeamMember
//uint32 unk2; //uint32 unk2;
//uint8 unk1; //uint8 unk1;
uint8 Class; uint8 Class;
uint32 played_week; uint32 games_week;
uint32 wons_week; uint32 wins_week;
uint32 played_season; uint32 games_season;
uint32 wons_season; uint32 wins_season;
uint32 personal_rating;
}; };
struct ArenaTeamStats struct ArenaTeamStats
{ {
uint32 rating; uint32 rating;
uint32 games; uint32 games_week;
uint32 wins; uint32 wins_week;
uint32 played; uint32 games_season;
uint32 wins2; uint32 wins_season;
uint32 rank; uint32 rank;
}; };
@ -123,7 +124,7 @@ class ArenaTeam
static uint8 GetSlotByType(uint32 type); static uint8 GetSlotByType(uint32 type);
const uint64& GetCaptain() const { return CaptainGuid; } const uint64& GetCaptain() const { return CaptainGuid; }
std::string GetName() const { return Name; } std::string GetName() const { return Name; }
ArenaTeamStats GetStats() const { return stats; } const ArenaTeamStats& GetStats() const { return stats; }
void SetStats(uint32 stat_type, uint32 value); void SetStats(uint32 stat_type, uint32 value);
uint32 GetRating() const { return stats.rating; } uint32 GetRating() const { return stats.rating; }
@ -143,6 +144,22 @@ class ArenaTeam
MemberList::iterator membersbegin(){ return members.begin(); } MemberList::iterator membersbegin(){ return members.begin(); }
MemberList::iterator membersEnd(){ return members.end(); } MemberList::iterator membersEnd(){ return members.end(); }
bool HaveMember(uint64 guid) const; bool HaveMember(uint64 guid) const;
ArenaTeamMember* GetMember(uint64 guid)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
if(itr->guid==guid)
return &(*itr);
return NULL;
}
ArenaTeamMember* GetMember(std::string& name)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
if(itr->name==name)
return &(*itr);
return NULL;
}
bool LoadArenaTeamFromDB(uint32 ArenaTeamId); bool LoadArenaTeamFromDB(uint32 ArenaTeamId);
void LoadMembersFromDB(uint32 ArenaTeamId); void LoadMembersFromDB(uint32 ArenaTeamId);
@ -156,6 +173,8 @@ class ArenaTeam
void Stats(WorldSession *session); void Stats(WorldSession *session);
void InspectStats(WorldSession *session, uint64 guid); void InspectStats(WorldSession *session, uint64 guid);
void FinishWeek();
protected: protected:
uint32 Id; uint32 Id;

View file

@ -289,25 +289,8 @@ void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
recv_data >> name; recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at) if(!at) // arena team not found
{
// arena team not found
return; return;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
// player guid not found
return;
}
if(at->GetCaptain() == guid)
{
// unsure
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
if(at->GetCaptain() != _player->GetGUID()) if(at->GetCaptain() != _player->GetGUID())
{ {
@ -315,13 +298,20 @@ void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
return; return;
} }
if(at->GetCaptain() == guid) if(!normalizePlayerName(name))
return;
ArenaTeamMember* member = at->GetMember(name);
if(!member) // member not found
return;
if(at->GetCaptain() == member->guid)
{ {
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
return; return;
} }
at->DelMember(guid); at->DelMember(member->guid);
// event // event
WorldPacket data; WorldPacket data;
@ -343,24 +333,8 @@ void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data
recv_data >> name; recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at) if(!at) // arena team not found
{
// arena team not found
return; return;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
// player guid not found
return;
}
if(at->GetCaptain() == guid)
{
// target player already captain
return;
}
if(at->GetCaptain() != _player->GetGUID()) if(at->GetCaptain() != _player->GetGUID())
{ {
@ -368,7 +342,17 @@ void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data
return; return;
} }
at->SetCaptain(guid); if(!normalizePlayerName(name))
return;
ArenaTeamMember* member = at->GetMember(name);
if(!member) // member not found
return;
if(at->GetCaptain() == member->guid) // target player already captain
return;
at->SetCaptain(member->guid);
// event // event
WorldPacket data; WorldPacket data;

View file

@ -709,14 +709,21 @@ void BattleGround::AddPlayer(Player *plr)
plr->RemoveArenaSpellCooldowns(); plr->RemoveArenaSpellCooldowns();
//plr->RemoveArenaAuras(); //plr->RemoveArenaAuras();
plr->RemoveAllEnchantments(TEMP_ENCHANTMENT_SLOT); plr->RemoveAllEnchantments(TEMP_ENCHANTMENT_SLOT);
if(team == ALLIANCE && plr->GetTeam() == ALLIANCE) if(team == ALLIANCE) // gold
plr->CastSpell(plr,SPELL_ALLIANCE_GOLD_FLAG,true); {
else if(team == HORDE && plr->GetTeam() == ALLIANCE) if(plr->GetTeam() == HORDE)
plr->CastSpell(plr,SPELL_ALLIANCE_GREEN_FLAG,true); plr->CastSpell(plr, SPELL_HORDE_GOLD_FLAG,true);
else if(team == ALLIANCE && plr->GetTeam() == HORDE) else
plr->CastSpell(plr,SPELL_HORDE_GOLD_FLAG,true); plr->CastSpell(plr, SPELL_ALLIANCE_GOLD_FLAG,true);
else }
plr->CastSpell(plr,SPELL_HORDE_GREEN_FLAG,true); else // green
{
if(plr->GetTeam() == HORDE)
plr->CastSpell(plr, SPELL_HORDE_GREEN_FLAG,true);
else
plr->CastSpell(plr, SPELL_ALLIANCE_GREEN_FLAG,true);
}
plr->DestroyConjuredItems(true); plr->DestroyConjuredItems(true);
if(GetStatus() == STATUS_WAIT_JOIN) // not started yet if(GetStatus() == STATUS_WAIT_JOIN) // not started yet

View file

@ -103,13 +103,13 @@ void BattleGroundQueue::AddPlayer(Player *plr, uint32 bgTypeId)
if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
{ {
ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF,
bgName, q_min_level, q_max_level, qAlliance, MinPlayers - qAlliance, qHorde, MinPlayers - qHorde); bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0);
} }
// System message // System message
else else
{ {
sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD,
bgName, q_min_level, q_max_level, qAlliance, MinPlayers - qAlliance, qHorde, MinPlayers - qHorde); bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0);
} }
} }
} }

View file

@ -209,7 +209,7 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
if(ban && !IsBanned(bad->GetGUID())) if(ban && !IsBanned(bad->GetGUID()))
{ {
banned.push_back(bad->GetGUID()); banned.insert(bad->GetGUID());
MakePlayerBanned(&data, bad->GetGUID(), good); MakePlayerBanned(&data, bad->GetGUID(), good);
} }
else else
@ -258,7 +258,7 @@ void Channel::UnBan(uint64 good, const char *badname)
} }
else else
{ {
banned.remove(bad->GetGUID()); banned.erase(bad->GetGUID());
WorldPacket data; WorldPacket data;
MakePlayerUnbanned(&data, bad->GetGUID(), good); MakePlayerUnbanned(&data, bad->GetGUID(), good);

View file

@ -147,7 +147,7 @@ class Channel
typedef std::map<uint64, PlayerInfo> PlayerList; typedef std::map<uint64, PlayerInfo> PlayerList;
PlayerList players; PlayerList players;
typedef std::list<uint64> BannedList; typedef std::set<uint64> BannedList;
BannedList banned; BannedList banned;
bool m_announce; bool m_announce;
bool m_moderate; bool m_moderate;
@ -202,15 +202,9 @@ class Channel
void SendToAllButOne(WorldPacket *data, uint64 who); void SendToAllButOne(WorldPacket *data, uint64 who);
void SendToOne(WorldPacket *data, uint64 who); void SendToOne(WorldPacket *data, uint64 who);
bool IsOn(uint64 who) const { return players.count(who) > 0; } bool IsOn(uint64 who) const { return players.count(who) != 0; }
bool IsBanned(const uint64 guid) const bool IsBanned(const uint64 guid) const {return banned.count(guid) != 0; }
{
for(BannedList::const_iterator i = banned.begin(); i != banned.end(); ++i)
if(*i == guid)
return true;
return false;
}
bool IsFirst() const { return !(players.size() > 1); } bool IsFirst() const { return !(players.size() > 1); }

View file

@ -156,18 +156,20 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ )
// ------- Query Without Declined Names -------- // ------- Query Without Declined Names --------
// 0 1 2 3 4 5 6 7 8 // 0 1 2 3 4 5 6 7 8
"SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
// 9 10 11 12 // 9 10 11 12 13
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level " "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid "
"FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='0' " "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='0' "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid" "WHERE characters.account = '%u' ORDER BY characters.guid"
: :
// --------- Query With Declined Names --------- // --------- Query With Declined Names ---------
// 0 1 2 3 4 5 6 7 8 // 0 1 2 3 4 5 6 7 8
"SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
// 9 10 11 12 13 // 9 10 11 12 13 14
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, genitive " "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, genitive "
"FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='0' " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='0' "
"LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid", "WHERE characters.account = '%u' ORDER BY characters.guid",
GetAccountId()); GetAccountId());
} }
@ -540,6 +542,22 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" );
} }
//QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow());
QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD);
if(resultGuild)
{
Field *fields = resultGuild->Fetch();
pCurrChar->SetInGuild(fields[0].GetUInt32());
pCurrChar->SetRank(fields[1].GetUInt32());
delete resultGuild;
}
else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership
{
pCurrChar->SetInGuild(0);
pCurrChar->SetRank(0);
}
if(pCurrChar->GetGuildId() != 0) if(pCurrChar->GetGuildId() != 0)
{ {
Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId());
@ -567,8 +585,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
{ {
// remove wrong guild data // remove wrong guild data
sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId());
pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); pCurrChar->SetInGuild(0);
pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID());
} }
} }
@ -591,22 +608,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
} }
} }
//QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow());
QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD);
if(resultGuild)
{
Field *fields = resultGuild->Fetch();
pCurrChar->SetInGuild(fields[0].GetUInt32());
pCurrChar->SetRank(fields[1].GetUInt32());
delete resultGuild;
}
else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership
{
pCurrChar->SetInGuild(0);
pCurrChar->SetRank(0);
}
if (!pCurrChar->GetMap()->Add(pCurrChar)) if (!pCurrChar->GetMap()->Add(pCurrChar))
{ {
AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId());
@ -640,7 +641,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
pCurrChar->LoadCorpse(); pCurrChar->LoadCorpse();
// setting Ghost+speed if dead // setting Ghost+speed if dead
//if ( pCurrChar->m_deathState == DEAD )
if (pCurrChar->m_deathState != ALIVE) if (pCurrChar->m_deathState != ALIVE)
{ {
// not blizz like, we must correctly save and load player instead... // not blizz like, we must correctly save and load player instead...
@ -745,6 +745,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
if(sWorld.IsShutdowning()) if(sWorld.IsShutdowning())
sWorld.ShutdownMsg(true,pCurrChar); sWorld.ShutdownMsg(true,pCurrChar);
if(sWorld.getConfig(CONFIG_ALL_TAXI_PATHS))
pCurrChar->SetTaxiCheater(true);
if(pCurrChar->isGameMaster()) if(pCurrChar->isGameMaster())
SendNotification(LANG_GM_ON); SendNotification(LANG_GM_ON);
@ -901,23 +904,8 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
recv_data >> guid; recv_data >> guid;
recv_data >> newname; recv_data >> newname;
QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); QueryResult *result = CharacterDatabase.PQuery("SELECT at_login, name FROM characters WHERE guid ='%u'", GUID_LOPART(guid));
if (result) if (!result)
{
uint32 at_loginFlags;
Field *fields = result->Fetch();
at_loginFlags = fields[0].GetUInt32();
delete result;
if (!(at_loginFlags & AT_LOGIN_RENAME))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << (uint8)CHAR_CREATE_ERROR;
SendPacket( &data );
return;
}
}
else
{ {
WorldPacket data(SMSG_CHAR_RENAME, 1); WorldPacket data(SMSG_CHAR_RENAME, 1);
data << (uint8)CHAR_CREATE_ERROR; data << (uint8)CHAR_CREATE_ERROR;
@ -925,10 +913,16 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
return; return;
} }
if(!objmgr.GetPlayerNameByGUID(guid, oldname)) // character not exist, because we have no name for this guid uint32 at_loginFlags;
Field *fields = result->Fetch();
at_loginFlags = fields[0].GetUInt32();
oldname = fields[1].GetCppString();
delete result;
if (!(at_loginFlags & AT_LOGIN_RENAME))
{ {
WorldPacket data(SMSG_CHAR_RENAME, 1); WorldPacket data(SMSG_CHAR_RENAME, 1);
data << (uint8)CHAR_LOGIN_NO_CHARACTER; data << (uint8)CHAR_CREATE_ERROR;
SendPacket( &data ); SendPacket( &data );
return; return;
} }

View file

@ -209,5 +209,5 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const
{ {
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
} }

View file

@ -446,6 +446,11 @@ void Creature::Update(uint32 diff)
m_regenTimer = 2000; m_regenTimer = 2000;
break; break;
} }
case DEAD_FALLING:
{
if (!FallGround())
setDeathState(JUST_DIED);
}
default: default:
break; break;
} }
@ -689,7 +694,7 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
// lazy loading single time at use // lazy loading single time at use
LoadGossipOptions(); LoadGossipOptions();
for( GossipOptionList::iterator i = m_goptions.begin( ); i != m_goptions.end( ); i++ ) for( GossipOptionList::iterator i = m_goptions.begin( ); i != m_goptions.end( ); ++i )
{ {
GossipOption* gso=&*i; GossipOption* gso=&*i;
if(gso->GossipId == gossipid) if(gso->GossipId == gossipid)
@ -921,44 +926,7 @@ void Creature::OnPoiSelect(Player* player, GossipOption const *gossip)
{ {
if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER) if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER)
{ {
//float x,y;
//bool findnpc=false;
Poi_Icon icon = ICON_POI_0; Poi_Icon icon = ICON_POI_0;
//QueryResult *result;
//Field *fields;
uint32 mapid=GetMapId();
Map const* map=MapManager::Instance().GetBaseMap( mapid );
uint16 areaflag=map->GetAreaFlag(GetPositionX(),GetPositionY());
uint32 zoneid=Map::GetZoneId(areaflag,mapid);
std::string areaname= gossip->OptionText;
/*
uint16 pflag;
// use the action relate to creaturetemplate.trainer_type ?
result= WorldDatabase.PQuery("SELECT creature.position_x,creature.position_y FROM creature,creature_template WHERE creature.map = '%u' AND creature.id = creature_template.entry AND creature_template.trainer_type = '%u'", mapid, gossip->Action );
if(!result)
return;
do
{
fields = result->Fetch();
x=fields[0].GetFloat();
y=fields[1].GetFloat();
pflag=map->GetAreaFlag(GetPositionX(),GetPositionY());
if(pflag==areaflag)
{
findnpc=true;
break;
}
}while(result->NextRow());
delete result;
if(!findnpc)
{
player->PlayerTalkClass->SendTalking( "$NSorry", "Here no this person.");
return;
}*/
//need add more case. //need add more case.
switch(gossip->Action) switch(gossip->Action)
{ {
@ -975,8 +943,9 @@ void Creature::OnPoiSelect(Player* player, GossipOption const *gossip)
icon=ICON_POI_TOWER; icon=ICON_POI_TOWER;
break; break;
} }
uint32 textid=GetGossipTextId( gossip->Action, zoneid ); uint32 textid = GetGossipTextId( gossip->Action, GetZoneId() );
player->PlayerTalkClass->SendTalking( textid ); player->PlayerTalkClass->SendTalking(textid);
// std::string areaname= gossip->OptionText;
// how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() ); // how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() );
} }
} }
@ -1009,7 +978,7 @@ uint32 Creature::GetNpcTextId()
GossipOption const* Creature::GetGossipOption( uint32 id ) const GossipOption const* Creature::GetGossipOption( uint32 id ) const
{ {
for( GossipOptionList::const_iterator i = m_goptions.begin( ); i != m_goptions.end( ); i++ ) for( GossipOptionList::const_iterator i = m_goptions.begin( ); i != m_goptions.end( ); ++i )
{ {
if(i->Action==id ) if(i->Action==id )
return &*i; return &*i;
@ -1340,7 +1309,15 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId()); m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId());
if(m_respawnTime > time(NULL)) // not ready to respawn if(m_respawnTime > time(NULL)) // not ready to respawn
{
m_deathState = DEAD; m_deathState = DEAD;
if(canFly())
{
float tz = GetMap()->GetHeight(data->posX,data->posY,data->posZ,false);
if(data->posZ - tz > 0.1)
Relocate(data->posX,data->posY,tz);
}
}
else if(m_respawnTime) // respawn time set but expired else if(m_respawnTime) // respawn time set but expired
{ {
m_respawnTime = 0; m_respawnTime = 0;
@ -1487,6 +1464,9 @@ void Creature::setDeathState(DeathState s)
if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY) || isWorldBoss()) if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY) || isWorldBoss())
SaveRespawnTime(); SaveRespawnTime();
if (canFly() && FallGround())
return;
if(!IsStopped()) if(!IsStopped())
StopMoving(); StopMoving();
} }
@ -1501,6 +1481,9 @@ void Creature::setDeathState(DeathState s)
if ( LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId) ) if ( LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId) )
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
if (canFly() && FallGround())
return;
Unit::setDeathState(CORPSE); Unit::setDeathState(CORPSE);
} }
if(s == JUST_ALIVED) if(s == JUST_ALIVED)
@ -1520,6 +1503,25 @@ void Creature::setDeathState(DeathState s)
} }
} }
bool Creature::FallGround()
{
// Let's abort after we called this function one time
if (getDeathState() == DEAD_FALLING)
return false;
// Let's do with no vmap because no way to get far distance with vmap high call
float tz = GetMap()->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), false);
// Abort too if the ground is very near
if (fabs(GetPositionZ() - tz) < 0.1f)
return false;
Unit::setDeathState(DEAD_FALLING);
GetMotionMaster()->MovePoint(0, GetPositionX(), GetPositionY(), tz);
Relocate(GetPositionX(), GetPositionY(), tz);
return true;
}
void Creature::Respawn() void Creature::Respawn()
{ {
RemoveCorpse(); RemoveCorpse();
@ -1775,7 +1777,7 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const
if(!pVictim->isInAccessablePlaceFor(this)) if(!pVictim->isInAccessablePlaceFor(this))
return true; return true;
if(sMapStore.LookupEntry(GetMapId())->Instanceable()) if(sMapStore.LookupEntry(GetMapId())->IsDungeon())
return false; return false;
float length = pVictim->GetDistance(CombatStartX,CombatStartY,CombatStartZ); float length = pVictim->GetDistance(CombatStartX,CombatStartY,CombatStartZ);

View file

@ -218,7 +218,7 @@ struct CreatureInfo
bool isTameable() const bool isTameable() const
{ {
return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEBLE); return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEABLE);
} }
}; };
@ -521,6 +521,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
const char* GetNameForLocaleIdx(int32 locale_idx) const; const char* GetNameForLocaleIdx(int32 locale_idx) const;
void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState
bool FallGround();
bool LoadFromDB(uint32 guid, Map *map); bool LoadFromDB(uint32 guid, Map *map);
void SaveToDB(); void SaveToDB();

View file

@ -148,5 +148,5 @@ void DynamicObject::Delay(int32 delaytime)
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
{ {
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
} }

View file

@ -190,7 +190,7 @@ void GameObject::Update(uint32 /*p_time*/)
if(caster && caster->GetTypeId()==TYPEID_PLAYER) if(caster && caster->GetTypeId()==TYPEID_PLAYER)
{ {
SetGoState(0); SetGoState(0);
SetUInt32Value(GAMEOBJECT_FLAGS, 32); SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
UpdateData udata; UpdateData udata;
WorldPacket packet; WorldPacket packet;
@ -723,7 +723,7 @@ bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const
// check distance // check distance
return IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject() + return IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject() +
(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f) ); (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
} }
void GameObject::Respawn() void GameObject::Respawn()

View file

@ -22,6 +22,7 @@
#include "Log.h" #include "Log.h"
#include "Database/DatabaseEnv.h" #include "Database/DatabaseEnv.h"
#include "Database/DatabaseImpl.h"
#include "Platform/Define.h" #include "Platform/Define.h"
#include "MapManager.h" #include "MapManager.h"
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
@ -29,49 +30,52 @@
#include "ObjectDefines.h" #include "ObjectDefines.h"
#include "Corpse.h" #include "Corpse.h"
static void CorpsesEraseCallBack(QueryResult *result, bool bones)
{
if(!result)
return;
do
{
Field *fields = result->Fetch();
uint32 guidlow = fields[0].GetUInt32();
float positionX = fields[1].GetFloat();
float positionY = fields[2].GetFloat();
uint32 mapid = fields[3].GetUInt32();
uint64 player_guid = MAKE_NEW_GUID(fields[4].GetUInt32(), 0, HIGHGUID_PLAYER);
uint64 guid = MAKE_NEW_GUID(guidlow, 0, HIGHGUID_CORPSE);
sLog.outDebug("[Global event] Removing %s %u (X:%f Y:%f Map:%u).",(bones?"bones":"corpse"),guidlow,positionX,positionY,mapid);
/// Resurrectable - convert corpses to bones
if(!bones)
{
if(!ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid))
{
sLog.outDebug("Corpse %u not found in world. Delete from DB.",guidlow);
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
}
}
else
///- or delete bones
{
MapManager::Instance().RemoveBonesFromMap(mapid, guid, positionX, positionY);
///- remove bones from the database
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
}
} while (result->NextRow());
delete result;
}
/// Handle periodic erase of corpses and bones /// Handle periodic erase of corpses and bones
static void CorpsesErase(bool bones,uint32 delay) static void CorpsesErase(bool bones,uint32 delay)
{ {
///- Get the list of eligible corpses/bones to be removed ///- Get the list of eligible corpses/bones to be removed
//No SQL injection (uint32 and enum) //No SQL injection (uint32 and enum)
QueryResult *result = CharacterDatabase.PQuery("SELECT guid,position_x,position_y,map,player FROM corpse WHERE UNIX_TIMESTAMP()-time > '%u' AND corpse_type %s '0'", delay, (bones ? "=" : "<>") ); CharacterDatabase.AsyncPQuery(&CorpsesEraseCallBack, bones, "SELECT guid,position_x,position_y,map,player FROM corpse WHERE UNIX_TIMESTAMP()-time > '%u' AND corpse_type %s '0'", delay, (bones ? "=" : "<>"));
if(result)
{
do
{
Field *fields = result->Fetch();
uint32 guidlow = fields[0].GetUInt32();
float positionX = fields[1].GetFloat();
float positionY = fields[2].GetFloat();
uint32 mapid = fields[3].GetUInt32();
uint64 player_guid = MAKE_NEW_GUID(fields[4].GetUInt32(), 0, HIGHGUID_PLAYER);
uint64 guid = MAKE_NEW_GUID(guidlow, 0, HIGHGUID_CORPSE);
sLog.outDebug("[Global event] Removing %s %u (X:%f Y:%f Map:%u).",(bones?"bones":"corpse"),guidlow,positionX,positionY,mapid);
/// Resurrectable - convert corpses to bones
if(!bones)
{
if(!ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid))
{
sLog.outDebug("Corpse %u not found in world. Delete from DB.",guidlow);
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
}
}
else
///- or delete bones
{
MapManager::Instance().RemoveBonesFromMap(mapid, guid, positionX, positionY);
///- remove bones from the database
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
}
} while (result->NextRow());
delete result;
}
} }
/// not thread guarded variant for call from other thread /// not thread guarded variant for call from other thread

View file

@ -128,26 +128,20 @@ void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
data << npcGUID; data << npcGUID;
data << uint32(0); // new 2.4.0 data << uint32(0); // new 2.4.0
data << uint32( TitleTextId ); data << uint32( TitleTextId );
data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x0F data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x0F
for ( unsigned int iI = 0; iI < mGossipMenu.MenuItemCount(); iI++ ) for ( unsigned int iI = 0; iI < mGossipMenu.MenuItemCount(); iI++ )
{ {
GossipMenuItem const& gItem = mGossipMenu.GetItem(iI); GossipMenuItem const& gItem = mGossipMenu.GetItem(iI);
data << uint32( iI ); data << uint32( iI );
data << uint8( gItem.m_gIcon ); data << uint8( gItem.m_gIcon );
// icons:
// 0 unlearn talents/misc
// 1 trader
// 2 taxi
// 3 trainer
// 9 BG/arena
data << uint8( gItem.m_gCoded ); // makes pop up box password data << uint8( gItem.m_gCoded ); // makes pop up box password
data << uint32(gItem.m_gBoxMoney); // money required to open menu, 2.0.3 data << uint32(gItem.m_gBoxMoney); // money required to open menu, 2.0.3
data << gItem.m_gMessage; // text for gossip item data << gItem.m_gMessage; // text for gossip item
data << gItem.m_gBoxMessage; // accept text (related to money) pop up box, 2.0.3 data << gItem.m_gBoxMessage; // accept text (related to money) pop up box, 2.0.3
} }
data << uint32( mQuestMenu.MenuItemCount() ); // max count 0x20 data << uint32( mQuestMenu.MenuItemCount() ); // max count 0x20
for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ ) for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ )
{ {
@ -155,7 +149,7 @@ void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
uint32 questID = qItem.m_qId; uint32 questID = qItem.m_qId;
Quest const* pQuest = objmgr.GetQuestTemplate(questID); Quest const* pQuest = objmgr.GetQuestTemplate(questID);
data << questID; data << uint32(questID);
data << uint32( qItem.m_qIcon ); data << uint32( qItem.m_qIcon );
data << uint32( pQuest ? pQuest->GetQuestLevel() : 0 ); data << uint32( pQuest ? pQuest->GetQuestLevel() : 0 );
std::string Title = pQuest->GetTitle(); std::string Title = pQuest->GetTitle();
@ -332,7 +326,7 @@ void QuestMenu::AddMenuItem( uint32 QuestId, uint8 Icon)
bool QuestMenu::HasItem( uint32 questid ) bool QuestMenu::HasItem( uint32 questid )
{ {
for (QuestMenuItemList::iterator i = m_qItems.begin(); i != m_qItems.end(); i++) for (QuestMenuItemList::iterator i = m_qItems.begin(); i != m_qItems.end(); ++i)
{ {
if(i->m_qId==questid) if(i->m_qId==questid)
{ {
@ -381,8 +375,7 @@ void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, std::string Title, uint
data << title; data << title;
} }
pSession->SendPacket( &data ); pSession->SendPacket( &data );
//uint32 fqid=pQuestMenu->GetItem(0).m_qId; sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u", GUID_LOPART(npcGUID));
//sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u, questid-0=%u",npcGUID,fqid);
} }
void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID ) void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID )
@ -392,7 +385,7 @@ void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID )
data << uint8(questStatus); data << uint8(questStatus);
pSession->SendPacket( &data ); pSession->SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u",GUID_LOPART(npcGUID),questStatus); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u", GUID_LOPART(npcGUID), questStatus);
} }
void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept ) void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept )
@ -462,6 +455,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
else else
data << uint32(0); data << uint32(0);
} }
data << uint32(pQuest->GetRewOrReqMoney()); data << uint32(pQuest->GetRewOrReqMoney());
} }
@ -479,7 +473,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
} }
pSession->SendPacket( &data ); pSession->SendPacket( &data );
sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId()); sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId());
} }
void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
@ -760,8 +754,10 @@ void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID
else else
data << uint32(0x03); data << uint32(0x03);
data << uint32(0x04) << uint32(0x08) << uint32(0x10); data << uint32(0x04);
data << uint32(0x08);
data << uint32(0x10);
pSession->SendPacket( &data ); pSession->SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() ); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() );
} }

View file

@ -41,10 +41,10 @@ class Player;
#define MIN_GRID_DELAY MINUTE*1000 #define MIN_GRID_DELAY MINUTE*1000
#define MIN_MAP_UPDATE_DELAY 50 #define MIN_MAP_UPDATE_DELAY 50
#define MAX_NUMBER_OF_CELLS 8 #define MAX_NUMBER_OF_CELLS 4
#define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS) #define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS)
#define CENTER_GRID_CELL_ID 256 #define CENTER_GRID_CELL_ID 128
#define CENTER_GRID_CELL_OFFSET (SIZE_OF_GRID_CELL/2) #define CENTER_GRID_CELL_OFFSET (SIZE_OF_GRID_CELL/2)
#define TOTAL_NUMBER_OF_CELLS_PER_MAP (MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_CELLS) #define TOTAL_NUMBER_OF_CELLS_PER_MAP (MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_CELLS)

View file

@ -70,7 +70,7 @@ inline void PlayerCreatureRelocationWorker(Player* pl, Creature* c)
pl->UpdateVisibilityOf(c); pl->UpdateVisibilityOf(c);
// Creature AI reaction // Creature AI reaction
if(!c->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) if(!c->hasUnitState(UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
{ {
if( c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode() ) if( c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode() )
c->AI()->MoveInLineOfSight(pl); c->AI()->MoveInLineOfSight(pl);
@ -79,13 +79,13 @@ inline void PlayerCreatureRelocationWorker(Player* pl, Creature* c)
inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2) inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2)
{ {
if(!c1->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) if(!c1->hasUnitState(UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
{ {
if( c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode() ) if( c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode() )
c1->AI()->MoveInLineOfSight(c2); c1->AI()->MoveInLineOfSight(c2);
} }
if(!c2->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) if(!c2->hasUnitState(UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
{ {
if( c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode() ) if( c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode() )
c2->AI()->MoveInLineOfSight(c1); c2->AI()->MoveInLineOfSight(c1);

View file

@ -212,7 +212,7 @@ bool Group::AddInvite(Player *player)
RemoveInvite(player); RemoveInvite(player);
m_invitees.insert(player->GetGUID()); m_invitees.insert(player);
player->SetGroupInvite(this); player->SetGroupInvite(this);
@ -231,14 +231,7 @@ bool Group::AddLeaderInvite(Player *player)
uint32 Group::RemoveInvite(Player *player) uint32 Group::RemoveInvite(Player *player)
{ {
for(InvitesList::iterator itr=m_invitees.begin(); itr!=m_invitees.end(); ++itr) m_invitees.erase(player);
{
if((*itr) == player->GetGUID())
{
m_invitees.erase(itr);
break;
}
}
player->SetGroupInvite(NULL); player->SetGroupInvite(NULL);
return GetMembersCount(); return GetMembersCount();
@ -247,14 +240,31 @@ uint32 Group::RemoveInvite(Player *player)
void Group::RemoveAllInvites() void Group::RemoveAllInvites()
{ {
for(InvitesList::iterator itr=m_invitees.begin(); itr!=m_invitees.end(); ++itr) for(InvitesList::iterator itr=m_invitees.begin(); itr!=m_invitees.end(); ++itr)
{ (*itr)->SetGroupInvite(NULL);
Player *invitee = objmgr.GetPlayer(*itr);
if(invitee)
invitee->SetGroupInvite(NULL);
}
m_invitees.clear(); m_invitees.clear();
} }
Player* Group::GetInvited(const uint64& guid) const
{
for(InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
{
if((*itr)->GetGUID() == guid)
return (*itr);
}
return NULL;
}
Player* Group::GetInvited(const std::string& name) const
{
for(InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
{
if((*itr)->GetName() == name)
return (*itr);
}
return NULL;
}
bool Group::AddMember(const uint64 &guid, const char* name) bool Group::AddMember(const uint64 &guid, const char* name)
{ {
if(!_addMember(guid, name)) if(!_addMember(guid, name))
@ -1109,7 +1119,7 @@ void Group::_setLeader(const uint64 &guid)
void Group::_removeRolls(const uint64 &guid) void Group::_removeRolls(const uint64 &guid)
{ {
for (Rolls::iterator it = RollId.begin(); it < RollId.end(); it++) for (Rolls::iterator it = RollId.begin(); it < RollId.end(); ++it)
{ {
Roll* roll = *it; Roll* roll = *it;
Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid); Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid);

View file

@ -143,7 +143,7 @@ class MANGOS_DLL_SPEC Group
typedef UNORDERED_MAP< uint32 /*mapId*/, InstanceGroupBind> BoundInstancesMap; typedef UNORDERED_MAP< uint32 /*mapId*/, InstanceGroupBind> BoundInstancesMap;
protected: protected:
typedef MemberSlotList::iterator member_witerator; typedef MemberSlotList::iterator member_witerator;
typedef std::set<uint64> InvitesList; typedef std::set<Player*> InvitesList;
typedef std::vector<Roll*> Rolls; typedef std::vector<Roll*> Rolls;
@ -183,6 +183,17 @@ class MANGOS_DLL_SPEC Group
// member manipulation methods // member manipulation methods
bool IsMember(const uint64& guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); } bool IsMember(const uint64& guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); }
bool IsLeader(const uint64& guid) const { return (GetLeaderGUID() == guid); } bool IsLeader(const uint64& guid) const { return (GetLeaderGUID() == guid); }
uint64 GetMemberGUID(const std::string& name)
{
for(member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
{
if(itr->name == name)
{
return itr->guid;
}
}
return 0;
}
bool IsAssistant(uint64 guid) const bool IsAssistant(uint64 guid) const
{ {
member_citerator mslot = _getMemberCSlot(guid); member_citerator mslot = _getMemberCSlot(guid);
@ -191,6 +202,8 @@ class MANGOS_DLL_SPEC Group
return mslot->assistant; return mslot->assistant;
} }
Player* GetInvited(const uint64& guid) const;
Player* GetInvited(const std::string& name) const;
bool SameSubGroup(uint64 guid1,const uint64& guid2) const bool SameSubGroup(uint64 guid1,const uint64& guid2) const
{ {

View file

@ -42,7 +42,7 @@
-FIX sending PartyMemberStats -FIX sending PartyMemberStats
*/ */
void WorldSession::SendPartyResult(PartyOperation operation, std::string member, PartyResult res) void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res)
{ {
WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1)); WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1));
data << (uint32)operation; data << (uint32)operation;
@ -246,17 +246,37 @@ void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
uint64 guid; uint64 guid;
recv_data >> guid; recv_data >> guid;
if(_player->InBattleGround()) //can't uninvite yourself
if(guid == GetPlayer()->GetGUID())
{ {
SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); sLog.outError("WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
return; return;
} }
std::string membername; PartyResult res = GetPlayer()->CanUninviteFromGroup();
if(!objmgr.GetPlayerNameByGUID(guid, membername)) if(res != PARTY_RESULT_OK)
return; // not found {
SendPartyResult(PARTY_OP_LEAVE, "", res);
return;
}
HandleGroupUninvite(guid, membername); Group* grp = GetPlayer()->GetGroup();
if(!grp)
return;
if(grp->IsMember(guid))
{
Player::RemoveFromGroup(grp,guid);
return;
}
if(Player* plr = grp->GetInvited(guid))
{
plr->UninviteFromGroup();
return;
}
SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_NOT_IN_YOUR_PARTY);
} }
void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data) void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
@ -266,65 +286,41 @@ void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
std::string membername; std::string membername;
recv_data >> membername; recv_data >> membername;
if(_player->InBattleGround())
{
SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED);
return;
}
// player not found // player not found
if(!normalizePlayerName(membername)) if(!normalizePlayerName(membername))
return; return;
uint64 guid = objmgr.GetPlayerGUIDByName(membername); // can't uninvite yourself
if(GetPlayer()->GetName() == membername)
// player not found
if(!guid)
return;
HandleGroupUninvite(guid, membername);
}
void WorldSession::HandleGroupUninvite(uint64 guid, std::string name)
{
Group *group = GetPlayer()->GetGroup();
if(!group)
return;
if(_player->InBattleGround())
{ {
SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); sLog.outError("WorldSession::HandleGroupUninviteNameOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
return; return;
} }
Player *player = objmgr.GetPlayer(guid); PartyResult res = GetPlayer()->CanUninviteFromGroup();
if(res != PARTY_RESULT_OK)
/** error handling **/
if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
{ {
SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_YOU_NOT_LEADER); SendPartyResult(PARTY_OP_LEAVE, "", res);
return; return;
} }
if(!group->IsMember(guid) && (player && player->GetGroupInvite() != group)) Group* grp = GetPlayer()->GetGroup();
if(!grp)
return;
if(uint64 guid = grp->GetMemberGUID(membername))
{ {
SendPartyResult(PARTY_OP_LEAVE, name, PARTY_RESULT_NOT_IN_YOUR_PARTY); Player::RemoveFromGroup(grp,guid);
return; return;
} }
if(guid == GetPlayer()->GetGUID()) if(Player* plr = grp->GetInvited(membername))
{ {
sLog.outError("WorldSession::HandleGroupUninvite: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); plr->UninviteFromGroup();
return; return;
} }
/********************/
// everything's fine, do it SendPartyResult(PARTY_OP_LEAVE, membername, PARTY_RESULT_NOT_IN_YOUR_PARTY);
if(player && player->GetGroupInvite()) // uninvite invitee
player->UninviteFromGroup();
else // uninvite member
Player::RemoveFromGroup(group,guid);
} }
void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data ) void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )

View file

@ -143,17 +143,13 @@ bool Guild::AddMember(uint64 plGuid, uint32 plRank)
CharacterDatabase.PExecute("INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')", CharacterDatabase.PExecute("INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')",
Id, GUID_LOPART(plGuid), newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str()); Id, GUID_LOPART(plGuid), newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str());
// If player not in game data in data field will be loaded from guild tables, no need to update it!!
if(pl) if(pl)
{ {
pl->SetInGuild(Id); pl->SetInGuild(Id);
pl->SetRank(newmember.RankId); pl->SetRank(newmember.RankId);
pl->SetGuildIdInvited(0); pl->SetGuildIdInvited(0);
} }
else
{
Player::SetUInt32ValueInDB(PLAYER_GUILDID, Id, plGuid);
Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, newmember.RankId, plGuid);
}
return true; return true;
} }
@ -421,69 +417,64 @@ void Guild::DelMember(uint64 guid, bool isDisbanding)
{ {
if(leaderGuid == guid && !isDisbanding) if(leaderGuid == guid && !isDisbanding)
{ {
QueryResult *result = CharacterDatabase.PQuery("SELECT guid FROM guild_member WHERE guildid='%u' AND guid != '%u' ORDER BY rank ASC LIMIT 1", Id, GUID_LOPART(leaderGuid)); MemberSlot* oldLeader = NULL;
if( result ) MemberSlot* best = NULL;
uint64 newLeaderGUID = 0;
for(Guild::MemberList::iterator i = members.begin(); i != members.end(); ++i)
{ {
uint64 newLeaderGUID; if(i->first == GUID_LOPART(guid))
Player *newLeader;
std::string newLeaderName, oldLeaderName;
newLeaderGUID = (*result)[0].GetUInt64();
delete result;
SetLeader(newLeaderGUID);
newLeader = objmgr.GetPlayer(newLeaderGUID);
if(newLeader)
{ {
newLeader->SetRank(GR_GUILDMASTER); oldLeader = &(i->second);
newLeaderName = newLeader->GetName(); continue;
}
else
{
Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, GR_GUILDMASTER, newLeaderGUID);
objmgr.GetPlayerNameByGUID(newLeaderGUID, newLeaderName);
} }
// when leader non-exist (at guild load with deleted leader only) not send broadcasts if(!best || best->RankId > i->second.RankId)
if(objmgr.GetPlayerNameByGUID(guid, oldLeaderName))
{ {
WorldPacket data(SMSG_GUILD_EVENT, (1+1+oldLeaderName.size()+1+newLeaderName.size()+1)); best = &(i->second);
data << (uint8)GE_LEADER_CHANGED; newLeaderGUID = i->first;
data << (uint8)2;
data << oldLeaderName;
data << newLeaderName;
BroadcastPacket(&data);
data.Initialize(SMSG_GUILD_EVENT, (1+1+oldLeaderName.size()+1));
data << (uint8)GE_LEFT;
data << (uint8)1;
data << oldLeaderName;
BroadcastPacket(&data);
} }
sLog.outDebug( "WORLD: Sent (SMSG_GUILD_EVENT)" );
} }
else if(!best)
{ {
Disband(); Disband();
return; return;
} }
SetLeader(newLeaderGUID);
// If player not online data in data field will be loaded from guild tabs no need to update it !!
if(Player *newLeader = objmgr.GetPlayer(newLeaderGUID))
newLeader->SetRank(GR_GUILDMASTER);
// when leader non-exist (at guild load with deleted leader only) not send broadcasts
if(oldLeader)
{
WorldPacket data(SMSG_GUILD_EVENT, (1+1+(oldLeader->name).size()+1+(best->name).size()+1));
data << (uint8)GE_LEADER_CHANGED;
data << (uint8)2;
data << oldLeader->name;
data << best->name;
BroadcastPacket(&data);
data.Initialize(SMSG_GUILD_EVENT, (1+1+(oldLeader->name).size()+1));
data << (uint8)GE_LEFT;
data << (uint8)1;
data << oldLeader->name;
BroadcastPacket(&data);
}
sLog.outDebug( "WORLD: Sent (SMSG_GUILD_EVENT)" );
} }
members.erase(GUID_LOPART(guid)); members.erase(GUID_LOPART(guid));
Player *player = objmgr.GetPlayer(guid); Player *player = objmgr.GetPlayer(guid);
// If player not online data in data field will be loaded from guild tabs no need to update it !!
if(player) if(player)
{ {
player->SetInGuild(0); player->SetInGuild(0);
player->SetRank(0); player->SetRank(0);
} }
else
{
Player::SetUInt32ValueInDB(PLAYER_GUILDID, 0, guid);
Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, GR_GUILDMASTER, guid);
}
CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guid = '%u'", GUID_LOPART(guid)); CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guid = '%u'", GUID_LOPART(guid));
} }
@ -495,10 +486,9 @@ void Guild::ChangeRank(uint64 guid, uint32 newRank)
itr->second.RankId = newRank; itr->second.RankId = newRank;
Player *player = objmgr.GetPlayer(guid); Player *player = objmgr.GetPlayer(guid);
// If player not online data in data field will be loaded from guild tabs no need to update it !!
if(player) if(player)
player->SetRank(newRank); player->SetRank(newRank);
else
Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, newRank, guid);
CharacterDatabase.PExecute( "UPDATE guild_member SET rank='%u' WHERE guid='%u'", newRank, GUID_LOPART(guid) ); CharacterDatabase.PExecute( "UPDATE guild_member SET rank='%u' WHERE guid='%u'", newRank, GUID_LOPART(guid) );
} }

View file

@ -329,7 +329,7 @@ class Guild
{ {
return (members.find(LowGuid) != members.end()); return (members.find(LowGuid) != members.end());
} }
MemberSlot* GetMemberSlot(std::string const& name, uint64& guid) MemberSlot* GetMemberSlot(const std::string& name, uint64& guid)
{ {
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{ {

View file

@ -977,7 +977,7 @@ void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data )
pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money); pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
GetPlayer()->ModifyMoney(-int(money)); GetPlayer()->ModifyMoney(-int(money));
GetPlayer()->SaveGoldToDB(); GetPlayer()->SaveDataFieldToDB(); //contains money
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction();
@ -1033,7 +1033,7 @@ void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data )
} }
GetPlayer()->ModifyMoney(money); GetPlayer()->ModifyMoney(money);
GetPlayer()->SaveGoldToDB(); GetPlayer()->SaveDataFieldToDB(); // contains money
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction();

View file

@ -339,7 +339,7 @@ void InstanceSaveManager::PackInstances()
uint32 InstanceNumber = 1; uint32 InstanceNumber = 1;
// we do assume std::set is sorted properly on integer value // we do assume std::set is sorted properly on integer value
for (std::set< uint32 >::iterator i = InstanceSet.begin(); i != InstanceSet.end(); i++) for (std::set< uint32 >::iterator i = InstanceSet.begin(); i != InstanceSet.end(); ++i)
{ {
if (*i != InstanceNumber) if (*i != InstanceNumber)
{ {

View file

@ -369,7 +369,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->ArcaneRes; data << pProto->ArcaneRes;
data << pProto->Delay; data << pProto->Delay;
data << pProto->Ammo_type; data << pProto->AmmoType;
data << pProto->RangedModRange; data << pProto->RangedModRange;
for(int s = 0; s < 5; s++) for(int s = 0; s < 5; s++)

View file

@ -443,17 +443,15 @@ inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemS
struct _Damage struct _Damage
{ {
float DamageMin; float DamageMin;
float DamageMax; float DamageMax;
uint32 DamageType; // id from Resistances.dbc uint32 DamageType; // id from Resistances.dbc
}; };
struct _ItemStat struct _ItemStat
{ {
uint32 ItemStatType; uint32 ItemStatType;
int32 ItemStatValue; int32 ItemStatValue;
}; };
struct _Spell struct _Spell
{ {
@ -464,7 +462,6 @@ struct _Spell
int32 SpellCooldown; int32 SpellCooldown;
uint32 SpellCategory; // id from SpellCategory.dbc uint32 SpellCategory; // id from SpellCategory.dbc
int32 SpellCategoryCooldown; int32 SpellCategoryCooldown;
}; };
struct _Socket struct _Socket
@ -479,7 +476,7 @@ struct ItemPrototype
uint32 Class; // id from ItemClass.dbc uint32 Class; // id from ItemClass.dbc
uint32 SubClass; // id from ItemSubClass.dbc uint32 SubClass; // id from ItemSubClass.dbc
uint32 Unk0; uint32 Unk0;
char* Name1; char* Name1;
uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc
uint32 Quality; uint32 Quality;
uint32 Flags; uint32 Flags;
@ -511,12 +508,11 @@ struct ItemPrototype
uint32 ShadowRes; uint32 ShadowRes;
uint32 ArcaneRes; uint32 ArcaneRes;
uint32 Delay; uint32 Delay;
uint32 Ammo_type; uint32 AmmoType;
float RangedModRange; float RangedModRange;
_Spell Spells[5]; _Spell Spells[5];
uint32 Bonding; uint32 Bonding;
char* Description; char* Description;
uint32 PageText; uint32 PageText;
uint32 LanguageID; uint32 LanguageID;
uint32 PageMaterial; uint32 PageMaterial;

View file

@ -1028,7 +1028,7 @@ bool ChatHandler::HandleModifyASpeedCommand(const char* args)
chr->SetSpeed(MOVE_RUN, ASpeed,true); chr->SetSpeed(MOVE_RUN, ASpeed,true);
chr->SetSpeed(MOVE_SWIM, ASpeed,true); chr->SetSpeed(MOVE_SWIM, ASpeed,true);
//chr->SetSpeed(MOVE_TURN, ASpeed,true); //chr->SetSpeed(MOVE_TURN, ASpeed,true);
chr->SetSpeed(MOVE_FLY, ASpeed,true); chr->SetSpeed(MOVE_FLIGHT, ASpeed,true);
return true; return true;
} }
@ -1144,7 +1144,7 @@ bool ChatHandler::HandleModifyBWalkCommand(const char* args)
if (needReportToTarget(chr)) if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetName(), BSpeed); ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetName(), BSpeed);
chr->SetSpeed(MOVE_WALKBACK,BSpeed,true); chr->SetSpeed(MOVE_RUN_BACK,BSpeed,true);
return true; return true;
} }
@ -1176,7 +1176,7 @@ bool ChatHandler::HandleModifyFlyCommand(const char* args)
if (needReportToTarget(chr)) if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetName(), FSpeed); ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetName(), FSpeed);
chr->SetSpeed(MOVE_FLY,FSpeed,true); chr->SetSpeed(MOVE_FLIGHT,FSpeed,true);
return true; return true;
} }

View file

@ -910,7 +910,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co
} }
// Rolling non-grouped items // Rolling non-grouped items
for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; i++ ) for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; ++i )
{ {
if ( !i->Roll() ) if ( !i->Roll() )
continue; // Bad luck for the entry continue; // Bad luck for the entry
@ -930,7 +930,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co
} }
// Now processing groups // Now processing groups
for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; i++ ) for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; ++i )
i->Process(loot); i->Process(loot);
} }
@ -959,7 +959,7 @@ bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) con
} }
// Now processing groups // Now processing groups
for (LootGroups::const_iterator i = Groups.begin() ; i != Groups.end() ; i++ ) for (LootGroups::const_iterator i = Groups.begin() ; i != Groups.end() ; ++i )
if (i->HasQuestDrop()) if (i->HasQuestDrop())
return true; return true;
@ -977,7 +977,7 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co
} }
// Checking non-grouped entries // Checking non-grouped entries
for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; i++ ) for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; ++i )
{ {
if (i->mincountOrRef < 0) // References processing if (i->mincountOrRef < 0) // References processing
{ {

View file

@ -517,7 +517,7 @@ void WorldSession::HandleTakeMoney(WorldPacket & recv_data )
// save money and mail to prevent cheating // save money and mail to prevent cheating
CharacterDatabase.BeginTransaction(); CharacterDatabase.BeginTransaction();
pl->SetUInt32ValueInDB(PLAYER_FIELD_COINAGE,pl->GetMoney(),pl->GetGUID()); pl->SaveDataFieldToDB(); // contains money
pl->_SaveMail(); pl->_SaveMail();
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction();
} }

View file

@ -573,9 +573,12 @@ void Map::Update(const uint32 &t_diff)
// for pets // for pets
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater); TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) // the player iterator is stored in the map object
// to make sure calls to Map::Remove don't invalidate it
for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
{ {
Player* plr = iter->getSource(); Player* plr = m_mapRefIter->getSource();
if(!plr->IsInWorld()) if(!plr->IsInWorld())
continue; continue;
@ -613,7 +616,6 @@ void Map::Update(const uint32 &t_diff)
} }
} }
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
// This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
if (IsBattleGroundOrArena()) if (IsBattleGroundOrArena())
@ -631,6 +633,13 @@ void Map::Update(const uint32 &t_diff)
void Map::Remove(Player *player, bool remove) void Map::Remove(Player *player, bool remove)
{ {
// this may be called during Map::Update
// after decrement+unlink, ++m_mapRefIter will continue correctly
// when the first element of the list is being removed
// nocheck_prev will return the padding element of the RefManager
// instead of NULL in the case of prev
if(m_mapRefIter == player->GetMapRef())
m_mapRefIter = m_mapRefIter->nocheck_prev();
player->GetMapRef().unlink(); player->GetMapRef().unlink();
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
@ -687,7 +696,7 @@ Map::Remove(T *obj, bool remove)
CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
{ {
sLog.outError("Map::Remove: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); sLog.outError("Map::Remove: Object " I64FMT " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
return; return;
} }
@ -695,7 +704,7 @@ Map::Remove(T *obj, bool remove)
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
return; return;
DEBUG_LOG("Remove object " I64FMTD " from grid[%u,%u]", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y); DEBUG_LOG("Remove object " I64FMT " from grid[%u,%u]", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y);
NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert( grid != NULL ); assert( grid != NULL );
@ -949,7 +958,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
if (i_InstanceId == 0) if (i_InstanceId == 0)
{ {
if(GridMaps[gx][gy]) delete (GridMaps[gx][gy]); if(GridMaps[gx][gy]) delete (GridMaps[gx][gy]);
// x and y are swaped // x and y are swapped
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx); VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx);
} }
else else
@ -1112,7 +1121,6 @@ uint8 Map::GetTerrainType(float x, float y ) const
return GridMaps[gx][gy]->terrain_type[(int)(lx)][(int)(ly)]; return GridMaps[gx][gy]->terrain_type[(int)(lx)][(int)(ly)];
else else
return 0; return 0;
} }
float Map::GetWaterLevel(float x, float y ) const float Map::GetWaterLevel(float x, float y ) const
@ -1616,6 +1624,8 @@ bool InstanceMap::Add(Player *player)
} }
if(i_data) i_data->OnPlayerEnter(player); if(i_data) i_data->OnPlayerEnter(player);
// for normal instances cancel the reset schedule when the
// first player enters (no players yet)
SetResetSchedule(false); SetResetSchedule(false);
player->SendInitWorldStates(); player->SendInitWorldStates();
@ -1642,11 +1652,12 @@ void InstanceMap::Update(const uint32& t_diff)
void InstanceMap::Remove(Player *player, bool remove) void InstanceMap::Remove(Player *player, bool remove)
{ {
sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName()); sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());
SetResetSchedule(true);
//if last player set unload timer //if last player set unload timer
if(!m_unloadTimer && m_mapRefManager.getSize() == 1) if(!m_unloadTimer && m_mapRefManager.getSize() == 1)
m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
Map::Remove(player, remove); Map::Remove(player, remove);
// for normal instances schedule the reset after all players have left
SetResetSchedule(true);
} }
void InstanceMap::CreateInstanceData(bool load) void InstanceMap::CreateInstanceData(bool load)

View file

@ -292,6 +292,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
uint32 m_unloadTimer; uint32 m_unloadTimer;
MapRefManager m_mapRefManager; MapRefManager m_mapRefManager;
MapRefManager::iterator m_mapRefIter;
private: private:
typedef GridReadGuard ReadGuard; typedef GridReadGuard ReadGuard;
typedef GridWriteGuard WriteGuard; typedef GridWriteGuard WriteGuard;

View file

@ -57,7 +57,7 @@ void MapInstanced::Update(const uint32& t)
void MapInstanced::MoveAllCreaturesInMoveList() void MapInstanced::MoveAllCreaturesInMoveList()
{ {
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
{ {
i->second->MoveAllCreaturesInMoveList(); i->second->MoveAllCreaturesInMoveList();
} }
@ -67,7 +67,7 @@ void MapInstanced::MoveAllCreaturesInMoveList()
void MapInstanced::RemoveAllObjectsInRemoveList() void MapInstanced::RemoveAllObjectsInRemoveList()
{ {
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
{ {
i->second->RemoveAllObjectsInRemoveList(); i->second->RemoveAllObjectsInRemoveList();
} }
@ -79,7 +79,7 @@ bool MapInstanced::RemoveBones(uint64 guid, float x, float y)
{ {
bool remove_result = false; bool remove_result = false;
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
{ {
remove_result = remove_result || i->second->RemoveBones(guid, x, y); remove_result = remove_result || i->second->RemoveBones(guid, x, y);
} }
@ -90,11 +90,11 @@ bool MapInstanced::RemoveBones(uint64 guid, float x, float y)
void MapInstanced::UnloadAll(bool pForce) void MapInstanced::UnloadAll(bool pForce)
{ {
// Unload instanced maps // Unload instanced maps
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
i->second->UnloadAll(pForce); i->second->UnloadAll(pForce);
// Delete the maps only after everything is unloaded to prevent crashes // Delete the maps only after everything is unloaded to prevent crashes
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
delete i->second; delete i->second;
m_InstancedMaps.clear(); m_InstancedMaps.clear();

View file

@ -39,6 +39,6 @@ class MapRefManager : public RefManager<Map, Player>
iterator rbegin() { return iterator(getLast()); } iterator rbegin() { return iterator(getLast()); }
iterator rend() { return iterator(NULL); } iterator rend() { return iterator(NULL); }
const_iterator begin() const { return const_iterator(getFirst()); } const_iterator begin() const { return const_iterator(getFirst()); }
const_iterator end() const { return const_iterator(getLast()); } const_iterator end() const { return const_iterator(NULL); }
}; };
#endif #endif

View file

@ -46,5 +46,7 @@ class MANGOS_DLL_SPEC MapReference : public Reference<Map, Player>
~MapReference() { unlink(); } ~MapReference() { unlink(); }
MapReference *next() { return (MapReference*)Reference<Map, Player>::next(); } MapReference *next() { return (MapReference*)Reference<Map, Player>::next(); }
MapReference const *next() const { return (MapReference const*)Reference<Map, Player>::next(); } MapReference const *next() const { return (MapReference const*)Reference<Map, Player>::next(); }
MapReference *nockeck_prev() { return (MapReference*)Reference<Map, Player>::nocheck_prev(); }
MapReference const *nocheck_prev() const { return (MapReference const*)Reference<Map, Player>::nocheck_prev(); }
}; };
#endif #endif

View file

@ -274,13 +274,6 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
if (uint64 lguid = GetPlayer()->GetLootGUID()) if (uint64 lguid = GetPlayer()->GetLootGUID())
DoLootRelease(lguid); DoLootRelease(lguid);
//instant logout for admins, gm's, mod's
if( GetSecurity() > SEC_PLAYER )
{
LogoutPlayer(true);
return;
}
//Can not logout if... //Can not logout if...
if( GetPlayer()->isInCombat() || //...is in combat if( GetPlayer()->isInCombat() || //...is in combat
GetPlayer()->duel || //...is in Duel GetPlayer()->duel || //...is in Duel
@ -296,8 +289,9 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
return; return;
} }
//instant logout in taverns/cities or on taxi //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in mangosd.conf
if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight()) if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight() ||
GetSecurity() >= sWorld.getConfig(CONFIG_INSTANT_LOGOUT))
{ {
LogoutPlayer(true); LogoutPlayer(true);
return; return;
@ -661,6 +655,10 @@ void WorldSession::HandleCorpseReclaimOpcode(WorldPacket &recv_data)
if (GetPlayer()->isAlive()) if (GetPlayer()->isAlive())
return; return;
// do not allow corpse reclaim in arena
if (GetPlayer()->InArena())
return;
// body not released yet // body not released yet
if(!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) if(!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
return; return;
@ -1382,7 +1380,7 @@ void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data )
sLog.outDebug("Removed FarSight from player %u", _player->GetGUIDLow()); sLog.outDebug("Removed FarSight from player %u", _player->GetGUIDLow());
break; break;
case 1: case 1:
sLog.outDebug("Added FarSight " I64FMTD " to player %u", _player->GetUInt64Value(PLAYER_FARSIGHT), _player->GetGUIDLow()); sLog.outDebug("Added FarSight " I64FMT " to player %u", _player->GetFarSight(), _player->GetGUIDLow());
break; break;
} }
} }
@ -1397,9 +1395,9 @@ void WorldSession::HandleChooseTitleOpcode( WorldPacket & recv_data )
recv_data >> title; recv_data >> title;
// -1 at none // -1 at none
if(title > 0 && title < 64) if(title > 0 && title < 128)
{ {
if(!GetPlayer()->HasFlag64(PLAYER__FIELD_KNOWN_TITLES,uint64(1) << title)) if(!GetPlayer()->HasTitle(title))
return; return;
} }
else else

View file

@ -290,22 +290,25 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
{ {
// calculate total z distance of the fall
float z_diff = GetPlayer()->m_lastFallZ - movementInfo.z;
sLog.outDebug("zDiff = %f", z_diff);
Player *target = GetPlayer(); Player *target = GetPlayer();
//Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
if (movementInfo.fallTime > 1100 && !target->isDead() && !target->isGameMaster() && // 14.57 can be calculated by resolving damageperc formular below to 0
if (z_diff >= 14.57f && !target->isDead() && !target->isGameMaster() &&
!target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL) && !target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL) &&
!target->HasAuraType(SPELL_AURA_FLY) && !target->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) ) !target->HasAuraType(SPELL_AURA_FLY) && !target->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
{ {
//Safe fall, fall time reduction //Safe fall, fall height reduction
int32 safe_fall = target->GetTotalAuraModifier(SPELL_AURA_SAFE_FALL); int32 safe_fall = target->GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0;
if(fall_time > 1100) //Prevent damage if fall time < 1100 float damageperc = 0.018f*(z_diff-safe_fall)-0.2426f;
if(damageperc >0 )
{ {
//Fall Damage calculation uint32 damage = (uint32)(damageperc * target->GetMaxHealth()*sWorld.getRate(RATE_DAMAGE_FALL));
float fallperc = float(fall_time)/1100;
uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * target->GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
float height = movementInfo.z; float height = movementInfo.z;
target->UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height); target->UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
@ -359,6 +362,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
GetPlayer()->m_movementInfo = movementInfo; GetPlayer()->m_movementInfo = movementInfo;
if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z)
GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);
if(GetPlayer()->isMovingOrTurning()) if(GetPlayer()->isMovingOrTurning())
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
@ -461,19 +466,19 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
UnitMoveType move_type; UnitMoveType move_type;
UnitMoveType force_move_type; UnitMoveType force_move_type;
static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "Walkback", "Swim", "Swimback", "Turn", "Fly", "Flyback" }; static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" };
uint16 opcode = recv_data.GetOpcode(); uint16 opcode = recv_data.GetOpcode();
switch(opcode) switch(opcode)
{ {
case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break; case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break;
case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break; case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break;
case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_WALKBACK; force_move_type = MOVE_WALKBACK; break; case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break;
case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break; case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break;
case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIMBACK; force_move_type = MOVE_SWIMBACK; break; case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break;
case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN; force_move_type = MOVE_TURN; break; case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break;
case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLY; force_move_type = MOVE_FLY; break; case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break;
case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLYBACK; force_move_type = MOVE_FLYBACK; break; case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break;
default: default:
sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode);
return; return;

View file

@ -551,9 +551,9 @@ void WorldSession::SendStablePet(uint64 guid )
void WorldSession::HandleStablePet( WorldPacket & recv_data ) void WorldSession::HandleStablePet( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8); CHECK_PACKET_SIZE(recv_data, 8);
sLog.outDebug("WORLD: Recv CMSG_STABLE_PET not dispose."); sLog.outDebug("WORLD: Recv CMSG_STABLE_PET");
uint64 npcGUID; uint64 npcGUID;
recv_data >> npcGUID; recv_data >> npcGUID;
@ -614,7 +614,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
void WorldSession::HandleUnstablePet( WorldPacket & recv_data ) void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8+4); CHECK_PACKET_SIZE(recv_data, 8+4);
sLog.outDebug("WORLD: Recv CMSG_UNSTABLE_PET."); sLog.outDebug("WORLD: Recv CMSG_UNSTABLE_PET.");
uint64 npcGUID; uint64 npcGUID;
@ -674,7 +674,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data ) void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8); CHECK_PACKET_SIZE(recv_data, 8);
sLog.outDebug("WORLD: Recv CMSG_BUY_STABLE_SLOT."); sLog.outDebug("WORLD: Recv CMSG_BUY_STABLE_SLOT.");
uint64 npcGUID; uint64 npcGUID;
@ -719,7 +719,7 @@ void WorldSession::HandleStableRevivePet( WorldPacket &/* recv_data */)
void WorldSession::HandleStableSwapPet( WorldPacket & recv_data ) void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8+4); CHECK_PACKET_SIZE(recv_data, 8+4);
sLog.outDebug("WORLD: Recv CMSG_STABLE_SWAP_PET."); sLog.outDebug("WORLD: Recv CMSG_STABLE_SWAP_PET.");
uint64 npcGUID; uint64 npcGUID;
@ -774,7 +774,7 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
void WorldSession::HandleRepairItemOpcode( WorldPacket & recv_data ) void WorldSession::HandleRepairItemOpcode( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8+8+1); CHECK_PACKET_SIZE(recv_data, 8+8+1);
sLog.outDebug("WORLD: CMSG_REPAIR_ITEM"); sLog.outDebug("WORLD: CMSG_REPAIR_ITEM");

View file

@ -376,12 +376,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
*data << ((Unit*)this)->GetSpeed( MOVE_WALK ); *data << ((Unit*)this)->GetSpeed( MOVE_WALK );
*data << ((Unit*)this)->GetSpeed( MOVE_RUN ); *data << ((Unit*)this)->GetSpeed( MOVE_RUN );
*data << ((Unit*)this)->GetSpeed( MOVE_SWIMBACK ); *data << ((Unit*)this)->GetSpeed( MOVE_SWIM_BACK );
*data << ((Unit*)this)->GetSpeed( MOVE_SWIM ); *data << ((Unit*)this)->GetSpeed( MOVE_SWIM );
*data << ((Unit*)this)->GetSpeed( MOVE_WALKBACK ); *data << ((Unit*)this)->GetSpeed( MOVE_RUN_BACK );
*data << ((Unit*)this)->GetSpeed( MOVE_FLY ); *data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT );
*data << ((Unit*)this)->GetSpeed( MOVE_FLYBACK ); *data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT_BACK );
*data << ((Unit*)this)->GetSpeed( MOVE_TURN ); *data << ((Unit*)this)->GetSpeed( MOVE_TURN_RATE );
// 0x08000000 // 0x08000000
if(flags2 & MOVEMENTFLAG_SPLINE2) if(flags2 & MOVEMENTFLAG_SPLINE2)
@ -625,7 +625,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
*data << uint32(1); *data << uint32(1);
break; break;
default: default:
*data << uint32(0); //unknown. not happen. *data << uint32(0); // unknown. not happen.
break; break;
} }
} }
@ -934,6 +934,56 @@ void Object::RemoveFlag( uint16 index, uint32 oldFlag )
} }
} }
void Object::SetByteFlag( uint16 index, uint8 offset, uint8 newFlag )
{
ASSERT( index < m_valuesCount || PrintIndexError( index , true ) );
if(offset > 4)
{
sLog.outError("Object::SetByteFlag: wrong offset %u", offset);
return;
}
if(!(uint8(m_uint32Values[ index ] >> (offset * 8)) & newFlag))
{
m_uint32Values[ index ] |= uint32(uint32(newFlag) << (offset * 8));
if(m_inWorld)
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
m_objectUpdated = true;
}
}
}
}
void Object::RemoveByteFlag( uint16 index, uint8 offset, uint8 oldFlag )
{
ASSERT( index < m_valuesCount || PrintIndexError( index , true ) );
if(offset > 4)
{
sLog.outError("Object::RemoveByteFlag: wrong offset %u", offset);
return;
}
if(uint8(m_uint32Values[ index ] >> (offset * 8)) & oldFlag)
{
m_uint32Values[ index ] &= ~uint32(uint32(oldFlag) << (offset * 8));
if(m_inWorld)
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
m_objectUpdated = true;
}
}
}
}
bool Object::PrintIndexError(uint32 index, bool set) const bool Object::PrintIndexError(uint32 index, bool set) const
{ {
sLog.outError("ERROR: Attempt %s non-existed value field: %u (count: %u) for object typeid: %u type mask: %u",(set ? "set value to" : "get value from"),index,m_valuesCount,GetTypeId(),m_objectType); sLog.outError("ERROR: Attempt %s non-existed value field: %u (count: %u) for object typeid: %u type mask: %u",(set ? "set value to" : "get value from"),index,m_valuesCount,GetTypeId(),m_objectType);
@ -1027,14 +1077,18 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const
return ( dist > 0 ? dist : 0); return ( dist > 0 ? dist : 0);
} }
bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2compare) const bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D) const
{ {
if (!obj || !IsInMap(obj)) return false; if (!obj || !IsInMap(obj)) return false;
float dx = GetPositionX() - obj->GetPositionX(); float dx = GetPositionX() - obj->GetPositionX();
float dy = GetPositionY() - obj->GetPositionY(); float dy = GetPositionY() - obj->GetPositionY();
float dz = GetPositionZ() - obj->GetPositionZ(); float distsq = dx*dx + dy*dy;
float distsq = dx*dx + dy*dy + dz*dz; if(is3D)
{
float dz = GetPositionZ() - obj->GetPositionZ();
distsq += dz*dz;
}
float sizefactor = GetObjectSize() + obj->GetObjectSize(); float sizefactor = GetObjectSize() + obj->GetObjectSize();
float maxdist = dist2compare + sizefactor; float maxdist = dist2compare + sizefactor;

View file

@ -226,6 +226,24 @@ class MANGOS_DLL_SPEC Object
return (m_uint32Values[ index ] & flag) != 0; return (m_uint32Values[ index ] & flag) != 0;
} }
void SetByteFlag( uint16 index, uint8 offset, uint8 newFlag );
void RemoveByteFlag( uint16 index, uint8 offset, uint8 newFlag );
void ToggleFlag( uint16 index, uint8 offset, uint8 flag )
{
if(HasByteFlag(index, offset, flag))
RemoveByteFlag(index, offset, flag);
else
SetByteFlag(index, offset, flag);
}
bool HasByteFlag( uint16 index, uint8 offset, uint8 flag ) const
{
ASSERT( index < m_valuesCount || PrintIndexError( index , false ) );
ASSERT( offset < 4 );
return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0;
}
void ApplyModFlag( uint16 index, uint32 flag, bool apply) void ApplyModFlag( uint16 index, uint32 flag, bool apply)
{ {
if(apply) SetFlag(index,flag); else RemoveFlag(index,flag); if(apply) SetFlag(index,flag); else RemoveFlag(index,flag);
@ -297,7 +315,7 @@ class MANGOS_DLL_SPEC Object
{ {
int32 *m_int32Values; int32 *m_int32Values;
uint32 *m_uint32Values; uint32 *m_uint32Values;
float *m_floatValues; float *m_floatValues;
}; };
uint32 *m_uint32Values_mirror; uint32 *m_uint32Values_mirror;
@ -399,7 +417,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
float GetDistance2d(const float x, const float y) const; float GetDistance2d(const float x, const float y) const;
float GetDistanceZ(const WorldObject* obj) const; float GetDistanceZ(const WorldObject* obj) const;
bool IsInMap(const WorldObject* obj) const { return GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); } bool IsInMap(const WorldObject* obj) const { return GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); }
bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare) const; bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const;
bool IsWithinLOS(const float x, const float y, const float z ) const; bool IsWithinLOS(const float x, const float y, const float z ) const;
bool IsWithinLOSInMap(const WorldObject* obj) const; bool IsWithinLOSInMap(const WorldObject* obj) const;

View file

@ -45,7 +45,6 @@ INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ZThread::FastMutex);
namespace MaNGOS namespace MaNGOS
{ {
struct MANGOS_DLL_DECL BuildUpdateForPlayer struct MANGOS_DLL_DECL BuildUpdateForPlayer
{ {
Player &i_player; Player &i_player;
@ -551,7 +550,7 @@ void ObjectAccessor::UpdateVisibilityForPlayer( Player* player )
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap; template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
template <class T> ZThread::FastMutex HashMapHolder<T>::i_lock; template <class T> ZThread::FastMutex HashMapHolder<T>::i_lock;
/// Global defintions for the hashmap storage /// Global definitions for the hashmap storage
template class HashMapHolder<Player>; template class HashMapHolder<Player>;
template class HashMapHolder<Pet>; template class HashMapHolder<Pet>;

View file

@ -72,7 +72,7 @@ class HashMapHolder
static LockType* GetLock() { return &i_lock; } static LockType* GetLock() { return &i_lock; }
private: private:
//Non instanciable only static //Non instanceable only static
HashMapHolder() {} HashMapHolder() {}
static LockType i_lock; static LockType i_lock;

View file

@ -50,7 +50,7 @@ ObjectGridRespawnMover::Visit(CreatureMapType &m)
{ {
// creature in unloading grid can have respawn point in another grid // creature in unloading grid can have respawn point in another grid
// if it will be unloaded then it will not respawn in original grid until unload/load original grid // if it will be unloaded then it will not respawn in original grid until unload/load original grid
// move to respwn point to prevent this case. For player view in respawn grid this wll be normal respawn. // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
for(CreatureMapType::iterator iter=m.begin(), next; iter != m.end(); iter = next) for(CreatureMapType::iterator iter=m.begin(), next; iter != m.end(); iter = next)
{ {
next = iter; ++next; next = iter; ++next;

View file

@ -192,7 +192,7 @@ Group * ObjectMgr::GetGroupByLeader(const uint64 &guid) const
Guild * ObjectMgr::GetGuildById(const uint32 GuildId) const Guild * ObjectMgr::GetGuildById(const uint32 GuildId) const
{ {
for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++) for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
if ((*itr)->GetId() == GuildId) if ((*itr)->GetId() == GuildId)
return *itr; return *itr;
@ -201,7 +201,7 @@ Guild * ObjectMgr::GetGuildById(const uint32 GuildId) const
Guild * ObjectMgr::GetGuildByName(std::string guildname) const Guild * ObjectMgr::GetGuildByName(std::string guildname) const
{ {
for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++) for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
if ((*itr)->GetName() == guildname) if ((*itr)->GetName() == guildname)
return *itr; return *itr;
@ -210,7 +210,7 @@ Guild * ObjectMgr::GetGuildByName(std::string guildname) const
std::string ObjectMgr::GetGuildNameById(const uint32 GuildId) const std::string ObjectMgr::GetGuildNameById(const uint32 GuildId) const
{ {
for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++) for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
if ((*itr)->GetId() == GuildId) if ((*itr)->GetId() == GuildId)
return (*itr)->GetName(); return (*itr)->GetName();
@ -228,7 +228,7 @@ Guild* ObjectMgr::GetGuildByLeader(const uint64 &guid) const
ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 ArenaTeamId) const ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 ArenaTeamId) const
{ {
for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++) for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); ++itr)
if ((*itr)->GetId() == ArenaTeamId) if ((*itr)->GetId() == ArenaTeamId)
return *itr; return *itr;
@ -237,7 +237,7 @@ ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 ArenaTeamId) const
ArenaTeam* ObjectMgr::GetArenaTeamByName(std::string arenateamname) const ArenaTeam* ObjectMgr::GetArenaTeamByName(std::string arenateamname) const
{ {
for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++) for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); ++itr)
if ((*itr)->GetName() == arenateamname) if ((*itr)->GetName() == arenateamname)
return *itr; return *itr;
@ -246,7 +246,7 @@ ArenaTeam* ObjectMgr::GetArenaTeamByName(std::string arenateamname) const
ArenaTeam* ObjectMgr::GetArenaTeamByCapitan(uint64 const& guid) const ArenaTeam* ObjectMgr::GetArenaTeamByCapitan(uint64 const& guid) const
{ {
for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++) for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); ++itr)
if ((*itr)->GetCaptain() == guid) if ((*itr)->GetCaptain() == guid)
return *itr; return *itr;
@ -2090,8 +2090,7 @@ void ObjectMgr::LoadPlayerInfo()
barGoLink bar( 1 ); barGoLink bar( 1 );
sLog.outString(); sLog.outString();
sLog.outString( ">> Loaded %u player create items", count ); sLog.outString( ">> Loaded %u custom player create items", count );
sLog.outErrorDb( "Error loading `playercreateinfo_item` table or empty table.");
} }
else else
{ {
@ -2143,7 +2142,7 @@ void ObjectMgr::LoadPlayerInfo()
delete result; delete result;
sLog.outString(); sLog.outString();
sLog.outString( ">> Loaded %u player create items", count ); sLog.outString( ">> Loaded %u custom player create items", count );
} }
} }
@ -2863,7 +2862,7 @@ void ObjectMgr::LoadQuests()
delete result; delete result;
// Post processing // Post processing
for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); iter++) for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); ++iter)
{ {
Quest * qinfo = iter->second; Quest * qinfo = iter->second;
@ -4082,7 +4081,7 @@ void ObjectMgr::LoadPageTexts()
{ {
std::ostringstream ss; std::ostringstream ss;
ss<< "The text page(s) "; ss<< "The text page(s) ";
for (std::set<uint32>::iterator itr= checkedPages.begin();itr!=checkedPages.end(); itr++) for (std::set<uint32>::iterator itr= checkedPages.begin();itr!=checkedPages.end(); ++itr)
ss << *itr << " "; ss << *itr << " ";
ss << "create(s) a circular reference, which can cause the server to freeze. Changing Next_Page of page " ss << "create(s) a circular reference, which can cause the server to freeze. Changing Next_Page of page "
<< pageItr->Page_ID <<" to 0"; << pageItr->Page_ID <<" to 0";
@ -5066,7 +5065,7 @@ AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
{ {
const MapEntry *mapEntry = sMapStore.LookupEntry(Map); const MapEntry *mapEntry = sMapStore.LookupEntry(Map);
if(!mapEntry) return NULL; if(!mapEntry) return NULL;
for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); itr++) for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); ++itr)
{ {
if(itr->second.target_mapId == mapEntry->entrance_map) if(itr->second.target_mapId == mapEntry->entrance_map)
{ {
@ -6321,7 +6320,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
bar.step(); bar.step();
sLog.outString(""); sLog.outString("");
if(min_value > 0) // error only in case internal strings if(min_value == MIN_MANGOS_STRING_ID) // error only in case internal strings
sLog.outErrorDb(">> Loaded 0 mangos strings. DB table `%s` is empty. Cannot continue.",table); sLog.outErrorDb(">> Loaded 0 mangos strings. DB table `%s` is empty. Cannot continue.",table);
else else
sLog.outString(">> Loaded 0 string templates. DB table `%s` is empty.",table); sLog.outString(">> Loaded 0 string templates. DB table `%s` is empty.",table);
@ -6387,7 +6386,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
delete result; delete result;
sLog.outString(); sLog.outString();
if(min_value > 0) // internal mangos strings if(min_value == MIN_MANGOS_STRING_ID) // error only in case internal strings
sLog.outString( ">> Loaded %u MaNGOS strings from table %s", count,table); sLog.outString( ">> Loaded %u MaNGOS strings from table %s", count,table);
else else
sLog.outString( ">> Loaded %u string templates from %s", count,table); sLog.outString( ">> Loaded %u string templates from %s", count,table);
@ -7257,7 +7256,7 @@ void ObjectMgr::CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids)
if(itrM->second.dataint) if(itrM->second.dataint)
{ {
if(!GetMangosStringLocale (itrM->second.dataint)) if(!GetMangosStringLocale (itrM->second.dataint))
sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", *itrM); sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", itrM->first);
if(ids.count(itrM->second.dataint)) if(ids.count(itrM->second.dataint))
ids.erase(itrM->second.dataint); ids.erase(itrM->second.dataint);

View file

@ -841,6 +841,7 @@ class ObjectMgr
int GetOrNewIndexForLocale(LocaleConstant loc); int GetOrNewIndexForLocale(LocaleConstant loc);
int DBCLocaleIndex; int DBCLocaleIndex;
private: private:
void LoadScripts(ScriptMapMap& scripts, char const* tablename); void LoadScripts(ScriptMapMap& scripts, char const* tablename);
void CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids); void CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids);

View file

@ -138,7 +138,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode }, /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode },
/*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode }, /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode },
/*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Depricated }, /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated },
/*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode }, /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode },
/*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode }, /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode },

View file

@ -170,7 +170,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
} }
Map *map = owner->GetMap(); Map *map = owner->GetMap();
uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET); uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_PET);
uint32 pet_number = fields[0].GetUInt32(); uint32 pet_number = fields[0].GetUInt32();
if(!Create(guid, map, petentry, pet_number)) if(!Create(guid, map, petentry, pet_number))
{ {
@ -179,7 +179,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
} }
float px, py, pz; float px, py, pz;
owner->GetClosePoint(px, py, pz,GetObjectSize(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
Relocate(px, py, pz, owner->GetOrientation()); Relocate(px, py, pz, owner->GetOrientation());
@ -351,7 +351,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
if(owner->GetTypeId() == TYPEID_PLAYER && getPetType() == HUNTER_PET) if(owner->GetTypeId() == TYPEID_PLAYER && getPetType() == HUNTER_PET)
{ {
result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'",owner->GetGUIDLow(),GetCharmInfo()->GetPetNumber()); result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", owner->GetGUIDLow(), GetCharmInfo()->GetPetNumber());
if(result) if(result)
{ {
@ -950,14 +950,14 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
} }
SetDisplayId(creature->GetDisplayId()); SetDisplayId(creature->GetDisplayId());
SetNativeDisplayId(creature->GetNativeDisplayId()); SetNativeDisplayId(creature->GetNativeDisplayId());
SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS)); SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
SetPower( POWER_HAPPINESS,166500); SetPower(POWER_HAPPINESS, 166500);
setPowerType(POWER_FOCUS); setPowerType(POWER_FOCUS);
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0); SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(creature->getLevel()))/4)); SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(creature->getLevel()))/4));
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
SetUInt32Value(UNIT_NPC_FLAGS , 0); SetUInt32Value(UNIT_NPC_FLAGS, 0);
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family); CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family);
if( char* familyname = cFamily->Name[sWorld.GetDefaultDbcLocale()] ) if( char* familyname = cFamily->Name[sWorld.GetDefaultDbcLocale()] )
@ -993,7 +993,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
uint32 creature_ID = (getPetType() == HUNTER_PET) ? 1 : cinfo->Entry; uint32 creature_ID = (getPetType() == HUNTER_PET) ? 1 : cinfo->Entry;
SetLevel( petlevel); SetLevel(petlevel);
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
@ -1006,7 +1006,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0);
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family); CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family);
if(cFamily && cFamily->minScale > 0.0f) if(cFamily && cFamily->minScale > 0.0f && getPetType()==HUNTER_PET)
{ {
float scale; float scale;
if (getLevel() >= cFamily->maxScaleLevel) if (getLevel() >= cFamily->maxScaleLevel)
@ -1082,7 +1082,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
for(int stat = 0; stat < MAX_STATS; ++stat) for(int stat = 0; stat < MAX_STATS; ++stat)
{ {
SetCreateStat(Stats(stat),float(pInfo->stats[stat])); SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
} }
} }
else // not exist in DB, use some default fake data else // not exist in DB, use some default fake data
@ -1093,11 +1093,11 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
SetCreateHealth(uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) ); SetCreateHealth(uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
SetCreateMana( uint32(((float(cinfo->maxmana) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) ); SetCreateMana( uint32(((float(cinfo->maxmana) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
SetCreateStat(STAT_STRENGTH,22); SetCreateStat(STAT_STRENGTH, 22);
SetCreateStat(STAT_AGILITY,22); SetCreateStat(STAT_AGILITY, 22);
SetCreateStat(STAT_STAMINA,25); SetCreateStat(STAT_STAMINA, 25);
SetCreateStat(STAT_INTELLECT,28); SetCreateStat(STAT_INTELLECT, 28);
SetCreateStat(STAT_SPIRIT,27); SetCreateStat(STAT_SPIRIT, 27);
} }
break; break;
} }
@ -1132,34 +1132,35 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
// remove elite bonuses included in DB values // remove elite bonuses included in DB values
SetCreateHealth( uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) ); SetCreateHealth( uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) );
SetCreateStat(STAT_STRENGTH,22); SetCreateStat(STAT_STRENGTH, 22);
SetCreateStat(STAT_AGILITY,22); SetCreateStat(STAT_AGILITY, 22);
SetCreateStat(STAT_STAMINA,25); SetCreateStat(STAT_STAMINA, 25);
SetCreateStat(STAT_INTELLECT,28); SetCreateStat(STAT_INTELLECT, 28);
SetCreateStat(STAT_SPIRIT,27); SetCreateStat(STAT_SPIRIT, 27);
} }
break; break;
} }
case GUARDIAN_PET: case GUARDIAN_PET:
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000); SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
SetCreateMana( 28 + 10*petlevel ); SetCreateMana(28 + 10*petlevel);
SetCreateHealth( 28 + 30*petlevel ); SetCreateHealth(28 + 30*petlevel);
// FIXME: this is wrong formula, possible each guardian pet have own damage formula // FIXME: this is wrong formula, possible each guardian pet have own damage formula
//these formula may not be correct; however, it is designed to be close to what it should be //these formula may not be correct; however, it is designed to be close to what it should be
//this makes dps 0.5 of pets level //this makes dps 0.5 of pets level
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
//damage range is then petlevel / 2 //damage range is then petlevel / 2
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)) ); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
break; break;
default: default:
sLog.outError("Pet have incorrect type (%u) for levelup.",getPetType()); break; sLog.outError("Pet have incorrect type (%u) for levelup.", getPetType());
break;
} }
for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]) ); SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]));
UpdateAllStats(); UpdateAllStats();
@ -1190,7 +1191,7 @@ bool Pet::HaveInDiet(ItemPrototype const* item) const
uint32 Pet::GetCurrentFoodBenefitLevel(uint32 itemlevel) uint32 Pet::GetCurrentFoodBenefitLevel(uint32 itemlevel)
{ {
// -5 or greater food level // -5 or greater food level
if(getLevel() <= itemlevel +5) //possible to feed level 60 pet with level 55 level food for full effect if(getLevel() <= itemlevel + 5) //possible to feed level 60 pet with level 55 level food for full effect
return 35000; return 35000;
// -10..-6 // -10..-6
else if(getLevel() <= itemlevel + 10) //pure guess, but sounds good else if(getLevel() <= itemlevel + 10) //pure guess, but sounds good
@ -1240,7 +1241,7 @@ void Pet::_LoadSpellCooldowns()
_AddCreatureSpellCooldown(spell_id,db_time); _AddCreatureSpellCooldown(spell_id,db_time);
sLog.outDebug("Pet (Number: %u) spell %u cooldown loaded (%u secs).",m_charmInfo->GetPetNumber(),spell_id,uint32(db_time-curTime)); sLog.outDebug("Pet (Number: %u) spell %u cooldown loaded (%u secs).", m_charmInfo->GetPetNumber(), spell_id, uint32(db_time-curTime));
} }
while( result->NextRow() ); while( result->NextRow() );
@ -1387,7 +1388,7 @@ void Pet::_LoadAuras(uint32 timediff)
void Pet::_SaveAuras() void Pet::_SaveAuras()
{ {
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
AuraMap const& auras = GetAuras(); AuraMap const& auras = GetAuras();
if (auras.empty()) if (auras.empty())
@ -1493,7 +1494,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id); uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id);
for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); itr++) for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{ {
if(itr->second->state == PETSPELL_REMOVED) continue; if(itr->second->state == PETSPELL_REMOVED) continue;
@ -1762,7 +1763,7 @@ void Pet::CastPetAuras(bool current)
if(getPetType() != HUNTER_PET && (getPetType() != SUMMON_PET || owner->getClass() != CLASS_WARLOCK)) if(getPetType() != HUNTER_PET && (getPetType() != SUMMON_PET || owner->getClass() != CLASS_WARLOCK))
return; return;
for(PetAuraSet::iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end(); ) for(PetAuraSet::iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end();)
{ {
PetAura const* pa = *itr; PetAura const* pa = *itr;
++itr; ++itr;
@ -1783,7 +1784,7 @@ void Pet::CastPetAura(PetAura const* aura)
if(auraId == 35696) // Demonic Knowledge if(auraId == 35696) // Demonic Knowledge
{ {
int32 basePoints = int32(aura->GetDamage() * (GetStat(STAT_STAMINA) + GetStat(STAT_INTELLECT)) / 100); int32 basePoints = int32(aura->GetDamage() * (GetStat(STAT_STAMINA) + GetStat(STAT_INTELLECT)) / 100);
CastCustomSpell(this,auraId,&basePoints, NULL, NULL, true ); CastCustomSpell(this, auraId, &basePoints, NULL, NULL, true);
} }
else else
CastSpell(this, auraId, true); CastSpell(this, auraId, true);

View file

@ -78,6 +78,7 @@ struct PetSpell
{ {
uint16 slotId; uint16 slotId;
uint16 active; uint16 active;
PetSpellState state : 16; PetSpellState state : 16;
PetSpellType type : 16; PetSpellType type : 16;
}; };
@ -144,7 +145,7 @@ class Pet : public Creature
bool isTemporarySummoned() const { return m_duration > 0; } bool isTemporarySummoned() const { return m_duration > 0; }
bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number); bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number);
bool CreateBaseAtCreature( Creature* creature ); bool CreateBaseAtCreature(Creature* creature);
bool LoadPetFromDB( Unit* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false ); bool LoadPetFromDB( Unit* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
void SavePetToDB(PetSaveMode mode); void SavePetToDB(PetSaveMode mode);
void Remove(PetSaveMode mode, bool returnreagent = false); void Remove(PetSaveMode mode, bool returnreagent = false);

View file

@ -34,7 +34,7 @@
void WorldSession::HandlePetAction( WorldPacket & recv_data ) void WorldSession::HandlePetAction( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8+2+2+8); CHECK_PACKET_SIZE(recv_data, 8+2+2+8);
uint64 guid1; uint64 guid1;
uint16 spellid; uint16 spellid;
@ -46,8 +46,8 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
recv_data >> guid2; //tag guid recv_data >> guid2; //tag guid
// used also for charmed creature // used also for charmed creature
Unit* pet= ObjectAccessor::GetUnit(*_player,guid1); Unit* pet= ObjectAccessor::GetUnit(*_player, guid1);
sLog.outDetail( "HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.\n", uint32(GUID_LOPART(guid1)), flag, spellid, uint32(GUID_LOPART(guid2)) ); sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.\n", uint32(GUID_LOPART(guid1)), flag, spellid, uint32(GUID_LOPART(guid2)) );
if(!pet) if(!pet)
{ {
sLog.outError( "Pet %u not exist.\n", uint32(GUID_LOPART(guid1)) ); sLog.outError( "Pet %u not exist.\n", uint32(GUID_LOPART(guid1)) );
@ -56,7 +56,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm()) if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
{ {
sLog.outError( "HandlePetAction.Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid1)),GetPlayer()->GetName() ); sLog.outError("HandlePetAction.Pet %u isn't pet of player %s.\n", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName() );
return; return;
} }
@ -99,7 +99,10 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
return; return;
// not let attack friendly units. // not let attack friendly units.
if( GetPlayer()->IsFriendlyTo(TargetUnit)) if(GetPlayer()->IsFriendlyTo(TargetUnit))
return;
// Not let attack through obstructions
if(!pet->IsWithinLOSInMap(TargetUnit))
return; return;
if(pet->getVictim()) if(pet->getVictim())
@ -307,7 +310,7 @@ void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8+4+2+2); CHECK_PACKET_SIZE(recv_data, 8+4+2+2);
sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION\n" ); sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION\n" );

View file

@ -173,7 +173,7 @@ void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all )
if(all) if(all)
{ {
for (uint8 i=0; i<TaxiMaskSize; i++) for (uint8 i=0; i<TaxiMaskSize; i++)
data << sTaxiNodesMask[i]; // all existed nodes data << uint32(sTaxiNodesMask[i]); // all existed nodes
} }
else else
{ {
@ -494,13 +494,6 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
for (int i = 0; i < PLAYER_SLOTS_COUNT; i++) for (int i = 0; i < PLAYER_SLOTS_COUNT; i++)
m_items[i] = NULL; m_items[i] = NULL;
//for(int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; j++)
//{
// SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOT_1+j*2,0);
// SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1+j,0);
// SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP_1+j,0);
//}
m_race = race; m_race = race;
m_class = class_; m_class = class_;
@ -553,7 +546,9 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
setFactionForRace(m_race); setFactionForRace(m_race);
SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( race ) | ( class_ << 8 ) | ( gender << 16 ) | ( powertype << 24 ) ) ); uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 );
SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) );
SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 );
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE );
@ -578,7 +573,14 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 ); SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 );
// set starting level // set starting level
SetUInt32Value( UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) ); if (GetSession()->GetSecurity() >= SEC_MODERATOR)
SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_GM_LEVEL));
else
SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL));
SetUInt32Value (PLAYER_FIELD_COINAGE, sWorld.getConfig(CONFIG_START_PLAYER_MONEY));
SetUInt32Value (PLAYER_FIELD_HONOR_CURRENCY, sWorld.getConfig(CONFIG_START_HONOR_POINTS));
SetUInt32Value (PLAYER_FIELD_ARENA_CURRENCY, sWorld.getConfig(CONFIG_START_ARENA_POINTS));
// Played time // Played time
m_Last_tick = time(NULL); m_Last_tick = time(NULL);
@ -600,8 +602,10 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
SetPower(POWER_MANA,GetMaxPower(POWER_MANA)); SetPower(POWER_MANA,GetMaxPower(POWER_MANA));
} }
// original spells
learnDefaultSpells(true); learnDefaultSpells(true);
// original action bar
std::list<uint16>::const_iterator action_itr[4]; std::list<uint16>::const_iterator action_itr[4];
for(int i=0; i<4; i++) for(int i=0; i<4; i++)
action_itr[i] = info->action[i].begin(); action_itr[i] = info->action[i].begin();
@ -618,37 +622,59 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
++action_itr[i]; ++action_itr[i];
} }
for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++) // original items
CharStartOutfitEntry const* oEntry = NULL;
for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
{ {
uint32 titem_id = item_id_itr->item_id; if(CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i))
uint32 titem_amount = item_id_itr->item_amount;
sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount);
// attempt equip
uint16 eDest;
uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false );
if( msg == EQUIP_ERR_OK )
{ {
EquipNewItem( eDest, titem_id, titem_amount, true); if(entry->RaceClassGender == RaceClassGender)
AutoUnequipOffhandIfNeed(); {
continue; // equipped, to next oEntry = entry;
break;
}
} }
// attempt store
ItemPosCountVec sDest;
// store in main bag to simplify second pass (special bags can be not equipped yet at this moment)
msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount );
if( msg == EQUIP_ERR_OK )
{
StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) );
continue; // stored, to next
}
// item can't be added
sLog.outError("STORAGE: Can't equip or store initial item %u for race %u class %u , error msg = %u",titem_id,race,class_,msg);
} }
if(oEntry)
{
for(int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
{
if(oEntry->ItemId[j] <= 0)
continue;
uint32 item_id = oEntry->ItemId[j];
ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id);
if(!iProto)
{
sLog.outErrorDb("Initial item id %u (race %u class %u) from CharStartOutfit.dbc not listed in `item_template`, ignoring.",item_id,getRace(),getClass());
continue;
}
uint32 count = iProto->Stackable; // max stack by default (mostly 1)
if(iProto->Class==ITEM_CLASS_CONSUMABLE && iProto->SubClass==ITEM_SUBCLASS_FOOD)
{
switch(iProto->Spells[0].SpellCategory)
{
case 11: // food
if(iProto->Stackable > 4)
count = 4;
break;
case 59: // drink
if(iProto->Stackable > 2)
count = 2;
break;
}
}
StoreNewItemInBestSlot(item_id, count);
}
}
for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++)
StoreNewItemInBestSlot(item_id_itr->item_id, item_id_itr->item_amount);
// bags and main-hand weapon must equipped at this moment // bags and main-hand weapon must equipped at this moment
// now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon) // now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon)
// or ammo not equipped in special bag // or ammo not equipped in special bag
@ -687,6 +713,35 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
return true; return true;
} }
bool Player::StoreNewItemInBestSlot(uint32 titem_id, uint32 titem_amount)
{
sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount);
// attempt equip
uint16 eDest;
uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false );
if( msg == EQUIP_ERR_OK )
{
EquipNewItem( eDest, titem_id, titem_amount, true);
AutoUnequipOffhandIfNeed();
return true; // equipped
}
// attempt store
ItemPosCountVec sDest;
// store in main bag to simplify second pass (special bags can be not equipped yet at this moment)
msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount );
if( msg == EQUIP_ERR_OK )
{
StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) );
return true; // stored
}
// item can't be added
sLog.outError("STORAGE: Can't equip or store initial item %u for race %u class %u , error msg = %u",titem_id,getRace(),getClass(),msg);
return false;
}
void Player::StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue) void Player::StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue)
{ {
uint32 BreathRegen = (uint32)-1; uint32 BreathRegen = (uint32)-1;
@ -734,9 +789,8 @@ void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 da
data << (uint32)damage; data << (uint32)damage;
data << (uint32)0; data << (uint32)0;
data << (uint32)0; data << (uint32)0;
//m_session->SendPacket(&data);
//Let other players see that you get damage
SendMessageToSet(&data, true); SendMessageToSet(&data, true);
DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
if(type==DAMAGE_FALL && !isAlive()) // DealDamage not apply item durability loss at self damage if(type==DAMAGE_FALL && !isAlive()) // DealDamage not apply item durability loss at self damage
@ -754,8 +808,8 @@ void Player::HandleDrowning()
if(!m_isunderwater) if(!m_isunderwater)
return; return;
//if have water breath , then remove bar //if player is GM, have waterbreath, is dead or if breathing is disabled then return
if(waterbreath || isGameMaster() || !isAlive()) if(waterbreath || isGameMaster() || !isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
{ {
StopMirrorTimer(BREATH_TIMER); StopMirrorTimer(BREATH_TIMER);
m_isunderwater = 0; m_isunderwater = 0;
@ -782,7 +836,7 @@ void Player::HandleDrowning()
m_isunderwater|= 0x04; m_isunderwater|= 0x04;
StartMirrorTimer(BREATH_TIMER, UnderWaterTime); StartMirrorTimer(BREATH_TIMER, UnderWaterTime);
} }
//continius trigger drowning "Damage" //continuous trigger drowning "Damage"
if ((m_breathTimer == 0) && (m_isunderwater & 0x01)) if ((m_breathTimer == 0) && (m_isunderwater & 0x01))
{ {
//TODO: Check this formula //TODO: Check this formula
@ -904,7 +958,7 @@ void Player::SetDrunkValue(uint16 newDrunkenValue, uint32 itemId)
return; return;
WorldPacket data(SMSG_CROSSED_INEBRIATION_THRESHOLD, (8+4+4)); WorldPacket data(SMSG_CROSSED_INEBRIATION_THRESHOLD, (8+4+4));
data << GetGUID(); data << uint64(GetGUID());
data << uint32(newDrunkenState); data << uint32(newDrunkenState);
data << uint32(itemId); data << uint32(itemId);
@ -1277,7 +1331,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << uint8(getLevel()); // player level *p_data << uint8(getLevel()); // player level
// do not use GetMap! it will spawn a new instance since the bound instances are not loaded // do not use GetMap! it will spawn a new instance since the bound instances are not loaded
uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY()); uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY());
sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId);
*p_data << zoneId; *p_data << zoneId;
*p_data << GetMapId(); *p_data << GetMapId();
@ -1285,7 +1339,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << GetPositionY(); *p_data << GetPositionY();
*p_data << GetPositionZ(); *p_data << GetPositionZ();
*p_data << GetUInt32Value(PLAYER_GUILDID); // guild id *p_data << (result ? result->Fetch()[13].GetUInt32() : 0);
uint32 char_flags = 0; uint32 char_flags = 0;
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM))
@ -1298,7 +1352,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
char_flags |= CHARACTER_FLAG_RENAME; char_flags |= CHARACTER_FLAG_RENAME;
// always send the flag if declined names aren't used // always send the flag if declined names aren't used
// to let the client select a default method of declining the name // to let the client select a default method of declining the name
if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[13].GetCppString() != "")) if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[14].GetCppString() != ""))
char_flags |= CHARACTER_FLAG_DECLINED; char_flags |= CHARACTER_FLAG_DECLINED;
*p_data << (uint32)char_flags; // character flags *p_data << (uint32)char_flags; // character flags
@ -1502,6 +1556,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
else else
// this will be used instead of the current location in SaveToDB // this will be used instead of the current location in SaveToDB
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
SetFallInformation(0, z);
//BuildHeartBeatMsg(&data); //BuildHeartBeatMsg(&data);
//SendMessageToSet(&data, true); //SendMessageToSet(&data, true);
@ -1649,6 +1704,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
} }
m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o); m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o);
SetFallInformation(0, final_z);
// if the player is saved before worldportack (at logout for example) // if the player is saved before worldportack (at logout for example)
// this will be used instead of the current location in SaveToDB // this will be used instead of the current location in SaveToDB
@ -1968,23 +2024,23 @@ bool Player::IsInSameGroupWith(Player const* p) const
/// \todo Shouldn't we also check if there is no other invitees before disbanding the group? /// \todo Shouldn't we also check if there is no other invitees before disbanding the group?
void Player::UninviteFromGroup() void Player::UninviteFromGroup()
{ {
if(GetGroupInvite()) // uninvited invitee Group* group = GetGroupInvite();
if(!group)
return;
group->RemoveInvite(this);
if(group->GetMembersCount() <= 1) // group has just 1 member => disband
{ {
Group* group = GetGroupInvite(); if(group->IsCreated())
group->RemoveInvite(this);
if(group->GetMembersCount() <= 1) // group has just 1 member => disband
{ {
if(group->IsCreated()) group->Disband(true);
{ objmgr.RemoveGroup(group);
group->Disband(true);
objmgr.RemoveGroup(group);
}
else
group->RemoveAllInvites();
delete group;
} }
else
group->RemoveAllInvites();
delete group;
} }
} }
@ -2094,7 +2150,7 @@ void Player::GiveLevel(uint32 level)
if(getLevel()!= level) if(getLevel()!= level)
m_Played_time[1] = 0; // Level Played Time reset m_Played_time[1] = 0; // Level Played Time reset
SetLevel(level); SetLevel(level);
UpdateMaxSkills(); UpdateSkillsForLevel ();
// save base values (bonuses already included in stored stats // save base values (bonuses already included in stored stats
for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) for(int i = STAT_STRENGTH; i < MAX_STATS; ++i)
@ -2167,7 +2223,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ); SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) );
SetUInt32Value(PLAYER_NEXT_LEVEL_XP, MaNGOS::XP::xp_to_level(getLevel())); SetUInt32Value(PLAYER_NEXT_LEVEL_XP, MaNGOS::XP::xp_to_level(getLevel()));
UpdateMaxSkills (); UpdateSkillsForLevel ();
// set default cast time multiplier // set default cast time multiplier
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
@ -2318,7 +2374,6 @@ void Player::SendInitialSpells()
continue; continue;
data << uint16(itr->first); data << uint16(itr->first);
//data << uint16(itr->second->slotId);
data << uint16(0); // it's not slot id data << uint16(0); // it's not slot id
spellCount +=1; spellCount +=1;
@ -2328,7 +2383,7 @@ void Player::SendInitialSpells()
uint16 spellCooldowns = m_spellCooldowns.size(); uint16 spellCooldowns = m_spellCooldowns.size();
data << uint16(spellCooldowns); data << uint16(spellCooldowns);
for(SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr!=m_spellCooldowns.end(); itr++) for(SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr!=m_spellCooldowns.end(); ++itr)
{ {
SpellEntry const *sEntry = sSpellStore.LookupEntry(itr->first); SpellEntry const *sEntry = sSpellStore.LookupEntry(itr->first);
if(!sEntry) if(!sEntry)
@ -2345,13 +2400,13 @@ void Player::SendInitialSpells()
data << uint16(sEntry->Category); // spell category data << uint16(sEntry->Category); // spell category
if(sEntry->Category) // may be wrong, but anyway better than nothing... if(sEntry->Category) // may be wrong, but anyway better than nothing...
{ {
data << uint32(0); data << uint32(0); // cooldown
data << uint32(cooldown); data << uint32(cooldown); // category cooldown
} }
else else
{ {
data << uint32(cooldown); data << uint32(cooldown); // cooldown
data << uint32(0); data << uint32(0); // category cooldown
} }
} }
@ -3150,7 +3205,7 @@ bool Player::_removeSpell(uint16 spell_id)
Mail* Player::GetMail(uint32 id) Mail* Player::GetMail(uint32 id)
{ {
for(PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); itr++) for(PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
{ {
if ((*itr)->messageID == id) if ((*itr)->messageID == id)
{ {
@ -3337,7 +3392,6 @@ void Player::DestroyForPlayer( Player *target ) const
if(target == this) if(target == this)
{ {
for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
{ {
if(m_items[i] == NULL) if(m_items[i] == NULL)
@ -3674,7 +3728,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
// some items limited to specific map // some items limited to specific map
DestroyZoneLimitedItem( true, GetZoneId()); DestroyZoneLimitedItem( true, GetZoneId());
if(!applySickness || getLevel() <= 10) if(!applySickness)
return; return;
//Characters from level 1-10 are not affected by resurrection sickness. //Characters from level 1-10 are not affected by resurrection sickness.
@ -4795,9 +4849,12 @@ void Player::ModifySkillBonus(uint32 skillid,int32 val, bool talent)
} }
} }
void Player::UpdateMaxSkills() void Player::UpdateSkillsForLevel()
{ {
uint16 maxconfskill = sWorld.GetConfigMaxSkillValue(); uint16 maxconfskill = sWorld.GetConfigMaxSkillValue();
uint32 maxSkill = GetMaxSkillValueForLevel();
bool alwaysMaxSkill = sWorld.getConfig(CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL);
for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++)
if (GetUInt32Value(PLAYER_SKILL_INDEX(i))) if (GetUInt32Value(PLAYER_SKILL_INDEX(i)))
@ -4815,11 +4872,15 @@ void Player::UpdateMaxSkills()
uint32 max = SKILL_MAX(data); uint32 max = SKILL_MAX(data);
uint32 val = SKILL_VALUE(data); uint32 val = SKILL_VALUE(data);
// update only level dependent max skill values /// update only level dependent max skill values
if(max!=1 && max != maxconfskill) if(max!=1)
{ {
uint32 max_Skill = GetMaxSkillValueForLevel(); /// miximize skill always
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(val,max_Skill)); if(alwaysMaxSkill)
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(maxSkill,maxSkill));
/// update max skill value if current max skill not maximized
else if(max != maxconfskill)
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(val,maxSkill));
} }
} }
} }
@ -5332,7 +5393,7 @@ void Player::SendInitialReputations()
RepListID a = 0; RepListID a = 0;
for (FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); itr++) for (FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
{ {
// fill in absent fields // fill in absent fields
for (; a != itr->first; a++) for (; a != itr->first; a++)
@ -5842,6 +5903,18 @@ void Player::UpdateHonorFields()
///An exact honor value can also be given (overriding the calcs) ///An exact honor value can also be given (overriding the calcs)
bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor) bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor)
{ {
// do not reward honor in arenas, but enable onkill spellproc
if(InArena())
{
if(!uVictim || uVictim == this || uVictim->GetTypeId() != TYPEID_PLAYER)
return false;
if( GetBGTeam() == ((Player*)uVictim)->GetBGTeam() )
return false;
return true;
}
// 'Inactive' this aura prevents the player from gaining honor points and battleground tokens // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens
if(GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) if(GetDummyAura(SPELL_AURA_PLAYER_INACTIVE))
return false; return false;
@ -6273,7 +6346,7 @@ void Player::DuelComplete(DuelCompleteType type)
/* remove auras */ /* remove auras */
std::vector<uint32> auras2remove; std::vector<uint32> auras2remove;
AuraMap const& vAuras = duel->opponent->GetAuras(); AuraMap const& vAuras = duel->opponent->GetAuras();
for (AuraMap::const_iterator i = vAuras.begin(); i != vAuras.end(); i++) for (AuraMap::const_iterator i = vAuras.begin(); i != vAuras.end(); ++i)
{ {
if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
auras2remove.push_back(i->second->GetId()); auras2remove.push_back(i->second->GetId());
@ -6284,7 +6357,7 @@ void Player::DuelComplete(DuelCompleteType type)
auras2remove.clear(); auras2remove.clear();
AuraMap const& auras = GetAuras(); AuraMap const& auras = GetAuras();
for (AuraMap::const_iterator i = auras.begin(); i != auras.end(); i++) for (AuraMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
{ {
if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
auras2remove.push_back(i->second->GetId()); auras2remove.push_back(i->second->GetId());
@ -6373,23 +6446,23 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
break; break;
case ITEM_MOD_AGILITY: // modify agility case ITEM_MOD_AGILITY: // modify agility
HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply); HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
ApplyStatBuffMod(STAT_AGILITY, val, apply); ApplyStatBuffMod(STAT_AGILITY, float(val), apply);
break; break;
case ITEM_MOD_STRENGTH: //modify strength case ITEM_MOD_STRENGTH: //modify strength
HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply); HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
ApplyStatBuffMod(STAT_STRENGTH, val, apply); ApplyStatBuffMod(STAT_STRENGTH, float(val), apply);
break; break;
case ITEM_MOD_INTELLECT: //modify intellect case ITEM_MOD_INTELLECT: //modify intellect
HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply); HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
ApplyStatBuffMod(STAT_INTELLECT, val, apply); ApplyStatBuffMod(STAT_INTELLECT, float(val), apply);
break; break;
case ITEM_MOD_SPIRIT: //modify spirit case ITEM_MOD_SPIRIT: //modify spirit
HandleStatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, float(val), apply); HandleStatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, float(val), apply);
ApplyStatBuffMod(STAT_SPIRIT, val, apply); ApplyStatBuffMod(STAT_SPIRIT, float(val), apply);
break; break;
case ITEM_MOD_STAMINA: //modify stamina case ITEM_MOD_STAMINA: //modify stamina
HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply); HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply);
ApplyStatBuffMod(STAT_STAMINA, val, apply); ApplyStatBuffMod(STAT_STAMINA, float(val), apply);
break; break;
case ITEM_MOD_DEFENSE_SKILL_RATING: case ITEM_MOD_DEFENSE_SKILL_RATING:
ApplyRatingMod(CR_DEFENSE_SKILL, int32(val), apply); ApplyRatingMod(CR_DEFENSE_SKILL, int32(val), apply);
@ -8767,7 +8840,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
} }
else // equipped bag else // equipped bag
{ {
// we need check 2 time (specilized/non_specialized), use NULL_BAG to prevent skipping bag // we need check 2 time (specialized/non_specialized), use NULL_BAG to prevent skipping bag
res = _CanStoreItem_InBag(bag,dest,pProto,count,true,false,pItem,NULL_BAG,slot); res = _CanStoreItem_InBag(bag,dest,pProto,count,true,false,pItem,NULL_BAG,slot);
if(res!=EQUIP_ERR_OK) if(res!=EQUIP_ERR_OK)
res = _CanStoreItem_InBag(bag,dest,pProto,count,true,true,pItem,NULL_BAG,slot); res = _CanStoreItem_InBag(bag,dest,pProto,count,true,true,pItem,NULL_BAG,slot);
@ -10225,7 +10298,6 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
if( bag == INVENTORY_SLOT_BAG_0 ) if( bag == INVENTORY_SLOT_BAG_0 )
{ {
SetUInt64Value((uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)), 0); SetUInt64Value((uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)), 0);
// equipment and equipped bags can have applied bonuses // equipment and equipped bags can have applied bonuses
@ -12056,7 +12128,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
if(pQuest->GetCharTitleId()) if(pQuest->GetCharTitleId())
{ {
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId())) if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId()))
SetFlag64(PLAYER__FIELD_KNOWN_TITLES, (uint64(1) << titleEntry->bit_index)); SetTitle(titleEntry);
} }
// Send reward mail // Send reward mail
@ -13073,7 +13145,7 @@ void Player::SendQuestComplete( uint32 quest_id )
if( quest_id ) if( quest_id )
{ {
WorldPacket data( SMSG_QUESTUPDATE_COMPLETE, 4 ); WorldPacket data( SMSG_QUESTUPDATE_COMPLETE, 4 );
data << quest_id; data << uint32(quest_id);
GetSession()->SendPacket( &data ); GetSession()->SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id ); sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id );
} }
@ -13593,14 +13665,14 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
SetUInt32Value(UNIT_CHANNEL_SPELL,0); SetUInt32Value(UNIT_CHANNEL_SPELL,0);
// clear charm/summon related fields // clear charm/summon related fields
SetUInt64Value(UNIT_FIELD_CHARM,0); SetCharm(NULL);
SetUInt64Value(UNIT_FIELD_SUMMON,0); SetPet(NULL);
SetUInt64Value(UNIT_FIELD_CHARMEDBY,0); SetCharmerGUID(NULL);
SetUInt64Value(UNIT_FIELD_SUMMONEDBY,0); SetOwnerGUID(NULL);
SetUInt64Value(UNIT_FIELD_CREATEDBY,0); SetCreatorGUID(NULL);
// reset some aura modifiers before aura apply // reset some aura modifiers before aura apply
SetUInt64Value(PLAYER_FARSIGHT, 0); SetFarSight(NULL);
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 ); SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 ); SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
@ -13685,7 +13757,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
if(uint32 curTitle = GetUInt32Value(PLAYER_CHOSEN_TITLE)) if(uint32 curTitle = GetUInt32Value(PLAYER_CHOSEN_TITLE))
{ {
if(!HasFlag64(PLAYER__FIELD_KNOWN_TITLES,uint64(1) << curTitle)) if(!HasTitle(curTitle))
SetUInt32Value(PLAYER_CHOSEN_TITLE,0); SetUInt32Value(PLAYER_CHOSEN_TITLE,0);
} }
@ -14300,7 +14372,7 @@ void Player::_LoadQuestStatus(QueryResult *result)
if(pQuest->GetCharTitleId()) if(pQuest->GetCharTitleId())
{ {
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId())) if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId()))
SetFlag64(PLAYER__FIELD_KNOWN_TITLES, (uint64(1) << titleEntry->bit_index)); SetTitle(titleEntry);
} }
} }
@ -14582,13 +14654,13 @@ void Player::SendRaidInfo()
uint32 counter = 0, i; uint32 counter = 0, i;
for(i = 0; i < TOTAL_DIFFICULTIES; i++) for(i = 0; i < TOTAL_DIFFICULTIES; i++)
for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); itr++) for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
if(itr->second.perm) counter++; if(itr->second.perm) counter++;
data << counter; data << counter;
for(i = 0; i < TOTAL_DIFFICULTIES; i++) for(i = 0; i < TOTAL_DIFFICULTIES; i++)
{ {
for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); itr++) for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
{ {
if(itr->second.perm) if(itr->second.perm)
{ {
@ -14913,7 +14985,8 @@ void Player::SaveToDB()
void Player::SaveInventoryAndGoldToDB() void Player::SaveInventoryAndGoldToDB()
{ {
_SaveInventory(); _SaveInventory();
SetUInt32ValueInDB(PLAYER_FIELD_COINAGE,GetMoney(),GetGUID()); //money is in data field
SaveDataFieldToDB();
} }
void Player::_SaveActions() void Player::_SaveActions()
@ -15084,7 +15157,7 @@ void Player::_SaveMail()
if (!m_mailsLoaded) if (!m_mailsLoaded)
return; return;
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); itr++) for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
{ {
Mail *m = (*itr); Mail *m = (*itr);
if (m->state == MAIL_STATE_CHANGED) if (m->state == MAIL_STATE_CHANGED)
@ -15304,6 +15377,20 @@ void Player::SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint
CharacterDatabase.Execute(ss.str().c_str()); CharacterDatabase.Execute(ss.str().c_str());
} }
void Player::SaveDataFieldToDB()
{
std::ostringstream ss;
ss<<"UPDATE characters SET data='";
for(uint16 i = 0; i < m_valuesCount; i++ )
{
ss << GetUInt32Value(i) << " ";
}
ss<<"' WHERE guid='"<< GUID_LOPART(GetGUIDLow()) <<"'";
CharacterDatabase.Execute(ss.str().c_str());
}
bool Player::SaveValuesArrayInDB(Tokens const& tokens, uint64 guid) bool Player::SaveValuesArrayInDB(Tokens const& tokens, uint64 guid)
{ {
std::ostringstream ss2; std::ostringstream ss2;
@ -15578,8 +15665,8 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
m_guardianPets.erase(pet->GetGUID()); m_guardianPets.erase(pet->GetGUID());
break; break;
default: default:
if(GetPetGUID()==pet->GetGUID()) if(GetPetGUID() == pet->GetGUID())
SetPet(0); SetPet(NULL);
break; break;
} }
@ -15751,7 +15838,7 @@ void Player::PetSpellInitialize()
if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)) if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK))
{ {
for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();itr++) for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();++itr)
{ {
if(itr->second->state == PETSPELL_REMOVED) if(itr->second->state == PETSPELL_REMOVED)
continue; continue;
@ -18151,10 +18238,25 @@ Player* Player::GetNextRandomRaidMember(float radius)
return nearMembers[randTarget]; return nearMembers[randTarget];
} }
PartyResult Player::CanUninviteFromGroup() const
{
const Group* grp = GetGroup();
if(!grp)
return PARTY_RESULT_YOU_NOT_IN_GROUP;
if(!grp->IsLeader(GetGUID()) && !grp->IsAssistant(GetGUID()))
return PARTY_RESULT_YOU_NOT_LEADER;
if(InBattleGround())
return PARTY_RESULT_INVITE_RESTRICTED;
return PARTY_RESULT_OK;
}
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z ) void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
{ {
float water_z = m->GetWaterLevel(x,y); float water_z = m->GetWaterLevel(x,y);
float height_z = m->GetHeight(x,y,z, false); // use .map base surface height float height_z = m->GetHeight(x,y,z, false); // use .map base surface height
uint8 flag1 = m->GetTerrainType(x,y); uint8 flag1 = m->GetTerrainType(x,y);
//!Underwater check, not in water if underground or above water level //!Underwater check, not in water if underground or above water level
@ -18197,11 +18299,28 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
bool Player::isAllowUseBattleGroundObject() bool Player::isAllowUseBattleGroundObject()
{ {
return ( //InBattleGround() && // in battleground - not need, check in other cases return ( //InBattleGround() && // in battleground - not need, check in other cases
!IsMounted() && // not mounted !IsMounted() && // not mounted
!HasStealthAura() && // not stealthed !HasStealthAura() && // not stealthed
!HasInvisibilityAura() && // not invisible !HasInvisibilityAura() && // not invisible
!HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup !HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup
isAlive() // live player isAlive() // live player
); );
} }
bool Player::HasTitle(uint32 bitIndex)
{
if (bitIndex > 128)
return false;
uint32 fieldIndexOffset = bitIndex/32;
uint32 flag = 1 << (bitIndex%32);
return HasFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag);
}
void Player::SetTitle(CharTitlesEntry const* title)
{
uint32 fieldIndexOffset = title->bit_index/32;
uint32 flag = 1 << (title->bit_index%32);
SetFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag);
}

View file

@ -516,10 +516,10 @@ typedef std::map<uint32, QuestStatusData> QuestStatusMap;
enum QuestSlotOffsets enum QuestSlotOffsets
{ {
QUEST_ID_OFFSET = 0, QUEST_ID_OFFSET = 0,
QUEST_STATE_OFFSET = 1, QUEST_STATE_OFFSET = 1,
QUEST_COUNTS_OFFSET = 2, QUEST_COUNTS_OFFSET = 2,
QUEST_TIME_OFFSET = 3 QUEST_TIME_OFFSET = 3
}; };
#define MAX_QUEST_OFFSET 4 #define MAX_QUEST_OFFSET 4
@ -1067,6 +1067,7 @@ class MANGOS_DLL_SPEC Player : public Unit
Item* EquipNewItem( uint16 pos, uint32 item, uint32 count, bool update ); Item* EquipNewItem( uint16 pos, uint32 item, uint32 count, bool update );
Item* EquipItem( uint16 pos, Item *pItem, bool update ); Item* EquipItem( uint16 pos, Item *pItem, bool update );
void AutoUnequipOffhandIfNeed(); void AutoUnequipOffhandIfNeed();
bool StoreNewItemInBestSlot(uint32 item_id, uint32 item_count);
uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const;
uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const; uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const;
@ -1263,7 +1264,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void SaveToDB(); void SaveToDB();
void SaveInventoryAndGoldToDB(); // fast save function for item/money cheating preventing void SaveInventoryAndGoldToDB(); // fast save function for item/money cheating preventing
void SaveGoldToDB() { SetUInt32ValueInDB(PLAYER_FIELD_COINAGE,GetMoney(),GetGUID()); } void SaveDataFieldToDB();
static bool SaveValuesArrayInDB(Tokens const& data,uint64 guid); static bool SaveValuesArrayInDB(Tokens const& data,uint64 guid);
static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value); static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value);
static void SetFloatValueInArray(Tokens& data,uint16 index, float value); static void SetFloatValueInArray(Tokens& data,uint16 index, float value);
@ -1502,8 +1503,8 @@ class MANGOS_DLL_SPEC Player : public Unit
void RemoveFromGroup() { RemoveFromGroup(GetGroup(),GetGUID()); } void RemoveFromGroup() { RemoveFromGroup(GetGroup(),GetGUID()); }
void SendUpdateToOutOfRangeGroupMembers(); void SendUpdateToOutOfRangeGroupMembers();
void SetInGuild(uint32 GuildId) { SetUInt32Value(PLAYER_GUILDID, GuildId); Player::SetUInt32ValueInDB(PLAYER_GUILDID, GuildId, GetGUID()); } void SetInGuild(uint32 GuildId) { SetUInt32Value(PLAYER_GUILDID, GuildId); }
void SetRank(uint32 rankId){ SetUInt32Value(PLAYER_GUILDRANK, rankId); Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, rankId, GetGUID()); } void SetRank(uint32 rankId){ SetUInt32Value(PLAYER_GUILDRANK, rankId); }
void SetGuildIdInvited(uint32 GuildId) { m_GuildIdInvited = GuildId; } void SetGuildIdInvited(uint32 GuildId) { m_GuildIdInvited = GuildId; }
uint32 GetGuildId() { return GetUInt32Value(PLAYER_GUILDID); } uint32 GetGuildId() { return GetUInt32Value(PLAYER_GUILDID); }
static uint32 GetGuildIdFromDB(uint64 guid); static uint32 GetGuildIdFromDB(uint64 guid);
@ -1516,7 +1517,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot) void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot)
{ {
SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6), ArenaTeamId); SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6), ArenaTeamId);
SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6), ArenaTeamId, GetGUID()); SaveDataFieldToDB(); // needed?
} }
uint32 GetArenaTeamId(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6)); } uint32 GetArenaTeamId(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6)); }
static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot); static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);
@ -1682,6 +1683,7 @@ class MANGOS_DLL_SPEC Player : public Unit
FactionStateList m_factions; FactionStateList m_factions;
ForcedReactions m_forcedReactions; ForcedReactions m_forcedReactions;
FactionStateList const& GetFactionStateList() { return m_factions; }
uint32 GetDefaultReputationFlags(const FactionEntry *factionEntry) const; uint32 GetDefaultReputationFlags(const FactionEntry *factionEntry) const;
int32 GetBaseReputation(const FactionEntry *factionEntry) const; int32 GetBaseReputation(const FactionEntry *factionEntry) const;
int32 GetReputation(uint32 faction_id) const; int32 GetReputation(uint32 faction_id) const;
@ -1712,7 +1714,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void SetFactionVisible(FactionState* faction); void SetFactionVisible(FactionState* faction);
void SetFactionVisibleForFactionTemplateId(uint32 FactionTemplateId); void SetFactionVisibleForFactionTemplateId(uint32 FactionTemplateId);
void SetFactionVisibleForFactionId(uint32 FactionId); void SetFactionVisibleForFactionId(uint32 FactionId);
void UpdateMaxSkills(); void UpdateSkillsForLevel();
void UpdateSkillsToMaxSkillsForLevel(); // for .levelup void UpdateSkillsToMaxSkillsForLevel(); // for .levelup
void ModifySkillBonus(uint32 skillid,int32 val, bool talent); void ModifySkillBonus(uint32 skillid,int32 val, bool talent);
@ -1908,6 +1910,13 @@ class MANGOS_DLL_SPEC Player : public Unit
/*** VARIOUS SYSTEMS ***/ /*** VARIOUS SYSTEMS ***/
/*********************************************************/ /*********************************************************/
MovementInfo m_movementInfo; MovementInfo m_movementInfo;
uint32 m_lastFallTime;
float m_lastFallZ;
void SetFallInformation(uint32 time, float z)
{
m_lastFallTime = time;
m_lastFallZ = z;
}
bool isMoving() const { return HasUnitMovementFlag(movementFlagsMask); } bool isMoving() const { return HasUnitMovementFlag(movementFlagsMask); }
bool isMovingOrTurning() const { return HasUnitMovementFlag(movementOrTurningFlagsMask); } bool isMovingOrTurning() const { return HasUnitMovementFlag(movementOrTurningFlagsMask); }
@ -1918,6 +1927,9 @@ class MANGOS_DLL_SPEC Player : public Unit
void SetClientControl(Unit* target, uint8 allowMove); void SetClientControl(Unit* target, uint8 allowMove);
uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); }
// Transports // Transports
Transport * GetTransport() const { return m_transport; } Transport * GetTransport() const { return m_transport; }
void SetTransport(Transport * t) { m_transport = t; } void SetTransport(Transport * t) { m_transport = t; }
@ -2014,6 +2026,7 @@ class MANGOS_DLL_SPEC Player : public Unit
uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } uint64 GetAuraUpdateMask() { return m_auraUpdateMask; }
void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
Player* GetNextRandomRaidMember(float radius); Player* GetNextRandomRaidMember(float radius);
PartyResult CanUninviteFromGroup() const;
GridReference<Player> &GetGridRef() { return m_gridRef; } GridReference<Player> &GetGridRef() { return m_gridRef; }
MapReference &GetMapRef() { return m_mapRef; } MapReference &GetMapRef() { return m_mapRef; }
@ -2023,6 +2036,9 @@ class MANGOS_DLL_SPEC Player : public Unit
WorldLocation& GetTeleportDest() { return m_teleport_dest; } WorldLocation& GetTeleportDest() { return m_teleport_dest; }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; } DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
bool HasTitle(uint32 bitIndex);
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
void SetTitle(CharTitlesEntry const* title);
protected: protected:

View file

@ -112,24 +112,24 @@ enum __QuestGiverStatus
enum __QuestFlags enum __QuestFlags
{ {
// Flags used at server and sended to client // Flags used at server and sent to client
QUEST_FLAGS_STAY_ALIVE = 1, // Not used currently QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently
QUEST_FLAGS_PARTY_ACCEPT = 2, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
QUEST_FLAGS_EXPLORATION = 4, // Not used currently QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently
QUEST_FLAGS_SHARABLE = 8, // Can be shared: Player::CanShareQuest() QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest()
//QUEST_FLAGS_NONE2 = 16, // Not used currently //QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently
QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content QUEST_FLAGS_EPIC = 0x00000020, // Not used currently: Unsure of content
QUEST_FLAGS_RAID = 64, // Not used currently QUEST_FLAGS_RAID = 0x00000040, // Not used currently
QUEST_FLAGS_TBC = 128, // Not used currently: Available if TBC expension enabled only QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expension enabled only
QUEST_FLAGS_UNK2 = 256, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs QUEST_FLAGS_UNK2 = 0x00000100, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs
QUEST_FLAGS_HIDDEN_REWARDS = 512, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE)) QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
QUEST_FLAGS_AUTO_REWARDED = 1024, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. QUEST_FLAGS_AUTO_REWARDED = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
QUEST_FLAGS_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests QUEST_FLAGS_TBC_RACES = 0x00000800, // Not used currently: Blood elf/Draenei starting zone quests
QUEST_FLAGS_DAILY = 4096, // Used to know quest is Daily one QUEST_FLAGS_DAILY = 0x00001000, // Used to know quest is Daily one
// Mangos flags for set SpecialFlags in DB if required but used only at server // Mangos flags for set SpecialFlags in DB if required but used only at server
QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB
QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x020000, // Set by 2 in SpecialFlags from DB (if reequired area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL) QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x020000, // Set by 2 in SpecialFlags from DB (if required area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL)
QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT, QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT,
// Mangos flags for internal use only // Mangos flags for internal use only
@ -318,7 +318,7 @@ struct QuestStatusData
: m_status(QUEST_STATUS_NONE),m_rewarded(false), : m_status(QUEST_STATUS_NONE),m_rewarded(false),
m_explored(false), m_timer(0), uState(QUEST_NEW) m_explored(false), m_timer(0), uState(QUEST_NEW)
{ {
memset(m_itemcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32)); memset(m_itemcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
memset(m_creatureOrGOcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32)); memset(m_creatureOrGOcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
} }

View file

@ -553,7 +553,6 @@ enum SpellEffects
SPELL_EFFECT_TRADE_SKILL = 47, SPELL_EFFECT_TRADE_SKILL = 47,
SPELL_EFFECT_STEALTH = 48, SPELL_EFFECT_STEALTH = 48,
SPELL_EFFECT_DETECT = 49, SPELL_EFFECT_DETECT = 49,
// SPELL_EFFECT_SUMMON_OBJECT = 50,
SPELL_EFFECT_TRANS_DOOR = 50, SPELL_EFFECT_TRANS_DOOR = 50,
SPELL_EFFECT_FORCE_CRITICAL_HIT = 51, SPELL_EFFECT_FORCE_CRITICAL_HIT = 51,
SPELL_EFFECT_GUARANTEE_HIT = 52, SPELL_EFFECT_GUARANTEE_HIT = 52,
@ -766,7 +765,7 @@ enum SpellImmunity
IMMUNITY_MECHANIC = 5 // enum Mechanics IMMUNITY_MECHANIC = 5 // enum Mechanics
}; };
#define MAX_SPELL_IMMUNITY 6 #define MAX_SPELL_IMMUNITY 6
enum Targets enum Targets
{ {
@ -831,7 +830,7 @@ enum SpellMissInfo
SPELL_MISS_IMMUNE2 = 8, SPELL_MISS_IMMUNE2 = 8,
SPELL_MISS_DEFLECT = 9, SPELL_MISS_DEFLECT = 9,
SPELL_MISS_ABSORB = 10, SPELL_MISS_ABSORB = 10,
SPELL_MISS_REFLECT = 11, SPELL_MISS_REFLECT = 11
}; };
enum SpellHitType enum SpellHitType
@ -903,13 +902,13 @@ enum GameobjectTypes
enum GameObjectFlags enum GameObjectFlags
{ {
GO_FLAG_IN_USE = 0x01, //disables interaction while animated GO_FLAG_IN_USE = 0x00000001, //disables interaction while animated
GO_FLAG_LOCKED = 0x02, //require key, spell, event, etc to be opened. Makes "Locked" appear in tooltip GO_FLAG_LOCKED = 0x00000002, //require key, spell, event, etc to be opened. Makes "Locked" appear in tooltip
GO_FLAG_INTERACT_COND = 0x04, //cannot interact (condition to interact) GO_FLAG_INTERACT_COND = 0x00000004, //cannot interact (condition to interact)
GO_FLAG_TRANSPORT = 0x08, //any kind of transport? Object can transport (elevator, boat, car) GO_FLAG_TRANSPORT = 0x00000008, //any kind of transport? Object can transport (elevator, boat, car)
GO_FLAG_UNK1 = 0x10, // GO_FLAG_UNK1 = 0x00000010, //
GO_FLAG_NODESPAWN = 0x20, //never despawn, typically for doors, they just change state GO_FLAG_NODESPAWN = 0x00000020, //never despawn, typically for doors, they just change state
GO_FLAG_TRIGGERED = 0x40, //typically, summoned objects. Triggered by spell or other events GO_FLAG_TRIGGERED = 0x00000040 //typically, summoned objects. Triggered by spell or other events
}; };
enum TextEmotes enum TextEmotes
@ -1503,7 +1502,7 @@ enum CreatureFamily
CREATURE_FAMILY_SPIDER = 3, CREATURE_FAMILY_SPIDER = 3,
CREATURE_FAMILY_BEAR = 4, CREATURE_FAMILY_BEAR = 4,
CREATURE_FAMILY_BOAR = 5, CREATURE_FAMILY_BOAR = 5,
CREATURE_FAMILY_CROCILISK = 6, CREATURE_FAMILY_CROCOLISK = 6,
CREATURE_FAMILY_CARRION_BIRD = 7, CREATURE_FAMILY_CARRION_BIRD = 7,
CREATURE_FAMILY_CRAB = 8, CREATURE_FAMILY_CRAB = 8,
CREATURE_FAMILY_GORILLA = 9, CREATURE_FAMILY_GORILLA = 9,
@ -1533,9 +1532,9 @@ enum CreatureFamily
enum CreatureTypeFlags enum CreatureTypeFlags
{ {
CREATURE_TYPEFLAGS_TAMEBLE = 0x0001, CREATURE_TYPEFLAGS_TAMEABLE = 0x0001,
CREATURE_TYPEFLAGS_HERBLOOT = 0x0100, CREATURE_TYPEFLAGS_HERBLOOT = 0x0100,
CREATURE_TYPEFLAGS_MININGLOOT = 0x0200, CREATURE_TYPEFLAGS_MININGLOOT = 0x0200
}; };
enum CreatureEliteType enum CreatureEliteType

View file

@ -270,6 +270,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_triggeringContainer = triggeringContainer; m_triggeringContainer = triggeringContainer;
m_referencedFromCurrentSpell = false; m_referencedFromCurrentSpell = false;
m_executedCurrently = false; m_executedCurrently = false;
m_delayStart = 0;
m_delayAtDamageCount = 0; m_delayAtDamageCount = 0;
m_applyMultiplierMask = 0; m_applyMultiplierMask = 0;
@ -639,7 +640,7 @@ void Spell::FillTargetMap()
if(m_caster->GetTypeId() == TYPEID_PLAYER) if(m_caster->GetTypeId() == TYPEID_PLAYER)
{ {
Player *me = (Player*)m_caster; Player *me = (Player*)m_caster;
for (std::list<Unit*>::const_iterator itr = tmpUnitMap.begin(); itr != tmpUnitMap.end(); itr++) for (std::list<Unit*>::const_iterator itr = tmpUnitMap.begin(); itr != tmpUnitMap.end(); ++itr)
{ {
Unit *owner = (*itr)->GetOwner(); Unit *owner = (*itr)->GetOwner();
Unit *u = owner ? owner : (*itr); Unit *u = owner ? owner : (*itr);
@ -2660,14 +2661,14 @@ void Spell::finish(bool ok)
m_spellState = SPELL_STATE_FINISHED; m_spellState = SPELL_STATE_FINISHED;
//remove spell mods
if (m_caster->GetTypeId() == TYPEID_PLAYER)
((Player*)m_caster)->RemoveSpellMods(this);
// other code related only to successfully finished spells // other code related only to successfully finished spells
if(!ok) if(!ok)
return; return;
//remove spell mods
if (m_caster->GetTypeId() == TYPEID_PLAYER)
((Player*)m_caster)->RemoveSpellMods(this);
//handle SPELL_AURA_ADD_TARGET_TRIGGER auras //handle SPELL_AURA_ADD_TARGET_TRIGGER auras
Unit::AuraList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER); Unit::AuraList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER);
for(Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i) for(Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
@ -2713,10 +2714,11 @@ void Spell::finish(bool ok)
// Clear combo at finish state // Clear combo at finish state
if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo)) if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo))
{ {
// Not drop combopoints if any miss exist // Not drop combopoints if negative spell and if any miss on enemy exist
bool needDrop = true; bool needDrop = true;
if (!IsPositiveSpell(m_spellInfo->Id))
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
if (ihit->missCondition != SPELL_MISS_NONE) if (ihit->missCondition != SPELL_MISS_NONE && ihit->targetGUID!=m_caster->GetGUID())
{ {
needDrop = false; needDrop = false;
break; break;
@ -2755,13 +2757,23 @@ void Spell::SendCastResult(uint8 result)
break; break;
case SPELL_FAILED_REQUIRES_AREA: case SPELL_FAILED_REQUIRES_AREA:
// hardcode areas limitation case // hardcode areas limitation case
if( m_spellInfo->Id==41618 || m_spellInfo->Id==41620 ) switch(m_spellInfo->Id)
data << uint32(3842); {
else if( m_spellInfo->Id==41617 || m_spellInfo->Id==41619 ) case 41617: // Cenarion Mana Salve
data << uint32(3905); case 41619: // Cenarion Healing Salve
// normal case data << uint32(3905);
else break;
data << uint32(m_spellInfo->AreaId); case 41618: // Bottled Nethergon Energy
case 41620: // Bottled Nethergon Vapor
data << uint32(3842);
break;
case 45373: // Bloodberry Elixir
data << uint32(4075);
break;
default: // default case
data << uint32(m_spellInfo->AreaId);
break;
}
break; break;
case SPELL_FAILED_TOTEMS: case SPELL_FAILED_TOTEMS:
if(m_spellInfo->Totem[0]) if(m_spellInfo->Totem[0])
@ -2797,17 +2809,13 @@ void Spell::SendSpellStart()
if(!IsNeedSendToClient()) if(!IsNeedSendToClient())
return; return;
sLog.outDebug("Sending SMSG_SPELL_START id=%u",m_spellInfo->Id); sLog.outDebug("Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
uint16 castFlags = CAST_FLAG_UNKNOWN1; uint32 castFlags = CAST_FLAG_UNKNOWN1;
if(IsRangedSpell()) if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; castFlags |= CAST_FLAG_AMMO;
Unit * target; Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
if(!m_targets.getUnitTarget())
target = m_caster;
else
target = m_targets.getUnitTarget();
WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2)); WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
if(m_CastItem) if(m_CastItem)
@ -2835,17 +2843,13 @@ void Spell::SendSpellGo()
if(!IsNeedSendToClient()) if(!IsNeedSendToClient())
return; return;
sLog.outDebug("Sending SMSG_SPELL_GO id=%u",m_spellInfo->Id); sLog.outDebug("Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id);
Unit * target; Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
if(!m_targets.getUnitTarget())
target = m_caster;
else
target = m_targets.getUnitTarget();
uint16 castFlags = CAST_FLAG_UNKNOWN3; uint32 castFlags = CAST_FLAG_UNKNOWN3;
if(IsRangedSpell()) if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
WorldPacket data(SMSG_SPELL_GO, 50); // guess size WorldPacket data(SMSG_SPELL_GO, 50); // guess size
if(m_CastItem) if(m_CastItem)
@ -2946,7 +2950,7 @@ void Spell::SendLogExecute()
data << uint32(count1); // count1 (effect count?) data << uint32(count1); // count1 (effect count?)
for(uint32 i = 0; i < count1; ++i) for(uint32 i = 0; i < count1; ++i)
{ {
data << uint32(m_spellInfo->Effect[0]); // spell effect? data << uint32(m_spellInfo->Effect[0]); // spell effect
uint32 count2 = 1; uint32 count2 = 1;
data << uint32(count2); // count2 (target count?) data << uint32(count2); // count2 (target count?)
for(uint32 j = 0; j < count2; ++j) for(uint32 j = 0; j < count2; ++j)
@ -3070,7 +3074,7 @@ void Spell::SendChannelUpdate(uint32 time)
WorldPacket data( MSG_CHANNEL_UPDATE, 8+4 ); WorldPacket data( MSG_CHANNEL_UPDATE, 8+4 );
data.append(m_caster->GetPackGUID()); data.append(m_caster->GetPackGUID());
data << time; data << uint32(time);
((Player*)m_caster)->GetSession()->SendPacket( &data ); ((Player*)m_caster)->GetSession()->SendPacket( &data );
} }
@ -3107,8 +3111,8 @@ void Spell::SendChannelStart(uint32 duration)
{ {
WorldPacket data( MSG_CHANNEL_START, (8+4+4) ); WorldPacket data( MSG_CHANNEL_START, (8+4+4) );
data.append(m_caster->GetPackGUID()); data.append(m_caster->GetPackGUID());
data << m_spellInfo->Id; data << uint32(m_spellInfo->Id);
data << duration; data << uint32(duration);
((Player*)m_caster)->GetSession()->SendPacket( &data ); ((Player*)m_caster)->GetSession()->SendPacket( &data );
} }
@ -3134,8 +3138,8 @@ void Spell::SendPlaySpellVisual(uint32 SpellID)
return; return;
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12);
data << m_caster->GetGUID(); data << uint64(m_caster->GetGUID());
data << SpellID; data << uint32(SpellID); // spell visual id?
((Player*)m_caster)->GetSession()->SendPacket(&data); ((Player*)m_caster)->GetSession()->SendPacket(&data);
} }
@ -4137,7 +4141,9 @@ uint8 Spell::CanCast(bool strict)
if(int32(m_targets.getUnitTarget()->getLevel()) > CalculateDamage(i,m_targets.getUnitTarget())) if(int32(m_targets.getUnitTarget()->getLevel()) > CalculateDamage(i,m_targets.getUnitTarget()))
return SPELL_FAILED_HIGHLEVEL; return SPELL_FAILED_HIGHLEVEL;
};break;
break;
}
case SPELL_AURA_MOUNTED: case SPELL_AURA_MOUNTED:
{ {
if (m_caster->IsInWater()) if (m_caster->IsInWater())
@ -4170,7 +4176,9 @@ uint8 Spell::CanCast(bool strict)
// can be casted at non-friendly unit or own pet/charm // can be casted at non-friendly unit or own pet/charm
if(m_caster->IsFriendlyTo(m_targets.getUnitTarget())) if(m_caster->IsFriendlyTo(m_targets.getUnitTarget()))
return SPELL_FAILED_TARGET_FRIENDLY; return SPELL_FAILED_TARGET_FRIENDLY;
};break;
break;
}
case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED: case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED:
case SPELL_AURA_FLY: case SPELL_AURA_FLY:
{ {
@ -4181,7 +4189,9 @@ uint8 Spell::CanCast(bool strict)
GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530) GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530)
return SPELL_FAILED_NOT_HERE; return SPELL_FAILED_NOT_HERE;
} }
};break;
break;
}
case SPELL_AURA_PERIODIC_MANA_LEECH: case SPELL_AURA_PERIODIC_MANA_LEECH:
{ {
if (!m_targets.getUnitTarget()) if (!m_targets.getUnitTarget())
@ -4192,9 +4202,11 @@ uint8 Spell::CanCast(bool strict)
if(m_targets.getUnitTarget()->getPowerType()!=POWER_MANA) if(m_targets.getUnitTarget()->getPowerType()!=POWER_MANA)
return SPELL_FAILED_BAD_TARGETS; return SPELL_FAILED_BAD_TARGETS;
break; break;
} }
default:break; default:
break;
} }
} }
@ -4317,14 +4329,14 @@ uint8 Spell::CheckCasterAuras() const
else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY) else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
prevented_reason = SPELL_FAILED_PACIFIED; prevented_reason = SPELL_FAILED_PACIFIED;
// Attr must make flag drop spell totally immuned from all effects // Attr must make flag drop spell totally immune from all effects
if(prevented_reason) if(prevented_reason)
{ {
if(school_immune || mechanic_immune || dispel_immune) if(school_immune || mechanic_immune || dispel_immune)
{ {
//Checking auras is needed now, because you are prevented by some state but the spell grants immunity. //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
Unit::AuraMap const& auras = m_caster->GetAuras(); Unit::AuraMap const& auras = m_caster->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++) for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{ {
if(itr->second) if(itr->second)
{ {

View file

@ -1975,7 +1975,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
( GetSpellProto()->EffectApplyAuraName[0]==1 || GetSpellProto()->EffectApplyAuraName[0]==128 ) ) ) ( GetSpellProto()->EffectApplyAuraName[0]==1 || GetSpellProto()->EffectApplyAuraName[0]==128 ) ) )
{ {
// spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425 // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
m_target->SetUInt64Value(PLAYER_FARSIGHT, 0); ((Player*)m_target)->SetFarSight(NULL);
WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0); WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
((Player*)m_target)->GetSession()->SendPacket(&data); ((Player*)m_target)->GetSession()->SendPacket(&data);
return; return;
@ -2141,7 +2141,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
// have a look if there is still some other Lifebloom dummy aura // have a look if there is still some other Lifebloom dummy aura
Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY); Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); itr++) for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr)
if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID &&
(*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL) (*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL)
return; return;
@ -2844,7 +2844,7 @@ void Aura::HandleBindSight(bool apply, bool Real)
if(!caster || caster->GetTypeId() != TYPEID_PLAYER) if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return; return;
caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0); ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
} }
void Aura::HandleFarSight(bool apply, bool Real) void Aura::HandleFarSight(bool apply, bool Real)
@ -2853,7 +2853,7 @@ void Aura::HandleFarSight(bool apply, bool Real)
if(!caster || caster->GetTypeId() != TYPEID_PLAYER) if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return; return;
caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_modifier.m_miscvalue : 0); ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
} }
void Aura::HandleAuraTrackCreatures(bool apply, bool Real) void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
@ -2959,7 +2959,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
} }
} }
if(caster->GetTypeId() == TYPEID_PLAYER) if(caster->GetTypeId() == TYPEID_PLAYER)
caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0); ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
} }
void Aura::HandleModPossessPet(bool apply, bool Real) void Aura::HandleModPossessPet(bool apply, bool Real)
@ -3661,7 +3661,7 @@ void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314); m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
} }
m_target->UpdateSpeed(MOVE_FLY, true); m_target->UpdateSpeed(MOVE_FLIGHT, true);
} }
void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real) void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
@ -3681,7 +3681,7 @@ void Aura::HandleAuraModDecreaseSpeed(bool /*apply*/, bool Real)
m_target->UpdateSpeed(MOVE_RUN, true); m_target->UpdateSpeed(MOVE_RUN, true);
m_target->UpdateSpeed(MOVE_SWIM, true); m_target->UpdateSpeed(MOVE_SWIM, true);
m_target->UpdateSpeed(MOVE_FLY, true); m_target->UpdateSpeed(MOVE_FLIGHT, true);
} }
void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real) void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
@ -3692,7 +3692,7 @@ void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
m_target->UpdateSpeed(MOVE_RUN, true); m_target->UpdateSpeed(MOVE_RUN, true);
m_target->UpdateSpeed(MOVE_SWIM, true); m_target->UpdateSpeed(MOVE_SWIM, true);
m_target->UpdateSpeed(MOVE_FLY, true); m_target->UpdateSpeed(MOVE_FLIGHT, true);
} }
/*********************************************************/ /*********************************************************/
@ -4681,21 +4681,24 @@ void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
if(int32(powerType) != m_modifier.m_miscvalue) if(int32(powerType) != m_modifier.m_miscvalue)
return; return;
m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_VALUE, float(m_modifier.m_amount), apply); UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(m_modifier.m_amount), apply);
} }
void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool Real) void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/)
{ {
Powers powerType = m_target->getPowerType(); Powers powerType = m_target->getPowerType();
if(int32(powerType) != m_modifier.m_miscvalue) if(int32(powerType) != m_modifier.m_miscvalue)
return; return;
m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_PCT, float(m_modifier.m_amount), apply); UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_modifier.m_amount), apply);
} }
void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool Real) void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/)
{ {
//m_target->ApplyMaxHealthPercentMod(m_modifier.m_amount,apply);
m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_modifier.m_amount), apply); m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_modifier.m_amount), apply);
} }

View file

@ -53,6 +53,7 @@
#include "SocialMgr.h" #include "SocialMgr.h"
#include "Util.h" #include "Util.h"
#include "TemporarySummon.h" #include "TemporarySummon.h"
#include "ScriptCalls.h"
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
{ {
@ -554,7 +555,7 @@ void Spell::EffectDummy(uint32 i)
switch(m_spellInfo->SpellFamilyName) switch(m_spellInfo->SpellFamilyName)
{ {
case SPELLFAMILY_GENERIC: case SPELLFAMILY_GENERIC:
// Gnomish Poultryizer trinket {
switch(m_spellInfo->Id ) switch(m_spellInfo->Id )
{ {
case 8063: // Deviate Fish case 8063: // Deviate Fish
@ -832,7 +833,7 @@ void Spell::EffectDummy(uint32 i)
if (!m_caster->HasAuraType(SPELL_AURA_MOUNTED)) if (!m_caster->HasAuraType(SPELL_AURA_MOUNTED))
return; return;
float flyspeed = m_caster->GetSpeedRate(MOVE_FLY); float flyspeed = m_caster->GetSpeedRate(MOVE_FLIGHT);
float speed = m_caster->GetSpeedRate(MOVE_RUN); float speed = m_caster->GetSpeedRate(MOVE_RUN);
m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
@ -935,9 +936,58 @@ void Spell::EffectDummy(uint32 i)
return; return;
} }
case 37674: // Chaos Blast case 37674: // Chaos Blast
if(unitTarget) {
m_caster->CastSpell(unitTarget,37675,true); if(!unitTarget)
return;
int32 basepoints0 = 100;
m_caster->CastCustomSpell(unitTarget,37675,&basepoints0,NULL,NULL,true);
return; return;
}
case 40802: // Mingo's Fortune Generator (Mingo's Fortune Giblets)
{
// selecting one from Bloodstained Fortune item
uint32 newitemid;
switch(urand(1,20))
{
case 1: newitemid = 32688; break;
case 2: newitemid = 32689; break;
case 3: newitemid = 32690; break;
case 4: newitemid = 32691; break;
case 5: newitemid = 32692; break;
case 6: newitemid = 32693; break;
case 7: newitemid = 32700; break;
case 8: newitemid = 32701; break;
case 9: newitemid = 32702; break;
case 10: newitemid = 32703; break;
case 11: newitemid = 32704; break;
case 12: newitemid = 32705; break;
case 13: newitemid = 32706; break;
case 14: newitemid = 32707; break;
case 15: newitemid = 32708; break;
case 16: newitemid = 32709; break;
case 17: newitemid = 32710; break;
case 18: newitemid = 32711; break;
case 19: newitemid = 32712; break;
case 20: newitemid = 32713; break;
default:
return;
}
DoCreateItem(i,newitemid);
return;
}
// Demon Broiled Surprise
/* FIX ME: Required for correct work implementing implicit target 7 (in pair (22,7))
case 43723:
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
((Player*)m_caster)->CastSpell(unitTarget, 43753, true);
return;
}
*/
case 44875: // Complete Raptor Capture case 44875: // Complete Raptor Capture
{ {
if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT) if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT)
@ -1085,6 +1135,7 @@ void Spell::EffectDummy(uint32 i)
} }
} }
break; break;
}
case SPELLFAMILY_MAGE: case SPELLFAMILY_MAGE:
switch(m_spellInfo->Id ) switch(m_spellInfo->Id )
{ {
@ -2095,7 +2146,7 @@ void Spell::EffectApplyAura(uint32 i)
// Prayer of Mending (jump animation), we need formal caster instead original for correct animation // Prayer of Mending (jump animation), we need formal caster instead original for correct animation
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL)) if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL))
m_caster->CastSpell(unitTarget,41637,true,NULL,Aur); m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID);
} }
void Spell::EffectUnlearnSpecialization( uint32 i ) void Spell::EffectUnlearnSpecialization( uint32 i )
@ -2677,6 +2728,9 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
if (gameObjTarget) if (gameObjTarget)
{ {
if (Script->GOHello(player, gameObjTarget))
return;
switch (gameObjTarget->GetGoType()) switch (gameObjTarget->GetGoType())
{ {
case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_DOOR:
@ -3124,17 +3178,17 @@ void Spell::EffectSummon(uint32 i)
if(duration > 0) if(duration > 0)
spawnCreature->SetDuration(duration); spawnCreature->SetDuration(duration);
spawnCreature->SetUInt64Value(UNIT_FIELD_SUMMONEDBY,m_caster->GetGUID()); spawnCreature->SetOwnerGUID(m_caster->GetGUID());
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0); spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
spawnCreature->setPowerType(POWER_MANA); spawnCreature->setPowerType(POWER_MANA);
spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, m_caster->getFaction());
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0); spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_0,2048); spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0); spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0); spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); spawnCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000); spawnCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
spawnCreature->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); spawnCreature->SetCreatorGUID(m_caster->GetGUID());
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
spawnCreature->InitStatsForLevel(level); spawnCreature->InitStatsForLevel(level);
@ -3396,7 +3450,8 @@ void Spell::EffectAddFarsight(uint32 i)
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002); dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
m_caster->AddDynObject(dynObj); m_caster->AddDynObject(dynObj);
dynObj->GetMap()->Add(dynObj); dynObj->GetMap()->Add(dynObj);
m_caster->SetUInt64Value(PLAYER_FARSIGHT, dynObj->GetGUID()); if(m_caster->GetTypeId() == TYPEID_PLAYER)
((Player*)m_caster)->SetFarSight(dynObj->GetGUID());
} }
void Spell::EffectSummonWild(uint32 i) void Spell::EffectSummonWild(uint32 i)
@ -3553,14 +3608,14 @@ void Spell::EffectSummonGuardian(uint32 i)
if(duration > 0) if(duration > 0)
spawnCreature->SetDuration(duration); spawnCreature->SetDuration(duration);
spawnCreature->SetUInt64Value(UNIT_FIELD_SUMMONEDBY,m_caster->GetGUID()); spawnCreature->SetOwnerGUID(m_caster->GetGUID());
spawnCreature->setPowerType(POWER_MANA); spawnCreature->setPowerType(POWER_MANA);
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0); spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0); spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0); spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0); spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0);
spawnCreature->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); spawnCreature->SetCreatorGUID(m_caster->GetGUID());
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
spawnCreature->InitStatsForLevel(level); spawnCreature->InitStatsForLevel(level);
@ -3962,15 +4017,15 @@ void Spell::EffectSummonPet(uint32 i)
NewSummon->GetCharmInfo()->SetReactState(REACT_DEFENSIVE); NewSummon->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
} }
NewSummon->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); NewSummon->SetOwnerGUID(m_caster->GetGUID());
NewSummon->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); NewSummon->SetCreatorGUID(m_caster->GetGUID());
NewSummon->SetUInt32Value(UNIT_NPC_FLAGS , 0); NewSummon->SetUInt32Value(UNIT_NPC_FLAGS, 0);
NewSummon->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction); NewSummon->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction);
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_0,2048); NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_1,0); NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
NewSummon->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,time(NULL)); NewSummon->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000); NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true); NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true);
@ -3979,7 +4034,7 @@ void Spell::EffectSummonPet(uint32 i)
// this enables popup window (pet dismiss, cancel), hunter pet additional flags set later // this enables popup window (pet dismiss, cancel), hunter pet additional flags set later
NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
NewSummon->InitStatsForLevel( petlevel); NewSummon->InitStatsForLevel(petlevel);
NewSummon->InitPetCreateSpells(); NewSummon->InitPetCreateSpells();
if(NewSummon->getPetType()==SUMMON_PET) if(NewSummon->getPetType()==SUMMON_PET)
@ -4432,6 +4487,38 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// by spell id // by spell id
switch(m_spellInfo->Id) switch(m_spellInfo->Id)
{ {
// PX-238 Winter Wondervolt TRAP
case 26275:
{
if( unitTarget->HasAura(26272,0)
|| unitTarget->HasAura(26157,0)
|| unitTarget->HasAura(26273,0)
|| unitTarget->HasAura(26274,0))
return;
uint32 iTmpSpellId;
switch(urand(0,3))
{
case 0:
iTmpSpellId = 26272;
break;
case 1:
iTmpSpellId = 26157;
break;
case 2:
iTmpSpellId = 26273;
break;
case 3:
iTmpSpellId = 26274;
break;
}
unitTarget->CastSpell(unitTarget, iTmpSpellId, true);
return;
}
// Bending Shinbone // Bending Shinbone
case 8856: case 8856:
{ {
@ -5516,8 +5603,8 @@ void Spell::EffectSummonCritter(uint32 i)
return; return;
} }
critter->SetUInt64Value(UNIT_FIELD_SUMMONEDBY,m_caster->GetGUID()); critter->SetOwnerGUID(m_caster->GetGUID());
critter->SetUInt64Value(UNIT_FIELD_CREATEDBY,m_caster->GetGUID()); critter->SetCreatorGUID(m_caster->GetGUID());
critter->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); critter->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);

View file

@ -260,7 +260,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data ) void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
{ {
CHECK_PACKET_SIZE(recv_data,8); CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid; uint64 guid;

View file

@ -2144,6 +2144,11 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
{ {
if(uint32 mask = spellmgr.GetSpellElixirMask(spellInfo->Id)) if(uint32 mask = spellmgr.GetSpellElixirMask(spellInfo->Id))
{ {
if(mask & ELIXIR_BATTLE_MASK)
{
if(spellInfo->Id==45373) // Bloodberry Elixir
return zone_id==4075;
}
if(mask & ELIXIR_UNSTABLE_MASK) if(mask & ELIXIR_UNSTABLE_MASK)
{ {
// in the Blade's Edge Mountains Plateaus and Gruul's Lair. // in the Blade's Edge Mountains Plateaus and Gruul's Lair.
@ -2151,9 +2156,8 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
} }
if(mask & ELIXIR_SHATTRATH_MASK) if(mask & ELIXIR_SHATTRATH_MASK)
{ {
// in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple // in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple, Sunwell Plateau
// TODO: and the Sunwell Plateau if(zone_id ==3607 || map_id==534 || map_id==564 || zone_id==4075)
if(zone_id ==3607 || map_id==534 || map_id==564)
return true; return true;
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id); MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
@ -2171,8 +2175,8 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
// special cases zone check (maps checked by multimap common id) // special cases zone check (maps checked by multimap common id)
switch(spellInfo->Id) switch(spellInfo->Id)
{ {
case 41618: case 41618: // Bottled Nethergon Energy
case 41620: case 41620: // Bottled Nethergon Vapor
{ {
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id); MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry) if(!mapEntry)
@ -2180,9 +2184,8 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
return mapEntry->multimap_id==206; return mapEntry->multimap_id==206;
} }
case 41617: // Cenarion Mana Salve
case 41617: case 41619: // Cenarion Healing Salve
case 41619:
{ {
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id); MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry) if(!mapEntry)
@ -2190,14 +2193,9 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
return mapEntry->multimap_id==207; return mapEntry->multimap_id==207;
} }
// Dragonmaw Illusion case 40216: // Dragonmaw Illusion
case 40216: case 42016: // Dragonmaw Illusion
case 42016: return area_id == 3759 || area_id == 3966 || area_id == 3939;
{
if ( area_id != 3759 && area_id != 3966 && area_id != 3939 )
return false;
break;
}
} }
return true; return true;

View file

@ -848,6 +848,7 @@ void Pet::UpdateMaxHealth()
void Pet::UpdateMaxPower(Powers power) void Pet::UpdateMaxPower(Powers power)
{ {
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f; float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f;
float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);

View file

@ -82,7 +82,7 @@ void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data
Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER); Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER);
if (!unit) if (!unit)
{ {
sLog.outDebug( "WORLD: HandleTaxiQueryAvailableNodesOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); sLog.outDebug( "WORLD: HandleTaxiQueryAvailableNodes - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
return; return;
} }

View file

@ -192,7 +192,7 @@ Unit* HostilReference::getSourceUnit()
void ThreatContainer::clearReferences() void ThreatContainer::clearReferences()
{ {
for(std::list<HostilReference*>::iterator i = iThreatList.begin(); i != iThreatList.end(); i++) for(std::list<HostilReference*>::iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
{ {
(*i)->unlink(); (*i)->unlink();
delete (*i); delete (*i);
@ -206,7 +206,7 @@ HostilReference* ThreatContainer::getReferenceByTarget(Unit* pVictim)
{ {
HostilReference* result = NULL; HostilReference* result = NULL;
uint64 guid = pVictim->GetGUID(); uint64 guid = pVictim->GetGUID();
for(std::list<HostilReference*>::iterator i = iThreatList.begin(); i != iThreatList.end(); i++) for(std::list<HostilReference*>::iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
{ {
if((*i)->getUnitGuid() == guid) if((*i)->getUnitGuid() == guid)
{ {

View file

@ -128,10 +128,9 @@ void Totem::UnSummon()
void Totem::SetOwner(uint64 guid) void Totem::SetOwner(uint64 guid)
{ {
SetUInt64Value(UNIT_FIELD_SUMMONEDBY, guid); SetCreatorGUID(guid);
SetUInt64Value(UNIT_FIELD_CREATEDBY, guid); SetOwnerGUID(guid);
Unit *owner = GetOwner(); if (Unit *owner = GetOwner())
if (owner)
{ {
setFaction(owner->getFaction()); setFaction(owner->getFaction());
SetLevel(owner->getLevel()); SetLevel(owner->getLevel());

View file

@ -59,7 +59,12 @@ struct MANGOS_DLL_DECL Traveller
template<> template<>
inline float Traveller<Creature>::Speed() inline float Traveller<Creature>::Speed()
{ {
return i_traveller.GetSpeed( i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN); if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
return i_traveller.GetSpeed(MOVE_WALK);
else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2))
return i_traveller.GetSpeed(MOVE_FLIGHT);
else
return i_traveller.GetSpeed(MOVE_RUN);
} }
template<> template<>

View file

@ -50,12 +50,12 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
{ {
2.5f, // MOVE_WALK 2.5f, // MOVE_WALK
7.0f, // MOVE_RUN 7.0f, // MOVE_RUN
1.25f, // MOVE_WALKBACK 1.25f, // MOVE_RUN_BACK
4.722222f, // MOVE_SWIM 4.722222f, // MOVE_SWIM
4.5f, // MOVE_SWIMBACK 4.5f, // MOVE_SWIM_BACK
3.141594f, // MOVE_TURN 3.141594f, // MOVE_TURN_RATE
7.0f, // MOVE_FLY 7.0f, // MOVE_FLIGHT
4.5f, // MOVE_FLYBACK 4.5f, // MOVE_FLIGHT_BACK
}; };
void InitTriggerAuraData(); void InitTriggerAuraData();
@ -2034,9 +2034,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
void Unit::HandleEmoteCommand(uint32 anim_id) void Unit::HandleEmoteCommand(uint32 anim_id)
{ {
WorldPacket data( SMSG_EMOTE, 12 ); WorldPacket data( SMSG_EMOTE, 12 );
data << anim_id << GetGUID(); data << uint32(anim_id);
WPAssert(data.size() == 12); data << uint64(GetGUID());
SendMessageToSet(&data, true); SendMessageToSet(&data, true);
} }
@ -3107,8 +3106,8 @@ float Unit::CalculateLevelPenalty(SpellEntry const* spellProto) const
void Unit::SendAttackStart(Unit* pVictim) void Unit::SendAttackStart(Unit* pVictim)
{ {
WorldPacket data( SMSG_ATTACKSTART, 16 ); WorldPacket data( SMSG_ATTACKSTART, 16 );
data << GetGUID(); data << uint64(GetGUID());
data << pVictim->GetGUID(); data << uint64(pVictim->GetGUID());
SendMessageToSet(&data, true); SendMessageToSet(&data, true);
DEBUG_LOG( "WORLD: Sent SMSG_ATTACKSTART" ); DEBUG_LOG( "WORLD: Sent SMSG_ATTACKSTART" );
@ -6557,17 +6556,14 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
{ {
int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this); int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100; basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100;
// Drain Soul // Drain Soul
triggered_spell_id = 18371; CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
target = this;
found = true;
break; break;
} }
} }
if(!found) // Not remove charge (aura removed on death in any cases)
return false; // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura
break; // fall through to normal cast return false;
} }
break; break;
} }
@ -8133,7 +8129,7 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
if(GetTypeId()==TYPEID_UNIT) if(GetTypeId()==TYPEID_UNIT)
{ {
WorldPacket data(SMSG_AI_REACTION, 12); WorldPacket data(SMSG_AI_REACTION, 12);
data << GetGUID(); data << uint64(GetGUID());
data << uint32(AI_REACTION_AGGRO); // Aggro sound data << uint32(AI_REACTION_AGGRO); // Aggro sound
((WorldObject*)this)->SendMessageToSet(&data, true); ((WorldObject*)this)->SendMessageToSet(&data, true);
@ -8349,17 +8345,17 @@ Unit* Unit::GetCharm() const
void Unit::SetPet(Pet* pet) void Unit::SetPet(Pet* pet)
{ {
SetUInt64Value(UNIT_FIELD_SUMMON,pet ? pet->GetGUID() : 0); SetUInt64Value(UNIT_FIELD_SUMMON, pet ? pet->GetGUID() : 0);
// FIXME: hack, speed must be set only at follow // FIXME: hack, speed must be set only at follow
if(pet) if(pet)
for(int i = 0; i < MAX_MOVE_TYPE; ++i) for(int i = 0; i < MAX_MOVE_TYPE; ++i)
pet->SetSpeed(UnitMoveType(i),m_speed_rate[i],true); pet->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
} }
void Unit::SetCharm(Unit* charmed) void Unit::SetCharm(Unit* pet)
{ {
SetUInt64Value(UNIT_FIELD_CHARM,charmed ? charmed->GetGUID() : 0); SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0);
} }
void Unit::UnsummonAllTotems() void Unit::UnsummonAllTotems()
@ -8396,7 +8392,6 @@ void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Po
data << uint32(SpellID); data << uint32(SpellID);
data << uint32(powertype); data << uint32(powertype);
data << uint32(Damage); data << uint32(Damage);
//data << uint8(critical ? 1 : 0); // removed in 2.4.0
SendMessageToSet(&data, true); SendMessageToSet(&data, true);
} }
@ -8853,7 +8848,7 @@ int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVic
bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType)
{ {
// not criting spell // not critting spell
if((spellProto->AttributesEx2 & SPELL_ATTR_EX2_CANT_CRIT)) if((spellProto->AttributesEx2 & SPELL_ATTR_EX2_CANT_CRIT))
return false; return false;
@ -9222,7 +9217,8 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
if(itr->type == spellInfo->Dispel) if(itr->type == spellInfo->Dispel)
return true; return true;
if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE)) // unaffected by school immunity if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity
!(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
{ {
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
@ -9685,7 +9681,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
return gain; return gain;
} }
bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList) const bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const
{ {
if(!u) if(!u)
return false; return false;
@ -9736,12 +9732,12 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList)
if(u->isInFlight()) // what see player in flight if(u->isInFlight()) // what see player in flight
{ {
// use object grey distance for all (only see objects any way) // use object grey distance for all (only see objects any way)
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
else if(!isAlive()) // distance for show body else if(!isAlive()) // distance for show body
{ {
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
else if(GetTypeId()==TYPEID_PLAYER) // distance for show player else if(GetTypeId()==TYPEID_PLAYER) // distance for show player
@ -9749,26 +9745,26 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList)
if(u->GetTypeId()==TYPEID_PLAYER) if(u->GetTypeId()==TYPEID_PLAYER)
{ {
// Players far than max visible distance for player or not in our map are not visible too // Players far than max visible distance for player or not in our map are not visible too
if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
else else
{ {
// Units far than max visible distance for creature or not in our map are not visible too // Units far than max visible distance for creature or not in our map are not visible too
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
} }
else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed
{ {
// Pet/charmed far than max visible distance for player or not in our map are not visible too // Pet/charmed far than max visible distance for player or not in our map are not visible too
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
else // distance for show creature else // distance for show creature
{ {
// Units far than max visible distance for creature or not in our map are not visible too // Units far than max visible distance for creature or not in our map are not visible too
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
@ -9996,16 +9992,16 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
} }
break; break;
} }
case MOVE_WALKBACK: case MOVE_RUN_BACK:
return; return;
case MOVE_SWIM: case MOVE_SWIM:
{ {
main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SWIM_SPEED); main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SWIM_SPEED);
break; break;
} }
case MOVE_SWIMBACK: case MOVE_SWIM_BACK:
return; return;
case MOVE_FLY: case MOVE_FLIGHT:
{ {
if (IsMounted()) // Use on mount auras if (IsMounted()) // Use on mount auras
main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED); main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
@ -10015,7 +10011,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
non_stack_bonus = (100.0 + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK))/100.0f; non_stack_bonus = (100.0 + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK))/100.0f;
break; break;
} }
case MOVE_FLYBACK: case MOVE_FLIGHT_BACK:
return; return;
default: default:
sLog.outError("Unit::UpdateSpeed: Unsupported move type (%d)", mtype); sLog.outError("Unit::UpdateSpeed: Unsupported move type (%d)", mtype);
@ -10030,7 +10026,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
{ {
case MOVE_RUN: case MOVE_RUN:
case MOVE_SWIM: case MOVE_SWIM:
case MOVE_FLY: case MOVE_FLIGHT:
{ {
// Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
// TODO: possible affect only on MOVE_RUN // TODO: possible affect only on MOVE_RUN
@ -10087,22 +10083,22 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
case MOVE_RUN: case MOVE_RUN:
data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+1+4+4+4+4+4+4+4); data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+1+4+4+4+4+4+4+4);
break; break;
case MOVE_WALKBACK: case MOVE_RUN_BACK:
data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
break; break;
case MOVE_SWIM: case MOVE_SWIM:
data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+1+4+4+4+4+4+4+4); data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+1+4+4+4+4+4+4+4);
break; break;
case MOVE_SWIMBACK: case MOVE_SWIM_BACK:
data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
break; break;
case MOVE_TURN: case MOVE_TURN_RATE:
data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+1+4+4+4+4+4+4+4); data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+1+4+4+4+4+4+4+4);
break; break;
case MOVE_FLY: case MOVE_FLIGHT:
data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+1+4+4+4+4+4+4+4); data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+1+4+4+4+4+4+4+4);
break; break;
case MOVE_FLYBACK: case MOVE_FLIGHT_BACK:
data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
break; break;
default: default:
@ -10135,22 +10131,22 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
case MOVE_RUN: case MOVE_RUN:
data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE, 17); data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE, 17);
break; break;
case MOVE_WALKBACK: case MOVE_RUN_BACK:
data.Initialize(SMSG_FORCE_RUN_BACK_SPEED_CHANGE, 16); data.Initialize(SMSG_FORCE_RUN_BACK_SPEED_CHANGE, 16);
break; break;
case MOVE_SWIM: case MOVE_SWIM:
data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, 16); data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, 16);
break; break;
case MOVE_SWIMBACK: case MOVE_SWIM_BACK:
data.Initialize(SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, 16); data.Initialize(SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, 16);
break; break;
case MOVE_TURN: case MOVE_TURN_RATE:
data.Initialize(SMSG_FORCE_TURN_RATE_CHANGE, 16); data.Initialize(SMSG_FORCE_TURN_RATE_CHANGE, 16);
break; break;
case MOVE_FLY: case MOVE_FLIGHT:
data.Initialize(SMSG_FORCE_FLIGHT_SPEED_CHANGE, 16); data.Initialize(SMSG_FORCE_FLIGHT_SPEED_CHANGE, 16);
break; break;
case MOVE_FLYBACK: case MOVE_FLIGHT_BACK:
data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16); data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16);
break; break;
default: default:
@ -10158,7 +10154,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
return; return;
} }
data.append(GetPackGUID()); data.append(GetPackGUID());
data << (uint32)0; data << (uint32)0; // moveEvent, NUM_PMOVE_EVTS = 0x39
if (mtype == MOVE_RUN) if (mtype == MOVE_RUN)
data << uint8(0); // new 2.1.0 data << uint8(0); // new 2.1.0
data << float(GetSpeed(mtype)); data << float(GetSpeed(mtype));
@ -10576,7 +10572,7 @@ Unit* Unit::GetUnit(WorldObject& object, uint64 guid)
bool Unit::isVisibleForInState( Player const* u, bool inVisibleList ) const bool Unit::isVisibleForInState( Player const* u, bool inVisibleList ) const
{ {
return isVisibleForOrDetect(u,false,inVisibleList); return isVisibleForOrDetect(u, false, inVisibleList, false);
} }
uint32 Unit::GetCreatureType() const uint32 Unit::GetCreatureType() const
@ -12105,6 +12101,10 @@ void Unit::ApplyCastTimePercentMod(float val, bool apply )
uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime ) uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime )
{ {
// Not apply this to creature casted spells with casttime==0
if(CastingTime==0 && GetTypeId()==TYPEID_UNIT && !((Creature*)this)->isPet())
return 3500;
if (CastingTime > 7000) CastingTime = 7000; if (CastingTime > 7000) CastingTime = 7000;
if (CastingTime < 1500) CastingTime = 1500; if (CastingTime < 1500) CastingTime = 1500;
@ -12302,9 +12302,9 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
return NULL; return NULL;
} }
pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, GetGUID()); pet->SetOwnerGUID(GetGUID());
pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, GetGUID()); pet->SetCreatorGUID(GetGUID());
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,getFaction()); pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id);
if(!pet->InitStatsForLevel(creatureTarget->getLevel())) if(!pet->InitStatsForLevel(creatureTarget->getLevel()))

View file

@ -339,7 +339,8 @@ enum DeathState
JUST_DIED = 1, JUST_DIED = 1,
CORPSE = 2, CORPSE = 2,
DEAD = 3, DEAD = 3,
JUST_ALIVED = 4 JUST_ALIVED = 4,
DEAD_FALLING= 5
}; };
enum UnitState enum UnitState
@ -365,14 +366,14 @@ enum UnitState
enum UnitMoveType enum UnitMoveType
{ {
MOVE_WALK = 0, MOVE_WALK = 0,
MOVE_RUN = 1, MOVE_RUN = 1,
MOVE_WALKBACK = 2, MOVE_RUN_BACK = 2,
MOVE_SWIM = 3, MOVE_SWIM = 3,
MOVE_SWIMBACK = 4, MOVE_SWIM_BACK = 4,
MOVE_TURN = 5, MOVE_TURN_RATE = 5,
MOVE_FLY = 6, MOVE_FLIGHT = 6,
MOVE_FLYBACK = 7 MOVE_FLIGHT_BACK = 7,
}; };
#define MAX_MOVE_TYPE 8 #define MAX_MOVE_TYPE 8
@ -1003,11 +1004,14 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
DeathState getDeathState() { return m_deathState; }; DeathState getDeathState() { return m_deathState; };
virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet
uint64 const& GetOwnerGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMONEDBY); } uint64 GetOwnerGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMONEDBY); }
void SetOwnerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner); }
uint64 GetCreatorGUID() const { return GetUInt64Value(UNIT_FIELD_CREATEDBY); }
void SetCreatorGUID(uint64 creator) { SetUInt64Value(UNIT_FIELD_CREATEDBY, creator); }
uint64 GetPetGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); } uint64 GetPetGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); }
uint64 GetCharmerGUID() const { return GetUInt64Value(UNIT_FIELD_CHARMEDBY); } uint64 GetCharmerGUID() const { return GetUInt64Value(UNIT_FIELD_CHARMEDBY); }
uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); }
void SetCharmerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_CHARMEDBY, owner); } void SetCharmerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_CHARMEDBY, owner); }
uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); }
uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); } uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); }
uint64 GetCharmerOrOwnerOrOwnGUID() const uint64 GetCharmerOrOwnerOrOwnGUID() const
@ -1036,6 +1040,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SetPet(Pet* pet); void SetPet(Pet* pet);
void SetCharm(Unit* pet); void SetCharm(Unit* pet);
bool isCharmed() const { return GetCharmerGUID() != 0; } bool isCharmed() const { return GetCharmerGUID() != 0; }
CharmInfo* GetCharmInfo() { return m_charmInfo; } CharmInfo* GetCharmInfo() { return m_charmInfo; }
@ -1158,7 +1163,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SetVisibility(UnitVisibility x); void SetVisibility(UnitVisibility x);
// common function for visibility checks for player/creatures with detection code // common function for visibility checks for player/creatures with detection code
bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false) const; bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
bool canDetectInvisibilityOf(Unit const* u) const; bool canDetectInvisibilityOf(Unit const* u) const;
// virtual functions for all world objects types // virtual functions for all world objects types
@ -1171,7 +1176,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
AuraList const& GetSingleCastAuras() const { return m_scAuras; } AuraList const& GetSingleCastAuras() const { return m_scAuras; }
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
// Threat related methodes // Threat related methods
bool CanHaveThreatList() const; bool CanHaveThreatList() const;
void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL); void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL); float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);

View file

@ -42,15 +42,15 @@ alter table creature_movement add `wpguid` int(11) default '0';
#include <cassert> #include <cassert>
//-----------------------------------------------// //-----------------------------------------------//
void void WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
{ {
sLog.outDetail("LoadPath: loading waypoint path for creature %d,%d", c.GetGUIDLow(), c.GetDBTableGUIDLow()); sLog.outDetail("LoadPath: loading waypoint path for creature %d,%d", c.GetGUIDLow(), c.GetDBTableGUIDLow());
i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow()); i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow());
if(!i_path) if(!i_path)
{ {
sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s(%d) doesn't have waypoint path", c.GetName(), c.GetDBTableGUIDLow()); sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %d) doesn't have waypoint path",
c.GetName(), c.GetEntry(), c.GetDBTableGUIDLow());
return; return;
} }
@ -59,26 +59,23 @@ WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
for(uint32 i = 0; i < node_count-1; i++) for(uint32 i = 0; i < node_count-1; i++)
i_hasDone[i] = false; i_hasDone[i] = false;
// to prevent a misbehaviour inside "update" // to prevent a misbehavior inside "update"
// update is always called with the next wp - but the wpSys needs the current // update is always called with the next wp - but the wpSys needs the current
// so when the routine is called the first time, wpSys gets the last waypoint // so when the routine is called the first time, wpSys gets the last waypoint
// and this prevents the system from performing text/emote, etc // and this prevents the system from performing text/emote, etc
i_hasDone[node_count - 1] = true; i_hasDone[node_count - 1] = true;
} }
void void WaypointMovementGenerator<Creature>::ClearWaypoints()
WaypointMovementGenerator<Creature>::ClearWaypoints()
{ {
i_path = NULL; i_path = NULL;
} }
void void WaypointMovementGenerator<Creature>::Initialize()
WaypointMovementGenerator<Creature>::Initialize()
{ {
} }
bool bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{ {
if(!&creature) if(!&creature)
return true; return true;
@ -103,7 +100,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &di
i_nextMoveTime.Update(diff); i_nextMoveTime.Update(diff);
i_destinationHolder.UpdateTraveller(traveller, diff, false, true); i_destinationHolder.UpdateTraveller(traveller, diff, false, true);
// creature has been stoped in middle of the waypoint segment // creature has been stopped in middle of the waypoint segment
if (!i_destinationHolder.HasArrived() && creature.IsStopped()) if (!i_destinationHolder.HasArrived() && creature.IsStopped())
{ {
if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it
@ -213,14 +210,12 @@ void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
} }
//----------------------------------------------------// //----------------------------------------------------//
void void FlightPathMovementGenerator::LoadPath(Player &)
FlightPathMovementGenerator::LoadPath(Player &)
{ {
objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds); objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds);
} }
uint32 uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
FlightPathMovementGenerator::GetPathAtMapEnd() const
{ {
if(i_currentNode >= i_mapIds.size()) if(i_currentNode >= i_mapIds.size())
return i_mapIds.size(); return i_mapIds.size();
@ -235,8 +230,7 @@ FlightPathMovementGenerator::GetPathAtMapEnd() const
return i_mapIds.size(); return i_mapIds.size();
} }
void void FlightPathMovementGenerator::Initialize(Player &player)
FlightPathMovementGenerator::Initialize(Player &player)
{ {
player.getHostilRefManager().setOnlineOfflineState(false); player.getHostilRefManager().setOnlineOfflineState(false);
player.addUnitState(UNIT_STAT_IN_FLIGHT); player.addUnitState(UNIT_STAT_IN_FLIGHT);
@ -251,7 +245,6 @@ FlightPathMovementGenerator::Initialize(Player &player)
void FlightPathMovementGenerator::Finalize(Player & player) void FlightPathMovementGenerator::Finalize(Player & player)
{ {
float x, y, z; float x, y, z;
i_destinationHolder.GetLocationNow(player.GetMapId(), x, y, z); i_destinationHolder.GetLocationNow(player.GetMapId(), x, y, z);
player.SetPosition(x, y, z, player.GetOrientation()); player.SetPosition(x, y, z, player.GetOrientation());
@ -271,8 +264,7 @@ void FlightPathMovementGenerator::Finalize(Player & player)
} }
} }
bool bool FlightPathMovementGenerator::Update(Player &player, const uint32 &diff)
FlightPathMovementGenerator::Update(Player &player, const uint32 &diff)
{ {
if( MovementInProgress() ) if( MovementInProgress() )
{ {
@ -307,8 +299,7 @@ FlightPathMovementGenerator::Update(Player &player, const uint32 &diff)
return false; return false;
} }
void void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
{ {
if(i_mapIds.empty()) if(i_mapIds.empty())
return; return;

View file

@ -73,10 +73,8 @@ class MANGOS_DLL_SPEC WaypointMovementGenerator<Creature>
: public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >, : public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >,
public PathMovementBase<Creature, WaypointPath*> public PathMovementBase<Creature, WaypointPath*>
{ {
TimeTrackerSmall i_nextMoveTime;
std::vector<bool> i_hasDone;
public: public:
WaypointMovementGenerator(Creature &) : i_nextMoveTime(0) {} WaypointMovementGenerator(Creature &) : i_nextMoveTime(0), b_StopedByPlayer(false) {}
~WaypointMovementGenerator() { ClearWaypoints(); } ~WaypointMovementGenerator() { ClearWaypoints(); }
void Initialize(Creature &u) void Initialize(Creature &u)
{ {
@ -85,7 +83,12 @@ public PathMovementBase<Creature, WaypointPath*>
LoadPath(u); LoadPath(u);
} }
void Finalize(Creature &) {} void Finalize(Creature &) {}
void Reset(Creature &u) { ReloadPath(u); } void Reset(Creature &u)
{
ReloadPath(u);
b_StopedByPlayer = false;
i_nextMoveTime.Reset(0);
}
bool Update(Creature &u, const uint32 &diff); bool Update(Creature &u, const uint32 &diff);
void MovementInform(Creature &); void MovementInform(Creature &);
@ -104,6 +107,9 @@ public PathMovementBase<Creature, WaypointPath*>
static void Initialize(void); static void Initialize(void);
private: private:
void ClearWaypoints(); void ClearWaypoints();
TimeTrackerSmall i_nextMoveTime;
std::vector<bool> i_hasDone;
bool b_StopedByPlayer; bool b_StopedByPlayer;
}; };

View file

@ -112,10 +112,12 @@ World::World()
World::~World() World::~World()
{ {
///- Empty the kicked session set ///- Empty the kicked session set
for (std::set<WorldSession*>::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr) while (!m_sessions.empty())
delete *itr; {
// not remove from queue, prevent loading new sessions
m_kicked_sessions.clear(); delete m_sessions.begin()->second;
m_sessions.erase(m_sessions.begin());
}
///- Empty the WeatherMap ///- Empty the WeatherMap
for (WeatherMap::iterator itr = m_weathers.begin(); itr != m_weathers.end(); ++itr) for (WeatherMap::iterator itr = m_weathers.begin(); itr != m_weathers.end(); ++itr)
@ -123,6 +125,9 @@ World::~World()
m_weathers.clear(); m_weathers.clear();
while (!cliCmdQueue.empty())
delete cliCmdQueue.next();
VMAP::VMapFactory::clear(); VMAP::VMapFactory::clear();
if(m_resultQueue) delete m_resultQueue; if(m_resultQueue) delete m_resultQueue;
@ -195,17 +200,26 @@ World::AddSession_ (WorldSession* s)
if (!RemoveSession (s->GetAccountId ())) if (!RemoveSession (s->GetAccountId ()))
{ {
s->KickPlayer (); s->KickPlayer ();
m_kicked_sessions.insert (s); delete s; // session not added yet in session list, so not listed in queue
return; return;
} }
// decrease session counts only at not reconnection case
bool decrease_session = true;
// if session already exist, prepare to it deleting at next world update // if session already exist, prepare to it deleting at next world update
// NOTE - KickPlayer() should be called on "old" in RemoveSession() // NOTE - KickPlayer() should be called on "old" in RemoveSession()
{ {
SessionMap::const_iterator old = m_sessions.find(s->GetAccountId ()); SessionMap::const_iterator old = m_sessions.find(s->GetAccountId ());
if(old != m_sessions.end()) if(old != m_sessions.end())
m_kicked_sessions.insert (old->second); {
// prevent decrease sessions count if session queued
if(RemoveQueuedPlayer(old->second))
decrease_session = false;
// not remove replaced session form queue if listed
delete old->second;
}
} }
m_sessions[s->GetAccountId ()] = s; m_sessions[s->GetAccountId ()] = s;
@ -213,9 +227,11 @@ World::AddSession_ (WorldSession* s)
uint32 Sessions = GetActiveAndQueuedSessionCount (); uint32 Sessions = GetActiveAndQueuedSessionCount ();
uint32 pLimit = GetPlayerAmountLimit (); uint32 pLimit = GetPlayerAmountLimit ();
uint32 QueueSize = GetQueueSize (); //number of players in the queue uint32 QueueSize = GetQueueSize (); //number of players in the queue
//so we don't count the user trying to //so we don't count the user trying to
//login as a session and queue the socket that we are using //login as a session and queue the socket that we are using
--Sessions; if(decrease_session)
--Sessions;
if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER ) if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER )
{ {
@ -259,6 +275,7 @@ int32 World::GetQueuePos(WorldSession* sess)
void World::AddQueuedPlayer(WorldSession* sess) void World::AddQueuedPlayer(WorldSession* sess)
{ {
sess->SetInQueue(true);
m_QueuedPlayer.push_back (sess); m_QueuedPlayer.push_back (sess);
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too. // The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
@ -274,7 +291,7 @@ void World::AddQueuedPlayer(WorldSession* sess)
//sess->SendAuthWaitQue (GetQueuePos (sess)); //sess->SendAuthWaitQue (GetQueuePos (sess));
} }
void World::RemoveQueuedPlayer(WorldSession* sess) bool World::RemoveQueuedPlayer(WorldSession* sess)
{ {
// sessions count including queued to remove (if removed_session set) // sessions count including queued to remove (if removed_session set)
uint32 sessions = GetActiveSessionCount(); uint32 sessions = GetActiveSessionCount();
@ -282,16 +299,16 @@ void World::RemoveQueuedPlayer(WorldSession* sess)
uint32 position = 1; uint32 position = 1;
Queue::iterator iter = m_QueuedPlayer.begin(); Queue::iterator iter = m_QueuedPlayer.begin();
// if session not queued then we need decrease sessions count (Remove socked callet before session removing from session list)
bool decrease_session = true;
// search to remove and count skipped positions // search to remove and count skipped positions
bool found = false;
for(;iter != m_QueuedPlayer.end(); ++iter, ++position) for(;iter != m_QueuedPlayer.end(); ++iter, ++position)
{ {
if(*iter==sess) if(*iter==sess)
{ {
sess->SetInQueue(false);
iter = m_QueuedPlayer.erase(iter); iter = m_QueuedPlayer.erase(iter);
decrease_session = false; // removing queued session found = true; // removing queued session
break; break;
} }
} }
@ -299,15 +316,16 @@ void World::RemoveQueuedPlayer(WorldSession* sess)
// iter point to next socked after removed or end() // iter point to next socked after removed or end()
// position store position of removed socket and then new position next socket after removed // position store position of removed socket and then new position next socket after removed
// decrease for case session queued for removing // if session not queued then we need decrease sessions count
if(decrease_session && sessions) if(!found && sessions)
--sessions; --sessions;
// accept first in queue // accept first in queue
if( (!m_playerLimit || sessions < m_playerLimit) && !m_QueuedPlayer.empty() ) if( (!m_playerLimit || sessions < m_playerLimit) && !m_QueuedPlayer.empty() )
{ {
WorldSession * socket = m_QueuedPlayer.front(); WorldSession* pop_sess = m_QueuedPlayer.front();
socket->SendAuthWaitQue(0); pop_sess->SetInQueue(false);
pop_sess->SendAuthWaitQue(0);
m_QueuedPlayer.pop_front(); m_QueuedPlayer.pop_front();
// update iter to point first queued socket or end() if queue is empty now // update iter to point first queued socket or end() if queue is empty now
@ -319,6 +337,8 @@ void World::RemoveQueuedPlayer(WorldSession* sess)
// iter point to first not updated socket, position store new position // iter point to first not updated socket, position store new position
for(; iter != m_QueuedPlayer.end(); ++iter, ++position) for(; iter != m_QueuedPlayer.end(); ++iter, ++position)
(*iter)->SendAuthWaitQue(position); (*iter)->SendAuthWaitQue(position);
return found;
} }
/// Find a Weather object by the given zoneid /// Find a Weather object by the given zoneid
@ -647,8 +667,63 @@ void World::LoadConfigSettings(bool reload)
sLog.outError("StartPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",m_configs[CONFIG_START_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]); sLog.outError("StartPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",m_configs[CONFIG_START_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]);
m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL]; m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];
} }
m_configs[CONFIG_START_PLAYER_MONEY] = sConfig.GetIntDefault("StartPlayerMoney", 0);
if(m_configs[CONFIG_START_PLAYER_MONEY] < 0)
{
sLog.outError("StartPlayerMoney (%i) must be in range 0..%u. Set to %u.",m_configs[CONFIG_START_PLAYER_MONEY],MAX_MONEY_AMOUNT,0);
m_configs[CONFIG_START_PLAYER_MONEY] = 0;
}
else if(m_configs[CONFIG_START_PLAYER_MONEY] > MAX_MONEY_AMOUNT)
{
sLog.outError("StartPlayerMoney (%i) must be in range 0..%u. Set to %u.",
m_configs[CONFIG_START_PLAYER_MONEY],MAX_MONEY_AMOUNT,MAX_MONEY_AMOUNT);
m_configs[CONFIG_START_PLAYER_MONEY] = MAX_MONEY_AMOUNT;
}
m_configs[CONFIG_MAX_HONOR_POINTS] = sConfig.GetIntDefault("MaxHonorPoints", 75000); m_configs[CONFIG_MAX_HONOR_POINTS] = sConfig.GetIntDefault("MaxHonorPoints", 75000);
if(m_configs[CONFIG_MAX_HONOR_POINTS] < 0)
{
sLog.outError("MaxHonorPoints (%i) can't be negative. Set to 0.",m_configs[CONFIG_MAX_HONOR_POINTS]);
m_configs[CONFIG_MAX_HONOR_POINTS] = 0;
}
m_configs[CONFIG_START_HONOR_POINTS] = sConfig.GetIntDefault("StartHonorPoints", 0);
if(m_configs[CONFIG_START_HONOR_POINTS] < 0)
{
sLog.outError("StartHonorPoints (%i) must be in range 0..MaxHonorPoints(%u). Set to %u.",
m_configs[CONFIG_START_HONOR_POINTS],m_configs[CONFIG_MAX_HONOR_POINTS],0);
m_configs[CONFIG_MAX_HONOR_POINTS] = 0;
}
else if(m_configs[CONFIG_START_HONOR_POINTS] > m_configs[CONFIG_MAX_HONOR_POINTS])
{
sLog.outError("StartHonorPoints (%i) must be in range 0..MaxHonorPoints(%u). Set to %u.",
m_configs[CONFIG_START_HONOR_POINTS],m_configs[CONFIG_MAX_HONOR_POINTS],m_configs[CONFIG_MAX_HONOR_POINTS]);
m_configs[CONFIG_START_HONOR_POINTS] = m_configs[CONFIG_MAX_HONOR_POINTS];
}
m_configs[CONFIG_MAX_ARENA_POINTS] = sConfig.GetIntDefault("MaxArenaPoints", 5000); m_configs[CONFIG_MAX_ARENA_POINTS] = sConfig.GetIntDefault("MaxArenaPoints", 5000);
if(m_configs[CONFIG_MAX_ARENA_POINTS] < 0)
{
sLog.outError("MaxArenaPoints (%i) can't be negative. Set to 0.",m_configs[CONFIG_MAX_ARENA_POINTS]);
m_configs[CONFIG_MAX_ARENA_POINTS] = 0;
}
m_configs[CONFIG_START_ARENA_POINTS] = sConfig.GetIntDefault("StartArenaPoints", 0);
if(m_configs[CONFIG_START_ARENA_POINTS] < 0)
{
sLog.outError("StartArenaPoints (%i) must be in range 0..MaxArenaPoints(%u). Set to %u.",
m_configs[CONFIG_START_ARENA_POINTS],m_configs[CONFIG_MAX_ARENA_POINTS],0);
m_configs[CONFIG_MAX_ARENA_POINTS] = 0;
}
else if(m_configs[CONFIG_START_ARENA_POINTS] > m_configs[CONFIG_MAX_ARENA_POINTS])
{
sLog.outError("StartArenaPoints (%i) must be in range 0..MaxArenaPoints(%u). Set to %u.",
m_configs[CONFIG_START_ARENA_POINTS],m_configs[CONFIG_MAX_ARENA_POINTS],m_configs[CONFIG_MAX_ARENA_POINTS]);
m_configs[CONFIG_START_ARENA_POINTS] = m_configs[CONFIG_MAX_ARENA_POINTS];
}
m_configs[CONFIG_ALL_TAXI_PATHS] = sConfig.GetBoolDefault("AllFlightPaths", false);
m_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfig.GetBoolDefault("Instance.IgnoreLevel", false); m_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfig.GetBoolDefault("Instance.IgnoreLevel", false);
m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false); m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false);
@ -678,6 +753,19 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false); m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false);
m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false); m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false);
m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1);
if(m_configs[CONFIG_START_GM_LEVEL] < m_configs[CONFIG_START_PLAYER_LEVEL])
{
sLog.outError("GM.StartLevel (%i) must be in range StartPlayerLevel(%u)..255. Set to %u.",
m_configs[CONFIG_START_GM_LEVEL],m_configs[CONFIG_START_PLAYER_LEVEL],m_configs[CONFIG_START_PLAYER_LEVEL]);
m_configs[CONFIG_START_GM_LEVEL] = m_configs[CONFIG_START_PLAYER_LEVEL];
}
else if(m_configs[CONFIG_START_GM_LEVEL] > 255)
{
sLog.outError("GM.StartLevel (%i) must be in range 1..255. Set to %u.",m_configs[CONFIG_START_GM_LEVEL],255);
m_configs[CONFIG_START_GM_LEVEL] = 255;
}
m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0); m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
m_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfig.GetIntDefault("MailDeliveryDelay",HOUR); m_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfig.GetIntDefault("MailDeliveryDelay",HOUR);
@ -742,6 +830,10 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY] = sConfig.GetBoolDefault("SaveRespawnTimeImmediately",true); m_configs[CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY] = sConfig.GetBoolDefault("SaveRespawnTimeImmediately",true);
m_configs[CONFIG_WEATHER] = sConfig.GetBoolDefault("ActivateWeather",true); m_configs[CONFIG_WEATHER] = sConfig.GetBoolDefault("ActivateWeather",true);
m_configs[CONFIG_DISABLE_BREATHING] = sConfig.GetIntDefault("DisableWaterBreath", SEC_CONSOLE);
m_configs[CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL] = sConfig.GetBoolDefault("AlwaysMaxSkillForLevel", false);
if(reload) if(reload)
{ {
uint32 val = sConfig.GetIntDefault("Expansion",1); uint32 val = sConfig.GetIntDefault("Expansion",1);
@ -798,6 +890,8 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_LISTEN_RANGE_TEXTEMOTE] = sConfig.GetIntDefault("ListenRange.TextEmote", 25); m_configs[CONFIG_LISTEN_RANGE_TEXTEMOTE] = sConfig.GetIntDefault("ListenRange.TextEmote", 25);
m_configs[CONFIG_LISTEN_RANGE_YELL] = sConfig.GetIntDefault("ListenRange.Yell", 300); m_configs[CONFIG_LISTEN_RANGE_YELL] = sConfig.GetIntDefault("ListenRange.Yell", 300);
m_configs[CONFIG_INSTANT_LOGOUT] = sConfig.GetIntDefault("InstantLogout", SEC_MODERATOR);
m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1); m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1);
if(m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE) if(m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
{ {
@ -2170,6 +2264,8 @@ void World::SendZoneText(uint32 zone, const char* text, WorldSession *self, uint
/// Kick (and save) all players /// Kick (and save) all players
void World::KickAll() void World::KickAll()
{ {
m_QueuedPlayer.clear(); // prevent send queue update packet and login queued sessions
// session not removed at kick and will removed in next update tick // session not removed at kick and will removed in next update tick
for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
itr->second->KickPlayer(); itr->second->KickPlayer();
@ -2184,18 +2280,6 @@ void World::KickAllLess(AccountTypes sec)
itr->second->KickPlayer(); itr->second->KickPlayer();
} }
/// Kick all queued players
void World::KickAllQueued()
{
// session not removed at kick and will removed in next update tick
//TODO here
// for (Queue::iterator itr = m_QueuedPlayer.begin(); itr != m_QueuedPlayer.end(); ++itr)
// if(WorldSession* session = (*itr)->GetSession())
// session->KickPlayer();
m_QueuedPlayer.empty();
}
/// Kick (and save) the designated player /// Kick (and save) the designated player
bool World::KickPlayer(std::string playerName) bool World::KickPlayer(std::string playerName)
{ {
@ -2426,20 +2510,13 @@ void World::SendServerMessage(uint32 type, const char *text, Player* player)
void World::UpdateSessions( time_t diff ) void World::UpdateSessions( time_t diff )
{ {
///- Add new sessions
while(!addSessQueue.empty()) while(!addSessQueue.empty())
{ {
WorldSession* sess = addSessQueue.next (); WorldSession* sess = addSessQueue.next ();
AddSession_ (sess); AddSession_ (sess);
} }
///- Delete kicked sessions at add new session
for (std::set<WorldSession*>::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr)
{
RemoveQueuedPlayer (*itr);
delete *itr;
}
m_kicked_sessions.clear();
///- Then send an update signal to remaining ones ///- Then send an update signal to remaining ones
for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next) for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
{ {

View file

@ -103,8 +103,11 @@ enum WorldConfigs
CONFIG_SKIP_CINEMATICS, CONFIG_SKIP_CINEMATICS,
CONFIG_MAX_PLAYER_LEVEL, CONFIG_MAX_PLAYER_LEVEL,
CONFIG_START_PLAYER_LEVEL, CONFIG_START_PLAYER_LEVEL,
CONFIG_START_PLAYER_MONEY,
CONFIG_MAX_HONOR_POINTS, CONFIG_MAX_HONOR_POINTS,
CONFIG_START_HONOR_POINTS,
CONFIG_MAX_ARENA_POINTS, CONFIG_MAX_ARENA_POINTS,
CONFIG_START_ARENA_POINTS,
CONFIG_INSTANCE_IGNORE_LEVEL, CONFIG_INSTANCE_IGNORE_LEVEL,
CONFIG_INSTANCE_IGNORE_RAID, CONFIG_INSTANCE_IGNORE_RAID,
CONFIG_BATTLEGROUND_CAST_DESERTER, CONFIG_BATTLEGROUND_CAST_DESERTER,
@ -122,6 +125,7 @@ enum WorldConfigs
CONFIG_GM_IN_GM_LIST, CONFIG_GM_IN_GM_LIST,
CONFIG_GM_IN_WHO_LIST, CONFIG_GM_IN_WHO_LIST,
CONFIG_GM_LOG_TRADE, CONFIG_GM_LOG_TRADE,
CONFIG_START_GM_LEVEL,
CONFIG_GROUP_VISIBILITY, CONFIG_GROUP_VISIBILITY,
CONFIG_MAIL_DELIVERY_DELAY, CONFIG_MAIL_DELIVERY_DELAY,
CONFIG_UPTIME_UPDATE, CONFIG_UPTIME_UPDATE,
@ -138,6 +142,7 @@ enum WorldConfigs
CONFIG_SKILL_GAIN_WEAPON, CONFIG_SKILL_GAIN_WEAPON,
CONFIG_MAX_OVERSPEED_PINGS, CONFIG_MAX_OVERSPEED_PINGS,
CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY, CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY,
CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL,
CONFIG_WEATHER, CONFIG_WEATHER,
CONFIG_EXPANSION, CONFIG_EXPANSION,
CONFIG_CHATFLOOD_MESSAGE_COUNT, CONFIG_CHATFLOOD_MESSAGE_COUNT,
@ -164,6 +169,9 @@ enum WorldConfigs
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP, CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP,
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE, CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE,
CONFIG_THREAT_RADIUS, CONFIG_THREAT_RADIUS,
CONFIG_INSTANT_LOGOUT,
CONFIG_DISABLE_BREATHING,
CONFIG_ALL_TAXI_PATHS,
CONFIG_DECLINED_NAMES_USED, CONFIG_DECLINED_NAMES_USED,
CONFIG_LISTEN_RANGE_SAY, CONFIG_LISTEN_RANGE_SAY,
CONFIG_LISTEN_RANGE_TEXTEMOTE, CONFIG_LISTEN_RANGE_TEXTEMOTE,
@ -350,7 +358,7 @@ class World
//player Queue //player Queue
typedef std::list<WorldSession*> Queue; typedef std::list<WorldSession*> Queue;
void AddQueuedPlayer(WorldSession*); void AddQueuedPlayer(WorldSession*);
void RemoveQueuedPlayer(WorldSession*); bool RemoveQueuedPlayer(WorldSession* session);
int32 GetQueuePos(WorldSession*); int32 GetQueuePos(WorldSession*);
uint32 GetQueueSize() const { return m_QueuedPlayer.size(); } uint32 GetQueueSize() const { return m_QueuedPlayer.size(); }
@ -433,7 +441,6 @@ class World
bool KickPlayer(std::string playerName); bool KickPlayer(std::string playerName);
void KickAll(); void KickAll();
void KickAllLess(AccountTypes sec); void KickAllLess(AccountTypes sec);
void KickAllQueued();
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author); BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);
bool RemoveBanAccount(BanMode mode, std::string nameOrIP); bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
@ -491,7 +498,6 @@ class World
WeatherMap m_weathers; WeatherMap m_weathers;
typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap; typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
SessionMap m_sessions; SessionMap m_sessions;
std::set<WorldSession*> m_kicked_sessions;
uint32 m_maxActiveSessionCount; uint32 m_maxActiveSessionCount;
uint32 m_maxQueuedSessionCount; uint32 m_maxQueuedSessionCount;

View file

@ -45,7 +45,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expan
LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time), LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time),
_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion), _player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion),
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)), m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)),
_logoutTime(0), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_latency(0) _logoutTime(0), m_inQueue(false), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_latency(0)
{ {
if (sock) if (sock)
{ {
@ -205,6 +205,13 @@ bool WorldSession::Update(uint32 /*diff*/)
(this->*opHandle.handler)(*packet); (this->*opHandle.handler)(*packet);
break; break;
case STATUS_AUTHED: case STATUS_AUTHED:
// prevent cheating with skip queue wait
if(m_inQueue)
{
logUnexpectedOpcode(packet, "the player not pass queue yet");
break;
}
m_playerRecentlyLogout = false; m_playerRecentlyLogout = false;
(this->*opHandle.handler)(*packet); (this->*opHandle.handler)(*packet);
break; break;
@ -473,38 +480,38 @@ void WorldSession::Handle_NULL( WorldPacket& recvPacket )
void WorldSession::Handle_EarlyProccess( WorldPacket& recvPacket ) void WorldSession::Handle_EarlyProccess( WorldPacket& recvPacket )
{ {
sLog.outError( "SESSION: received opcode %s (0x%.4X) that must be proccessed in WorldSocket::OnRead", sLog.outError( "SESSION: received opcode %s (0x%.4X) that must be processed in WorldSocket::OnRead",
LookupOpcodeName(recvPacket.GetOpcode()), LookupOpcodeName(recvPacket.GetOpcode()),
recvPacket.GetOpcode()); recvPacket.GetOpcode());
} }
void WorldSession::Handle_ServerSide( WorldPacket& recvPacket ) void WorldSession::Handle_ServerSide( WorldPacket& recvPacket )
{ {
sLog.outError( "SESSION: received sever-side opcode %s (0x%.4X)", sLog.outError( "SESSION: received server-side opcode %s (0x%.4X)",
LookupOpcodeName(recvPacket.GetOpcode()), LookupOpcodeName(recvPacket.GetOpcode()),
recvPacket.GetOpcode()); recvPacket.GetOpcode());
} }
void WorldSession::Handle_Depricated( WorldPacket& recvPacket ) void WorldSession::Handle_Deprecated( WorldPacket& recvPacket )
{ {
sLog.outError( "SESSION: received depricated opcode %s (0x%.4X)", sLog.outError( "SESSION: received deprecated opcode %s (0x%.4X)",
LookupOpcodeName(recvPacket.GetOpcode()), LookupOpcodeName(recvPacket.GetOpcode()),
recvPacket.GetOpcode()); recvPacket.GetOpcode());
} }
void WorldSession::SendAuthWaitQue(uint32 position) void WorldSession::SendAuthWaitQue(uint32 position)
{ {
if(position == 0) if(position == 0)
{ {
WorldPacket packet( SMSG_AUTH_RESPONSE, 1 ); WorldPacket packet( SMSG_AUTH_RESPONSE, 1 );
packet << uint8( AUTH_OK ); packet << uint8( AUTH_OK );
SendPacket(&packet); SendPacket(&packet);
} }
else else
{ {
WorldPacket packet( SMSG_AUTH_RESPONSE, 5 ); WorldPacket packet( SMSG_AUTH_RESPONSE, 5 );
packet << uint8( AUTH_WAIT_QUEUE ); packet << uint8( AUTH_WAIT_QUEUE );
packet << uint32 (position); packet << uint32 (position);
SendPacket(&packet); SendPacket(&packet);
} }
} }

View file

@ -83,7 +83,7 @@ class MANGOS_DLL_SPEC WorldSession
void SendNotification(int32 string_id,...); void SendNotification(int32 string_id,...);
void SendPetNameInvalid(uint32 error, std::string name, DeclinedName *declinedName); void SendPetNameInvalid(uint32 error, std::string name, DeclinedName *declinedName);
void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type); void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type);
void SendPartyResult(PartyOperation operation, std::string member, PartyResult res); void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3); void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3);
uint32 GetSecurity() const { return _security; } uint32 GetSecurity() const { return _security; }
@ -95,6 +95,9 @@ class MANGOS_DLL_SPEC WorldSession
void SetPlayer(Player *plr) { _player = plr; } void SetPlayer(Player *plr) { _player = plr; }
uint8 Expansion() const { return m_expansion; } uint8 Expansion() const { return m_expansion; }
/// Session in auth.queue currently
void SetInQueue(bool state) { m_inQueue = state; }
/// Is the user engaged in a log out process? /// Is the user engaged in a log out process?
bool isLogingOut() const { return _logoutTime || m_playerLogout; } bool isLogingOut() const { return _logoutTime || m_playerLogout; }
@ -206,7 +209,7 @@ class MANGOS_DLL_SPEC WorldSession
void Handle_NULL(WorldPacket& recvPacket); // not used void Handle_NULL(WorldPacket& recvPacket); // not used
void Handle_EarlyProccess( WorldPacket& recvPacket);// just mark packets processed in WorldSocket::OnRead void Handle_EarlyProccess( WorldPacket& recvPacket);// just mark packets processed in WorldSocket::OnRead
void Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from client void Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from client
void Handle_Depricated(WorldPacket& recvPacket); // never used anymore by client void Handle_Deprecated(WorldPacket& recvPacket); // never used anymore by client
void HandleCharEnumOpcode(WorldPacket& recvPacket); void HandleCharEnumOpcode(WorldPacket& recvPacket);
void HandleCharDeleteOpcode(WorldPacket& recvPacket); void HandleCharDeleteOpcode(WorldPacket& recvPacket);
@ -329,7 +332,6 @@ class MANGOS_DLL_SPEC WorldSession
void HandleGroupDeclineOpcode(WorldPacket& recvPacket); void HandleGroupDeclineOpcode(WorldPacket& recvPacket);
void HandleGroupUninviteNameOpcode(WorldPacket& recvPacket); void HandleGroupUninviteNameOpcode(WorldPacket& recvPacket);
void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket); void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket);
void HandleGroupUninvite(uint64 guid, std::string name);
void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket); void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket);
void HandleGroupLeaveOpcode(WorldPacket& recvPacket); void HandleGroupLeaveOpcode(WorldPacket& recvPacket);
void HandleGroupPassOnLootOpcode( WorldPacket &recv_data ); void HandleGroupPassOnLootOpcode( WorldPacket &recv_data );
@ -635,6 +637,7 @@ class MANGOS_DLL_SPEC WorldSession
uint8 m_expansion; uint8 m_expansion;
time_t _logoutTime; time_t _logoutTime;
bool m_inQueue; // session wait in auth.queue
bool m_playerLoading; // code processed in LoginPlayer bool m_playerLoading; // code processed in LoginPlayer
bool m_playerLogout; // code processed in LogoutPlayer bool m_playerLogout; // code processed in LogoutPlayer
bool m_playerRecentlyLogout; bool m_playerRecentlyLogout;

View file

@ -712,7 +712,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
Field* fields = result->Fetch (); Field* fields = result->Fetch ();
expansion = fields[8].GetUInt8 () && sWorld.getConfig (CONFIG_EXPANSION) > 0; expansion = ((sWorld.getConfig(CONFIG_EXPANSION) > fields[8].GetUInt8()) ? fields[8].GetUInt8() : sWorld.getConfig(CONFIG_EXPANSION));
N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
g.SetDword (7); g.SetDword (7);
@ -734,8 +734,8 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
x.SetBinary (sha1.GetDigest (), sha1.GetLength ()); x.SetBinary (sha1.GetDigest (), sha1.GetLength ());
v = g.ModExp (x, N); v = g.ModExp (x, N);
const char* sStr = s.AsHexStr (); //Must be freed by OPENSSL_free() const char* sStr = s.AsHexStr (); //Must be freed by OPENSSL_free()
const char* vStr = v.AsHexStr (); //Must be freed by OPENSSL_free() const char* vStr = v.AsHexStr (); //Must be freed by OPENSSL_free()
const char* vold = fields[6].GetString (); const char* vold = fields[6].GetString ();
DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v_old: %s v_new: %s", DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v_old: %s v_new: %s",
@ -825,7 +825,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
SendPacket (packet); SendPacket (packet);
sLog.outBasic ("WorldSocket::HandleAuthSession: User tryes to login but his security level is not enough"); sLog.outBasic ("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough");
return -1; return -1;
} }
@ -940,7 +940,7 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
if (m_Session) if (m_Session)
m_Session->SetLatency (latency); m_Session->SetLatency (latency);
else else
{ {
sLog.outError ("WorldSocket::HandlePing: peer sent CMSG_PING, " sLog.outError ("WorldSocket::HandlePing: peer sent CMSG_PING, "

View file

@ -242,7 +242,7 @@ WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address)
m_NetThreads = new ReactorRunnable[m_NetThreadsCount]; m_NetThreads = new ReactorRunnable[m_NetThreadsCount];
sLog.outBasic ("Max alowed socket connections %d",ACE::max_handles ()); sLog.outBasic ("Max allowed socket connections %d",ACE::max_handles ());
// -1 means use default // -1 means use default
m_SockOutKBuff = sConfig.GetIntDefault ("Network.OutKBuff", -1); m_SockOutKBuff = sConfig.GetIntDefault ("Network.OutKBuff", -1);

View file

@ -31,6 +31,7 @@
#include "Language.h" #include "Language.h"
#include "MapManager.h" #include "MapManager.h"
#include <fstream> #include <fstream>
#include "ObjectMgr.h"
bool ChatHandler::HandleDebugInArcCommand(const char* /*args*/) bool ChatHandler::HandleDebugInArcCommand(const char* /*args*/)
{ {
@ -59,8 +60,8 @@ bool ChatHandler::HandleDebugSpellFailCommand(const char* args)
uint8 failnum = (uint8)atoi(px); uint8 failnum = (uint8)atoi(px);
WorldPacket data(SMSG_CAST_FAILED, 5); WorldPacket data(SMSG_CAST_FAILED, 5);
data << (uint32)133; data << uint32(133);
data << failnum; data << uint8(failnum);
m_session->SendPacket(&data); m_session->SendPacket(&data);
return true; return true;
@ -145,11 +146,14 @@ bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
std::string type; std::string type;
ifs >> type; ifs >> type;
if(type == "")
break;
if(type == "uint8") if(type == "uint8")
{ {
uint8 val1; uint16 val1;
ifs >> val1; ifs >> val1;
data << val1; data << uint8(val1);
} }
else if(type == "uint16") else if(type == "uint16")
{ {
@ -187,7 +191,8 @@ bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
} }
else else
{ {
sLog.outDebug("Sending opcode: unknown type %s", type.c_str()); sLog.outDebug("Sending opcode: unknown type '%s'", type.c_str());
break;
} }
} }
ifs.close(); ifs.close();

View file

@ -50,7 +50,7 @@ class RASocket: public TcpSocket
bool bLog; bool bLog;
bool bSecure; //kick on wrong pass, non exist. user, user with no priv bool bSecure; //kick on wrong pass, non exist. user, user with no priv
//will protect from DOS, bruteforce attacks //will protect from DOS, bruteforce attacks
//some 'smart' protection must be added for more scurity //some 'smart' protection must be added for more security
uint8 iMinLevel; uint8 iMinLevel;
enum enum
{ {

Some files were not shown because too many files have changed in this diff Show more