mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
Dropped the new SD2 Module in
This commit is contained in:
parent
5260602e28
commit
1ed51d35e9
650 changed files with 183227 additions and 0 deletions
891
src/modules/SD2/@@Temp_VC120/ScriptDev2.vcxproj
Normal file
891
src/modules/SD2/@@Temp_VC120/ScriptDev2.vcxproj
Normal file
|
|
@ -0,0 +1,891 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>ScriptDev2</ProjectName>
|
||||
<ProjectGuid>{4295C8A9-79B7-4354-8064-F05FB9CA0C96}</ProjectGuid>
|
||||
<RootNamespace>ScriptDev2</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\..\bin\win32_debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\ScriptDev2__$(Platform)_$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\..\bin\x64_debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\ScriptDev2__$(Platform)_$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\..\bin\win32_release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\ScriptDev2__$(Platform)_$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\..\bin\x64_release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\ScriptDev2__$(Platform)_$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mangosscript</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">mangosscript</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">mangosscript</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">mangosscript</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<AdditionalOptions>/Zm200 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>mangosd.lib;ACEd.lib;framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\win\VC120\mangosd__Win32_Debug;..\..\..\..\win\VC120\framework__Win32_Debug;..\..\..\..\dep\lib\win32_debug\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mangosscript.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<AdditionalOptions>/Zm200 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>mangosd.lib;ACEd.lib;framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\win\VC120\mangosd__x64_Debug;..\..\..\..\win\VC120\framework__x64_Debug;..\..\..\..\dep\lib\x64_Debug\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mangosscript.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/Zm200 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SCRIPT;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>mangosd.lib;ACE.lib;framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\win\VC120\mangosd__Win32_Release;..\..\..\..\win\VC120\framework__Win32_Release;..\..\..\..\dep\lib\win32_release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mangosscript.lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/Zm200 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SCRIPT;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>mangosd.lib;ACE.lib;framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\win\VC120\mangosd__x64_Release;..\..\..\..\win\VC120\framework__x64_Release;..\..\..\..\dep\lib\x64_release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mangosscript.lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\base\escort_ai.cpp" />
|
||||
<ClCompile Include="..\base\follower_ai.cpp" />
|
||||
<ClCompile Include="..\base\guard_ai.cpp" />
|
||||
<ClCompile Include="..\base\pet_ai.cpp" />
|
||||
<ClCompile Include="..\scripts\battlegrounds\battleground.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\alterac_mountains.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\arathi_highlands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blasted_lands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\burning_steppes.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\dun_morogh.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\eastern_plaguelands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\elwynn_forest.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\eversong_woods.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\ghostlands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\gilneas.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\gilneas_city.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\hinterlands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\ironforge.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\isle_of_queldanas.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\loch_modan.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\redridge_mountains.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\searing_gorge.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\silvermoon_city.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\silverpine_forest.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stormwind_city.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stranglethorn_vale.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\swamp_of_sorrows.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\tirisfal_glades.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\twilight_highlands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\undercity.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\vashjir.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\western_plaguelands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\westfall.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\wetlands.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\bastion_of_twilight\ascendant_council.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\bastion_of_twilight\boss_chogall.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\bastion_of_twilight\boss_halfus_wyrmbreaker.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\bastion_of_twilight\boss_sinestra.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\bastion_of_twilight\boss_valiona_and_theralion.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\bastion_of_twilight\instance_bastion_of_twilight.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_caverns\boss_beauty.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_caverns\boss_corla.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_caverns\boss_karsh_steelbender.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_caverns\boss_lord_obsidius.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_caverns\boss_romogg.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_caverns\instance_blackrock_caverns.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\blackrock_depths.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\boss_ambassador_flamelash.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\boss_coren_direbrew.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\boss_emperor_dagran_thaurissan.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\boss_general_angerforge.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\boss_high_interrogator_gerstahn.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\instance_blackrock_depths.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_spire\boss_gyth.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_spire\boss_overlord_wyrmthalak.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_spire\boss_pyroguard_emberseer.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_spire\instance_blackrock_spire.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\boss_atramedes.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\boss_chimaeron.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\boss_magmaw.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\boss_maloriak.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\boss_nefarian_descent.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\instance_blackwing_descent.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\omnotron_defense.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_broodlord_lashlayer.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_chromaggus.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_ebonroc.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_firemaw.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_flamegor.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_nefarian.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_razorgore.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_vaelastrasz.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\boss_victor_nefarius.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\instance_blackwing_lair.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_baron_geddon.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_garr.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_gehennas.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_golemagg.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_lucifron.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_magmadar.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_majordomo_executus.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_ragnaros.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_shazzrah.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\boss_sulfuron_harbinger.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\instance_molten_core.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\molten_core.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\deadmines\boss_mr_smite.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\deadmines\deadmines.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\deadmines\instance_deadmines.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\gnomeregan\boss_thermaplugg.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\gnomeregan\gnomeregan.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\gnomeregan\instance_gnomeregan.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\grim_batol\boss_drahga_shadowburner.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\grim_batol\boss_erudax.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\grim_batol\boss_forgemaster_throngus.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\grim_batol\boss_general_umbriss.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\grim_batol\instance_grim_batol.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_curator.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_maiden_of_virtue.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_midnight.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_moroes.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_netherspite.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_nightbane.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_prince_malchezaar.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_shade_of_aran.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\boss_terestian_illhoof.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\bosses_opera.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\chess_event.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\instance_karazhan.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\karazhan\karazhan.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\magisters_terrace\boss_felblood_kaelthas.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\magisters_terrace\boss_priestess_delrissa.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\magisters_terrace\boss_selin_fireheart.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\magisters_terrace\boss_vexallus.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\magisters_terrace\instance_magisters_terrace.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\magisters_terrace\magisters_terrace.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scarlet_enclave\ebon_hold.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scarlet_enclave\world_map_ebon_hold.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scarlet_monastery\boss_arcanist_doan.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scarlet_monastery\boss_headless_horseman.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scarlet_monastery\boss_herod.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scarlet_monastery\boss_mograine_and_whitemane.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scarlet_monastery\instance_scarlet_monastery.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scholomance\boss_darkmaster_gandling.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scholomance\boss_jandice_barov.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\scholomance\instance_scholomance.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\shadowfang_keep\boss_hummel.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\shadowfang_keep\instance_shadowfang_keep.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\shadowfang_keep\shadowfang_keep.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stratholme\boss_baroness_anastari.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stratholme\boss_cannon_master_willey.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stratholme\boss_dathrohan_balnazzar.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stratholme\boss_maleki_the_pallid.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stratholme\boss_order_of_silver_hand.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stratholme\instance_stratholme.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\stratholme\stratholme.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunken_temple\instance_sunken_temple.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunken_temple\sunken_temple.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunwell_plateau\boss_brutallus.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunwell_plateau\boss_eredar_twins.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunwell_plateau\boss_felmyst.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunwell_plateau\boss_kalecgos.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunwell_plateau\boss_kiljaeden.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunwell_plateau\boss_muru.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\sunwell_plateau\instance_sunwell_plateau.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\throne_of_the_tides\boss_commander_ulthok.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\throne_of_the_tides\boss_erunak_and_ghursha.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\throne_of_the_tides\boss_lady_nazjar.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\throne_of_the_tides\boss_ozumat.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\throne_of_the_tides\instance_throne_of_the_tides.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\uldaman\boss_archaedas.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\uldaman\uldaman.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\uldaman\instance_uldaman.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\boss_akilzon.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\boss_halazzi.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\boss_janalai.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\boss_malacrass.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\boss_nalorakk.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\boss_zuljin.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\instance_zulaman.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulaman\zulaman.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_arlokk.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_hakkar.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_hazzarah.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_jeklik.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_jindo.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_mandokir.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_marli.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_renataki.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_thekal.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\boss_venoxis.cpp" />
|
||||
<ClCompile Include="..\scripts\eastern_kingdoms\zulgurub\instance_zulgurub.cpp" />
|
||||
<ClCompile Include="..\scripts\examples\example_creature.cpp" />
|
||||
<ClCompile Include="..\scripts\examples\example_escort.cpp" />
|
||||
<ClCompile Include="..\scripts\examples\example_gossip_codebox.cpp" />
|
||||
<ClCompile Include="..\scripts\examples\example_misc.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ashenvale.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\azshara.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\azuremyst_isle.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\bloodmyst_isle.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\boss_azuregos.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\darkshore.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\desolace.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\durotar.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\dustwallow_marsh.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\felwood.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\feralas.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\molten_front.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\moonglade.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\mount_hyjal.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\mulgore.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\orgrimmar.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\silithus.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\stonetalon_mountains.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\tanaris.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\teldrassil.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\the_barrens.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\thousand_needles.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\thunder_bluff.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\uldum.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ungoro_crater.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\winterspring.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\blackfathom_deeps\instance_blackfathom_deeps.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\culling_of_stratholme\culling_of_stratholme.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\culling_of_stratholme\instance_culling_of_stratholme.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dark_portal\boss_aeonus.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dark_portal\boss_chrono_lord_deja.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dark_portal\boss_temporus.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dark_portal\dark_portal.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dark_portal\instance_dark_portal.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\boss_deathwing.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\boss_hagara.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\boss_morchok.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\boss_ultraxion.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\boss_warlord_zonozz.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\boss_warmaster_blackhorn.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\boss_yorsahj.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\dragon_soul.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\instance_dragon_soul.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\end_of_time\end_of_time.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\end_of_time\instance_end_of_time.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hour_of_twilight\boss_archbishop_benedictus.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hour_of_twilight\boss_arcurion.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hour_of_twilight\boss_asira_dawnslayer.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hour_of_twilight\instance_hour_of_twilight.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hyjal_summit\boss_archimonde.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hyjal_summit\hyjal.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hyjal_summit\hyjalAI.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\hyjal_summit\instance_hyjal.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\old_hillsbrad\instance_old_hillsbrad.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\old_hillsbrad\old_hillsbrad.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\well_of_eternity\boss_mannoroth_and_varothen.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\well_of_eternity\boss_perotharn.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\well_of_eternity\boss_queen_azshara.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\caverns_of_time\well_of_eternity\instance_well_of_eternity.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\dire_maul\dire_maul.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\dire_maul\instance_dire_maul.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\boss_alysrazor.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\boss_baleroc.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\boss_bethtilac.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\boss_lord_rhyolith.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\boss_majordomo_staghelm.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\boss_ragnaros_firelands.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\boss_shannox.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\firelands\instance_firelands.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\lost_city_of_tolvir\boss_general_husam.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\lost_city_of_tolvir\boss_lockmaw.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\lost_city_of_tolvir\boss_prophet_barim.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\lost_city_of_tolvir\boss_siamat.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\lost_city_of_tolvir\instance_lost_city_of_tolvir.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\maraudon\boss_noxxion.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\onyxias_lair\boss_onyxia.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\onyxias_lair\instance_onyxias_lair.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\razorfen_downs\razorfen_downs.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\razorfen_kraul\instance_razorfen_kraul.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\razorfen_kraul\razorfen_kraul.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\boss_ayamiss.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\boss_buru.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\boss_kurinnaxx.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\boss_moam.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\boss_ossirian.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\boss_rajaxx.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\instance_ruins_of_ahnqiraj.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\ruins_of_ahnqiraj\ruins_of_ahnqiraj.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_bug_trio.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_cthun.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_fankriss.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_huhuran.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_ouro.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_sartura.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_skeram.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_twinemperors.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\boss_viscidus.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\instance_temple_of_ahnqiraj.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\temple_of_ahnqiraj\mob_anubisath_sentinel.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\throne_of_the_four_winds\boss_alakir.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\throne_of_the_four_winds\conclave_of_the_wind.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\throne_of_the_four_winds\instance_throne_of_the_four_winds.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\vortex_pinnacle\boss_altairus.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\vortex_pinnacle\boss_asaad.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\vortex_pinnacle\boss_grand_vizier_ertan.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\vortex_pinnacle\instance_vortex_pinnacle.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\wailing_caverns\instance_wailing_caverns.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\wailing_caverns\wailing_caverns.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\zulfarrak\boss_zumrah.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\zulfarrak\instance_zulfarrak.cpp" />
|
||||
<ClCompile Include="..\scripts\kalimdor\zulfarrak\zulfarrak.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\deepholm.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\kezan.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\lost_isles.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\stonecore\boss_corborus.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\stonecore\boss_ozruk.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\stonecore\boss_priestess_azil.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\stonecore\boss_slabhide.cpp" />
|
||||
<ClCompile Include="..\scripts\maelstrom\stonecore\instance_stonecore.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\borean_tundra.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\dalaran.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\dragonblight.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\grizzly_hills.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\howling_fjord.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\sholazar_basin.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\storm_peaks.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\zuldrak.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\ahnkahet\boss_amanitar.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\ahnkahet\boss_jedoga.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\ahnkahet\boss_nadox.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\ahnkahet\boss_taldaram.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\ahnkahet\boss_volazj.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\ahnkahet\instance_ahnkahet.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\azjol-nerub\boss_anubarak.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\azjol-nerub\boss_hadronox.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\azjol-nerub\boss_krikthir.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\azjol-nerub\azjol-nerub\instance_azjol-nerub.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_champion\boss_grand_champions.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_champion\instance_trial_of_the_champion.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_champion\trial_of_the_champion.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\boss_anubarak_trial.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\boss_faction_champions.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\boss_jaraxxus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\boss_northrend_beasts.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\boss_twin_valkyr.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\instance_trial_of_the_crusader.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\trial_of_the_crusader.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\draktharon_keep\boss_novos.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\draktharon_keep\boss_tharonja.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\draktharon_keep\boss_trollgore.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\draktharon_keep\instance_draktharon_keep.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\gundrak\boss_colossus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\gundrak\boss_eck.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\gundrak\boss_galdarah.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\gundrak\boss_moorabi.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\gundrak\boss_sladran.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\gundrak\instance_gundrak.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls\boss_bronjahm.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls\boss_devourer_of_souls.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls\instance_forge_of_souls.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection\boss_falric.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection\boss_lich_king.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection\boss_marwyn.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection\halls_of_reflection.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection\instance_halls_of_reflection.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron\boss_forgemaster_garfrost.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron\boss_krick_and_ick.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron\boss_scourgelord_tyrannus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron\instance_pit_of_saron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron\pit_of_saron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\blood_prince_council.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_blood_queen_lanathel.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_deathbringer_saurfang.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_festergut.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_lady_deathwhisper.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_lord_marrowgar.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_professor_putricide.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_rotface.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_sindragosa.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_the_lich_king.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_valithria_dreamwalker.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\gunship_battle.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\instance_icecrown_citadel.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_anubrekhan.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_faerlina.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_four_horsemen.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_gluth.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_gothik.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_grobbulus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_heigan.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_kelthuzad.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_loatheb.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_maexxna.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_noth.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_patchwerk.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_razuvious.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_sapphiron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\boss_thaddius.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\naxxramas\instance_naxxramas.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\eye_of_eternity\boss_malygos.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\eye_of_eternity\instance_eye_of_eternity.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\nexus\boss_anomalus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\nexus\boss_keristrasza.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\nexus\boss_ormorok.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\nexus\boss_telestra.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\nexus\instance_nexus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\oculus\boss_eregos.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\oculus\boss_urom.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\oculus\boss_varos.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\oculus\instance_oculus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\nexus\oculus\oculus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\obsidian_sanctum\boss_sartharion.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\obsidian_sanctum\instance_obsidian_sanctum.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ruby_sanctum\boss_baltharus.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ruby_sanctum\boss_halion.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ruby_sanctum\boss_saviana.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ruby_sanctum\boss_zarithrian.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ruby_sanctum\instance_ruby_sanctum.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_lightning\boss_bjarngrim.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_lightning\boss_ionar.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_lightning\boss_loken.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_lightning\boss_volkhan.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_lightning\instance_halls_of_lightning.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_stone\boss_maiden_of_grief.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_stone\boss_sjonnir.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_stone\halls_of_stone.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\halls_of_stone\instance_halls_of_stone.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\assembly_of_iron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_algalon.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_auriaya.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_flame_leviathan.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_freya.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_general_vezax.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_hodir.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_ignis.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_kologarn.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_mimiron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_razorscale.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_thorim.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_xt_002.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\boss_yogg_saron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\instance_ulduar.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\ulduar\ulduar\ulduar.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_keep\boss_ingvar.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_keep\boss_keleseth.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_keep\boss_skarvald_and_dalronn.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_keep\instance_utgarde_keep.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_keep\utgarde_keep.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_pinnacle\boss_gortok.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_pinnacle\boss_skadi.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_pinnacle\boss_svala.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_pinnacle\boss_ymiron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\utgarde_keep\utgarde_pinnacle\instance_utgarde_pinnacle.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\vault_of_archavon\boss_archavon.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\vault_of_archavon\boss_emalon.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\vault_of_archavon\boss_koralon.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\vault_of_archavon\boss_toravon.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\vault_of_archavon\instance_vault_of_archavon.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\violet_hold\boss_erekem.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\violet_hold\boss_ichoron.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\violet_hold\instance_violet_hold.cpp" />
|
||||
<ClCompile Include="..\scripts\northrend\violet_hold\violet_hold.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\blades_edge_mountains.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\boss_doomlord_kazzak.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\boss_doomwalker.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_peninsula.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\nagrand.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\netherstorm.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\shadowmoon_valley.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\shattrath_city.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\terokkar_forest.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\zangarmarsh.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\auchenai_crypts\boss_exarch_maladaar.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\auchenai_crypts\boss_shirrak.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\mana_tombs\boss_nexusprince_shaffar.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\mana_tombs\boss_pandemonius.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\sethekk_halls\boss_anzu.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\sethekk_halls\boss_darkweaver_syth.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\sethekk_halls\boss_talon_king_ikiss.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\sethekk_halls\instance_sethekk_halls.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\shadow_labyrinth\boss_ambassador_hellmaw.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\shadow_labyrinth\boss_blackheart_the_inciter.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\shadow_labyrinth\boss_grandmaster_vorpil.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\shadow_labyrinth\boss_murmur.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\auchindoun\shadow_labyrinth\instance_shadow_labyrinth.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\black_temple.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_bloodboil.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_illidan.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_mother_shahraz.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_reliquary_of_souls.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_shade_of_akama.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_supremus.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_teron_gorefiend.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\boss_warlord_najentus.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\illidari_council.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\black_temple\instance_black_temple.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\boss_fathomlord_karathress.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\boss_hydross_the_unstable.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\boss_lady_vashj.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\boss_leotheras_the_blind.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\boss_morogrim_tidewalker.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\boss_the_lurker_below.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\instance_serpent_shrine.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\slave_pens\boss_ahune.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\steam_vault\boss_hydromancer_thespia.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\steam_vault\boss_mekgineer_steamrigger.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\steam_vault\boss_warlord_kalithresh.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\steam_vault\instance_steam_vault.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\coilfang_reservoir\underbog\boss_hungarfen.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\gruuls_lair\boss_gruul.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\gruuls_lair\boss_high_king_maulgar.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\gruuls_lair\instance_gruuls_lair.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\blood_furnace\boss_broggok.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\blood_furnace\boss_kelidan_the_breaker.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\blood_furnace\boss_the_maker.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\blood_furnace\instance_blood_furnace.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\hellfire_ramparts\boss_nazan_and_vazruden.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\hellfire_ramparts\boss_omor_the_unscarred.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\hellfire_ramparts\boss_watchkeeper_gargolmar.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\hellfire_ramparts\instance_hellfire_ramparts.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\magtheridons_lair\boss_magtheridon.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\magtheridons_lair\instance_magtheridons_lair.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\shattered_halls\boss_nethekurse.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\shattered_halls\boss_warbringer_omrogg.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\shattered_halls\boss_warchief_kargath_bladefist.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\hellfire_citadel\shattered_halls\instance_shattered_halls.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\arcatraz\arcatraz.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\arcatraz\boss_dalliah.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\arcatraz\boss_harbinger_skyriss.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\arcatraz\boss_soccothrates.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\arcatraz\instance_arcatraz.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\botanica\boss_high_botanist_freywinn.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\botanica\boss_laj.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\botanica\boss_warp_splinter.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_eye\boss_alar.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_eye\boss_astromancer.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_eye\boss_kaelthas.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_eye\boss_void_reaver.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_eye\instance_the_eye.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_mechanar\boss_nethermancer_sepethrea.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_mechanar\boss_pathaleon_the_calculator.cpp" />
|
||||
<ClCompile Include="..\scripts\outland\tempest_keep\the_mechanar\instance_mechanar.cpp" />
|
||||
<ClCompile Include="..\scripts\world\areatrigger_scripts.cpp" />
|
||||
<ClCompile Include="..\scripts\world\bosses_emerald_dragons.cpp" />
|
||||
<ClCompile Include="..\scripts\world\go_scripts.cpp" />
|
||||
<ClCompile Include="..\scripts\world\guards.cpp" />
|
||||
<ClCompile Include="..\scripts\world\item_scripts.cpp" />
|
||||
<ClCompile Include="..\scripts\world\mob_generic_creature.cpp" />
|
||||
<ClCompile Include="..\scripts\world\npc_professions.cpp" />
|
||||
<ClCompile Include="..\scripts\world\npcs_special.cpp" />
|
||||
<ClCompile Include="..\scripts\world\spell_scripts.cpp" />
|
||||
<ClCompile Include="..\scripts\world\world_map_scripts.cpp" />
|
||||
<ClCompile Include="..\include\precompiled.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\include\sc_creature.cpp" />
|
||||
<ClCompile Include="..\include\sc_grid_searchers.cpp" />
|
||||
<ClCompile Include="..\include\sc_instance.cpp" />
|
||||
<ClCompile Include="..\system\MangosdRev.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\system\ScriptLoader.cpp" />
|
||||
<ClCompile Include="..\system\system.cpp" />
|
||||
<ClCompile Include="..\ScriptMgr.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\base\escort_ai.h" />
|
||||
<ClInclude Include="..\base\follower_ai.h" />
|
||||
<ClInclude Include="..\base\guard_ai.h" />
|
||||
<ClInclude Include="..\base\pet_ai.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\bastion_of_twilight\bastion_of_twilight.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_caverns\blackrock_caverns.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_depths\blackrock_depths.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackrock_spire\blackrock_spire.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_descent\blackwing_descent.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\blackrock_mountain\blackwing_lair\blackwing_lair.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\blackrock_mountain\molten_core\molten_core.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\deadmines\deadmines.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\gnomeregan\gnomeregan.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\grim_batol\grim_batol.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\karazhan\karazhan.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\magisters_terrace\magisters_terrace.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\scarlet_enclave\world_map_ebon_hold.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\scarlet_monastery\scarlet_monastery.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\scholomance\scholomance.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\shadowfang_keep\shadowfang_keep.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\stratholme\stratholme.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\sunken_temple\sunken_temple.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\sunwell_plateau\sunwell_plateau.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\throne_of_the_tides\throne_of_the_tides.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\uldaman\uldaman.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\zulaman\zulaman.h" />
|
||||
<ClInclude Include="..\scripts\eastern_kingdoms\zulgurub\zulgurub.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\blackfathom_deeps\blackfathom_deeps.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\culling_of_stratholme\culling_of_stratholme.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\dark_portal\dark_portal.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\dragon_soul\dragon_soul.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\end_of_time\end_of_time.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\hour_of_twilight\hour_of_twilight.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\hyjal_summit\hyjal.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\hyjal_summit\hyjalAI.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\old_hillsbrad\old_hillsbrad.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\caverns_of_time\well_of_eternity\well_of_eternity.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\dire_maul\dire_maul.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\firelands\firelands.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\lost_city_of_tolvir\lost_city_of_tolvir.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\onyxias_lair\onyxias_lair.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\razorfen_kraul\razorfen_kraul.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\ruins_of_ahnqiraj\ruins_of_ahnqiraj.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\temple_of_ahnqiraj\temple_of_ahnqiraj.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\throne_of_the_four_winds\throne_of_the_four_winds.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\vortex_pinnacle\vortex_pinnacle.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\wailing_caverns\wailing_caverns.h" />
|
||||
<ClInclude Include="..\scripts\kalimdor\zulfarrak\zulfarrak.h" />
|
||||
<ClInclude Include="..\scripts\maelstrom\stonecore\stonecore.h" />
|
||||
<ClInclude Include="..\scripts\northrend\azjol-nerub\ahnkahet\ahnkahet.h" />
|
||||
<ClInclude Include="..\scripts\northrend\azjol-nerub\azjol-nerub\azjol-nerub.h" />
|
||||
<ClInclude Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_champion\trial_of_the_champion.h" />
|
||||
<ClInclude Include="..\scripts\northrend\crusaders_coliseum\trial_of_the_crusader\trial_of_the_crusader.h" />
|
||||
<ClInclude Include="..\scripts\northrend\draktharon_keep\draktharon_keep.h" />
|
||||
<ClInclude Include="..\scripts\northrend\gundrak\gundrak.h" />
|
||||
<ClInclude Include="..\scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls\forge_of_souls.h" />
|
||||
<ClInclude Include="..\scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection\halls_of_reflection.h" />
|
||||
<ClInclude Include="..\scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron\pit_of_saron.h" />
|
||||
<ClInclude Include="..\scripts\northrend\icecrown_citadel\icecrown_citadel\icecrown_citadel.h" />
|
||||
<ClInclude Include="..\scripts\northrend\naxxramas\naxxramas.h" />
|
||||
<ClInclude Include="..\scripts\northrend\nexus\eye_of_eternity\eye_of_eternity.h" />
|
||||
<ClInclude Include="..\scripts\northrend\nexus\nexus\nexus.h" />
|
||||
<ClInclude Include="..\scripts\northrend\nexus\oculus\oculus.h" />
|
||||
<ClInclude Include="..\scripts\northrend\obsidian_sanctum\obsidian_sanctum.h" />
|
||||
<ClInclude Include="..\scripts\northrend\ruby_sanctum\ruby_sanctum.h" />
|
||||
<ClInclude Include="..\scripts\northrend\ulduar\halls_of_lightning\halls_of_lightning.h" />
|
||||
<ClInclude Include="..\scripts\northrend\ulduar\halls_of_stone\halls_of_stone.h" />
|
||||
<ClInclude Include="..\scripts\northrend\ulduar\ulduar\ulduar.h" />
|
||||
<ClInclude Include="..\scripts\northrend\utgarde_keep\utgarde_keep\utgarde_keep.h" />
|
||||
<ClInclude Include="..\scripts\northrend\utgarde_keep\utgarde_pinnacle\utgarde_pinnacle.h" />
|
||||
<ClInclude Include="..\scripts\northrend\vault_of_archavon\vault_of_archavon.h" />
|
||||
<ClInclude Include="..\scripts\northrend\violet_hold\violet_hold.h" />
|
||||
<ClInclude Include="..\scripts\outland\auchindoun\sethekk_halls\sethekk_halls.h" />
|
||||
<ClInclude Include="..\scripts\outland\auchindoun\shadow_labyrinth\shadow_labyrinth.h" />
|
||||
<ClInclude Include="..\scripts\outland\black_temple\black_temple.h" />
|
||||
<ClInclude Include="..\scripts\outland\coilfang_reservoir\serpent_shrine\serpent_shrine.h" />
|
||||
<ClInclude Include="..\scripts\outland\coilfang_reservoir\steam_vault\steam_vault.h" />
|
||||
<ClInclude Include="..\scripts\outland\gruuls_lair\gruuls_lair.h" />
|
||||
<ClInclude Include="..\scripts\outland\hellfire_citadel\blood_furnace\blood_furnace.h" />
|
||||
<ClInclude Include="..\scripts\outland\hellfire_citadel\hellfire_ramparts\hellfire_ramparts.h" />
|
||||
<ClInclude Include="..\scripts\outland\hellfire_citadel\magtheridons_lair\magtheridons_lair.h" />
|
||||
<ClInclude Include="..\scripts\outland\hellfire_citadel\shattered_halls\shattered_halls.h" />
|
||||
<ClInclude Include="..\scripts\outland\tempest_keep\arcatraz\arcatraz.h" />
|
||||
<ClInclude Include="..\scripts\outland\tempest_keep\the_eye\the_eye.h" />
|
||||
<ClInclude Include="..\scripts\outland\tempest_keep\the_mechanar\mechanar.h" />
|
||||
<ClInclude Include="..\scripts\world\world_map_scripts.h" />
|
||||
<ClInclude Include="..\include\precompiled.h" />
|
||||
<ClInclude Include="..\include\sc_creature.h" />
|
||||
<ClInclude Include="..\include\sc_gossip.h" />
|
||||
<ClInclude Include="..\include\sc_grid_searchers.h" />
|
||||
<ClInclude Include="..\include\sc_instance.h" />
|
||||
<ClInclude Include="..\system\ScriptLoader.h" />
|
||||
<ClInclude Include="..\system\system.h" />
|
||||
<ClInclude Include="..\config.h" />
|
||||
<CustomBuild Include="..\revision.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Extracting revision</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cd "$(SolutionDir)"
|
||||
"$(SolutionDir)..\..\..\win\VC120\genrevision__Win32_$(Configuration)\genrevision.exe"
|
||||
</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.svn/entries;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">revision.h;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Extracting revision</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cd "$(SolutionDir)"
|
||||
"$(SolutionDir)..\..\..\win\VC120\genrevision__Win32_$(Configuration)\genrevision.exe"
|
||||
</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.svn/entries;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">revision.h;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Extracting revision</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cd "$(SolutionDir)"
|
||||
"$(SolutionDir)..\..\..\win\VC120\genrevision__Win32_$(Configuration)\genrevision.exe"
|
||||
</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.svn/entries;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">revision.h;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Extracting revision</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cd "$(SolutionDir)"
|
||||
"$(SolutionDir)..\..\..\win\VC120\genrevision__Win32_$(Configuration)\genrevision.exe"
|
||||
</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.svn/entries;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">revision.h;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="..\sd2_revision_nr.h" />
|
||||
<ClInclude Include="..\sd2_revision_sql.h" />
|
||||
<ClInclude Include="..\ScriptMgr.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
2249
src/modules/SD2/@@Temp_VC120/ScriptDev2.vcxproj.filters
Normal file
2249
src/modules/SD2/@@Temp_VC120/ScriptDev2.vcxproj.filters
Normal file
File diff suppressed because it is too large
Load diff
516
src/modules/SD2/CMakeLists.txt
Normal file
516
src/modules/SD2/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,516 @@
|
|||
#
|
||||
# Copyright (C) 2005-2015 MaNGOS <http://getmangos.eu/>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
include(MacroMangosSourceGroup)
|
||||
|
||||
set(mangosscript_PCH_H "${CMAKE_CURRENT_SOURCE_DIR}/include/precompiled.h")
|
||||
if(PCH)
|
||||
set(mangosscript_PCH_CPP "${CMAKE_CURRENT_SOURCE_DIR}/include/precompiled.cpp")
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/base"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}/src/shared"
|
||||
"${CMAKE_SOURCE_DIR}/src/framework"
|
||||
"${CMAKE_SOURCE_DIR}/src/game/Server"
|
||||
"${CMAKE_SOURCE_DIR}/src/game/BattleGround"
|
||||
"${CMAKE_SOURCE_DIR}/src/game/WorldHandlers"
|
||||
"${CMAKE_SOURCE_DIR}/src/game/Object"
|
||||
"${CMAKE_SOURCE_DIR}/src/game/References"
|
||||
"${CMAKE_SOURCE_DIR}/src/game/MotionGenerators"
|
||||
"${CMAKE_SOURCE_DIR}/src/game/vmap"
|
||||
"${CMAKE_SOURCE_DIR}/dep/include"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
"${CMAKE_BINARY_DIR}/src/shared"
|
||||
"${ACE_INCLUDE_DIR}"
|
||||
"${MYSQL_INCLUDE_DIR}"
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the scriptdev2 library
|
||||
set(sources
|
||||
sd2_revision_nr.h
|
||||
sd2_revision_sql.h
|
||||
ScriptDevMgr.cpp
|
||||
ScriptDevMgr.h
|
||||
base/escort_ai.cpp
|
||||
base/escort_ai.h
|
||||
base/follower_ai.cpp
|
||||
base/follower_ai.h
|
||||
base/guard_ai.cpp
|
||||
base/guard_ai.h
|
||||
base/pet_ai.cpp
|
||||
base/pet_ai.h
|
||||
|
||||
${mangosscript_PCH_H}
|
||||
${mangosscript_PCH_CPP}
|
||||
include/sc_creature.cpp
|
||||
include/sc_creature.h
|
||||
include/sc_grid_searchers.cpp
|
||||
include/sc_grid_searchers.h
|
||||
include/sc_instance.cpp
|
||||
include/sc_instance.h
|
||||
include/sc_gossip.h
|
||||
|
||||
system/ScriptLoader.cpp
|
||||
system/ScriptLoader.h
|
||||
system/system.cpp
|
||||
system/system.h
|
||||
)
|
||||
|
||||
set(mangosscript_LIB_SRCS ${sources})
|
||||
|
||||
#Battleground Scripts
|
||||
file(GLOB sources_battlegrounds scripts/battlegrounds/*.cpp scripts/battlegrounds/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_battlegrounds})
|
||||
source_group("Battleground Scripts" FILES ${sources_battlegrounds})
|
||||
|
||||
#World Scripts
|
||||
file(GLOB sources_world scripts/world/*.cpp scripts/world/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_world})
|
||||
source_group("World Scripts" FILES ${sources_world})
|
||||
|
||||
#Eastern Kingdom Scripts
|
||||
file(GLOB sources_eastern_kingdoms scripts/eastern_kingdoms/*.cpp scripts/eastern_kingdoms/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_eastern_kingdoms})
|
||||
source_group("Eastern Kingdoms Scripts" FILES ${sources_eastern_kingdoms})
|
||||
|
||||
#Kalimdor Scripts
|
||||
file(GLOB sources_kalimdor scripts/kalimdor/*.cpp scripts/kalimdor/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_kalimdor})
|
||||
source_group("Kalimdor Scripts" FILES ${sources_kalimdor})
|
||||
|
||||
#Outlands Scripts
|
||||
file(GLOB sources_outlands scripts/outland/*.cpp scripts/outland/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_outlands})
|
||||
source_group("Outlands Scripts" FILES ${sources_outlands})
|
||||
|
||||
#Northrend Scripts
|
||||
file(GLOB sources_northrend scripts/northrend/*.cpp scripts/northrend/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_northrend})
|
||||
source_group("Northrend Scripts" FILES ${sources_northrend})
|
||||
|
||||
#Instance: Blackrock Depths Scripts
|
||||
file(GLOB sources_instance_ek_brd scripts/eastern_kingdoms/blackrock_mountain/blackrock_depths/*.cpp scripts/eastern_kingdoms/blackrock_mountain/blackrock_depths/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_brd})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Blackrock Depths" FILES ${sources_instance_ek_brd})
|
||||
|
||||
#Instance: Blackrock Spire Scripts
|
||||
file(GLOB sources_instance_ek_brs scripts/eastern_kingdoms/blackrock_mountain/blackrock_spire/*.cpp scripts/eastern_kingdoms/blackrock_mountain/blackrock_spire/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_brs})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Blackrock Spire" FILES ${sources_instance_ek_brs})
|
||||
|
||||
#Instance: Deadmines Scripts
|
||||
file(GLOB sources_instance_ek_tdm scripts/eastern_kingdoms/deadmines/*.cpp scripts/eastern_kingdoms/deadmines/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_tdm})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Deadmines" FILES ${sources_instance_ek_tdm})
|
||||
|
||||
#Instance: Gnomeregan Scripts
|
||||
file(GLOB sources_instance_ek_gno scripts/eastern_kingdoms/gnomeregan/*.cpp scripts/eastern_kingdoms/gnomeregan/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_gno})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Gnomeregan" FILES ${sources_instance_ek_gno})
|
||||
|
||||
#Instance: Scarlet Monastery Scripts
|
||||
file(GLOB sources_instance_ek_sm scripts/eastern_kingdoms/scarlet_monastery/*.cpp scripts/eastern_kingdoms/scarlet_monastery/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_sm})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Scarlet Monastery" FILES ${sources_instance_ek_sm})
|
||||
|
||||
#Instance: Scholomance Scripts
|
||||
file(GLOB sources_instance_ek_scholo scripts/eastern_kingdoms/scholomance/*.cpp scripts/eastern_kingdoms/scholomance/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_scholo})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Scholomance" FILES ${sources_instance_ek_scholo})
|
||||
|
||||
#Instance: Uldaman Scripts
|
||||
file(GLOB sources_instance_ek_uld scripts/eastern_kingdoms/uldaman/*.cpp scripts/eastern_kingdoms/uldaman/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_uld})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Uldaman" FILES ${sources_instance_ek_uld})
|
||||
|
||||
#Instance: Shadowfang Keep Scripts
|
||||
file(GLOB sources_instance_ek_sfk scripts/eastern_kingdoms/shadowfang_keep/*.cpp scripts/eastern_kingdoms/shadowfang_keep/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_sfk})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Shadowfang Keep" FILES ${sources_instance_ek_sfk})
|
||||
|
||||
#Instance: Sunken Temple Scripts
|
||||
file(GLOB sources_instance_ek_st scripts/eastern_kingdoms/sunken_temple/*.cpp scripts/eastern_kingdoms/sunken_temple/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_st})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Sunken Temple" FILES ${sources_instance_ek_st})
|
||||
|
||||
#Instance: Stratholme Scripts
|
||||
file(GLOB sources_instance_ek_strat scripts/eastern_kingdoms/stratholme/*.cpp scripts/eastern_kingdoms/stratholme/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_strat})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Stratholme" FILES ${sources_instance_ek_strat})
|
||||
|
||||
#Instance: Magisters Terrace Scripts
|
||||
file(GLOB sources_instance_ek_mt scripts/eastern_kingdoms/magisters_terrace/*.cpp scripts/eastern_kingdoms/magisters_terrace/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ek_mt})
|
||||
source_group("Eastern Kingdoms Scripts\\Instances\\Magisters Terrace" FILES ${sources_instance_ek_mt})
|
||||
|
||||
#Raid: Karazhan Scripts
|
||||
file(GLOB sources_raid_ek_kara scripts/eastern_kingdoms/karazhan/*.cpp scripts/eastern_kingdoms/karazhan/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ek_kara})
|
||||
source_group("Eastern Kingdoms Scripts\\Raids\\Karazhan" FILES ${sources_raid_ek_kara})
|
||||
|
||||
#Raid: Sunwell Plateau Scripts
|
||||
file(GLOB sources_raid_ek_sp scripts/eastern_kingdoms/sunwell_plateau/*.cpp scripts/eastern_kingdoms/sunwell_plateau/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ek_sp})
|
||||
source_group("Eastern Kingdoms Scripts\\Raids\\Sunwell Plateau" FILES ${sources_raid_ek_sp})
|
||||
|
||||
#Raid: Zul'Aman Scripts
|
||||
file(GLOB sources_raid_ek_za scripts/eastern_kingdoms/zulaman/*.cpp scripts/eastern_kingdoms/zulaman/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ek_za})
|
||||
source_group("Eastern Kingdoms Scripts\\Raids\\Zul'Aman" FILES ${sources_raid_ek_za})
|
||||
|
||||
#Raid: Molten Core Scripts
|
||||
file(GLOB sources_raid_ek_mc scripts/eastern_kingdoms/blackrock_mountain/molten_core/*.cpp scripts/eastern_kingdoms/blackrock_mountain/molten_core/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ek_mc})
|
||||
source_group("Eastern Kingdoms Scripts\\Raids\\Molten Core" FILES ${sources_raid_ek_mc})
|
||||
|
||||
#Raid: Blackwing Lair Scripts
|
||||
file(GLOB sources_raid_ek_bwl scripts/eastern_kingdoms/blackrock_mountain/blackwing_lair/*.cpp scripts/eastern_kingdoms/blackrock_mountain/blackwing_lair/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ek_bwl})
|
||||
source_group("Eastern Kingdoms Scripts\\Raids\\Blackwing Lair" FILES ${sources_raid_ek_bwl})
|
||||
|
||||
#Raid: Zul Gurub Scripts
|
||||
file(GLOB sources_raid_ek_zg scripts/eastern_kingdoms/zulgurub/*.cpp scripts/eastern_kingdoms/zulgurub/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ek_zg})
|
||||
source_group("Eastern Kingdoms Scripts\\Raids\\Zul Gurub" FILES ${sources_raid_ek_zg})
|
||||
|
||||
#Instance: Blackfathom Deeps Scripts
|
||||
file(GLOB sources_instance_k_bdf scripts/kalimdor/blackfathom_deeps/*.cpp scripts/kalimdor/blackfathom_deeps/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_bdf})
|
||||
source_group("Kalimdor Scripts\\Instances\\Blackfathom Deeps" FILES ${sources_instance_k_bdf})
|
||||
|
||||
#Instance: Dire Maul Scripts
|
||||
file(GLOB sources_instance_k_dm scripts/kalimdor/dire_maul/*.cpp scripts/kalimdor/dire_maul/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_dm})
|
||||
source_group("Kalimdor Scripts\\Instances\\Dire Maul" FILES ${sources_instance_k_dm})
|
||||
|
||||
#Instance: Maraudon Scripts
|
||||
file(GLOB sources_instance_k_mara scripts/kalimdor/maraudon/*.cpp scripts/kalimdor/maraudon/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_mara})
|
||||
source_group("Kalimdor Scripts\\Instances\\Maraudon Scripts" FILES ${sources_instance_k_mara})
|
||||
|
||||
#Instance: Razorfen Downs Scripts
|
||||
file(GLOB sources_instance_k_rfd scripts/kalimdor/razorfen_downs/*.cpp scripts/kalimdor/razorfen_downs/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_rfd})
|
||||
source_group("Kalimdor Scripts\\Instances\\Razorfen Downs" FILES ${sources_instance_k_rfd})
|
||||
|
||||
#Instance: Razorfen Kraul Scripts
|
||||
file(GLOB sources_instance_k_rfk scripts/kalimdor/razorfen_kraul/*.cpp scripts/kalimdor/razorfen_kraul/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_rfk})
|
||||
source_group("Kalimdor Scripts\\Instances\\Razorfen Kraul" FILES ${sources_instance_k_rfk})
|
||||
|
||||
#Instance: Wailing Caverns Scripts
|
||||
file(GLOB sources_instance_k_wc scripts/kalimdor/wailing_caverns/*.cpp scripts/kalimdor/wailing_caverns/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_wc})
|
||||
source_group("Kalimdor Scripts\\Instances\\Wailing Caverns" FILES ${sources_instance_k_wc})
|
||||
|
||||
#Instance: Caverns of Time - Black Morass
|
||||
file(GLOB sources_instance_k_cot_bm scripts/kalimdor/caverns_of_time/dark_portal/*.cpp scripts/kalimdor/caverns_of_time/dark_portal/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_cot_bm})
|
||||
source_group("Kalimdor Scripts\\Instances\\Caverns of Time\\Black Morass" FILES ${sources_instance_k_cot_bm})
|
||||
|
||||
#Instance: Caverns of Time - Old Hillsbrad
|
||||
file(GLOB sources_instance_k_cot_oh scripts/kalimdor/caverns_of_time/old_hillsbrad/*.cpp scripts/kalimdor/caverns_of_time/old_hillsbrad/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_cot_oh})
|
||||
source_group("Kalimdor Scripts\\Instances\\Caverns of Time\\Old Hillsbrad" FILES ${sources_instance_k_cot_oh})
|
||||
|
||||
#Instance: Caverns of Time - Culling of Stratholme
|
||||
file(GLOB sources_instance_k_cot_cos scripts/kalimdor/caverns_of_time/culling_of_stratholme/*.cpp scripts/kalimdor/caverns_of_time/culling_of_stratholme/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_cot_cos})
|
||||
source_group("Kalimdor Scripts\\Instances\\Caverns of Time\\Culling of Stratholme" FILES ${sources_instance_k_cot_cos})
|
||||
|
||||
#Instance: Zul Farrak Scripts
|
||||
file(GLOB sources_instance_k_zf scripts/kalimdor/zulfarrak/*.cpp scripts/kalimdor/zulfarrak/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_zf})
|
||||
source_group("Kalimdor Scripts\\Instances\\Zul Farrak" FILES ${sources_instance_k_zf})
|
||||
|
||||
#Raid: Caverns of Time - Mount Hyjal
|
||||
file(GLOB sources_instance_k_cot_mh scripts/kalimdor/caverns_of_time/hyjal/*.cpp scripts/kalimdor/caverns_of_time/hyjal/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_k_cot_mh})
|
||||
source_group("Kalimdor Scripts\\Raids\\Caverns of Time\\Mount Hyjal" FILES ${sources_instance_k_cot_mh})
|
||||
|
||||
#Raid: Onyxias Lair Scripts
|
||||
file(GLOB sources_raid_k_ony scripts/kalimdor/onyxias_lair/*.cpp scripts/kalimdor/onyxias_lair/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_k_ony})
|
||||
source_group("Kalimdor Scripts\\Raids\\Onyxias Lair" FILES ${sources_raid_k_ony})
|
||||
|
||||
#Raid: Ruins of AQ Scripts
|
||||
file(GLOB sources_raid_k_raq scripts/kalimdor/ruins_of_ahnqiraj/*.cpp scripts/kalimdor/ruins_of_ahnqiraj/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_k_raq})
|
||||
source_group("Kalimdor Scripts\\Raids\\Ruins of AQ" FILES ${sources_raid_k_raq})
|
||||
|
||||
#Raid: Temple of AQ Scripts
|
||||
file(GLOB sources_raid_k_taq scripts/kalimdor/temple_of_ahnqiraj/*.cpp scripts/kalimdor/temple_of_ahnqiraj/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_k_taq})
|
||||
source_group("Kalimdor Scripts\\Raids\\Temple of AQ" FILES ${sources_raid_k_taq})
|
||||
|
||||
#Instance: Auchindoun - Auchenai Crypts
|
||||
file(GLOB sources_instance_ol_aac scripts/outland/auchindoun/auchenai_crypts/*.cpp scripts/outland/auchindoun/auchenai_crypts/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ol_aac})
|
||||
source_group("Outlands Scripts\\Instances\\Auchindoun\\Auchenai Crypts" FILES ${sources_instance_ol_aac})
|
||||
|
||||
#Instance: Auchindoun - Mana Tombs
|
||||
file(GLOB sources_instance_ol_amt scripts/outland/auchindoun/mana_tombs/*.cpp scripts/outland/auchindoun/mana_tombs/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ol_amt})
|
||||
source_group("Outlands Scripts\\Instances\\Auchindoun\\Mana Tombs" FILES ${sources_instance_ol_amt})
|
||||
|
||||
#Instance: Auchindoun - Sethekk Halls
|
||||
file(GLOB sources_instance_ol_ash scripts/outland/auchindoun/sethekk_halls/*.cpp scripts/outland/auchindoun/sethekk_halls/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ol_ash})
|
||||
source_group("Outlands Scripts\\Instances\\Auchindoun\\Sethekk Halls" FILES ${sources_instance_ol_ash})
|
||||
|
||||
#Instance: Auchindoun - Shadow Labyrinth
|
||||
file(GLOB sources_instance_ol_asl scripts/outland/auchindoun/shadow_labyrinth/*.cpp scripts/outland/auchindoun/shadow_labyrinth/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ol_asl})
|
||||
source_group("Outlands Scripts\\Instances\\Auchindoun\\Shadow Labyrinth" FILES ${sources_instance_ol_asl})
|
||||
|
||||
#Instance: Coilfang Reservoir - Slave Pens
|
||||
file(GLOB sources_instance_ol_csp scripts/outland/coilfang_reservoir/slave_pens/*.cpp scripts/outland/coilfang_reservoir/slave_pens/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ol_csp})
|
||||
source_group("Outlands Scripts\\Instances\\Coilfang Reservoir\\Slave Pens" FILES ${sources_instance_ol_csp})
|
||||
|
||||
#Instance: Coilfang Reservoir - Steam Vaults
|
||||
file(GLOB sources_instance_ol_cst scripts/outland/coilfang_reservoir/steam_vault/*.cpp scripts/outland/coilfang_reservoir/steam_vault/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ol_cst})
|
||||
source_group("Outlands Scripts\\Instances\\Coilfang Reservoir\\Steam Vaults" FILES ${sources_instance_ol_cst})
|
||||
|
||||
#Instance: Coilfang Reservoir - Underbog
|
||||
file(GLOB sources_instance_ol_cu scripts/outland/coilfang_reservoir/underbog/*.cpp scripts/outland/coilfang_reservoir/underbog/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_ol_cu})
|
||||
source_group("Outlands Scripts\\Instances\\Coilfang Reservoir\\Underbog" FILES ${sources_instance_ol_cu})
|
||||
|
||||
#Instance: Hellfire Citadel - Blood Furnace
|
||||
file(GLOB sources_raid_ol_hbf scripts/outland/hellfire_citadel/blood_furnace/*.cpp scripts/outland/hellfire_citadel/blood_furnace/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_hbf})
|
||||
source_group("Outlands Scripts\\Instances\\Hellfire Citadel\\Blood Furnace" FILES ${sources_raid_ol_hbf})
|
||||
|
||||
#Instance: Hellfire Citadel - Hellfire Ramparts
|
||||
file(GLOB sources_raid_ol_hhr scripts/outland/hellfire_citadel/hellfire_ramparts/*.cpp scripts/outland/hellfire_citadel/hellfire_ramparts/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_hhr})
|
||||
source_group("Outlands Scripts\\Instances\\Hellfire Citadel\\Hellfire Ramparts" FILES ${sources_raid_ol_hhr})
|
||||
|
||||
#Instance: Hellfire Citadel - Shattered Halls
|
||||
file(GLOB sources_raid_ol_hsh scripts/outland/hellfire_citadel/shattered_halls/*.cpp scripts/outland/hellfire_citadel/shattered_halls/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_hsh})
|
||||
source_group("Outlands Scripts\\Instances\\Hellfire Citadel\\Shattered Halls" FILES ${sources_raid_ol_hsh})
|
||||
|
||||
#Instance: Tempest Keep - Arcatraz
|
||||
file(GLOB sources_raid_ol_ta scripts/outland/tempest_keep/arcatraz/*.cpp scripts/outland/tempest_keep/arcatraz/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_ta})
|
||||
source_group("Outlands Scripts\\Instances\\Tempest Keep\\Arcatraz" FILES ${sources_raid_ol_ta})
|
||||
|
||||
#Instance: Tempest Keep - Botanica
|
||||
file(GLOB sources_raid_ol_tb scripts/outland/tempest_keep/botanica/*.cpp scripts/outland/tempest_keep/botanica/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_tb})
|
||||
source_group("Outlands Scripts\\Instances\\Tempest Keep\\Botanica" FILES ${sources_raid_ol_tb})
|
||||
|
||||
#Instance: Tempest Keep - The Mechanar
|
||||
file(GLOB sources_raid_ol_ttm scripts/outland/tempest_keep/the_mechanar/*.cpp scripts/outland/tempest_keep/the_mechanar/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_ttm})
|
||||
source_group("Outlands Scripts\\Instances\\Tempest Keep\\The Mechanar" FILES ${sources_raid_ol_ttm})
|
||||
|
||||
#Raid: Hellfire Citadel - Magtheridons Lair
|
||||
file(GLOB sources_raid_ol_hml scripts/outland/hellfire_citadel/magtheridons_lair/*.cpp scripts/outland/hellfire_citadel/magtheridons_lair/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_hml})
|
||||
source_group("Outlands Scripts\\Raids\\Hellfire Citadel\\Magtheridons Lair" FILES ${sources_raid_ol_hml})
|
||||
|
||||
#Raid: Tempest Keep - The Eye
|
||||
file(GLOB sources_raid_ol_tte scripts/outland/tempest_keep/the_eye/*.cpp scripts/outland/tempest_keep/the_eye/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_tte})
|
||||
source_group("Outlands Scripts\\Raids\\Tempest Keep\\The Eye" FILES ${sources_raid_ol_tte})
|
||||
|
||||
#Raid: Coilfang Reservoir - Serpentshrine Cavern
|
||||
file(GLOB sources_raid_ol_csc scripts/outland/coilfang_reservoir/serpent_shrine/*.cpp scripts/outland/coilfang_reservoir/serpent_shrine/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_csc})
|
||||
source_group("Outlands Scripts\\Raids\\Coilfang Reservoir\\Serpentshrine Cavern" FILES ${sources_raid_ol_csc})
|
||||
|
||||
#Raid: Black Temple
|
||||
file(GLOB sources_raid_ol_bt scripts/outland/black_temple/*.cpp scripts/outland/black_temple/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_bt})
|
||||
source_group("Outlands Scripts\\Raids\\Black Temple" FILES ${sources_raid_ol_bt})
|
||||
|
||||
#Raid: Gruul's Lair
|
||||
file(GLOB sources_raid_ol_gl scripts/outland/gruuls_lair/*.cpp scripts/outland/gruuls_lair/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_ol_gl})
|
||||
source_group("Outlands Scripts\\Raids\\Gruul's Lair" FILES ${sources_raid_ol_gl})
|
||||
|
||||
#Instance: Azjol Nerub
|
||||
file(GLOB sources_instance_nr_aznj scripts/northrend/azjol-nerub/azjol-nerub/*.cpp scripts/northrend/azjol-nerub/azjol-nerub/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_aznj})
|
||||
source_group("Northrend Scripts\\Instances\\Azjol Nerub" FILES ${sources_instance_nr_aznj})
|
||||
|
||||
#Instance: Ahn'Kahet
|
||||
file(GLOB sources_instance_nr_ahnk scripts/northrend/azjol-nerub/ahnkahet/*.cpp scripts/northrend/azjol-nerub/ahnkahet/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_ahnk})
|
||||
source_group("Northrend Scripts\\Instances\\Ahn'Kahet" FILES ${sources_instance_nr_ahnk})
|
||||
|
||||
#Instance: Trial of the Champion
|
||||
file(GLOB sources_instance_nr_totch scripts/northrend/crusaders_coliseum/trial_of_the_champion/*.cpp scripts/northrend/crusaders_coliseum/trial_of_the_champion/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_totch})
|
||||
source_group("Northrend Scripts\\Instances\\Trial of the Champion" FILES ${sources_instance_nr_totch})
|
||||
|
||||
#Instance: Drak'Tharon Keep
|
||||
file(GLOB sources_instance_nr_dtk scripts/northrend/draktharon_keep/*.cpp scripts/northrend/draktharon_keep/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_dtk})
|
||||
source_group("Northrend Scripts\\Instances\\Drak'Tharon Keep" FILES ${sources_instance_nr_dtk})
|
||||
|
||||
#Instance: Gundrak
|
||||
file(GLOB sources_instance_nr_gdk scripts/northrend/gundrak/*.cpp scripts/northrend/gundrak/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_gdk})
|
||||
source_group("Northrend Scripts\\Instances\\Gundrak" FILES ${sources_instance_nr_gdk})
|
||||
|
||||
#Instance: Frozen Halls: Forge of Souls
|
||||
file(GLOB sources_instance_nr_fh_fos scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/*.cpp scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_fh_fos})
|
||||
source_group("Northrend Scripts\\Instances\\Forge of Souls" FILES ${sources_instance_nr_fh_fos})
|
||||
|
||||
#Instance: Frozen Halls: Halls of Reflection
|
||||
file(GLOB sources_instance_nr_fh_hor scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/*.cpp scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_fh_hor})
|
||||
source_group("Northrend Scripts\\Instances\\Halls of Reflection" FILES ${sources_instance_nr_fh_hor})
|
||||
|
||||
#Instance: Frozen Halls: Pit of Saron
|
||||
file(GLOB sources_instance_nr_fh_pos scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/*.cpp scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_fh_pos})
|
||||
source_group("Northrend Scripts\\Instances\\Pit of Saron" FILES ${sources_instance_nr_fh_pos})
|
||||
|
||||
#Instance: The Nexus
|
||||
file(GLOB sources_instance_nr_nex scripts/northrend/nexus/nexus/*.cpp scripts/northrend/nexus/nexus/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_nex})
|
||||
source_group("Northrend Scripts\\Instances\\The Nexus" FILES ${sources_instance_nr_nex})
|
||||
|
||||
#Instance: The Oculus
|
||||
file(GLOB sources_instance_nr_oculus scripts/northrend/nexus/oculus/*.cpp scripts/northrend/nexus/oculus/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_oculus})
|
||||
source_group("Northrend Scripts\\Instances\\The Oculus" FILES ${sources_instance_nr_oculus})
|
||||
|
||||
#Instance: Halls of Lightning
|
||||
file(GLOB sources_instance_nr_uld_hol scripts/northrend/ulduar/halls_of_lightning/*.cpp scripts/northrend/ulduar/halls_of_lightning/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_uld_hol})
|
||||
source_group("Northrend Scripts\\Instances\\Halls of Lightning" FILES ${sources_instance_nr_uld_hol})
|
||||
|
||||
#Instance: Halls of Stone
|
||||
file(GLOB sources_instance_nr_uld_hos scripts/northrend/ulduar/halls_of_stone/*.cpp scripts/northrend/ulduar/halls_of_stone/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_uld_hos})
|
||||
source_group("Northrend Scripts\\Instances\\Halls of Stone" FILES ${sources_instance_nr_uld_hos})
|
||||
|
||||
#Instance: Utgarde Keep
|
||||
file(GLOB sources_instance_nr_uk scripts/northrend/utgarde_keep/utgarde_keep/*.cpp scripts/northrend/utgarde_keep/utgarde_keep/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_uk})
|
||||
source_group("Northrend Scripts\\Instances\\Utgarde Keep" FILES ${sources_instance_nr_uk})
|
||||
|
||||
#Instance: Utgarde Pinnacle
|
||||
file(GLOB sources_instance_nr_up scripts/northrend/utgarde_keep/utgarde_pinnacle/*.cpp scripts/northrend/utgarde_keep/utgarde_pinnacle/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_up})
|
||||
source_group("Northrend Scripts\\Instances\\Utgarde Pinnacle" FILES ${sources_instance_nr_up})
|
||||
|
||||
#Instance: Violet Hold
|
||||
file(GLOB sources_instance_nr_vh scripts/northrend/violet_hold/*.cpp scripts/northrend/violet_hold/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_instance_nr_vh})
|
||||
source_group("Northrend Scripts\\Instances\\Violet Hold" FILES ${sources_instance_nr_vh})
|
||||
|
||||
#Raid: Naxxramas
|
||||
file(GLOB sources_raid_nr_naxx scripts/northrend/naxxramas/*.cpp scripts/northrend/naxxramas/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_naxx})
|
||||
source_group("Northrend Scripts\\Raids\\Naxxramas" FILES ${sources_raid_nr_naxx})
|
||||
|
||||
#Raid: Vault of Archavon
|
||||
file(GLOB sources_raid_nr_voa scripts/northrend/vault_of_archavon/*.cpp scripts/northrend/vault_of_archavon/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_voa})
|
||||
source_group("Northrend Scripts\\Raids\\Vault of Archavon" FILES ${sources_raid_nr_voa})
|
||||
|
||||
#Raid: Obsidian Sanctum
|
||||
file(GLOB sources_raid_nr_os scripts/northrend/obsidian_sanctum/*.cpp scripts/northrend/obsidian_sanctum/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_os})
|
||||
source_group("Northrend Scripts\\Raids\\Obsidian Sanctum" FILES ${sources_raid_nr_os})
|
||||
|
||||
#Raid: Ruby Sanctum
|
||||
file(GLOB sources_raid_nr_rs scripts/northrend/ruby_sanctum/*.cpp scripts/northrend/ruby_sanctum/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_rs})
|
||||
source_group("Northrend Scripts\\Raids\\Ruby Sanctum" FILES ${sources_raid_nr_rs})
|
||||
|
||||
#Raid: Icecrown Citadel
|
||||
file(GLOB sources_raid_nr_icc scripts/northrend/icecrown_citadel/icecrown_citadel/*.cpp scripts/northrend/icecrown_citadel/icecrown_citadel/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_icc})
|
||||
source_group("Northrend Scripts\\Raids\\Icecrown Citadel" FILES ${sources_raid_nr_icc})
|
||||
|
||||
#Raid: Trial of the Crusader
|
||||
file(GLOB sources_raid_nr_totc scripts/northrend/crusaders_coliseum/trial_of_the_crusader/*.cpp scripts/northrend/crusaders_coliseum/trial_of_the_crusader/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_totc})
|
||||
source_group("Northrend Scripts\\Raids\\Trial of the Crusader" FILES ${sources_raid_nr_totc})
|
||||
|
||||
#Raid: Eye of Eternity
|
||||
file(GLOB sources_raid_nr_eoe scripts/northrend/nexus/eye_of_eternity/*.cpp scripts/northrend/nexus/eye_of_eternity/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_eoe})
|
||||
source_group("Northrend Scripts\\Raids\\Eye of Eternity" FILES ${sources_raid_nr_eoe})
|
||||
|
||||
#Raid: Ulduar
|
||||
file(GLOB sources_raid_nr_uld scripts/northrend/ulduar/ulduar/*.cpp scripts/northrend/ulduar/ulduar/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_raid_nr_uld})
|
||||
source_group("Northrend Scripts\\Raids\\Ulduar" FILES ${sources_raid_nr_uld})
|
||||
|
||||
#WorldScript: Scarlet Enclave
|
||||
file(GLOB sources_world_scarlet_enclave scripts/eastern_kingdoms/scarlet_enclave/*.cpp scripts/eastern_kingdoms/scarlet_enclave/*.h)
|
||||
LIST(APPEND mangosscript_LIB_SRCS ${sources_world_scarlet_enclave})
|
||||
source_group("Eastern Kingdoms Scripts\\World\\Scarlet Enclave" FILES ${sources_world_scarlet_enclave})
|
||||
|
||||
add_library(mangosscript STATIC
|
||||
${mangosscript_PCH_CPP}
|
||||
${mangosscript_LIB_SRCS}
|
||||
)
|
||||
|
||||
# Generate precompiled header
|
||||
if(PCH)
|
||||
ADD_CXX_PCH(mangosscript ${mangosscript_PCH_H} ${mangosscript_PCH_CPP})
|
||||
endif()
|
||||
|
||||
if(NOT ACE_USE_EXTERNAL)
|
||||
add_dependencies(mangosscript ace)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
set(mangosscript_LINK_FLAGS "-pthread")
|
||||
if(APPLE)
|
||||
set(mangosscript_LINK_FLAGS "-framework Carbon ${mangosscript_LINK_FLAGS}")
|
||||
# Needed for the linking because of the missing symbols
|
||||
set(mangosscript_LINK_FLAGS "-Wl,-undefined -Wl,dynamic_lookup ${mangosscript_LINK_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(mangosscript_PROPERTIES INSTALL_NAME_DIR "${LIBS_DIR}")
|
||||
else()
|
||||
set(mangosscript_PROPERTIES INSTALL_RPATH ${LIBS_DIR})
|
||||
endif()
|
||||
|
||||
# Run out of build tree
|
||||
set(mangosscript_PROPERTIES
|
||||
${mangosscript_PROPERTIES}
|
||||
BUILD_WITH_INSTALL_RPATH OFF
|
||||
)
|
||||
|
||||
set_target_properties(mangosscript PROPERTIES
|
||||
LINK_FLAGS ${mangosscript_LINK_FLAGS}
|
||||
${mangosscript_PROPERTIES}
|
||||
)
|
||||
endif()
|
||||
40
src/modules/SD2/README
Normal file
40
src/modules/SD2/README
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
== ScriptDev2 README ==
|
||||
|
||||
Copyright (C) 2006 - 2013 ScriptDev2 <https://github.com/scriptdev2>
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
== Welcome to ScriptDev2 ==
|
||||
|
||||
ScriptDev2 is a script library, an extention of the scripting capabilities
|
||||
that comes with MaNGOS (https://getmangos.eu/), written in C++ and is
|
||||
compatible with Windows and Linux. SQL needed for database support both
|
||||
MySQL and PostgreSQL.
|
||||
|
||||
This script library provides unique scripts for NPCs, gameobjects, events
|
||||
and other that need unique implementation.
|
||||
|
||||
Once ScriptDev2 is compiled it is automatically run by MaNGOS on server
|
||||
startup.
|
||||
|
||||
For further information on ScriptDev2, please visit our project web site
|
||||
at http://www.scriptdev2.com/
|
||||
|
||||
Documentation on various development related topics can be found in the
|
||||
../doc/ sub directory as well as on the web site.
|
||||
|
||||
The required SQL files for creating the database backend are included in
|
||||
the ../sql/ sub directory. If you are updating from an older ScriptDev2
|
||||
version, make sure to take a look at the SQL files provided in the
|
||||
../sql/updates/ sub directory.
|
||||
643
src/modules/SD2/ScriptDevMgr.cpp
Normal file
643
src/modules/SD2/ScriptDevMgr.cpp
Normal file
|
|
@ -0,0 +1,643 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "Config/Config.h"
|
||||
#include "config-sd2.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "DBCStores.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "system/ScriptLoader.h"
|
||||
#include "system/system.h"
|
||||
#include "ScriptDevMgr.h"
|
||||
#include "Spell.h"
|
||||
|
||||
typedef std::vector<Script*> SDScriptVec;
|
||||
int num_sc_scripts;
|
||||
SDScriptVec m_scripts;
|
||||
|
||||
Config SD2Config;
|
||||
|
||||
void FillSpellSummary();
|
||||
|
||||
void LoadDatabase()
|
||||
{
|
||||
std::string strSD2DBinfo = SD2Config.GetStringDefault("ScriptDev2DatabaseInfo", "");
|
||||
|
||||
if (strSD2DBinfo.empty())
|
||||
{
|
||||
script_error_log("Missing Scriptdev2 database info from configuration file. Load database aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize connection to DB
|
||||
if (SD2Database.Initialize(strSD2DBinfo.c_str()))
|
||||
{
|
||||
outstring_log("SD2: ScriptDev2 database initialized.");
|
||||
outstring_log("\n");
|
||||
|
||||
pSystemMgr.LoadVersion();
|
||||
pSystemMgr.LoadScriptTexts();
|
||||
pSystemMgr.LoadScriptTextsCustom();
|
||||
pSystemMgr.LoadScriptGossipTexts();
|
||||
pSystemMgr.LoadScriptWaypoints();
|
||||
}
|
||||
else
|
||||
{
|
||||
script_error_log("Unable to connect to Database. Load database aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
SD2Database.HaltDelayThread();
|
||||
}
|
||||
|
||||
struct TSpellSummary
|
||||
{
|
||||
uint8 Targets; // set of enum SelectTarget
|
||||
uint8 Effects; // set of enum SelectEffect
|
||||
} extern* SpellSummary;
|
||||
|
||||
|
||||
// Free Spell Summary
|
||||
|
||||
// Free resources before library unload
|
||||
|
||||
|
||||
|
||||
|
||||
// ScriptDev2 startup
|
||||
|
||||
// Get configuration file
|
||||
|
||||
// Set SD2 Error Log File
|
||||
|
||||
|
||||
// Check config file version
|
||||
|
||||
|
||||
// Load database (must be called after SD2Config.SetSource).
|
||||
|
||||
|
||||
// Resize script ids to needed ammount of assigned ScriptNames (from core)
|
||||
|
||||
|
||||
|
||||
// Check existance scripts for all registered by core script names
|
||||
|
||||
|
||||
//*********************************
|
||||
//*** Functions used globally ***
|
||||
|
||||
/**
|
||||
* Function that does script text
|
||||
*
|
||||
* @param iTextEntry Entry of the text, stored in SD2-database
|
||||
* @param pSource Source of the text
|
||||
* @param pTarget Can be NULL (depending on CHAT_TYPE of iTextEntry). Possible target for the text
|
||||
*/
|
||||
void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget)
|
||||
{
|
||||
if (!pSource)
|
||||
{
|
||||
script_error_log("DoScriptText entry %i, invalid Source pointer.", iTextEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iTextEntry >= 0)
|
||||
{
|
||||
script_error_log("DoScriptText with source entry %u (TypeId=%u, guid=%u) attempts to process text entry %i, but text entry must be negative.",
|
||||
pSource->GetEntry(), pSource->GetTypeId(), pSource->GetGUIDLow(), iTextEntry);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoDisplayText(pSource, iTextEntry, pTarget);
|
||||
// TODO - maybe add some call-stack like error output if above function returns false
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that either simulates or does script text for a map
|
||||
*
|
||||
* @param iTextEntry Entry of the text, stored in SD2-database, only type CHAT_TYPE_ZONE_YELL supported
|
||||
* @param uiCreatureEntry Id of the creature of whom saying will be simulated
|
||||
* @param pMap Given Map on which the map-wide text is displayed
|
||||
* @param pCreatureSource Can be NULL. If pointer to Creature is given, then the creature does the map-wide text
|
||||
* @param pTarget Can be NULL. Possible target for the text
|
||||
*/
|
||||
void DoOrSimulateScriptTextForMap(int32 iTextEntry, uint32 uiCreatureEntry, Map* pMap, Creature* pCreatureSource /*=NULL*/, Unit* pTarget /*=NULL*/)
|
||||
{
|
||||
if (!pMap)
|
||||
{
|
||||
script_error_log("DoOrSimulateScriptTextForMap entry %i, invalid Map pointer.", iTextEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iTextEntry >= 0)
|
||||
{
|
||||
script_error_log("DoOrSimulateScriptTextForMap with source entry %u for map %u attempts to process text entry %i, but text entry must be negative.", uiCreatureEntry, pMap->GetId(), iTextEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
CreatureInfo const* pInfo = GetCreatureTemplateStore(uiCreatureEntry);
|
||||
if (!pInfo)
|
||||
{
|
||||
script_error_log("DoOrSimulateScriptTextForMap has invalid source entry %u for map %u.", uiCreatureEntry, pMap->GetId());
|
||||
return;
|
||||
}
|
||||
|
||||
MangosStringLocale const* pData = GetMangosStringData(iTextEntry);
|
||||
if (!pData)
|
||||
{
|
||||
script_error_log("DoOrSimulateScriptTextForMap with source entry %u for map %u could not find text entry %i.", uiCreatureEntry, pMap->GetId(), iTextEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
debug_log("SD2: DoOrSimulateScriptTextForMap: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u",
|
||||
iTextEntry, pData->SoundId, pData->Type, pData->Language, pData->Emote);
|
||||
|
||||
if (pData->Type != CHAT_TYPE_ZONE_YELL)
|
||||
{
|
||||
script_error_log("DoSimulateScriptTextForMap entry %i has not supported chat type %u.", iTextEntry, pData->Type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pData->SoundId)
|
||||
{
|
||||
pMap->PlayDirectSoundToMap(pData->SoundId);
|
||||
}
|
||||
|
||||
if (pCreatureSource) // If provided pointer for sayer, use direct version
|
||||
{
|
||||
pMap->MonsterYellToMap(pCreatureSource->GetObjectGuid(), iTextEntry, pData->Language, pTarget);
|
||||
}
|
||||
else // Simulate yell
|
||||
{
|
||||
pMap->MonsterYellToMap(pInfo, iTextEntry, pData->Language, pTarget);
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************
|
||||
//*** Functions used internally ***
|
||||
|
||||
void Script::RegisterSelf(bool bReportError)
|
||||
{
|
||||
if (uint32 id = GetScriptId(Name.c_str()))
|
||||
{
|
||||
m_scripts[id] = this;
|
||||
++num_sc_scripts;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bReportError)
|
||||
{
|
||||
script_error_log("Script registering but ScriptName %s is not assigned in database. Script will not be used.", Name.c_str());
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************
|
||||
//*** Functions to be Exported ***
|
||||
|
||||
void SD2::FreeScriptLibrary()
|
||||
{
|
||||
// Free Spell Summary
|
||||
delete []SpellSummary;
|
||||
|
||||
// Free resources before library unload
|
||||
for (SDScriptVec::const_iterator itr = m_scripts.begin(); itr != m_scripts.end(); ++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
m_scripts.clear();
|
||||
num_sc_scripts = 0;
|
||||
setScriptLibraryErrorFile(NULL, NULL);
|
||||
}
|
||||
|
||||
void SD2::InitScriptLibrary()
|
||||
{
|
||||
// ScriptDev2 startup
|
||||
outstring_log(" ___ _ _ ___ ___ ");
|
||||
outstring_log(" / __| __ _ _(_)_ __| |_| \\ _____ _|_ )");
|
||||
outstring_log(" \\__ \\/ _| '_| | '_ \\ _| |) / -_) V // / ");
|
||||
outstring_log(" |___/\\__|_| |_| .__/\\__|___/\\___|\\_//___|");
|
||||
outstring_log(" |_| ");
|
||||
outstring_log(" http://scriptdev2.com/\n");
|
||||
|
||||
// Get configuration file
|
||||
bool configFailure = false;
|
||||
if (!SD2Config.SetSource(MANGOSD_CONFIG_LOCATION))
|
||||
{
|
||||
configFailure = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
outstring_log("SD2: Using configuration file %s", MANGOSD_CONFIG_LOCATION);
|
||||
}
|
||||
|
||||
// Set SD2 Error Log File
|
||||
std::string sd2LogFile = SD2Config.GetStringDefault("SD2ErrorLogFile", "scriptdev2-errors.log");
|
||||
setScriptLibraryErrorFile(sd2LogFile.c_str(), "SD2");
|
||||
if (configFailure)
|
||||
{
|
||||
script_error_log("Unable to open configuration file. Database will be unaccessible. Configuration values will use default.");
|
||||
}
|
||||
|
||||
// Check config file version
|
||||
if (SD2Config.GetIntDefault("ConfVersion", 0) != MANGOSD_CONFIG_VERSION)
|
||||
{
|
||||
script_error_log("Configuration file version doesn't match expected version. Some config variables may be wrong or missing.");
|
||||
}
|
||||
outstring_log("\n");
|
||||
|
||||
// Load database (must be called after SD2Config.SetSource).
|
||||
LoadDatabase();
|
||||
outstring_log("SD2: Loading C++ scripts");
|
||||
BarGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
// Resize script ids to needed ammount of assigned ScriptNames (from core)
|
||||
m_scripts.resize(GetScriptIdsCount(), NULL);
|
||||
FillSpellSummary();
|
||||
AddScripts();
|
||||
|
||||
// Check existance scripts for all registered by core script names
|
||||
for (uint32 i = 1; i < GetScriptIdsCount(); ++i)
|
||||
{
|
||||
if (!m_scripts[i])
|
||||
{
|
||||
script_error_log("No script found for ScriptName '%s'.", GetScriptName(i));
|
||||
}
|
||||
}
|
||||
outstring_log(">> Loaded %i C++ Scripts.", num_sc_scripts);
|
||||
}
|
||||
|
||||
char const* SD2::GetScriptLibraryVersion()
|
||||
{
|
||||
return strSD2Version.c_str();
|
||||
}
|
||||
|
||||
bool SD2::GossipHello(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pGossipHello)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pGossipHello(pPlayer, pCreature);
|
||||
}
|
||||
|
||||
bool SD2::GOGossipHello(Player* pPlayer, GameObject* pGo)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pGo->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pGossipHelloGO)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pGossipHelloGO(pPlayer, pGo);
|
||||
}
|
||||
|
||||
bool SD2::GossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
|
||||
{
|
||||
debug_log("SD2: Gossip selection, sender: %u, action: %u", uiSender, uiAction);
|
||||
|
||||
Script* pTempScript = m_scripts[pCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pGossipSelect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pGossipSelect(pPlayer, pCreature, uiSender, uiAction);
|
||||
}
|
||||
|
||||
bool SD2::GOGossipSelect(Player* pPlayer, GameObject* pGo, uint32 uiSender, uint32 uiAction)
|
||||
{
|
||||
debug_log("SD2: GO Gossip selection, sender: %u, action: %u", uiSender, uiAction);
|
||||
|
||||
Script* pTempScript = m_scripts[pGo->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pGossipSelectGO)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pGossipSelectGO(pPlayer, pGo, uiSender, uiAction);
|
||||
}
|
||||
|
||||
bool SD2::GossipSelectWithCode(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction, const char* sCode)
|
||||
{
|
||||
debug_log("SD2: Gossip selection with code, sender: %u, action: %u", uiSender, uiAction);
|
||||
|
||||
Script* pTempScript = m_scripts[pCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pGossipSelectWithCode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pGossipSelectWithCode(pPlayer, pCreature, uiSender, uiAction, sCode);
|
||||
}
|
||||
|
||||
bool SD2::GOGossipSelectWithCode(Player* pPlayer, GameObject* pGo, uint32 uiSender, uint32 uiAction, const char* sCode)
|
||||
{
|
||||
debug_log("SD2: GO Gossip selection with code, sender: %u, action: %u", uiSender, uiAction);
|
||||
|
||||
Script* pTempScript = m_scripts[pGo->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pGossipSelectGOWithCode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pGossipSelectGOWithCode(pPlayer, pGo, uiSender, uiAction, sCode);
|
||||
}
|
||||
|
||||
bool SD2::QuestAccept(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pQuestAcceptNPC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pQuestAcceptNPC(pPlayer, pCreature, pQuest);
|
||||
}
|
||||
|
||||
bool SD2::QuestRewarded(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pQuestRewardedNPC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pQuestRewardedNPC(pPlayer, pCreature, pQuest);
|
||||
}
|
||||
|
||||
uint32 SD2::GetNPCDialogStatus(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pDialogStatusNPC)
|
||||
{
|
||||
return DIALOG_STATUS_UNDEFINED;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pDialogStatusNPC(pPlayer, pCreature);
|
||||
}
|
||||
|
||||
uint32 SD2::GetGODialogStatus(Player* pPlayer, GameObject* pGo)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pGo->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pDialogStatusGO)
|
||||
{
|
||||
return DIALOG_STATUS_UNDEFINED;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pDialogStatusGO(pPlayer, pGo);
|
||||
}
|
||||
|
||||
bool SD2::ItemQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pItem->GetProto()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pQuestAcceptItem)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pQuestAcceptItem(pPlayer, pItem, pQuest);
|
||||
}
|
||||
|
||||
bool SD2::GOUse(Player* pPlayer, GameObject* pGo)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pGo->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pGOUse)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pGOUse(pPlayer, pGo);
|
||||
}
|
||||
|
||||
bool SD2::GOQuestAccept(Player* pPlayer, GameObject* pGo, const Quest* pQuest)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pGo->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pQuestAcceptGO)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pQuestAcceptGO(pPlayer, pGo, pQuest);
|
||||
}
|
||||
|
||||
bool SD2::GOQuestRewarded(Player* pPlayer, GameObject* pGo, Quest const* pQuest)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pGo->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pQuestRewardedGO)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
return pTempScript->pQuestRewardedGO(pPlayer, pGo, pQuest);
|
||||
}
|
||||
|
||||
bool SD2::AreaTrigger(Player* pPlayer, AreaTriggerEntry const* atEntry)
|
||||
{
|
||||
Script* pTempScript = m_scripts[GetAreaTriggerScriptId(atEntry->id)];
|
||||
|
||||
if (!pTempScript || !pTempScript->pAreaTrigger)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pAreaTrigger(pPlayer, atEntry);
|
||||
}
|
||||
|
||||
bool SD2::NpcSpellClick(Player* pPlayer, Creature* pClickedCreature, uint32 uiSpellId)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pClickedCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pNpcSpellClick)
|
||||
return false;
|
||||
|
||||
return pTempScript->pNpcSpellClick(pPlayer, pClickedCreature, uiSpellId);
|
||||
}
|
||||
|
||||
bool SD2::ProcessEvent(uint32 uiEventId, Object* pSource, Object* pTarget, bool bIsStart)
|
||||
{
|
||||
Script* pTempScript = m_scripts[GetEventIdScriptId(uiEventId)];
|
||||
|
||||
if (!pTempScript || !pTempScript->pProcessEventId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// bIsStart may be false, when event is from taxi node events (arrival=false, departure=true)
|
||||
return pTempScript->pProcessEventId(uiEventId, pSource, pTarget, bIsStart);
|
||||
}
|
||||
|
||||
CreatureAI* SD2::GetCreatureAI(Creature* pCreature)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pCreature->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->GetAI)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pTempScript->GetAI(pCreature);
|
||||
}
|
||||
|
||||
bool SD2::ItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pItem->GetProto()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pItemUse)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pItemUse(pPlayer, pItem, targets);
|
||||
}
|
||||
|
||||
bool SD2::EffectDummyCreature(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pTarget->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pEffectDummyNPC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pEffectDummyNPC(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool SD2::EffectDummyGameObject(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pTarget->GetGOInfo()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pEffectDummyGO)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pEffectDummyGO(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool SD2::EffectDummyItem(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Item* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pTarget->GetProto()->ScriptId];
|
||||
|
||||
if (!pTempScript || !pTempScript->pEffectDummyItem)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pEffectDummyItem(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool SD2::EffectScriptEffectCreature(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pTarget->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pEffectScriptEffectNPC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pEffectScriptEffectNPC(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
|
||||
}
|
||||
|
||||
bool SD2::AuraDummy(Aura const* pAura, bool bApply)
|
||||
{
|
||||
Script* pTempScript = m_scripts[((Creature*)pAura->GetTarget())->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->pEffectAuraDummy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTempScript->pEffectAuraDummy(pAura, bApply);
|
||||
}
|
||||
|
||||
InstanceData* SD2::CreateInstanceData(Map* pMap)
|
||||
{
|
||||
Script* pTempScript = m_scripts[pMap->GetScriptId()];
|
||||
|
||||
if (!pTempScript || !pTempScript->GetInstanceData)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pTempScript->GetInstanceData(pMap);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
182
src/modules/SD2/ScriptDevMgr.h
Normal file
182
src/modules/SD2/ScriptDevMgr.h
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_SCRIPTMGR_H
|
||||
#define SC_SCRIPTMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "DBCStructure.h"
|
||||
|
||||
class Player;
|
||||
class Creature;
|
||||
class CreatureAI;
|
||||
class InstanceData;
|
||||
class Quest;
|
||||
class Item;
|
||||
class GameObject;
|
||||
class SpellCastTargets;
|
||||
class Map;
|
||||
class Unit;
|
||||
class WorldObject;
|
||||
class Aura;
|
||||
class Object;
|
||||
class ObjectGuid;
|
||||
|
||||
// *********************************************************
|
||||
// **************** Functions used by core *****************
|
||||
|
||||
class SD2
|
||||
{
|
||||
public:
|
||||
static void FreeScriptLibrary();
|
||||
static void InitScriptLibrary();
|
||||
static char const* GetScriptLibraryVersion();
|
||||
|
||||
static CreatureAI* GetCreatureAI(Creature* pCreature);
|
||||
static InstanceData* CreateInstanceData(Map* pMap);
|
||||
|
||||
static bool GossipHello(Player*, Creature*);
|
||||
static bool GOGossipHello(Player*, GameObject*);
|
||||
static bool GossipSelect(Player*, Creature*, uint32, uint32);
|
||||
static bool GOGossipSelect(Player*, GameObject*, uint32, uint32);
|
||||
static bool GossipSelectWithCode(Player*, Creature*, uint32, uint32, const char*);
|
||||
static bool GOGossipSelectWithCode(Player*, GameObject*, uint32, uint32, const char*);
|
||||
static bool QuestAccept(Player*, Creature*, Quest const*);
|
||||
static bool GOQuestAccept(Player*, GameObject*, Quest const*);
|
||||
static bool ItemQuestAccept(Player*, Item*, Quest const*);
|
||||
static bool QuestRewarded(Player*, Creature*, Quest const*);
|
||||
static bool GOQuestRewarded(Player*, GameObject*, Quest const*);
|
||||
static uint32 GetNPCDialogStatus(Player*, Creature*);
|
||||
static uint32 GetGODialogStatus(Player*, GameObject*);
|
||||
static bool GOUse(Player*, GameObject*);
|
||||
static bool ItemUse(Player*, Item*, SpellCastTargets const&);
|
||||
static bool AreaTrigger(Player*, AreaTriggerEntry const*);
|
||||
static bool NpcSpellClick(Player* pPlayer, Creature* pClickedCreature, uint32 uiSpellId);
|
||||
static bool ProcessEvent(uint32, Object*, Object*, bool);
|
||||
static bool EffectDummyCreature(Unit*, uint32, SpellEffectIndex, Creature*, ObjectGuid);
|
||||
static bool EffectDummyGameObject(Unit*, uint32, SpellEffectIndex, GameObject*, ObjectGuid);
|
||||
static bool EffectDummyItem(Unit*, uint32, SpellEffectIndex, Item*, ObjectGuid);
|
||||
static bool EffectScriptEffectCreature(Unit*, uint32, SpellEffectIndex, Creature*, ObjectGuid);
|
||||
static bool AuraDummy(Aura const*, bool);
|
||||
};
|
||||
|
||||
// *********************************************************
|
||||
// ************** Some defines used globally ***************
|
||||
|
||||
// Basic defines
|
||||
#define VISIBLE_RANGE (166.0f) // MAX visible range (size of grid)
|
||||
#define DEFAULT_TEXT "<ScriptDev2 Text Entry Missing!>"
|
||||
|
||||
/* Escort Factions
|
||||
* TODO: find better namings and definitions.
|
||||
* N=Neutral, A=Alliance, H=Horde.
|
||||
* NEUTRAL or FRIEND = Hostility to player surroundings (not a good definition)
|
||||
* ACTIVE or PASSIVE = Hostility to environment surroundings.
|
||||
*/
|
||||
enum EscortFaction
|
||||
{
|
||||
FACTION_ESCORT_A_NEUTRAL_PASSIVE = 10,
|
||||
FACTION_ESCORT_H_NEUTRAL_PASSIVE = 33,
|
||||
FACTION_ESCORT_N_NEUTRAL_PASSIVE = 113,
|
||||
|
||||
FACTION_ESCORT_A_NEUTRAL_ACTIVE = 231,
|
||||
FACTION_ESCORT_H_NEUTRAL_ACTIVE = 232,
|
||||
FACTION_ESCORT_N_NEUTRAL_ACTIVE = 250,
|
||||
|
||||
FACTION_ESCORT_N_FRIEND_PASSIVE = 290,
|
||||
FACTION_ESCORT_N_FRIEND_ACTIVE = 495,
|
||||
|
||||
FACTION_ESCORT_A_PASSIVE = 774,
|
||||
FACTION_ESCORT_H_PASSIVE = 775,
|
||||
|
||||
FACTION_ESCORT_N_ACTIVE = 1986,
|
||||
FACTION_ESCORT_H_ACTIVE = 2046
|
||||
};
|
||||
|
||||
// *********************************************************
|
||||
// ************* Some structures used globally *************
|
||||
|
||||
struct Script
|
||||
{
|
||||
Script() :
|
||||
pGossipHello(NULL), pGossipHelloGO(NULL), pGossipSelect(NULL), pGossipSelectGO(NULL),
|
||||
pGossipSelectWithCode(NULL), pGossipSelectGOWithCode(NULL),
|
||||
pDialogStatusNPC(NULL), pDialogStatusGO(NULL),
|
||||
pQuestAcceptNPC(NULL), pQuestAcceptGO(NULL), pQuestAcceptItem(NULL),
|
||||
pQuestRewardedNPC(NULL), pQuestRewardedGO(NULL),
|
||||
pGOUse(NULL), pItemUse(NULL), pAreaTrigger(NULL), pNpcSpellClick(NULL), pProcessEventId(NULL),
|
||||
pEffectDummyNPC(NULL), pEffectDummyGO(NULL), pEffectDummyItem(NULL), pEffectScriptEffectNPC(NULL),
|
||||
pEffectAuraDummy(NULL), GetAI(NULL), GetInstanceData(NULL)
|
||||
{}
|
||||
|
||||
std::string Name;
|
||||
|
||||
bool (*pGossipHello)(Player*, Creature*);
|
||||
bool (*pGossipHelloGO)(Player*, GameObject*);
|
||||
bool (*pGossipSelect)(Player*, Creature*, uint32, uint32);
|
||||
bool (*pGossipSelectGO)(Player*, GameObject*, uint32, uint32);
|
||||
bool (*pGossipSelectWithCode)(Player*, Creature*, uint32, uint32, const char*);
|
||||
bool (*pGossipSelectGOWithCode)(Player*, GameObject*, uint32, uint32, const char*);
|
||||
uint32(*pDialogStatusNPC)(Player*, Creature*);
|
||||
uint32(*pDialogStatusGO)(Player*, GameObject*);
|
||||
bool (*pQuestAcceptNPC)(Player*, Creature*, Quest const*);
|
||||
bool (*pQuestAcceptGO)(Player*, GameObject*, Quest const*);
|
||||
bool (*pQuestAcceptItem)(Player*, Item*, Quest const*);
|
||||
bool (*pQuestRewardedNPC)(Player*, Creature*, Quest const*);
|
||||
bool (*pQuestRewardedGO)(Player*, GameObject*, Quest const*);
|
||||
bool (*pGOUse)(Player*, GameObject*);
|
||||
bool (*pItemUse)(Player*, Item*, SpellCastTargets const&);
|
||||
bool (*pAreaTrigger)(Player*, AreaTriggerEntry const*);
|
||||
bool (*pNpcSpellClick)(Player*, Creature*, uint32);
|
||||
bool (*pProcessEventId)(uint32, Object*, Object*, bool);
|
||||
bool (*pEffectDummyNPC)(Unit*, uint32, SpellEffectIndex, Creature*, ObjectGuid);
|
||||
bool (*pEffectDummyGO)(Unit*, uint32, SpellEffectIndex, GameObject*, ObjectGuid);
|
||||
bool (*pEffectDummyItem)(Unit*, uint32, SpellEffectIndex, Item*, ObjectGuid);
|
||||
bool (*pEffectScriptEffectNPC)(Unit*, uint32, SpellEffectIndex, Creature*, ObjectGuid);
|
||||
bool (*pEffectAuraDummy)(const Aura*, bool);
|
||||
|
||||
CreatureAI* (*GetAI)(Creature*);
|
||||
InstanceData* (*GetInstanceData)(Map*);
|
||||
|
||||
void RegisterSelf(bool bReportError = true);
|
||||
};
|
||||
|
||||
// *********************************************************
|
||||
// ************* Some functions used globally **************
|
||||
|
||||
// Generic scripting text function
|
||||
void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget = NULL);
|
||||
void DoOrSimulateScriptTextForMap(int32 iTextEntry, uint32 uiCreatureEntry, Map* pMap, Creature* pCreatureSource = NULL, Unit* pTarget = NULL);
|
||||
|
||||
// *********************************************************
|
||||
// **************** Internal hook mechanics ****************
|
||||
|
||||
#if COMPILER == COMPILER_GNU || COMPILER == COMPILER_CLANG
|
||||
#define FUNC_PTR(name,callconvention,returntype,parameters) typedef returntype(*name)parameters __attribute__ ((callconvention));
|
||||
#else
|
||||
#define FUNC_PTR(name, callconvention, returntype, parameters) typedef returntype(callconvention *name)parameters;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
661
src/modules/SD2/base/escort_ai.cpp
Normal file
661
src/modules/SD2/base/escort_ai.cpp
Normal file
|
|
@ -0,0 +1,661 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: EscortAI
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Npc
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "escort_ai.h"
|
||||
#include "../system/system.h"
|
||||
|
||||
const float MAX_PLAYER_DISTANCE = 66.0f;
|
||||
|
||||
enum
|
||||
{
|
||||
POINT_LAST_POINT = 0xFFFFFF,
|
||||
POINT_HOME = 0xFFFFFE
|
||||
};
|
||||
|
||||
npc_escortAI::npc_escortAI(Creature* pCreature) : ScriptedAI(pCreature),
|
||||
m_uiWPWaitTimer(2500),
|
||||
m_uiPlayerCheckTimer(1000),
|
||||
m_uiEscortState(STATE_ESCORT_NONE),
|
||||
m_pQuestForEscort(NULL),
|
||||
m_bIsRunning(false),
|
||||
m_bCanInstantRespawn(false),
|
||||
m_bCanReturnToStart(false)
|
||||
{}
|
||||
|
||||
void npc_escortAI::GetAIInformation(ChatHandler& reader)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << "EscortAI ";
|
||||
if (m_playerGuid)
|
||||
{
|
||||
oss << "started for " << m_playerGuid.GetString() << " ";
|
||||
}
|
||||
if (m_pQuestForEscort)
|
||||
{
|
||||
oss << "started with quest " << m_pQuestForEscort->GetQuestId();
|
||||
}
|
||||
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
oss << "\nEscortFlags: Escorting" << (HasEscortState(STATE_ESCORT_RETURNING) ? ", Returning" : "") << (HasEscortState(STATE_ESCORT_PAUSED) ? ", Paused" : "");
|
||||
|
||||
if (CurrentWP != WaypointList.end())
|
||||
{
|
||||
oss << "\nNext Waypoint Id = " << CurrentWP->uiId << " Position: " << CurrentWP->fX << " " << CurrentWP->fY << " " << CurrentWP->fZ;
|
||||
}
|
||||
}
|
||||
|
||||
reader.PSendSysMessage(oss.str().c_str());
|
||||
}
|
||||
|
||||
bool npc_escortAI::IsVisible(Unit* pWho) const
|
||||
{
|
||||
if (!pWho)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_creature->IsWithinDist(pWho, VISIBLE_RANGE) && pWho->IsVisibleForOrDetect(m_creature, m_creature, true);
|
||||
}
|
||||
|
||||
void npc_escortAI::AttackStart(Unit* pWho)
|
||||
{
|
||||
if (!pWho)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->AddThreat(pWho);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
|
||||
{
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
}
|
||||
|
||||
if (IsCombatMovement())
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void npc_escortAI::EnterCombat(Unit* pEnemy)
|
||||
{
|
||||
// Store combat start position
|
||||
m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
|
||||
|
||||
if (!pEnemy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Aggro(pEnemy);
|
||||
}
|
||||
|
||||
void npc_escortAI::Aggro(Unit* /*pEnemy*/) {}
|
||||
|
||||
// see followerAI
|
||||
bool npc_escortAI::AssistPlayerInCombat(Unit* pWho)
|
||||
{
|
||||
if (!pWho->getVictim())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// experimental (unknown) flag not present
|
||||
if (!(m_creature->GetCreatureInfo()->CreatureTypeFlags & CREATURE_TYPEFLAGS_CAN_ASSIST))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// unit state prevents (similar check is done in CanInitiateAttack which also include checking unit_flags. We skip those here)
|
||||
if (m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// victim of pWho is not a player
|
||||
if (!pWho->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// never attack friendly
|
||||
if (m_creature->IsFriendlyTo(pWho))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// too far away and no free sight?
|
||||
if (m_creature->IsWithinDistInMap(pWho, MAX_PLAYER_DISTANCE) && m_creature->IsWithinLOSInMap(pWho))
|
||||
{
|
||||
// already fighting someone?
|
||||
if (!m_creature->getVictim())
|
||||
{
|
||||
AttackStart(pWho);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
m_creature->AddThreat(pWho);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void npc_escortAI::MoveInLineOfSight(Unit* pWho)
|
||||
{
|
||||
if (pWho->IsTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
// AssistPlayerInCombat can start attack, so return if true
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING) && AssistPlayerInCombat(pWho))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_creature->CanInitiateAttack())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->IsHostileTo(pWho))
|
||||
{
|
||||
float fAttackRadius = m_creature->GetAttackDistance(pWho);
|
||||
if (m_creature->IsWithinDistInMap(pWho, fAttackRadius) && m_creature->IsWithinLOSInMap(pWho))
|
||||
{
|
||||
if (!m_creature->getVictim())
|
||||
{
|
||||
pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(pWho);
|
||||
}
|
||||
else if (m_creature->GetMap()->IsDungeon())
|
||||
{
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
m_creature->AddThreat(pWho);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void npc_escortAI::JustDied(Unit* /*pKiller*/)
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING) || !m_playerGuid || !m_pQuestForEscort)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Player* pPlayer = GetPlayerForEscort())
|
||||
{
|
||||
if (Group* pGroup = pPlayer->GetGroup())
|
||||
{
|
||||
for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
|
||||
{
|
||||
if (Player* pMember = pRef->getSource())
|
||||
{
|
||||
if (pMember->GetQuestStatus(m_pQuestForEscort->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
pMember->FailQuest(m_pQuestForEscort->GetQuestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(m_pQuestForEscort->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
pPlayer->FailQuest(m_pQuestForEscort->GetQuestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void npc_escortAI::JustRespawned()
|
||||
{
|
||||
m_uiEscortState = STATE_ESCORT_NONE;
|
||||
|
||||
if (!IsCombatMovement())
|
||||
{
|
||||
SetCombatMovement(true);
|
||||
}
|
||||
|
||||
// add a small delay before going to first waypoint, normal in near all cases
|
||||
m_uiWPWaitTimer = 2500;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void npc_escortAI::EnterEvadeMode()
|
||||
{
|
||||
m_creature->RemoveAllAurasOnEvade();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(true);
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
// We have left our path
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
|
||||
{
|
||||
debug_log("SD2: EscortAI has left combat and is now returning to CombatStartPosition.");
|
||||
|
||||
AddEscortState(STATE_ESCORT_RETURNING);
|
||||
|
||||
float fPosX, fPosY, fPosZ;
|
||||
m_creature->GetCombatStartPosition(fPosX, fPosY, fPosZ);
|
||||
m_creature->GetMotionMaster()->MovePoint(POINT_LAST_POINT, fPosX, fPosY, fPosZ);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool npc_escortAI::IsPlayerOrGroupInRange()
|
||||
{
|
||||
if (Player* pPlayer = GetPlayerForEscort())
|
||||
{
|
||||
if (Group* pGroup = pPlayer->GetGroup())
|
||||
{
|
||||
for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
|
||||
{
|
||||
Player* pMember = pRef->getSource();
|
||||
if (pMember && m_creature->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_creature->IsWithinDistInMap(pPlayer, MAX_PLAYER_DISTANCE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns false, if npc is despawned
|
||||
bool npc_escortAI::MoveToNextWaypoint()
|
||||
{
|
||||
// Do nothing if escorting is paused
|
||||
if (HasEscortState(STATE_ESCORT_PAUSED))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Final Waypoint reached (and final wait time waited)
|
||||
if (CurrentWP == WaypointList.end())
|
||||
{
|
||||
debug_log("SD2: EscortAI reached end of waypoints");
|
||||
|
||||
if (m_bCanReturnToStart)
|
||||
{
|
||||
float fRetX, fRetY, fRetZ;
|
||||
m_creature->GetRespawnCoord(fRetX, fRetY, fRetZ);
|
||||
|
||||
m_creature->GetMotionMaster()->MovePoint(POINT_HOME, fRetX, fRetY, fRetZ);
|
||||
|
||||
m_uiWPWaitTimer = 0;
|
||||
|
||||
debug_log("SD2: EscortAI are returning home to spawn location: %u, %f, %f, %f", POINT_HOME, fRetX, fRetY, fRetZ);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_bCanInstantRespawn)
|
||||
{
|
||||
m_creature->SetDeathState(JUST_DIED);
|
||||
m_creature->Respawn();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_creature->GetMotionMaster()->MovePoint(CurrentWP->uiId, CurrentWP->fX, CurrentWP->fY, CurrentWP->fZ);
|
||||
debug_log("SD2: EscortAI start waypoint %u (%f, %f, %f).", CurrentWP->uiId, CurrentWP->fX, CurrentWP->fY, CurrentWP->fZ);
|
||||
|
||||
WaypointStart(CurrentWP->uiId);
|
||||
|
||||
m_uiWPWaitTimer = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void npc_escortAI::UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
// Waypoint Updating
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING) && !m_creature->getVictim() && m_uiWPWaitTimer && !HasEscortState(STATE_ESCORT_RETURNING))
|
||||
{
|
||||
if (m_uiWPWaitTimer <= uiDiff)
|
||||
{
|
||||
if (!MoveToNextWaypoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiWPWaitTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if player or any member of his group is within range
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING) && m_playerGuid && !m_creature->getVictim() && !HasEscortState(STATE_ESCORT_RETURNING))
|
||||
{
|
||||
if (m_uiPlayerCheckTimer < uiDiff)
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_PAUSED) && !IsPlayerOrGroupInRange())
|
||||
{
|
||||
debug_log("SD2: EscortAI failed because player/group was to far away or not found");
|
||||
|
||||
if (m_bCanInstantRespawn)
|
||||
{
|
||||
m_creature->SetDeathState(JUST_DIED);
|
||||
m_creature->Respawn();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_uiPlayerCheckTimer = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiPlayerCheckTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateEscortAI(uiDiff);
|
||||
}
|
||||
|
||||
void npc_escortAI::UpdateEscortAI(const uint32 /*uiDiff*/)
|
||||
{
|
||||
// Check if we have a current target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId)
|
||||
{
|
||||
if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Combat start position reached, continue waypoint movement
|
||||
if (uiPointId == POINT_LAST_POINT)
|
||||
{
|
||||
debug_log("SD2: EscortAI has returned to original position before combat");
|
||||
|
||||
m_creature->SetWalk(!m_bIsRunning);
|
||||
RemoveEscortState(STATE_ESCORT_RETURNING);
|
||||
}
|
||||
else if (uiPointId == POINT_HOME)
|
||||
{
|
||||
debug_log("SD2: EscortAI has returned to original home location and will continue from beginning of waypoint list.");
|
||||
|
||||
CurrentWP = WaypointList.begin();
|
||||
m_uiWPWaitTimer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure that we are still on the right waypoint
|
||||
if (CurrentWP->uiId != uiPointId)
|
||||
{
|
||||
script_error_log("EscortAI for Npc %u reached waypoint out of order %u, expected %u.", m_creature->GetEntry(), uiPointId, CurrentWP->uiId);
|
||||
return;
|
||||
}
|
||||
|
||||
debug_log("SD2: EscortAI waypoint %u reached.", CurrentWP->uiId);
|
||||
|
||||
// In case we were moving while in combat, we should evade back to this position
|
||||
m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
|
||||
|
||||
// Call WP function
|
||||
WaypointReached(CurrentWP->uiId);
|
||||
|
||||
m_uiWPWaitTimer = CurrentWP->uiWaitTime;
|
||||
|
||||
++CurrentWP;
|
||||
}
|
||||
|
||||
if (!m_uiWPWaitTimer)
|
||||
{
|
||||
// Continue WP Movement if Can
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING) && !HasEscortState(STATE_ESCORT_PAUSED | STATE_ESCORT_RETURNING) && !m_creature->getVictim())
|
||||
{
|
||||
MoveToNextWaypoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiWPWaitTimer = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs)
|
||||
{
|
||||
Escort_Waypoint t(id, x, y, z, WaitTimeMs);
|
||||
|
||||
WaypointList.push_back(t);
|
||||
}*/
|
||||
|
||||
void npc_escortAI::FillPointMovementListForCreature()
|
||||
{
|
||||
std::vector<ScriptPointMove> const& pPointsEntries = pSystemMgr.GetPointMoveList(m_creature->GetEntry());
|
||||
|
||||
if (pPointsEntries.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<ScriptPointMove>::const_iterator itr;
|
||||
|
||||
for (itr = pPointsEntries.begin(); itr != pPointsEntries.end(); ++itr)
|
||||
{
|
||||
Escort_Waypoint pPoint(itr->uiPointId, itr->fX, itr->fY, itr->fZ, itr->uiWaitTime);
|
||||
WaypointList.push_back(pPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void npc_escortAI::SetCurrentWaypoint(uint32 uiPointId)
|
||||
{
|
||||
if (!(HasEscortState(STATE_ESCORT_PAUSED))) // Only when paused
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (uiPointId == CurrentWP->uiId) // Already here
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool bFoundWaypoint = false;
|
||||
for (std::list<Escort_Waypoint>::iterator itr = WaypointList.begin(); itr != WaypointList.end(); ++itr)
|
||||
{
|
||||
if (itr->uiId == uiPointId)
|
||||
{
|
||||
CurrentWP = itr; // Set to found itr
|
||||
bFoundWaypoint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFoundWaypoint)
|
||||
{
|
||||
debug_log("SD2: EscortAI current waypoint tried to set to id %u, but doesn't exist in WaypointList", uiPointId);
|
||||
return;
|
||||
}
|
||||
|
||||
m_uiWPWaitTimer = 1;
|
||||
|
||||
debug_log("SD2: EscortAI current waypoint set to id %u", CurrentWP->uiId);
|
||||
}
|
||||
|
||||
void npc_escortAI::SetRun(bool bRun)
|
||||
{
|
||||
if (bRun)
|
||||
{
|
||||
if (!m_bIsRunning)
|
||||
{
|
||||
m_creature->SetWalk(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_log("SD2: EscortAI attempt to set run mode, but is already running.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bIsRunning)
|
||||
{
|
||||
m_creature->SetWalk(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_log("SD2: EscortAI attempt to set walk mode, but is already walking.");
|
||||
}
|
||||
}
|
||||
m_bIsRunning = bRun;
|
||||
}
|
||||
|
||||
// TODO: get rid of this many variables passed in function.
|
||||
void npc_escortAI::Start(bool bRun, const Player* pPlayer, const Quest* pQuest, bool bInstantRespawn, bool bCanLoopPath)
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
{
|
||||
script_error_log("EscortAI attempt to Start while in combat.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
script_error_log("EscortAI attempt to Start while already escorting.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WaypointList.empty())
|
||||
{
|
||||
WaypointList.clear();
|
||||
}
|
||||
|
||||
FillPointMovementListForCreature();
|
||||
|
||||
if (WaypointList.empty())
|
||||
{
|
||||
error_db_log("SD2: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint).");
|
||||
return;
|
||||
}
|
||||
|
||||
// set variables
|
||||
m_bIsRunning = bRun;
|
||||
|
||||
m_playerGuid = pPlayer ? pPlayer->GetObjectGuid() : ObjectGuid();
|
||||
m_pQuestForEscort = pQuest;
|
||||
|
||||
m_bCanInstantRespawn = bInstantRespawn;
|
||||
m_bCanReturnToStart = bCanLoopPath;
|
||||
|
||||
if (m_bCanReturnToStart && m_bCanInstantRespawn)
|
||||
{
|
||||
debug_log("SD2: EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn.");
|
||||
}
|
||||
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
|
||||
{
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
debug_log("SD2: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle.");
|
||||
}
|
||||
|
||||
// disable npcflags
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
|
||||
debug_log("SD2: EscortAI started with " SIZEFMTD " waypoints. Run = %d, PlayerGuid = %s", WaypointList.size(), m_bIsRunning, m_playerGuid.GetString().c_str());
|
||||
|
||||
CurrentWP = WaypointList.begin();
|
||||
|
||||
// Set initial speed
|
||||
m_creature->SetWalk(!m_bIsRunning);
|
||||
|
||||
AddEscortState(STATE_ESCORT_ESCORTING);
|
||||
|
||||
JustStartedEscort();
|
||||
}
|
||||
|
||||
void npc_escortAI::SetEscortPaused(bool bPaused)
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (bPaused)
|
||||
{
|
||||
AddEscortState(STATE_ESCORT_PAUSED);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveEscortState(STATE_ESCORT_PAUSED);
|
||||
}
|
||||
}
|
||||
136
src/modules/SD2/base/escort_ai.h
Normal file
136
src/modules/SD2/base/escort_ai.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_ESCORTAI_H
|
||||
#define SC_ESCORTAI_H
|
||||
|
||||
// Remove this include, when EscortAI stores uint32 quest-id instead of Quest*
|
||||
#include "ObjectMgr.h"
|
||||
|
||||
struct Escort_Waypoint
|
||||
{
|
||||
Escort_Waypoint(uint32 uiId, float fX, float fY, float fZ, uint32 uiWaitTime) :
|
||||
uiId(uiId),
|
||||
fX(fX),
|
||||
fY(fY),
|
||||
fZ(fZ),
|
||||
uiWaitTime(uiWaitTime)
|
||||
{}
|
||||
|
||||
uint32 uiId;
|
||||
float fX;
|
||||
float fY;
|
||||
float fZ;
|
||||
uint32 uiWaitTime;
|
||||
};
|
||||
|
||||
enum EscortState
|
||||
{
|
||||
STATE_ESCORT_NONE = 0x000, // nothing in progress
|
||||
STATE_ESCORT_ESCORTING = 0x001, // escort are in progress
|
||||
STATE_ESCORT_RETURNING = 0x002, // escort is returning after being in combat
|
||||
STATE_ESCORT_PAUSED = 0x004 // will not proceed with waypoints before state is removed
|
||||
};
|
||||
|
||||
struct npc_escortAI : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
explicit npc_escortAI(Creature* pCreature);
|
||||
~npc_escortAI() {}
|
||||
|
||||
void GetAIInformation(ChatHandler& reader) override;
|
||||
|
||||
virtual void Aggro(Unit*) override;
|
||||
|
||||
virtual void Reset() override = 0;
|
||||
|
||||
// CreatureAI functions
|
||||
bool IsVisible(Unit*) const override;
|
||||
|
||||
void AttackStart(Unit*) override;
|
||||
|
||||
void EnterCombat(Unit*) override;
|
||||
|
||||
void MoveInLineOfSight(Unit*) override;
|
||||
|
||||
void JustDied(Unit*) override;
|
||||
|
||||
void JustRespawned() override;
|
||||
|
||||
void EnterEvadeMode() override;
|
||||
|
||||
void UpdateAI(const uint32) override; // the "internal" update, calls UpdateEscortAI()
|
||||
|
||||
// Called when an AI Event is received
|
||||
void ReceiveAIEvent(AIEventType /*eventType*/, Creature* /*pSender*/, Unit* /*pInvoker*/, uint32 /*uiMiscValue*/) override {}
|
||||
|
||||
virtual void UpdateEscortAI(const uint32); // used when it's needed to add code in update (abilities, scripted events, etc)
|
||||
|
||||
void MovementInform(uint32, uint32) override;
|
||||
|
||||
// EscortAI functions
|
||||
// void AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs = 0);
|
||||
|
||||
virtual void WaypointReached(uint32 uiPointId) = 0;
|
||||
virtual void WaypointStart(uint32 /*uiPointId*/) {}
|
||||
|
||||
void Start(bool bRun = false, const Player* pPlayer = NULL, const Quest* pQuest = NULL, bool bInstantRespawn = false, bool bCanLoopPath = false);
|
||||
|
||||
void SetRun(bool bRun = true);
|
||||
void SetEscortPaused(bool uPaused);
|
||||
|
||||
bool HasEscortState(uint32 uiEscortState) { return (m_uiEscortState & uiEscortState); }
|
||||
|
||||
// update current point
|
||||
void SetCurrentWaypoint(uint32 uiPointId);
|
||||
|
||||
protected:
|
||||
Player* GetPlayerForEscort() { return m_creature->GetMap()->GetPlayer(m_playerGuid); }
|
||||
virtual void JustStartedEscort() {}
|
||||
|
||||
private:
|
||||
bool AssistPlayerInCombat(Unit* pWho);
|
||||
bool IsPlayerOrGroupInRange();
|
||||
bool MoveToNextWaypoint();
|
||||
void FillPointMovementListForCreature();
|
||||
|
||||
void AddEscortState(uint32 uiEscortState) { m_uiEscortState |= uiEscortState; }
|
||||
void RemoveEscortState(uint32 uiEscortState) { m_uiEscortState &= ~uiEscortState; }
|
||||
|
||||
ObjectGuid m_playerGuid;
|
||||
uint32 m_uiWPWaitTimer;
|
||||
uint32 m_uiPlayerCheckTimer;
|
||||
uint32 m_uiEscortState;
|
||||
|
||||
const Quest* m_pQuestForEscort; // generally passed in Start() when regular escort script.
|
||||
|
||||
std::list<Escort_Waypoint> WaypointList;
|
||||
std::list<Escort_Waypoint>::iterator CurrentWP;
|
||||
|
||||
bool m_bIsRunning; // all creatures are walking by default (has flag SPLINEFLAG_WALKMODE)
|
||||
bool m_bCanInstantRespawn; // if creature should respawn instantly after escort over (if not, database respawntime are used)
|
||||
bool m_bCanReturnToStart; // if creature can walk same path (loop) without despawn. Not for regular escort quests.
|
||||
};
|
||||
#endif
|
||||
457
src/modules/SD2/base/follower_ai.cpp
Normal file
457
src/modules/SD2/base/follower_ai.cpp
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: FollowerAI
|
||||
SD%Complete: 60
|
||||
SDComment: This AI is under development
|
||||
SDCategory: Npc
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "follower_ai.h"
|
||||
|
||||
const float MAX_PLAYER_DISTANCE = 100.0f;
|
||||
|
||||
enum
|
||||
{
|
||||
POINT_COMBAT_START = 0xFFFFFF
|
||||
};
|
||||
|
||||
FollowerAI::FollowerAI(Creature* pCreature) : ScriptedAI(pCreature),
|
||||
m_uiUpdateFollowTimer(2500),
|
||||
m_uiFollowState(STATE_FOLLOW_NONE),
|
||||
m_pQuestForFollow(NULL)
|
||||
{}
|
||||
|
||||
void FollowerAI::AttackStart(Unit* pWho)
|
||||
{
|
||||
if (!pWho)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->AddThreat(pWho);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
if (IsCombatMovement())
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This part provides assistance to a player that are attacked by pWho, even if out of normal aggro range
|
||||
// It will cause m_creature to attack pWho that are attacking _any_ player (which has been confirmed may happen also on offi)
|
||||
bool FollowerAI::AssistPlayerInCombat(Unit* pWho)
|
||||
{
|
||||
if (!pWho->getVictim())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// experimental (unknown) flag not present
|
||||
if (!(m_creature->GetCreatureInfo()->CreatureTypeFlags & CREATURE_TYPEFLAGS_CAN_ASSIST))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// unit state prevents (similar check is done in CanInitiateAttack which also include checking unit_flags. We skip those here)
|
||||
if (m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// victim of pWho is not a player
|
||||
if (!pWho->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// never attack friendly
|
||||
if (m_creature->IsFriendlyTo(pWho))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// too far away and no free sight?
|
||||
if (m_creature->IsWithinDistInMap(pWho, MAX_PLAYER_DISTANCE) && m_creature->IsWithinLOSInMap(pWho))
|
||||
{
|
||||
// already fighting someone?
|
||||
if (!m_creature->getVictim())
|
||||
{
|
||||
AttackStart(pWho);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
m_creature->AddThreat(pWho);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FollowerAI::MoveInLineOfSight(Unit* pWho)
|
||||
{
|
||||
if (pWho->IsTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
// AssistPlayerInCombat can start attack, so return if true
|
||||
if (HasFollowState(STATE_FOLLOW_INPROGRESS) && AssistPlayerInCombat(pWho))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_creature->CanInitiateAttack())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->IsHostileTo(pWho))
|
||||
{
|
||||
float fAttackRadius = m_creature->GetAttackDistance(pWho);
|
||||
if (m_creature->IsWithinDistInMap(pWho, fAttackRadius) && m_creature->IsWithinLOSInMap(pWho))
|
||||
{
|
||||
if (!m_creature->getVictim())
|
||||
{
|
||||
pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(pWho);
|
||||
}
|
||||
else if (m_creature->GetMap()->IsDungeon())
|
||||
{
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
m_creature->AddThreat(pWho);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FollowerAI::JustDied(Unit* /*pKiller*/)
|
||||
{
|
||||
if (!HasFollowState(STATE_FOLLOW_INPROGRESS) || !m_leaderGuid || !m_pQuestForFollow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: need a better check for quests with time limit.
|
||||
if (Player* pPlayer = GetLeaderForFollower())
|
||||
{
|
||||
if (Group* pGroup = pPlayer->GetGroup())
|
||||
{
|
||||
for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
|
||||
{
|
||||
if (Player* pMember = pRef->getSource())
|
||||
{
|
||||
if (pMember->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
pMember->FailQuest(m_pQuestForFollow->GetQuestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
pPlayer->FailQuest(m_pQuestForFollow->GetQuestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FollowerAI::JustRespawned()
|
||||
{
|
||||
m_uiFollowState = STATE_FOLLOW_NONE;
|
||||
|
||||
if (!IsCombatMovement())
|
||||
{
|
||||
SetCombatMovement(true);
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void FollowerAI::EnterEvadeMode()
|
||||
{
|
||||
m_creature->RemoveAllAurasOnEvade();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(true);
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
|
||||
if (HasFollowState(STATE_FOLLOW_INPROGRESS))
|
||||
{
|
||||
debug_log("SD2: FollowerAI left combat, returning to CombatStartPosition.");
|
||||
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
|
||||
{
|
||||
float fPosX, fPosY, fPosZ;
|
||||
m_creature->GetCombatStartPosition(fPosX, fPosY, fPosZ);
|
||||
m_creature->GetMotionMaster()->MovePoint(POINT_COMBAT_START, fPosX, fPosY, fPosZ);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void FollowerAI::UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !m_creature->getVictim())
|
||||
{
|
||||
if (m_uiUpdateFollowTimer < uiDiff)
|
||||
{
|
||||
if (HasFollowState(STATE_FOLLOW_COMPLETE) && !HasFollowState(STATE_FOLLOW_POSTEVENT))
|
||||
{
|
||||
debug_log("SD2: FollowerAI is set completed, despawns.");
|
||||
m_creature->ForcedDespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
bool bIsMaxRangeExceeded = true;
|
||||
|
||||
if (Player* pPlayer = GetLeaderForFollower())
|
||||
{
|
||||
if (HasFollowState(STATE_FOLLOW_RETURNING))
|
||||
{
|
||||
debug_log("SD2: FollowerAI is returning to leader.");
|
||||
|
||||
RemoveFollowState(STATE_FOLLOW_RETURNING);
|
||||
m_creature->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Group* pGroup = pPlayer->GetGroup())
|
||||
{
|
||||
for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
|
||||
{
|
||||
Player* pMember = pRef->getSource();
|
||||
|
||||
if (pMember && m_creature->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
|
||||
{
|
||||
bIsMaxRangeExceeded = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_creature->IsWithinDistInMap(pPlayer, MAX_PLAYER_DISTANCE))
|
||||
{
|
||||
bIsMaxRangeExceeded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bIsMaxRangeExceeded)
|
||||
{
|
||||
debug_log("SD2: FollowerAI failed because player/group was to far away or not found");
|
||||
m_creature->ForcedDespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
m_uiUpdateFollowTimer = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiUpdateFollowTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFollowerAI(uiDiff);
|
||||
}
|
||||
|
||||
void FollowerAI::UpdateFollowerAI(const uint32 /*uiDiff*/)
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void FollowerAI::MovementInform(uint32 uiMotionType, uint32 uiPointId)
|
||||
{
|
||||
if (uiMotionType != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (uiPointId == POINT_COMBAT_START)
|
||||
{
|
||||
if (GetLeaderForFollower())
|
||||
{
|
||||
if (!HasFollowState(STATE_FOLLOW_PAUSED))
|
||||
{
|
||||
AddFollowState(STATE_FOLLOW_RETURNING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const Quest* pQuest)
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
{
|
||||
debug_log("SD2: FollowerAI attempt to StartFollow while in combat.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasFollowState(STATE_FOLLOW_INPROGRESS))
|
||||
{
|
||||
script_error_log("FollowerAI attempt to StartFollow while already following.");
|
||||
return;
|
||||
}
|
||||
|
||||
// set variables
|
||||
m_leaderGuid = pLeader->GetObjectGuid();
|
||||
|
||||
if (uiFactionForFollower)
|
||||
{
|
||||
m_creature->SetFactionTemporary(uiFactionForFollower, TEMPFACTION_RESTORE_RESPAWN);
|
||||
}
|
||||
|
||||
m_pQuestForFollow = pQuest;
|
||||
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
|
||||
{
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
debug_log("SD2: FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle.");
|
||||
}
|
||||
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
|
||||
AddFollowState(STATE_FOLLOW_INPROGRESS);
|
||||
|
||||
m_creature->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
|
||||
debug_log("SD2: FollowerAI start follow %s (Guid %s)", pLeader->GetName(), m_leaderGuid.GetString().c_str());
|
||||
}
|
||||
|
||||
Player* FollowerAI::GetLeaderForFollower()
|
||||
{
|
||||
if (Player* pLeader = m_creature->GetMap()->GetPlayer(m_leaderGuid))
|
||||
{
|
||||
if (pLeader->IsAlive())
|
||||
{
|
||||
return pLeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Group* pGroup = pLeader->GetGroup())
|
||||
{
|
||||
for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
|
||||
{
|
||||
Player* pMember = pRef->getSource();
|
||||
|
||||
if (pMember && pMember->IsAlive() && m_creature->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
|
||||
{
|
||||
debug_log("SD2: FollowerAI GetLeader changed and returned new leader.");
|
||||
m_leaderGuid = pMember->GetObjectGuid();
|
||||
return pMember;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_log("SD2: FollowerAI GetLeader can not find suitable leader.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FollowerAI::SetFollowComplete(bool bWithEndEvent)
|
||||
{
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == FOLLOW_MOTION_TYPE)
|
||||
{
|
||||
m_creature->StopMoving();
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
|
||||
if (bWithEndEvent)
|
||||
{
|
||||
AddFollowState(STATE_FOLLOW_POSTEVENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HasFollowState(STATE_FOLLOW_POSTEVENT))
|
||||
{
|
||||
RemoveFollowState(STATE_FOLLOW_POSTEVENT);
|
||||
}
|
||||
}
|
||||
|
||||
AddFollowState(STATE_FOLLOW_COMPLETE);
|
||||
}
|
||||
|
||||
void FollowerAI::SetFollowPaused(bool bPaused)
|
||||
{
|
||||
if (!HasFollowState(STATE_FOLLOW_INPROGRESS) || HasFollowState(STATE_FOLLOW_COMPLETE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (bPaused)
|
||||
{
|
||||
AddFollowState(STATE_FOLLOW_PAUSED);
|
||||
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == FOLLOW_MOTION_TYPE)
|
||||
{
|
||||
m_creature->StopMoving();
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveFollowState(STATE_FOLLOW_PAUSED);
|
||||
|
||||
if (Player* pLeader = GetLeaderForFollower())
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
86
src/modules/SD2/base/follower_ai.h
Normal file
86
src/modules/SD2/base/follower_ai.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_FOLLOWERAI_H
|
||||
#define SC_FOLLOWERAI_H
|
||||
|
||||
enum FollowState
|
||||
{
|
||||
STATE_FOLLOW_NONE = 0x000,
|
||||
STATE_FOLLOW_INPROGRESS = 0x001, // must always have this state for any follow
|
||||
STATE_FOLLOW_RETURNING = 0x002, // when returning to combat start after being in combat
|
||||
STATE_FOLLOW_PAUSED = 0x004, // disables following
|
||||
STATE_FOLLOW_COMPLETE = 0x008, // follow is completed and may end
|
||||
STATE_FOLLOW_PREEVENT = 0x010, // not implemented (allow pre event to run, before follow is initiated)
|
||||
STATE_FOLLOW_POSTEVENT = 0x020 // can be set at complete and allow post event to run
|
||||
};
|
||||
|
||||
class FollowerAI : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
explicit FollowerAI(Creature* pCreature);
|
||||
~FollowerAI() {}
|
||||
|
||||
// virtual void WaypointReached(uint32 uiPointId) = 0;
|
||||
|
||||
void MovementInform(uint32 uiMotionType, uint32 uiPointId) override;
|
||||
|
||||
void AttackStart(Unit*) override;
|
||||
|
||||
void MoveInLineOfSight(Unit*) override;
|
||||
|
||||
void EnterEvadeMode() override;
|
||||
|
||||
void JustDied(Unit*) override;
|
||||
|
||||
void JustRespawned() override;
|
||||
|
||||
void UpdateAI(const uint32) override; // the "internal" update, calls UpdateFollowerAI()
|
||||
virtual void UpdateFollowerAI(const uint32); // used when it's needed to add code in update (abilities, scripted events, etc)
|
||||
|
||||
void StartFollow(Player* pPlayer, uint32 uiFactionForFollower = 0, const Quest* pQuest = NULL);
|
||||
|
||||
void SetFollowPaused(bool bPaused); // if special event require follow mode to hold/resume during the follow
|
||||
void SetFollowComplete(bool bWithEndEvent = false);
|
||||
|
||||
bool HasFollowState(uint32 uiFollowState) { return (m_uiFollowState & uiFollowState); }
|
||||
|
||||
protected:
|
||||
Player* GetLeaderForFollower();
|
||||
|
||||
private:
|
||||
void AddFollowState(uint32 uiFollowState) { m_uiFollowState |= uiFollowState; }
|
||||
void RemoveFollowState(uint32 uiFollowState) { m_uiFollowState &= ~uiFollowState; }
|
||||
|
||||
bool AssistPlayerInCombat(Unit* pWho);
|
||||
|
||||
ObjectGuid m_leaderGuid;
|
||||
uint32 m_uiUpdateFollowTimer;
|
||||
uint32 m_uiFollowState;
|
||||
|
||||
const Quest* m_pQuestForFollow; // normally we have a quest
|
||||
};
|
||||
|
||||
#endif
|
||||
274
src/modules/SD2/base/guard_ai.cpp
Normal file
274
src/modules/SD2/base/guard_ai.cpp
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Guard_AI
|
||||
SD%Complete: 90
|
||||
SDComment:
|
||||
SDCategory: Guards
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "guard_ai.h"
|
||||
|
||||
// This script is for use within every single guard to save coding time
|
||||
|
||||
guardAI::guardAI(Creature* pCreature) : ScriptedAI(pCreature),
|
||||
m_uiGlobalCooldown(0),
|
||||
m_uiBuffTimer(0)
|
||||
{}
|
||||
|
||||
void guardAI::Reset()
|
||||
{
|
||||
m_uiGlobalCooldown = 0;
|
||||
m_uiBuffTimer = 0; // Rebuff as soon as we can
|
||||
}
|
||||
|
||||
void guardAI::Aggro(Unit* pWho)
|
||||
{
|
||||
if (m_creature->GetEntry() == NPC_CENARION_INFANTRY)
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
DoScriptText(SAY_GUARD_SIL_AGGRO1, m_creature, pWho);
|
||||
break;
|
||||
case 1:
|
||||
DoScriptText(SAY_GUARD_SIL_AGGRO2, m_creature, pWho);
|
||||
break;
|
||||
case 2:
|
||||
DoScriptText(SAY_GUARD_SIL_AGGRO3, m_creature, pWho);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (const SpellEntry* pSpellInfo = m_creature->ReachWithSpellAttack(pWho))
|
||||
{
|
||||
DoCastSpell(pWho, pSpellInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void guardAI::JustDied(Unit* pKiller)
|
||||
{
|
||||
// Send Zone Under Attack message to the LocalDefense and WorldDefense Channels
|
||||
if (Player* pPlayer = pKiller->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
{
|
||||
m_creature->SendZoneUnderAttackMessage(pPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
void guardAI::UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
// Always decrease our global cooldown first
|
||||
if (m_uiGlobalCooldown > uiDiff)
|
||||
{
|
||||
m_uiGlobalCooldown -= uiDiff;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiGlobalCooldown = 0;
|
||||
}
|
||||
|
||||
// Buff timer (only buff when we are alive and not in combat
|
||||
if (m_creature->IsAlive() && !m_creature->IsInCombat())
|
||||
{
|
||||
if (m_uiBuffTimer < uiDiff)
|
||||
{
|
||||
// Find a spell that targets friendly and applies an aura (these are generally buffs)
|
||||
const SpellEntry* pSpellInfo = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA);
|
||||
|
||||
if (pSpellInfo && !m_uiGlobalCooldown)
|
||||
{
|
||||
// Cast the buff spell
|
||||
DoCastSpell(m_creature, pSpellInfo);
|
||||
|
||||
// Set our global cooldown
|
||||
m_uiGlobalCooldown = GENERIC_CREATURE_COOLDOWN;
|
||||
|
||||
// Set our timer to 10 minutes before rebuff
|
||||
m_uiBuffTimer = 600000;
|
||||
} // Try again in 30 seconds
|
||||
else
|
||||
{
|
||||
m_uiBuffTimer = 30000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiBuffTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure our attack is ready and we arn't currently casting
|
||||
if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
|
||||
{
|
||||
// If we are within range melee the target
|
||||
if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim()))
|
||||
{
|
||||
bool bHealing = false;
|
||||
const SpellEntry* pSpellInfo = NULL;
|
||||
|
||||
// Select a healing spell if less than 30% hp
|
||||
if (m_creature->GetHealthPercent() < 30.0f)
|
||||
{
|
||||
pSpellInfo = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
|
||||
}
|
||||
|
||||
// No healing spell available, select a hostile spell
|
||||
if (pSpellInfo)
|
||||
{
|
||||
bHealing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSpellInfo = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE);
|
||||
}
|
||||
|
||||
// 20% chance to replace our white hit with a spell
|
||||
if (pSpellInfo && !urand(0, 4) && !m_uiGlobalCooldown)
|
||||
{
|
||||
// Cast the spell
|
||||
if (bHealing)
|
||||
{
|
||||
DoCastSpell(m_creature, pSpellInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoCastSpell(m_creature->getVictim(), pSpellInfo);
|
||||
}
|
||||
|
||||
// Set our global cooldown
|
||||
m_uiGlobalCooldown = GENERIC_CREATURE_COOLDOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||
}
|
||||
|
||||
m_creature->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only run this code if we arn't already casting
|
||||
if (!m_creature->IsNonMeleeSpellCasted(false))
|
||||
{
|
||||
bool bHealing = false;
|
||||
const SpellEntry* pSpellInfo = NULL;
|
||||
|
||||
// Select a healing spell if less than 30% hp ONLY 33% of the time
|
||||
if (m_creature->GetHealthPercent() < 30.0f && !urand(0, 2))
|
||||
{
|
||||
pSpellInfo = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
|
||||
}
|
||||
|
||||
// No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
|
||||
if (pSpellInfo)
|
||||
{
|
||||
bHealing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSpellInfo = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, ATTACK_DISTANCE, 0, SELECT_EFFECT_DONTCARE);
|
||||
}
|
||||
|
||||
// Found a spell, check if we arn't on cooldown
|
||||
if (pSpellInfo && !m_uiGlobalCooldown)
|
||||
{
|
||||
// If we are currently moving stop us and set the movement generator
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
|
||||
{
|
||||
m_creature->GetMotionMaster()->Clear(false);
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
|
||||
// Cast spell
|
||||
if (bHealing)
|
||||
{
|
||||
DoCastSpell(m_creature, pSpellInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoCastSpell(m_creature->getVictim(), pSpellInfo);
|
||||
}
|
||||
|
||||
// Set our global cooldown
|
||||
m_uiGlobalCooldown = GENERIC_CREATURE_COOLDOWN;
|
||||
} // If no spells available and we arn't moving run to target
|
||||
else if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
|
||||
{
|
||||
// Cancel our current spell and then mutate new movement generator
|
||||
m_creature->InterruptNonMeleeSpells(false);
|
||||
m_creature->GetMotionMaster()->Clear(false);
|
||||
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void guardAI::DoReplyToTextEmote(uint32 uiTextEmote)
|
||||
{
|
||||
switch (uiTextEmote)
|
||||
{
|
||||
case TEXTEMOTE_KISS:
|
||||
m_creature->HandleEmote(EMOTE_ONESHOT_BOW);
|
||||
break;
|
||||
case TEXTEMOTE_WAVE:
|
||||
m_creature->HandleEmote(EMOTE_ONESHOT_WAVE);
|
||||
break;
|
||||
case TEXTEMOTE_SALUTE:
|
||||
m_creature->HandleEmote(EMOTE_ONESHOT_SALUTE);
|
||||
break;
|
||||
case TEXTEMOTE_SHY:
|
||||
m_creature->HandleEmote(EMOTE_ONESHOT_FLEX);
|
||||
break;
|
||||
case TEXTEMOTE_RUDE:
|
||||
case TEXTEMOTE_CHICKEN:
|
||||
m_creature->HandleEmote(EMOTE_ONESHOT_POINT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void guardAI_orgrimmar::ReceiveEmote(Player* pPlayer, uint32 uiTextEmote)
|
||||
{
|
||||
if (pPlayer->GetTeam() == HORDE)
|
||||
{
|
||||
DoReplyToTextEmote(uiTextEmote);
|
||||
}
|
||||
}
|
||||
|
||||
void guardAI_stormwind::ReceiveEmote(Player* pPlayer, uint32 uiTextEmote)
|
||||
{
|
||||
if (pPlayer->GetTeam() == ALLIANCE)
|
||||
{
|
||||
DoReplyToTextEmote(uiTextEmote);
|
||||
}
|
||||
}
|
||||
83
src/modules/SD2/base/guard_ai.h
Normal file
83
src/modules/SD2/base/guard_ai.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_GUARDAI_H
|
||||
#define SC_GUARDAI_H
|
||||
|
||||
enum
|
||||
{
|
||||
GENERIC_CREATURE_COOLDOWN = 5000,
|
||||
|
||||
SAY_GUARD_SIL_AGGRO1 = -1000198,
|
||||
SAY_GUARD_SIL_AGGRO2 = -1000199,
|
||||
SAY_GUARD_SIL_AGGRO3 = -1000200,
|
||||
|
||||
NPC_CENARION_INFANTRY = 15184
|
||||
};
|
||||
|
||||
enum eShattrathGuard
|
||||
{
|
||||
SPELL_BANISHED_SHATTRATH_A = 36642,
|
||||
SPELL_BANISHED_SHATTRATH_S = 36671,
|
||||
SPELL_BANISH_TELEPORT = 36643,
|
||||
SPELL_EXILE = 39533
|
||||
};
|
||||
|
||||
struct guardAI : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
explicit guardAI(Creature* pCreature);
|
||||
~guardAI() {}
|
||||
|
||||
uint32 m_uiGlobalCooldown; // This variable acts like the global cooldown that players have (1.5 seconds)
|
||||
uint32 m_uiBuffTimer; // This variable keeps track of buffs
|
||||
|
||||
void Reset() override;
|
||||
|
||||
void Aggro(Unit* pWho) override;
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override;
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override;
|
||||
|
||||
// Commonly used for guards in main cities
|
||||
void DoReplyToTextEmote(uint32 uiTextEmote);
|
||||
};
|
||||
|
||||
struct guardAI_orgrimmar : public guardAI
|
||||
{
|
||||
guardAI_orgrimmar(Creature* pCreature) : guardAI(pCreature) {}
|
||||
|
||||
void ReceiveEmote(Player* pPlayer, uint32 uiTextEmote) override;
|
||||
};
|
||||
|
||||
struct guardAI_stormwind : public guardAI
|
||||
{
|
||||
guardAI_stormwind(Creature* pCreature) : guardAI(pCreature) {}
|
||||
|
||||
void ReceiveEmote(Player* pPlayer, uint32 uiTextEmote) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
171
src/modules/SD2/base/pet_ai.cpp
Normal file
171
src/modules/SD2/base/pet_ai.cpp
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: ScriptedPetAI
|
||||
SD%Complete: 50
|
||||
SDComment: Intended to be used with Guardian/Protector/Minipets. Little/no control over when pet enter/leave combat. Must be considered to be under development.
|
||||
SDCategory: Npc
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "pet_ai.h"
|
||||
|
||||
ScriptedPetAI::ScriptedPetAI(Creature* pCreature) : CreatureAI(pCreature)
|
||||
{}
|
||||
|
||||
bool ScriptedPetAI::IsVisible(Unit* pWho) const
|
||||
{
|
||||
return pWho && m_creature->IsWithinDist(pWho, VISIBLE_RANGE)
|
||||
&& pWho->IsVisibleForOrDetect(m_creature, m_creature, true);
|
||||
}
|
||||
|
||||
void ScriptedPetAI::MoveInLineOfSight(Unit* pWho)
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_creature->GetCharmInfo() || !m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->CanInitiateAttack() && pWho->IsTargetableForAttack() &&
|
||||
m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->IsWithinDistInMap(pWho, m_creature->GetAttackDistance(pWho)) && m_creature->IsWithinLOSInMap(pWho))
|
||||
{
|
||||
pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(pWho);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedPetAI::AttackStart(Unit* pWho)
|
||||
{
|
||||
if (pWho && m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedPetAI::AttackedBy(Unit* pAttacker)
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->GetCharmInfo() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
|
||||
m_creature->CanReachWithMeleeAttack(pAttacker))
|
||||
{
|
||||
AttackStart(pAttacker);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedPetAI::ResetPetCombat()
|
||||
{
|
||||
Unit* pOwner = m_creature->GetCharmerOrOwner();
|
||||
|
||||
if (pOwner && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveFollow(pOwner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_creature->GetMotionMaster()->Clear(false);
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
|
||||
m_creature->AttackStop();
|
||||
|
||||
debug_log("SD2: ScriptedPetAI reset pet combat and stop attack.");
|
||||
Reset();
|
||||
}
|
||||
|
||||
void ScriptedPetAI::UpdatePetAI(const uint32 /*uiDiff*/)
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void ScriptedPetAI::UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
if (!m_creature->IsAlive()) // should not be needed, IsAlive is checked in mangos before calling UpdateAI
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// UpdateAllies() is done in the generic PetAI in Mangos, but we can't do this from script side.
|
||||
// Unclear what side effects this has, but is something to be resolved from Mangos.
|
||||
|
||||
if (m_creature->getVictim()) // in combat
|
||||
{
|
||||
if (!m_creature->getVictim()->IsTargetableForAttack())
|
||||
{
|
||||
// target no longer valid for pet, so either attack stops or new target are selected
|
||||
// doesn't normally reach this, because of how petAi is designed in Mangos. CombatStop
|
||||
// are called before this update diff, and then pet will already have no victim.
|
||||
ResetPetCombat();
|
||||
return;
|
||||
}
|
||||
|
||||
// update when in combat
|
||||
UpdatePetAI(uiDiff);
|
||||
}
|
||||
else if (m_creature->GetCharmInfo())
|
||||
{
|
||||
Unit* pOwner = m_creature->GetCharmerOrOwner();
|
||||
|
||||
if (!pOwner)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pOwner->IsInCombat() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
// Not correct in all cases.
|
||||
// When mob initiate attack by spell, pet should not start attack before spell landed.
|
||||
AttackStart(pOwner->getAttackerForHelper());
|
||||
}
|
||||
else if (m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
|
||||
{
|
||||
// not following, so start follow
|
||||
if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW))
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveFollow(pOwner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
|
||||
// update when not in combat
|
||||
UpdatePetOOCAI(uiDiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
src/modules/SD2/base/pet_ai.h
Normal file
60
src/modules/SD2/base/pet_ai.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_PET_H
|
||||
#define SC_PET_H
|
||||
|
||||
// Using CreatureAI for now. Might change later and use PetAI (need to export for dll first)
|
||||
class ScriptedPetAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit ScriptedPetAI(Creature* pCreature);
|
||||
~ScriptedPetAI() {}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*pWho*/) override;
|
||||
|
||||
void AttackStart(Unit* /*pWho*/) override;
|
||||
|
||||
void AttackedBy(Unit* /*pAttacker*/) override;
|
||||
|
||||
bool IsVisible(Unit* /*pWho*/) const override;
|
||||
|
||||
void KilledUnit(Unit* /*pVictim*/) override {}
|
||||
|
||||
void OwnerKilledUnit(Unit* /*pVictim*/) override {}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override;
|
||||
|
||||
virtual void Reset() {}
|
||||
|
||||
virtual void UpdatePetAI(const uint32 uiDiff); // while in combat
|
||||
|
||||
virtual void UpdatePetOOCAI(const uint32 /*uiDiff*/) {} // when not in combat
|
||||
|
||||
protected:
|
||||
void ResetPetCombat();
|
||||
};
|
||||
|
||||
#endif
|
||||
38
src/modules/SD2/config-sd2.h
Normal file
38
src/modules/SD2/config-sd2.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_CONFIG_H
|
||||
#define SC_CONFIG_H
|
||||
|
||||
#include "Platform/CompilerDefs.h"
|
||||
//#include "revision.h"
|
||||
#include "sd2_revision_nr.h"
|
||||
#include "SystemConfig.h"
|
||||
|
||||
#ifndef SCRIPTDEV2_VERSION
|
||||
#define SCRIPTDEV2_VERSION "Revision [" SD2_REVISION_NR "] (" REVISION_ID ") " REVISION_DATE " " REVISION_TIME
|
||||
#endif
|
||||
|
||||
#endif
|
||||
344
src/modules/SD2/docs/License.md
Normal file
344
src/modules/SD2/docs/License.md
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
==========================
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (c) 1989, 1981 [Free Software Foundation, Inc.][1]
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
## Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public License is intended to
|
||||
guarantee your freedom to share and change free software -- to make sure the
|
||||
software is free for all its users. This General Public License applies to most
|
||||
of the Free Software Foundation's software and to any other program whose
|
||||
authors commit to using it [^1]. You can apply it to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom to
|
||||
distribute copies of free software (and charge for this service if you wish),
|
||||
that you receive source code or can get it if you want it, that you can change
|
||||
the software or use pieces of it in new free programs; and that you know you
|
||||
can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to deny
|
||||
you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of the
|
||||
software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that you have. You must make
|
||||
sure that they, too, receive or can get the source code. And you must show them
|
||||
these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2) offer
|
||||
you this license which gives you legal permission to copy, distribute and/or
|
||||
modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If the
|
||||
software is modified by someone else and passed on, we want its recipients to
|
||||
know that what they have is not the original, so that any problems introduced
|
||||
by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We wish
|
||||
to avoid the danger that redistributors of a free program will individually
|
||||
obtain patent licenses, in effect making the program proprietary. To prevent
|
||||
this, we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
### 0.
|
||||
|
||||
This License applies to any program or other work which contains a notice
|
||||
placed by the copyright holder saying it may be distributed under the terms of
|
||||
this General Public License. The "Program", below, refers to any such program
|
||||
or work, and a "work based on the Program" means either the Program or any
|
||||
derivative work under copyright law: that is to say, a work containing the
|
||||
Program or a portion of it, either verbatim or with modifications and/or
|
||||
translated into another language. (Hereinafter, translation is included
|
||||
without limitation in the term "modification".) Each licensee is addressed
|
||||
as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not covered by
|
||||
this License; they are outside its scope. The act of running the Program is not
|
||||
restricted, and the output from the Program is covered only if its contents
|
||||
constitute a work based on the Program (independent of having been made by
|
||||
running the Program). Whether that is true depends on what the Program does.
|
||||
|
||||
### 1.
|
||||
|
||||
You may copy and distribute verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and appropriately
|
||||
publish on each copy an appropriate copyright notice and disclaimer of warranty;
|
||||
keep intact all the notices that refer to this License and to the absence of
|
||||
any warranty; and give any other recipients of the Program a copy of this
|
||||
License along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you may
|
||||
at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
### 2.
|
||||
|
||||
You may modify your copy or copies of the Program or any portion of it, thus
|
||||
forming a work based on the Program, and copy and distribute such modifications
|
||||
or work under the terms of Section 1 above, provided that you also meet all of
|
||||
these conditions:
|
||||
|
||||
* **a)** You must cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change.
|
||||
* **b)** You must cause any work that you distribute or publish, that in whole
|
||||
or in part contains or is derived from the Program or any part thereof, to be
|
||||
licensed as a whole at no charge to all third parties under the terms of this
|
||||
License.
|
||||
* **c)** If the modified program normally reads commands interactively when run,
|
||||
you must cause it, when started running for such interactive use in the most
|
||||
ordinary way, to print or display an announcement including an appropriate
|
||||
copyright notice and a notice that there is no warranty (or else, saying that
|
||||
you provide a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this License.
|
||||
(Exception: if the Program itself is interactive but does not normally print
|
||||
such an announcement, your work based on the Program is not required to print
|
||||
an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Program, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License,
|
||||
and its terms, do not apply to those sections when you distribute them as
|
||||
separate works. But when you distribute the same sections as part of a whole
|
||||
which is a work based on the Program, the distribution of the whole must be on
|
||||
the terms of this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise the
|
||||
right to control the distribution of derivative or collective works based on
|
||||
the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program with the
|
||||
Program (or with a work based on the Program) on a volume of a storage or
|
||||
distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
### 3.
|
||||
|
||||
You may copy and distribute the Program (or a work based on it, under Section 2)
|
||||
in object code or executable form under the terms of Sections 1 and 2 above
|
||||
provided that you also do one of the following:
|
||||
|
||||
* **a)** Accompany it with the complete corresponding machine-readable source
|
||||
code, which must be distributed under the terms of Sections 1 and 2 above on
|
||||
a medium customarily used for software interchange; or,
|
||||
* **b)** Accompany it with a written offer, valid for at least three years, to
|
||||
give any third party, for a charge no more than your cost of physically
|
||||
performing source distribution, a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of Sections 1
|
||||
and 2 above on a medium customarily used for software interchange; or,
|
||||
* **c)** Accompany it with the information you received as to the offer to
|
||||
distribute corresponding source code. (This alternative is allowed only for
|
||||
noncommercial distribution and only if you received the program in object code
|
||||
or executable form with such an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable work, complete source code means all
|
||||
the source code for all modules it contains, plus any associated interface
|
||||
definition files, plus the scripts used to control compilation and installation
|
||||
of the executable. However, as a special exception, the source code distributed
|
||||
need not include anything that is normally distributed (in either source or
|
||||
binary form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component itself
|
||||
accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the source
|
||||
code from the same place counts as distribution of the source code, even though
|
||||
third parties are not compelled to copy the source along with the object code.
|
||||
|
||||
### 4.
|
||||
|
||||
You may not copy, modify, sublicense, or distribute the Program except as
|
||||
expressly provided under this License. Any attempt otherwise to copy, modify,
|
||||
sublicense or distribute the Program is void, and will automatically terminate
|
||||
your rights under this License. However, parties who have received copies, or
|
||||
rights, from you under this License will not have their licenses terminated so
|
||||
long as such parties remain in full compliance.
|
||||
|
||||
### 5.
|
||||
|
||||
You are not required to accept this License, since you have not signed it.
|
||||
However, nothing else grants you permission to modify or distribute the Program
|
||||
or its derivative works. These actions are prohibited by law if you do not
|
||||
accept this License. Therefore, by modifying or distributing the Program (or any
|
||||
work based on the Program), you indicate your acceptance of this License to do
|
||||
so, and all its terms and conditions for copying, distributing or modifying the
|
||||
Program or works based on it.
|
||||
|
||||
### 6.
|
||||
|
||||
Each time you redistribute the Program (or any work based on the Program), the
|
||||
recipient automatically receives a license from the original licensor to copy,
|
||||
distribute or modify the Program subject to these terms and conditions. You may
|
||||
not impose any further restrictions on the recipients' exercise of the rights
|
||||
granted herein. You are not responsible for enforcing compliance by third
|
||||
parties to this License.
|
||||
|
||||
### 7.
|
||||
|
||||
If, as a consequence of a court judgment or allegation of patent infringement
|
||||
or for any other reason (not limited to patent issues), conditions are imposed
|
||||
on you (whether by court order, agreement or otherwise) that contradict the
|
||||
conditions of this License, they do not excuse you from the conditions of this
|
||||
License. If you cannot distribute so as to satisfy simultaneously your obligations
|
||||
under this License and any other pertinent obligations, then as a consequence
|
||||
you may not distribute the Program at all. For example, if a patent license
|
||||
would not permit royalty-free redistribution of the Program by all those who
|
||||
receive copies directly or indirectly through you, then the only way you could
|
||||
satisfy both it and this License would be to refrain entirely from distribution
|
||||
of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply and the
|
||||
section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents or
|
||||
other property right claims or to contest validity of any such claims; this
|
||||
section has the sole purpose of protecting the integrity of the free software
|
||||
distribution system, which is implemented by public license practices. Many
|
||||
people have made generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that system; it is
|
||||
up to the author/donor to decide if he or she is willing to distribute software
|
||||
through any other system and a licensee cannot impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
### 8.
|
||||
|
||||
If the distribution and/or use of the Program is restricted in certain countries
|
||||
either by patents or by copyrighted interfaces, the original copyright holder
|
||||
who places the Program under this License may add an explicit geographical
|
||||
distribution limitation excluding those countries, so that distribution is
|
||||
permitted only in or among countries not thus excluded. In such case, this
|
||||
License incorporates the limitation as if written in the body of this License.
|
||||
|
||||
### 9.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of the
|
||||
General Public License from time to time. Such new versions will be similar in
|
||||
spirit to the present version, but may differ in detail to address new problems
|
||||
or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies
|
||||
a version number of this License which applies to it and "any later version",
|
||||
you have the option of following the terms and conditions either of that version
|
||||
or of any later version published by the Free Software Foundation. If the Program
|
||||
does not specify a version number of this License, you may choose any version
|
||||
ever published by the Free Software Foundation.
|
||||
|
||||
### 10.
|
||||
|
||||
If you wish to incorporate parts of the Program into other free programs whose
|
||||
distribution conditions are different, write to the author to ask for
|
||||
permission. For software which is copyrighted by the Free Software Foundation,
|
||||
write to the Free Software Foundation; we sometimes make exceptions for this.
|
||||
Our decision will be guided by the two goals of preserving the free status of
|
||||
all derivatives of our free software and of promoting the sharing and reuse of
|
||||
software generally.
|
||||
|
||||
## NO WARRANTY
|
||||
|
||||
### 11.
|
||||
|
||||
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE
|
||||
PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
|
||||
PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
|
||||
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
### 12.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
|
||||
COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
|
||||
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
|
||||
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY
|
||||
TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||
THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
## END OF TERMS AND CONDITIONS
|
||||
|
||||
### How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest possible
|
||||
use to the public, the best way to achieve this is to make it free software
|
||||
which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach
|
||||
them to the start of each source file to most effectively convey the exclusion
|
||||
of warranty; and each file should have at least the "copyright" line and a
|
||||
pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this when it
|
||||
starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may be
|
||||
called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary. Here
|
||||
is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may consider
|
||||
it more useful to permit linking proprietary applications with the library. If
|
||||
this is what you want to do, use the GNU Lesser General Public License instead
|
||||
of this License.
|
||||
|
||||
[^1]: Some other Free Software Foundation software is covered by the GNU Lesser
|
||||
General Public License instead.
|
||||
|
||||
[1]: http://fsf.org/ "Free Software Foundation, Inc."
|
||||
[2]: http://www.gnu.org/licenses/ "Licenses - GNU Project"
|
||||
257
src/modules/SD2/docs/SQL_guide.md
Normal file
257
src/modules/SD2/docs/SQL_guide.md
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
Introduction to Database content for SD2
|
||||
================================================
|
||||
|
||||
This guide is intended to help people
|
||||
|
||||
* to understand which information of the database is used with SD2
|
||||
* who want to contribute their patches as complete as possible
|
||||
|
||||
All SQL-related files are located in the ScriptDev2/SQL and subsequent directories.
|
||||
|
||||
SQL-Files
|
||||
---------
|
||||
|
||||
Files that contain full SD2-Database content
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For a script we usually have to take care of these files:
|
||||
|
||||
* mangos_scriptname_full.sql
|
||||
+
|
||||
This file is applied to the world database (default: mangos), and contains the script names
|
||||
+
|
||||
* scriptdev2_script_full.sql
|
||||
+
|
||||
This file is applied to the sd2 database (default: scriptdev2), and contains texts, gossip-items and waypoints
|
||||
|
||||
Patchfiles for incremental Updates
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Patches for the databases are stored in the files:
|
||||
|
||||
* Updates/rXXXX_mangos.sql
|
||||
+
|
||||
This file contains the changes that should be done with the patch to the world-database
|
||||
+
|
||||
* Updates/rXXXX_scriptdev2.sql
|
||||
+
|
||||
This file contains the changes that should be done with the patch to the scriptdev2-database
|
||||
|
||||
World-Database
|
||||
--------------
|
||||
|
||||
ScriptNames of NPCs:
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If we need to assign a ScriptName to a NPC (GameObject-Scripts are similar) the statement is:
|
||||
|
||||
-----------
|
||||
UPDATE creature_template SET ScriptName='npc_and_his_name' WHERE entry=XYZ;
|
||||
-----------
|
||||
or
|
||||
-----------
|
||||
UPDATE creature_template SET ScriptName='npc_something_identifying' WHERE entry IN (XYZ, ZYX);
|
||||
-----------
|
||||
|
||||
'Remark:' For creatures with many difficulty entries, only the one for normal difficulty needs the ScriptName.
|
||||
|
||||
ScriptNames for scripted_areatrigger:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For Areatriggers (or scripted_event) we usally cannot use UPDATE, hence we need to DELETE possible old entries first:
|
||||
|
||||
-----------
|
||||
DELETE FROM scripted_areatrigger WHERE entry=XYZ;
|
||||
INSERT INTO scripted_areatrigger VALUES (XYZ, at_some_place);
|
||||
-----------
|
||||
|
||||
ScriptDev2-Database
|
||||
-------------------
|
||||
|
||||
entry-Format for texts and for gossip-texts:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The to be used entry is a combination of the number depending on the map and a counter.
|
||||
|
||||
* This is for texts: -1<MapId><three-digit-counter>
|
||||
* For gossip-texts: -3<MapId><three-digit-counter>
|
||||
+
|
||||
where <MapId> is the ID of the map for instances, or 000 for all other maps.
|
||||
|
||||
Example: Text on WorldMap
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Let's say we want to add a new text to a NPC on Kalimdor (no instance),
|
||||
then we need to look which is the last text entry of the format -1000XYZ
|
||||
(this one can be found in scriptdev2_script_full.sql).
|
||||
|
||||
On the moment where I write this guide this is:
|
||||
|
||||
----------
|
||||
(-1000589,'Kroshius live? Kroshius crush!',0,1,0,0,'SAY_KROSHIUS_REVIVE');
|
||||
----------
|
||||
|
||||
so our first text entry will be -1000590.
|
||||
|
||||
Example: Gossip-Item in Instance
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Let's say we want to add a new gossip item to a NPC in Culling of Stratholme, this map has the ID 595.
|
||||
At this moment there is already some gossip_text, and the last one is
|
||||
|
||||
------------
|
||||
(-3595005,'So how does the Infinite Dragonflight plan to interfere?','chromie GOSSIP_ITEM_INN_3');
|
||||
------------
|
||||
|
||||
so our first gossip-text entry will be -3595006.
|
||||
|
||||
Format for texts
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The format is `(entry,content_default,sound,type,language,emote,comment)` with these meanings:
|
||||
|
||||
entry:: should now be clear ;)
|
||||
content_default:: is the text (in english) enclosed with '. +
|
||||
There are a few placeholders that can be used:
|
||||
+
|
||||
[horizontal]
|
||||
%s;; self, is the name of the Unit saying the text +
|
||||
The $-placeholders work only if you use DoScriptText with a 'target'.
|
||||
$N, $n;; the [N, n]ame of the target
|
||||
$C, $c;; the [C, c]lass of the target
|
||||
$R, $r;; the [R, r]ace of the target
|
||||
$GA:B; ;; if the target is male then A else B is displayed, Example:
|
||||
+
|
||||
--------------------------------
|
||||
'Time to teach you a lesson in manners, little $Gboy:girl;!'
|
||||
--------------------------------
|
||||
+
|
||||
Remember to escape [red]#\'# with [red]#\'#, Example:
|
||||
+
|
||||
--------------------------------
|
||||
'That \'s my favourite chocolate bar'.
|
||||
--------------------------------
|
||||
sound:: is the sound ID that shall be played on saying, they are stored in SoundEntries.dbc
|
||||
+
|
||||
[quote, Ntsc]
|
||||
_____________________________
|
||||
Sound Ids are stored within the SoundEntries.dbc file. Within that dbc file you will find a reference to the actual file that is played. We cannot help you with reading these files so please do not ask how.
|
||||
_____________________________
|
||||
+
|
||||
type:: is the type of the text, there are these possibilities:
|
||||
+
|
||||
-------------
|
||||
0 CHAT_TYPE_SAY - 'white' text
|
||||
1 CHAT_TYPE_YELL - 'red' text
|
||||
2 CHAT_TYPE_TEXT_EMOTE - 'yellow' emote-text (no <Name>... )
|
||||
3 CHAT_TYPE_BOSS_EMOTE - 'big yellow' emote-text displayed in the center of the screen
|
||||
4 CHAT_TYPE_WHISPER - whisper, needs a target
|
||||
5 CHAT_TYPE_BOSS_WHISPER - whipser, needs a target
|
||||
6 CHAT_TYPE_ZONE_YELL - 'red' text, displayed to everyone in the zone
|
||||
--------------
|
||||
+
|
||||
language:: is the language of the text (like LANG_GNOMISH), see +enum Language+ in `game/SharedDefines.h` -- usually zero (LANG_UNIVERSAL)
|
||||
emote:: is the emote the npc shall perform on saying the text, can be found in +enum Emote+ in `game/SharedDefines.h`
|
||||
comment:: is a comment to this text, usually the used enum of the script, like SAY_KROSHIUS_REVIVE, if this enum is not identifying the npc, then the name of the npc is put before.
|
||||
|
||||
Format for gossip-texts
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The format for gossip texts is `(entry,content_default,comment)` +
|
||||
The fields have the same meaning as for script-texts.
|
||||
|
||||
Format for waypoints
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The format for waypoints is `(entry,pointid,location_x,location_y,location_z,waittime,point_comment)` with these meanings:
|
||||
|
||||
entry:: is the entry of the scripted NPC
|
||||
pointid:: is the ID of the point, usally starting with 01, and increasing
|
||||
location_*:: describes the position of the waypoint
|
||||
waittime:: is the time, the mob will wait after reaching _this_ waypoint, before he continues to go to the next
|
||||
point_comment:: is used to note if something special is happening at this point, like quest credit
|
||||
|
||||
|
||||
Creating the Patch
|
||||
------------------
|
||||
|
||||
There are different ways to get to a patch, I prefer this workflow:
|
||||
|
||||
For the scriptdev2 database (patch files):
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Open scriptdev2_script_full.txt +
|
||||
scroll to the right place for the needed SQL-statements, to note the entry. +
|
||||
(for texts depending on mapId, and to the last counter, for waypoints behind the last inserted waypoint)
|
||||
|
||||
Example for normal world text:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Assume the last entry in your map (here world-map) was:
|
||||
|
||||
--------------
|
||||
(-1000589,'Kroshius live? Kroshius crush!',0,1,0,0,'SAY_KROSHIUS_REVIVE');
|
||||
--------------
|
||||
|
||||
Now create a new file: Updates/r0000_scriptdev2.sql
|
||||
Add there:
|
||||
|
||||
-----------
|
||||
DELETE FROM script_texts WHERE entry=-1000590;
|
||||
INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES
|
||||
(-1000590,'My fancy aggro-text',0,1,0,0,'boss_hogger SAY_AGGRO');
|
||||
-----------
|
||||
or
|
||||
-----------
|
||||
DELETE FROM script_texts WHERE entry BETWEEN -1000592 AND -1000590;
|
||||
INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES
|
||||
(-1000590,'My fancy aggro-text1',0,1,0,0,'boss_hogger SAY_AGGRO1'),
|
||||
(-1000591,'My fancy aggro-text2',0,1,0,0,'boss_hogger SAY_AGGRO2'),
|
||||
(-1000592,'My fancy aggro-text3',0,1,0,0,'boss_hogger SAY_AGGRO3');
|
||||
-----------
|
||||
|
||||
Hint: the INSERT statements can also be copied from the scriptdev2_script_full.sql
|
||||
|
||||
Example for waypoints:
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The required SQL code to add a waypoint is:
|
||||
|
||||
----------
|
||||
DELETE FROM script_waypoint WHERE entry=<MyNpcEntry>;
|
||||
INSERT INTO script_waypoint VALUES
|
||||
(<MyNpcEntry>, 1, 4013.51,6390.33, 29.970, 0, '<MyNPCName> - start escort'),
|
||||
(<MyNpcEntry>, 2, 4060.51,6400.33, 20.970, 0, '<MyNPCName> - finish escort');
|
||||
----------
|
||||
|
||||
When the Update file is done, append an additional empty line +
|
||||
And test these lines for correctness!
|
||||
|
||||
For the scriptdev2 database (full files):
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If everything works alright, and you finally intend to prepare the full-patch, copy the SQL-Code that is needed to the proper place in scriptdev2_script_full.sql,
|
||||
(for a new npc add an empty line), and change the semicolon to a comma:
|
||||
|
||||
Example for world text:
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
-----------
|
||||
(-1000589,'Kroshius live? Kroshius crush!',0,1,0,0,'SAY_KROSHIUS_REVIVE'),
|
||||
|
||||
(-1000590,'My fancy aggro-text',0,1,0,0,'boss_hogger SAY_AGGRO');
|
||||
-----------
|
||||
|
||||
The waypoints are added behind the last waypoint, after an empty line.
|
||||
|
||||
For the world database:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create a new file: Updates/r0000_mangos.sql +
|
||||
In this file put the needed statements for your ScriptNames, append an empty line, convert lineendings to Unix, and then test it for correctness.
|
||||
|
||||
If everything is alright, open mangos_scriptname_full.sql and go to the right place (this is usally sorted alphabetically by zone). +
|
||||
Insert the needed statement where it fits (usally again ordered alphabetically)
|
||||
|
||||
After this is done, Create a patch including the (untracked) files in Update/ +
|
||||
then you have all information in the created patch, and anyone who wants to test your patch just needs to apply the created files from Updates/
|
||||
31
src/modules/SD2/docs/Script_Layout.md
Normal file
31
src/modules/SD2/docs/Script_Layout.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
Script source code layout
|
||||
=========================
|
||||
In order to make it easier to find scripts, we have agreed on a fixed naming scheme
|
||||
for directories and scripts.
|
||||
|
||||
Directories
|
||||
-----------
|
||||
* **battlegrounds**: contains scripts used in the Alterac Valley, Arathi Basin and
|
||||
Warsong Gulch battlegrounds.
|
||||
* **eastern_kingdoms**: contains scripts for area triggers, creatures, dungeons,
|
||||
instances, etc. related to the Eastern Kingdoms continent. Instances located on
|
||||
Eastern Kingdoms are grouped in sub-directories by instance name.
|
||||
* **kalimdor**: contains scripts for area triggers, creatures, dungeons, instances,
|
||||
etc. related to the Kalimdor continent. Instances located on Kalimdor are grouped
|
||||
in sub-directories by instance name.
|
||||
* **world**: contains scripts which are used on every map, and not limited to one
|
||||
specific zone. This includes scripts for area triggers, game objects, items, and
|
||||
some creatures which can be found over the world. Also, scripts for spells are
|
||||
stored here.
|
||||
Contains scripts for anything that is not related to a specified zone.
|
||||
|
||||
Naming Conventions
|
||||
------------------
|
||||
Source files should be named `type_objectname.cpp` where
|
||||
|
||||
* *type* is replaced by the type of object,
|
||||
* and *objectname* is replaced by the name of the object, creature, item, or area
|
||||
that this script will be used by.
|
||||
|
||||
`AddSC` functions used for registering scripts to the server core should use the
|
||||
form of `void AddSC_filename(void);`.
|
||||
85
src/modules/SD2/docs/Text-tables.md
Normal file
85
src/modules/SD2/docs/Text-tables.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
Texts Documentation
|
||||
===================
|
||||
In order for scripts to have a centralized storage for texts, text tables have been
|
||||
added to the database. Any script can access and use texts from these tables.
|
||||
|
||||
An additional table is available for custom scripts.
|
||||
|
||||
For each table ranges of valid identifiers have been define
|
||||
|
||||
* entry `-1` to `-999999`: reserved EventAI in *mangos*,
|
||||
* entry `-1000000` to `-1999999`: script text entries,
|
||||
* entry `-2000000` to `-2999999`: text entries for custom scripts,
|
||||
* entry `-3000000` to `-3999999`: texts for scripted gossip texts.
|
||||
|
||||
Text entries not using identifiers from the defined ranges will result in startup
|
||||
errors.
|
||||
|
||||
Database structure
|
||||
------------------
|
||||
`custom_texts`, `gossip_texts`, and `script_texts` share an indentical table
|
||||
structure, thus making it very easy to add new text entries.
|
||||
|
||||
Field name | Description
|
||||
--------------- | --------------------------------------------------------------
|
||||
entry | A unique *negative* identifier to the text entry.
|
||||
content_default | The default text to be displayed in English.
|
||||
content_loc1 | Korean localization of `content_default`.
|
||||
content_loc2 | French localization of `content_default`.
|
||||
content_loc3 | German localization of `content_default`.
|
||||
content_loc4 | Chinese localization of `content_default`.
|
||||
content_loc5 | Taiwanese localization of `content_default`.
|
||||
content_loc6 | Spanish Spain localization of `content_default`.
|
||||
content_loc7 | Spanish Latin America localization of `content_default`.
|
||||
content_loc8 | Russian localization of `content_default`.
|
||||
sound | A sound from SoundEntries.dbc to be played.
|
||||
type | Type of text (Say/Yell/Text emote/Whisper/Boss whisper/zone yell).
|
||||
language | A text language from Languages.dbc
|
||||
emote | An emote from Emotes.dbc. Only source of text will play this emote (not target, if target are defined in DoScriptText)
|
||||
comment | This is a comment using the Creature ID of NPC using it.
|
||||
|
||||
*Note*: `sound`, `type`, `language` and `emote` exist only in the tables
|
||||
`script_texts` and `custom_texts`.
|
||||
|
||||
*Note*: Fields `content_loc1` to `content_loc8` are `NULL` values by default and
|
||||
are handled by separate localization projects.
|
||||
|
||||
Text Types (`type`)
|
||||
-------------------
|
||||
Below is the list of current text types that texts tables can handle.
|
||||
|
||||
ID | Internal name | Description
|
||||
-- | ---------------------- | ----------------------------------
|
||||
0 | CHAT_TYPE_SAY | Displayed as a Say (Speech Bubble).
|
||||
1 | CHAT_TYPE_YELL | Displayed as a Yell (Red Speech Bubble) and usually has a matching Sound ID.
|
||||
2 | CHAT_TYPE_TEXT_EMOTE | Displayed as a text emote in orange in the chat log.
|
||||
3 | CHAT_TYPE_BOSS_EMOTE | Displayed as a text emote in orange in the chat log (Used only for specific Bosses).
|
||||
4 | CHAT_TYPE_WHISPER | Displayed as a whisper to the player in the chat log.
|
||||
5 | CHAT_TYPE_BOSS_WHISPER | Displayed as a whisper to the player in the chat log (Used only for specific Bosses).
|
||||
6 | CHAT_TYPE_ZONE_YELL | Same as CHAT_TYPE_YELL but will display to all players in current zone.
|
||||
|
||||
Language Types (`language`)
|
||||
---------------------------
|
||||
This is the race language that the text is native to. Below is the list of
|
||||
current language types that are allowed.
|
||||
|
||||
ID | Internal Name | Description
|
||||
--- | ------------- | --------------------------------------------------------
|
||||
0 | UNIVERSAL | Understood by *all* races.
|
||||
1 | ORCISH | Understood *only* by Horde races.
|
||||
2 | DARNASSIAN | Understood *only* by the Night Elf race.
|
||||
3 | TAURAHE | Understood *only* by the Tauren race.
|
||||
6 | DWARVISH | Understood *only* by the Dwarf race.
|
||||
7 | COMMON | Understood *only* by Alliance races.
|
||||
8 | DEMONIC | Understood *only* by the Demon race (Not Implemented).
|
||||
9 | TITAN | This language was used by Sargeras to speak with other Titians (Not Implemented).
|
||||
10 | THALASSIAN | Understood *only* by the Blood Elf race.
|
||||
11 | DRACONIC | Understood *only* by the Dragon race.
|
||||
12 | KALIMAG | Text will display as Kalimag (not readable by players, language of all elementals)
|
||||
13 | GNOMISH | Understood *only* by the Gnome race.
|
||||
14 | TROLL | Understood *only* by the Troll race.
|
||||
33 | GUTTERSPEAK | Understood *only* by the Undead race.
|
||||
35 | DRAENEI | Understood *only* by the Draenai Race.
|
||||
36 | ZOMBIE | (not currently used?)
|
||||
37 | GNOMISH BINARY| Understood *only* by Alliance when drinking Binary Brew
|
||||
38 | GOBLIN BINARY | Understood *only* by Horde when drinking Binary Brew
|
||||
26
src/modules/SD2/include/precompiled.cpp
Normal file
26
src/modules/SD2/include/precompiled.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
42
src/modules/SD2/include/precompiled.h
Normal file
42
src/modules/SD2/include/precompiled.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_PRECOMPILED_H
|
||||
#define SC_PRECOMPILED_H
|
||||
|
||||
#include "../ScriptDevMgr.h"
|
||||
#include "Object.h"
|
||||
#include "Unit.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "GameObject.h"
|
||||
#include "sc_creature.h"
|
||||
#include "sc_gossip.h"
|
||||
#include "sc_grid_searchers.h"
|
||||
#include "sc_instance.h"
|
||||
#include "SpellAuras.h"
|
||||
|
||||
|
||||
#endif
|
||||
727
src/modules/SD2/include/sc_creature.cpp
Normal file
727
src/modules/SD2/include/sc_creature.cpp
Normal file
|
|
@ -0,0 +1,727 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "Item.h"
|
||||
#include "Spell.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
// Spell summary for ScriptedAI::SelectSpell
|
||||
struct TSpellSummary
|
||||
{
|
||||
uint8 Targets; // set of enum SelectTarget
|
||||
uint8 Effects; // set of enum SelectEffect
|
||||
}* SpellSummary;
|
||||
|
||||
ScriptedAI::ScriptedAI(Creature* pCreature) : CreatureAI(pCreature),
|
||||
m_uiEvadeCheckCooldown(2500)
|
||||
{}
|
||||
|
||||
/// This function shows if combat movement is enabled, overwrite for more info
|
||||
void ScriptedAI::GetAIInformation(ChatHandler& reader)
|
||||
{
|
||||
reader.PSendSysMessage("ScriptedAI, combat movement is %s", reader.GetOnOffStr(IsCombatMovement()));
|
||||
}
|
||||
|
||||
/// Return if the creature can "see" pWho
|
||||
bool ScriptedAI::IsVisible(Unit* pWho) const
|
||||
{
|
||||
if (!pWho)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_creature->IsWithinDist(pWho, VISIBLE_RANGE) && pWho->IsVisibleForOrDetect(m_creature, m_creature, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function triggers the creature attacking pWho, depending on conditions like:
|
||||
* - Can the creature start an attack?
|
||||
* - Is pWho hostile to the creature?
|
||||
* - Can the creature reach pWho?
|
||||
* - Is pWho in aggro-range?
|
||||
* If the creature can attack pWho, it will if it has no victim.
|
||||
* Inside dungeons, the creature will get into combat with pWho, even if it has already a victim
|
||||
*/
|
||||
void ScriptedAI::MoveInLineOfSight(Unit* pWho)
|
||||
{
|
||||
if (m_creature->CanInitiateAttack() && pWho->IsTargetableForAttack() &&
|
||||
m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_creature->IsWithinDistInMap(pWho, m_creature->GetAttackDistance(pWho)) && m_creature->IsWithinLOSInMap(pWho))
|
||||
{
|
||||
if (!m_creature->getVictim())
|
||||
{
|
||||
pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(pWho);
|
||||
}
|
||||
else if (m_creature->GetMap()->IsDungeon())
|
||||
{
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
m_creature->AddThreat(pWho);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the TargetGuid for the creature if required
|
||||
* Also it will handle the combat movement (chase movement), depending on SetCombatMovement(bool)
|
||||
*/
|
||||
void ScriptedAI::AttackStart(Unit* pWho)
|
||||
{
|
||||
if (!m_creature->CanAttackByItself())
|
||||
return;
|
||||
|
||||
if (pWho && m_creature->Attack(pWho, true)) // The Attack function also uses basic checks if pWho can be attacked
|
||||
{
|
||||
m_creature->AddThreat(pWho);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
HandleMovementOnAttackStart(pWho);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function only calls Aggro, which is to be used for scripting purposes
|
||||
*/
|
||||
void ScriptedAI::EnterCombat(Unit* pEnemy)
|
||||
{
|
||||
if (pEnemy)
|
||||
{
|
||||
Aggro(pEnemy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main update function, by default let the creature behave as expected by a mob (threat management and melee dmg)
|
||||
* Always handle here threat-management with m_creature->SelectHostileTarget()
|
||||
* Handle (if required) melee attack with DoMeleeAttackIfReady()
|
||||
* This is usally overwritten to support timers for ie spells
|
||||
*/
|
||||
void ScriptedAI::UpdateAI(const uint32 /*uiDiff*/)
|
||||
{
|
||||
// Check if we have a current target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
Unit* victim = m_creature->getVictim();
|
||||
|
||||
const SpellEntry* potentialSpell = m_creature->ReachWithSpellAttack(victim);
|
||||
if (potentialSpell)
|
||||
m_creature->CastSpell(victim, potentialSpell->Id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function cleans up the combat state if the creature evades
|
||||
* It will:
|
||||
* - Drop Auras
|
||||
* - Drop all threat
|
||||
* - Stop combat
|
||||
* - Move the creature home
|
||||
* - Clear tagging for loot
|
||||
* - call Reset()
|
||||
*/
|
||||
void ScriptedAI::EnterEvadeMode()
|
||||
{
|
||||
m_creature->RemoveAllAurasOnEvade();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(true);
|
||||
|
||||
if (m_creature->IsAlive())
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
/// This function calls Reset() to reset variables as expected
|
||||
void ScriptedAI::JustRespawned()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void ScriptedAI::DoStartMovement(Unit* pVictim, float fDistance, float fAngle)
|
||||
{
|
||||
if (pVictim)
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveChase(pVictim, fDistance, fAngle);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedAI::DoStartNoMovement(Unit* pVictim)
|
||||
{
|
||||
if (!pVictim)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
m_creature->StopMoving();
|
||||
}
|
||||
|
||||
void ScriptedAI::DoStopAttack()
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
{
|
||||
m_creature->AttackStop();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedAI::DoCast(Unit* pTarget, uint32 uiSpellId, bool bTriggered)
|
||||
{
|
||||
if (m_creature->IsNonMeleeSpellCasted(false) && !bTriggered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_creature->CastSpell(pTarget, uiSpellId, bTriggered);
|
||||
}
|
||||
|
||||
void ScriptedAI::DoCastSpell(Unit* pTarget, SpellEntry const* pSpellInfo, bool bTriggered)
|
||||
{
|
||||
if (m_creature->IsNonMeleeSpellCasted(false) && !bTriggered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_creature->CastSpell(pTarget, pSpellInfo, bTriggered);
|
||||
}
|
||||
|
||||
void ScriptedAI::DoPlaySoundToSet(WorldObject* pSource, uint32 uiSoundId)
|
||||
{
|
||||
if (!pSource)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetSoundEntriesStore()->LookupEntry(uiSoundId))
|
||||
{
|
||||
script_error_log("Invalid soundId %u used in DoPlaySoundToSet (Source: TypeId %u, GUID %u)", uiSoundId, pSource->GetTypeId(), pSource->GetGUIDLow());
|
||||
return;
|
||||
}
|
||||
|
||||
pSource->PlayDirectSound(uiSoundId);
|
||||
}
|
||||
|
||||
Creature* ScriptedAI::DoSpawnCreature(uint32 uiId, float fX, float fY, float fZ, float fAngle, uint32 uiType, uint32 uiDespawntime)
|
||||
{
|
||||
return m_creature->SummonCreature(uiId, m_creature->GetPositionX() + fX, m_creature->GetPositionY() + fY, m_creature->GetPositionZ() + fZ, fAngle, (TempSummonType)uiType, uiDespawntime);
|
||||
}
|
||||
|
||||
SpellEntry const* ScriptedAI::SelectSpell(Unit* pTarget, int32 uiSchool, int32 iMechanic, SelectTarget selectTargets, uint32 uiPowerCostMin, uint32 uiPowerCostMax, float fRangeMin, float fRangeMax, SelectEffect selectEffects)
|
||||
{
|
||||
// No target so we can't cast
|
||||
if (!pTarget)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Silenced so we can't cast
|
||||
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Using the extended script system we first create a list of viable spells
|
||||
SpellEntry const* apSpell[4];
|
||||
memset(apSpell, 0, sizeof(SpellEntry*) * 4);
|
||||
|
||||
uint32 uiSpellCount = 0;
|
||||
|
||||
SpellEntry const* pTempSpell;
|
||||
SpellRangeEntry const* pTempRange;
|
||||
|
||||
// Check if each spell is viable(set it to null if not)
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
pTempSpell = GetSpellStore()->LookupEntry(m_creature->m_spells[i]);
|
||||
|
||||
// This spell doesn't exist
|
||||
if (!pTempSpell)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Targets and Effects checked first as most used restrictions
|
||||
// Check the spell targets if specified
|
||||
if (selectTargets && !(SpellSummary[m_creature->m_spells[i]].Targets & (1 << (selectTargets - 1))))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check the type of spell if we are looking for a specific spell type
|
||||
if (selectEffects && !(SpellSummary[m_creature->m_spells[i]].Effects & (1 << (selectEffects - 1))))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for school if specified
|
||||
if (uiSchool >= 0 && pTempSpell->SchoolMask & uiSchool)
|
||||
{ continue; }
|
||||
|
||||
// Check for spell mechanic if specified
|
||||
if (iMechanic >= 0 && pTempSpell->GetMechanic() != (uint32)iMechanic)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure that the spell uses the requested amount of power
|
||||
if (uiPowerCostMin && pTempSpell->GetManaCost() < uiPowerCostMin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uiPowerCostMax && pTempSpell->GetManaCost() > uiPowerCostMax)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Continue if we don't have the mana to actually cast this spell
|
||||
if (pTempSpell->GetManaCost() > m_creature->GetPower((Powers)pTempSpell->powerType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the Range
|
||||
pTempRange = GetSpellRangeStore()->LookupEntry(pTempSpell->rangeIndex);
|
||||
|
||||
// Spell has invalid range store so we can't use it
|
||||
if (!pTempRange)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the spell meets our range requirements
|
||||
if (fRangeMin && pTempRange->maxRange < fRangeMin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fRangeMax && pTempRange->maxRange > fRangeMax)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if our target is in range
|
||||
if (m_creature->IsWithinDistInMap(pTarget, pTempRange->minRange) || !m_creature->IsWithinDistInMap(pTarget, pTempRange->maxRange))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// All good so lets add it to the spell list
|
||||
apSpell[uiSpellCount] = pTempSpell;
|
||||
++uiSpellCount;
|
||||
}
|
||||
|
||||
// We got our usable spells so now lets randomly pick one
|
||||
if (!uiSpellCount)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return apSpell[urand(0, uiSpellCount - 1)];
|
||||
}
|
||||
|
||||
bool ScriptedAI::CanCast(Unit* pTarget, SpellEntry const* pSpellEntry, bool bTriggered)
|
||||
{
|
||||
// No target so we can't cast
|
||||
if (!pTarget || !pSpellEntry)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Silenced so we can't cast
|
||||
if (!bTriggered && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for power
|
||||
if (!bTriggered && m_creature->GetPower((Powers)pSpellEntry->powerType) < pSpellEntry->GetManaCost())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SpellRangeEntry const* pTempRange = GetSpellRangeStore()->LookupEntry(pSpellEntry->rangeIndex);
|
||||
|
||||
// Spell has invalid range store so we can't use it
|
||||
if (!pTempRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unit is out of range of this spell
|
||||
if (!m_creature->IsInRange(pTarget, pTempRange->minRange, pTempRange->maxRange))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FillSpellSummary()
|
||||
{
|
||||
SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];
|
||||
|
||||
SpellEntry const* pTempSpell;
|
||||
|
||||
for (uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i)
|
||||
{
|
||||
SpellSummary[i].Effects = 0;
|
||||
SpellSummary[i].Targets = 0;
|
||||
|
||||
pTempSpell = GetSpellStore()->LookupEntry(i);
|
||||
// This spell doesn't exist
|
||||
if (!pTempSpell)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint8 j = 0; j < 3; ++j)
|
||||
{
|
||||
SpellEffectEntry const* pSpellEffect = pTempSpell->GetSpellEffect(SpellEffectIndex(j));
|
||||
if (!pSpellEffect)
|
||||
continue;
|
||||
|
||||
// Spell targets self
|
||||
if (pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_SELF)
|
||||
{
|
||||
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF - 1);
|
||||
}
|
||||
|
||||
// Spell targets a single enemy
|
||||
if (pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CHAIN_DAMAGE ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CURRENT_ENEMY_COORDINATES)
|
||||
{
|
||||
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY - 1);
|
||||
}
|
||||
|
||||
// Spell targets AoE at enemy
|
||||
if (pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_ENEMY_IN_AREA ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CASTER_COORDINATES ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
|
||||
{
|
||||
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY - 1);
|
||||
}
|
||||
|
||||
// Spell targets an enemy
|
||||
if (pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CHAIN_DAMAGE ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CURRENT_ENEMY_COORDINATES ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_ENEMY_IN_AREA ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CASTER_COORDINATES ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
|
||||
{
|
||||
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY - 1);
|
||||
}
|
||||
|
||||
// Spell targets a single friend(or self)
|
||||
if (pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_SELF ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_SINGLE_FRIEND ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_SINGLE_PARTY)
|
||||
{
|
||||
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND - 1);
|
||||
}
|
||||
|
||||
// Spell targets aoe friends
|
||||
if (pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_PARTY_AROUND_CASTER ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_AREAEFFECT_PARTY ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CASTER_COORDINATES)
|
||||
{
|
||||
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND - 1);
|
||||
}
|
||||
|
||||
// Spell targets any friend(or self)
|
||||
if (pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_SELF ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_SINGLE_FRIEND ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_SINGLE_PARTY ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_ALL_PARTY_AROUND_CASTER ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_AREAEFFECT_PARTY ||
|
||||
pTempSpell->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_CASTER_COORDINATES)
|
||||
{
|
||||
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND - 1);
|
||||
}
|
||||
|
||||
// Make sure that this spell includes a damage effect
|
||||
if (pSpellEffect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE ||
|
||||
pSpellEffect->Effect == SPELL_EFFECT_INSTAKILL ||
|
||||
pSpellEffect->Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
|
||||
pSpellEffect->Effect == SPELL_EFFECT_HEALTH_LEECH)
|
||||
{
|
||||
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_DAMAGE - 1);
|
||||
}
|
||||
|
||||
// Make sure that this spell includes a healing effect (or an apply aura with a periodic heal)
|
||||
if (pSpellEffect->Effect == SPELL_EFFECT_HEAL ||
|
||||
pSpellEffect->Effect == SPELL_EFFECT_HEAL_MAX_HEALTH ||
|
||||
pSpellEffect->Effect == SPELL_EFFECT_HEAL_MECHANICAL ||
|
||||
(pSpellEffect->Effect == SPELL_EFFECT_APPLY_AURA && pTempSpell->GetEffectApplyAuraNameByIndex(SpellEffectIndex(j)) == 8))
|
||||
{
|
||||
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING - 1);
|
||||
}
|
||||
|
||||
// Make sure that this spell applies an aura
|
||||
if (pSpellEffect->Effect == SPELL_EFFECT_APPLY_AURA)
|
||||
{
|
||||
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedAI::DoResetThreat()
|
||||
{
|
||||
if (!m_creature->CanHaveThreatList() || m_creature->GetThreatManager().isThreatListEmpty())
|
||||
{
|
||||
script_error_log("DoResetThreat called for creature that either can not have threat list or has empty threat list (m_creature entry = %d)", m_creature->GetEntry());
|
||||
return;
|
||||
}
|
||||
|
||||
ThreatList const& tList = m_creature->GetThreatManager().getThreatList();
|
||||
for (ThreatList::const_iterator itr = tList.begin(); itr != tList.end(); ++itr)
|
||||
{
|
||||
Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());
|
||||
|
||||
if (pUnit && m_creature->GetThreatManager().getThreat(pUnit))
|
||||
{
|
||||
m_creature->GetThreatManager().modifyThreatPercent(pUnit, -100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedAI::DoTeleportPlayer(Unit* pUnit, float fX, float fY, float fZ, float fO)
|
||||
{
|
||||
if (!pUnit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pUnit->GetTypeId() != TYPEID_PLAYER)
|
||||
{
|
||||
script_error_log("%s tried to teleport non-player (%s) to x: %f y:%f z: %f o: %f. Aborted.", m_creature->GetGuidStr().c_str(), pUnit->GetGuidStr().c_str(), fX, fY, fZ, fO);
|
||||
return;
|
||||
}
|
||||
|
||||
((Player*)pUnit)->TeleportTo(pUnit->GetMapId(), fX, fY, fZ, fO, TELE_TO_NOT_LEAVE_COMBAT);
|
||||
}
|
||||
|
||||
Unit* ScriptedAI::DoSelectLowestHpFriendly(float fRange, uint32 uiMinHPDiff)
|
||||
{
|
||||
Unit* pUnit = NULL;
|
||||
|
||||
MaNGOS::MostHPMissingInRangeCheck u_check(m_creature, fRange, uiMinHPDiff);
|
||||
MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRangeCheck> searcher(pUnit, u_check);
|
||||
|
||||
Cell::VisitGridObjects(m_creature, searcher, fRange);
|
||||
|
||||
return pUnit;
|
||||
}
|
||||
|
||||
std::list<Creature*> ScriptedAI::DoFindFriendlyCC(float fRange)
|
||||
{
|
||||
std::list<Creature*> pList;
|
||||
|
||||
MaNGOS::FriendlyCCedInRangeCheck u_check(m_creature, fRange);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRangeCheck> searcher(pList, u_check);
|
||||
|
||||
Cell::VisitGridObjects(m_creature, searcher, fRange);
|
||||
|
||||
return pList;
|
||||
}
|
||||
|
||||
std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float fRange, uint32 uiSpellId)
|
||||
{
|
||||
std::list<Creature*> pList;
|
||||
|
||||
MaNGOS::FriendlyMissingBuffInRangeCheck u_check(m_creature, fRange, uiSpellId);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRangeCheck> searcher(pList, u_check);
|
||||
|
||||
Cell::VisitGridObjects(m_creature, searcher, fRange);
|
||||
|
||||
return pList;
|
||||
}
|
||||
|
||||
Player* ScriptedAI::GetPlayerAtMinimumRange(float fMinimumRange)
|
||||
{
|
||||
Player* pPlayer = NULL;
|
||||
|
||||
MaNGOS::AnyPlayerInObjectRangeCheck check(m_creature, fMinimumRange);
|
||||
MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> searcher(pPlayer, check);
|
||||
|
||||
Cell::VisitWorldObjects(m_creature, searcher, fMinimumRange);
|
||||
|
||||
return pPlayer;
|
||||
}
|
||||
|
||||
void ScriptedAI::SetEquipmentSlots(bool bLoadDefault, int32 iMainHand, int32 iOffHand, int32 iRanged)
|
||||
{
|
||||
if (bLoadDefault)
|
||||
{
|
||||
m_creature->LoadEquipment(m_creature->GetCreatureInfo()->equipmentId, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iMainHand >= 0)
|
||||
{
|
||||
m_creature->SetVirtualItem(VIRTUAL_ITEM_SLOT_0, iMainHand);
|
||||
}
|
||||
|
||||
if (iOffHand >= 0)
|
||||
{
|
||||
m_creature->SetVirtualItem(VIRTUAL_ITEM_SLOT_1, iOffHand);
|
||||
}
|
||||
|
||||
if (iRanged >= 0)
|
||||
{
|
||||
m_creature->SetVirtualItem(VIRTUAL_ITEM_SLOT_2, iRanged);
|
||||
}
|
||||
}
|
||||
|
||||
// Hacklike storage used for misc creatures that are expected to evade of outside of a certain area.
|
||||
// It is assumed the information is found elswehere and can be handled by mangos. So far no luck finding such information/way to extract it.
|
||||
enum
|
||||
{
|
||||
NPC_BROODLORD = 12017,
|
||||
NPC_VOID_REAVER = 19516,
|
||||
NPC_JAN_ALAI = 23578,
|
||||
NPC_SARTHARION = 28860,
|
||||
NPC_TALON_KING_IKISS = 18473,
|
||||
NPC_KARGATH_BLADEFIST = 16808,
|
||||
NPC_ANUBARAK = 29120,
|
||||
NPC_SINDRAGOSA = 36853,
|
||||
NPC_ZARITHRIAN = 39746,
|
||||
};
|
||||
|
||||
bool ScriptedAI::EnterEvadeIfOutOfCombatArea(const uint32 uiDiff)
|
||||
{
|
||||
if (m_uiEvadeCheckCooldown < uiDiff)
|
||||
{
|
||||
m_uiEvadeCheckCooldown = 2500;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiEvadeCheckCooldown -= uiDiff;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_creature->IsInEvadeMode() || !m_creature->getVictim())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float fX = m_creature->GetPositionX();
|
||||
float fY = m_creature->GetPositionY();
|
||||
float fZ = m_creature->GetPositionZ();
|
||||
|
||||
switch (m_creature->GetEntry())
|
||||
{
|
||||
case NPC_BROODLORD: // broodlord (not move down stairs)
|
||||
if (fZ > 448.60f)
|
||||
{ return false; }
|
||||
break;
|
||||
case NPC_VOID_REAVER: // void reaver (calculate from center of room)
|
||||
if (m_creature->GetDistance2d(432.59f, 371.93f) < 105.0f)
|
||||
{ return false; }
|
||||
break;
|
||||
case NPC_JAN_ALAI: // jan'alai (calculate by Z)
|
||||
if (fZ > 12.0f)
|
||||
{ return false; }
|
||||
break;
|
||||
case NPC_SARTHARION: // sartharion (calculate box)
|
||||
if (fX > 3218.86f && fX < 3275.69f && fY < 572.40f && fY > 484.68f)
|
||||
{ return false; }
|
||||
break;
|
||||
case NPC_TALON_KING_IKISS:
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
m_creature->GetRespawnCoord(fX, fY, fZ);
|
||||
if (m_creature->GetDistance2d(fX, fY) < 70.0f)
|
||||
{ return false; }
|
||||
break;
|
||||
}
|
||||
case NPC_KARGATH_BLADEFIST:
|
||||
if (fX < 255.0f && fX > 205.0f)
|
||||
{ return false; }
|
||||
break;
|
||||
case NPC_ANUBARAK:
|
||||
if (fY < 281.0f && fY > 228.0f)
|
||||
return false;
|
||||
break;
|
||||
case NPC_SINDRAGOSA:
|
||||
if (fX > 4314.0f)
|
||||
return false;
|
||||
break;
|
||||
case NPC_ZARITHRIAN:
|
||||
if (fZ > 87.0f)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
script_error_log("EnterEvadeIfOutOfCombatArea used for creature entry %u, but does not have any definition.", m_creature->GetEntry());
|
||||
return false;
|
||||
}
|
||||
|
||||
EnterEvadeMode();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scripted_NoMovementAI::GetAIInformation(ChatHandler& reader)
|
||||
{
|
||||
reader.PSendSysMessage("Subclass of Scripted_NoMovementAI");
|
||||
}
|
||||
|
||||
void Scripted_NoMovementAI::AttackStart(Unit* pWho)
|
||||
{
|
||||
if (!m_creature->CanAttackByItself())
|
||||
return;
|
||||
|
||||
if (pWho && m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->AddThreat(pWho);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
DoStartNoMovement(pWho);
|
||||
}
|
||||
}
|
||||
255
src/modules/SD2/include/sc_creature.h
Normal file
255
src/modules/SD2/include/sc_creature.h
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_CREATURE_H
|
||||
#define SC_CREATURE_H
|
||||
|
||||
#include "Chat.h"
|
||||
#include "DBCStores.h" // Mostly only used the Lookup acces, but a few cases really do use the DBC-Stores
|
||||
|
||||
// Spell targets used by SelectSpell
|
||||
enum SelectTarget
|
||||
{
|
||||
SELECT_TARGET_DONTCARE = 0, // All target types allowed
|
||||
|
||||
SELECT_TARGET_SELF, // Only Self casting
|
||||
|
||||
SELECT_TARGET_SINGLE_ENEMY, // Only Single Enemy
|
||||
SELECT_TARGET_AOE_ENEMY, // Only AoE Enemy
|
||||
SELECT_TARGET_ANY_ENEMY, // AoE or Single Enemy
|
||||
|
||||
SELECT_TARGET_SINGLE_FRIEND, // Only Single Friend
|
||||
SELECT_TARGET_AOE_FRIEND, // Only AoE Friend
|
||||
SELECT_TARGET_ANY_FRIEND, // AoE or Single Friend
|
||||
};
|
||||
|
||||
// Spell Effects used by SelectSpell
|
||||
enum SelectEffect
|
||||
{
|
||||
SELECT_EFFECT_DONTCARE = 0, // All spell effects allowed
|
||||
SELECT_EFFECT_DAMAGE, // Spell does damage
|
||||
SELECT_EFFECT_HEALING, // Spell does healing
|
||||
SELECT_EFFECT_AURA, // Spell applies an aura
|
||||
};
|
||||
|
||||
enum SCEquip
|
||||
{
|
||||
EQUIP_NO_CHANGE = -1,
|
||||
EQUIP_UNEQUIP = 0
|
||||
};
|
||||
|
||||
/// Documentation of CreatureAI functions can be found in MaNGOS source
|
||||
// Only list them here again to ensure that the interface between SD2 and the core is not changed unnoticed
|
||||
struct ScriptedAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit ScriptedAI(Creature* pCreature);
|
||||
~ScriptedAI() {}
|
||||
|
||||
// *************
|
||||
// CreatureAI Functions
|
||||
// *************
|
||||
|
||||
// == Information about AI ========================
|
||||
// Get information about the AI
|
||||
void GetAIInformation(ChatHandler& reader) override;
|
||||
|
||||
// == Reactions At =================================
|
||||
|
||||
// Called if IsVisible(Unit* pWho) is true at each relative pWho move
|
||||
void MoveInLineOfSight(Unit* pWho) override;
|
||||
|
||||
// Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
|
||||
void EnterCombat(Unit* pEnemy) override;
|
||||
|
||||
// Called at stoping attack by any attacker
|
||||
void EnterEvadeMode() override;
|
||||
|
||||
// Called when reached home after MoveTargetHome (in evade)
|
||||
void JustReachedHome() override {}
|
||||
|
||||
// Called at any Heal received
|
||||
void HealedBy(Unit* /*pHealer*/, uint32& /*uiHealedAmount*/) override {}
|
||||
|
||||
// Called at any Damage to any victim (before damage apply)
|
||||
void DamageDeal(Unit* /*pDoneTo*/, uint32& /*uiDamage*/) override {}
|
||||
|
||||
// Called at any Damage from any attacker (before damage apply)
|
||||
void DamageTaken(Unit* /*pDealer*/, uint32& /*uiDamage*/) override {}
|
||||
|
||||
// Called at creature death
|
||||
void JustDied(Unit* /*pKiller*/) override {}
|
||||
|
||||
// Called when the corpse of this creature gets removed
|
||||
void CorpseRemoved(uint32& /*uiRespawnDelay*/) override {}
|
||||
|
||||
// Called when a summoned creature is killed
|
||||
void SummonedCreatureJustDied(Creature* /*pSummoned*/) override {}
|
||||
|
||||
// Called at creature killing another unit
|
||||
void KilledUnit(Unit* /*pVictim*/) override {}
|
||||
|
||||
// Called when owner of m_creature (if m_creature is PROTECTOR_PET) kills a unit
|
||||
void OwnerKilledUnit(Unit* /*pVictim*/) override {}
|
||||
|
||||
// Called when the creature successfully summons a creature
|
||||
void JustSummoned(Creature* /*pSummoned*/) override {}
|
||||
|
||||
// Called when the creature successfully summons a gameobject
|
||||
void JustSummoned(GameObject* /*pGo*/) override {}
|
||||
|
||||
// Called when a summoned creature gets TemporarySummon::UnSummon ed
|
||||
void SummonedCreatureDespawn(Creature* /*pSummoned*/) override {}
|
||||
|
||||
// Called when hit by a spell
|
||||
void SpellHit(Unit* /*pCaster*/, const SpellEntry* /*pSpell*/) override {}
|
||||
|
||||
// Called when spell hits creature's target
|
||||
void SpellHitTarget(Unit* /*pTarget*/, const SpellEntry* /*pSpell*/) override {}
|
||||
|
||||
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
|
||||
/// This will by default result in reattacking, if the creature has no victim
|
||||
void AttackedBy(Unit* pAttacker) override { CreatureAI::AttackedBy(pAttacker); }
|
||||
|
||||
// Called when creature is respawned (for reseting variables)
|
||||
void JustRespawned() override;
|
||||
|
||||
// Called at waypoint reached or point movement finished
|
||||
void MovementInform(uint32 /*uiMovementType*/, uint32 /*uiData*/) override {}
|
||||
|
||||
// Called if a temporary summoned of m_creature reach a move point
|
||||
void SummonedMovementInform(Creature* /*pSummoned*/, uint32 /*uiMotionType*/, uint32 /*uiData*/) override {}
|
||||
|
||||
// Called at text emote receive from player
|
||||
void ReceiveEmote(Player* /*pPlayer*/, uint32 /*uiEmote*/) override {}
|
||||
|
||||
// Called at each attack of m_creature by any victim
|
||||
void AttackStart(Unit* pWho) override;
|
||||
|
||||
// Called at World update tick
|
||||
void UpdateAI(const uint32) override;
|
||||
|
||||
// == State checks =================================
|
||||
|
||||
// Check if unit is visible for MoveInLineOfSight
|
||||
bool IsVisible(Unit* pWho) const override;
|
||||
|
||||
// Called when victim entered water and creature can not enter water
|
||||
bool canReachByRangeAttack(Unit* pWho) override { return CreatureAI::canReachByRangeAttack(pWho); }
|
||||
|
||||
// *************
|
||||
// Variables
|
||||
// *************
|
||||
|
||||
// *************
|
||||
// Pure virtual functions
|
||||
// *************
|
||||
|
||||
/**
|
||||
* This is a SD2 internal function, that every AI must implement
|
||||
* Usally used to reset combat variables
|
||||
* Called by default on creature evade and respawn
|
||||
* In most scripts also called in the constructor of the AI
|
||||
*/
|
||||
virtual void Reset() = 0;
|
||||
|
||||
/// Called at creature EnterCombat with an enemy
|
||||
/**
|
||||
* This is a SD2 internal function
|
||||
* Called by default on creature EnterCombat with an enemy
|
||||
*/
|
||||
virtual void Aggro(Unit* /*pWho*/) {}
|
||||
|
||||
// *************
|
||||
// AI Helper Functions
|
||||
// *************
|
||||
|
||||
// Start movement toward victim
|
||||
void DoStartMovement(Unit* pVictim, float fDistance = 0, float fAngle = 0);
|
||||
|
||||
// Start no movement on victim
|
||||
void DoStartNoMovement(Unit* pVictim);
|
||||
|
||||
// Stop attack of current victim
|
||||
void DoStopAttack();
|
||||
|
||||
// Cast spell by Id
|
||||
void DoCast(Unit* pTarget, uint32 uiSpellId, bool bTriggered = false);
|
||||
|
||||
// Cast spell by spell info
|
||||
void DoCastSpell(Unit* pTarget, SpellEntry const* pSpellInfo, bool bTriggered = false);
|
||||
|
||||
// Plays a sound to all nearby players
|
||||
void DoPlaySoundToSet(WorldObject* pSource, uint32 uiSoundId);
|
||||
|
||||
// Drops all threat to 0%. Does not remove enemies from the threat list
|
||||
void DoResetThreat();
|
||||
|
||||
// Teleports a player without dropping threat (only teleports to same map)
|
||||
void DoTeleportPlayer(Unit* pUnit, float fX, float fY, float fZ, float fO);
|
||||
|
||||
// Returns friendly unit with the most amount of hp missing from max hp
|
||||
Unit* DoSelectLowestHpFriendly(float fRange, uint32 uiMinHPDiff = 1);
|
||||
|
||||
// Returns a list of friendly CC'd units within range
|
||||
std::list<Creature*> DoFindFriendlyCC(float fRange);
|
||||
|
||||
// Returns a list of all friendly units missing a specific buff within range
|
||||
std::list<Creature*> DoFindFriendlyMissingBuff(float fRange, uint32 uiSpellId);
|
||||
|
||||
// Return a player with at least minimumRange from m_creature
|
||||
Player* GetPlayerAtMinimumRange(float fMinimumRange);
|
||||
|
||||
// Spawns a creature relative to m_creature
|
||||
Creature* DoSpawnCreature(uint32 uiId, float fX, float fY, float fZ, float fAngle, uint32 uiType, uint32 uiDespawntime);
|
||||
|
||||
// Returns spells that meet the specified criteria from the creatures spell list
|
||||
SpellEntry const* SelectSpell(Unit* pTarget, int32 uiSchool, int32 iMechanic, SelectTarget selectTargets, uint32 uiPowerCostMin, uint32 uiPowerCostMax, float fRangeMin, float fRangeMax, SelectEffect selectEffect);
|
||||
|
||||
// Checks if you can cast the specified spell
|
||||
bool CanCast(Unit* pTarget, SpellEntry const* pSpell, bool bTriggered = false);
|
||||
|
||||
void SetEquipmentSlots(bool bLoadDefault, int32 iMainHand = EQUIP_NO_CHANGE, int32 iOffHand = EQUIP_NO_CHANGE, int32 iRanged = EQUIP_NO_CHANGE);
|
||||
|
||||
bool EnterEvadeIfOutOfCombatArea(const uint32 uiDiff);
|
||||
|
||||
private:
|
||||
uint32 m_uiEvadeCheckCooldown;
|
||||
};
|
||||
|
||||
struct Scripted_NoMovementAI : public ScriptedAI
|
||||
{
|
||||
Scripted_NoMovementAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
void GetAIInformation(ChatHandler& reader) override;
|
||||
|
||||
// Called at each attack of m_creature by any victim
|
||||
void AttackStart(Unit* pWho) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
180
src/modules/SD2/include/sc_gossip.h
Normal file
180
src/modules/SD2/include/sc_gossip.h
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_GOSSIP_H
|
||||
#define SC_GOSSIP_H
|
||||
|
||||
#include "Player.h"
|
||||
#include "GossipDef.h"
|
||||
#include "QuestDef.h"
|
||||
|
||||
// Gossip Item Text
|
||||
#define GOSSIP_TEXT_BROWSE_GOODS "I'd like to browse your goods."
|
||||
#define GOSSIP_TEXT_TRAIN "Train me!"
|
||||
|
||||
#define GOSSIP_TEXT_BANK "The bank"
|
||||
#define GOSSIP_TEXT_IRONFORGE_BANK "The bank of Ironforge"
|
||||
#define GOSSIP_TEXT_STORMWIND_BANK "The bank of Stormwind"
|
||||
#define GOSSIP_TEXT_WINDRIDER "The wind rider master"
|
||||
#define GOSSIP_TEXT_GRYPHON "The gryphon master"
|
||||
#define GOSSIP_TEXT_BATHANDLER "The bat handler"
|
||||
#define GOSSIP_TEXT_HIPPOGRYPH "The hippogryph master"
|
||||
#define GOSSIP_TEXT_ZEPPLINMASTER "The zeppelin master"
|
||||
#define GOSSIP_TEXT_DEEPRUNTRAM "The Deeprun Tram"
|
||||
#define GOSSIP_TEXT_FERRY "The Rut'theran Ferry"
|
||||
#define GOSSIP_TEXT_FLIGHTMASTER "The flight master"
|
||||
#define GOSSIP_TEXT_AUCTIONHOUSE "The auction house"
|
||||
#define GOSSIP_TEXT_GUILDMASTER "The guild master"
|
||||
#define GOSSIP_TEXT_INN "The inn"
|
||||
#define GOSSIP_TEXT_MAILBOX "The mailbox"
|
||||
#define GOSSIP_TEXT_STABLEMASTER "The stable master"
|
||||
#define GOSSIP_TEXT_WEAPONMASTER "The weapon master"
|
||||
#define GOSSIP_TEXT_OFFICERS "The officers' lounge"
|
||||
#define GOSSIP_TEXT_BATTLEMASTER "The battlemaster"
|
||||
#define GOSSIP_TEXT_BARBER "Barber"
|
||||
#define GOSSIP_TEXT_CLASSTRAINER "A class trainer"
|
||||
#define GOSSIP_TEXT_PROFTRAINER "A profession trainer"
|
||||
#define GOSSIP_TEXT_LEXICON "Lexicon of Power"
|
||||
|
||||
#define GOSSIP_TEXT_ALTERACVALLEY "Alterac Valley"
|
||||
#define GOSSIP_TEXT_ARATHIBASIN "Arathi Basin"
|
||||
#define GOSSIP_TEXT_WARSONGULCH "Warsong Gulch"
|
||||
#define GOSSIP_TEXT_ARENA "Arena"
|
||||
#define GOSSIP_TEXT_EYEOFTHESTORM "Eye of The Storm"
|
||||
#define GOSSIP_TEXT_STRANDOFANCIENT "Strand of the Ancients"
|
||||
|
||||
#define GOSSIP_TEXT_DEATH_KNIGHT "Death Knight"
|
||||
#define GOSSIP_TEXT_DRUID "Druid"
|
||||
#define GOSSIP_TEXT_HUNTER "Hunter"
|
||||
#define GOSSIP_TEXT_PRIEST "Priest"
|
||||
#define GOSSIP_TEXT_ROGUE "Rogue"
|
||||
#define GOSSIP_TEXT_WARRIOR "Warrior"
|
||||
#define GOSSIP_TEXT_PALADIN "Paladin"
|
||||
#define GOSSIP_TEXT_SHAMAN "Shaman"
|
||||
#define GOSSIP_TEXT_MAGE "Mage"
|
||||
#define GOSSIP_TEXT_WARLOCK "Warlock"
|
||||
|
||||
#define GOSSIP_TEXT_ALCHEMY "Alchemy"
|
||||
#define GOSSIP_TEXT_BLACKSMITHING "Blacksmithing"
|
||||
#define GOSSIP_TEXT_COOKING "Cooking"
|
||||
#define GOSSIP_TEXT_ENCHANTING "Enchanting"
|
||||
#define GOSSIP_TEXT_ENGINEERING "Engineering"
|
||||
#define GOSSIP_TEXT_FIRSTAID "First Aid"
|
||||
#define GOSSIP_TEXT_HERBALISM "Herbalism"
|
||||
#define GOSSIP_TEXT_LEATHERWORKING "Leatherworking"
|
||||
#define GOSSIP_TEXT_TAILORING "Tailoring"
|
||||
#define GOSSIP_TEXT_MINING "Mining"
|
||||
#define GOSSIP_TEXT_FISHING "Fishing"
|
||||
#define GOSSIP_TEXT_SKINNING "Skinning"
|
||||
#define GOSSIP_TEXT_JEWELCRAFTING "Jewelcrafting"
|
||||
#define GOSSIP_TEXT_INSCRIPTION "Inscription"
|
||||
|
||||
enum
|
||||
{
|
||||
// Skill defines
|
||||
TRADESKILL_ALCHEMY = 1,
|
||||
TRADESKILL_BLACKSMITHING = 2,
|
||||
TRADESKILL_COOKING = 3,
|
||||
TRADESKILL_ENCHANTING = 4,
|
||||
TRADESKILL_ENGINEERING = 5,
|
||||
TRADESKILL_FIRSTAID = 6,
|
||||
TRADESKILL_HERBALISM = 7,
|
||||
TRADESKILL_LEATHERWORKING = 8,
|
||||
TRADESKILL_POISONS = 9,
|
||||
TRADESKILL_TAILORING = 10,
|
||||
TRADESKILL_MINING = 11,
|
||||
TRADESKILL_FISHING = 12,
|
||||
TRADESKILL_SKINNING = 13,
|
||||
TRADESKILL_JEWLCRAFTING = 14,
|
||||
TRADESKILL_INSCRIPTION = 15,
|
||||
|
||||
TRADESKILL_LEVEL_NONE = 0,
|
||||
TRADESKILL_LEVEL_APPRENTICE = 1,
|
||||
TRADESKILL_LEVEL_JOURNEYMAN = 2,
|
||||
TRADESKILL_LEVEL_EXPERT = 3,
|
||||
TRADESKILL_LEVEL_ARTISAN = 4,
|
||||
TRADESKILL_LEVEL_MASTER = 5,
|
||||
TRADESKILL_LEVEL_GRAND_MASTER = 6,
|
||||
|
||||
// Gossip defines
|
||||
GOSSIP_ACTION_TRADE = 1,
|
||||
GOSSIP_ACTION_TRAIN = 2,
|
||||
GOSSIP_ACTION_TAXI = 3,
|
||||
GOSSIP_ACTION_GUILD = 4,
|
||||
GOSSIP_ACTION_BATTLE = 5,
|
||||
GOSSIP_ACTION_BANK = 6,
|
||||
GOSSIP_ACTION_INN = 7,
|
||||
GOSSIP_ACTION_HEAL = 8,
|
||||
GOSSIP_ACTION_TABARD = 9,
|
||||
GOSSIP_ACTION_AUCTION = 10,
|
||||
GOSSIP_ACTION_INN_INFO = 11,
|
||||
GOSSIP_ACTION_UNLEARN = 12,
|
||||
GOSSIP_ACTION_INFO_DEF = 1000,
|
||||
|
||||
GOSSIP_SENDER_MAIN = 1,
|
||||
GOSSIP_SENDER_INN_INFO = 2,
|
||||
GOSSIP_SENDER_INFO = 3,
|
||||
GOSSIP_SENDER_SEC_PROFTRAIN = 4,
|
||||
GOSSIP_SENDER_SEC_CLASSTRAIN = 5,
|
||||
GOSSIP_SENDER_SEC_BATTLEINFO = 6,
|
||||
GOSSIP_SENDER_SEC_BANK = 7,
|
||||
GOSSIP_SENDER_SEC_INN = 8,
|
||||
GOSSIP_SENDER_SEC_MAILBOX = 9,
|
||||
GOSSIP_SENDER_SEC_STABLEMASTER = 10
|
||||
};
|
||||
|
||||
extern uint32 GetSkillLevel(Player* pPlayer, uint32 uiSkill);
|
||||
|
||||
// Defined fuctions to use with player.
|
||||
|
||||
// This fuction add's a menu item,
|
||||
// Icon Id
|
||||
// Text
|
||||
// Sender(this is to identify the current Menu with this item)
|
||||
// Option id (identifies this Menu Item)
|
||||
// Text to be displayed in pop up box
|
||||
// Money value in pop up box
|
||||
// Coded
|
||||
#define ADD_GOSSIP_ITEM(uiIcon, chrText, uiSender, uiOptionId) PlayerTalkClass->GetGossipMenu().AddMenuItem(uiIcon, chrText, uiSender, uiOptionId, "", 0)
|
||||
#define ADD_GOSSIP_ITEM_ID(uiIcon, iTextId, uiSender, uiOptionId) PlayerTalkClass->GetGossipMenu().AddMenuItem(uiIcon, iTextId, uiSender, uiOptionId, 0, 0)
|
||||
#define ADD_GOSSIP_ITEM_EXTENDED(uiIcon, chrText, uiSender, uiOptionId, chrBoxMessage, uiBoxMoney, bCode) PlayerTalkClass->GetGossipMenu().AddMenuItem(uiIcon, chrText, uiSender, uiOptionId, chrBoxMessage, uiBoxMoney, bCode)
|
||||
|
||||
// This fuction Sends the current menu to show to client
|
||||
// uiTextId - NPCTEXTID (uint32)
|
||||
// guid - npc guid (ObjectGuid)
|
||||
#define SEND_GOSSIP_MENU(uiTextId, guid) PlayerTalkClass->SendGossipMenu(uiTextId, guid)
|
||||
|
||||
// Closes the Menu
|
||||
#define CLOSE_GOSSIP_MENU() PlayerTalkClass->CloseGossip()
|
||||
|
||||
// Fuctions to send NPC lists
|
||||
// a - is always the npc guid (ObjectGuid)
|
||||
#define SEND_VENDORLIST(a) GetSession()->SendListInventory(a)
|
||||
#define SEND_TRAINERLIST(a) GetSession()->SendTrainerList(a)
|
||||
#define SEND_BANKERLIST(a) GetSession()->SendShowBank(a)
|
||||
#define SEND_TABARDLIST(a) GetSession()->SendTabardVendorActivate(a)
|
||||
#define SEND_TAXILIST(a) GetSession()->SendTaxiStatus(a)
|
||||
|
||||
#endif
|
||||
73
src/modules/SD2/include/sc_grid_searchers.cpp
Normal file
73
src/modules/SD2/include/sc_grid_searchers.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
// return closest GO in grid, with range from pSource
|
||||
GameObject* GetClosestGameObjectWithEntry(WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange)
|
||||
{
|
||||
GameObject* pGo = NULL;
|
||||
|
||||
MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*pSource, uiEntry, fMaxSearchRange);
|
||||
MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> searcher(pGo, go_check);
|
||||
|
||||
Cell::VisitGridObjects(pSource, searcher, fMaxSearchRange);
|
||||
|
||||
return pGo;
|
||||
}
|
||||
|
||||
// return closest creature alive in grid, with range from pSource
|
||||
Creature* GetClosestCreatureWithEntry(WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange, bool bOnlyAlive/*=true*/, bool bOnlyDead/*=false*/)
|
||||
{
|
||||
Creature* pCreature = NULL;
|
||||
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*pSource, uiEntry, bOnlyAlive, bOnlyDead, fMaxSearchRange);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check);
|
||||
|
||||
Cell::VisitGridObjects(pSource, searcher, fMaxSearchRange);
|
||||
|
||||
return pCreature;
|
||||
}
|
||||
|
||||
void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList , WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange)
|
||||
{
|
||||
MaNGOS::GameObjectEntryInPosRangeCheck check(*pSource, uiEntry, pSource->GetPositionX(), pSource->GetPositionY(), pSource->GetPositionZ(), fMaxSearchRange);
|
||||
MaNGOS::GameObjectListSearcher<MaNGOS::GameObjectEntryInPosRangeCheck> searcher(lList, check);
|
||||
|
||||
Cell::VisitGridObjects(pSource, searcher, fMaxSearchRange);
|
||||
}
|
||||
|
||||
void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange)
|
||||
{
|
||||
MaNGOS::AllCreaturesOfEntryInRangeCheck check(pSource, uiEntry, fMaxSearchRange);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::AllCreaturesOfEntryInRangeCheck> searcher(lList, check);
|
||||
|
||||
Cell::VisitGridObjects(pSource, searcher, fMaxSearchRange);
|
||||
}
|
||||
63
src/modules/SD2/include/sc_grid_searchers.h
Normal file
63
src/modules/SD2/include/sc_grid_searchers.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_GRIDSEARCH_H
|
||||
#define SC_GRIDSEARCH_H
|
||||
|
||||
#include "Object.h"
|
||||
class GameObject;
|
||||
class Creature;
|
||||
|
||||
struct ObjectDistanceOrder : public std::binary_function<const WorldObject, const WorldObject, bool>
|
||||
{
|
||||
const Unit* m_pSource;
|
||||
|
||||
ObjectDistanceOrder(const Unit* pSource) : m_pSource(pSource) {}
|
||||
|
||||
bool operator()(const WorldObject* pLeft, const WorldObject* pRight) const
|
||||
{
|
||||
return m_pSource->GetDistanceOrder(pLeft, pRight);
|
||||
}
|
||||
};
|
||||
|
||||
struct ObjectDistanceOrderReversed : public std::binary_function<const WorldObject, const WorldObject, bool>
|
||||
{
|
||||
const Unit* m_pSource;
|
||||
|
||||
ObjectDistanceOrderReversed(const Unit* pSource) : m_pSource(pSource) {}
|
||||
|
||||
bool operator()(const WorldObject* pLeft, const WorldObject* pRight) const
|
||||
{
|
||||
return !m_pSource->GetDistanceOrder(pLeft, pRight);
|
||||
}
|
||||
};
|
||||
|
||||
GameObject* GetClosestGameObjectWithEntry(WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange);
|
||||
Creature* GetClosestCreatureWithEntry(WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange, bool bOnlyAlive = true, bool bOnlyDead = false);
|
||||
|
||||
void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList , WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange);
|
||||
void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange);
|
||||
|
||||
#endif
|
||||
420
src/modules/SD2/include/sc_instance.cpp
Normal file
420
src/modules/SD2/include/sc_instance.cpp
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
/**
|
||||
Function that uses a door or a button
|
||||
|
||||
@param guid The ObjectGuid of the Door/ Button that will be used
|
||||
@param uiWithRestoreTime (in seconds) if == 0 autoCloseTime will be used (if not 0 by default in *_template)
|
||||
@param bUseAlternativeState Use to alternative state
|
||||
*/
|
||||
void ScriptedInstance::DoUseDoorOrButton(ObjectGuid guid, uint32 uiWithRestoreTime, bool bUseAlternativeState)
|
||||
{
|
||||
if (!guid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameObject* pGo = instance->GetGameObject(guid))
|
||||
{
|
||||
if (pGo->GetGoType() == GAMEOBJECT_TYPE_DOOR || pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON || pGo->GetGoType() == GAMEOBJECT_TYPE_TRAPDOOR)
|
||||
{
|
||||
if (pGo->getLootState() == GO_READY)
|
||||
{
|
||||
pGo->UseDoorOrButton(uiWithRestoreTime, bUseAlternativeState);
|
||||
}
|
||||
else if (pGo->getLootState() == GO_ACTIVATED)
|
||||
{
|
||||
pGo->ResetDoorOrButton();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
script_error_log("Script call DoUseDoorOrButton, but gameobject entry %u is type %u.", pGo->GetEntry(), pGo->GetGoType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Function that uses a door or button that is stored in m_mGoEntryGuidStore
|
||||
void ScriptedInstance::DoUseDoorOrButton(uint32 uiEntry, uint32 uiWithRestoreTime /*= 0*/, bool bUseAlternativeState /*= false*/)
|
||||
{
|
||||
EntryGuidMap::iterator find = m_mGoEntryGuidStore.find(uiEntry);
|
||||
if (find != m_mGoEntryGuidStore.end())
|
||||
{
|
||||
DoUseDoorOrButton(find->second, uiWithRestoreTime, bUseAlternativeState);
|
||||
}
|
||||
else
|
||||
// Output log, possible reason is not added GO to storage, or not yet loaded
|
||||
{
|
||||
debug_log("SD2: Script call DoUseDoorOrButton(by Entry), but no gameobject of entry %u was created yet, or it was not stored by script for map %u.", uiEntry, instance->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Function that respawns a despawned GameObject with given time
|
||||
|
||||
@param guid The ObjectGuid of the GO that will be respawned
|
||||
@param uiTimeToDespawn (in seconds) Despawn the GO after this time, default is a minute
|
||||
*/
|
||||
void ScriptedInstance::DoRespawnGameObject(ObjectGuid guid, uint32 uiTimeToDespawn)
|
||||
{
|
||||
if (!guid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameObject* pGo = instance->GetGameObject(guid))
|
||||
{
|
||||
// not expect any of these should ever be handled
|
||||
if (pGo->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE || pGo->GetGoType() == GAMEOBJECT_TYPE_DOOR ||
|
||||
pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pGo->isSpawned())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pGo->SetRespawnTime(uiTimeToDespawn);
|
||||
pGo->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// Function that uses a door or button that is stored in m_mGoEntryGuidStore
|
||||
void ScriptedInstance::DoToggleGameObjectFlags(uint32 uiEntry, uint32 uiGOflags, bool bApply)
|
||||
{
|
||||
EntryGuidMap::iterator find = m_mGoEntryGuidStore.find(uiEntry);
|
||||
if (find != m_mGoEntryGuidStore.end())
|
||||
{
|
||||
DoToggleGameObjectFlags(find->second, uiGOflags, bApply);
|
||||
}
|
||||
else
|
||||
// Output log, possible reason is not added GO to storage, or not yet loaded
|
||||
{
|
||||
debug_log("SD2: Script call ToogleTameObjectFlags (by Entry), but no gameobject of entry %u was created yet, or it was not stored by script for map %u.", uiEntry, instance->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Function that toggles the GO-flags of a GameObject
|
||||
|
||||
@param guid The ObjectGuid of the GO that will be respawned
|
||||
@param uiGOflags Which GO-flags to toggle
|
||||
@param bApply should the GO-flags be applied or removed?
|
||||
*/
|
||||
void ScriptedInstance::DoToggleGameObjectFlags(ObjectGuid guid, uint32 uiGOflags, bool bApply)
|
||||
{
|
||||
if (!guid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameObject* pGo = instance->GetGameObject(guid))
|
||||
{
|
||||
if (bApply)
|
||||
{
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS, uiGOflags);
|
||||
}
|
||||
else
|
||||
{
|
||||
pGo->RemoveFlag(GAMEOBJECT_FLAGS, uiGOflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Function that respawns a despawned GO that is stored in m_mGoEntryGuidStore
|
||||
void ScriptedInstance::DoRespawnGameObject(uint32 uiEntry, uint32 uiTimeToDespawn)
|
||||
{
|
||||
EntryGuidMap::iterator find = m_mGoEntryGuidStore.find(uiEntry);
|
||||
if (find != m_mGoEntryGuidStore.end())
|
||||
{
|
||||
DoRespawnGameObject(find->second, uiTimeToDespawn);
|
||||
}
|
||||
else
|
||||
// Output log, possible reason is not added GO to storage, or not yet loaded;
|
||||
{
|
||||
debug_log("SD2: Script call DoRespawnGameObject(by Entry), but no gameobject of entry %u was created yet, or it was not stored by script for map %u.", uiEntry, instance->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to update a world state for all players in the map
|
||||
|
||||
@param uiStateId The WorldState that will be set for all players in the map
|
||||
@param uiStateData The Value to which the State will be set to
|
||||
*/
|
||||
void ScriptedInstance::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData)
|
||||
{
|
||||
Map::PlayerList const& lPlayers = instance->GetPlayers();
|
||||
|
||||
if (!lPlayers.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
|
||||
{
|
||||
if (Player* pPlayer = itr->getSource())
|
||||
{
|
||||
pPlayer->SendUpdateWorldState(uiStateId, uiStateData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_log("SD2: DoUpdateWorldState attempt send data but no players in map.");
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the first found Player* (with requested properties) in the map. Can return NULL.
|
||||
Player* ScriptedInstance::GetPlayerInMap(bool bOnlyAlive /*=false*/, bool bCanBeGamemaster /*=true*/)
|
||||
{
|
||||
Map::PlayerList const& lPlayers = instance->GetPlayers();
|
||||
|
||||
for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
|
||||
{
|
||||
Player* pPlayer = itr->getSource();
|
||||
if (pPlayer && (!bOnlyAlive || pPlayer->IsAlive()) && (bCanBeGamemaster || !pPlayer->isGameMaster()))
|
||||
{
|
||||
return pPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Returns a pointer to a loaded GameObject that was stored in m_mGoEntryGuidStore. Can return NULL
|
||||
GameObject* ScriptedInstance::GetSingleGameObjectFromStorage(uint32 uiEntry)
|
||||
{
|
||||
EntryGuidMap::iterator find = m_mGoEntryGuidStore.find(uiEntry);
|
||||
if (find != m_mGoEntryGuidStore.end())
|
||||
{
|
||||
return instance->GetGameObject(find->second);
|
||||
}
|
||||
|
||||
// Output log, possible reason is not added GO to map, or not yet loaded;
|
||||
script_error_log("Script requested gameobject with entry %u, but no gameobject of this entry was created yet, or it was not stored by script for map %u.", uiEntry, instance->GetId());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Returns a pointer to a loaded Creature that was stored in m_mGoEntryGuidStore. Can return NULL
|
||||
Creature* ScriptedInstance::GetSingleCreatureFromStorage(uint32 uiEntry, bool bSkipDebugLog /*=false*/)
|
||||
{
|
||||
EntryGuidMap::iterator find = m_mNpcEntryGuidStore.find(uiEntry);
|
||||
if (find != m_mNpcEntryGuidStore.end())
|
||||
{
|
||||
return instance->GetCreature(find->second);
|
||||
}
|
||||
|
||||
// Output log, possible reason is not added GO to map, or not yet loaded;
|
||||
if (!bSkipDebugLog)
|
||||
{
|
||||
script_error_log("Script requested creature with entry %u, but no npc of this entry was created yet, or it was not stored by script for map %u.", uiEntry, instance->GetId());
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to start a timed achievement criteria for players in the map
|
||||
|
||||
@param criteriaType The Type that is required to complete the criteria, see enum AchievementCriteriaTypes in MaNGOS
|
||||
@param uiTimedCriteriaMiscId The ID that identifies how the criteria is started
|
||||
*/
|
||||
void ScriptedInstance::DoStartTimedAchievement(AchievementCriteriaTypes criteriaType, uint32 uiTimedCriteriaMiscId)
|
||||
{
|
||||
Map::PlayerList const& lPlayers = instance->GetPlayers();
|
||||
|
||||
if (!lPlayers.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
|
||||
{
|
||||
if (Player* pPlayer = itr->getSource())
|
||||
pPlayer->StartTimedAchievementCriteria(criteriaType, uiTimedCriteriaMiscId);
|
||||
}
|
||||
}
|
||||
else
|
||||
debug_log("SD2: DoStartTimedAchievement attempt start achievements but no players in map.");
|
||||
}
|
||||
|
||||
/**
|
||||
Constructor for DialogueHelper
|
||||
|
||||
@param pDialogueArray The static const array of DialogueEntry holding the information about the dialogue. This array MUST be terminated by {0,0,0}
|
||||
*/
|
||||
DialogueHelper::DialogueHelper(DialogueEntry const* pDialogueArray) :
|
||||
m_pInstance(NULL),
|
||||
m_pDialogueArray(pDialogueArray),
|
||||
m_pCurrentEntry(NULL),
|
||||
m_pDialogueTwoSideArray(NULL),
|
||||
m_pCurrentEntryTwoSide(NULL),
|
||||
m_uiTimer(0),
|
||||
m_bIsFirstSide(true),
|
||||
m_bCanSimulate(false)
|
||||
{}
|
||||
|
||||
/**
|
||||
Constructor for DialogueHelper (Two Sides)
|
||||
|
||||
@param pDialogueTwoSideArray The static const array of DialogueEntryTwoSide holding the information about the dialogue. This array MUST be terminated by {0,0,0,0,0}
|
||||
*/
|
||||
DialogueHelper::DialogueHelper(DialogueEntryTwoSide const* pDialogueTwoSideArray) :
|
||||
m_pInstance(NULL),
|
||||
m_pDialogueArray(NULL),
|
||||
m_pCurrentEntry(NULL),
|
||||
m_pDialogueTwoSideArray(pDialogueTwoSideArray),
|
||||
m_pCurrentEntryTwoSide(NULL),
|
||||
m_uiTimer(0),
|
||||
m_bIsFirstSide(true),
|
||||
m_bCanSimulate(false)
|
||||
{}
|
||||
|
||||
/**
|
||||
Function to start a (part of a) dialogue
|
||||
|
||||
@param iTextEntry The TextEntry of the dialogue that will be started (must be always the entry of first side)
|
||||
*/
|
||||
void DialogueHelper::StartNextDialogueText(int32 iTextEntry)
|
||||
{
|
||||
// Find iTextEntry
|
||||
bool bFound = false;
|
||||
|
||||
if (m_pDialogueArray) // One Side
|
||||
{
|
||||
for (DialogueEntry const* pEntry = m_pDialogueArray; pEntry->iTextEntry; ++pEntry)
|
||||
{
|
||||
if (pEntry->iTextEntry == iTextEntry)
|
||||
{
|
||||
m_pCurrentEntry = pEntry;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Two Sides
|
||||
{
|
||||
for (DialogueEntryTwoSide const* pEntry = m_pDialogueTwoSideArray; pEntry->iTextEntry; ++pEntry)
|
||||
{
|
||||
if (pEntry->iTextEntry == iTextEntry)
|
||||
{
|
||||
m_pCurrentEntryTwoSide = pEntry;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
script_error_log("Script call DialogueHelper::StartNextDialogueText, but textEntry %i is not in provided dialogue (on map id %u)", iTextEntry, m_pInstance ? m_pInstance->instance->GetId() : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
DoNextDialogueStep();
|
||||
}
|
||||
|
||||
/// Internal helper function to do the actual say of a DialogueEntry
|
||||
void DialogueHelper::DoNextDialogueStep()
|
||||
{
|
||||
// Last Dialogue Entry done?
|
||||
if ((m_pCurrentEntry && !m_pCurrentEntry->iTextEntry) || (m_pCurrentEntryTwoSide && !m_pCurrentEntryTwoSide->iTextEntry))
|
||||
{
|
||||
m_uiTimer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Text, SpeakerEntry and Timer
|
||||
int32 iTextEntry = 0;
|
||||
uint32 uiSpeakerEntry = 0;
|
||||
|
||||
if (m_pDialogueArray) // One Side
|
||||
{
|
||||
uiSpeakerEntry = m_pCurrentEntry->uiSayerEntry;
|
||||
iTextEntry = m_pCurrentEntry->iTextEntry;
|
||||
|
||||
m_uiTimer = m_pCurrentEntry->uiTimer;
|
||||
}
|
||||
else // Two Sides
|
||||
{
|
||||
// Second Entries can be 0, if they are the entry from first side will be taken
|
||||
uiSpeakerEntry = !m_bIsFirstSide && m_pCurrentEntryTwoSide->uiSayerEntryAlt ? m_pCurrentEntryTwoSide->uiSayerEntryAlt : m_pCurrentEntryTwoSide->uiSayerEntry;
|
||||
iTextEntry = !m_bIsFirstSide && m_pCurrentEntryTwoSide->iTextEntryAlt ? m_pCurrentEntryTwoSide->iTextEntryAlt : m_pCurrentEntryTwoSide->iTextEntry;
|
||||
|
||||
m_uiTimer = m_pCurrentEntryTwoSide->uiTimer;
|
||||
}
|
||||
|
||||
// Simulate Case
|
||||
if (uiSpeakerEntry && iTextEntry < 0)
|
||||
{
|
||||
// Use Speaker if directly provided
|
||||
Creature* pSpeaker = GetSpeakerByEntry(uiSpeakerEntry);
|
||||
if (m_pInstance && !pSpeaker) // Get Speaker from instance
|
||||
{
|
||||
if (m_bCanSimulate) // Simulate case
|
||||
{
|
||||
m_pInstance->DoOrSimulateScriptTextForThisInstance(iTextEntry, uiSpeakerEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
pSpeaker = m_pInstance->GetSingleCreatureFromStorage(uiSpeakerEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if (pSpeaker)
|
||||
{
|
||||
DoScriptText(iTextEntry, pSpeaker);
|
||||
}
|
||||
}
|
||||
|
||||
JustDidDialogueStep(m_pDialogueArray ? m_pCurrentEntry->iTextEntry : m_pCurrentEntryTwoSide->iTextEntry);
|
||||
|
||||
// Increment position
|
||||
if (m_pDialogueArray)
|
||||
{
|
||||
++m_pCurrentEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_pCurrentEntryTwoSide;
|
||||
}
|
||||
}
|
||||
|
||||
/// Call this function within any DialogueUpdate method. This is required for saying next steps in a dialogue
|
||||
void DialogueHelper::DialogueUpdate(uint32 uiDiff)
|
||||
{
|
||||
if (m_uiTimer)
|
||||
{
|
||||
if (m_uiTimer <= uiDiff)
|
||||
{
|
||||
DoNextDialogueStep();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
156
src/modules/SD2/include/sc_instance.h
Normal file
156
src/modules/SD2/include/sc_instance.h
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef SC_INSTANCE_H
|
||||
#define SC_INSTANCE_H
|
||||
|
||||
#include "InstanceData.h"
|
||||
#include "Map.h"
|
||||
|
||||
enum EncounterState
|
||||
{
|
||||
NOT_STARTED = 0,
|
||||
IN_PROGRESS = 1,
|
||||
FAIL = 2,
|
||||
DONE = 3,
|
||||
SPECIAL = 4
|
||||
};
|
||||
|
||||
#define OUT_SAVE_INST_DATA debug_log("SD2: Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
|
||||
#define OUT_SAVE_INST_DATA_COMPLETE debug_log("SD2: Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
|
||||
#define OUT_LOAD_INST_DATA(a) debug_log("SD2: Loading Instance Data for Instance %s (Map %d, Instance Id %d). Input is '%s'", instance->GetMapName(), instance->GetId(), instance->GetInstanceId(), a)
|
||||
#define OUT_LOAD_INST_DATA_COMPLETE debug_log("SD2: Instance Data for Instance %s (Map %d, Instance Id: %d) is loaded.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
|
||||
#define OUT_LOAD_INST_DATA_FAIL script_error_log("Unable to load Instance Data for Instance %s (Map %d, Instance Id: %d).", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
|
||||
|
||||
class ScriptedInstance : public InstanceData
|
||||
{
|
||||
public:
|
||||
ScriptedInstance(Map* pMap) : InstanceData(pMap) {}
|
||||
~ScriptedInstance() {}
|
||||
|
||||
// Default accessor functions
|
||||
GameObject* GetSingleGameObjectFromStorage(uint32 uiEntry);
|
||||
Creature* GetSingleCreatureFromStorage(uint32 uiEntry, bool bSkipDebugLog = false);
|
||||
|
||||
// Change active state of doors or buttons
|
||||
void DoUseDoorOrButton(ObjectGuid guid, uint32 uiWithRestoreTime = 0, bool bUseAlternativeState = false);
|
||||
void DoUseDoorOrButton(uint32 uiEntry, uint32 uiWithRestoreTime = 0, bool bUseAlternativeState = false);
|
||||
|
||||
// Respawns a GO having negative spawntimesecs in gameobject-table
|
||||
void DoRespawnGameObject(ObjectGuid guid, uint32 uiTimeToDespawn = MINUTE);
|
||||
void DoRespawnGameObject(uint32 uiEntry, uint32 uiTimeToDespawn = MINUTE);
|
||||
|
||||
// Toggle the flags of a GO
|
||||
void DoToggleGameObjectFlags(ObjectGuid guid, uint32 uiGOflags, bool bApply);
|
||||
void DoToggleGameObjectFlags(uint32 uiEntry, uint32 uiGOflags, bool bApply);
|
||||
|
||||
// Sends world state update to all players in instance
|
||||
void DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData);
|
||||
|
||||
// Get a Player from map
|
||||
Player* GetPlayerInMap(bool bOnlyAlive = false, bool bCanBeGamemaster = true);
|
||||
|
||||
/// Wrapper for simulating map-wide text in this instance. It is expected that the Creature is stored in m_mNpcEntryGuidStore if loaded.
|
||||
void DoOrSimulateScriptTextForThisInstance(int32 iTextEntry, uint32 uiCreatureEntry)
|
||||
{
|
||||
// Prevent debug output in GetSingleCreatureFromStorage
|
||||
DoOrSimulateScriptTextForMap(iTextEntry, uiCreatureEntry, instance, GetSingleCreatureFromStorage(uiCreatureEntry, true));
|
||||
}
|
||||
|
||||
// Starts a timed achievement criteria for all players in instance
|
||||
void DoStartTimedAchievement(AchievementCriteriaTypes criteriaType, uint32 uiTimedCriteriaMiscId);
|
||||
|
||||
protected:
|
||||
// Storage for GO-Guids and NPC-Guids
|
||||
typedef std::map<uint32, ObjectGuid> EntryGuidMap;
|
||||
EntryGuidMap m_mGoEntryGuidStore; ///< Store unique GO-Guids by entry
|
||||
EntryGuidMap m_mNpcEntryGuidStore; ///< Store unique NPC-Guids by entry
|
||||
};
|
||||
|
||||
// Class for world maps (May need additional zone-wide functions later on)
|
||||
class ScriptedMap : public ScriptedInstance
|
||||
{
|
||||
public:
|
||||
ScriptedMap(Map* pMap) : ScriptedInstance(pMap) {}
|
||||
};
|
||||
|
||||
/// A static const array of this structure must be handled to DialogueHelper
|
||||
struct DialogueEntry
|
||||
{
|
||||
int32 iTextEntry; ///< To be said text entry
|
||||
uint32 uiSayerEntry; ///< Entry of the mob who should say
|
||||
uint32 uiTimer; ///< Time delay until next text of array is said (0 stops)
|
||||
};
|
||||
|
||||
/// A static const array of this structure must be handled to DialogueHelper
|
||||
struct DialogueEntryTwoSide
|
||||
{
|
||||
int32 iTextEntry; ///< To be said text entry (first side)
|
||||
uint32 uiSayerEntry; ///< Entry of the mob who should say (first side)
|
||||
int32 iTextEntryAlt; ///< To be said text entry (second side)
|
||||
uint32 uiSayerEntryAlt; ///< Entry of the mob who should say (second side)
|
||||
uint32 uiTimer; ///< Time delay until next text of array is said (0 stops)
|
||||
};
|
||||
|
||||
/// Helper class handling a dialogue given as static const array of DialogueEntry or DialogueEntryTwoSide
|
||||
class DialogueHelper
|
||||
{
|
||||
public:
|
||||
// The array MUST be terminated by {0,0,0}
|
||||
DialogueHelper(DialogueEntry const* pDialogueArray);
|
||||
// The array MUST be terminated by {0,0,0,0,0}
|
||||
DialogueHelper(DialogueEntryTwoSide const* aDialogueTwoSide);
|
||||
|
||||
/// Function to initialize the dialogue helper for instances. If not used with instances, GetSpeakerByEntry MUST be overwritten to obtain the speakers
|
||||
void InitializeDialogueHelper(ScriptedInstance* pInstance, bool bCanSimulateText = false) { m_pInstance = pInstance; m_bCanSimulate = bCanSimulateText; }
|
||||
/// Set if take first entries or second entries
|
||||
void SetDialogueSide(bool bIsFirstSide) { m_bIsFirstSide = bIsFirstSide; }
|
||||
|
||||
void StartNextDialogueText(int32 iTextEntry);
|
||||
|
||||
void DialogueUpdate(uint32 uiDiff);
|
||||
|
||||
protected:
|
||||
/// Will be called when a dialogue step was done
|
||||
virtual void JustDidDialogueStep(int32 /*iEntry*/) {}
|
||||
/// Will be called to get a speaker, MUST be implemented if not used in instances
|
||||
virtual Creature* GetSpeakerByEntry(uint32 /*uiEntry*/) { return NULL; }
|
||||
|
||||
private:
|
||||
void DoNextDialogueStep();
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
DialogueEntry const* m_pDialogueArray;
|
||||
DialogueEntry const* m_pCurrentEntry;
|
||||
DialogueEntryTwoSide const* m_pDialogueTwoSideArray;
|
||||
DialogueEntryTwoSide const* m_pCurrentEntryTwoSide;
|
||||
|
||||
uint32 m_uiTimer;
|
||||
bool m_bIsFirstSide;
|
||||
bool m_bCanSimulate;
|
||||
};
|
||||
|
||||
#endif
|
||||
132
src/modules/SD2/scripts/battlegrounds/battleground.cpp
Normal file
132
src/modules/SD2/scripts/battlegrounds/battleground.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ScriptData
|
||||
* SDName: Battleground
|
||||
* SD%Complete: 100
|
||||
* SDComment: Spirit guides in battlegrounds will revive all players every 30 sec.
|
||||
* SDCategory: Battlegrounds
|
||||
* EndScriptData
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
/**
|
||||
* Script Info
|
||||
*
|
||||
* Spirit guides in battlegrounds resurrecting many players at once every 30
|
||||
* seconds through a channeled spell, which gets autocasted the whole time.
|
||||
*
|
||||
* If a spirit guide despawns all players around him will get teleported to
|
||||
* the next spirit guide.
|
||||
*
|
||||
* this script handles gossipHello and JustDied also allows autocast of the
|
||||
* channeled spell.
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_SPIRIT_HEAL_CHANNEL = 22011, // Spirit Heal Channel
|
||||
|
||||
SPELL_SPIRIT_HEAL = 22012, // Spirit Heal
|
||||
SPELL_SPIRIT_HEAL_MANA = 44535, // in battlegrounds player get this no-mana-cost-buff
|
||||
|
||||
SPELL_WAITING_TO_RESURRECT = 2584 // players who cancel this aura don't want a resurrection
|
||||
};
|
||||
|
||||
struct npc_spirit_guideAI : public ScriptedAI
|
||||
{
|
||||
npc_spirit_guideAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pCreature->SetActiveObjectState(true);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset() override {}
|
||||
|
||||
void UpdateAI(const uint32 /*uiDiff*/) override
|
||||
{
|
||||
// auto cast the whole time this spell
|
||||
if (!m_creature->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
{
|
||||
m_creature->CastSpell(m_creature, SPELL_SPIRIT_HEAL_CHANNEL, false);
|
||||
}
|
||||
}
|
||||
|
||||
void CorpseRemoved(uint32&) override
|
||||
{
|
||||
// TODO: would be better to cast a dummy spell
|
||||
Map* pMap = m_creature->GetMap();
|
||||
|
||||
if (!pMap || !pMap->IsBattleGround())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Map::PlayerList const& PlayerList = pMap->GetPlayers();
|
||||
|
||||
for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
|
||||
{
|
||||
Player* pPlayer = itr->getSource();
|
||||
if (!pPlayer || !pPlayer->IsWithinDistInMap(m_creature, 20.0f) || !pPlayer->HasAura(SPELL_WAITING_TO_RESURRECT))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// repop player again - now this node won't be counted and another node is searched
|
||||
pPlayer->RepopAtGraveyard();
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* pUnit, const SpellEntry* pSpellEntry) override
|
||||
{
|
||||
if (pSpellEntry->Id == SPELL_SPIRIT_HEAL && pUnit->GetTypeId() == TYPEID_PLAYER
|
||||
&& pUnit->HasAura(SPELL_WAITING_TO_RESURRECT))
|
||||
{ pUnit->CastSpell(pUnit, SPELL_SPIRIT_HEAL_MANA, true); }
|
||||
}
|
||||
};
|
||||
|
||||
bool GossipHello_npc_spirit_guide(Player* pPlayer, Creature* /*pCreature*/)
|
||||
{
|
||||
pPlayer->CastSpell(pPlayer, SPELL_WAITING_TO_RESURRECT, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_npc_spirit_guide(Creature* pCreature)
|
||||
{
|
||||
return new npc_spirit_guideAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_battleground()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_spirit_guide";
|
||||
pNewScript->GetAI = &GetAI_npc_spirit_guide;
|
||||
pNewScript->pGossipHello = &GossipHello_npc_spirit_guide;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ScriptData
|
||||
* SDName: Alterac_Mountains
|
||||
* SD%Complete: 0
|
||||
* SDComment: Placeholder
|
||||
* SDCategory: Alterac Mountains
|
||||
* EndScriptData
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentData
|
||||
* EndContentData
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_alterac_mountains()
|
||||
{
|
||||
}
|
||||
279
src/modules/SD2/scripts/eastern_kingdoms/arathi_highlands.cpp
Normal file
279
src/modules/SD2/scripts/eastern_kingdoms/arathi_highlands.cpp
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ScriptData
|
||||
* SDName: Arathi Highlands
|
||||
* SD%Complete: 100
|
||||
* SDComment: Quest support: 660, 665
|
||||
* SDCategory: Arathi Highlands
|
||||
* EndScriptData
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentData
|
||||
* npc_professor_phizzlethorpe
|
||||
* npc_kinelory
|
||||
* EndContentData
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "escort_ai.h"
|
||||
|
||||
/*######
|
||||
## npc_professor_phizzlethorpe
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_PROGRESS_1 = -1000264,
|
||||
SAY_PROGRESS_2 = -1000265,
|
||||
SAY_PROGRESS_3 = -1000266,
|
||||
EMOTE_PROGRESS_4 = -1000267,
|
||||
SAY_AGGRO = -1000268,
|
||||
SAY_PROGRESS_5 = -1000269,
|
||||
SAY_PROGRESS_6 = -1000270,
|
||||
SAY_PROGRESS_7 = -1000271,
|
||||
EMOTE_PROGRESS_8 = -1000272,
|
||||
SAY_PROGRESS_9 = -1000273,
|
||||
|
||||
QUEST_SUNKEN_TREASURE = 665,
|
||||
ENTRY_VENGEFUL_SURGE = 2776
|
||||
};
|
||||
|
||||
struct npc_professor_phizzlethorpeAI : public npc_escortAI
|
||||
{
|
||||
npc_professor_phizzlethorpeAI(Creature* pCreature) : npc_escortAI(pCreature) { Reset(); }
|
||||
|
||||
void Reset() override { }
|
||||
|
||||
void WaypointReached(uint32 uiPointId) override
|
||||
{
|
||||
Player* pPlayer = GetPlayerForEscort();
|
||||
|
||||
if (!pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (uiPointId)
|
||||
{
|
||||
case 4:
|
||||
DoScriptText(SAY_PROGRESS_2, m_creature, pPlayer);
|
||||
break;
|
||||
case 5:
|
||||
DoScriptText(SAY_PROGRESS_3, m_creature, pPlayer);
|
||||
break;
|
||||
case 8:
|
||||
DoScriptText(EMOTE_PROGRESS_4, m_creature);
|
||||
break;
|
||||
case 9:
|
||||
m_creature->SummonCreature(ENTRY_VENGEFUL_SURGE, -2056.41f, -2144.01f, 20.59f, 5.70f, TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, 600000);
|
||||
m_creature->SummonCreature(ENTRY_VENGEFUL_SURGE, -2050.17f, -2140.02f, 19.54f, 5.17f, TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, 600000);
|
||||
break;
|
||||
case 10:
|
||||
DoScriptText(SAY_PROGRESS_5, m_creature, pPlayer);
|
||||
break;
|
||||
case 11:
|
||||
DoScriptText(SAY_PROGRESS_6, m_creature, pPlayer);
|
||||
SetRun();
|
||||
break;
|
||||
case 19:
|
||||
DoScriptText(SAY_PROGRESS_7, m_creature, pPlayer);
|
||||
break;
|
||||
case 20:
|
||||
DoScriptText(EMOTE_PROGRESS_8, m_creature);
|
||||
DoScriptText(SAY_PROGRESS_9, m_creature, pPlayer);
|
||||
pPlayer->GroupEventHappens(QUEST_SUNKEN_TREASURE, m_creature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
pSummoned->AI()->AttackStart(m_creature);
|
||||
}
|
||||
};
|
||||
|
||||
bool QuestAccept_npc_professor_phizzlethorpe(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_SUNKEN_TREASURE)
|
||||
{
|
||||
pCreature->SetFactionTemporary(FACTION_ESCORT_N_NEUTRAL_PASSIVE, TEMPFACTION_RESTORE_RESPAWN);
|
||||
DoScriptText(SAY_PROGRESS_1, pCreature, pPlayer);
|
||||
|
||||
if (npc_professor_phizzlethorpeAI* pEscortAI = dynamic_cast<npc_professor_phizzlethorpeAI*>(pCreature->AI()))
|
||||
{
|
||||
pEscortAI->Start(false, pPlayer, pQuest, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_npc_professor_phizzlethorpe(Creature* pCreature)
|
||||
{
|
||||
return new npc_professor_phizzlethorpeAI(pCreature);
|
||||
}
|
||||
|
||||
/*######
|
||||
## npc_kinelory
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_START = -1000948,
|
||||
SAY_REACH_BOTTOM = -1000949,
|
||||
SAY_AGGRO_KINELORY = -1000950,
|
||||
SAY_AGGRO_JORELL = -1000951,
|
||||
SAY_WATCH_BACK = -1000952,
|
||||
EMOTE_BELONGINGS = -1000953,
|
||||
SAY_DATA_FOUND = -1000954,
|
||||
SAY_ESCAPE = -1000955,
|
||||
SAY_FINISH = -1000956,
|
||||
EMOTE_HAND_PACK = -1000957,
|
||||
|
||||
// ToDo: find the healing spell id!
|
||||
SPELL_BEAR_FORM = 4948,
|
||||
|
||||
NPC_JORELL = 2733,
|
||||
NPC_QUAE = 2712,
|
||||
|
||||
QUEST_HINTS_NEW_PLAGUE = 660
|
||||
};
|
||||
|
||||
struct npc_kineloryAI : public npc_escortAI
|
||||
{
|
||||
npc_kineloryAI(Creature* pCreature) : npc_escortAI(pCreature) { Reset(); }
|
||||
|
||||
uint32 m_uiBearFormTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiBearFormTimer = urand(1000, 5000);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 uiPointId) override
|
||||
{
|
||||
switch (uiPointId)
|
||||
{
|
||||
case 9:
|
||||
DoScriptText(SAY_REACH_BOTTOM, m_creature);
|
||||
break;
|
||||
case 16:
|
||||
DoScriptText(SAY_WATCH_BACK, m_creature);
|
||||
DoScriptText(EMOTE_BELONGINGS, m_creature);
|
||||
break;
|
||||
case 17:
|
||||
DoScriptText(SAY_DATA_FOUND, m_creature);
|
||||
break;
|
||||
case 18:
|
||||
DoScriptText(SAY_ESCAPE, m_creature);
|
||||
if (Player* pPlayer = GetPlayerForEscort())
|
||||
{ m_creature->SetFacingToObject(pPlayer); }
|
||||
SetRun();
|
||||
break;
|
||||
case 33:
|
||||
DoScriptText(SAY_FINISH, m_creature);
|
||||
if (Creature* pQuae = GetClosestCreatureWithEntry(m_creature, NPC_QUAE, 10.0f))
|
||||
{
|
||||
DoScriptText(EMOTE_HAND_PACK, m_creature, pQuae);
|
||||
m_creature->SetFacingToObject(pQuae);
|
||||
}
|
||||
break;
|
||||
case 34:
|
||||
if (Player* pPlayer = GetPlayerForEscort())
|
||||
{ pPlayer->GroupEventHappens(QUEST_HINTS_NEW_PLAGUE, m_creature); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (pWho->GetEntry() == NPC_JORELL)
|
||||
{ DoScriptText(SAY_AGGRO_JORELL, pWho, m_creature); }
|
||||
else if (roll_chance_i(10))
|
||||
{ DoScriptText(SAY_AGGRO_KINELORY, m_creature); }
|
||||
}
|
||||
|
||||
void ReceiveAIEvent(AIEventType eventType, Creature* /*pSender*/, Unit* pInvoker, uint32 uiMiscValue) override
|
||||
{
|
||||
if (eventType == AI_EVENT_START_ESCORT && pInvoker->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
DoScriptText(SAY_START, m_creature);
|
||||
Start(false, (Player*)pInvoker, GetQuestTemplateStore(uiMiscValue), true);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEscortAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{ return; }
|
||||
|
||||
if (m_uiBearFormTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_BEAR_FORM) == CAST_OK)
|
||||
{ m_uiBearFormTimer = urand(25000, 30000); }
|
||||
}
|
||||
else
|
||||
{ m_uiBearFormTimer -= uiDiff; }
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_kinelory(Creature* pCreature)
|
||||
{
|
||||
return new npc_kineloryAI(pCreature);
|
||||
}
|
||||
|
||||
bool QuestAccept_npc_kinelory(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_HINTS_NEW_PLAGUE)
|
||||
{ pCreature->AI()->SendAIEvent(AI_EVENT_START_ESCORT, pPlayer, pCreature, pQuest->GetQuestId()); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_arathi_highlands()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_professor_phizzlethorpe";
|
||||
pNewScript->GetAI = &GetAI_npc_professor_phizzlethorpe;
|
||||
pNewScript->pQuestAcceptNPC = &QuestAccept_npc_professor_phizzlethorpe;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_kinelory";
|
||||
pNewScript->GetAI = &GetAI_npc_kinelory;
|
||||
pNewScript->pQuestAcceptNPC = &QuestAccept_npc_kinelory;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: ascendant_council
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Bastion of Twilight
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_ascendant_council()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_chogall
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Bastion of Twilight
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_chogall()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_halfus_wyrmbreaker
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Bastion of Twilight
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_halfus_wyrmbreaker()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_sinestra
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Bastion of Twilight
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_sinestra()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_valiona_and_theralion
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Bastion of Twilight
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_valiona_and_theralion()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: instance_bastion_of_twilight
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Bastion of Twilight
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_instance_bastion_of_twilight()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
||||
#ifndef DEF_BLACKROCK_CAVERNS_H
|
||||
#define DEF_BLACKROCK_CAVERNS_H
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_ENCOUNTER = 5,
|
||||
|
||||
TYPE_ROMOGG = 0,
|
||||
TYPE_CORLA = 1,
|
||||
TYPE_KARSH = 2,
|
||||
TYPE_BEAUTY = 3,
|
||||
TYPE_OBSIDIUS = 4,
|
||||
|
||||
NPC_ROMOGG = 39665,
|
||||
NPC_CORLA = 39679,
|
||||
NPC_KARSH = 39698,
|
||||
NPC_BEAUTY = 39700,
|
||||
NPC_OBSIDIUS = 39705,
|
||||
};
|
||||
|
||||
class instance_blackrock_caverns : public ScriptedInstance
|
||||
{
|
||||
public:
|
||||
instance_blackrock_caverns(Map* pMap);
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature) override;
|
||||
void OnObjectCreate(GameObject* pGo) override;
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData) override;
|
||||
uint32 GetData(uint32 uiType) const override;
|
||||
|
||||
const char* Save() const override { return m_strInstData.c_str(); }
|
||||
void Load(const char* chrIn) override;
|
||||
|
||||
private:
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
std::string m_strInstData;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_beauty
|
||||
SD%Complete: 10
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackrock Caverns
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_caverns.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// ToDo: add spells and yells here
|
||||
};
|
||||
|
||||
struct boss_beautyAI : public ScriptedAI
|
||||
{
|
||||
boss_beautyAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
bool m_bIsRegularMode;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BEAUTY, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BEAUTY, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BEAUTY, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_beauty(Creature* pCreature)
|
||||
{
|
||||
return new boss_beautyAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_beauty()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_beauty";
|
||||
pNewScript->GetAI = &GetAI_boss_beauty;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_corla
|
||||
SD%Complete: 10
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackrock Caverns
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_caverns.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// ToDo: add spells and yells here
|
||||
};
|
||||
|
||||
struct boss_corlaAI : public ScriptedAI
|
||||
{
|
||||
boss_corlaAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
bool m_bIsRegularMode;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_CORLA, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_CORLA, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_CORLA, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_corla(Creature* pCreature)
|
||||
{
|
||||
return new boss_corlaAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_corla()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_corla";
|
||||
pNewScript->GetAI = &GetAI_boss_corla;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_karsh_steelbender
|
||||
SD%Complete: 10
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackrock Caverns
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_caverns.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// ToDo: add spells and yells here
|
||||
};
|
||||
|
||||
struct boss_karsh_steelbenderAI : public ScriptedAI
|
||||
{
|
||||
boss_karsh_steelbenderAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
bool m_bIsRegularMode;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KARSH, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KARSH, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KARSH, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_karsh_steelbender(Creature* pCreature)
|
||||
{
|
||||
return new boss_karsh_steelbenderAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_karsh_steelbender()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_karsh_steelbender";
|
||||
pNewScript->GetAI = &GetAI_boss_karsh_steelbender;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_lord_obsidius
|
||||
SD%Complete: 10
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackrock Caverns
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_caverns.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// ToDo: add spells and yells here
|
||||
};
|
||||
|
||||
struct boss_lord_obsidiusAI : public ScriptedAI
|
||||
{
|
||||
boss_lord_obsidiusAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
bool m_bIsRegularMode;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_OBSIDIUS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_OBSIDIUS, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_OBSIDIUS, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_lord_obsidius(Creature* pCreature)
|
||||
{
|
||||
return new boss_lord_obsidiusAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_lord_obsidius()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_lord_obsidius";
|
||||
pNewScript->GetAI = &GetAI_boss_lord_obsidius;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_romogg
|
||||
SD%Complete: 10
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackrock Caverns
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_caverns.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// ToDo: add spells and yells here
|
||||
};
|
||||
|
||||
struct boss_romoggAI : public ScriptedAI
|
||||
{
|
||||
boss_romoggAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
bool m_bIsRegularMode;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_ROMOGG, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_ROMOGG, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_ROMOGG, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_romogg(Creature* pCreature)
|
||||
{
|
||||
return new boss_romoggAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_romogg()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_romogg";
|
||||
pNewScript->GetAI = &GetAI_boss_romogg;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: instance_blackrock_caverns
|
||||
SD%Complete: 10
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackrock Caverns
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_caverns.h"
|
||||
|
||||
instance_blackrock_caverns::instance_blackrock_caverns(Map* pMap) : ScriptedInstance(pMap)
|
||||
{
|
||||
Initialize();
|
||||
};
|
||||
|
||||
void instance_blackrock_caverns::Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
}
|
||||
|
||||
void instance_blackrock_caverns::OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
// ToDo: add Creature references here
|
||||
}
|
||||
|
||||
void instance_blackrock_caverns::OnObjectCreate(GameObject* pGo)
|
||||
{
|
||||
// ToDo: add Gameobject references here
|
||||
}
|
||||
|
||||
void instance_blackrock_caverns::SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case TYPE_ROMOGG:
|
||||
case TYPE_CORLA:
|
||||
case TYPE_KARSH:
|
||||
case TYPE_BEAUTY:
|
||||
case TYPE_OBSIDIUS:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiData == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
|
||||
<< m_auiEncounter[3] << " " << m_auiEncounter[4];
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 instance_blackrock_caverns::GetData(uint32 uiType) const
|
||||
{
|
||||
if (uiType < MAX_ENCOUNTER)
|
||||
return m_auiEncounter[uiType];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void instance_blackrock_caverns::Load(const char* chrIn)
|
||||
{
|
||||
if (!chrIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(chrIn);
|
||||
|
||||
std::istringstream loadStream(chrIn);
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
|
||||
>> m_auiEncounter[4];
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
InstanceData* GetInstanceData_instance_blackrock_caverns(Map* pMap)
|
||||
{
|
||||
return new instance_blackrock_caverns(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_blackrock_caverns()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "instance_blackrock_caverns";
|
||||
pNewScript->GetInstanceData = &GetInstanceData_instance_blackrock_caverns;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,164 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
||||
#ifndef DEF_BRD_H
|
||||
#define DEF_BRD_H
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_ENCOUNTER = 7,
|
||||
MAX_RELIC_DOORS = 12,
|
||||
MAX_DWARFS = 7,
|
||||
|
||||
TYPE_RING_OF_LAW = 1,
|
||||
TYPE_VAULT = 2,
|
||||
TYPE_BAR = 3,
|
||||
TYPE_TOMB_OF_SEVEN = 4,
|
||||
TYPE_LYCEUM = 5,
|
||||
TYPE_IRON_HALL = 6,
|
||||
TYPE_QUEST_JAIL_BREAK = 7,
|
||||
|
||||
NPC_EMPEROR = 9019,
|
||||
NPC_PRINCESS = 8929,
|
||||
NPC_PHALANX = 9502,
|
||||
NPC_HATEREL = 9034,
|
||||
NPC_ANGERREL = 9035,
|
||||
NPC_VILEREL = 9036,
|
||||
NPC_GLOOMREL = 9037,
|
||||
NPC_SEETHREL = 9038,
|
||||
NPC_DOOMREL = 9039,
|
||||
NPC_DOPEREL = 9040,
|
||||
NPC_MAGMUS = 9938,
|
||||
NPC_WATCHER_DOOMGRIP = 9476,
|
||||
NPC_WARBRINGER_CONST = 8905, // Four of them in Relict Vault are related to Doomgrip summon event
|
||||
|
||||
// Jail Break event related
|
||||
NPC_OGRABISI = 9677,
|
||||
NPC_SHILL = 9678,
|
||||
NPC_CREST = 9680,
|
||||
NPC_JAZ = 9681,
|
||||
NPC_TOBIAS = 9679,
|
||||
NPC_DUGHAL = 9022,
|
||||
|
||||
GO_ARENA_1 = 161525,
|
||||
GO_ARENA_2 = 161522,
|
||||
GO_ARENA_3 = 161524,
|
||||
GO_ARENA_4 = 161523,
|
||||
|
||||
GO_SHADOW_LOCK = 161460,
|
||||
GO_SHADOW_MECHANISM = 161461,
|
||||
GO_SHADOW_GIANT_DOOR = 157923,
|
||||
GO_SHADOW_DUMMY = 161516,
|
||||
GO_BAR_KEG_SHOT = 170607,
|
||||
GO_BAR_KEG_TRAP = 171941,
|
||||
GO_BAR_DOOR = 170571,
|
||||
GO_TOMB_ENTER = 170576,
|
||||
GO_TOMB_EXIT = 170577,
|
||||
GO_LYCEUM = 170558,
|
||||
GO_GOLEM_ROOM_N = 170573,
|
||||
GO_GOLEM_ROOM_S = 170574,
|
||||
GO_THRONE_ROOM = 170575,
|
||||
|
||||
GO_SPECTRAL_CHALICE = 164869,
|
||||
GO_CHEST_SEVEN = 169243,
|
||||
GO_ARENA_SPOILS = 181074,
|
||||
GO_SECRET_DOOR = 174553,
|
||||
|
||||
// Jail break event related
|
||||
GO_JAIL_DOOR_SUPPLY = 170561,
|
||||
GO_JAIL_SUPPLY_CRATE = 166872,
|
||||
|
||||
SPELL_STONED = 10255, // Aura of Warbringer Constructs in Relict Vault
|
||||
|
||||
FACTION_DWARF_HOSTILE = 754, // Hostile faction for the Tomb of the Seven dwarfs
|
||||
};
|
||||
|
||||
enum ArenaNPCs
|
||||
{
|
||||
// Gladiators
|
||||
NPC_LEFTY = 16049,
|
||||
NPC_ROTFANG = 16050,
|
||||
NPC_SNOKH = 16051,
|
||||
NPC_MALGEN = 16052,
|
||||
NPC_KORV = 16053,
|
||||
NPC_REZZNIK = 16054,
|
||||
NPC_VAJASHNI = 16055,
|
||||
NPC_VOLIDA = 16058,
|
||||
NPC_THELDREN = 16059,
|
||||
// Ring mobs
|
||||
NPC_WORM = 8925,
|
||||
NPC_STINGER = 8926,
|
||||
NPC_SCREECHER = 8927,
|
||||
NPC_THUNDERSNOUT = 8928,
|
||||
NPC_CREEPER = 8933,
|
||||
NPC_BEETLE = 8932,
|
||||
// Ring bosses
|
||||
NPC_GOROSH = 9027,
|
||||
NPC_GRIZZLE = 9028,
|
||||
NPC_EVISCERATOR = 9029,
|
||||
NPC_OKTHOR = 9030,
|
||||
NPC_ANUBSHIAH = 9031,
|
||||
NPC_HEDRUM = 9032
|
||||
};
|
||||
|
||||
static const uint32 aArenaNPCs[] =
|
||||
{
|
||||
// Gladiators
|
||||
NPC_LEFTY, NPC_ROTFANG, NPC_SNOKH, NPC_MALGEN, NPC_KORV, NPC_REZZNIK, NPC_VAJASHNI, NPC_VOLIDA, NPC_THELDREN,
|
||||
// Ring mobs
|
||||
NPC_WORM, NPC_STINGER, NPC_SCREECHER, NPC_THUNDERSNOUT, NPC_CREEPER, NPC_BEETLE,
|
||||
// Ring bosses
|
||||
NPC_GOROSH, NPC_GRIZZLE, NPC_EVISCERATOR, NPC_OKTHOR, NPC_ANUBSHIAH, NPC_HEDRUM
|
||||
};
|
||||
|
||||
// Used to summon Watcher Doomgrip
|
||||
static const float aVaultPositions[4] = {821.905f, -338.382f, -50.134f, 3.78736f};
|
||||
|
||||
// Tomb of the Seven dwarfs
|
||||
static const uint32 aTombDwarfes[MAX_DWARFS] = {NPC_ANGERREL, NPC_SEETHREL, NPC_DOPEREL, NPC_GLOOMREL, NPC_VILEREL, NPC_HATEREL, NPC_DOOMREL};
|
||||
|
||||
class instance_blackrock_depths : public ScriptedInstance
|
||||
{
|
||||
public:
|
||||
instance_blackrock_depths(Map* pMap);
|
||||
~instance_blackrock_depths() {}
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature) override;
|
||||
void OnCreatureEnterCombat(Creature* pCreature) override;
|
||||
void OnCreatureDeath(Creature* pCreature) override;
|
||||
void OnCreatureEvade(Creature* pCreature);
|
||||
void OnObjectCreate(GameObject* pGo) override;
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData) override;
|
||||
uint32 GetData(uint32 uiType) const override;
|
||||
|
||||
const char* Save() const override { return m_strInstData.c_str(); }
|
||||
void Load(const char* chrIn) override;
|
||||
|
||||
void Update(uint32 uiDiff) override;
|
||||
|
||||
// Arena Event
|
||||
void SetArenaCenterCoords(float fX, float fY, float fZ) { m_fArenaCenterX = fX; m_fArenaCenterY = fY; m_fArenaCenterZ = fZ; }
|
||||
void GetArenaCenterCoords(float& fX, float& fY, float& fZ) { fX = m_fArenaCenterX; fY = m_fArenaCenterY; fZ = m_fArenaCenterZ; }
|
||||
|
||||
private:
|
||||
void DoCallNextDwarf();
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
std::string m_strInstData;
|
||||
|
||||
uint32 m_uiBarAleCount;
|
||||
uint8 m_uiCofferDoorsOpened;
|
||||
|
||||
uint8 m_uiDwarfRound;
|
||||
uint32 m_uiDwarfFightTimer;
|
||||
|
||||
float m_fArenaCenterX, m_fArenaCenterY, m_fArenaCenterZ;
|
||||
|
||||
GuidSet m_sVaultNpcGuids;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Ambassador_Flamelash
|
||||
SD%Complete: 80
|
||||
SDComment: Texts missing, Add handling rather guesswork, Add spell Burning Spirit likely won't work
|
||||
SDCategory: Blackrock Depths
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_FIREBLAST = 15573,
|
||||
SPELL_BURNING_SPIRIT = 13489,
|
||||
SPELL_BURNING_SPIRIT_BUFF = 14744,
|
||||
|
||||
NPC_BURNING_SPIRIT = 9178,
|
||||
};
|
||||
|
||||
struct boss_ambassador_flamelashAI : public ScriptedAI
|
||||
{
|
||||
boss_ambassador_flamelashAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
|
||||
|
||||
uint32 m_uiSpiritTimer;
|
||||
int Rand;
|
||||
int RandX;
|
||||
int RandY;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiSpiritTimer = 12000;
|
||||
}
|
||||
|
||||
void SummonSpirits()
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 30.0f, fX, fY, fZ);
|
||||
m_creature->SummonCreature(NPC_BURNING_SPIRIT, fX, fY, fZ, m_creature->GetAngle(fX, fY) + M_PI_F, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 60000);
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_FIREBLAST);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
pSummoned->GetMotionMaster()->MovePoint(1, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
|
||||
}
|
||||
|
||||
void SummonedMovementInform(Creature* pSummoned, uint32 /*uiMotionType*/, uint32 uiPointId) override
|
||||
{
|
||||
if (uiPointId != 1)
|
||||
return;
|
||||
|
||||
pSummoned->CastSpell(m_creature, SPELL_BURNING_SPIRIT, true);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// m_uiSpiritTimer
|
||||
if (m_uiSpiritTimer < uiDiff)
|
||||
{
|
||||
SummonSpirits();
|
||||
SummonSpirits();
|
||||
SummonSpirits();
|
||||
SummonSpirits();
|
||||
|
||||
m_uiSpiritTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiSpiritTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool EffectDummyCreature_spell_boss_ambassador_flamelash(Unit* /*pCaster*/, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget, ObjectGuid /*originalCasterGuid*/)
|
||||
{
|
||||
if (uiSpellId == SPELL_BURNING_SPIRIT && uiEffIndex == EFFECT_INDEX_1)
|
||||
{
|
||||
pCreatureTarget->CastSpell(pCreatureTarget, SPELL_BURNING_SPIRIT_BUFF, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_ambassador_flamelash(Creature* pCreature)
|
||||
{
|
||||
return new boss_ambassador_flamelashAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_ambassador_flamelash()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_ambassador_flamelash";
|
||||
pNewScript->GetAI = &GetAI_boss_ambassador_flamelash;
|
||||
pNewScript->pEffectDummyNPC = &EffectDummyCreature_spell_boss_ambassador_flamelash;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_coren_direbrew
|
||||
SD%Complete: 75
|
||||
SDComment: Some parts are not complete - requires additional research. Brewmaidens scripts handled in eventAI.
|
||||
SDCategory: Blackrock Depths
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_AGGRO = -1230034,
|
||||
|
||||
// spells
|
||||
SPELL_DIREBREW_DISARM = 47310,
|
||||
SPELL_SUMMON_DIREBREW_MINION = 47375,
|
||||
SPELL_DIREBREW_CHARGE = 47718,
|
||||
SPELL_SUMMON_MOLE_MACHINE = 47691, // triggers 47690
|
||||
|
||||
// summoned auras
|
||||
SPELL_PORT_TO_COREN = 52850,
|
||||
|
||||
// other summoned spells - currently not used in script
|
||||
// SPELL_CHUCK_MUG = 50276,
|
||||
// SPELL_BARRELED_AURA = 50278, // used by Ursula
|
||||
// SPELL_HAS_BREW = 47331, // triggers 47344 - aura which asks for the second brew on item expire
|
||||
// SPELL_SEND_FIRST_MUG = 47333, // triggers 47345
|
||||
// SPELL_SEND_SECOND_MUG = 47339, // triggers 47340 - spell triggered by 47344
|
||||
// SPELL_BREWMAIDEN_DESPAWN_AURA = 48186, // purpose unk
|
||||
|
||||
// npcs
|
||||
NPC_DIREBREW_MINION = 26776,
|
||||
NPC_ILSA_DIREBREW = 26764,
|
||||
NPC_URSULA_DIREBREW = 26822,
|
||||
|
||||
// other
|
||||
FACTION_HOSTILE = 736,
|
||||
|
||||
QUEST_INSULT_COREN = 12062,
|
||||
|
||||
MAX_DIREBREW_MINIONS = 3,
|
||||
};
|
||||
|
||||
struct boss_coren_direbrewAI : public ScriptedAI
|
||||
{
|
||||
boss_coren_direbrewAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
|
||||
|
||||
uint32 m_uiDisarmTimer;
|
||||
uint32 m_uiChargeTimer;
|
||||
uint32 m_uiSummonTimer;
|
||||
uint8 m_uiPhase;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiDisarmTimer = 10000;
|
||||
m_uiChargeTimer = 5000;
|
||||
m_uiSummonTimer = 15000;
|
||||
m_uiPhase = 0;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
// Spawn 3 minions on aggro
|
||||
for (uint8 i = 0; i < MAX_DIREBREW_MINIONS; ++i)
|
||||
DoCastSpellIfCan(m_creature, SPELL_SUMMON_DIREBREW_MINION, CAST_TRIGGERED);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
switch (pSummoned->GetEntry())
|
||||
{
|
||||
case NPC_ILSA_DIREBREW:
|
||||
case NPC_URSULA_DIREBREW:
|
||||
pSummoned->CastSpell(m_creature, SPELL_PORT_TO_COREN, true);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_creature->getVictim())
|
||||
pSummoned->AI()->AttackStart(m_creature->getVictim());
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Spawn Ilsa
|
||||
if (m_creature->GetHealthPercent() < 66.0f && m_uiPhase == 0)
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 10, fX, fY, fZ);
|
||||
m_creature->SummonCreature(NPC_ILSA_DIREBREW, fX, fY, fZ, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
|
||||
m_uiPhase = 1;
|
||||
}
|
||||
|
||||
// Spawn Ursula
|
||||
if (m_creature->GetHealthPercent() < 33.0f && m_uiPhase == 1)
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 10, fX, fY, fZ);
|
||||
m_creature->SummonCreature(NPC_URSULA_DIREBREW, fX, fY, fZ, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
|
||||
m_uiPhase = 2;
|
||||
}
|
||||
|
||||
if (m_uiDisarmTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_DIREBREW_DISARM) == CAST_OK)
|
||||
m_uiDisarmTimer = 15000;
|
||||
}
|
||||
else
|
||||
m_uiDisarmTimer -= uiDiff;
|
||||
|
||||
if (m_uiChargeTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_DIREBREW_CHARGE, SELECT_FLAG_NOT_IN_MELEE_RANGE))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_DIREBREW_CHARGE) == CAST_OK)
|
||||
m_uiChargeTimer = urand(5000, 10000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiChargeTimer -= uiDiff;
|
||||
|
||||
if (m_uiSummonTimer < uiDiff)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_DIREBREW_MINIONS; ++i)
|
||||
DoCastSpellIfCan(m_creature, SPELL_SUMMON_DIREBREW_MINION, CAST_TRIGGERED);
|
||||
|
||||
m_uiSummonTimer = 15000;
|
||||
}
|
||||
else
|
||||
m_uiSummonTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_coren_direbrew(Creature* pCreature)
|
||||
{
|
||||
return new boss_coren_direbrewAI(pCreature);
|
||||
}
|
||||
|
||||
bool QuestRewarded_npc_coren_direbrew(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_INSULT_COREN)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, pCreature, pPlayer);
|
||||
|
||||
pCreature->SetFactionTemporary(FACTION_HOSTILE, TEMPFACTION_RESTORE_REACH_HOME | TEMPFACTION_RESTORE_RESPAWN);
|
||||
pCreature->AI()->AttackStart(pPlayer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_boss_coren_direbrew()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_coren_direbrew";
|
||||
pNewScript->GetAI = &GetAI_boss_coren_direbrew;
|
||||
pNewScript->pQuestRewardedNPC = &QuestRewarded_npc_coren_direbrew;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Emperor_Dagran_Thaurissan
|
||||
SD%Complete: 90
|
||||
SDComment: With script for Moria
|
||||
SDCategory: Blackrock Depths
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_depths.h"
|
||||
|
||||
enum eEmperor
|
||||
{
|
||||
FACTION_NEUTRAL = 734,
|
||||
SAY_AGGRO = -1230001,
|
||||
SAY_SLAY = -1230002,
|
||||
|
||||
SPELL_HANDOFTHAURISSAN = 17492,
|
||||
SPELL_AVATAROFFLAME = 15636
|
||||
};
|
||||
|
||||
struct boss_emperor_dagran_thaurissanAI : public ScriptedAI
|
||||
{
|
||||
boss_emperor_dagran_thaurissanAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiHandOfThaurissan_Timer;
|
||||
uint32 m_uiAvatarOfFlame_Timer;
|
||||
// uint32 m_uiCounter;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiHandOfThaurissan_Timer = 4000;
|
||||
m_uiAvatarOfFlame_Timer = 25000;
|
||||
// m_uiCounter = 0;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
m_creature->CallForHelp(VISIBLE_RANGE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pVictim*/) override
|
||||
{
|
||||
if (!m_pInstance)
|
||||
return;
|
||||
|
||||
if (Creature* pPrincess = m_pInstance->GetSingleCreatureFromStorage(NPC_PRINCESS))
|
||||
{
|
||||
if (pPrincess->IsAlive())
|
||||
{
|
||||
pPrincess->SetFactionTemporary(FACTION_NEUTRAL, TEMPFACTION_NONE);
|
||||
pPrincess->AI()->EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*pVictim*/) override
|
||||
{
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_uiHandOfThaurissan_Timer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
DoCastSpellIfCan(pTarget, SPELL_HANDOFTHAURISSAN);
|
||||
|
||||
// 3 Hands of Thaurissan will be casted
|
||||
// if (m_uiCounter < 3)
|
||||
//{
|
||||
// m_uiHandOfThaurissan_Timer = 1000;
|
||||
// ++m_uiCounter;
|
||||
//}
|
||||
// else
|
||||
//{
|
||||
m_uiHandOfThaurissan_Timer = 5000;
|
||||
// m_uiCounter = 0;
|
||||
//}
|
||||
}
|
||||
else
|
||||
m_uiHandOfThaurissan_Timer -= uiDiff;
|
||||
|
||||
// AvatarOfFlame_Timer
|
||||
if (m_uiAvatarOfFlame_Timer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_AVATAROFFLAME);
|
||||
m_uiAvatarOfFlame_Timer = 18000;
|
||||
}
|
||||
else
|
||||
m_uiAvatarOfFlame_Timer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_emperor_dagran_thaurissan(Creature* pCreature)
|
||||
{
|
||||
return new boss_emperor_dagran_thaurissanAI(pCreature);
|
||||
}
|
||||
|
||||
/*######
|
||||
## boss_moira_bronzebeard
|
||||
######*/
|
||||
|
||||
enum ePrincess
|
||||
{
|
||||
SPELL_HEAL = 15586,
|
||||
SPELL_RENEW = 10929,
|
||||
SPELL_SHIELD = 10901,
|
||||
SPELL_MINDBLAST = 15587,
|
||||
SPELL_SHADOWWORDPAIN = 15654,
|
||||
SPELL_SMITE = 10934,
|
||||
SPELL_SHADOW_BOLT = 15537,
|
||||
SPELL_OPEN_PORTAL = 13912
|
||||
};
|
||||
|
||||
struct boss_moira_bronzebeardAI : public ScriptedAI
|
||||
{
|
||||
boss_moira_bronzebeardAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiHeal_Timer;
|
||||
uint32 m_uiMindBlast_Timer;
|
||||
uint32 m_uiShadowWordPain_Timer;
|
||||
uint32 m_uiSmite_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiHeal_Timer = 12000; // These times are probably wrong
|
||||
m_uiMindBlast_Timer = 16000;
|
||||
m_uiShadowWordPain_Timer = 2000;
|
||||
m_uiSmite_Timer = 8000;
|
||||
}
|
||||
|
||||
void AttackStart(Unit* pWho) override
|
||||
{
|
||||
if (m_creature->Attack(pWho, false))
|
||||
{
|
||||
m_creature->AddThreat(pWho);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho, 25.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
{
|
||||
if (Creature* pEmperor = m_pInstance->GetSingleCreatureFromStorage(NPC_EMPEROR))
|
||||
{
|
||||
// if evade, then check if he is alive. If not, start make portal
|
||||
if (!pEmperor->IsAlive())
|
||||
m_creature->CastSpell(m_creature, SPELL_OPEN_PORTAL, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// MindBlast_Timer
|
||||
if (m_uiMindBlast_Timer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_MINDBLAST);
|
||||
m_uiMindBlast_Timer = 14000;
|
||||
}
|
||||
else
|
||||
m_uiMindBlast_Timer -= uiDiff;
|
||||
|
||||
// ShadowWordPain_Timer
|
||||
if (m_uiShadowWordPain_Timer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOWWORDPAIN);
|
||||
m_uiShadowWordPain_Timer = 18000;
|
||||
}
|
||||
else
|
||||
m_uiShadowWordPain_Timer -= uiDiff;
|
||||
|
||||
// Smite_Timer
|
||||
if (m_uiSmite_Timer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_SMITE);
|
||||
m_uiSmite_Timer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiSmite_Timer -= uiDiff;
|
||||
|
||||
// Heal_Timer
|
||||
if (m_uiHeal_Timer < uiDiff)
|
||||
{
|
||||
if (Creature* pEmperor = m_pInstance->GetSingleCreatureFromStorage(NPC_EMPEROR))
|
||||
{
|
||||
if (pEmperor->IsAlive() && pEmperor->GetHealthPercent() != 100.0f)
|
||||
DoCastSpellIfCan(pEmperor, SPELL_HEAL);
|
||||
}
|
||||
|
||||
m_uiHeal_Timer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiHeal_Timer -= uiDiff;
|
||||
|
||||
// No meele?
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_moira_bronzebeard(Creature* pCreature)
|
||||
{
|
||||
return new boss_moira_bronzebeardAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_draganthaurissan()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_emperor_dagran_thaurissan";
|
||||
pNewScript->GetAI = &GetAI_boss_emperor_dagran_thaurissan;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_moira_bronzebeard";
|
||||
pNewScript->GetAI = &GetAI_boss_moira_bronzebeard;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_General_Angerforge
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Blackrock Depths
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_MIGHTYBLOW = 14099,
|
||||
SPELL_HAMSTRING = 9080,
|
||||
SPELL_CLEAVE = 20691,
|
||||
|
||||
NPC_ANVILRAGE_RESERVIST = 8901,
|
||||
NPC_ANVILRAGE_MEDIC = 8894,
|
||||
};
|
||||
|
||||
struct boss_general_angerforgeAI : public ScriptedAI
|
||||
{
|
||||
boss_general_angerforgeAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
|
||||
|
||||
uint32 m_uiMightyBlowTimer;
|
||||
uint32 m_uiHamStringTimer;
|
||||
uint32 m_uiCleaveTimer;
|
||||
uint32 m_uiAddsTimer;
|
||||
bool m_bSummonedMedics;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiMightyBlowTimer = 8000;
|
||||
m_uiHamStringTimer = 12000;
|
||||
m_uiCleaveTimer = 16000;
|
||||
m_uiAddsTimer = 0;
|
||||
m_bSummonedMedics = false;
|
||||
}
|
||||
|
||||
void SummonAdd(uint32 uiEntry)
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 20.0f, fX, fY, fZ);
|
||||
m_creature->SummonCreature(uiEntry, fX, fY, fZ, 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 60000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
pSummoned->AI()->AttackStart(pTarget);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// MightyBlow_Timer
|
||||
if (m_uiMightyBlowTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_MIGHTYBLOW);
|
||||
m_uiMightyBlowTimer = 18000;
|
||||
}
|
||||
else
|
||||
m_uiMightyBlowTimer -= uiDiff;
|
||||
|
||||
// HamString_Timer
|
||||
if (m_uiHamStringTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_HAMSTRING);
|
||||
m_uiHamStringTimer = 15000;
|
||||
}
|
||||
else
|
||||
m_uiHamStringTimer -= uiDiff;
|
||||
|
||||
// Cleave_Timer
|
||||
if (m_uiCleaveTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE);
|
||||
m_uiCleaveTimer = 9000;
|
||||
}
|
||||
else
|
||||
m_uiCleaveTimer -= uiDiff;
|
||||
|
||||
// Adds_Timer
|
||||
if (m_creature->GetHealthPercent() < 21.0f)
|
||||
{
|
||||
if (m_uiAddsTimer < uiDiff)
|
||||
{
|
||||
// summon 3 Adds every 25s
|
||||
SummonAdd(NPC_ANVILRAGE_RESERVIST);
|
||||
SummonAdd(NPC_ANVILRAGE_RESERVIST);
|
||||
SummonAdd(NPC_ANVILRAGE_RESERVIST);
|
||||
|
||||
m_uiAddsTimer = 25000;
|
||||
}
|
||||
else
|
||||
m_uiAddsTimer -= uiDiff;
|
||||
}
|
||||
|
||||
// Summon Medics
|
||||
if (!m_bSummonedMedics && m_creature->GetHealthPercent() < 21.0f)
|
||||
{
|
||||
SummonAdd(NPC_ANVILRAGE_MEDIC);
|
||||
SummonAdd(NPC_ANVILRAGE_MEDIC);
|
||||
m_bSummonedMedics = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_general_angerforge(Creature* pCreature)
|
||||
{
|
||||
return new boss_general_angerforgeAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_general_angerforge()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_general_angerforge";
|
||||
pNewScript->GetAI = &GetAI_boss_general_angerforge;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_High_Interrogator_Gerstahn
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Blackrock Depths
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_SHADOWWORDPAIN = 14032,
|
||||
SPELL_MANABURN = 14033,
|
||||
SPELL_PSYCHICSCREAM = 13704,
|
||||
SPELL_SHADOWSHIELD = 12040
|
||||
};
|
||||
|
||||
struct boss_high_interrogator_gerstahnAI : public ScriptedAI
|
||||
{
|
||||
boss_high_interrogator_gerstahnAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
|
||||
|
||||
uint32 m_uiShadowWordPainTimer;
|
||||
uint32 m_uiManaBurnTimer;
|
||||
uint32 m_uiPsychicScreamTimer;
|
||||
uint32 m_uiShadowShieldTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiShadowWordPainTimer = 4000;
|
||||
m_uiManaBurnTimer = 14000;
|
||||
m_uiPsychicScreamTimer = 32000;
|
||||
m_uiShadowShieldTimer = 8000;
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// ShadowWordPain_Timer
|
||||
if (m_uiShadowWordPainTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
DoCastSpellIfCan(pTarget, SPELL_SHADOWWORDPAIN);
|
||||
|
||||
m_uiShadowWordPainTimer = 7000;
|
||||
}
|
||||
else
|
||||
m_uiShadowWordPainTimer -= uiDiff;
|
||||
|
||||
// ManaBurn_Timer
|
||||
if (m_uiManaBurnTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_MANABURN, SELECT_FLAG_POWER_MANA))
|
||||
DoCastSpellIfCan(pTarget, SPELL_MANABURN);
|
||||
|
||||
m_uiManaBurnTimer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiManaBurnTimer -= uiDiff;
|
||||
|
||||
// PsychicScream_Timer
|
||||
if (m_uiPsychicScreamTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_PSYCHICSCREAM);
|
||||
m_uiPsychicScreamTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiPsychicScreamTimer -= uiDiff;
|
||||
|
||||
// ShadowShield_Timer
|
||||
if (m_uiShadowShieldTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_SHADOWSHIELD);
|
||||
m_uiShadowShieldTimer = 25000;
|
||||
}
|
||||
else
|
||||
m_uiShadowShieldTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_high_interrogator_gerstahn(Creature* pCreature)
|
||||
{
|
||||
return new boss_high_interrogator_gerstahnAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_high_interrogator_gerstahn()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_high_interrogator_gerstahn";
|
||||
pNewScript->GetAI = &GetAI_boss_high_interrogator_gerstahn;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Instance_Blackrock_Depths
|
||||
SD%Complete: 80
|
||||
SDComment:
|
||||
SDCategory: Blackrock Depths
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_depths.h"
|
||||
|
||||
instance_blackrock_depths::instance_blackrock_depths(Map* pMap) : ScriptedInstance(pMap),
|
||||
m_uiBarAleCount(0),
|
||||
m_uiCofferDoorsOpened(0),
|
||||
m_uiDwarfRound(0),
|
||||
m_uiDwarfFightTimer(0),
|
||||
|
||||
m_fArenaCenterX(0.0f),
|
||||
m_fArenaCenterY(0.0f),
|
||||
m_fArenaCenterZ(0.0f)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
case NPC_EMPEROR:
|
||||
case NPC_PRINCESS:
|
||||
case NPC_PHALANX:
|
||||
case NPC_HATEREL:
|
||||
case NPC_ANGERREL:
|
||||
case NPC_VILEREL:
|
||||
case NPC_GLOOMREL:
|
||||
case NPC_SEETHREL:
|
||||
case NPC_DOOMREL:
|
||||
case NPC_DOPEREL:
|
||||
case NPC_SHILL:
|
||||
case NPC_CREST:
|
||||
case NPC_JAZ:
|
||||
case NPC_TOBIAS:
|
||||
case NPC_DUGHAL:
|
||||
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
||||
break;
|
||||
|
||||
case NPC_WARBRINGER_CONST:
|
||||
// Golems not in the Relict Vault?
|
||||
if (std::abs(pCreature->GetPositionZ() - aVaultPositions[2]) > 1.0f || !pCreature->IsWithinDist2d(aVaultPositions[0], aVaultPositions[1], 20.0f))
|
||||
break;
|
||||
// Golems in Relict Vault need to have a stoned aura, set manually to prevent reapply when reached home
|
||||
pCreature->CastSpell(pCreature, SPELL_STONED, true);
|
||||
// Store the Relict Vault Golems into m_sVaultNpcGuids
|
||||
case NPC_WATCHER_DOOMGRIP:
|
||||
m_sVaultNpcGuids.insert(pCreature->GetObjectGuid());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::OnObjectCreate(GameObject* pGo)
|
||||
{
|
||||
switch (pGo->GetEntry())
|
||||
{
|
||||
case GO_ARENA_1:
|
||||
case GO_ARENA_2:
|
||||
case GO_ARENA_3:
|
||||
case GO_ARENA_4:
|
||||
case GO_SHADOW_LOCK:
|
||||
case GO_SHADOW_MECHANISM:
|
||||
case GO_SHADOW_GIANT_DOOR:
|
||||
case GO_SHADOW_DUMMY:
|
||||
case GO_BAR_KEG_SHOT:
|
||||
case GO_BAR_KEG_TRAP:
|
||||
case GO_BAR_DOOR:
|
||||
case GO_TOMB_ENTER:
|
||||
case GO_TOMB_EXIT:
|
||||
case GO_LYCEUM:
|
||||
case GO_GOLEM_ROOM_N:
|
||||
case GO_GOLEM_ROOM_S:
|
||||
case GO_THRONE_ROOM:
|
||||
case GO_SPECTRAL_CHALICE:
|
||||
case GO_CHEST_SEVEN:
|
||||
case GO_ARENA_SPOILS:
|
||||
case GO_SECRET_DOOR:
|
||||
case GO_JAIL_DOOR_SUPPLY:
|
||||
case GO_JAIL_SUPPLY_CRATE:
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
m_mGoEntryGuidStore[pGo->GetEntry()] = pGo->GetObjectGuid();
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case TYPE_RING_OF_LAW:
|
||||
// If finished the arena event after theldren fight
|
||||
if (uiData == DONE && m_auiEncounter[0] == SPECIAL)
|
||||
DoRespawnGameObject(GO_ARENA_SPOILS, HOUR);
|
||||
m_auiEncounter[0] = uiData;
|
||||
break;
|
||||
case TYPE_VAULT:
|
||||
if (uiData == SPECIAL)
|
||||
{
|
||||
++m_uiCofferDoorsOpened;
|
||||
|
||||
if (m_uiCofferDoorsOpened == MAX_RELIC_DOORS)
|
||||
{
|
||||
SetData(TYPE_VAULT, IN_PROGRESS);
|
||||
|
||||
Creature* pConstruct = NULL;
|
||||
|
||||
// Activate vault constructs
|
||||
for (GuidSet::const_iterator itr = m_sVaultNpcGuids.begin(); itr != m_sVaultNpcGuids.end(); ++itr)
|
||||
{
|
||||
pConstruct = instance->GetCreature(*itr);
|
||||
if (pConstruct)
|
||||
pConstruct->RemoveAurasDueToSpell(SPELL_STONED);
|
||||
}
|
||||
|
||||
if (!pConstruct)
|
||||
return;
|
||||
|
||||
// Summon doomgrip
|
||||
pConstruct->SummonCreature(NPC_WATCHER_DOOMGRIP, aVaultPositions[0], aVaultPositions[1], aVaultPositions[2], aVaultPositions[3], TEMPSUMMON_DEAD_DESPAWN, 0);
|
||||
}
|
||||
// No need to store in this case
|
||||
return;
|
||||
}
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_SECRET_DOOR);
|
||||
m_auiEncounter[1] = uiData;
|
||||
break;
|
||||
case TYPE_BAR:
|
||||
if (uiData == SPECIAL)
|
||||
++m_uiBarAleCount;
|
||||
else
|
||||
m_auiEncounter[2] = uiData;
|
||||
break;
|
||||
case TYPE_TOMB_OF_SEVEN:
|
||||
// Don't set the same data twice
|
||||
if (uiData == m_auiEncounter[3])
|
||||
break;
|
||||
// Combat door
|
||||
DoUseDoorOrButton(GO_TOMB_ENTER);
|
||||
// Start the event
|
||||
if (uiData == IN_PROGRESS)
|
||||
DoCallNextDwarf();
|
||||
if (uiData == FAIL)
|
||||
{
|
||||
// Reset dwarfes
|
||||
for (uint8 i = 0; i < MAX_DWARFS; ++i)
|
||||
{
|
||||
if (Creature* pDwarf = GetSingleCreatureFromStorage(aTombDwarfes[i]))
|
||||
{
|
||||
if (!pDwarf->IsAlive())
|
||||
pDwarf->Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
m_uiDwarfRound = 0;
|
||||
m_uiDwarfFightTimer = 0;
|
||||
}
|
||||
if (uiData == DONE)
|
||||
{
|
||||
DoRespawnGameObject(GO_CHEST_SEVEN, HOUR);
|
||||
DoUseDoorOrButton(GO_TOMB_EXIT);
|
||||
}
|
||||
m_auiEncounter[3] = uiData;
|
||||
break;
|
||||
case TYPE_LYCEUM:
|
||||
if (uiData == DONE)
|
||||
{
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_N);
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_S);
|
||||
}
|
||||
m_auiEncounter[4] = uiData;
|
||||
break;
|
||||
case TYPE_IRON_HALL:
|
||||
switch (uiData)
|
||||
{
|
||||
case IN_PROGRESS:
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_N);
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_S);
|
||||
break;
|
||||
case FAIL:
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_N);
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_S);
|
||||
break;
|
||||
case DONE:
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_N);
|
||||
DoUseDoorOrButton(GO_GOLEM_ROOM_S);
|
||||
DoUseDoorOrButton(GO_THRONE_ROOM);
|
||||
break;
|
||||
}
|
||||
m_auiEncounter[5] = uiData;
|
||||
break;
|
||||
case TYPE_QUEST_JAIL_BREAK:
|
||||
m_auiEncounter[6] = uiData;
|
||||
return;
|
||||
}
|
||||
|
||||
if (uiData == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
|
||||
<< m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6];
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 instance_blackrock_depths::GetData(uint32 uiType) const
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case TYPE_RING_OF_LAW:
|
||||
return m_auiEncounter[0];
|
||||
case TYPE_VAULT:
|
||||
return m_auiEncounter[1];
|
||||
case TYPE_BAR:
|
||||
if (m_auiEncounter[2] == IN_PROGRESS && m_uiBarAleCount == 3)
|
||||
return SPECIAL;
|
||||
else
|
||||
return m_auiEncounter[2];
|
||||
case TYPE_TOMB_OF_SEVEN:
|
||||
return m_auiEncounter[3];
|
||||
case TYPE_LYCEUM:
|
||||
return m_auiEncounter[4];
|
||||
case TYPE_IRON_HALL:
|
||||
return m_auiEncounter[5];
|
||||
case TYPE_QUEST_JAIL_BREAK:
|
||||
return m_auiEncounter[6];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::Load(const char* chrIn)
|
||||
{
|
||||
if (!chrIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(chrIn);
|
||||
|
||||
std::istringstream loadStream(chrIn);
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
|
||||
>> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6];
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::OnCreatureEnterCombat(Creature* pCreature)
|
||||
{
|
||||
if (pCreature->GetEntry() == NPC_MAGMUS)
|
||||
SetData(TYPE_IRON_HALL, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::OnCreatureEvade(Creature* pCreature)
|
||||
{
|
||||
if (GetData(TYPE_RING_OF_LAW) == IN_PROGRESS || GetData(TYPE_RING_OF_LAW) == SPECIAL)
|
||||
{
|
||||
for (uint8 i = 0; i < countof(aArenaNPCs); ++i)
|
||||
{
|
||||
if (pCreature->GetEntry() == aArenaNPCs[i])
|
||||
{
|
||||
SetData(TYPE_RING_OF_LAW, FAIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
// Handle Tomb of the Seven reset in case of wipe
|
||||
case NPC_HATEREL:
|
||||
case NPC_ANGERREL:
|
||||
case NPC_VILEREL:
|
||||
case NPC_GLOOMREL:
|
||||
case NPC_SEETHREL:
|
||||
case NPC_DOPEREL:
|
||||
case NPC_DOOMREL:
|
||||
SetData(TYPE_TOMB_OF_SEVEN, FAIL);
|
||||
break;
|
||||
case NPC_MAGMUS:
|
||||
SetData(TYPE_IRON_HALL, FAIL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::OnCreatureDeath(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
case NPC_WARBRINGER_CONST:
|
||||
case NPC_WATCHER_DOOMGRIP:
|
||||
if (GetData(TYPE_VAULT) == IN_PROGRESS)
|
||||
{
|
||||
m_sVaultNpcGuids.erase(pCreature->GetObjectGuid());
|
||||
|
||||
// If all event npcs dead then set event to done
|
||||
if (m_sVaultNpcGuids.empty())
|
||||
SetData(TYPE_VAULT, DONE);
|
||||
}
|
||||
break;
|
||||
case NPC_OGRABISI:
|
||||
case NPC_SHILL:
|
||||
case NPC_CREST:
|
||||
case NPC_JAZ:
|
||||
if (GetData(TYPE_QUEST_JAIL_BREAK) == IN_PROGRESS)
|
||||
SetData(TYPE_QUEST_JAIL_BREAK, SPECIAL);
|
||||
break;
|
||||
// Handle Tomb of the Seven dwarf death event
|
||||
case NPC_HATEREL:
|
||||
case NPC_ANGERREL:
|
||||
case NPC_VILEREL:
|
||||
case NPC_GLOOMREL:
|
||||
case NPC_SEETHREL:
|
||||
case NPC_DOPEREL:
|
||||
// Only handle the event when event is in progress
|
||||
if (GetData(TYPE_TOMB_OF_SEVEN) != IN_PROGRESS)
|
||||
return;
|
||||
// Call the next dwarf only if it's the last one which joined the fight
|
||||
if (pCreature->GetEntry() == aTombDwarfes[m_uiDwarfRound - 1])
|
||||
DoCallNextDwarf();
|
||||
break;
|
||||
case NPC_DOOMREL:
|
||||
SetData(TYPE_TOMB_OF_SEVEN, DONE);
|
||||
break;
|
||||
case NPC_MAGMUS:
|
||||
SetData(TYPE_IRON_HALL, DONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::DoCallNextDwarf()
|
||||
{
|
||||
if (Creature* pDwarf = GetSingleCreatureFromStorage(aTombDwarfes[m_uiDwarfRound]))
|
||||
{
|
||||
if (Player* pPlayer = GetPlayerInMap())
|
||||
{
|
||||
pDwarf->SetFactionTemporary(FACTION_DWARF_HOSTILE, TEMPFACTION_RESTORE_RESPAWN | TEMPFACTION_RESTORE_REACH_HOME);
|
||||
pDwarf->AI()->AttackStart(pPlayer);
|
||||
}
|
||||
}
|
||||
m_uiDwarfFightTimer = 30000;
|
||||
++m_uiDwarfRound;
|
||||
}
|
||||
|
||||
void instance_blackrock_depths::Update(uint32 uiDiff)
|
||||
{
|
||||
if (m_uiDwarfFightTimer)
|
||||
{
|
||||
if (m_uiDwarfFightTimer <= uiDiff)
|
||||
{
|
||||
if (m_uiDwarfRound < MAX_DWARFS)
|
||||
{
|
||||
DoCallNextDwarf();
|
||||
m_uiDwarfFightTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiDwarfFightTimer = 0;
|
||||
}
|
||||
else
|
||||
m_uiDwarfFightTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
InstanceData* GetInstanceData_instance_blackrock_depths(Map* pMap)
|
||||
{
|
||||
return new instance_blackrock_depths(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_blackrock_depths()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "instance_blackrock_depths";
|
||||
pNewScript->GetInstanceData = &GetInstanceData_instance_blackrock_depths;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
||||
#ifndef DEF_BLACKROCK_SPIRE_H
|
||||
#define DEF_BLACKROCK_SPIRE_H
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_ENCOUNTER = 6,
|
||||
MAX_ROOMS = 7,
|
||||
|
||||
TYPE_ROOM_EVENT = 0,
|
||||
TYPE_EMBERSEER = 1,
|
||||
TYPE_FLAMEWREATH = 2, // Only summon once per instance
|
||||
TYPE_STADIUM = 3,
|
||||
TYPE_DRAKKISATH = 4,
|
||||
TYPE_VALTHALAK = 5, // Only summon once per instance
|
||||
|
||||
NPC_SCARSHIELD_INFILTRATOR = 10299,
|
||||
NPC_BLACKHAND_SUMMONER = 9818,
|
||||
NPC_BLACKHAND_VETERAN = 9819,
|
||||
NPC_PYROGUARD_EMBERSEER = 9816,
|
||||
NPC_SOLAKAR_FLAMEWREATH = 10264,
|
||||
NPC_BLACKHAND_INCARCERATOR = 10316,
|
||||
NPC_LORD_VICTOR_NEFARIUS = 10162,
|
||||
NPC_REND_BLACKHAND = 10429,
|
||||
NPC_GYTH = 10339,
|
||||
NPC_DRAKKISATH = 10363,
|
||||
NPC_CHROMATIC_WHELP = 10442, // related to Gyth arena event
|
||||
NPC_CHROMATIC_DRAGON = 10447,
|
||||
NPC_BLACKHAND_HANDLER = 10742,
|
||||
|
||||
// Doors
|
||||
GO_EMBERSEER_IN = 175244,
|
||||
GO_DOORS = 175705,
|
||||
GO_EMBERSEER_OUT = 175153,
|
||||
GO_FATHER_FLAME = 175245,
|
||||
GO_GYTH_ENTRY_DOOR = 164726,
|
||||
GO_GYTH_COMBAT_DOOR = 175185,
|
||||
GO_GYTH_EXIT_DOOR = 175186,
|
||||
GO_DRAKKISATH_DOOR_1 = 175946,
|
||||
GO_DRAKKISATH_DOOR_2 = 175947,
|
||||
|
||||
GO_ROOM_7_RUNE = 175194,
|
||||
GO_ROOM_3_RUNE = 175195,
|
||||
GO_ROOM_6_RUNE = 175196,
|
||||
GO_ROOM_1_RUNE = 175197,
|
||||
GO_ROOM_5_RUNE = 175198,
|
||||
GO_ROOM_2_RUNE = 175199,
|
||||
GO_ROOM_4_RUNE = 175200,
|
||||
|
||||
GO_ROOKERY_EGG = 175124,
|
||||
|
||||
GO_EMBERSEER_RUNE_1 = 175266,
|
||||
GO_EMBERSEER_RUNE_2 = 175267,
|
||||
GO_EMBERSEER_RUNE_3 = 175268,
|
||||
GO_EMBERSEER_RUNE_4 = 175269,
|
||||
GO_EMBERSEER_RUNE_5 = 175270,
|
||||
GO_EMBERSEER_RUNE_6 = 175271,
|
||||
GO_EMBERSEER_RUNE_7 = 175272,
|
||||
|
||||
MAX_STADIUM_WAVES = 7,
|
||||
MAX_STADIUM_MOBS_PER_WAVE = 5,
|
||||
|
||||
FACTION_BLACK_DRAGON = 103
|
||||
};
|
||||
|
||||
struct SpawnLocation
|
||||
{
|
||||
float m_fX, m_fY, m_fZ, m_fO;
|
||||
};
|
||||
|
||||
static const SpawnLocation aStadiumLocs[7] =
|
||||
{
|
||||
{210.00f, -420.30f, 110.94f, 3.14f}, // dragons summon location
|
||||
{210.14f, -397.54f, 111.1f}, // Gyth summon location
|
||||
{163.62f, -420.33f, 110.47f}, // center of the stadium location (for movement)
|
||||
{164.63f, -444.04f, 121.97f, 3.22f}, // Lord Nefarius summon position
|
||||
{161.01f, -443.73f, 121.97f, 6.26f}, // Rend summon position
|
||||
{164.64f, -443.30f, 121.97f, 1.61f}, // Nefarius move position
|
||||
{165.74f, -466.46f, 116.80f}, // Rend move position
|
||||
};
|
||||
|
||||
// Stadium event description
|
||||
static const uint32 aStadiumEventNpcs[MAX_STADIUM_WAVES][5] =
|
||||
{
|
||||
{NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_DRAGON, 0},
|
||||
{NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_DRAGON, 0},
|
||||
{NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_DRAGON, NPC_BLACKHAND_HANDLER, 0},
|
||||
{NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_DRAGON, NPC_BLACKHAND_HANDLER, 0},
|
||||
{NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_DRAGON, NPC_BLACKHAND_HANDLER},
|
||||
{NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_DRAGON, NPC_CHROMATIC_DRAGON, NPC_BLACKHAND_HANDLER},
|
||||
{NPC_CHROMATIC_WHELP, NPC_CHROMATIC_WHELP, NPC_CHROMATIC_DRAGON, NPC_CHROMATIC_DRAGON, NPC_BLACKHAND_HANDLER},
|
||||
};
|
||||
|
||||
class instance_blackrock_spire : public ScriptedInstance, private DialogueHelper
|
||||
{
|
||||
public:
|
||||
instance_blackrock_spire(Map* pMap);
|
||||
~instance_blackrock_spire() {}
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void OnObjectCreate(GameObject* pGo) override;
|
||||
void OnCreatureCreate(Creature* pCreature) override;
|
||||
|
||||
void OnCreatureDeath(Creature* pCreature) override;
|
||||
void OnCreatureEvade(Creature* pCreature);
|
||||
void OnCreatureEnterCombat(Creature* pCreature) override;
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData) override;
|
||||
uint32 GetData(uint32 uiType) const override;
|
||||
|
||||
const char* Save() const override { return m_strInstData.c_str(); }
|
||||
void Load(const char* chrIn) override;
|
||||
|
||||
void DoUseEmberseerRunes(bool bReset = false);
|
||||
void DoProcessEmberseerEvent();
|
||||
|
||||
void DoSortRoomEventMobs();
|
||||
void GetIncarceratorGUIDList(GuidList& lList) { lList = m_lIncarceratorGUIDList; }
|
||||
|
||||
void StartflamewreathEventIfCan();
|
||||
|
||||
void Update(uint32 uiDiff) override;
|
||||
|
||||
private:
|
||||
void JustDidDialogueStep(int32 iEntry) override;
|
||||
void DoSendNextStadiumWave();
|
||||
void DoSendNextFlamewreathWave();
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
std::string m_strInstData;
|
||||
|
||||
uint32 m_uiFlamewreathEventTimer;
|
||||
uint32 m_uiFlamewreathWaveCount;
|
||||
uint32 m_uiStadiumEventTimer;
|
||||
uint8 m_uiStadiumWaves;
|
||||
uint8 m_uiStadiumMobsAlive;
|
||||
|
||||
ObjectGuid m_aRoomRuneGuid[MAX_ROOMS];
|
||||
GuidList m_alRoomEventMobGUIDSorted[MAX_ROOMS];
|
||||
GuidList m_lRoomEventMobGUIDList;
|
||||
GuidList m_lIncarceratorGUIDList;
|
||||
GuidList m_lEmberseerRunesGUIDList;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Gyth
|
||||
SD%Complete: 100
|
||||
SDComment: Timers may need adjustments
|
||||
SDCategory: Blackrock Spire
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_spire.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_NEFARIUS_BUFF_GYTH = -1229017,
|
||||
EMOTE_KNOCKED_OFF = -1229019,
|
||||
|
||||
SPELL_CHROMATIC_CHAOS = 16337, // casted by Nefarius at 50%
|
||||
SPELL_REND_MOUNTS = 16167,
|
||||
SPELL_SUMMON_REND = 16328,
|
||||
SPELL_CORROSIVE_ACID = 16359,
|
||||
SPELL_FREEZE = 16350,
|
||||
SPELL_FLAME_BREATH = 16390,
|
||||
SPELL_KNOCK_AWAY = 10101,
|
||||
};
|
||||
|
||||
struct boss_gythAI : public ScriptedAI
|
||||
{
|
||||
boss_gythAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (instance_blackrock_spire*) pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
instance_blackrock_spire* m_pInstance;
|
||||
|
||||
uint32 uiCorrosiveAcidTimer;
|
||||
uint32 uiFreezeTimer;
|
||||
uint32 uiFlamebreathTimer;
|
||||
|
||||
bool m_bSummonedRend;
|
||||
bool m_bHasChromaticChaos;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
uiCorrosiveAcidTimer = 8000;
|
||||
uiFreezeTimer = 11000;
|
||||
uiFlamebreathTimer = 4000;
|
||||
m_bSummonedRend = false;
|
||||
m_bHasChromaticChaos = false;
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_REND_MOUNTS);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
DoScriptText(EMOTE_KNOCKED_OFF, pSummoned);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Chromatic Chaos at 50%
|
||||
if (!m_bHasChromaticChaos && m_creature->GetHealthPercent() < 50.0f)
|
||||
{
|
||||
if (m_pInstance)
|
||||
{
|
||||
if (Creature* pNefarius = m_pInstance->GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
|
||||
{
|
||||
pNefarius->CastSpell(m_creature, SPELL_CHROMATIC_CHAOS, true);
|
||||
DoScriptText(SAY_NEFARIUS_BUFF_GYTH, pNefarius);
|
||||
m_bHasChromaticChaos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CorrosiveAcid_Timer
|
||||
if (uiCorrosiveAcidTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_CORROSIVE_ACID) == CAST_OK)
|
||||
uiCorrosiveAcidTimer = 7000;
|
||||
}
|
||||
else
|
||||
uiCorrosiveAcidTimer -= uiDiff;
|
||||
|
||||
// Freeze_Timer
|
||||
if (uiFreezeTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FREEZE) == CAST_OK)
|
||||
uiFreezeTimer = 16000;
|
||||
}
|
||||
else
|
||||
uiFreezeTimer -= uiDiff;
|
||||
|
||||
// Flamebreath_Timer
|
||||
if (uiFlamebreathTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FLAME_BREATH) == CAST_OK)
|
||||
uiFlamebreathTimer = 10500;
|
||||
}
|
||||
else
|
||||
uiFlamebreathTimer -= uiDiff;
|
||||
|
||||
// Summon Rend
|
||||
if (!m_bSummonedRend && m_creature->GetHealthPercent() < 11.0f)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_REND) == CAST_OK)
|
||||
{
|
||||
m_creature->RemoveAurasDueToSpell(SPELL_REND_MOUNTS);
|
||||
m_bSummonedRend = true;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_gyth(Creature* pCreature)
|
||||
{
|
||||
return new boss_gythAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_gyth()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_gyth";
|
||||
pNewScript->GetAI = &GetAI_boss_gyth;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Overlord_Wyrmthalak
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Blackrock Spire
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_BLASTWAVE = 11130,
|
||||
SPELL_SHOUT = 23511,
|
||||
SPELL_CLEAVE = 20691,
|
||||
SPELL_KNOCKAWAY = 20686,
|
||||
|
||||
NPC_SPIRESTONE_WARLORD = 9216,
|
||||
NPC_SMOLDERTHORN_BERSERKER = 9268
|
||||
};
|
||||
|
||||
const float afLocations[2][4] =
|
||||
{
|
||||
{ -39.355381f, -513.456482f, 88.472046f, 4.679872f},
|
||||
{ -49.875881f, -511.896942f, 88.195160f, 4.613114f}
|
||||
};
|
||||
|
||||
struct boss_overlordwyrmthalakAI : public ScriptedAI
|
||||
{
|
||||
boss_overlordwyrmthalakAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
|
||||
|
||||
uint32 m_uiBlastWaveTimer;
|
||||
uint32 m_uiShoutTimer;
|
||||
uint32 m_uiCleaveTimer;
|
||||
uint32 m_uiKnockawayTimer;
|
||||
bool m_bSummoned;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiBlastWaveTimer = 20000;
|
||||
m_uiShoutTimer = 2000;
|
||||
m_uiCleaveTimer = 6000;
|
||||
m_uiKnockawayTimer = 12000;
|
||||
m_bSummoned = false;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
if (pSummoned->GetEntry() != NPC_SPIRESTONE_WARLORD && pSummoned->GetEntry() != NPC_SMOLDERTHORN_BERSERKER)
|
||||
return;
|
||||
|
||||
if (m_creature->getVictim())
|
||||
{
|
||||
Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
|
||||
pSummoned->AI()->AttackStart(pTarget ? pTarget : m_creature->getVictim());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// BlastWave
|
||||
if (m_uiBlastWaveTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_BLASTWAVE);
|
||||
m_uiBlastWaveTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiBlastWaveTimer -= uiDiff;
|
||||
|
||||
// Shout
|
||||
if (m_uiShoutTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_SHOUT);
|
||||
m_uiShoutTimer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiShoutTimer -= uiDiff;
|
||||
|
||||
// Cleave
|
||||
if (m_uiCleaveTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE);
|
||||
m_uiCleaveTimer = 7000;
|
||||
}
|
||||
else
|
||||
m_uiCleaveTimer -= uiDiff;
|
||||
|
||||
// Knockaway
|
||||
if (m_uiKnockawayTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_KNOCKAWAY);
|
||||
m_uiKnockawayTimer = 14000;
|
||||
}
|
||||
else
|
||||
m_uiKnockawayTimer -= uiDiff;
|
||||
|
||||
// Summon two Beserks
|
||||
if (!m_bSummoned && m_creature->GetHealthPercent() < 51.0f)
|
||||
{
|
||||
m_creature->SummonCreature(NPC_SPIRESTONE_WARLORD, afLocations[0][0], afLocations[0][1], afLocations[0][2], afLocations[0][3], TEMPSUMMON_TIMED_DESPAWN, 300000);
|
||||
m_creature->SummonCreature(NPC_SMOLDERTHORN_BERSERKER, afLocations[1][0], afLocations[1][1], afLocations[1][2], afLocations[1][3], TEMPSUMMON_TIMED_DESPAWN, 300000);
|
||||
|
||||
m_bSummoned = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_overlordwyrmthalak(Creature* pCreature)
|
||||
{
|
||||
return new boss_overlordwyrmthalakAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_overlordwyrmthalak()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_overlord_wyrmthalak";
|
||||
pNewScript->GetAI = &GetAI_boss_overlordwyrmthalak;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Pyroguard_Emberseer
|
||||
SD%Complete: 90
|
||||
SDComment: Dummy spells used during the transformation may need further research
|
||||
SDCategory: Blackrock Spire
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_spire.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// Intro emote/say
|
||||
EMOTE_NEAR = -1229001,
|
||||
EMOTE_FULL = -1229002,
|
||||
SAY_FREE = -1229003,
|
||||
|
||||
MAX_GROWING_STACKS = 20,
|
||||
|
||||
// Intro spells
|
||||
SPELL_ENCAGE_EMBERSEER = 15281, // cast by Blackhand Incarcerator
|
||||
|
||||
SPELL_FIRE_SHIELD = 13376, // not sure what's the purpose of this
|
||||
SPELL_DESPAWN_EMBERSEER = 16078, // not sure what's the purpose of this
|
||||
SPELL_FREEZE_ANIM = 16245, // not sure what's the purpose of this
|
||||
SPELL_FULL_STRENGHT = 16047,
|
||||
SPELL_GROWING = 16049, // stacking aura
|
||||
SPELL_BONUS_DAMAGE = 16534, // triggered on full grow
|
||||
SPELL_TRANSFORM = 16052,
|
||||
|
||||
// Combat spells
|
||||
SPELL_FIRENOVA = 23462,
|
||||
SPELL_FLAMEBUFFET = 23341,
|
||||
SPELL_PYROBLAST = 20228 // guesswork, but best fitting in spells-area, was 17274 (has mana cost)
|
||||
};
|
||||
|
||||
struct boss_pyroguard_emberseerAI : public ScriptedAI
|
||||
{
|
||||
boss_pyroguard_emberseerAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (instance_blackrock_spire*) pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
instance_blackrock_spire* m_pInstance;
|
||||
|
||||
uint32 m_uiEncageTimer;
|
||||
uint32 m_uiFireNovaTimer;
|
||||
uint32 m_uiFlameBuffetTimer;
|
||||
uint32 m_uiPyroBlastTimer;
|
||||
uint8 m_uiGrowingStacks;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiEncageTimer = 10000;
|
||||
m_uiFireNovaTimer = 6000;
|
||||
m_uiFlameBuffetTimer = 3000;
|
||||
m_uiPyroBlastTimer = 14000;
|
||||
m_uiGrowingStacks = 0;
|
||||
|
||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_EMBERSEER, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_EMBERSEER, FAIL);
|
||||
}
|
||||
|
||||
// Wrapper to handle the transformation
|
||||
void DoHandleEmberseerGrowing()
|
||||
{
|
||||
++m_uiGrowingStacks;
|
||||
|
||||
if (m_uiGrowingStacks == MAX_GROWING_STACKS * 0.5f)
|
||||
DoScriptText(EMOTE_NEAR, m_creature);
|
||||
else if (m_uiGrowingStacks == MAX_GROWING_STACKS)
|
||||
{
|
||||
DoScriptText(EMOTE_FULL, m_creature);
|
||||
DoScriptText(SAY_FREE, m_creature);
|
||||
|
||||
// Note: the spell order needs further research
|
||||
DoCastSpellIfCan(m_creature, SPELL_FULL_STRENGHT, CAST_TRIGGERED);
|
||||
DoCastSpellIfCan(m_creature, SPELL_BONUS_DAMAGE, CAST_TRIGGERED);
|
||||
DoCastSpellIfCan(m_creature, SPELL_TRANSFORM, CAST_TRIGGERED);
|
||||
|
||||
// activate all runes
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->DoUseEmberseerRunes();
|
||||
// Redundant check: if for some reason the event isn't set in progress until this point - avoid using the altar again when the boss is fully grown
|
||||
m_pInstance->SetData(TYPE_EMBERSEER, IN_PROGRESS);
|
||||
}
|
||||
|
||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Cast Encage spell on OOC timer
|
||||
if (m_uiEncageTimer)
|
||||
{
|
||||
if (m_uiEncageTimer <= uiDiff)
|
||||
{
|
||||
if (!m_pInstance)
|
||||
{
|
||||
script_error_log("Instance Blackrock Spire: ERROR Failed to load instance data for this instace.");
|
||||
return;
|
||||
}
|
||||
|
||||
GuidList m_lIncarceratorsGuid;
|
||||
m_pInstance->GetIncarceratorGUIDList(m_lIncarceratorsGuid);
|
||||
|
||||
for (GuidList::const_iterator itr = m_lIncarceratorsGuid.begin(); itr != m_lIncarceratorsGuid.end(); ++itr)
|
||||
{
|
||||
if (Creature* pIncarcerator = m_creature->GetMap()->GetCreature(*itr))
|
||||
pIncarcerator->CastSpell(m_creature, SPELL_ENCAGE_EMBERSEER, false);
|
||||
}
|
||||
|
||||
m_uiEncageTimer = 0;
|
||||
}
|
||||
else
|
||||
m_uiEncageTimer -= uiDiff;
|
||||
}
|
||||
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// FireNova Timer
|
||||
if (m_uiFireNovaTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FIRENOVA) == CAST_OK)
|
||||
m_uiFireNovaTimer = 6000;
|
||||
}
|
||||
else
|
||||
m_uiFireNovaTimer -= uiDiff;
|
||||
|
||||
// FlameBuffet Timer
|
||||
if (m_uiFlameBuffetTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FLAMEBUFFET) == CAST_OK)
|
||||
m_uiFlameBuffetTimer = 14000;
|
||||
}
|
||||
else
|
||||
m_uiFlameBuffetTimer -= uiDiff;
|
||||
|
||||
// PyroBlast Timer
|
||||
if (m_uiPyroBlastTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_PYROBLAST) == CAST_OK)
|
||||
m_uiPyroBlastTimer = 15000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiPyroBlastTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_pyroguard_emberseer(Creature* pCreature)
|
||||
{
|
||||
return new boss_pyroguard_emberseerAI(pCreature);
|
||||
}
|
||||
|
||||
bool EffectDummyCreature_pyroguard_emberseer(Unit* /*pCaster*/, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget, ObjectGuid /*originalCasterGuid*/)
|
||||
{
|
||||
// always check spellid and effectindex
|
||||
if (uiSpellId == SPELL_GROWING && uiEffIndex == EFFECT_INDEX_0)
|
||||
{
|
||||
if (boss_pyroguard_emberseerAI* pEmberseerAI = dynamic_cast<boss_pyroguard_emberseerAI*>(pCreatureTarget->AI()))
|
||||
pEmberseerAI->DoHandleEmberseerGrowing();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddSC_boss_pyroguard_emberseer()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_pyroguard_emberseer";
|
||||
pNewScript->GetAI = &GetAI_boss_pyroguard_emberseer;
|
||||
pNewScript->pEffectDummyNPC = &EffectDummyCreature_pyroguard_emberseer;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,715 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: instance_blackrock_spire
|
||||
SD%Complete: 75
|
||||
SDComment: The Stadium event is missing some yells. Seal of Ascension related event NYI
|
||||
SDCategory: Blackrock Spire
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackrock_spire.h"
|
||||
|
||||
enum
|
||||
{
|
||||
AREATRIGGER_ENTER_UBRS = 2046,
|
||||
AREATRIGGER_STADIUM = 2026,
|
||||
|
||||
// Arena event dialogue - handled by instance
|
||||
SAY_NEFARIUS_INTRO_1 = -1229004,
|
||||
SAY_NEFARIUS_INTRO_2 = -1229005,
|
||||
SAY_NEFARIUS_ATTACK_1 = -1229006,
|
||||
SAY_REND_JOIN = -1229007,
|
||||
SAY_NEFARIUS_ATTACK_2 = -1229008,
|
||||
SAY_NEFARIUS_ATTACK_3 = -1229009,
|
||||
SAY_NEFARIUS_ATTACK_4 = -1229010,
|
||||
SAY_REND_LOSE_1 = -1229011,
|
||||
SAY_REND_LOSE_2 = -1229012,
|
||||
SAY_NEFARIUS_LOSE_3 = -1229013,
|
||||
SAY_NEFARIUS_LOSE_4 = -1229014,
|
||||
SAY_REND_ATTACK = -1229015,
|
||||
SAY_NEFARIUS_WARCHIEF = -1229016,
|
||||
SAY_NEFARIUS_VICTORY = -1229018,
|
||||
|
||||
// Emberseer event
|
||||
EMOTE_BEGIN = -1229000,
|
||||
SPELL_EMBERSEER_GROWING = 16048,
|
||||
|
||||
// Solakar Flamewreath Event
|
||||
SAY_ROOKERY_EVENT_START = -1229020,
|
||||
NPC_ROOKERY_GUARDIAN = 10258,
|
||||
NPC_ROOKERY_HATCHER = 10683,
|
||||
};
|
||||
|
||||
/* Areatrigger
|
||||
1470 Instance Entry
|
||||
1628 LBRS, between Spiders and Ogres
|
||||
1946 LBRS, ubrs pre-quest giver (1)
|
||||
1986 LBRS, ubrs pre-quest giver (2)
|
||||
1987 LBRS, ubrs pre-quest giver (3)
|
||||
2026 UBRS, stadium event trigger
|
||||
2046 UBRS, way to upper
|
||||
2066 UBRS, The Beast - Exit (to the dark chamber)
|
||||
2067 UBRS, The Beast - Entry
|
||||
2068 LBRS, fall out of map
|
||||
3726 UBRS, entrance to BWL
|
||||
*/
|
||||
|
||||
static const DialogueEntry aStadiumDialogue[] =
|
||||
{
|
||||
{NPC_LORD_VICTOR_NEFARIUS, 0, 1000},
|
||||
{SAY_NEFARIUS_INTRO_1, NPC_LORD_VICTOR_NEFARIUS, 7000},
|
||||
{SAY_NEFARIUS_INTRO_2, NPC_LORD_VICTOR_NEFARIUS, 5000},
|
||||
{NPC_BLACKHAND_HANDLER, 0, 0},
|
||||
{SAY_NEFARIUS_LOSE_4, NPC_LORD_VICTOR_NEFARIUS, 3000},
|
||||
{SAY_REND_ATTACK, NPC_REND_BLACKHAND, 2000},
|
||||
{SAY_NEFARIUS_WARCHIEF, NPC_LORD_VICTOR_NEFARIUS, 0},
|
||||
{SAY_NEFARIUS_VICTORY, NPC_LORD_VICTOR_NEFARIUS, 5000},
|
||||
{NPC_REND_BLACKHAND, 0, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
static const float rookeryEventSpawnPos[3] = {43.7685f, -259.82f, 91.6483f};
|
||||
|
||||
instance_blackrock_spire::instance_blackrock_spire(Map* pMap) : ScriptedInstance(pMap), DialogueHelper(aStadiumDialogue),
|
||||
m_uiFlamewreathEventTimer(0),
|
||||
m_uiFlamewreathWaveCount(0),
|
||||
m_uiStadiumEventTimer(0),
|
||||
m_uiStadiumWaves(0),
|
||||
m_uiStadiumMobsAlive(0)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
memset(&m_aRoomRuneGuid, 0, sizeof(m_aRoomRuneGuid));
|
||||
InitializeDialogueHelper(this);
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::OnObjectCreate(GameObject* pGo)
|
||||
{
|
||||
switch (pGo->GetEntry())
|
||||
{
|
||||
case GO_EMBERSEER_IN:
|
||||
if (GetData(TYPE_ROOM_EVENT) == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_DOORS:
|
||||
break;
|
||||
case GO_EMBERSEER_OUT:
|
||||
if (GetData(TYPE_EMBERSEER) == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_FATHER_FLAME:
|
||||
case GO_GYTH_ENTRY_DOOR:
|
||||
case GO_GYTH_COMBAT_DOOR:
|
||||
case GO_DRAKKISATH_DOOR_1:
|
||||
case GO_DRAKKISATH_DOOR_2:
|
||||
break;
|
||||
case GO_GYTH_EXIT_DOOR:
|
||||
if (GetData(TYPE_STADIUM) == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
|
||||
case GO_ROOM_1_RUNE: m_aRoomRuneGuid[0] = pGo->GetObjectGuid(); return;
|
||||
case GO_ROOM_2_RUNE: m_aRoomRuneGuid[1] = pGo->GetObjectGuid(); return;
|
||||
case GO_ROOM_3_RUNE: m_aRoomRuneGuid[2] = pGo->GetObjectGuid(); return;
|
||||
case GO_ROOM_4_RUNE: m_aRoomRuneGuid[3] = pGo->GetObjectGuid(); return;
|
||||
case GO_ROOM_5_RUNE: m_aRoomRuneGuid[4] = pGo->GetObjectGuid(); return;
|
||||
case GO_ROOM_6_RUNE: m_aRoomRuneGuid[5] = pGo->GetObjectGuid(); return;
|
||||
case GO_ROOM_7_RUNE: m_aRoomRuneGuid[6] = pGo->GetObjectGuid(); return;
|
||||
|
||||
case GO_EMBERSEER_RUNE_1:
|
||||
case GO_EMBERSEER_RUNE_2:
|
||||
case GO_EMBERSEER_RUNE_3:
|
||||
case GO_EMBERSEER_RUNE_4:
|
||||
case GO_EMBERSEER_RUNE_5:
|
||||
case GO_EMBERSEER_RUNE_6:
|
||||
case GO_EMBERSEER_RUNE_7:
|
||||
m_lEmberseerRunesGUIDList.push_back(pGo->GetObjectGuid());
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
m_mGoEntryGuidStore[pGo->GetEntry()] = pGo->GetObjectGuid();
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
case NPC_PYROGUARD_EMBERSEER:
|
||||
case NPC_SOLAKAR_FLAMEWREATH:
|
||||
case NPC_LORD_VICTOR_NEFARIUS:
|
||||
case NPC_GYTH:
|
||||
case NPC_REND_BLACKHAND:
|
||||
case NPC_SCARSHIELD_INFILTRATOR:
|
||||
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
||||
break;
|
||||
|
||||
case NPC_BLACKHAND_SUMMONER:
|
||||
case NPC_BLACKHAND_VETERAN: m_lRoomEventMobGUIDList.push_back(pCreature->GetObjectGuid()); break;
|
||||
case NPC_BLACKHAND_INCARCERATOR: m_lIncarceratorGUIDList.push_back(pCreature->GetObjectGuid()); break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case TYPE_ROOM_EVENT:
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_EMBERSEER_IN);
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
case TYPE_EMBERSEER:
|
||||
// Don't set the same data twice
|
||||
if (m_auiEncounter[uiType] == uiData)
|
||||
break;
|
||||
// Combat door
|
||||
DoUseDoorOrButton(GO_DOORS);
|
||||
// Respawn all incarcerators and reset the runes on FAIL
|
||||
if (uiData == FAIL)
|
||||
{
|
||||
for (GuidList::const_iterator itr = m_lIncarceratorGUIDList.begin(); itr != m_lIncarceratorGUIDList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pIncarcerator = instance->GetCreature(*itr))
|
||||
{
|
||||
if (!pIncarcerator->IsAlive())
|
||||
pIncarcerator->Respawn();
|
||||
pIncarcerator->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
DoUseEmberseerRunes(true);
|
||||
}
|
||||
else if (uiData == DONE)
|
||||
{
|
||||
DoUseEmberseerRunes();
|
||||
DoUseDoorOrButton(GO_EMBERSEER_OUT);
|
||||
}
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
case TYPE_FLAMEWREATH:
|
||||
if (uiData == FAIL)
|
||||
{
|
||||
m_uiFlamewreathEventTimer = 0;
|
||||
m_uiFlamewreathWaveCount = 0;
|
||||
}
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
case TYPE_STADIUM:
|
||||
// Don't set the same data twice
|
||||
if (m_auiEncounter[uiType] == uiData)
|
||||
break;
|
||||
// Combat door
|
||||
DoUseDoorOrButton(GO_GYTH_ENTRY_DOOR);
|
||||
// Start event
|
||||
if (uiData == IN_PROGRESS)
|
||||
StartNextDialogueText(SAY_NEFARIUS_INTRO_1);
|
||||
else if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_GYTH_EXIT_DOOR);
|
||||
else if (uiData == FAIL)
|
||||
{
|
||||
// Despawn Nefarius and Rend on fail (the others are despawned OnCreatureEvade())
|
||||
if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
|
||||
pNefarius->ForcedDespawn();
|
||||
if (Creature* pRend = GetSingleCreatureFromStorage(NPC_REND_BLACKHAND))
|
||||
pRend->ForcedDespawn();
|
||||
if (Creature* pGyth = GetSingleCreatureFromStorage(NPC_GYTH))
|
||||
pGyth->ForcedDespawn();
|
||||
|
||||
m_uiStadiumEventTimer = 0;
|
||||
m_uiStadiumMobsAlive = 0;
|
||||
m_uiStadiumWaves = 0;
|
||||
}
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
case TYPE_DRAKKISATH:
|
||||
case TYPE_VALTHALAK:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiData == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5];
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::Load(const char* chrIn)
|
||||
{
|
||||
if (!chrIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(chrIn);
|
||||
|
||||
std::istringstream loadStream(chrIn);
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4] >> m_auiEncounter[5];
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
uint32 instance_blackrock_spire::GetData(uint32 uiType) const
|
||||
{
|
||||
if (uiType < MAX_ENCOUNTER)
|
||||
return m_auiEncounter[uiType];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::DoSortRoomEventMobs()
|
||||
{
|
||||
if (GetData(TYPE_ROOM_EVENT) != NOT_STARTED)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ROOMS; ++i)
|
||||
{
|
||||
if (GameObject* pRune = instance->GetGameObject(m_aRoomRuneGuid[i]))
|
||||
{
|
||||
for (GuidList::const_iterator itr = m_lRoomEventMobGUIDList.begin(); itr != m_lRoomEventMobGUIDList.end(); ++itr)
|
||||
{
|
||||
Creature* pCreature = instance->GetCreature(*itr);
|
||||
if (pCreature && pCreature->IsAlive() && pCreature->GetDistance(pRune) < 10.0f)
|
||||
m_alRoomEventMobGUIDSorted[i].push_back(*itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetData(TYPE_ROOM_EVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::OnCreatureDeath(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
case NPC_BLACKHAND_SUMMONER:
|
||||
case NPC_BLACKHAND_VETERAN:
|
||||
// Handle Runes
|
||||
if (m_auiEncounter[TYPE_ROOM_EVENT] == IN_PROGRESS)
|
||||
{
|
||||
uint8 uiNotEmptyRoomsCount = 0;
|
||||
for (uint8 i = 0; i < MAX_ROOMS; ++i)
|
||||
{
|
||||
if (m_aRoomRuneGuid[i]) // This check is used, to ensure which runes still need processing
|
||||
{
|
||||
m_alRoomEventMobGUIDSorted[i].remove(pCreature->GetObjectGuid());
|
||||
if (m_alRoomEventMobGUIDSorted[i].empty())
|
||||
{
|
||||
DoUseDoorOrButton(m_aRoomRuneGuid[i]);
|
||||
m_aRoomRuneGuid[i].Clear();
|
||||
}
|
||||
else
|
||||
++uiNotEmptyRoomsCount; // found an not empty room
|
||||
}
|
||||
}
|
||||
if (!uiNotEmptyRoomsCount)
|
||||
SetData(TYPE_ROOM_EVENT, DONE);
|
||||
}
|
||||
break;
|
||||
case NPC_SOLAKAR_FLAMEWREATH:
|
||||
SetData(TYPE_FLAMEWREATH, DONE);
|
||||
break;
|
||||
case NPC_DRAKKISATH:
|
||||
SetData(TYPE_DRAKKISATH, DONE);
|
||||
DoUseDoorOrButton(GO_DRAKKISATH_DOOR_1);
|
||||
DoUseDoorOrButton(GO_DRAKKISATH_DOOR_2);
|
||||
break;
|
||||
case NPC_CHROMATIC_WHELP:
|
||||
case NPC_CHROMATIC_DRAGON:
|
||||
case NPC_BLACKHAND_HANDLER:
|
||||
// check if it's summoned - some npcs with the same entry are already spawned in the instance
|
||||
if (!pCreature->IsTemporarySummon())
|
||||
break;
|
||||
--m_uiStadiumMobsAlive;
|
||||
if (m_uiStadiumMobsAlive == 0)
|
||||
DoSendNextStadiumWave();
|
||||
break;
|
||||
case NPC_GYTH:
|
||||
case NPC_REND_BLACKHAND:
|
||||
--m_uiStadiumMobsAlive;
|
||||
if (m_uiStadiumMobsAlive == 0)
|
||||
StartNextDialogueText(SAY_NEFARIUS_VICTORY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::OnCreatureEvade(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
// Emberseer should evade if the incarcerators evade
|
||||
case NPC_BLACKHAND_INCARCERATOR:
|
||||
if (Creature* pEmberseer = GetSingleCreatureFromStorage(NPC_PYROGUARD_EMBERSEER))
|
||||
pEmberseer->AI()->EnterEvadeMode();
|
||||
break;
|
||||
case NPC_SOLAKAR_FLAMEWREATH:
|
||||
case NPC_ROOKERY_GUARDIAN:
|
||||
case NPC_ROOKERY_HATCHER:
|
||||
SetData(TYPE_FLAMEWREATH, FAIL);
|
||||
break;
|
||||
case NPC_CHROMATIC_WHELP:
|
||||
case NPC_CHROMATIC_DRAGON:
|
||||
case NPC_BLACKHAND_HANDLER:
|
||||
case NPC_GYTH:
|
||||
case NPC_REND_BLACKHAND:
|
||||
// check if it's summoned - some npcs with the same entry are already spawned in the instance
|
||||
if (!pCreature->IsTemporarySummon())
|
||||
break;
|
||||
SetData(TYPE_STADIUM, FAIL);
|
||||
pCreature->ForcedDespawn();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::OnCreatureEnterCombat(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
// Once one of the Incarcerators gets Aggro, the door should close
|
||||
case NPC_BLACKHAND_INCARCERATOR:
|
||||
SetData(TYPE_EMBERSEER, IN_PROGRESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::DoProcessEmberseerEvent()
|
||||
{
|
||||
if (GetData(TYPE_EMBERSEER) == DONE || GetData(TYPE_EMBERSEER) == IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (m_lIncarceratorGUIDList.empty())
|
||||
{
|
||||
script_error_log("Npc %u couldn't be found. Please check your DB content!", NPC_BLACKHAND_INCARCERATOR);
|
||||
return;
|
||||
}
|
||||
|
||||
// start to grow
|
||||
if (Creature* pEmberseer = GetSingleCreatureFromStorage(NPC_PYROGUARD_EMBERSEER))
|
||||
{
|
||||
// If already casting, return
|
||||
if (pEmberseer->HasAura(SPELL_EMBERSEER_GROWING))
|
||||
return;
|
||||
|
||||
DoScriptText(EMOTE_BEGIN, pEmberseer);
|
||||
pEmberseer->CastSpell(pEmberseer, SPELL_EMBERSEER_GROWING, true);
|
||||
}
|
||||
|
||||
// remove the incarcerators flags and stop casting
|
||||
for (GuidList::const_iterator itr = m_lIncarceratorGUIDList.begin(); itr != m_lIncarceratorGUIDList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pCreature = instance->GetCreature(*itr))
|
||||
{
|
||||
if (pCreature->IsAlive())
|
||||
{
|
||||
pCreature->InterruptNonMeleeSpells(false);
|
||||
pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::DoUseEmberseerRunes(bool bReset)
|
||||
{
|
||||
if (m_lEmberseerRunesGUIDList.empty())
|
||||
return;
|
||||
|
||||
for (GuidList::const_iterator itr = m_lEmberseerRunesGUIDList.begin(); itr != m_lEmberseerRunesGUIDList.end(); ++itr)
|
||||
{
|
||||
if (bReset)
|
||||
{
|
||||
if (GameObject* pRune = instance->GetGameObject(*itr))
|
||||
pRune->ResetDoorOrButton();
|
||||
}
|
||||
else
|
||||
DoUseDoorOrButton(*itr);
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::JustDidDialogueStep(int32 iEntry)
|
||||
{
|
||||
switch (iEntry)
|
||||
{
|
||||
case NPC_BLACKHAND_HANDLER:
|
||||
m_uiStadiumEventTimer = 1000;
|
||||
// Move the two near the balcony
|
||||
if (Creature* pRend = GetSingleCreatureFromStorage(NPC_REND_BLACKHAND))
|
||||
pRend->SetFacingTo(aStadiumLocs[5].m_fO);
|
||||
if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
|
||||
pNefarius->GetMotionMaster()->MovePoint(0, aStadiumLocs[5].m_fX, aStadiumLocs[5].m_fY, aStadiumLocs[5].m_fZ);
|
||||
break;
|
||||
case SAY_NEFARIUS_WARCHIEF:
|
||||
// Prepare for Gyth - note: Nefarius should be moving around the balcony
|
||||
if (Creature* pRend = GetSingleCreatureFromStorage(NPC_REND_BLACKHAND))
|
||||
{
|
||||
pRend->ForcedDespawn(5000);
|
||||
pRend->SetWalk(false);
|
||||
pRend->GetMotionMaster()->MovePoint(0, aStadiumLocs[6].m_fX, aStadiumLocs[6].m_fY, aStadiumLocs[6].m_fZ);
|
||||
}
|
||||
m_uiStadiumEventTimer = 30000;
|
||||
break;
|
||||
case SAY_NEFARIUS_VICTORY:
|
||||
SetData(TYPE_STADIUM, DONE);
|
||||
break;
|
||||
case NPC_REND_BLACKHAND:
|
||||
// Despawn Nefarius
|
||||
if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
|
||||
{
|
||||
pNefarius->ForcedDespawn(5000);
|
||||
pNefarius->GetMotionMaster()->MovePoint(0, aStadiumLocs[6].m_fX, aStadiumLocs[6].m_fY, aStadiumLocs[6].m_fZ);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::DoSendNextStadiumWave()
|
||||
{
|
||||
if (m_uiStadiumWaves < MAX_STADIUM_WAVES)
|
||||
{
|
||||
// Send current wave mobs
|
||||
if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
for (uint8 i = 0; i < MAX_STADIUM_MOBS_PER_WAVE; ++i)
|
||||
{
|
||||
if (aStadiumEventNpcs[m_uiStadiumWaves][i] == 0)
|
||||
continue;
|
||||
|
||||
pNefarius->GetRandomPoint(aStadiumLocs[0].m_fX, aStadiumLocs[0].m_fY, aStadiumLocs[0].m_fZ, 7.0f, fX, fY, fZ);
|
||||
fX = std::min(aStadiumLocs[0].m_fX, fX); // Halfcircle - suits better the rectangular form
|
||||
if (Creature* pTemp = pNefarius->SummonCreature(aStadiumEventNpcs[m_uiStadiumWaves][i], fX, fY, fZ, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0))
|
||||
{
|
||||
// Get some point in the center of the stadium
|
||||
pTemp->GetRandomPoint(aStadiumLocs[2].m_fX, aStadiumLocs[2].m_fY, aStadiumLocs[2].m_fZ, 5.0f, fX, fY, fZ);
|
||||
fX = std::min(aStadiumLocs[2].m_fX, fX);// Halfcircle - suits better the rectangular form
|
||||
|
||||
pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
|
||||
++m_uiStadiumMobsAlive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DoUseDoorOrButton(GO_GYTH_COMBAT_DOOR);
|
||||
}
|
||||
// All waves are cleared - start Gyth intro
|
||||
else if (m_uiStadiumWaves == MAX_STADIUM_WAVES)
|
||||
StartNextDialogueText(SAY_NEFARIUS_LOSE_4);
|
||||
else
|
||||
{
|
||||
// Send Gyth
|
||||
if (Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS))
|
||||
{
|
||||
if (Creature* pTemp = pNefarius->SummonCreature(NPC_GYTH, aStadiumLocs[1].m_fX, aStadiumLocs[1].m_fY, aStadiumLocs[1].m_fZ, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0))
|
||||
pTemp->GetMotionMaster()->MovePoint(0, aStadiumLocs[2].m_fX, aStadiumLocs[2].m_fY, aStadiumLocs[2].m_fZ);
|
||||
}
|
||||
|
||||
// Set this to 2, because Rend will be summoned later during the fight
|
||||
m_uiStadiumMobsAlive = 2;
|
||||
|
||||
DoUseDoorOrButton(GO_GYTH_COMBAT_DOOR);
|
||||
}
|
||||
|
||||
++m_uiStadiumWaves;
|
||||
|
||||
// Stop the timer when all the waves have been sent
|
||||
if (m_uiStadiumWaves >= MAX_STADIUM_WAVES)
|
||||
m_uiStadiumEventTimer = 0;
|
||||
else
|
||||
m_uiStadiumEventTimer = 60000;
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::DoSendNextFlamewreathWave()
|
||||
{
|
||||
GameObject* pSummoner = GetSingleGameObjectFromStorage(GO_FATHER_FLAME);
|
||||
if (!pSummoner)
|
||||
return;
|
||||
|
||||
// TODO - The npcs would move nicer if they had DB waypoints, so i suggest to change their default movement to DB waypoints, and random movement when they reached their goal
|
||||
|
||||
if (m_uiFlamewreathWaveCount < 6) // Send two adds (6 waves, then boss)
|
||||
{
|
||||
Creature* pSummoned = NULL;
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
pSummoner->GetRandomPoint(rookeryEventSpawnPos[0], rookeryEventSpawnPos[1], rookeryEventSpawnPos[2], 2.5f, fX, fY, fZ);
|
||||
// Summon Rookery Hatchers in first wave, else random
|
||||
if (pSummoned = pSummoner->SummonCreature(urand(0, 1) && m_uiFlamewreathWaveCount ? NPC_ROOKERY_GUARDIAN : NPC_ROOKERY_HATCHER,
|
||||
fX, fY, fZ, 0.0, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 300000))
|
||||
{
|
||||
pSummoner->GetContactPoint(pSummoned, fX, fY, fZ);
|
||||
pSummoned->GetMotionMaster()->MovePoint(1, fX, fY, pSummoner->GetPositionZ());
|
||||
}
|
||||
}
|
||||
if (pSummoned && m_uiFlamewreathWaveCount == 0)
|
||||
DoScriptText(SAY_ROOKERY_EVENT_START, pSummoned);
|
||||
|
||||
if (m_uiFlamewreathWaveCount < 4)
|
||||
m_uiFlamewreathEventTimer = 30000;
|
||||
else if (m_uiFlamewreathWaveCount < 6)
|
||||
m_uiFlamewreathEventTimer = 40000;
|
||||
else
|
||||
m_uiFlamewreathEventTimer = 10000;
|
||||
|
||||
++m_uiFlamewreathWaveCount;
|
||||
}
|
||||
else // Send Flamewreath
|
||||
{
|
||||
if (Creature* pSolakar = pSummoner->SummonCreature(NPC_SOLAKAR_FLAMEWREATH, rookeryEventSpawnPos[0], rookeryEventSpawnPos[1], rookeryEventSpawnPos[2], 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, HOUR * IN_MILLISECONDS))
|
||||
pSolakar->GetMotionMaster()->MovePoint(1, pSummoner->GetPositionX(), pSummoner->GetPositionY(), pSummoner->GetPositionZ());
|
||||
SetData(TYPE_FLAMEWREATH, SPECIAL);
|
||||
m_uiFlamewreathEventTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::Update(uint32 uiDiff)
|
||||
{
|
||||
DialogueUpdate(uiDiff);
|
||||
|
||||
if (m_uiStadiumEventTimer)
|
||||
{
|
||||
if (m_uiStadiumEventTimer <= uiDiff)
|
||||
DoSendNextStadiumWave();
|
||||
else
|
||||
m_uiStadiumEventTimer -= uiDiff;
|
||||
}
|
||||
|
||||
if (m_uiFlamewreathEventTimer)
|
||||
{
|
||||
if (m_uiFlamewreathEventTimer <= uiDiff)
|
||||
DoSendNextFlamewreathWave();
|
||||
else
|
||||
m_uiFlamewreathEventTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackrock_spire::StartflamewreathEventIfCan()
|
||||
{
|
||||
// Already done or currently in progress - or endboss done
|
||||
if (m_auiEncounter[TYPE_FLAMEWREATH] == DONE || m_auiEncounter[TYPE_FLAMEWREATH] == IN_PROGRESS || m_auiEncounter[TYPE_DRAKKISATH] == DONE)
|
||||
return;
|
||||
|
||||
// Boss still around
|
||||
if (GetSingleCreatureFromStorage(NPC_SOLAKAR_FLAMEWREATH, true))
|
||||
return;
|
||||
|
||||
// Start summoning of mobs
|
||||
m_uiFlamewreathEventTimer = 1;
|
||||
m_uiFlamewreathWaveCount = 0;
|
||||
}
|
||||
|
||||
InstanceData* GetInstanceData_instance_blackrock_spire(Map* pMap)
|
||||
{
|
||||
return new instance_blackrock_spire(pMap);
|
||||
}
|
||||
|
||||
bool AreaTrigger_at_blackrock_spire(Player* pPlayer, AreaTriggerEntry const* pAt)
|
||||
{
|
||||
if (!pPlayer->IsAlive() || pPlayer->isGameMaster())
|
||||
return false;
|
||||
|
||||
switch (pAt->id)
|
||||
{
|
||||
case AREATRIGGER_ENTER_UBRS:
|
||||
if (instance_blackrock_spire* pInstance = (instance_blackrock_spire*) pPlayer->GetInstanceData())
|
||||
pInstance->DoSortRoomEventMobs();
|
||||
break;
|
||||
case AREATRIGGER_STADIUM:
|
||||
if (instance_blackrock_spire* pInstance = (instance_blackrock_spire*) pPlayer->GetInstanceData())
|
||||
{
|
||||
if (pInstance->GetData(TYPE_STADIUM) == IN_PROGRESS || pInstance->GetData(TYPE_STADIUM) == DONE)
|
||||
return false;
|
||||
|
||||
// Summon Nefarius and Rend for the dialogue event
|
||||
// Note: Nefarius and Rend need to be hostile and not attackable
|
||||
if (Creature* pNefarius = pPlayer->SummonCreature(NPC_LORD_VICTOR_NEFARIUS, aStadiumLocs[3].m_fX, aStadiumLocs[3].m_fY, aStadiumLocs[3].m_fZ, aStadiumLocs[3].m_fO, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
pNefarius->SetFactionTemporary(FACTION_BLACK_DRAGON, TEMPFACTION_NONE);
|
||||
if (Creature* pRend = pPlayer->SummonCreature(NPC_REND_BLACKHAND, aStadiumLocs[4].m_fX, aStadiumLocs[4].m_fY, aStadiumLocs[4].m_fZ, aStadiumLocs[4].m_fO, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
pRend->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
|
||||
pInstance->SetData(TYPE_STADIUM, IN_PROGRESS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProcessEventId_event_spell_altar_emberseer(uint32 /*uiEventId*/, Object* pSource, Object* /*pTarget*/, bool bIsStart)
|
||||
{
|
||||
if (bIsStart && pSource->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (instance_blackrock_spire* pInstance = (instance_blackrock_spire*)((Player*)pSource)->GetInstanceData())
|
||||
{
|
||||
pInstance->DoProcessEmberseerEvent();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GOUse_go_father_flame(Player* /*pPlayer*/, GameObject* pGo)
|
||||
{
|
||||
if (instance_blackrock_spire* pInstance = (instance_blackrock_spire*)pGo->GetInstanceData())
|
||||
pInstance->StartflamewreathEventIfCan();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_instance_blackrock_spire()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "instance_blackrock_spire";
|
||||
pNewScript->GetInstanceData = &GetInstanceData_instance_blackrock_spire;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "at_blackrock_spire";
|
||||
pNewScript->pAreaTrigger = &AreaTrigger_at_blackrock_spire;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "event_spell_altar_emberseer";
|
||||
pNewScript->pProcessEventId = &ProcessEventId_event_spell_altar_emberseer;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "go_father_flame";
|
||||
pNewScript->pGOUse = &GOUse_go_father_flame;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_atramedes
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackwing Descent
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_adramedes()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_chimaeron
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackwing Descent
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_chimaeron()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_magmaw
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackwing Descent
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_magmaw()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_maloriak
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackwing Descent
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_maloriak()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_nefarian_descent
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackwing Descent
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_boss_nefarian_descent()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: instance_blackwing_descent
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackwing Descent
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_instance_blackwing_descent()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: omnotron_defense
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Blackwing Descent
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_omnotron_defense()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
||||
#ifndef DEF_BLACKWING_LAIR
|
||||
#define DEF_BLACKWING_LAIR
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_ENCOUNTER = 8,
|
||||
|
||||
TYPE_RAZORGORE = 0,
|
||||
TYPE_VAELASTRASZ = 1,
|
||||
TYPE_LASHLAYER = 2,
|
||||
TYPE_FIREMAW = 3,
|
||||
TYPE_EBONROC = 4,
|
||||
TYPE_FLAMEGOR = 5,
|
||||
TYPE_CHROMAGGUS = 6,
|
||||
TYPE_NEFARIAN = 7,
|
||||
|
||||
DATA_DRAGON_EGG = 1, // track the used eggs
|
||||
|
||||
NPC_RAZORGORE = 12435,
|
||||
NPC_VAELASTRASZ = 13020,
|
||||
NPC_LASHLAYER = 12017,
|
||||
NPC_FIREMAW = 11983,
|
||||
NPC_EBONROC = 14601,
|
||||
NPC_FLAMEGOR = 11981,
|
||||
NPC_CHROMAGGUS = 14020,
|
||||
NPC_NEFARIAN = 11583,
|
||||
NPC_LORD_VICTOR_NEFARIUS = 10162,
|
||||
NPC_BLACKWING_TECHNICIAN = 13996, // Flees at Vael intro event
|
||||
|
||||
// Razorgore event related
|
||||
NPC_GRETHOK_CONTROLLER = 12557,
|
||||
NPC_BLACKWING_ORB_TRIGGER = 14449,
|
||||
NPC_NEFARIANS_TROOPS = 14459,
|
||||
NPC_MONSTER_GENERATOR = 12434,
|
||||
NPC_BLACKWING_LEGIONNAIRE = 12416, // one spawn per turn
|
||||
NPC_BLACKWING_MAGE = 12420, // one spawn per turn
|
||||
NPC_DRAGONSPAWN = 12422, // two spawns per turn
|
||||
|
||||
GO_DOOR_RAZORGORE_ENTER = 176964,
|
||||
GO_DOOR_RAZORGORE_EXIT = 176965,
|
||||
GO_DOOR_NEFARIAN = 176966,
|
||||
// GO_DOOR_CHROMAGGUS_ENTER = 179115,
|
||||
// GO_DOOR_CHROMAGGUS_SIDE = 179116,
|
||||
GO_DOOR_CHROMAGGUS_EXIT = 179117,
|
||||
GO_DOOR_VAELASTRASZ = 179364,
|
||||
GO_DOOR_LASHLAYER = 179365,
|
||||
GO_ORB_OF_DOMINATION = 177808, // trigger 19832 on Razorgore
|
||||
GO_BLACK_DRAGON_EGG = 177807,
|
||||
GO_DRAKONID_BONES = 179804,
|
||||
|
||||
EMOTE_ORB_SHUT_OFF = -1469035,
|
||||
EMOTE_TROOPS_FLEE = -1469033, // emote by Nefarian's Troops npc
|
||||
|
||||
MAX_EGGS_DEFENDERS = 4,
|
||||
};
|
||||
|
||||
// Coords used to spawn Nefarius at the throne
|
||||
static const float aNefariusSpawnLoc[4] = { -7466.16f, -1040.80f, 412.053f, 2.14675f};
|
||||
|
||||
static const uint32 aRazorgoreSpawns[MAX_EGGS_DEFENDERS] = {NPC_BLACKWING_LEGIONNAIRE, NPC_BLACKWING_MAGE, NPC_DRAGONSPAWN, NPC_DRAGONSPAWN};
|
||||
|
||||
class instance_blackwing_lair : public ScriptedInstance
|
||||
{
|
||||
public:
|
||||
instance_blackwing_lair(Map* pMap);
|
||||
~instance_blackwing_lair() {}
|
||||
|
||||
void Initialize() override;
|
||||
bool IsEncounterInProgress() const override;
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature) override;
|
||||
void OnObjectCreate(GameObject* pGo) override;
|
||||
|
||||
void OnCreatureEnterCombat(Creature* pCreature) override;
|
||||
void OnCreatureDeath(Creature* pCreature) override;
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData) override;
|
||||
uint32 GetData(uint32 uiType) const override;
|
||||
|
||||
void SetData64(uint32 uiData, uint64 uiGuid) override;
|
||||
|
||||
const char* Save() const override { return m_strInstData.c_str(); }
|
||||
void Load(const char* chrIn) override;
|
||||
|
||||
void Update(uint32 uiDiff) override;
|
||||
|
||||
protected:
|
||||
std::string m_strInstData;
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
|
||||
uint32 m_uiResetTimer;
|
||||
uint32 m_uiDefenseTimer;
|
||||
|
||||
GuidList m_lTechnicianGuids;
|
||||
GuidList m_lDragonEggsGuids;
|
||||
GuidList m_lDrakonidBonesGuids;
|
||||
GuidList m_lDefendersGuids;
|
||||
GuidList m_lUsedEggsGuids;
|
||||
GuidVector m_vGeneratorGuids;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Broodlord_Lashlayer
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_AGGRO = -1469000,
|
||||
SAY_LEASH = -1469001,
|
||||
|
||||
SPELL_CLEAVE = 26350,
|
||||
SPELL_BLAST_WAVE = 23331,
|
||||
SPELL_MORTAL_STRIKE = 24573,
|
||||
SPELL_KNOCK_AWAY = 25778
|
||||
};
|
||||
|
||||
struct boss_broodlordAI : public ScriptedAI
|
||||
{
|
||||
boss_broodlordAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiCleaveTimer;
|
||||
uint32 m_uiBlastWaveTimer;
|
||||
uint32 m_uiMortalStrikeTimer;
|
||||
uint32 m_uiKnockAwayTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiCleaveTimer = 8000; // These times are probably wrong
|
||||
m_uiBlastWaveTimer = 12000;
|
||||
m_uiMortalStrikeTimer = 20000;
|
||||
m_uiKnockAwayTimer = 30000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LASHLAYER, IN_PROGRESS);
|
||||
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LASHLAYER, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LASHLAYER, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Cleave Timer
|
||||
if (m_uiCleaveTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK)
|
||||
m_uiCleaveTimer = 7000;
|
||||
}
|
||||
else
|
||||
m_uiCleaveTimer -= uiDiff;
|
||||
|
||||
// Blast Wave
|
||||
if (m_uiBlastWaveTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_BLAST_WAVE) == CAST_OK)
|
||||
m_uiBlastWaveTimer = urand(8000, 16000);
|
||||
}
|
||||
else
|
||||
m_uiBlastWaveTimer -= uiDiff;
|
||||
|
||||
// Mortal Strike Timer
|
||||
if (m_uiMortalStrikeTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MORTAL_STRIKE) == CAST_OK)
|
||||
m_uiMortalStrikeTimer = urand(25000, 35000);
|
||||
}
|
||||
else
|
||||
m_uiMortalStrikeTimer -= uiDiff;
|
||||
|
||||
if (m_uiKnockAwayTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_KNOCK_AWAY);
|
||||
// Drop 50% aggro - TODO should be scriptedEffect?
|
||||
if (m_creature->GetThreatManager().getThreat(m_creature->getVictim()))
|
||||
m_creature->GetThreatManager().modifyThreatPercent(m_creature->getVictim(), -50);
|
||||
|
||||
m_uiKnockAwayTimer = urand(15000, 30000);
|
||||
}
|
||||
else
|
||||
m_uiKnockAwayTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
if (EnterEvadeIfOutOfCombatArea(uiDiff))
|
||||
DoScriptText(SAY_LEASH, m_creature);
|
||||
}
|
||||
};
|
||||
CreatureAI* GetAI_boss_broodlord(Creature* pCreature)
|
||||
{
|
||||
return new boss_broodlordAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_broodlord()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_broodlord";
|
||||
pNewScript->GetAI = &GetAI_boss_broodlord;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Chromaggus
|
||||
SD%Complete: 95
|
||||
SDComment: Chromatic Mutation disabled due to lack of core support
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
EMOTE_GENERIC_FRENZY_KILL = -1000001,
|
||||
EMOTE_SHIMMER = -1469003,
|
||||
|
||||
// These spells are actually called elemental shield
|
||||
// What they do is decrease all damage by 75% then they increase
|
||||
// One school of damage by 1100%
|
||||
SPELL_FIRE_VULNERABILITY = 22277,
|
||||
SPELL_FROST_VULNERABILITY = 22278,
|
||||
SPELL_SHADOW_VULNERABILITY = 22279,
|
||||
SPELL_NATURE_VULNERABILITY = 22280,
|
||||
SPELL_ARCANE_VULNERABILITY = 22281,
|
||||
|
||||
MAX_BREATHS = 5,
|
||||
SPELL_INCINERATE = 23308, // Incinerate 23308,23309
|
||||
SPELL_TIME_LAPSE = 23310, // Time lapse 23310, 23311(old threat mod that was removed in 2.01)
|
||||
SPELL_CORROSIVE_ACID = 23313, // Corrosive Acid 23313, 23314
|
||||
SPELL_IGNITE_FLESH = 23315, // Ignite Flesh 23315,23316
|
||||
SPELL_FROST_BURN = 23187, // Frost burn 23187, 23189
|
||||
|
||||
// Brood Affliction 23173 - Scripted Spell that cycles through all targets within 100 yards and has a chance to cast one of the afflictions on them
|
||||
// Since Scripted spells arn't coded I'll just write a function that does the same thing
|
||||
SPELL_BROODAF_BLUE = 23153, // Blue affliction 23153
|
||||
SPELL_BROODAF_BLACK = 23154, // Black affliction 23154
|
||||
SPELL_BROODAF_RED = 23155, // Red affliction 23155 (23168 on death)
|
||||
SPELL_BROODAF_BRONZE = 23170, // Bronze Affliction 23170
|
||||
SPELL_BROODAF_GREEN = 23169, // Brood Affliction Green 23169
|
||||
|
||||
SPELL_CHROMATIC_MUT_1 = 23174, // Spell cast on player if they get all 5 debuffs
|
||||
|
||||
SPELL_FRENZY = 28371, // The frenzy spell may be wrong
|
||||
SPELL_ENRAGE = 28747
|
||||
};
|
||||
|
||||
static const uint32 aPossibleBreaths[MAX_BREATHS] = {SPELL_INCINERATE, SPELL_TIME_LAPSE, SPELL_CORROSIVE_ACID, SPELL_IGNITE_FLESH, SPELL_FROST_BURN};
|
||||
|
||||
struct boss_chromaggusAI : public ScriptedAI
|
||||
{
|
||||
boss_chromaggusAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
// Select the 2 different breaths that we are going to use until despawned
|
||||
// 5 possiblities for the first breath, 4 for the second, 20 total possiblites
|
||||
|
||||
// select two different numbers between 0..MAX_BREATHS-1
|
||||
uint8 uiPos1 = urand(0, MAX_BREATHS - 1);
|
||||
uint8 uiPos2 = (uiPos1 + urand(1, MAX_BREATHS - 1)) % MAX_BREATHS;
|
||||
|
||||
m_uiBreathOneSpell = aPossibleBreaths[uiPos1];
|
||||
m_uiBreathTwoSpell = aPossibleBreaths[uiPos2];
|
||||
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiBreathOneSpell;
|
||||
uint32 m_uiBreathTwoSpell;
|
||||
uint32 m_uiCurrentVulnerabilitySpell;
|
||||
|
||||
uint32 m_uiShimmerTimer;
|
||||
uint32 m_uiBreathOneTimer;
|
||||
uint32 m_uiBreathTwoTimer;
|
||||
uint32 m_uiAfflictionTimer;
|
||||
uint32 m_uiFrenzyTimer;
|
||||
bool m_bEnraged;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiCurrentVulnerabilitySpell = 0; // We use this to store our last vulnerability spell so we can remove it later
|
||||
|
||||
m_uiShimmerTimer = 0; // Time till we change vurlnerabilites
|
||||
m_uiBreathOneTimer = 30000; // First breath is 30 seconds
|
||||
m_uiBreathTwoTimer = 60000; // Second is 1 minute so that we can alternate
|
||||
m_uiAfflictionTimer = 10000; // This is special - 5 seconds means that we cast this on 1 pPlayer every 5 sconds
|
||||
m_uiFrenzyTimer = 15000;
|
||||
|
||||
m_bEnraged = false;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_CHROMAGGUS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_CHROMAGGUS, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_CHROMAGGUS, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Shimmer Timer Timer
|
||||
if (m_uiShimmerTimer < uiDiff)
|
||||
{
|
||||
// Remove old vulnerability spell
|
||||
if (m_uiCurrentVulnerabilitySpell)
|
||||
m_creature->RemoveAurasDueToSpell(m_uiCurrentVulnerabilitySpell);
|
||||
|
||||
// Cast new random vurlnabilty on self
|
||||
uint32 aSpellId[] = {SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY};
|
||||
uint32 uiSpell = aSpellId[urand(0, 4)];
|
||||
|
||||
if (DoCastSpellIfCan(m_creature, uiSpell) == CAST_OK)
|
||||
{
|
||||
m_uiCurrentVulnerabilitySpell = uiSpell;
|
||||
|
||||
DoScriptText(EMOTE_SHIMMER, m_creature);
|
||||
m_uiShimmerTimer = 45000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiShimmerTimer -= uiDiff;
|
||||
|
||||
// Breath One Timer
|
||||
if (m_uiBreathOneTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, m_uiBreathOneSpell) == CAST_OK)
|
||||
m_uiBreathOneTimer = 60000;
|
||||
}
|
||||
else
|
||||
m_uiBreathOneTimer -= uiDiff;
|
||||
|
||||
// Breath Two Timer
|
||||
if (m_uiBreathTwoTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, m_uiBreathTwoSpell) == CAST_OK)
|
||||
m_uiBreathTwoTimer = 60000;
|
||||
}
|
||||
else
|
||||
m_uiBreathTwoTimer -= uiDiff;
|
||||
|
||||
// Affliction Timer
|
||||
if (m_uiAfflictionTimer < uiDiff)
|
||||
{
|
||||
uint32 m_uiSpellAfflict = 0;
|
||||
|
||||
switch (urand(0, 4))
|
||||
{
|
||||
case 0: m_uiSpellAfflict = SPELL_BROODAF_BLUE; break;
|
||||
case 1: m_uiSpellAfflict = SPELL_BROODAF_BLACK; break;
|
||||
case 2: m_uiSpellAfflict = SPELL_BROODAF_RED; break;
|
||||
case 3: m_uiSpellAfflict = SPELL_BROODAF_BRONZE; break;
|
||||
case 4: m_uiSpellAfflict = SPELL_BROODAF_GREEN; break;
|
||||
}
|
||||
|
||||
GuidVector vGuids;
|
||||
m_creature->FillGuidsListFromThreatList(vGuids);
|
||||
for (GuidVector::const_iterator i = vGuids.begin(); i != vGuids.end(); ++i)
|
||||
{
|
||||
Unit* pUnit = m_creature->GetMap()->GetUnit(*i);
|
||||
|
||||
if (pUnit)
|
||||
{
|
||||
// Cast affliction
|
||||
DoCastSpellIfCan(pUnit, m_uiSpellAfflict, CAST_TRIGGERED);
|
||||
|
||||
// Chromatic mutation if target is effected by all afflictions
|
||||
if (pUnit->HasAura(SPELL_BROODAF_BLUE, EFFECT_INDEX_0)
|
||||
&& pUnit->HasAura(SPELL_BROODAF_BLACK, EFFECT_INDEX_0)
|
||||
&& pUnit->HasAura(SPELL_BROODAF_RED, EFFECT_INDEX_0)
|
||||
&& pUnit->HasAura(SPELL_BROODAF_BRONZE, EFFECT_INDEX_0)
|
||||
&& pUnit->HasAura(SPELL_BROODAF_GREEN, EFFECT_INDEX_0))
|
||||
{
|
||||
// target->RemoveAllAuras();
|
||||
// DoCastSpellIfCan(target,SPELL_CHROMATIC_MUT_1);
|
||||
|
||||
// Chromatic mutation is causing issues
|
||||
// Assuming it is caused by a lack of core support for Charm
|
||||
// So instead we instant kill our target
|
||||
|
||||
// WORKAROUND
|
||||
if (pUnit->GetTypeId() == TYPEID_PLAYER)
|
||||
m_creature->CastSpell(pUnit, 5, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_uiAfflictionTimer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiAfflictionTimer -= uiDiff;
|
||||
|
||||
// Frenzy Timer
|
||||
if (m_uiFrenzyTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK)
|
||||
{
|
||||
DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature);
|
||||
m_uiFrenzyTimer = urand(10000, 15000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiFrenzyTimer -= uiDiff;
|
||||
|
||||
// Enrage if not already enraged and below 20%
|
||||
if (!m_bEnraged && m_creature->GetHealthPercent() < 20.0f)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_ENRAGE);
|
||||
m_bEnraged = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_chromaggus(Creature* pCreature)
|
||||
{
|
||||
return new boss_chromaggusAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_chromaggus()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_chromaggus";
|
||||
pNewScript->GetAI = &GetAI_boss_chromaggus;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Ebonroc
|
||||
SD%Complete: 100
|
||||
SDComment: None
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_SHADOW_FLAME = 22539,
|
||||
SPELL_WING_BUFFET = 18500,
|
||||
SPELL_SHADOW_OF_EBONROC = 23340,
|
||||
SPELL_THRASH = 3391
|
||||
};
|
||||
|
||||
struct boss_ebonrocAI : public ScriptedAI
|
||||
{
|
||||
boss_ebonrocAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiShadowFlameTimer;
|
||||
uint32 m_uiWingBuffetTimer;
|
||||
uint32 m_uiShadowOfEbonrocTimer;
|
||||
uint32 m_uiTrashTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiShadowFlameTimer = 15000; // These times are probably wrong
|
||||
m_uiWingBuffetTimer = 30000;
|
||||
m_uiShadowOfEbonrocTimer = 45000;
|
||||
m_uiTrashTimer = 25000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_EBONROC, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_EBONROC, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_EBONROC, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Shadow Flame Timer
|
||||
if (m_uiShadowFlameTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SHADOW_FLAME) == CAST_OK)
|
||||
m_uiShadowFlameTimer = urand(12000, 15000);
|
||||
}
|
||||
else
|
||||
m_uiShadowFlameTimer -= uiDiff;
|
||||
|
||||
// Wing Buffet Timer
|
||||
if (m_uiWingBuffetTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_WING_BUFFET) == CAST_OK)
|
||||
m_uiWingBuffetTimer = 25000;
|
||||
}
|
||||
else
|
||||
m_uiWingBuffetTimer -= uiDiff;
|
||||
|
||||
// Shadow of Ebonroc Timer
|
||||
if (m_uiShadowOfEbonrocTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_OF_EBONROC) == CAST_OK)
|
||||
m_uiShadowOfEbonrocTimer = urand(25000, 35000);
|
||||
}
|
||||
else
|
||||
m_uiShadowOfEbonrocTimer -= uiDiff;
|
||||
|
||||
// Thrash Timer
|
||||
if (m_uiTrashTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_THRASH) == CAST_OK)
|
||||
m_uiTrashTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiTrashTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_ebonroc(Creature* pCreature)
|
||||
{
|
||||
return new boss_ebonrocAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_ebonroc()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_ebonroc";
|
||||
pNewScript->GetAI = &GetAI_boss_ebonroc;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Firemaw
|
||||
SD%Complete: 100
|
||||
SDComment: None
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_SHADOW_FLAME = 22539,
|
||||
SPELL_WING_BUFFET = 23339,
|
||||
SPELL_FLAME_BUFFET = 23341,
|
||||
SPELL_THRASH = 3391
|
||||
};
|
||||
|
||||
struct boss_firemawAI : public ScriptedAI
|
||||
{
|
||||
boss_firemawAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiShadowFlameTimer;
|
||||
uint32 m_uiWingBuffetTimer;
|
||||
uint32 m_uiFlameBuffetTimer;
|
||||
uint32 m_uiTrashTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiShadowFlameTimer = 30000; // These times are probably wrong
|
||||
m_uiWingBuffetTimer = 24000;
|
||||
m_uiFlameBuffetTimer = 5000;
|
||||
m_uiTrashTimer = 25000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FIREMAW, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FIREMAW, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FIREMAW, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Shadow Flame Timer
|
||||
if (m_uiShadowFlameTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SHADOW_FLAME) == CAST_OK)
|
||||
m_uiShadowFlameTimer = urand(15000, 18000);
|
||||
}
|
||||
else
|
||||
m_uiShadowFlameTimer -= uiDiff;
|
||||
|
||||
// Wing Buffet Timer
|
||||
if (m_uiWingBuffetTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_WING_BUFFET) == CAST_OK)
|
||||
{
|
||||
if (m_creature->GetThreatManager().getThreat(m_creature->getVictim()))
|
||||
m_creature->GetThreatManager().modifyThreatPercent(m_creature->getVictim(), -75);
|
||||
|
||||
m_uiWingBuffetTimer = 25000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiWingBuffetTimer -= uiDiff;
|
||||
|
||||
// Flame Buffet Timer
|
||||
if (m_uiFlameBuffetTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FLAME_BUFFET) == CAST_OK)
|
||||
m_uiFlameBuffetTimer = 5000;
|
||||
}
|
||||
else
|
||||
m_uiFlameBuffetTimer -= uiDiff;
|
||||
|
||||
// Thrash Timer
|
||||
if (m_uiTrashTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_THRASH) == CAST_OK)
|
||||
m_uiTrashTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiTrashTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
CreatureAI* GetAI_boss_firemaw(Creature* pCreature)
|
||||
{
|
||||
return new boss_firemawAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_firemaw()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_firemaw";
|
||||
pNewScript->GetAI = &GetAI_boss_firemaw;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Flamegor
|
||||
SD%Complete: 100
|
||||
SDComment: None
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
EMOTE_GENERIC_FRENZY = -1000002,
|
||||
|
||||
SPELL_SHADOW_FLAME = 22539,
|
||||
SPELL_WING_BUFFET = 23339,
|
||||
SPELL_FRENZY = 23342, // This spell periodically triggers fire nova
|
||||
SPELL_THRASH = 3391
|
||||
};
|
||||
|
||||
struct boss_flamegorAI : public ScriptedAI
|
||||
{
|
||||
boss_flamegorAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiShadowFlameTimer;
|
||||
uint32 m_uiWingBuffetTimer;
|
||||
uint32 m_uiFrenzyTimer;
|
||||
uint32 m_uiTrashTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiShadowFlameTimer = 21000; // These times are probably wrong
|
||||
m_uiWingBuffetTimer = 35000;
|
||||
m_uiFrenzyTimer = 10000;
|
||||
m_uiTrashTimer = 25000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FLAMEGOR, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FLAMEGOR, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FLAMEGOR, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Shadow Flame Timer
|
||||
if (m_uiShadowFlameTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SHADOW_FLAME) == CAST_OK)
|
||||
m_uiShadowFlameTimer = urand(15000, 22000);
|
||||
}
|
||||
else
|
||||
m_uiShadowFlameTimer -= uiDiff;
|
||||
|
||||
// Wing Buffet Timer
|
||||
if (m_uiWingBuffetTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_WING_BUFFET) == CAST_OK)
|
||||
{
|
||||
if (m_creature->GetThreatManager().getThreat(m_creature->getVictim()))
|
||||
m_creature->GetThreatManager().modifyThreatPercent(m_creature->getVictim(), -75);
|
||||
|
||||
m_uiWingBuffetTimer = 25000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiWingBuffetTimer -= uiDiff;
|
||||
|
||||
// Frenzy Timer
|
||||
if (m_uiFrenzyTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK)
|
||||
{
|
||||
DoScriptText(EMOTE_GENERIC_FRENZY, m_creature);
|
||||
m_uiFrenzyTimer = urand(8000, 10000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiFrenzyTimer -= uiDiff;
|
||||
|
||||
// Thrash Timer
|
||||
if (m_uiTrashTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_THRASH) == CAST_OK)
|
||||
m_uiTrashTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiTrashTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_flamegor(Creature* pCreature)
|
||||
{
|
||||
return new boss_flamegorAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_flamegor()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_flamegor";
|
||||
pNewScript->GetAI = &GetAI_boss_flamegor;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Nefarian
|
||||
SD%Complete: 80
|
||||
SDComment: Some issues with class calls effecting more than one class
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_XHEALTH = -1469008, // at 5% hp
|
||||
SAY_AGGRO = -1469009,
|
||||
SAY_RAISE_SKELETONS = -1469010,
|
||||
SAY_SLAY = -1469011,
|
||||
SAY_DEATH = -1469012,
|
||||
|
||||
SAY_MAGE = -1469013,
|
||||
SAY_WARRIOR = -1469014,
|
||||
SAY_DRUID = -1469015,
|
||||
SAY_PRIEST = -1469016,
|
||||
SAY_PALADIN = -1469017,
|
||||
SAY_SHAMAN = -1469018,
|
||||
SAY_WARLOCK = -1469019,
|
||||
SAY_HUNTER = -1469020,
|
||||
SAY_ROGUE = -1469021,
|
||||
SAY_DEATH_KNIGHT = -1469031, // spell unk for the moment
|
||||
|
||||
SPELL_SHADOWFLAME_INITIAL = 22992, // old spell id 22972 -> wrong
|
||||
SPELL_SHADOWFLAME = 22539,
|
||||
SPELL_BELLOWING_ROAR = 22686,
|
||||
SPELL_VEIL_OF_SHADOW = 22687, // old spell id 7068 -> wrong
|
||||
SPELL_CLEAVE = 20691,
|
||||
SPELL_TAIL_LASH = 23364,
|
||||
// SPELL_BONE_CONTRUST = 23363, // 23362, 23361 Missing from DBC!
|
||||
|
||||
SPELL_MAGE = 23410, // wild magic
|
||||
SPELL_WARRIOR = 23397, // beserk
|
||||
SPELL_DRUID = 23398, // cat form
|
||||
SPELL_PRIEST = 23401, // corrupted healing
|
||||
SPELL_PALADIN = 23418, // syphon blessing
|
||||
SPELL_SHAMAN = 23425, // totems
|
||||
SPELL_WARLOCK = 23427, // infernals -> should trigger 23426
|
||||
SPELL_HUNTER = 23436, // bow broke
|
||||
SPELL_ROGUE = 23414, // Paralise
|
||||
};
|
||||
|
||||
struct boss_nefarianAI : public ScriptedAI
|
||||
{
|
||||
boss_nefarianAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiShadowFlameTimer;
|
||||
uint32 m_uiBellowingRoarTimer;
|
||||
uint32 m_uiVeilOfShadowTimer;
|
||||
uint32 m_uiCleaveTimer;
|
||||
uint32 m_uiTailLashTimer;
|
||||
uint32 m_uiClassCallTimer;
|
||||
bool m_bPhase3;
|
||||
bool m_bHasEndYell;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiShadowFlameTimer = 12000; // These times are probably wrong
|
||||
m_uiBellowingRoarTimer = 30000;
|
||||
m_uiVeilOfShadowTimer = 15000;
|
||||
m_uiCleaveTimer = 7000;
|
||||
m_uiTailLashTimer = 10000;
|
||||
m_uiClassCallTimer = 35000; // 35-40 seconds
|
||||
m_bPhase3 = false;
|
||||
m_bHasEndYell = false;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
if (urand(0, 4))
|
||||
return;
|
||||
|
||||
DoScriptText(SAY_SLAY, m_creature, pVictim);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_NEFARIAN, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_NEFARIAN, FAIL);
|
||||
|
||||
// Cleanup encounter
|
||||
if (m_creature->IsTemporarySummon())
|
||||
{
|
||||
TemporarySummon* pTemporary = (TemporarySummon*)m_creature;
|
||||
|
||||
if (Creature* pNefarius = m_creature->GetMap()->GetCreature(pTemporary->GetSummonerGuid()))
|
||||
pNefarius->AI()->EnterEvadeMode();
|
||||
}
|
||||
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
// Remove flying in case Nefarian aggroes before his combat point was reached
|
||||
if (m_creature->IsLevitating())
|
||||
{
|
||||
m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, 0);
|
||||
m_creature->SetLevitate(false);
|
||||
}
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_SHADOWFLAME_INITIAL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// ShadowFlame_Timer
|
||||
if (m_uiShadowFlameTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SHADOWFLAME) == CAST_OK)
|
||||
m_uiShadowFlameTimer = 12000;
|
||||
}
|
||||
else
|
||||
m_uiShadowFlameTimer -= uiDiff;
|
||||
|
||||
// BellowingRoar_Timer
|
||||
if (m_uiBellowingRoarTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_BELLOWING_ROAR) == CAST_OK)
|
||||
m_uiBellowingRoarTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiBellowingRoarTimer -= uiDiff;
|
||||
|
||||
// VeilOfShadow_Timer
|
||||
if (m_uiVeilOfShadowTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_VEIL_OF_SHADOW) == CAST_OK)
|
||||
m_uiVeilOfShadowTimer = 15000;
|
||||
}
|
||||
else
|
||||
m_uiVeilOfShadowTimer -= uiDiff;
|
||||
|
||||
// Cleave_Timer
|
||||
if (m_uiCleaveTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK)
|
||||
m_uiCleaveTimer = 7000;
|
||||
}
|
||||
else
|
||||
m_uiCleaveTimer -= uiDiff;
|
||||
|
||||
// TailLash_Timer
|
||||
if (m_uiTailLashTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_TAIL_LASH) == CAST_OK)
|
||||
m_uiTailLashTimer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiTailLashTimer -= uiDiff;
|
||||
|
||||
// ClassCall_Timer
|
||||
if (m_uiClassCallTimer < uiDiff)
|
||||
{
|
||||
// Cast a random class call
|
||||
// On official it is based on what classes are currently on the hostil list
|
||||
// but we can't do that yet so just randomly call one
|
||||
|
||||
switch (urand(0, 8))
|
||||
{
|
||||
case 0:
|
||||
DoScriptText(SAY_MAGE, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_MAGE);
|
||||
break;
|
||||
case 1:
|
||||
DoScriptText(SAY_WARRIOR, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_WARRIOR);
|
||||
break;
|
||||
case 2:
|
||||
DoScriptText(SAY_DRUID, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_DRUID);
|
||||
break;
|
||||
case 3:
|
||||
DoScriptText(SAY_PRIEST, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_PRIEST);
|
||||
break;
|
||||
case 4:
|
||||
DoScriptText(SAY_PALADIN, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_PALADIN);
|
||||
break;
|
||||
case 5:
|
||||
DoScriptText(SAY_SHAMAN, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_SHAMAN);
|
||||
break;
|
||||
case 6:
|
||||
DoScriptText(SAY_WARLOCK, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_WARLOCK);
|
||||
break;
|
||||
case 7:
|
||||
DoScriptText(SAY_HUNTER, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_HUNTER);
|
||||
break;
|
||||
case 8:
|
||||
DoScriptText(SAY_ROGUE, m_creature);
|
||||
DoCastSpellIfCan(m_creature, SPELL_ROGUE);
|
||||
break;
|
||||
}
|
||||
|
||||
m_uiClassCallTimer = urand(35000, 40000);
|
||||
}
|
||||
else
|
||||
m_uiClassCallTimer -= uiDiff;
|
||||
|
||||
// Phase3 begins when we are below X health
|
||||
if (!m_bPhase3 && m_creature->GetHealthPercent() < 20.0f)
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_NEFARIAN, SPECIAL);
|
||||
m_bPhase3 = true;
|
||||
DoScriptText(SAY_RAISE_SKELETONS, m_creature);
|
||||
}
|
||||
|
||||
// 5% hp yell
|
||||
if (!m_bHasEndYell && m_creature->GetHealthPercent() < 5.0f)
|
||||
{
|
||||
m_bHasEndYell = true;
|
||||
DoScriptText(SAY_XHEALTH, m_creature);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_nefarian(Creature* pCreature)
|
||||
{
|
||||
return new boss_nefarianAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_nefarian()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_nefarian";
|
||||
pNewScript->GetAI = &GetAI_boss_nefarian;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Razorgore
|
||||
SD%Complete: 95
|
||||
SDComment: Timers may be improved.
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_EGGS_BROKEN_1 = -1469022,
|
||||
SAY_EGGS_BROKEN_2 = -1469023,
|
||||
SAY_EGGS_BROKEN_3 = -1469024,
|
||||
SAY_DEATH = -1469025,
|
||||
|
||||
SPELL_POSSESS = 23014, // visual effect and increase the damage taken
|
||||
SPELL_DESTROY_EGG = 19873,
|
||||
SPELL_EXPLODE_ORB = 20037, // used if attacked without destroying the eggs - triggers 20038
|
||||
|
||||
SPELL_CLEAVE = 19632,
|
||||
SPELL_WARSTOMP = 24375,
|
||||
SPELL_FIREBALL_VOLLEY = 22425,
|
||||
SPELL_CONFLAGRATION = 23023,
|
||||
};
|
||||
|
||||
struct boss_razorgoreAI : public ScriptedAI
|
||||
{
|
||||
boss_razorgoreAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (instance_blackwing_lair*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
instance_blackwing_lair* m_pInstance;
|
||||
|
||||
uint32 m_uiIntroVisualTimer;
|
||||
uint32 m_uiCleaveTimer;
|
||||
uint32 m_uiWarStompTimer;
|
||||
uint32 m_uiFireballVolleyTimer;
|
||||
uint32 m_uiConflagrationTimer;
|
||||
|
||||
bool m_bEggsExploded;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiIntroVisualTimer = 5000;
|
||||
m_bEggsExploded = false;
|
||||
|
||||
m_uiCleaveTimer = urand(4000, 8000);
|
||||
m_uiWarStompTimer = 30000;
|
||||
m_uiConflagrationTimer = urand(10000, 15000);
|
||||
m_uiFireballVolleyTimer = urand(15000, 20000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
{
|
||||
// Don't set instance data unless all eggs are destroyed
|
||||
if (m_pInstance->GetData(TYPE_RAZORGORE) != SPECIAL)
|
||||
return;
|
||||
|
||||
m_pInstance->SetData(TYPE_RAZORGORE, DONE);
|
||||
}
|
||||
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage) override
|
||||
{
|
||||
if (uiDamage < m_creature->GetHealth())
|
||||
return;
|
||||
|
||||
if (!m_pInstance)
|
||||
return;
|
||||
|
||||
// Don't allow any accident
|
||||
if (m_bEggsExploded)
|
||||
{
|
||||
uiDamage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Boss explodes everything and resets - this happens if not all eggs are destroyed
|
||||
if (m_pInstance->GetData(TYPE_RAZORGORE) == IN_PROGRESS)
|
||||
{
|
||||
uiDamage = 0;
|
||||
m_bEggsExploded = true;
|
||||
m_pInstance->SetData(TYPE_RAZORGORE, FAIL);
|
||||
DoCastSpellIfCan(m_creature, SPELL_EXPLODE_ORB, CAST_TRIGGERED);
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_RAZORGORE, FAIL);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
// Defenders should attack the players and the boss
|
||||
pSummoned->SetInCombatWithZone();
|
||||
pSummoned->AI()->AttackStart(m_creature);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{
|
||||
// Set visual only on OOC timer
|
||||
if (m_uiIntroVisualTimer)
|
||||
{
|
||||
if (m_uiIntroVisualTimer <= uiDiff)
|
||||
{
|
||||
if (!m_pInstance)
|
||||
{
|
||||
script_error_log("Instance Blackwing Lair: ERROR Failed to load instance data for this instace.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Creature* pOrbTrigger = m_pInstance->GetSingleCreatureFromStorage(NPC_BLACKWING_ORB_TRIGGER))
|
||||
pOrbTrigger->CastSpell(m_creature, SPELL_POSSESS, false);
|
||||
m_uiIntroVisualTimer = 0;
|
||||
}
|
||||
else
|
||||
m_uiIntroVisualTimer -= uiDiff;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Cleave
|
||||
if (m_uiCleaveTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK)
|
||||
m_uiCleaveTimer = urand(4000, 8000);
|
||||
}
|
||||
else
|
||||
m_uiCleaveTimer -= uiDiff;
|
||||
|
||||
// War Stomp
|
||||
if (m_uiWarStompTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_WARSTOMP) == CAST_OK)
|
||||
m_uiWarStompTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiWarStompTimer -= uiDiff;
|
||||
|
||||
// Fireball Volley
|
||||
if (m_uiFireballVolleyTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FIREBALL_VOLLEY) == CAST_OK)
|
||||
m_uiFireballVolleyTimer = urand(15000, 20000);
|
||||
}
|
||||
else
|
||||
m_uiFireballVolleyTimer -= uiDiff;
|
||||
|
||||
// Conflagration
|
||||
if (m_uiConflagrationTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_CONFLAGRATION) == CAST_OK)
|
||||
m_uiConflagrationTimer = urand(15000, 25000);
|
||||
}
|
||||
else
|
||||
m_uiConflagrationTimer -= uiDiff;
|
||||
|
||||
/* This is obsolete code, not working anymore, keep as reference, should be handled in core though
|
||||
* // Aura Check. If the gamer is affected by confliguration we attack a random gamer.
|
||||
* if (m_creature->getVictim()->HasAura(SPELL_CONFLAGRATION, EFFECT_INDEX_0))
|
||||
* {
|
||||
* if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
|
||||
* m_creature->TauntApply(pTarget);
|
||||
* }
|
||||
*/
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_razorgore(Creature* pCreature)
|
||||
{
|
||||
return new boss_razorgoreAI(pCreature);
|
||||
}
|
||||
|
||||
bool EffectDummyGameObj_go_black_dragon_egg(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, GameObject* pGOTarget, ObjectGuid /*originalCasterGuid*/)
|
||||
{
|
||||
if (uiSpellId == SPELL_DESTROY_EGG && uiEffIndex == EFFECT_INDEX_1)
|
||||
{
|
||||
if (!pGOTarget->isSpawned())
|
||||
return true;
|
||||
|
||||
if (ScriptedInstance* pInstance = (ScriptedInstance*)pGOTarget->GetInstanceData())
|
||||
{
|
||||
if (urand(0, 1))
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0: DoScriptText(SAY_EGGS_BROKEN_1, pCaster); break;
|
||||
case 1: DoScriptText(SAY_EGGS_BROKEN_2, pCaster); break;
|
||||
case 2: DoScriptText(SAY_EGGS_BROKEN_3, pCaster); break;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the eggs which are destroyed, in order to count them for the second phase
|
||||
pInstance->SetData64(DATA_DRAGON_EGG, pGOTarget->GetObjectGuid());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddSC_boss_razorgore()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_razorgore";
|
||||
pNewScript->GetAI = &GetAI_boss_razorgore;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "go_black_dragon_egg";
|
||||
pNewScript->pEffectDummyGO = &EffectDummyGameObj_go_black_dragon_egg;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Vaelastrasz
|
||||
SD%Complete: 75
|
||||
SDComment: Burning Adrenaline not correctly implemented in core
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_LINE_1 = -1469026,
|
||||
SAY_LINE_2 = -1469027,
|
||||
SAY_LINE_3 = -1469028,
|
||||
SAY_HALFLIFE = -1469029,
|
||||
SAY_KILLTARGET = -1469030,
|
||||
SAY_NEFARIUS_CORRUPT_1 = -1469006, // When he corrupts Vaelastrasz
|
||||
SAY_NEFARIUS_CORRUPT_2 = -1469032,
|
||||
SAY_TECHNICIAN_RUN = -1469034,
|
||||
|
||||
SPELL_ESSENCE_OF_THE_RED = 23513,
|
||||
SPELL_FLAME_BREATH = 23461,
|
||||
SPELL_FIRE_NOVA = 23462,
|
||||
SPELL_TAIL_SWEEP = 15847,
|
||||
SPELL_BURNING_ADRENALINE = 23620,
|
||||
SPELL_CLEAVE = 20684, // Chain cleave is most likely named something different and contains a dummy effect
|
||||
|
||||
SPELL_NEFARIUS_CORRUPTION = 23642,
|
||||
|
||||
GOSSIP_ITEM_VAEL_1 = -3469003,
|
||||
GOSSIP_ITEM_VAEL_2 = -3469004,
|
||||
// Vael Gossip texts might be 7156 and 7256; At the moment are missing from DB
|
||||
// For the moment add the default values
|
||||
GOSSIP_TEXT_VAEL_1 = 384,
|
||||
GOSSIP_TEXT_VAEL_2 = 384,
|
||||
|
||||
FACTION_HOSTILE = 14,
|
||||
|
||||
AREATRIGGER_VAEL_INTRO = 3626,
|
||||
};
|
||||
|
||||
struct boss_vaelastraszAI : public ScriptedAI
|
||||
{
|
||||
boss_vaelastraszAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
|
||||
// Set stand state to dead before the intro event
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
ObjectGuid m_nefariusGuid;
|
||||
uint32 m_uiIntroTimer;
|
||||
uint8 m_uiIntroPhase;
|
||||
|
||||
ObjectGuid m_playerGuid;
|
||||
uint32 m_uiSpeechTimer;
|
||||
uint8 m_uiSpeechNum;
|
||||
|
||||
uint32 m_uiCleaveTimer;
|
||||
uint32 m_uiFlameBreathTimer;
|
||||
uint32 m_uiFireNovaTimer;
|
||||
uint32 m_uiBurningAdrenalineCasterTimer;
|
||||
uint32 m_uiBurningAdrenalineTankTimer;
|
||||
uint32 m_uiTailSweepTimer;
|
||||
bool m_bHasYelled;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_playerGuid.Clear();
|
||||
|
||||
m_uiIntroTimer = 0;
|
||||
m_uiIntroPhase = 0;
|
||||
m_uiSpeechTimer = 0;
|
||||
m_uiSpeechNum = 0;
|
||||
m_uiCleaveTimer = 8000; // These times are probably wrong
|
||||
m_uiFlameBreathTimer = 11000;
|
||||
m_uiBurningAdrenalineCasterTimer = 15000;
|
||||
m_uiBurningAdrenalineTankTimer = 45000;
|
||||
m_uiFireNovaTimer = 5000;
|
||||
m_uiTailSweepTimer = 20000;
|
||||
m_bHasYelled = false;
|
||||
|
||||
// Creature should have only 1/3 of hp
|
||||
m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.3));
|
||||
}
|
||||
|
||||
void BeginIntro()
|
||||
{
|
||||
// Start Intro delayed
|
||||
m_uiIntroTimer = 1000;
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VAELASTRASZ, SPECIAL);
|
||||
}
|
||||
|
||||
void BeginSpeech(Player* pTarget)
|
||||
{
|
||||
// Stand up and begin speach
|
||||
m_playerGuid = pTarget->GetObjectGuid();
|
||||
|
||||
// 10 seconds
|
||||
DoScriptText(SAY_LINE_1, m_creature);
|
||||
|
||||
// Make boss stand
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
m_uiSpeechTimer = 10000;
|
||||
m_uiSpeechNum = 0;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
if (urand(0, 4))
|
||||
return;
|
||||
|
||||
DoScriptText(SAY_KILLTARGET, m_creature, pVictim);
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VAELASTRASZ, IN_PROGRESS);
|
||||
|
||||
// Buff players on aggro
|
||||
DoCastSpellIfCan(m_creature, SPELL_ESSENCE_OF_THE_RED);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VAELASTRASZ, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VAELASTRASZ, FAIL);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_LORD_VICTOR_NEFARIUS)
|
||||
{
|
||||
// Set not selectable, so players won't interact with it
|
||||
pSummoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
m_nefariusGuid = pSummoned->GetObjectGuid();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (m_uiIntroTimer)
|
||||
{
|
||||
if (m_uiIntroTimer <= uiDiff)
|
||||
{
|
||||
switch (m_uiIntroPhase)
|
||||
{
|
||||
case 0:
|
||||
m_creature->SummonCreature(NPC_LORD_VICTOR_NEFARIUS, aNefariusSpawnLoc[0], aNefariusSpawnLoc[1], aNefariusSpawnLoc[2], aNefariusSpawnLoc[3], TEMPSUMMON_TIMED_DESPAWN, 25000);
|
||||
m_uiIntroTimer = 1000;
|
||||
break;
|
||||
case 1:
|
||||
if (Creature* pNefarius = m_creature->GetMap()->GetCreature(m_nefariusGuid))
|
||||
{
|
||||
pNefarius->CastSpell(m_creature, SPELL_NEFARIUS_CORRUPTION, true);
|
||||
DoScriptText(SAY_NEFARIUS_CORRUPT_1, pNefarius);
|
||||
}
|
||||
m_uiIntroTimer = 16000;
|
||||
break;
|
||||
case 2:
|
||||
if (Creature* pNefarius = m_creature->GetMap()->GetCreature(m_nefariusGuid))
|
||||
DoScriptText(SAY_NEFARIUS_CORRUPT_2, pNefarius);
|
||||
|
||||
// Set npc flags now
|
||||
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
m_uiIntroTimer = 0;
|
||||
break;
|
||||
}
|
||||
++m_uiIntroPhase;
|
||||
}
|
||||
else
|
||||
m_uiIntroTimer -= uiDiff;
|
||||
}
|
||||
|
||||
// Speech
|
||||
if (m_uiSpeechTimer)
|
||||
{
|
||||
if (m_uiSpeechTimer <= uiDiff)
|
||||
{
|
||||
switch (m_uiSpeechNum)
|
||||
{
|
||||
case 0:
|
||||
// 16 seconds till next line
|
||||
DoScriptText(SAY_LINE_2, m_creature);
|
||||
m_uiSpeechTimer = 16000;
|
||||
++m_uiSpeechNum;
|
||||
break;
|
||||
case 1:
|
||||
// This one is actually 16 seconds but we only go to 10 seconds because he starts attacking after he says "I must fight this!"
|
||||
DoScriptText(SAY_LINE_3, m_creature);
|
||||
m_uiSpeechTimer = 10000;
|
||||
++m_uiSpeechNum;
|
||||
break;
|
||||
case 2:
|
||||
m_creature->SetFactionTemporary(FACTION_HOSTILE, TEMPFACTION_RESTORE_RESPAWN);
|
||||
|
||||
if (m_playerGuid)
|
||||
{
|
||||
if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid))
|
||||
AttackStart(pPlayer);
|
||||
}
|
||||
m_uiSpeechTimer = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiSpeechTimer -= uiDiff;
|
||||
}
|
||||
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Yell if hp lower than 15%
|
||||
if (m_creature->GetHealthPercent() < 15.0f && !m_bHasYelled)
|
||||
{
|
||||
DoScriptText(SAY_HALFLIFE, m_creature);
|
||||
m_bHasYelled = true;
|
||||
}
|
||||
|
||||
// Cleave Timer
|
||||
if (m_uiCleaveTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK)
|
||||
m_uiCleaveTimer = 15000;
|
||||
}
|
||||
else
|
||||
m_uiCleaveTimer -= uiDiff;
|
||||
|
||||
// Flame Breath Timer
|
||||
if (m_uiFlameBreathTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FLAME_BREATH) == CAST_OK)
|
||||
m_uiFlameBreathTimer = urand(4000, 8000);
|
||||
}
|
||||
else
|
||||
m_uiFlameBreathTimer -= uiDiff;
|
||||
|
||||
// Burning Adrenaline Caster Timer
|
||||
if (m_uiBurningAdrenalineCasterTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_BURNING_ADRENALINE, SELECT_FLAG_PLAYER | SELECT_FLAG_POWER_MANA))
|
||||
{
|
||||
pTarget->CastSpell(pTarget, SPELL_BURNING_ADRENALINE, true, NULL, NULL, m_creature->GetObjectGuid());
|
||||
m_uiBurningAdrenalineCasterTimer = 15000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiBurningAdrenalineCasterTimer -= uiDiff;
|
||||
|
||||
// Burning Adrenaline Tank Timer
|
||||
if (m_uiBurningAdrenalineTankTimer < uiDiff)
|
||||
{
|
||||
// have the victim cast the spell on himself otherwise the third effect aura will be applied
|
||||
// to Vael instead of the player
|
||||
m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_BURNING_ADRENALINE, true, NULL, NULL, m_creature->GetObjectGuid());
|
||||
|
||||
m_uiBurningAdrenalineTankTimer = 45000;
|
||||
}
|
||||
else
|
||||
m_uiBurningAdrenalineTankTimer -= uiDiff;
|
||||
|
||||
// Fire Nova Timer
|
||||
if (m_uiFireNovaTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FIRE_NOVA) == CAST_OK)
|
||||
m_uiFireNovaTimer = 5000;
|
||||
}
|
||||
else
|
||||
m_uiFireNovaTimer -= uiDiff;
|
||||
|
||||
// Tail Sweep Timer
|
||||
if (m_uiTailSweepTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_TAIL_SWEEP) == CAST_OK)
|
||||
m_uiTailSweepTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiTailSweepTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool GossipSelect_boss_vaelastrasz(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
|
||||
{
|
||||
switch (uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VAEL_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_VAEL_2, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
if (boss_vaelastraszAI* pVaelAI = dynamic_cast<boss_vaelastraszAI*>(pCreature->AI()))
|
||||
pVaelAI->BeginSpeech(pPlayer);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GossipHello_boss_vaelastrasz(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (pCreature->IsQuestGiver())
|
||||
pPlayer->PrepareQuestMenu(pCreature->GetObjectGuid());
|
||||
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VAEL_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_VAEL_1, pCreature->GetObjectGuid());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_vaelastrasz(Creature* pCreature)
|
||||
{
|
||||
return new boss_vaelastraszAI(pCreature);
|
||||
}
|
||||
|
||||
bool AreaTrigger_at_vaelastrasz(Player* pPlayer, AreaTriggerEntry const* pAt)
|
||||
{
|
||||
if (pAt->id == AREATRIGGER_VAEL_INTRO)
|
||||
{
|
||||
if (pPlayer->isGameMaster() || pPlayer->IsDead())
|
||||
return false;
|
||||
|
||||
if (instance_blackwing_lair* pInstance = (instance_blackwing_lair*)pPlayer->GetInstanceData())
|
||||
{
|
||||
// Handle intro event
|
||||
if (pInstance->GetData(TYPE_VAELASTRASZ) == NOT_STARTED)
|
||||
{
|
||||
if (Creature* pVaelastrasz = pInstance->GetSingleCreatureFromStorage(NPC_VAELASTRASZ))
|
||||
if (boss_vaelastraszAI* pVaelAI = dynamic_cast<boss_vaelastraszAI*>(pVaelastrasz->AI()))
|
||||
pVaelAI->BeginIntro();
|
||||
}
|
||||
|
||||
// ToDo: make goblins flee
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddSC_boss_vaelastrasz()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_vaelastrasz";
|
||||
pNewScript->GetAI = &GetAI_boss_vaelastrasz;
|
||||
pNewScript->pGossipHello = &GossipHello_boss_vaelastrasz;
|
||||
pNewScript->pGossipSelect = &GossipSelect_boss_vaelastrasz;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "at_vaelastrasz";
|
||||
pNewScript->pAreaTrigger = &AreaTrigger_at_vaelastrasz;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Victor_Nefarius
|
||||
SD%Complete: 90
|
||||
SDComment: Small adjustments needed; Timers
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_GAMESBEGIN_1 = -1469004,
|
||||
SAY_GAMESBEGIN_2 = -1469005,
|
||||
SAY_NEFARIAN_INTRO = -1469007,
|
||||
|
||||
GOSSIP_ITEM_NEFARIUS_1 = -3469000,
|
||||
GOSSIP_ITEM_NEFARIUS_2 = -3469001,
|
||||
GOSSIP_ITEM_NEFARIUS_3 = -3469002,
|
||||
GOSSIP_TEXT_NEFARIUS_1 = 7134,
|
||||
GOSSIP_TEXT_NEFARIUS_2 = 7198,
|
||||
GOSSIP_TEXT_NEFARIUS_3 = 7199,
|
||||
|
||||
MAX_DRAKES = 5,
|
||||
MAX_DRAKE_SUMMONS = 42,
|
||||
NPC_BRONZE_DRAKANOID = 14263,
|
||||
NPC_BLUE_DRAKANOID = 14261,
|
||||
NPC_RED_DRAKANOID = 14264,
|
||||
NPC_GREEN_DRAKANOID = 14262,
|
||||
NPC_BLACK_DRAKANOID = 14265,
|
||||
NPC_CHROMATIC_DRAKANOID = 14302,
|
||||
|
||||
SPELL_NEFARIUS_BARRIER = 22663, // immunity in phase 1
|
||||
SPELL_SHADOWBLINK_INTRO = 22664,
|
||||
SPELL_SHADOWBOLT_VOLLEY = 22665,
|
||||
SPELL_SILENCE = 22666,
|
||||
SPELL_SHADOW_COMMAND = 22667,
|
||||
SPELL_SHADOWBOLT = 22677,
|
||||
SPELL_FEAR = 22678,
|
||||
SPELL_SHADOWBLINK = 22681, // triggers a random from spells (22668 - 22676)
|
||||
|
||||
SPELL_SUMMON_DRAKONID_BONES = 23363,
|
||||
|
||||
MAP_ID_BWL = 469,
|
||||
|
||||
FACTION_BLACK_DRAGON = 103
|
||||
};
|
||||
|
||||
static const DialogueEntry aIntroDialogue[] =
|
||||
{
|
||||
{SAY_GAMESBEGIN_1, NPC_LORD_VICTOR_NEFARIUS, 4000},
|
||||
{SAY_GAMESBEGIN_2, NPC_LORD_VICTOR_NEFARIUS, 5000},
|
||||
{SPELL_SHADOWBLINK, 0, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
struct SpawnLocation
|
||||
{
|
||||
float m_fX, m_fY, m_fZ;
|
||||
};
|
||||
|
||||
static const SpawnLocation aNefarianLocs[4] =
|
||||
{
|
||||
{ -7599.32f, -1191.72f, 475.545f}, // opening where red/blue/black darknid spawner appear (ori 3.05433)
|
||||
{ -7526.27f, -1135.04f, 473.445f}, // same as above, closest to door (ori 5.75959)
|
||||
{ -7498.177f, -1273.277f, 481.649f}, // nefarian spawn location (ori 1.798)
|
||||
{ -7502.002f, -1256.503f, 476.758f}, // nefarian fly to this position
|
||||
};
|
||||
|
||||
static const uint32 aPossibleDrake[MAX_DRAKES] = {NPC_BRONZE_DRAKANOID, NPC_BLUE_DRAKANOID, NPC_RED_DRAKANOID, NPC_GREEN_DRAKANOID, NPC_BLACK_DRAKANOID};
|
||||
|
||||
// This script is complicated
|
||||
// Instead of morphing Victor Nefarius we will have him control phase 1
|
||||
// And then have him spawn "Nefarian" for phase 2
|
||||
// When phase 2 starts Victor Nefarius will go invisible and stop attacking
|
||||
// If Nefarian reched home because nef killed the players then nef will trigger this guy to EnterEvadeMode
|
||||
// and allow players to start the event over
|
||||
// If nefarian dies then he will kill himself then he will be despawned in Nefarian script
|
||||
// To prevent players from doing the event twice
|
||||
|
||||
// Dev note: Lord Victor Nefarius should despawn completely, then ~5 seconds later Nefarian should appear.
|
||||
|
||||
struct boss_victor_nefariusAI : public ScriptedAI, private DialogueHelper
|
||||
{
|
||||
boss_victor_nefariusAI(Creature* pCreature) : ScriptedAI(pCreature),
|
||||
DialogueHelper(aIntroDialogue)
|
||||
{
|
||||
// Select the 2 different drakes that we are going to use until despawned
|
||||
// 5 possiblities for the first drake, 4 for the second, 20 total possiblites
|
||||
|
||||
// select two different numbers between 0..MAX_DRAKES-1
|
||||
uint8 uiPos1 = urand(0, MAX_DRAKES - 1);
|
||||
uint8 uiPos2 = (uiPos1 + urand(1, MAX_DRAKES - 1)) % MAX_DRAKES;
|
||||
|
||||
m_uiDrakeTypeOne = aPossibleDrake[uiPos1];
|
||||
m_uiDrakeTypeTwo = aPossibleDrake[uiPos2];
|
||||
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
InitializeDialogueHelper(m_pInstance);
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiSpawnedAdds;
|
||||
uint32 m_uiAddSpawnTimer;
|
||||
uint32 m_uiShadowBoltTimer;
|
||||
uint32 m_uiFearTimer;
|
||||
uint32 m_uiDrakeTypeOne;
|
||||
uint32 m_uiDrakeTypeTwo;
|
||||
uint32 m_uiShadowboltVolleyTimer;
|
||||
uint32 m_uiSilenceTimer;
|
||||
uint32 m_uiShadowCommandTimer;
|
||||
uint32 m_uiShadowBlinkTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
// Check the map id because the same creature entry is involved in other scripted event in other instance
|
||||
if (m_creature->GetMapId() != MAP_ID_BWL)
|
||||
return;
|
||||
|
||||
m_uiSpawnedAdds = 0;
|
||||
m_uiAddSpawnTimer = 10000;
|
||||
m_uiShadowBoltTimer = 3000;
|
||||
m_uiFearTimer = 8000;
|
||||
m_uiShadowboltVolleyTimer = 13000;
|
||||
m_uiSilenceTimer = 23000;
|
||||
m_uiShadowCommandTimer = 30000;
|
||||
m_uiShadowBlinkTimer = 40000;
|
||||
|
||||
// set gossip flag to begin the event
|
||||
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
|
||||
// Make visible if needed
|
||||
if (m_creature->GetVisibility() != VISIBILITY_ON)
|
||||
m_creature->SetVisibility(VISIBILITY_ON);
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_NEFARIAN, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_NEFARIAN, FAIL);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* pWho) override
|
||||
{
|
||||
if (m_creature->Attack(pWho, false))
|
||||
{
|
||||
m_creature->AddThreat(pWho);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
// Only range attack - ToDo: research the distance
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho, 30.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
if (m_creature->GetMapId() != MAP_ID_BWL)
|
||||
return;
|
||||
|
||||
if (pSummoned->GetEntry() == NPC_NEFARIAN)
|
||||
{
|
||||
pSummoned->SetWalk(false);
|
||||
|
||||
// see boss_onyxia (also note the removal of this in boss_nefarian)
|
||||
pSummoned->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2);
|
||||
pSummoned->SetLevitate(true);
|
||||
|
||||
// Let Nefarian fly towards combat area
|
||||
pSummoned->GetMotionMaster()->MovePoint(1, aNefarianLocs[3].m_fX, aNefarianLocs[3].m_fY, aNefarianLocs[3].m_fZ);
|
||||
DoScriptText(SAY_NEFARIAN_INTRO, pSummoned);
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_uiSpawnedAdds;
|
||||
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
pSummoned->AI()->AttackStart(pTarget);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedMovementInform(Creature* pSummoned, uint32 uiMotionType, uint32 uiPointId) override
|
||||
{
|
||||
if (m_creature->GetMapId() != MAP_ID_BWL)
|
||||
return;
|
||||
|
||||
// If Nefarian has reached combat area, let him attack
|
||||
if (pSummoned->GetEntry() == NPC_NEFARIAN && uiMotionType == POINT_MOTION_TYPE && uiPointId == 1)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
pSummoned->AI()->AttackStart(pTarget);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureJustDied(Creature* pSummoned) override
|
||||
{
|
||||
if (m_creature->GetMapId() != MAP_ID_BWL)
|
||||
return;
|
||||
|
||||
// Despawn self when Nefarian is killed
|
||||
if (pSummoned->GetEntry() == NPC_NEFARIAN)
|
||||
m_creature->ForcedDespawn();
|
||||
else
|
||||
pSummoned->CastSpell(pSummoned, SPELL_SUMMON_DRAKONID_BONES, true);
|
||||
}
|
||||
|
||||
void JustDidDialogueStep(int32 iEntry) override
|
||||
{
|
||||
// Start combat after the dialogue is finished
|
||||
if (iEntry == SPELL_SHADOWBLINK)
|
||||
{
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
m_creature->SetFactionTemporary(FACTION_BLACK_DRAGON, TEMPFACTION_RESTORE_REACH_HOME);
|
||||
DoCastSpellIfCan(m_creature, SPELL_NEFARIUS_BARRIER, CAST_TRIGGERED);
|
||||
DoCastSpellIfCan(m_creature, SPELL_SHADOWBLINK_INTRO, CAST_TRIGGERED);
|
||||
m_creature->SetInCombatWithZone();
|
||||
}
|
||||
}
|
||||
|
||||
void DoStartIntro()
|
||||
{
|
||||
StartNextDialogueText(SAY_GAMESBEGIN_1);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (m_creature->GetMapId() != MAP_ID_BWL)
|
||||
return;
|
||||
|
||||
DialogueUpdate(uiDiff);
|
||||
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Only do this if we haven't spawned nef yet
|
||||
if (m_uiSpawnedAdds < MAX_DRAKE_SUMMONS)
|
||||
{
|
||||
// Shadowbolt Timer
|
||||
if (m_uiShadowBoltTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_SHADOWBOLT) == CAST_OK)
|
||||
m_uiShadowBoltTimer = urand(2000, 4000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiShadowBoltTimer -= uiDiff;
|
||||
|
||||
// Fear Timer
|
||||
if (m_uiFearTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_FEAR) == CAST_OK)
|
||||
m_uiFearTimer = urand(10000, 20000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiFearTimer -= uiDiff;
|
||||
|
||||
// Shadowbolt Volley
|
||||
if (m_uiShadowboltVolleyTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SHADOWBOLT_VOLLEY) == CAST_OK)
|
||||
m_uiShadowboltVolleyTimer = urand(19000, 28000);
|
||||
}
|
||||
else
|
||||
m_uiShadowboltVolleyTimer -= uiDiff;
|
||||
|
||||
// Silence
|
||||
if (m_uiSilenceTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_SILENCE) == CAST_OK)
|
||||
m_uiSilenceTimer = urand(14000, 23000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiSilenceTimer -= uiDiff;
|
||||
|
||||
// Shadow Command
|
||||
if (m_uiShadowCommandTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_COMMAND) == CAST_OK)
|
||||
m_uiShadowCommandTimer = urand(24000, 30000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiShadowCommandTimer -= uiDiff;
|
||||
|
||||
// ShadowBlink
|
||||
if (m_uiShadowBlinkTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SHADOWBLINK) == CAST_OK)
|
||||
m_uiShadowBlinkTimer = urand(30000, 40000);
|
||||
}
|
||||
else
|
||||
m_uiShadowBlinkTimer -= uiDiff;
|
||||
|
||||
// Add spawning mechanism
|
||||
if (m_uiAddSpawnTimer < uiDiff)
|
||||
{
|
||||
// Spawn 2 random types of creatures at the 2 locations
|
||||
uint32 uiCreatureId = 0;
|
||||
|
||||
// 1 in 3 chance it will be a chromatic
|
||||
uiCreatureId = urand(0, 2) ? m_uiDrakeTypeOne : uint32(NPC_CHROMATIC_DRAKANOID);
|
||||
m_creature->SummonCreature(uiCreatureId, aNefarianLocs[0].m_fX, aNefarianLocs[0].m_fY, aNefarianLocs[0].m_fZ, 5.000f, TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, 30000);
|
||||
|
||||
// 1 in 3 chance it will be a chromatic
|
||||
uiCreatureId = urand(0, 2) ? m_uiDrakeTypeTwo : uint32(NPC_CHROMATIC_DRAKANOID);
|
||||
m_creature->SummonCreature(uiCreatureId, aNefarianLocs[1].m_fX, aNefarianLocs[1].m_fY, aNefarianLocs[1].m_fZ, 5.000, TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, 30000);
|
||||
|
||||
// Begin phase 2 by spawning Nefarian
|
||||
if (m_uiSpawnedAdds >= MAX_DRAKE_SUMMONS)
|
||||
{
|
||||
// Inturrupt any spell casting
|
||||
m_creature->InterruptNonMeleeSpells(false);
|
||||
|
||||
// Make super invis
|
||||
if (m_creature->GetVisibility() != VISIBILITY_OFF)
|
||||
m_creature->SetVisibility(VISIBILITY_OFF);
|
||||
|
||||
// Spawn Nefarian
|
||||
// Summon as active, to be able to work proper!
|
||||
m_creature->SummonCreature(NPC_NEFARIAN, aNefarianLocs[2].m_fX, aNefarianLocs[2].m_fY, aNefarianLocs[2].m_fZ, 0, TEMPSUMMON_DEAD_DESPAWN, 0, true);
|
||||
}
|
||||
|
||||
m_uiAddSpawnTimer = 4000;
|
||||
}
|
||||
else
|
||||
m_uiAddSpawnTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_victor_nefarius(Creature* pCreature)
|
||||
{
|
||||
return new boss_victor_nefariusAI(pCreature);
|
||||
}
|
||||
|
||||
bool GossipHello_boss_victor_nefarius(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (pCreature->GetMapId() != MAP_ID_BWL)
|
||||
return true;
|
||||
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NEFARIUS_1 , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_NEFARIUS_1, pCreature->GetObjectGuid());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GossipSelect_boss_victor_nefarius(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
|
||||
{
|
||||
if (pCreature->GetMapId() != MAP_ID_BWL)
|
||||
return true;
|
||||
|
||||
switch (uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
pCreature->HandleEmote(EMOTE_ONESHOT_TALK);
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NEFARIUS_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_NEFARIUS_2, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
pCreature->HandleEmote(EMOTE_ONESHOT_TALK);
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NEFARIUS_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_NEFARIUS_3, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+3:
|
||||
pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
// Start the intro event
|
||||
if (boss_victor_nefariusAI* pBossAI = dynamic_cast<boss_victor_nefariusAI*>(pCreature->AI()))
|
||||
pBossAI->DoStartIntro();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_boss_victor_nefarius()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_victor_nefarius";
|
||||
pNewScript->GetAI = &GetAI_boss_victor_nefarius;
|
||||
pNewScript->pGossipHello = &GossipHello_boss_victor_nefarius;
|
||||
pNewScript->pGossipSelect = &GossipSelect_boss_victor_nefarius;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Instance_Blackwing_Lair
|
||||
SD%Complete: 90
|
||||
SDComment:
|
||||
SDCategory: Blackwing Lair
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "blackwing_lair.h"
|
||||
|
||||
instance_blackwing_lair::instance_blackwing_lair(Map* pMap) : ScriptedInstance(pMap),
|
||||
m_uiResetTimer(0),
|
||||
m_uiDefenseTimer(0)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
}
|
||||
|
||||
bool instance_blackwing_lair::IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
case NPC_BLACKWING_TECHNICIAN:
|
||||
// Sort creatures so we can get only the ones near Vaelastrasz
|
||||
if (pCreature->IsWithinDist2d(aNefariusSpawnLoc[0], aNefariusSpawnLoc[1], 50.0f))
|
||||
m_lTechnicianGuids.push_back(pCreature->GetObjectGuid());
|
||||
break;
|
||||
case NPC_MONSTER_GENERATOR:
|
||||
m_vGeneratorGuids.push_back(pCreature->GetObjectGuid());
|
||||
break;
|
||||
case NPC_BLACKWING_LEGIONNAIRE:
|
||||
case NPC_BLACKWING_MAGE:
|
||||
case NPC_DRAGONSPAWN:
|
||||
m_lDefendersGuids.push_back(pCreature->GetObjectGuid());
|
||||
break;
|
||||
case NPC_RAZORGORE:
|
||||
case NPC_NEFARIANS_TROOPS:
|
||||
case NPC_BLACKWING_ORB_TRIGGER:
|
||||
case NPC_VAELASTRASZ:
|
||||
case NPC_LORD_VICTOR_NEFARIUS:
|
||||
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::OnObjectCreate(GameObject* pGo)
|
||||
{
|
||||
switch (pGo->GetEntry())
|
||||
{
|
||||
case GO_DOOR_RAZORGORE_ENTER:
|
||||
case GO_ORB_OF_DOMINATION:
|
||||
case GO_DOOR_NEFARIAN:
|
||||
break;
|
||||
case GO_DOOR_RAZORGORE_EXIT:
|
||||
if (m_auiEncounter[TYPE_RAZORGORE] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_DOOR_CHROMAGGUS_EXIT:
|
||||
if (m_auiEncounter[TYPE_CHROMAGGUS] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_DOOR_VAELASTRASZ:
|
||||
if (m_auiEncounter[TYPE_VAELASTRASZ] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_DOOR_LASHLAYER:
|
||||
if (m_auiEncounter[TYPE_LASHLAYER] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_BLACK_DRAGON_EGG:
|
||||
m_lDragonEggsGuids.push_back(pGo->GetObjectGuid());
|
||||
return;
|
||||
case GO_DRAKONID_BONES:
|
||||
m_lDrakonidBonesGuids.push_back(pGo->GetObjectGuid());
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
m_mGoEntryGuidStore[pGo->GetEntry()] = pGo->GetObjectGuid();
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case TYPE_RAZORGORE:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData != SPECIAL)
|
||||
DoUseDoorOrButton(GO_DOOR_RAZORGORE_ENTER);
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_DOOR_RAZORGORE_EXIT);
|
||||
else if (uiData == FAIL)
|
||||
{
|
||||
m_uiResetTimer = 30000;
|
||||
|
||||
// Reset the Orb of Domination and the eggs
|
||||
DoToggleGameObjectFlags(GO_ORB_OF_DOMINATION, GO_FLAG_NO_INTERACT, true);
|
||||
|
||||
// Reset defenders
|
||||
for (GuidList::const_iterator itr = m_lDefendersGuids.begin(); itr != m_lDefendersGuids.end(); ++itr)
|
||||
{
|
||||
if (Creature* pDefender = instance->GetCreature(*itr))
|
||||
pDefender->ForcedDespawn();
|
||||
}
|
||||
|
||||
m_lUsedEggsGuids.clear();
|
||||
m_lDefendersGuids.clear();
|
||||
}
|
||||
break;
|
||||
case TYPE_VAELASTRASZ:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
// Prevent the players from running back to the first room; use if the encounter is not special
|
||||
if (uiData != SPECIAL)
|
||||
DoUseDoorOrButton(GO_DOOR_RAZORGORE_EXIT);
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_DOOR_VAELASTRASZ);
|
||||
break;
|
||||
case TYPE_LASHLAYER:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_DOOR_LASHLAYER);
|
||||
break;
|
||||
case TYPE_FIREMAW:
|
||||
case TYPE_EBONROC:
|
||||
case TYPE_FLAMEGOR:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
case TYPE_CHROMAGGUS:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_DOOR_CHROMAGGUS_EXIT);
|
||||
break;
|
||||
case TYPE_NEFARIAN:
|
||||
// Don't store the same thing twice
|
||||
if (m_auiEncounter[uiType] == uiData)
|
||||
break;
|
||||
if (uiData == SPECIAL)
|
||||
{
|
||||
// handle missing spell 23362
|
||||
Creature* pNefarius = GetSingleCreatureFromStorage(NPC_LORD_VICTOR_NEFARIUS);
|
||||
if (!pNefarius)
|
||||
break;
|
||||
|
||||
for (GuidList::const_iterator itr = m_lDrakonidBonesGuids.begin(); itr != m_lDrakonidBonesGuids.end(); ++itr)
|
||||
{
|
||||
// The Go script will handle the missing spell 23361
|
||||
if (GameObject* pGo = instance->GetGameObject(*itr))
|
||||
pGo->Use(pNefarius);
|
||||
}
|
||||
// Don't store special data
|
||||
break;
|
||||
}
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
DoUseDoorOrButton(GO_DOOR_NEFARIAN);
|
||||
// Cleanup the drakonid bones
|
||||
if (uiData == FAIL)
|
||||
{
|
||||
for (GuidList::const_iterator itr = m_lDrakonidBonesGuids.begin(); itr != m_lDrakonidBonesGuids.end(); ++itr)
|
||||
{
|
||||
if (GameObject* pGo = instance->GetGameObject(*itr))
|
||||
pGo->SetLootState(GO_JUST_DEACTIVATED);
|
||||
}
|
||||
|
||||
m_lDrakonidBonesGuids.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiData == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
|
||||
<< m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
|
||||
<< m_auiEncounter[6] << " " << m_auiEncounter[7];
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::Load(const char* chrIn)
|
||||
{
|
||||
if (!chrIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(chrIn);
|
||||
|
||||
std::istringstream loadStream(chrIn);
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
|
||||
>> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7];
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
uint32 instance_blackwing_lair::GetData(uint32 uiType) const
|
||||
{
|
||||
if (uiType < MAX_ENCOUNTER)
|
||||
return m_auiEncounter[uiType];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::SetData64(uint32 uiData, uint64 uiGuid)
|
||||
{
|
||||
if (uiData == DATA_DRAGON_EGG)
|
||||
{
|
||||
if (GameObject* pEgg = instance->GetGameObject(ObjectGuid(uiGuid)))
|
||||
m_lUsedEggsGuids.push_back(pEgg->GetObjectGuid());
|
||||
|
||||
// If all eggs are destroyed, then allow Razorgore to be attacked
|
||||
if (m_lUsedEggsGuids.size() == m_lDragonEggsGuids.size())
|
||||
{
|
||||
SetData(TYPE_RAZORGORE, SPECIAL);
|
||||
DoToggleGameObjectFlags(GO_ORB_OF_DOMINATION, GO_FLAG_NO_INTERACT, true);
|
||||
|
||||
// Emote for the start of the second phase
|
||||
if (Creature* pTrigger = GetSingleCreatureFromStorage(NPC_NEFARIANS_TROOPS))
|
||||
{
|
||||
DoScriptText(EMOTE_ORB_SHUT_OFF, pTrigger);
|
||||
DoScriptText(EMOTE_TROOPS_FLEE, pTrigger);
|
||||
}
|
||||
|
||||
// Break mind control and set max health
|
||||
if (Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE))
|
||||
{
|
||||
pRazorgore->RemoveAllAuras();
|
||||
pRazorgore->SetHealth(pRazorgore->GetMaxHealth());
|
||||
}
|
||||
|
||||
// All defenders evade and despawn
|
||||
for (GuidList::const_iterator itr = m_lDefendersGuids.begin(); itr != m_lDefendersGuids.end(); ++itr)
|
||||
{
|
||||
if (Creature* pDefender = instance->GetCreature(*itr))
|
||||
{
|
||||
pDefender->AI()->EnterEvadeMode();
|
||||
pDefender->ForcedDespawn(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::OnCreatureEnterCombat(Creature* pCreature)
|
||||
{
|
||||
if (pCreature->GetEntry() == NPC_GRETHOK_CONTROLLER)
|
||||
{
|
||||
SetData(TYPE_RAZORGORE, IN_PROGRESS);
|
||||
m_uiDefenseTimer = 40000;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::OnCreatureDeath(Creature* pCreature)
|
||||
{
|
||||
if (pCreature->GetEntry() == NPC_GRETHOK_CONTROLLER)
|
||||
{
|
||||
// Allow orb to be used
|
||||
DoToggleGameObjectFlags(GO_ORB_OF_DOMINATION, GO_FLAG_NO_INTERACT, false);
|
||||
|
||||
if (Creature* pOrbTrigger = GetSingleCreatureFromStorage(NPC_BLACKWING_ORB_TRIGGER))
|
||||
pOrbTrigger->InterruptNonMeleeSpells(false);
|
||||
}
|
||||
}
|
||||
|
||||
void instance_blackwing_lair::Update(uint32 uiDiff)
|
||||
{
|
||||
// Reset Razorgore in case of wipe
|
||||
if (m_uiResetTimer)
|
||||
{
|
||||
if (m_uiResetTimer <= uiDiff)
|
||||
{
|
||||
// Respawn Razorgore
|
||||
if (Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE))
|
||||
{
|
||||
if (!pRazorgore->IsAlive())
|
||||
pRazorgore->Respawn();
|
||||
}
|
||||
|
||||
// Respawn the Dragon Eggs
|
||||
for (GuidList::const_iterator itr = m_lDragonEggsGuids.begin(); itr != m_lDragonEggsGuids.end(); ++itr)
|
||||
{
|
||||
if (GameObject* pEgg = instance->GetGameObject(*itr))
|
||||
{
|
||||
if (!pEgg->isSpawned())
|
||||
pEgg->Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
m_uiResetTimer = 0;
|
||||
}
|
||||
else
|
||||
m_uiResetTimer -= uiDiff;
|
||||
}
|
||||
|
||||
if (GetData(TYPE_RAZORGORE) != IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (m_uiDefenseTimer < uiDiff)
|
||||
{
|
||||
// Allow Razorgore to spawn the defenders
|
||||
Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE);
|
||||
if (!pRazorgore)
|
||||
return;
|
||||
|
||||
// Randomize generators
|
||||
std::random_shuffle(m_vGeneratorGuids.begin(), m_vGeneratorGuids.end());
|
||||
|
||||
// Spawn the defenders
|
||||
for (uint8 i = 0; i < MAX_EGGS_DEFENDERS; ++i)
|
||||
{
|
||||
Creature* pGenerator = instance->GetCreature(m_vGeneratorGuids[i]);
|
||||
if (!pGenerator)
|
||||
return;
|
||||
|
||||
pRazorgore->SummonCreature(aRazorgoreSpawns[i], pGenerator->GetPositionX(), pGenerator->GetPositionY(), pGenerator->GetPositionZ(), pGenerator->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0);
|
||||
}
|
||||
|
||||
m_uiDefenseTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiDefenseTimer -= uiDiff;
|
||||
}
|
||||
|
||||
InstanceData* GetInstanceData_instance_blackwing_lair(Map* pMap)
|
||||
{
|
||||
return new instance_blackwing_lair(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_blackwing_lair()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "instance_blackwing_lair";
|
||||
pNewScript->GetInstanceData = &GetInstanceData_instance_blackwing_lair;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Baron_Geddon
|
||||
SD%Complete: 100
|
||||
SDComment: Armaggedon is not working properly (core issue)
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
EMOTE_SERVICE = -1409000,
|
||||
|
||||
SPELL_INFERNO = 19695,
|
||||
SPELL_IGNITE_MANA = 19659,
|
||||
SPELL_LIVING_BOMB = 20475,
|
||||
SPELL_ARMAGEDDON = 20478
|
||||
};
|
||||
|
||||
struct boss_baron_geddonAI : public ScriptedAI
|
||||
{
|
||||
boss_baron_geddonAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
bool m_bIsArmageddon;
|
||||
uint32 m_uiInfernoTimer;
|
||||
uint32 m_uiIgniteManaTimer;
|
||||
uint32 m_uiLivingBombTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_bIsArmageddon = false;
|
||||
m_uiInfernoTimer = 45000;
|
||||
m_uiIgniteManaTimer = 30000;
|
||||
m_uiLivingBombTimer = 35000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GEDDON, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GEDDON, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GEDDON, NOT_STARTED);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_bIsArmageddon) // Do nothing untill armageddon triggers
|
||||
return;
|
||||
|
||||
// If we are <2% hp cast Armageddom
|
||||
if (m_creature->GetHealthPercent() <= 2.0f && !m_bIsArmageddon)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_ARMAGEDDON, CAST_INTERRUPT_PREVIOUS) == CAST_OK)
|
||||
{
|
||||
DoScriptText(EMOTE_SERVICE, m_creature);
|
||||
m_bIsArmageddon = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Inferno_Timer
|
||||
if (m_uiInfernoTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_INFERNO) == CAST_OK)
|
||||
m_uiInfernoTimer = 45000;
|
||||
}
|
||||
else
|
||||
m_uiInfernoTimer -= uiDiff;
|
||||
|
||||
// Ignite Mana Timer
|
||||
if (m_uiIgniteManaTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_IGNITE_MANA) == CAST_OK)
|
||||
m_uiIgniteManaTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiIgniteManaTimer -= uiDiff;
|
||||
|
||||
// Living Bomb Timer
|
||||
if (m_uiLivingBombTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_LIVING_BOMB) == CAST_OK)
|
||||
m_uiLivingBombTimer = 35000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiLivingBombTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_baron_geddon(Creature* pCreature)
|
||||
{
|
||||
return new boss_baron_geddonAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_baron_geddon()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_baron_geddon";
|
||||
pNewScript->GetAI = &GetAI_boss_baron_geddon;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Garr
|
||||
SD%Complete: 50
|
||||
SDComment: Garr's enrage is missing
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
// Garr spells
|
||||
SPELL_ANTIMAGICPULSE = 19492,
|
||||
SPELL_MAGMASHACKLES = 19496,
|
||||
SPELL_ENRAGE = 19516, // TODO Stacking enrage (stacks to 10 times)
|
||||
|
||||
// Add spells
|
||||
SPELL_ERUPTION = 19497,
|
||||
SPELL_MASSIVE_ERUPTION = 20483, // TODO possible on death
|
||||
SPELL_IMMOLATE = 20294,
|
||||
SPELL_SEPARATION_ANXIETY = 23492, // Used if separated too far from Garr, 21095 use unknown.
|
||||
};
|
||||
|
||||
struct boss_garrAI : public ScriptedAI
|
||||
{
|
||||
boss_garrAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiAntiMagicPulseTimer;
|
||||
uint32 m_uiMagmaShacklesTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiAntiMagicPulseTimer = 25000;
|
||||
m_uiMagmaShacklesTimer = 15000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GARR, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GARR, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GARR, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// AntiMagicPulse_Timer
|
||||
if (m_uiAntiMagicPulseTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_ANTIMAGICPULSE) == CAST_OK)
|
||||
m_uiAntiMagicPulseTimer = urand(10000, 15000);
|
||||
}
|
||||
else
|
||||
m_uiAntiMagicPulseTimer -= uiDiff;
|
||||
|
||||
// MagmaShackles_Timer
|
||||
if (m_uiMagmaShacklesTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_MAGMASHACKLES) == CAST_OK)
|
||||
m_uiMagmaShacklesTimer = urand(8000, 12000);
|
||||
}
|
||||
else
|
||||
m_uiMagmaShacklesTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
struct mob_fireswornAI : public ScriptedAI
|
||||
{
|
||||
mob_fireswornAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiImmolateTimer;
|
||||
uint32 m_uiSeparationCheckTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiImmolateTimer = urand(4000, 8000); // These times are probably wrong
|
||||
m_uiSeparationCheckTimer = 5000;
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Immolate_Timer
|
||||
if (m_uiImmolateTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_IMMOLATE) == CAST_OK)
|
||||
m_uiImmolateTimer = urand(5000, 10000);
|
||||
}
|
||||
}
|
||||
else m_uiImmolateTimer -= uiDiff;
|
||||
|
||||
if (m_uiSeparationCheckTimer < uiDiff)
|
||||
{
|
||||
// Distance guesswork, but should be ok
|
||||
Creature* pGarr = m_pInstance->GetSingleCreatureFromStorage(NPC_GARR);
|
||||
if (pGarr && pGarr->IsAlive() && !m_creature->IsWithinDist2d(pGarr->GetPositionX(), pGarr->GetPositionY(), 50.0f))
|
||||
DoCastSpellIfCan(m_creature, SPELL_SEPARATION_ANXIETY, CAST_TRIGGERED);
|
||||
|
||||
m_uiSeparationCheckTimer = 5000;
|
||||
}
|
||||
else
|
||||
m_uiSeparationCheckTimer -= uiDiff;
|
||||
|
||||
// Cast Erruption and let them die
|
||||
if (m_creature->GetHealthPercent() <= 10.0f)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature->getVictim(), SPELL_ERUPTION);
|
||||
m_creature->SetDeathState(JUST_DIED);
|
||||
m_creature->RemoveCorpse();
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_garr(Creature* pCreature)
|
||||
{
|
||||
return new boss_garrAI(pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_firesworn(Creature* pCreature)
|
||||
{
|
||||
return new mob_fireswornAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_garr()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_garr";
|
||||
pNewScript->GetAI = &GetAI_boss_garr;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "mob_firesworn";
|
||||
pNewScript->GetAI = &GetAI_mob_firesworn;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Gehennas
|
||||
SD%Complete: 90
|
||||
SDComment:
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_SHADOW_BOLT = 19728, // 19729 exists too, but can be reflected
|
||||
SPELL_RAIN_OF_FIRE = 19717,
|
||||
SPELL_GEHENNAS_CURSE = 19716
|
||||
};
|
||||
|
||||
struct boss_gehennasAI : public ScriptedAI
|
||||
{
|
||||
boss_gehennasAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiShadowBoltTimer;
|
||||
uint32 m_uiRainOfFireTimer;
|
||||
uint32 m_uiGehennasCurseTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiShadowBoltTimer = 6000;
|
||||
m_uiRainOfFireTimer = 10000;
|
||||
m_uiGehennasCurseTimer = 12000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pwho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GEHENNAS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GEHENNAS, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GEHENNAS, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// ShadowBolt Timer
|
||||
if (m_uiShadowBoltTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_BOLT) == CAST_OK)
|
||||
m_uiShadowBoltTimer = 7000;
|
||||
}
|
||||
else // In case someone attempts soloing, we don't need to scan for targets every tick
|
||||
m_uiShadowBoltTimer = 7000;
|
||||
}
|
||||
else
|
||||
m_uiShadowBoltTimer -= uiDiff;
|
||||
|
||||
// Rain of Fire Timer
|
||||
if (m_uiRainOfFireTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_RAIN_OF_FIRE) == CAST_OK)
|
||||
m_uiRainOfFireTimer = urand(4000, 12000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiRainOfFireTimer -= uiDiff;
|
||||
|
||||
// GehennasCurse Timer
|
||||
if (m_uiGehennasCurseTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_GEHENNAS_CURSE) == CAST_OK)
|
||||
m_uiGehennasCurseTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiGehennasCurseTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_gehennas(Creature* pCreature)
|
||||
{
|
||||
return new boss_gehennasAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_gehennas()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_gehennas";
|
||||
pNewScript->GetAI = &GetAI_boss_gehennas;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Golemagg
|
||||
SD%Complete: 80
|
||||
SDComment: Rager need to be tied to boss (Despawn on boss-death)
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_MAGMA_SPLASH = 13879,
|
||||
SPELL_PYROBLAST = 20228,
|
||||
SPELL_EARTHQUAKE = 19798,
|
||||
SPELL_ENRAGE = 19953,
|
||||
SPELL_GOLEMAGG_TRUST = 20553,
|
||||
|
||||
// Core Rager
|
||||
EMOTE_LOW_HP = -1409002,
|
||||
SPELL_MANGLE = 19820
|
||||
};
|
||||
|
||||
struct boss_golemaggAI : public ScriptedAI
|
||||
{
|
||||
boss_golemaggAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiPyroblastTimer;
|
||||
uint32 m_uiEarthquakeTimer;
|
||||
uint32 m_uiBuffTimer;
|
||||
bool m_bEnraged;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiPyroblastTimer = 7 * IN_MILLISECONDS;
|
||||
m_uiEarthquakeTimer = 3 * IN_MILLISECONDS;
|
||||
m_uiBuffTimer = 1.5 * IN_MILLISECONDS;
|
||||
m_bEnraged = false;
|
||||
|
||||
m_creature->CastSpell(m_creature, SPELL_MAGMA_SPLASH, true);
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GOLEMAGG, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GOLEMAGG, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GOLEMAGG, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Pyroblast
|
||||
if (m_uiPyroblastTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_PYROBLAST) == CAST_OK)
|
||||
m_uiPyroblastTimer = 7 * IN_MILLISECONDS;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiPyroblastTimer -= uiDiff;
|
||||
|
||||
// Enrage
|
||||
if (!m_bEnraged && m_creature->GetHealthPercent() < 10.0f)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK)
|
||||
m_bEnraged = true;
|
||||
}
|
||||
|
||||
// Earthquake
|
||||
if (m_bEnraged)
|
||||
{
|
||||
if (m_uiEarthquakeTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_EARTHQUAKE) == CAST_OK)
|
||||
m_uiEarthquakeTimer = 3 * IN_MILLISECONDS;
|
||||
}
|
||||
else
|
||||
m_uiEarthquakeTimer -= uiDiff;
|
||||
}
|
||||
|
||||
// Golemagg's Trust
|
||||
if (m_uiBuffTimer < uiDiff)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_GOLEMAGG_TRUST);
|
||||
m_uiBuffTimer = 1.5 * IN_MILLISECONDS;
|
||||
}
|
||||
else
|
||||
m_uiBuffTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
struct mob_core_ragerAI : public ScriptedAI
|
||||
{
|
||||
mob_core_ragerAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
uint32 m_uiMangleTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiMangleTimer = 7 * IN_MILLISECONDS; // These times are probably wrong
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage) override
|
||||
{
|
||||
if (m_creature->GetHealthPercent() < 50.0f)
|
||||
{
|
||||
if (m_pInstance && m_pInstance->GetData(TYPE_GOLEMAGG) != DONE)
|
||||
{
|
||||
DoScriptText(EMOTE_LOW_HP, m_creature);
|
||||
m_creature->SetHealth(m_creature->GetMaxHealth());
|
||||
uiDamage = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Mangle
|
||||
if (m_uiMangleTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MANGLE) == CAST_OK)
|
||||
m_uiMangleTimer = 10 * IN_MILLISECONDS;
|
||||
}
|
||||
else
|
||||
m_uiMangleTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_golemagg(Creature* pCreature)
|
||||
{
|
||||
return new boss_golemaggAI(pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_core_rager(Creature* pCreature)
|
||||
{
|
||||
return new mob_core_ragerAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_golemagg()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_golemagg";
|
||||
pNewScript->GetAI = &GetAI_boss_golemagg;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "mob_core_rager";
|
||||
pNewScript->GetAI = &GetAI_mob_core_rager;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Lucifron
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_IMPENDINGDOOM = 19702,
|
||||
SPELL_LUCIFRONCURSE = 19703,
|
||||
SPELL_SHADOWSHOCK = 19460
|
||||
};
|
||||
|
||||
struct boss_lucifronAI : public ScriptedAI
|
||||
{
|
||||
boss_lucifronAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiImpendingDoomTimer;
|
||||
uint32 m_uiLucifronCurseTimer;
|
||||
uint32 m_uiShadowShockTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiImpendingDoomTimer = 10000;
|
||||
m_uiLucifronCurseTimer = 20000;
|
||||
m_uiShadowShockTimer = 6000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LUCIFRON, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LUCIFRON, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LUCIFRON, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Impending doom timer
|
||||
if (m_uiImpendingDoomTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_IMPENDINGDOOM) == CAST_OK)
|
||||
m_uiImpendingDoomTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiImpendingDoomTimer -= uiDiff;
|
||||
|
||||
// Lucifron's curse timer
|
||||
if (m_uiLucifronCurseTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_LUCIFRONCURSE) == CAST_OK)
|
||||
m_uiLucifronCurseTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiLucifronCurseTimer -= uiDiff;
|
||||
|
||||
// Shadowshock
|
||||
if (m_uiShadowShockTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_SHADOWSHOCK) == CAST_OK)
|
||||
m_uiShadowShockTimer = 6000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiShadowShockTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_lucifron(Creature* pCreature)
|
||||
{
|
||||
return new boss_lucifronAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_lucifron()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_lucifron";
|
||||
pNewScript->GetAI = &GetAI_boss_lucifron;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Magmadar
|
||||
SD%Complete: 75
|
||||
SDComment: Lavabomb needs still core support
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
EMOTE_GENERIC_FRENZY_KILL = -1000001,
|
||||
|
||||
SPELL_FRENZY = 19451,
|
||||
SPELL_MAGMASPIT = 19449, // This is actually a buff he gives himself
|
||||
SPELL_PANIC = 19408,
|
||||
SPELL_LAVABOMB = 19411, // This calls a dummy server side effect that isn't implemented yet
|
||||
SPELL_LAVABOMB_ALT = 19428
|
||||
};
|
||||
|
||||
struct boss_magmadarAI : public ScriptedAI
|
||||
{
|
||||
boss_magmadarAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiFrenzyTimer;
|
||||
uint32 m_uiPanicTimer;
|
||||
uint32 m_uiLavabombTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiFrenzyTimer = 30000;
|
||||
m_uiPanicTimer = 7000;
|
||||
m_uiLavabombTimer = 12000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_MAGMASPIT, true);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_MAGMADAR, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_MAGMADAR, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_MAGMADAR, NOT_STARTED);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Frenzy_Timer
|
||||
if (m_uiFrenzyTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK)
|
||||
{
|
||||
DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature);
|
||||
m_uiFrenzyTimer = 15000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiFrenzyTimer -= uiDiff;
|
||||
|
||||
// Panic_Timer
|
||||
if (m_uiPanicTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_PANIC) == CAST_OK)
|
||||
m_uiPanicTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiPanicTimer -= uiDiff;
|
||||
|
||||
// Lavabomb_Timer
|
||||
if (m_uiLavabombTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_LAVABOMB) == CAST_OK)
|
||||
m_uiLavabombTimer = 12000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiLavabombTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_magmadar(Creature* pCreature)
|
||||
{
|
||||
return new boss_magmadarAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_magmadar()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_magmadar";
|
||||
pNewScript->GetAI = &GetAI_boss_magmadar;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Majordomo_Executus
|
||||
SD%Complete: 95
|
||||
SDComment: Minor weaknesses
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_AGGRO = -1409003,
|
||||
SAY_SLAY = -1409005,
|
||||
SAY_SPECIAL = -1409006, // Use unknown
|
||||
SAY_LAST_ADD = -1409019, // When only one add remaining
|
||||
SAY_DEFEAT_1 = -1409007,
|
||||
SAY_DEFEAT_2 = -1409020,
|
||||
SAY_DEFEAT_3 = -1409021,
|
||||
|
||||
SAY_SUMMON_0 = -1409023,
|
||||
SAY_SUMMON_1 = -1409024,
|
||||
SAY_SUMMON_MAJ = -1409008,
|
||||
SAY_ARRIVAL1_RAG = -1409009,
|
||||
SAY_ARRIVAL2_MAJ = -1409010,
|
||||
SAY_ARRIVAL3_RAG = -1409011,
|
||||
SAY_ARRIVAL4_MAJ = -1409022,
|
||||
|
||||
GOSSIP_ITEM_SUMMON_1 = -3409000,
|
||||
GOSSIP_ITEM_SUMMON_2 = -3409001,
|
||||
GOSSIP_ITEM_SUMMON_3 = -3409002,
|
||||
|
||||
TEXT_ID_SUMMON_1 = 4995,
|
||||
TEXT_ID_SUMMON_2 = 5011,
|
||||
TEXT_ID_SUMMON_3 = 5012,
|
||||
|
||||
SPELL_MAGIC_REFLECTION = 20619,
|
||||
SPELL_DAMAGE_REFLECTION = 21075,
|
||||
SPELL_BLASTWAVE = 20229,
|
||||
SPELL_AEGIS = 20620,
|
||||
SPELL_TELEPORT = 20618,
|
||||
|
||||
SPELL_TELEPORT_SELF = 19484,
|
||||
SPELL_SUMMON_RAGNAROS = 19774,
|
||||
SPELL_ELEMENTAL_FIRE = 19773,
|
||||
SPELL_RAGNA_EMERGE = 20568,
|
||||
};
|
||||
|
||||
struct boss_majordomoAI : public ScriptedAI
|
||||
{
|
||||
boss_majordomoAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (instance_molten_core*)pCreature->GetInstanceData();
|
||||
m_bHasEncounterFinished = false;
|
||||
Reset();
|
||||
}
|
||||
|
||||
instance_molten_core* m_pInstance;
|
||||
|
||||
uint32 m_uiMagicReflectionTimer;
|
||||
uint32 m_uiDamageReflectionTimer;
|
||||
uint32 m_uiBlastwaveTimer;
|
||||
uint32 m_uiTeleportTimer;
|
||||
uint32 m_uiAegisTimer;
|
||||
uint32 m_uiSpeechTimer;
|
||||
|
||||
ObjectGuid m_ragnarosGuid;
|
||||
bool m_bHasEncounterFinished;
|
||||
uint8 m_uiAddsKilled;
|
||||
uint8 m_uiSpeech;
|
||||
GuidList m_luiMajordomoAddsGUIDs;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiMagicReflectionTimer = 30000; // Damage reflection first so we alternate
|
||||
m_uiDamageReflectionTimer = 15000;
|
||||
m_uiBlastwaveTimer = 10000;
|
||||
m_uiTeleportTimer = 20000;
|
||||
m_uiAegisTimer = 5000;
|
||||
m_uiSpeechTimer = 1000;
|
||||
|
||||
m_uiAddsKilled = 0;
|
||||
m_uiSpeech = 0;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*pVictim*/) override
|
||||
{
|
||||
if (urand(0, 4))
|
||||
return;
|
||||
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (pWho->GetTypeId() == TYPEID_UNIT && pWho->GetEntry() == NPC_RAGNAROS)
|
||||
return;
|
||||
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_MAJORDOMO, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (!m_bHasEncounterFinished) // Normal reached home, FAIL
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_MAJORDOMO, FAIL);
|
||||
}
|
||||
else // Finished the encounter, DONE
|
||||
{
|
||||
// Exit combat
|
||||
m_creature->RemoveAllAurasOnEvade();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(true);
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
|
||||
// Set friendly
|
||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
m_creature->SetFactionTemporary(FACTION_MAJORDOMO_FRIENDLY, TEMPFACTION_RESTORE_RESPAWN);
|
||||
|
||||
// Reset orientation
|
||||
m_creature->SetFacingTo(m_aMajordomoLocations[0].m_fO);
|
||||
|
||||
// Start his speech
|
||||
m_uiSpeechTimer = 1; // At next tick
|
||||
m_uiSpeech = 1;
|
||||
|
||||
m_pInstance->SetData(TYPE_MAJORDOMO, DONE);
|
||||
}
|
||||
}
|
||||
|
||||
void StartSummonEvent(Player* pPlayer)
|
||||
{
|
||||
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
|
||||
// Prevent possible exploits with double summoning
|
||||
if (m_creature->GetMap()->GetCreature(m_ragnarosGuid))
|
||||
return;
|
||||
|
||||
DoScriptText(SAY_SUMMON_0, m_creature, pPlayer);
|
||||
|
||||
m_uiSpeechTimer = 5000;
|
||||
m_uiSpeech = 10;
|
||||
}
|
||||
|
||||
void JustRespawned() override
|
||||
{
|
||||
// Encounter finished, need special treatment
|
||||
if (m_bHasEncounterFinished)
|
||||
{
|
||||
// This needs to be set to be able to resummon Ragnaros
|
||||
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
|
||||
// Relocate here
|
||||
debug_log("SD2: boss_majordomo_executus: Relocate to Ragnaros' Lair on respawn");
|
||||
m_creature->GetMap()->CreatureRelocation(m_creature, m_aMajordomoLocations[1].m_fX, m_aMajordomoLocations[1].m_fY, m_aMajordomoLocations[1].m_fZ, m_aMajordomoLocations[1].m_fO);
|
||||
m_creature->SetActiveObjectState(false);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_FLAMEWAKER_HEALER || pSummoned->GetEntry() == NPC_FLAMEWAKER_ELITE)
|
||||
{
|
||||
m_luiMajordomoAddsGUIDs.push_back(pSummoned->GetObjectGuid());
|
||||
pSummoned->SetRespawnDelay(2 * HOUR);
|
||||
}
|
||||
else if (pSummoned->GetEntry() == NPC_RAGNAROS)
|
||||
{
|
||||
m_ragnarosGuid = pSummoned->GetObjectGuid();
|
||||
pSummoned->CastSpell(pSummoned, SPELL_RAGNA_EMERGE, false);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller) override
|
||||
{
|
||||
if (pKiller->GetTypeId() == TYPEID_UNIT && pKiller->GetEntry() == NPC_RAGNAROS)
|
||||
DoScriptText(SAY_ARRIVAL4_MAJ, m_creature);
|
||||
}
|
||||
|
||||
void CorpseRemoved(uint32& uiRespawnDelay) override
|
||||
{
|
||||
uiRespawnDelay = urand(2 * HOUR, 3 * HOUR);
|
||||
|
||||
if (m_bHasEncounterFinished)
|
||||
{
|
||||
// Needed for proper respawn handling
|
||||
debug_log("SD2: boss_majordomo_executus: Set active");
|
||||
m_creature->SetActiveObjectState(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureJustDied(Creature* pSummoned) override
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_FLAMEWAKER_HEALER || pSummoned->GetEntry() == NPC_FLAMEWAKER_ELITE)
|
||||
{
|
||||
m_uiAddsKilled += 1;
|
||||
|
||||
// Yell if only one Add alive
|
||||
if (m_uiAddsKilled == m_luiMajordomoAddsGUIDs.size() - 1)
|
||||
DoScriptText(SAY_LAST_ADD, m_creature);
|
||||
|
||||
// All adds are killed, retreat
|
||||
else if (m_uiAddsKilled == m_luiMajordomoAddsGUIDs.size())
|
||||
{
|
||||
m_bHasEncounterFinished = true;
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unsummon Majordomo adds
|
||||
void UnsummonMajordomoAdds()
|
||||
{
|
||||
for (GuidList::const_iterator itr = m_luiMajordomoAddsGUIDs.begin(); itr != m_luiMajordomoAddsGUIDs.end(); ++itr)
|
||||
{
|
||||
if (Creature* pAdd = m_creature->GetMap()->GetCreature(*itr))
|
||||
if (pAdd->IsTemporarySummon())
|
||||
((TemporarySummon*)pAdd)->UnSummon();
|
||||
}
|
||||
|
||||
m_luiMajordomoAddsGUIDs.clear();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*pDealer*/, uint32& uiDamage) override
|
||||
{
|
||||
if (uiDamage > m_creature->GetHealth())
|
||||
{
|
||||
uiDamage = 0;
|
||||
DoCastSpellIfCan(m_creature, SPELL_AEGIS, CAST_TRIGGERED);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Handling of his combat-end speech and Ragnaros summoning
|
||||
if (m_uiSpeech)
|
||||
{
|
||||
if (m_uiSpeechTimer < uiDiff)
|
||||
{
|
||||
switch (m_uiSpeech)
|
||||
{
|
||||
// Majordomo retreat event
|
||||
case 1:
|
||||
DoScriptText(SAY_DEFEAT_1, m_creature);
|
||||
m_uiSpeechTimer = 7500;
|
||||
++m_uiSpeech;
|
||||
break;
|
||||
case 2:
|
||||
DoScriptText(SAY_DEFEAT_2, m_creature);
|
||||
m_uiSpeechTimer = 8000;
|
||||
++m_uiSpeech;
|
||||
break;
|
||||
case 3:
|
||||
DoScriptText(SAY_DEFEAT_3, m_creature);
|
||||
m_uiSpeechTimer = 21500;
|
||||
++m_uiSpeech;
|
||||
break;
|
||||
case 4:
|
||||
DoCastSpellIfCan(m_creature, SPELL_TELEPORT_SELF);
|
||||
// TODO - when should they be unsummoned?
|
||||
// TODO - also unclear how this should be handled, as of range issues
|
||||
m_uiSpeechTimer = 900;
|
||||
++m_uiSpeech;
|
||||
break;
|
||||
case 5:
|
||||
// Majordomo is away now, remove his adds
|
||||
UnsummonMajordomoAdds();
|
||||
m_uiSpeech = 0;
|
||||
break;
|
||||
|
||||
// Ragnaros Summon Event
|
||||
case 10:
|
||||
DoScriptText(SAY_SUMMON_1, m_creature);
|
||||
++m_uiSpeech;
|
||||
m_uiSpeechTimer = 1000;
|
||||
break;
|
||||
case 11:
|
||||
DoCastSpellIfCan(m_creature, SPELL_SUMMON_RAGNAROS);
|
||||
// TODO - Move along, this expects to be handled with mmaps
|
||||
m_creature->GetMotionMaster()->MovePoint(1, 831.079590f, -816.023193f, -229.023270f);
|
||||
++m_uiSpeech;
|
||||
m_uiSpeechTimer = 7000;
|
||||
break;
|
||||
case 12:
|
||||
// Reset orientation
|
||||
if (GameObject* pLavaSteam = m_pInstance->GetSingleGameObjectFromStorage(GO_LAVA_STEAM))
|
||||
m_creature->SetFacingToObject(pLavaSteam);
|
||||
m_uiSpeechTimer = 4500;
|
||||
++m_uiSpeech;
|
||||
break;
|
||||
case 13:
|
||||
DoScriptText(SAY_SUMMON_MAJ, m_creature);
|
||||
++m_uiSpeech;
|
||||
m_uiSpeechTimer = 8000;
|
||||
break;
|
||||
case 14:
|
||||
// Summon Ragnaros
|
||||
if (m_pInstance)
|
||||
if (GameObject* pGo = m_pInstance->GetSingleGameObjectFromStorage(GO_LAVA_STEAM))
|
||||
m_creature->SummonCreature(NPC_RAGNAROS, pGo->GetPositionX(), pGo->GetPositionY(), pGo->GetPositionZ(), fmod(m_creature->GetOrientation() + M_PI, 2 * M_PI), TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 2 * HOUR * IN_MILLISECONDS);
|
||||
++m_uiSpeech;
|
||||
m_uiSpeechTimer = 8700;
|
||||
break;
|
||||
case 15:
|
||||
if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_ragnarosGuid))
|
||||
DoScriptText(SAY_ARRIVAL1_RAG, pRagnaros);
|
||||
++m_uiSpeech;
|
||||
m_uiSpeechTimer = 11700;
|
||||
break;
|
||||
case 16:
|
||||
DoScriptText(SAY_ARRIVAL2_MAJ, m_creature);
|
||||
++m_uiSpeech;
|
||||
m_uiSpeechTimer = 8700;
|
||||
break;
|
||||
case 17:
|
||||
if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_ragnarosGuid))
|
||||
DoScriptText(SAY_ARRIVAL3_RAG, pRagnaros);
|
||||
++m_uiSpeech;
|
||||
m_uiSpeechTimer = 16500;
|
||||
break;
|
||||
case 18:
|
||||
if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_ragnarosGuid))
|
||||
pRagnaros->CastSpell(m_creature, SPELL_ELEMENTAL_FIRE, false);
|
||||
// Rest of summoning speech is handled by Ragnaros, as Majordomo will be dead
|
||||
m_uiSpeech = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiSpeechTimer -= uiDiff;
|
||||
}
|
||||
|
||||
// When encounter finished, no need to do anything anymore (important for moving home after victory)
|
||||
if (m_bHasEncounterFinished)
|
||||
return;
|
||||
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Cast Ageis to heal self
|
||||
if (m_uiAegisTimer <= uiDiff)
|
||||
m_uiAegisTimer = 0;
|
||||
else
|
||||
m_uiAegisTimer -= uiDiff;
|
||||
|
||||
if (m_creature->GetHealthPercent() < 90.0f && !m_uiAegisTimer)
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_AEGIS);
|
||||
m_uiAegisTimer = 10000;
|
||||
}
|
||||
|
||||
// Magic Reflection Timer
|
||||
if (m_uiMagicReflectionTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_MAGIC_REFLECTION) == CAST_OK)
|
||||
m_uiMagicReflectionTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiMagicReflectionTimer -= uiDiff;
|
||||
|
||||
// Damage Reflection Timer
|
||||
if (m_uiDamageReflectionTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_DAMAGE_REFLECTION) == CAST_OK)
|
||||
m_uiDamageReflectionTimer = 30000;
|
||||
}
|
||||
else
|
||||
m_uiDamageReflectionTimer -= uiDiff;
|
||||
|
||||
// Teleports the target to the heated rock in the center of the area
|
||||
if (m_uiTeleportTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_TELEPORT) == CAST_OK)
|
||||
m_uiTeleportTimer = 20000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiTeleportTimer -= uiDiff;
|
||||
|
||||
// Blastwave Timer
|
||||
if (m_uiBlastwaveTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_BLASTWAVE) == CAST_OK)
|
||||
m_uiBlastwaveTimer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiBlastwaveTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_majordomo(Creature* pCreature)
|
||||
{
|
||||
return new boss_majordomoAI(pCreature);
|
||||
}
|
||||
|
||||
bool GossipHello_boss_majordomo(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (instance_molten_core* pInstance = (instance_molten_core*)pCreature->GetInstanceData())
|
||||
{
|
||||
if (pInstance->GetData(TYPE_RAGNAROS) == NOT_STARTED || pInstance->GetData(TYPE_RAGNAROS) == FAIL)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SUMMON_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
pPlayer->SEND_GOSSIP_MENU(TEXT_ID_SUMMON_1, pCreature->GetObjectGuid());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GossipSelect_boss_majordomo(Player* pPlayer, Creature* pCreature, uint32 /*sender*/, uint32 uiAction)
|
||||
{
|
||||
switch (uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SUMMON_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
pPlayer->SEND_GOSSIP_MENU(TEXT_ID_SUMMON_2, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SUMMON_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
pPlayer->SEND_GOSSIP_MENU(TEXT_ID_SUMMON_3, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
if (boss_majordomoAI* pMajoAI = dynamic_cast<boss_majordomoAI*>(pCreature->AI()))
|
||||
pMajoAI->StartSummonEvent(pPlayer);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EffectDummyCreature_spell_boss_majordomo(Unit* /*pCaster*/, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget, ObjectGuid /*originalCasterGuid*/)
|
||||
{
|
||||
if (uiSpellId != SPELL_TELEPORT_SELF || uiEffIndex != EFFECT_INDEX_0)
|
||||
return false;
|
||||
|
||||
pCreatureTarget->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
pCreatureTarget->NearTeleportTo(m_aMajordomoLocations[1].m_fX, m_aMajordomoLocations[1].m_fY, m_aMajordomoLocations[1].m_fZ, m_aMajordomoLocations[1].m_fO, true);
|
||||
// TODO - some visibility update?
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_boss_majordomo()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_majordomo";
|
||||
pNewScript->pEffectDummyNPC = &EffectDummyCreature_spell_boss_majordomo;
|
||||
pNewScript->pGossipHello = &GossipHello_boss_majordomo;
|
||||
pNewScript->pGossipSelect = &GossipSelect_boss_majordomo;
|
||||
pNewScript->GetAI = &GetAI_boss_majordomo;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,343 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Ragnaros
|
||||
SD%Complete: 70
|
||||
SDComment: Melee/ Range Combat behavior is not correct(any enemy in melee range, not only getVictim), Some abilities are missing
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
/* There have been quite some bugs about his spells, keep this as reference untill all finished
|
||||
* Missing features (based on wowwiki)
|
||||
* Lava Burst - this spell is handled by Go 178088 which is summoned by spells 21886, 21900 - 21907
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_ARRIVAL5_RAG = -1409012,
|
||||
SAY_REINFORCEMENTS_1 = -1409013,
|
||||
SAY_REINFORCEMENTS_2 = -1409014,
|
||||
SAY_HAMMER = -1409015,
|
||||
SAY_WRATH = -1409016,
|
||||
SAY_KILL = -1409017,
|
||||
SAY_MAGMABURST = -1409018,
|
||||
|
||||
SPELL_WRATH_OF_RAGNAROS = 20566,
|
||||
SPELL_ELEMENTAL_FIRE = 20564,
|
||||
SPELL_MAGMA_BLAST = 20565, // Ranged attack if nobody is in melee range
|
||||
SPELL_MELT_WEAPON = 21387,
|
||||
SPELL_RAGNA_SUBMERGE = 21107, // Stealth aura
|
||||
SPELL_RAGNA_EMERGE = 20568, // Emerge from lava
|
||||
SPELL_ELEMENTAL_FIRE_KILL = 19773,
|
||||
SPELL_MIGHT_OF_RAGNAROS = 21154,
|
||||
SPELL_INTENSE_HEAT = 21155,
|
||||
|
||||
MAX_ADDS_IN_SUBMERGE = 8,
|
||||
NPC_SON_OF_FLAME = 12143,
|
||||
NPC_FLAME_OF_RAGNAROS = 13148,
|
||||
};
|
||||
|
||||
struct boss_ragnarosAI : public Scripted_NoMovementAI
|
||||
{
|
||||
boss_ragnarosAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
|
||||
{
|
||||
m_pInstance = (instance_molten_core*)pCreature->GetInstanceData();
|
||||
m_uiEnterCombatTimer = 0;
|
||||
m_bHasAggroYelled = false;
|
||||
Reset();
|
||||
}
|
||||
|
||||
instance_molten_core* m_pInstance;
|
||||
|
||||
uint32 m_uiEnterCombatTimer;
|
||||
uint32 m_uiWrathOfRagnarosTimer;
|
||||
uint32 m_uiHammerTimer;
|
||||
uint32 m_uiMagmaBlastTimer;
|
||||
uint32 m_uiElementalFireTimer;
|
||||
uint32 m_uiSubmergeTimer;
|
||||
uint32 m_uiAttackTimer;
|
||||
uint32 m_uiAddCount;
|
||||
|
||||
bool m_bHasAggroYelled;
|
||||
bool m_bHasYelledMagmaBurst;
|
||||
bool m_bHasSubmergedOnce;
|
||||
bool m_bIsSubmerged;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiWrathOfRagnarosTimer = 30000; // TODO Research more, according to wowwiki 25s, but timers up to 34s confirmed
|
||||
m_uiHammerTimer = 11000; // TODO wowwiki states 20-30s timer, but ~11s confirmed
|
||||
m_uiMagmaBlastTimer = 2000;
|
||||
m_uiElementalFireTimer = 3000;
|
||||
m_uiSubmergeTimer = 3 * MINUTE * IN_MILLISECONDS;
|
||||
m_uiAttackTimer = 90 * IN_MILLISECONDS;
|
||||
m_uiAddCount = 0;
|
||||
|
||||
m_bHasYelledMagmaBurst = false;
|
||||
m_bHasSubmergedOnce = false;
|
||||
m_bIsSubmerged = false;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim) override
|
||||
{
|
||||
if (pVictim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (urand(0, 3))
|
||||
return;
|
||||
|
||||
DoScriptText(SAY_KILL, m_creature);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_RAGNAROS, DONE);
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho) override
|
||||
{
|
||||
if (pWho->GetTypeId() == TYPEID_UNIT && pWho->GetEntry() == NPC_MAJORDOMO)
|
||||
return;
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_MELT_WEAPON);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_RAGNAROS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void EnterEvadeMode() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_RAGNAROS, FAIL);
|
||||
|
||||
// Reset flag if had been submerged
|
||||
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
|
||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void SummonedCreatureJustDied(Creature* pSummmoned) override
|
||||
{
|
||||
// If all Sons of Flame are dead, trigger emerge
|
||||
if (pSummmoned->GetEntry() == NPC_SON_OF_FLAME)
|
||||
{
|
||||
m_uiAddCount--;
|
||||
|
||||
// If last add killed then emerge soonish
|
||||
if (m_uiAddCount == 0)
|
||||
m_uiAttackTimer = std::min(m_uiAttackTimer, (uint32)1000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_SON_OF_FLAME)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
pSummoned->AI()->AttackStart(pTarget);
|
||||
|
||||
++m_uiAddCount;
|
||||
}
|
||||
else if (pSummoned->GetEntry() == NPC_FLAME_OF_RAGNAROS)
|
||||
pSummoned->CastSpell(pSummoned, SPELL_INTENSE_HEAT, true, NULL, NULL, m_creature->GetObjectGuid());
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* pTarget, const SpellEntry* pSpell) override
|
||||
{
|
||||
// As Majordomo is now killed, the last timer (until attacking) must be handled with ragnaros script
|
||||
if (pSpell->Id == SPELL_ELEMENTAL_FIRE_KILL && pTarget->GetTypeId() == TYPEID_UNIT && pTarget->GetEntry() == NPC_MAJORDOMO)
|
||||
m_uiEnterCombatTimer = 10000;
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (m_uiEnterCombatTimer)
|
||||
{
|
||||
if (m_uiEnterCombatTimer <= uiDiff)
|
||||
{
|
||||
if (!m_bHasAggroYelled)
|
||||
{
|
||||
m_uiEnterCombatTimer = 3000;
|
||||
m_bHasAggroYelled = true;
|
||||
DoScriptText(SAY_ARRIVAL5_RAG, m_creature);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiEnterCombatTimer = 0;
|
||||
// If we don't remove this passive flag, he will be unattackable after evading, this way he will enter combat
|
||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
|
||||
if (m_pInstance)
|
||||
{
|
||||
if (Player* pPlayer = m_pInstance->GetPlayerInMap(true, false))
|
||||
{
|
||||
m_creature->AI()->AttackStart(pPlayer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiEnterCombatTimer -= uiDiff;
|
||||
}
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_bIsSubmerged)
|
||||
{
|
||||
// Timer to check when Ragnaros should emerge (is set to soonish, when last add is killed)
|
||||
if (m_uiAttackTimer < uiDiff)
|
||||
{
|
||||
// Become emerged again
|
||||
DoCastSpellIfCan(m_creature, SPELL_RAGNA_EMERGE);
|
||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
m_uiSubmergeTimer = 3 * MINUTE * IN_MILLISECONDS;
|
||||
m_uiMagmaBlastTimer = 3000; // Delay the magma blast after emerge
|
||||
m_bIsSubmerged = false;
|
||||
}
|
||||
else
|
||||
m_uiAttackTimer -= uiDiff;
|
||||
|
||||
// Do nothing while submerged
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrath Of Ragnaros Timer
|
||||
if (m_uiWrathOfRagnarosTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_WRATH_OF_RAGNAROS) == CAST_OK)
|
||||
{
|
||||
DoScriptText(SAY_WRATH, m_creature);
|
||||
m_uiWrathOfRagnarosTimer = 30000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiWrathOfRagnarosTimer -= uiDiff;
|
||||
|
||||
// Elemental Fire Timer
|
||||
if (m_uiElementalFireTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ELEMENTAL_FIRE) == CAST_OK)
|
||||
m_uiElementalFireTimer = urand(10000, 14000);
|
||||
}
|
||||
else
|
||||
m_uiElementalFireTimer -= uiDiff;
|
||||
|
||||
// Hammer of Ragnaros
|
||||
if (m_uiHammerTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_MIGHT_OF_RAGNAROS, SELECT_FLAG_POWER_MANA))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_MIGHT_OF_RAGNAROS) == CAST_OK)
|
||||
{
|
||||
DoScriptText(SAY_HAMMER, m_creature);
|
||||
m_uiHammerTimer = 11000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiHammerTimer = 11000;
|
||||
}
|
||||
else
|
||||
m_uiHammerTimer -= uiDiff;
|
||||
|
||||
// Submerge Timer
|
||||
if (m_uiSubmergeTimer < uiDiff)
|
||||
{
|
||||
// Submerge and attack again after 90 secs
|
||||
DoCastSpellIfCan(m_creature, SPELL_RAGNA_SUBMERGE, CAST_INTERRUPT_PREVIOUS);
|
||||
m_creature->HandleEmote(EMOTE_ONESHOT_SUBMERGE);
|
||||
m_bIsSubmerged = true;
|
||||
m_uiAttackTimer = 90 * IN_MILLISECONDS;
|
||||
|
||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
// Say dependend if first time or not
|
||||
DoScriptText(!m_bHasSubmergedOnce ? SAY_REINFORCEMENTS_1 : SAY_REINFORCEMENTS_2, m_creature);
|
||||
m_bHasSubmergedOnce = true;
|
||||
|
||||
// Summon 8 elementals at random points around the boss
|
||||
float fX, fY, fZ;
|
||||
for (uint8 i = 0; i < MAX_ADDS_IN_SUBMERGE; ++i)
|
||||
{
|
||||
m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 30.0f, fX, fY, fZ);
|
||||
m_creature->SummonCreature(NPC_SON_OF_FLAME, fX, fY, fZ, 0.0f, TEMPSUMMON_TIMED_OOC_DESPAWN, 1000);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_uiSubmergeTimer -= uiDiff;
|
||||
|
||||
// TODO this actually should select _any_ enemy in melee range, not only the tank
|
||||
// Range check for melee target, if nobody is found in range, then cast magma blast on random
|
||||
// If we are within range melee the target
|
||||
if (m_creature->IsNonMeleeSpellCasted(false) || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim()))
|
||||
{
|
||||
// Make sure our attack is ready
|
||||
if (m_creature->isAttackReady())
|
||||
{
|
||||
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||
m_creature->resetAttackTimer();
|
||||
m_bHasYelledMagmaBurst = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Magma Burst Timer
|
||||
if (m_uiMagmaBlastTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_MAGMA_BLAST) == CAST_OK)
|
||||
{
|
||||
if (!m_bHasYelledMagmaBurst)
|
||||
{
|
||||
DoScriptText(SAY_MAGMABURST, m_creature);
|
||||
m_bHasYelledMagmaBurst = true;
|
||||
}
|
||||
m_uiMagmaBlastTimer = 1000; // Spamm this!
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiMagmaBlastTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_ragnaros(Creature* pCreature)
|
||||
{
|
||||
return new boss_ragnarosAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_ragnaros()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_ragnaros";
|
||||
pNewScript->GetAI = &GetAI_boss_ragnaros;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Shazzrah
|
||||
SD%Complete: 75
|
||||
SDComment: Teleport NYI (need core support, remove hack here when implemented)
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_ARCANE_EXPLOSION = 19712,
|
||||
SPELL_SHAZZRAH_CURSE = 19713,
|
||||
SPELL_MAGIC_GROUNDING = 19714,
|
||||
SPELL_COUNTERSPELL = 19715,
|
||||
SPELL_GATE_OF_SHAZZRAH = 23138 // effect spell: 23139
|
||||
};
|
||||
|
||||
struct boss_shazzrahAI : public ScriptedAI
|
||||
{
|
||||
boss_shazzrahAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiArcaneExplosionTimer;
|
||||
uint32 m_uiShazzrahCurseTimer;
|
||||
uint32 m_uiMagicGroundingTimer;
|
||||
uint32 m_uiCounterspellTimer;
|
||||
uint32 m_uiBlinkTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiArcaneExplosionTimer = 6000;
|
||||
m_uiShazzrahCurseTimer = 10000;
|
||||
m_uiMagicGroundingTimer = 24000;
|
||||
m_uiCounterspellTimer = 15000;
|
||||
m_uiBlinkTimer = 30000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_SHAZZRAH, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_SHAZZRAH, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_SHAZZRAH, NOT_STARTED);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Arcane Explosion Timer
|
||||
if (m_uiArcaneExplosionTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_ARCANE_EXPLOSION) == CAST_OK)
|
||||
m_uiArcaneExplosionTimer = urand(5000, 9000);
|
||||
}
|
||||
else
|
||||
m_uiArcaneExplosionTimer -= uiDiff;
|
||||
|
||||
// Shazzrah Curse Timer
|
||||
if (m_uiShazzrahCurseTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SHAZZRAH_CURSE) == CAST_OK)
|
||||
m_uiShazzrahCurseTimer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiShazzrahCurseTimer -= uiDiff;
|
||||
|
||||
// Magic Grounding Timer
|
||||
if (m_uiMagicGroundingTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_MAGIC_GROUNDING) == CAST_OK)
|
||||
m_uiMagicGroundingTimer = 35000;
|
||||
}
|
||||
else
|
||||
m_uiMagicGroundingTimer -= uiDiff;
|
||||
|
||||
// Counterspell Timer
|
||||
if (m_uiCounterspellTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_COUNTERSPELL) == CAST_OK)
|
||||
m_uiCounterspellTimer = urand(16000, 20000);
|
||||
}
|
||||
else
|
||||
m_uiCounterspellTimer -= uiDiff;
|
||||
|
||||
// Blink Timer
|
||||
if (m_uiBlinkTimer < uiDiff)
|
||||
{
|
||||
// Teleporting him to a random gamer and casting Arcane Explosion after that.
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_GATE_OF_SHAZZRAH) == CAST_OK)
|
||||
{
|
||||
// manual, until added effect of dummy properly -- TODO REMOVE HACK
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
m_creature->NearTeleportTo(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), m_creature->GetOrientation());
|
||||
DoResetThreat();
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_ARCANE_EXPLOSION, CAST_TRIGGERED);
|
||||
|
||||
m_uiBlinkTimer = 45000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiBlinkTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_shazzrah(Creature* pCreature)
|
||||
{
|
||||
return new boss_shazzrahAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_shazzrah()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_shazzrah";
|
||||
pNewScript->GetAI = &GetAI_boss_shazzrah;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Sulfuron_Harbringer
|
||||
SD%Complete: 80
|
||||
SDComment: Spells Dark strike and Flamespear need confirmation
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SPELL_DARK_STRIKE = 19777, // Wowhead Linked to add - need confirmation!
|
||||
SPELL_DEMORALIZING_SHOUT = 19778,
|
||||
SPELL_INSPIRE = 19779,
|
||||
SPELL_HAND_OF_RAGNAROS = 19780,
|
||||
SPELL_FLAMESPEAR = 19781,
|
||||
|
||||
// Adds Spells
|
||||
SPELL_HEAL = 19775,
|
||||
SPELL_SHADOWWORD_PAIN = 19776,
|
||||
SPELL_IMMOLATE = 20294
|
||||
};
|
||||
|
||||
struct boss_sulfuronAI : public ScriptedAI
|
||||
{
|
||||
boss_sulfuronAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiDarkstrikeTimer;
|
||||
uint32 m_uiDemoralizingShoutTimer;
|
||||
uint32 m_uiInspireTimer;
|
||||
uint32 m_uiKnockdownTimer;
|
||||
uint32 m_uiFlamespearTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiDarkstrikeTimer = 10000;
|
||||
m_uiDemoralizingShoutTimer = 15000;
|
||||
m_uiInspireTimer = 3000;
|
||||
m_uiKnockdownTimer = 6000;
|
||||
m_uiFlamespearTimer = 2000;
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_SULFURON, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_SULFURON, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_SULFURON, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Demoralizing Shout Timer
|
||||
if (m_uiDemoralizingShoutTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_DEMORALIZING_SHOUT) == CAST_OK)
|
||||
m_uiDemoralizingShoutTimer = urand(15000, 20000);
|
||||
}
|
||||
else
|
||||
m_uiDemoralizingShoutTimer -= uiDiff;
|
||||
|
||||
// Inspire Timer
|
||||
if (m_uiInspireTimer < uiDiff)
|
||||
{
|
||||
Creature* pTarget = NULL;
|
||||
std::list<Creature*> pList = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE);
|
||||
if (!pList.empty())
|
||||
{
|
||||
std::list<Creature*>::iterator i = pList.begin();
|
||||
advance(i, (rand() % pList.size()));
|
||||
pTarget = (*i);
|
||||
}
|
||||
|
||||
if (!pTarget)
|
||||
pTarget = m_creature;
|
||||
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_INSPIRE) == CAST_OK)
|
||||
m_uiInspireTimer = 10000;
|
||||
}
|
||||
else
|
||||
m_uiInspireTimer -= uiDiff;
|
||||
|
||||
// Hand of Ragnaros Timer
|
||||
if (m_uiKnockdownTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_HAND_OF_RAGNAROS) == CAST_OK)
|
||||
m_uiKnockdownTimer = urand(12000, 15000);
|
||||
}
|
||||
else
|
||||
m_uiKnockdownTimer -= uiDiff;
|
||||
|
||||
// Flamespear Timer
|
||||
if (m_uiFlamespearTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_FLAMESPEAR) == CAST_OK)
|
||||
m_uiFlamespearTimer = urand(12000, 16000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiFlamespearTimer -= uiDiff;
|
||||
|
||||
// Dark Strike Timer
|
||||
if (m_uiDarkstrikeTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DARK_STRIKE) == CAST_OK)
|
||||
m_uiDarkstrikeTimer = urand(15000, 18000);
|
||||
}
|
||||
else
|
||||
m_uiDarkstrikeTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
struct mob_flamewaker_priestAI : public ScriptedAI
|
||||
{
|
||||
mob_flamewaker_priestAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
uint32 m_uiHealTimer;
|
||||
uint32 m_uiShadowWordPainTimer;
|
||||
uint32 m_uiImmolateTimer;
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiHealTimer = urand(15000, 30000);
|
||||
m_uiShadowWordPainTimer = 2000;
|
||||
m_uiImmolateTimer = 8000;
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// Casting Heal to Sulfuron or other Guards.
|
||||
if (m_uiHealTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pUnit = DoSelectLowestHpFriendly(60.0f, 1))
|
||||
{
|
||||
if (DoCastSpellIfCan(pUnit, SPELL_HEAL) == CAST_OK)
|
||||
m_uiHealTimer = urand(15000, 20000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiHealTimer -= uiDiff;
|
||||
|
||||
// ShadowWord Pain Timer
|
||||
if (m_uiShadowWordPainTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_SHADOWWORD_PAIN) == CAST_OK)
|
||||
m_uiShadowWordPainTimer = urand(18000, 26000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiShadowWordPainTimer -= uiDiff;
|
||||
|
||||
// Immolate Timer
|
||||
if (m_uiImmolateTimer < uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_IMMOLATE) == CAST_OK)
|
||||
m_uiImmolateTimer = urand(15000, 25000);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiImmolateTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_sulfuron(Creature* pCreature)
|
||||
{
|
||||
return new boss_sulfuronAI(pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_flamewaker_priest(Creature* pCreature)
|
||||
{
|
||||
return new mob_flamewaker_priestAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_sulfuron()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_sulfuron";
|
||||
pNewScript->GetAI = &GetAI_boss_sulfuron;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "mob_flamewaker_priest";
|
||||
pNewScript->GetAI = &GetAI_mob_flamewaker_priest;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Instance_Molten_Core
|
||||
SD%Complete: 25
|
||||
SDComment: Majordomos and Ragnaros Event missing
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "molten_core.h"
|
||||
|
||||
static sSpawnLocation m_aBosspawnLocs[MAX_MAJORDOMO_ADDS] =
|
||||
{
|
||||
{NPC_FLAMEWAKER_ELITE, 737.945f, -1156.48f, -118.945f, 4.46804f},
|
||||
{NPC_FLAMEWAKER_ELITE, 752.520f, -1191.02f, -118.218f, 2.49582f},
|
||||
{NPC_FLAMEWAKER_ELITE, 752.953f, -1163.94f, -118.869f, 3.70010f},
|
||||
{NPC_FLAMEWAKER_ELITE, 738.814f, -1197.40f, -118.018f, 1.83260f},
|
||||
{NPC_FLAMEWAKER_HEALER, 746.939f, -1194.87f, -118.016f, 2.21657f},
|
||||
{NPC_FLAMEWAKER_HEALER, 747.132f, -1158.87f, -118.897f, 4.03171f},
|
||||
{NPC_FLAMEWAKER_HEALER, 757.116f, -1170.12f, -118.793f, 3.40339f},
|
||||
{NPC_FLAMEWAKER_HEALER, 755.910f, -1184.46f, -118.449f, 2.80998f}
|
||||
};
|
||||
|
||||
instance_molten_core::instance_molten_core(Map* pMap) : ScriptedInstance(pMap)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void instance_molten_core::Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
}
|
||||
|
||||
bool instance_molten_core::IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void instance_molten_core::OnPlayerEnter(Player* /*pPlayer*/)
|
||||
{
|
||||
// Summon Majordomo if can
|
||||
DoSpawnMajordomoIfCan(true);
|
||||
}
|
||||
|
||||
void instance_molten_core::OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
// Bosses
|
||||
case NPC_GARR:
|
||||
case NPC_SULFURON:
|
||||
case NPC_MAJORDOMO:
|
||||
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_molten_core::OnObjectCreate(GameObject* pGo)
|
||||
{
|
||||
switch (pGo->GetEntry())
|
||||
{
|
||||
// Runes
|
||||
case GO_RUNE_KRESS:
|
||||
case GO_RUNE_MOHN:
|
||||
case GO_RUNE_BLAZ:
|
||||
case GO_RUNE_MAZJ:
|
||||
case GO_RUNE_ZETH:
|
||||
case GO_RUNE_THERI:
|
||||
case GO_RUNE_KORO:
|
||||
|
||||
// Majordomo event chest
|
||||
case GO_CACHE_OF_THE_FIRE_LORD:
|
||||
// Ragnaros GOs
|
||||
case GO_LAVA_STEAM:
|
||||
case GO_LAVA_SPLASH:
|
||||
m_mGoEntryGuidStore[pGo->GetEntry()] = pGo->GetObjectGuid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_molten_core::SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case TYPE_LUCIFRON:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
case TYPE_MAGMADAR:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_RUNE_KRESS);
|
||||
break;
|
||||
case TYPE_GEHENNAS:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_RUNE_MOHN);
|
||||
break;
|
||||
case TYPE_GARR:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_RUNE_BLAZ);
|
||||
break;
|
||||
case TYPE_SHAZZRAH:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_RUNE_MAZJ);
|
||||
break;
|
||||
case TYPE_GEDDON:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_RUNE_ZETH);
|
||||
break;
|
||||
case TYPE_GOLEMAGG:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_RUNE_THERI);
|
||||
break;
|
||||
case TYPE_SULFURON:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_RUNE_KORO);
|
||||
break;
|
||||
case TYPE_MAJORDOMO:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
if (uiData == DONE)
|
||||
DoRespawnGameObject(GO_CACHE_OF_THE_FIRE_LORD, HOUR);
|
||||
break;
|
||||
case TYPE_RAGNAROS:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if Majordomo can be summoned
|
||||
if (uiData == DONE)
|
||||
DoSpawnMajordomoIfCan(false);
|
||||
|
||||
if (uiData == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
|
||||
<< m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
|
||||
<< m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8] << " "
|
||||
<< m_auiEncounter[9];
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 instance_molten_core::GetData(uint32 uiType) const
|
||||
{
|
||||
if (uiType < MAX_ENCOUNTER)
|
||||
return m_auiEncounter[uiType];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle Majordomo summon here
|
||||
void instance_molten_core::DoSpawnMajordomoIfCan(bool bByPlayerEnter)
|
||||
{
|
||||
// If both Majordomo and Ragnaros events are finished, return
|
||||
if (m_auiEncounter[TYPE_MAJORDOMO] == DONE && m_auiEncounter[TYPE_RAGNAROS] == DONE)
|
||||
return;
|
||||
|
||||
// If already spawned return
|
||||
if (GetSingleCreatureFromStorage(NPC_MAJORDOMO, true))
|
||||
return;
|
||||
|
||||
// Check if all rune bosses are done
|
||||
for (uint8 i = TYPE_MAGMADAR; i < TYPE_MAJORDOMO; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] != DONE)
|
||||
return;
|
||||
}
|
||||
|
||||
Player* pPlayer = GetPlayerInMap();
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
// Summon Majordomo
|
||||
// If Majordomo encounter isn't done, summon at encounter place, else near Ragnaros
|
||||
uint8 uiSummonPos = m_auiEncounter[TYPE_MAJORDOMO] == DONE ? 1 : 0;
|
||||
if (Creature* pMajordomo = pPlayer->SummonCreature(m_aMajordomoLocations[uiSummonPos].m_uiEntry, m_aMajordomoLocations[uiSummonPos].m_fX, m_aMajordomoLocations[uiSummonPos].m_fY, m_aMajordomoLocations[uiSummonPos].m_fZ, m_aMajordomoLocations[uiSummonPos].m_fO, TEMPSUMMON_MANUAL_DESPAWN, 2 * HOUR * IN_MILLISECONDS))
|
||||
{
|
||||
if (uiSummonPos) // Majordomo encounter already done, set faction
|
||||
{
|
||||
pMajordomo->SetFactionTemporary(FACTION_MAJORDOMO_FRIENDLY, TEMPFACTION_RESTORE_RESPAWN);
|
||||
pMajordomo->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
pMajordomo->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
else // Else yell and summon adds
|
||||
{
|
||||
if (!bByPlayerEnter)
|
||||
DoScriptText(SAY_MAJORDOMO_SPAWN, pMajordomo);
|
||||
|
||||
for (uint8 i = 0; i < MAX_MAJORDOMO_ADDS; ++i)
|
||||
pMajordomo->SummonCreature(m_aBosspawnLocs[i].m_uiEntry, m_aBosspawnLocs[i].m_fX, m_aBosspawnLocs[i].m_fY, m_aBosspawnLocs[i].m_fZ, m_aBosspawnLocs[i].m_fO, TEMPSUMMON_MANUAL_DESPAWN, DAY * IN_MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void instance_molten_core::Load(const char* chrIn)
|
||||
{
|
||||
if (!chrIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(chrIn);
|
||||
|
||||
std::istringstream loadStream(chrIn);
|
||||
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
|
||||
>> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7]
|
||||
>> m_auiEncounter[8] >> m_auiEncounter[9];
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
InstanceData* GetInstance_instance_molten_core(Map* pMap)
|
||||
{
|
||||
return new instance_molten_core(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_molten_core()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "instance_molten_core";
|
||||
pNewScript->GetInstanceData = &GetInstance_instance_molten_core;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Molten_Core
|
||||
SD%Complete:
|
||||
SDComment:
|
||||
SDCategory: Molten Core
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
EndContentData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_molten_core()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
||||
#ifndef DEF_MOLTEN_CORE_H
|
||||
#define DEF_MOLTEN_CORE_H
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_ENCOUNTER = 10,
|
||||
|
||||
TYPE_LUCIFRON = 0,
|
||||
TYPE_MAGMADAR = 1,
|
||||
TYPE_GEHENNAS = 2,
|
||||
TYPE_GARR = 3,
|
||||
TYPE_SHAZZRAH = 4,
|
||||
TYPE_GEDDON = 5,
|
||||
TYPE_GOLEMAGG = 6,
|
||||
TYPE_SULFURON = 7,
|
||||
TYPE_MAJORDOMO = 8,
|
||||
TYPE_RAGNAROS = 9,
|
||||
|
||||
NPC_LUCIFRON = 12118,
|
||||
NPC_MAGMADAR = 11982,
|
||||
NPC_GEHENNAS = 12259,
|
||||
NPC_GARR = 12057,
|
||||
NPC_SHAZZRAH = 12264,
|
||||
NPC_GEDDON = 12056,
|
||||
NPC_GOLEMAGG = 11988,
|
||||
NPC_SULFURON = 12098,
|
||||
NPC_MAJORDOMO = 12018,
|
||||
NPC_RAGNAROS = 11502,
|
||||
|
||||
// Adds
|
||||
// Used for respawn in case of wipe
|
||||
NPC_FLAMEWAKER_PROTECTOR = 12119, // Lucifron
|
||||
NPC_FLAMEWAKER = 11661, // Gehennas
|
||||
NPC_FIRESWORN = 12099, // Garr
|
||||
NPC_CORE_RAGER = 11672, // Golemagg
|
||||
NPC_FLAMEWAKER_PRIEST = 11662, // Sulfuron
|
||||
NPC_FLAMEWAKER_HEALER = 11663, // Majordomo
|
||||
NPC_FLAMEWAKER_ELITE = 11664, // Majordomo
|
||||
|
||||
GO_LAVA_STEAM = 178107,
|
||||
GO_LAVA_SPLASH = 178108,
|
||||
GO_CACHE_OF_THE_FIRE_LORD = 179703,
|
||||
GO_RUNE_KRESS = 176956, // Magmadar
|
||||
GO_RUNE_MOHN = 176957, // Gehennas
|
||||
GO_RUNE_BLAZ = 176955, // Garr
|
||||
GO_RUNE_MAZJ = 176953, // Shazzah
|
||||
GO_RUNE_ZETH = 176952, // Geddon
|
||||
GO_RUNE_THERI = 176954, // Golemagg
|
||||
GO_RUNE_KORO = 176951, // Sulfuron
|
||||
|
||||
MAX_MAJORDOMO_ADDS = 8,
|
||||
FACTION_MAJORDOMO_FRIENDLY = 1080,
|
||||
SAY_MAJORDOMO_SPAWN = -1409004,
|
||||
};
|
||||
|
||||
struct sSpawnLocation
|
||||
{
|
||||
uint32 m_uiEntry;
|
||||
float m_fX, m_fY, m_fZ, m_fO;
|
||||
};
|
||||
|
||||
static sSpawnLocation m_aMajordomoLocations[2] =
|
||||
{
|
||||
{NPC_MAJORDOMO, 758.089f, -1176.71f, -118.640f, 3.12414f}, // Summon fight position
|
||||
{NPC_MAJORDOMO, 847.103f, -816.153f, -229.775f, 4.344f} // Summon and teleport location (near Ragnaros)
|
||||
};
|
||||
|
||||
class instance_molten_core : public ScriptedInstance
|
||||
{
|
||||
public:
|
||||
instance_molten_core(Map* pMap);
|
||||
~instance_molten_core() {}
|
||||
|
||||
void Initialize() override;
|
||||
bool IsEncounterInProgress() const override;
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature) override;
|
||||
void OnObjectCreate(GameObject* pGo) override;
|
||||
void OnPlayerEnter(Player* pPlayer) override;
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData) override;
|
||||
uint32 GetData(uint32 uiType) const override;
|
||||
|
||||
const char* Save() const override { return m_strInstData.c_str(); }
|
||||
void Load(const char* chrIn) override;
|
||||
|
||||
protected:
|
||||
void DoSpawnMajordomoIfCan(bool bByPlayerEnter);
|
||||
|
||||
std::string m_strInstData;
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
};
|
||||
|
||||
#endif
|
||||
144
src/modules/SD2/scripts/eastern_kingdoms/blasted_lands.cpp
Normal file
144
src/modules/SD2/scripts/eastern_kingdoms/blasted_lands.cpp
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ScriptData
|
||||
* SDName: Blasted_Lands
|
||||
* SD%Complete: 90
|
||||
* SDComment: Quest support: 2784, 2801. Missing some texts for Fallen Hero. Teleporter to Rise of the Defiler missing group support.
|
||||
* SDCategory: Blasted Lands
|
||||
* EndScriptData
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentData
|
||||
* npc_fallen_hero_of_horde
|
||||
* EndContentData
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
/*######
|
||||
## npc_fallen_hero_of_horde
|
||||
######*/
|
||||
|
||||
#define GOSSIP_ITEM_FALLEN "Continue..."
|
||||
|
||||
#define GOSSIP_ITEM_FALLEN1 "What could be worse than death?"
|
||||
#define GOSSIP_ITEM_FALLEN2 "Subordinates?"
|
||||
#define GOSSIP_ITEM_FALLEN3 "What are the stones of binding?"
|
||||
#define GOSSIP_ITEM_FALLEN4 "You can count on me, Hero"
|
||||
#define GOSSIP_ITEM_FALLEN5 "I shall"
|
||||
|
||||
bool GossipHello_npc_fallen_hero_of_horde(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (pCreature->IsQuestGiver())
|
||||
{
|
||||
pPlayer->PrepareQuestMenu(pCreature->GetObjectGuid());
|
||||
}
|
||||
|
||||
if (pPlayer->GetQuestStatus(2784) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Why are you here?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
}
|
||||
|
||||
if (pPlayer->GetQuestStatus(2801) == QUEST_STATUS_INCOMPLETE && pPlayer->GetTeam() == HORDE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Continue story...", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
}
|
||||
|
||||
if (pPlayer->GetQuestStatus(2801) == QUEST_STATUS_INCOMPLETE && pPlayer->GetTeam() == ALLIANCE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Why are you here?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
}
|
||||
|
||||
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetObjectGuid());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GossipSelect_npc_fallen_hero_of_horde(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
|
||||
{
|
||||
switch (uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11);
|
||||
pPlayer->SEND_GOSSIP_MENU(1392, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+11:
|
||||
pPlayer->SEND_GOSSIP_MENU(1411, pCreature->GetObjectGuid());
|
||||
if (pPlayer->GetQuestStatus(2784) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
pPlayer->AreaExploredOrEventHappens(2784);
|
||||
}
|
||||
if (pPlayer->GetTeam() == ALLIANCE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
pPlayer->SEND_GOSSIP_MENU(1411, pCreature->GetObjectGuid());
|
||||
}
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21);
|
||||
pPlayer->SEND_GOSSIP_MENU(1451, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+21:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22);
|
||||
pPlayer->SEND_GOSSIP_MENU(1452, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+22:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23);
|
||||
pPlayer->SEND_GOSSIP_MENU(1453, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+23:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24);
|
||||
pPlayer->SEND_GOSSIP_MENU(1454, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+24:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25);
|
||||
pPlayer->SEND_GOSSIP_MENU(1455, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+25:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FALLEN5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 26);
|
||||
pPlayer->SEND_GOSSIP_MENU(1456, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+26:
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
pPlayer->AreaExploredOrEventHappens(2801);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_blasted_lands()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_fallen_hero_of_horde";
|
||||
pNewScript->pGossipHello = &GossipHello_npc_fallen_hero_of_horde;
|
||||
pNewScript->pGossipSelect = &GossipSelect_npc_fallen_hero_of_horde;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
513
src/modules/SD2/scripts/eastern_kingdoms/burning_steppes.cpp
Normal file
513
src/modules/SD2/scripts/eastern_kingdoms/burning_steppes.cpp
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ScriptData
|
||||
* SDName: Burning_Steppes
|
||||
* SD%Complete: 100
|
||||
* SDComment: Quest support: 4121, 4122, 4224, 4866.
|
||||
* SDCategory: Burning Steppes
|
||||
* EndScriptData
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentData
|
||||
* npc_ragged_john
|
||||
* npc_grark_lorkrub
|
||||
* EndContentData
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "escort_ai.h"
|
||||
|
||||
/*######
|
||||
## npc_ragged_john
|
||||
######*/
|
||||
|
||||
struct npc_ragged_johnAI : public ScriptedAI
|
||||
{
|
||||
npc_ragged_johnAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
|
||||
|
||||
void Reset() override {}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (who->HasAura(16468, EFFECT_INDEX_0))
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(who, 15) && who->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
DoCastSpellIfCan(who, 16472);
|
||||
((Player*)who)->AreaExploredOrEventHappens(4866);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_creature->getVictim() && who->IsTargetableForAttack() && (m_creature->IsHostileTo(who)) && who->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float attackRadius = m_creature->GetAttackDistance(who);
|
||||
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
|
||||
{
|
||||
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_ragged_john(Creature* pCreature)
|
||||
{
|
||||
return new npc_ragged_johnAI(pCreature);
|
||||
}
|
||||
|
||||
bool GossipHello_npc_ragged_john(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (pCreature->IsQuestGiver())
|
||||
{
|
||||
pPlayer->PrepareQuestMenu(pCreature->GetObjectGuid());
|
||||
}
|
||||
|
||||
if (pPlayer->GetQuestStatus(4224) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Official business, John. I need some information about Marshal Windsor. Tell me about he last time you saw him.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
}
|
||||
|
||||
pPlayer->SEND_GOSSIP_MENU(2713, pCreature->GetObjectGuid());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GossipSelect_npc_ragged_john(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
|
||||
{
|
||||
switch (uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "So what did you do?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
pPlayer->SEND_GOSSIP_MENU(2714, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Start making sense, dwarf. I don't want to have anything to do with your cracker, your pappy, or any sort of 'discreditin'.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
pPlayer->SEND_GOSSIP_MENU(2715, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Ironfoe?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
pPlayer->SEND_GOSSIP_MENU(2716, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+3:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Interesting... continue, John.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
|
||||
pPlayer->SEND_GOSSIP_MENU(2717, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+4:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "So that's how Windsor died...", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
|
||||
pPlayer->SEND_GOSSIP_MENU(2718, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+5:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "So how did he die?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
|
||||
pPlayer->SEND_GOSSIP_MENU(2719, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+6:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Ok, so where the hell is he? Wait a minute! Are you drunk?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
|
||||
pPlayer->SEND_GOSSIP_MENU(2720, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+7:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "WHY is he in Blackrock Depths?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8);
|
||||
pPlayer->SEND_GOSSIP_MENU(2721, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+8:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "300? So the Dark Irons killed him and dragged him into the Depths?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
|
||||
pPlayer->SEND_GOSSIP_MENU(2722, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+9:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Ahh... Ironfoe.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
|
||||
pPlayer->SEND_GOSSIP_MENU(2723, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+10:
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Thanks, Ragged John. Your story was very uplifting and informative.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11);
|
||||
pPlayer->SEND_GOSSIP_MENU(2725, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+11:
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
pPlayer->AreaExploredOrEventHappens(4224);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*######
|
||||
## npc_grark_lorkrub
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_START = -1000873,
|
||||
SAY_PAY = -1000874,
|
||||
SAY_FIRST_AMBUSH_START = -1000875,
|
||||
SAY_FIRST_AMBUSH_END = -1000876,
|
||||
SAY_SEC_AMBUSH_START = -1000877,
|
||||
SAY_SEC_AMBUSH_END = -1000878,
|
||||
SAY_THIRD_AMBUSH_START = -1000879,
|
||||
SAY_THIRD_AMBUSH_END = -1000880,
|
||||
EMOTE_LAUGH = -1000881,
|
||||
SAY_LAST_STAND = -1000882,
|
||||
SAY_LEXLORT_1 = -1000883,
|
||||
SAY_LEXLORT_2 = -1000884,
|
||||
EMOTE_RAISE_AXE = -1000885,
|
||||
EMOTE_LOWER_HAND = -1000886,
|
||||
SAY_LEXLORT_3 = -1000887,
|
||||
SAY_LEXLORT_4 = -1000888,
|
||||
|
||||
EMOTE_SUBMIT = -1000889,
|
||||
SAY_AGGRO = -1000890,
|
||||
|
||||
SPELL_CAPTURE_GRARK = 14250,
|
||||
|
||||
NPC_BLACKROCK_AMBUSHER = 9522,
|
||||
NPC_BLACKROCK_RAIDER = 9605,
|
||||
NPC_FLAMESCALE_DRAGONSPAWN = 7042,
|
||||
NPC_SEARSCALE_DRAKE = 7046,
|
||||
|
||||
NPC_GRARK_LORKRUB = 9520,
|
||||
NPC_HIGH_EXECUTIONER_NUZARK = 9538,
|
||||
NPC_SHADOW_OF_LEXLORT = 9539,
|
||||
|
||||
FACTION_FRIENDLY = 35,
|
||||
|
||||
QUEST_ID_PRECARIOUS_PREDICAMENT = 4121
|
||||
};
|
||||
|
||||
static const DialogueEntry aOutroDialogue[] =
|
||||
{
|
||||
{SAY_LAST_STAND, NPC_GRARK_LORKRUB, 5000},
|
||||
{SAY_LEXLORT_1, NPC_SHADOW_OF_LEXLORT, 3000},
|
||||
{SAY_LEXLORT_2, NPC_SHADOW_OF_LEXLORT, 5000},
|
||||
{EMOTE_RAISE_AXE, NPC_HIGH_EXECUTIONER_NUZARK, 4000},
|
||||
{EMOTE_LOWER_HAND, NPC_SHADOW_OF_LEXLORT, 3000},
|
||||
{SAY_LEXLORT_3, NPC_SHADOW_OF_LEXLORT, 3000},
|
||||
{NPC_GRARK_LORKRUB, 0, 5000},
|
||||
{SAY_LEXLORT_4, NPC_SHADOW_OF_LEXLORT, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
struct npc_grark_lorkrubAI : public npc_escortAI, private DialogueHelper
|
||||
{
|
||||
npc_grark_lorkrubAI(Creature* pCreature) : npc_escortAI(pCreature),
|
||||
DialogueHelper(aOutroDialogue)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
ObjectGuid m_nuzarkGuid;
|
||||
ObjectGuid m_lexlortGuid;
|
||||
|
||||
GuidList m_lSearscaleGuidList;
|
||||
|
||||
uint8 m_uiKilledCreatures;
|
||||
bool m_bIsFirstSearScale;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
m_uiKilledCreatures = 0;
|
||||
m_bIsFirstSearScale = true;
|
||||
|
||||
m_lSearscaleGuidList.clear();
|
||||
|
||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Aggro(Unit* /*pWho*/) override
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* pWho) override
|
||||
{
|
||||
// No combat during escort
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
npc_escortAI::MoveInLineOfSight(pWho);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 uiPointId) override
|
||||
{
|
||||
switch (uiPointId)
|
||||
{
|
||||
case 1:
|
||||
DoScriptText(SAY_START, m_creature);
|
||||
break;
|
||||
case 7:
|
||||
DoScriptText(SAY_PAY, m_creature);
|
||||
break;
|
||||
case 12:
|
||||
DoScriptText(SAY_FIRST_AMBUSH_START, m_creature);
|
||||
SetEscortPaused(true);
|
||||
|
||||
m_creature->SummonCreature(NPC_BLACKROCK_AMBUSHER, -7844.3f, -1521.6f, 139.2f, 0.0f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
m_creature->SummonCreature(NPC_BLACKROCK_AMBUSHER, -7860.4f, -1507.8f, 141.0f, 6.0f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
m_creature->SummonCreature(NPC_BLACKROCK_RAIDER, -7845.6f, -1508.1f, 138.8f, 6.1f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
m_creature->SummonCreature(NPC_BLACKROCK_RAIDER, -7859.8f, -1521.8f, 139.2f, 6.2f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
break;
|
||||
case 24:
|
||||
DoScriptText(SAY_SEC_AMBUSH_START, m_creature);
|
||||
SetEscortPaused(true);
|
||||
|
||||
m_creature->SummonCreature(NPC_BLACKROCK_AMBUSHER, -8035.3f, -1222.2f, 135.5f, 5.1f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
m_creature->SummonCreature(NPC_FLAMESCALE_DRAGONSPAWN, -8037.5f, -1216.9f, 135.8f, 5.1f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
m_creature->SummonCreature(NPC_BLACKROCK_AMBUSHER, -8009.5f, -1222.1f, 139.2f, 3.9f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
m_creature->SummonCreature(NPC_FLAMESCALE_DRAGONSPAWN, -8007.1f, -1219.4f, 140.1f, 3.9f, TEMPSUMMON_TIMED_OOC_DESPAWN, 20000);
|
||||
break;
|
||||
case 28:
|
||||
m_creature->SummonCreature(NPC_SEARSCALE_DRAKE, -7897.8f, -1123.1f, 233.4f, 3.0f, TEMPSUMMON_TIMED_OOC_DESPAWN, 60000);
|
||||
m_creature->SummonCreature(NPC_SEARSCALE_DRAKE, -7898.8f, -1125.1f, 193.9f, 3.0f, TEMPSUMMON_TIMED_OOC_DESPAWN, 60000);
|
||||
m_creature->SummonCreature(NPC_SEARSCALE_DRAKE, -7895.6f, -1119.5f, 194.5f, 3.1f, TEMPSUMMON_TIMED_OOC_DESPAWN, 60000);
|
||||
break;
|
||||
case 30:
|
||||
{
|
||||
SetEscortPaused(true);
|
||||
DoScriptText(SAY_THIRD_AMBUSH_START, m_creature);
|
||||
|
||||
Player* pPlayer = GetPlayerForEscort();
|
||||
if (!pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set all the dragons in combat
|
||||
for (GuidList::const_iterator itr = m_lSearscaleGuidList.begin(); itr != m_lSearscaleGuidList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
|
||||
{
|
||||
pTemp->AI()->AttackStart(pPlayer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 36:
|
||||
DoScriptText(EMOTE_LAUGH, m_creature);
|
||||
break;
|
||||
case 45:
|
||||
StartNextDialogueText(SAY_LAST_STAND);
|
||||
SetEscortPaused(true);
|
||||
|
||||
m_creature->SummonCreature(NPC_HIGH_EXECUTIONER_NUZARK, -7532.3f, -1029.4f, 258.0f, 2.7f, TEMPSUMMON_TIMED_DESPAWN, 40000);
|
||||
m_creature->SummonCreature(NPC_SHADOW_OF_LEXLORT, -7532.8f, -1032.9f, 258.2f, 2.5f, TEMPSUMMON_TIMED_DESPAWN, 40000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDidDialogueStep(int32 iEntry) override
|
||||
{
|
||||
switch (iEntry)
|
||||
{
|
||||
case SAY_LEXLORT_1:
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
break;
|
||||
case SAY_LEXLORT_3:
|
||||
// Note: this part isn't very clear. Should he just simply attack him, or charge him?
|
||||
if (Creature* pNuzark = m_creature->GetMap()->GetCreature(m_nuzarkGuid))
|
||||
{
|
||||
pNuzark->HandleEmote(EMOTE_ONESHOT_ATTACK2HTIGHT);
|
||||
}
|
||||
break;
|
||||
case NPC_GRARK_LORKRUB:
|
||||
// Fake death creature when the axe is lowered. This will allow us to finish the event
|
||||
m_creature->InterruptNonMeleeSpells(true);
|
||||
m_creature->SetHealth(1);
|
||||
m_creature->StopMoving();
|
||||
m_creature->ClearComboPointHolders();
|
||||
m_creature->RemoveAllAurasOnDeath();
|
||||
m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
|
||||
m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
|
||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
m_creature->ClearAllReactives();
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
break;
|
||||
case SAY_LEXLORT_4:
|
||||
// Finish the quest
|
||||
if (Player* pPlayer = GetPlayerForEscort())
|
||||
{
|
||||
pPlayer->GroupEventHappens(QUEST_ID_PRECARIOUS_PREDICAMENT, m_creature);
|
||||
}
|
||||
// Kill self
|
||||
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
switch (pSummoned->GetEntry())
|
||||
{
|
||||
case NPC_HIGH_EXECUTIONER_NUZARK:
|
||||
m_nuzarkGuid = pSummoned->GetObjectGuid();
|
||||
break;
|
||||
case NPC_SHADOW_OF_LEXLORT:
|
||||
m_lexlortGuid = pSummoned->GetObjectGuid();
|
||||
break;
|
||||
case NPC_SEARSCALE_DRAKE:
|
||||
// If it's the flying drake allow him to move in circles
|
||||
if (m_bIsFirstSearScale)
|
||||
{
|
||||
m_bIsFirstSearScale = false;
|
||||
|
||||
pSummoned->SetLevitate(true);
|
||||
// ToDo: this guy should fly in circles above the creature
|
||||
}
|
||||
m_lSearscaleGuidList.push_back(pSummoned->GetObjectGuid());
|
||||
break;
|
||||
|
||||
default:
|
||||
// The hostile mobs should attack the player only
|
||||
if (Player* pPlayer = GetPlayerForEscort())
|
||||
{
|
||||
pSummoned->AI()->AttackStart(pPlayer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureJustDied(Creature* /*pSummoned*/) override
|
||||
{
|
||||
++m_uiKilledCreatures;
|
||||
|
||||
switch (m_uiKilledCreatures)
|
||||
{
|
||||
case 4:
|
||||
DoScriptText(SAY_FIRST_AMBUSH_END, m_creature);
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case 8:
|
||||
DoScriptText(SAY_SEC_AMBUSH_END, m_creature);
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case 11:
|
||||
DoScriptText(SAY_THIRD_AMBUSH_END, m_creature);
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Creature* GetSpeakerByEntry(uint32 uiEntry) override
|
||||
{
|
||||
switch (uiEntry)
|
||||
{
|
||||
case NPC_GRARK_LORKRUB:
|
||||
return m_creature;
|
||||
case NPC_HIGH_EXECUTIONER_NUZARK:
|
||||
return m_creature->GetMap()->GetCreature(m_nuzarkGuid);
|
||||
case NPC_SHADOW_OF_LEXLORT:
|
||||
return m_creature->GetMap()->GetCreature(m_lexlortGuid);
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEscortAI(const uint32 uiDiff) override
|
||||
{
|
||||
DialogueUpdate(uiDiff);
|
||||
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_grark_lorkrub(Creature* pCreature)
|
||||
{
|
||||
return new npc_grark_lorkrubAI(pCreature);
|
||||
}
|
||||
|
||||
bool QuestAccept_npc_grark_lorkrub(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_ID_PRECARIOUS_PREDICAMENT)
|
||||
{
|
||||
if (npc_grark_lorkrubAI* pEscortAI = dynamic_cast<npc_grark_lorkrubAI*>(pCreature->AI()))
|
||||
{
|
||||
pEscortAI->Start(false, pPlayer, pQuest);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EffectDummyCreature_spell_capture_grark(Unit* /*pCaster*/, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget, ObjectGuid /*originalCasterGuid*/)
|
||||
{
|
||||
// always check spellid and effectindex
|
||||
if (uiSpellId == SPELL_CAPTURE_GRARK && uiEffIndex == EFFECT_INDEX_0)
|
||||
{
|
||||
// Note: this implementation needs additional research! There is a lot of guesswork involved in this!
|
||||
if (pCreatureTarget->GetHealthPercent() > 25.0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The faction is guesswork - needs more research
|
||||
DoScriptText(EMOTE_SUBMIT, pCreatureTarget);
|
||||
pCreatureTarget->SetFactionTemporary(FACTION_FRIENDLY, TEMPFACTION_RESTORE_RESPAWN);
|
||||
pCreatureTarget->AI()->EnterEvadeMode();
|
||||
|
||||
// always return true when we are handling this spell and effect
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddSC_burning_steppes()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_ragged_john";
|
||||
pNewScript->GetAI = &GetAI_npc_ragged_john;
|
||||
pNewScript->pGossipHello = &GossipHello_npc_ragged_john;
|
||||
pNewScript->pGossipSelect = &GossipSelect_npc_ragged_john;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_grark_lorkrub";
|
||||
pNewScript->GetAI = &GetAI_npc_grark_lorkrub;
|
||||
pNewScript->pQuestAcceptNPC = &QuestAccept_npc_grark_lorkrub;
|
||||
pNewScript->pEffectDummyNPC = &EffectDummyCreature_spell_capture_grark;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Mr_Smite
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Deadmines
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "deadmines.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_PHASE_2 = -1036002,
|
||||
SAY_PHASE_3 = -1036003,
|
||||
|
||||
// EQUIP_ID_SWORD = 2179, // default equipment, not used in code
|
||||
EQUIP_ID_AXE = 2183,
|
||||
EQUIP_ID_HAMMER = 10756,
|
||||
|
||||
SPELL_NIBLE_REFLEXES = 6433, // removed after phase 1
|
||||
SPELL_SMITE_SLAM = 6435, // only casted in phase 3
|
||||
SPELL_SMITE_STOMP = 6432,
|
||||
SPELL_SMITE_HAMMER = 6436, // unclear, not casted in sniff
|
||||
SPELL_THRASH = 12787, // only casted in phase 2; unclear, 3391 directly casted in sniff
|
||||
|
||||
PHASE_1 = 1,
|
||||
PHASE_2 = 2,
|
||||
PHASE_3 = 3,
|
||||
PHASE_EQUIP_NULL = 4,
|
||||
PHASE_EQUIP_START = 5,
|
||||
PHASE_EQUIP_PROCESS = 6,
|
||||
PHASE_EQUIP_END = 7,
|
||||
};
|
||||
|
||||
struct boss_mr_smiteAI : public ScriptedAI
|
||||
{
|
||||
boss_mr_smiteAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
|
||||
|
||||
uint32 m_uiPhase;
|
||||
uint32 m_uiEquipTimer;
|
||||
uint32 m_uiSlamTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiPhase = PHASE_1;
|
||||
m_uiEquipTimer = 0;
|
||||
m_uiSlamTimer = 9000;
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_NIBLE_REFLEXES, CAST_TRIGGERED);
|
||||
|
||||
// must assume database has the default equipment set
|
||||
SetEquipmentSlots(true);
|
||||
}
|
||||
|
||||
void AttackedBy(Unit* pAttacker) override
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_uiPhase > PHASE_3)
|
||||
return;
|
||||
|
||||
AttackStart(pAttacker);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* pWho) override
|
||||
{
|
||||
if (m_uiPhase > PHASE_3)
|
||||
return;
|
||||
|
||||
if (m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->AddThreat(pWho);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 uiMotionType, uint32 /*uiPointId*/) override
|
||||
{
|
||||
if (uiMotionType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
m_creature->SetSheath(SHEATH_STATE_UNARMED);
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
|
||||
m_uiEquipTimer = 3000;
|
||||
m_uiPhase = PHASE_EQUIP_PROCESS;
|
||||
}
|
||||
|
||||
void PhaseEquipStart()
|
||||
{
|
||||
ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData();
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
GameObject* pChest = pInstance->GetSingleGameObjectFromStorage(GO_SMITE_CHEST);
|
||||
|
||||
if (!pChest)
|
||||
return;
|
||||
|
||||
m_uiPhase = PHASE_EQUIP_NULL;
|
||||
|
||||
float fX, fY, fZ;
|
||||
pChest->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE);
|
||||
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->SetFacingToObject(pChest);
|
||||
m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
|
||||
}
|
||||
|
||||
void PhaseEquipProcess()
|
||||
{
|
||||
if (m_creature->GetHealthPercent() < 33.0f)
|
||||
{
|
||||
// It's Hammer, go Hammer!
|
||||
SetEquipmentSlots(false, EQUIP_ID_HAMMER, EQUIP_UNEQUIP);
|
||||
DoCastSpellIfCan(m_creature, SPELL_SMITE_HAMMER);
|
||||
}
|
||||
else
|
||||
SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE);
|
||||
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
m_uiPhase = PHASE_EQUIP_END;
|
||||
m_uiEquipTimer = 1000;
|
||||
}
|
||||
|
||||
void PhaseEquipEnd()
|
||||
{
|
||||
// We don't have getVictim, so select from threat list
|
||||
Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0);
|
||||
|
||||
if (!pVictim)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
m_creature->SetSheath(SHEATH_STATE_MELEE);
|
||||
|
||||
m_uiPhase = m_creature->GetHealthPercent() < 33.0f ? PHASE_3 : PHASE_2;
|
||||
|
||||
if (m_uiPhase == PHASE_2)
|
||||
DoCastSpellIfCan(m_creature, SPELL_THRASH, CAST_TRIGGERED);
|
||||
|
||||
AttackStart(pVictim);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{
|
||||
if (m_uiEquipTimer)
|
||||
{
|
||||
// decrease the cooldown in between equipment change phases
|
||||
if (m_uiEquipTimer > uiDiff)
|
||||
{
|
||||
m_uiEquipTimer -= uiDiff;
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_uiEquipTimer = 0;
|
||||
}
|
||||
|
||||
switch (m_uiPhase)
|
||||
{
|
||||
case PHASE_EQUIP_START:
|
||||
PhaseEquipStart();
|
||||
break;
|
||||
case PHASE_EQUIP_PROCESS:
|
||||
PhaseEquipProcess();
|
||||
break;
|
||||
case PHASE_EQUIP_END:
|
||||
PhaseEquipEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// the normal combat phases
|
||||
switch (m_uiPhase)
|
||||
{
|
||||
case PHASE_1:
|
||||
{
|
||||
if (m_creature->GetHealthPercent() < 66.0f)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SMITE_STOMP) == CAST_OK)
|
||||
{
|
||||
DoScriptText(m_creature->GetHealthPercent() < 33.0f ? SAY_PHASE_3 : SAY_PHASE_2, m_creature);
|
||||
m_uiPhase = PHASE_EQUIP_START;
|
||||
m_uiEquipTimer = 2500;
|
||||
|
||||
// will clear getVictim (m_attacking)
|
||||
m_creature->AttackStop(true);
|
||||
m_creature->RemoveAurasDueToSpell(SPELL_NIBLE_REFLEXES);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PHASE_2:
|
||||
{
|
||||
if (m_creature->GetHealthPercent() < 33.0f)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SMITE_STOMP) == CAST_OK)
|
||||
{
|
||||
DoScriptText(SAY_PHASE_3, m_creature);
|
||||
m_uiPhase = PHASE_EQUIP_START;
|
||||
m_uiEquipTimer = 2500;
|
||||
|
||||
// will clear getVictim (m_attacking)
|
||||
m_creature->AttackStop(true);
|
||||
m_creature->RemoveAurasDueToSpell(SPELL_THRASH);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PHASE_3:
|
||||
{
|
||||
if (m_uiSlamTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SMITE_SLAM) == CAST_OK)
|
||||
m_uiSlamTimer = 11000;
|
||||
}
|
||||
else
|
||||
m_uiSlamTimer -= uiDiff;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_mr_smite(Creature* pCreature)
|
||||
{
|
||||
return new boss_mr_smiteAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_mr_smite()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "boss_mr_smite";
|
||||
pNewScript->GetAI = &GetAI_boss_mr_smite;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Deadmines
|
||||
SD%Complete: 100
|
||||
SDComment: Contains GO for Iron Clad door event
|
||||
SDCategory: Deadmines
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "deadmines.h"
|
||||
|
||||
bool GOUse_go_defias_cannon(Player* /*pPlayer*/, GameObject* pGo)
|
||||
{
|
||||
ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData();
|
||||
|
||||
if (!pInstance)
|
||||
return false;
|
||||
|
||||
if (pInstance->GetData(TYPE_IRON_CLAD_DOOR) == DONE)
|
||||
return false;
|
||||
|
||||
pInstance->SetData(TYPE_IRON_CLAD_DOOR, DONE);
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddSC_deadmines()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "go_defias_cannon";
|
||||
pNewScript->pGOUse = &GOUse_go_defias_cannon;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
||||
#ifndef DEF_DEADMINES_H
|
||||
#define DEF_DEADMINES_H
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_ENCOUNTER = 4,
|
||||
|
||||
TYPE_RHAHKZOR = 0,
|
||||
TYPE_SNEED = 1,
|
||||
TYPE_GILNID = 2,
|
||||
TYPE_IRON_CLAD_DOOR = 3,
|
||||
|
||||
INST_SAY_ALARM1 = -1036000,
|
||||
INST_SAY_ALARM2 = -1036001,
|
||||
|
||||
GO_FACTORY_DOOR = 13965, // rhahk'zor
|
||||
GO_MAST_ROOM_DOOR = 16400, // sneed
|
||||
GO_FOUNDRY_DOOR = 16399, // gilnid
|
||||
GO_HEAVY_DOOR_1 = 17153, // to sneed
|
||||
GO_HEAVY_DOOR_2 = 17154, // to gilnid
|
||||
GO_IRON_CLAD_DOOR = 16397,
|
||||
GO_DEFIAS_CANNON = 16398,
|
||||
GO_SMITE_CHEST = 144111, // use to get correct location of mr.smites equipment changes
|
||||
GO_MYSTERIOUS_CHEST = 180024, // used for quest 7938; spawns in the instance only if one of the players has the quest
|
||||
|
||||
NPC_RHAHKZOR = 644,
|
||||
NPC_SNEED = 643,
|
||||
NPC_GILNID = 1763,
|
||||
NPC_MR_SMITE = 646,
|
||||
NPC_PIRATE = 657,
|
||||
NPC_SQUALLSHAPER = 1732,
|
||||
|
||||
QUEST_FORTUNE_AWAITS = 7938,
|
||||
};
|
||||
|
||||
class instance_deadmines : public ScriptedInstance
|
||||
{
|
||||
public:
|
||||
instance_deadmines(Map* pMap);
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void OnPlayerEnter(Player* pPlayer) override;
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature) override;
|
||||
void OnObjectCreate(GameObject* pGo) override;
|
||||
|
||||
void OnCreatureDeath(Creature* pCreature) override;
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData) override;
|
||||
uint32 GetData(uint32 uiType) const override;
|
||||
|
||||
const char* Save() const override { return m_strInstData.c_str(); }
|
||||
void Load(const char* chrIn) override;
|
||||
|
||||
void Update(uint32 uiDiff) override;
|
||||
|
||||
private:
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
std::string m_strInstData;
|
||||
|
||||
uint32 m_uiIronDoorTimer;
|
||||
uint32 m_uiDoorStep;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
/* Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Instance_Deadmines
|
||||
SD%Complete: 0
|
||||
SDComment: Placeholder
|
||||
SDCategory: Deadmines
|
||||
EndScriptData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "deadmines.h"
|
||||
|
||||
instance_deadmines::instance_deadmines(Map* pMap) : ScriptedInstance(pMap),
|
||||
m_uiIronDoorTimer(0),
|
||||
m_uiDoorStep(0)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void instance_deadmines::Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
}
|
||||
|
||||
void instance_deadmines::OnPlayerEnter(Player* pPlayer)
|
||||
{
|
||||
// Respawn the Mysterious chest if one of the players who enter the instance has the quest in his log
|
||||
if (pPlayer->GetQuestStatus(QUEST_FORTUNE_AWAITS) == QUEST_STATUS_COMPLETE &&
|
||||
!pPlayer->GetQuestRewardStatus(QUEST_FORTUNE_AWAITS))
|
||||
DoRespawnGameObject(GO_MYSTERIOUS_CHEST, HOUR);
|
||||
}
|
||||
|
||||
void instance_deadmines::OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
if (pCreature->GetEntry() == NPC_MR_SMITE)
|
||||
m_mNpcEntryGuidStore[NPC_MR_SMITE] = pCreature->GetObjectGuid();
|
||||
}
|
||||
|
||||
void instance_deadmines::OnObjectCreate(GameObject* pGo)
|
||||
{
|
||||
switch (pGo->GetEntry())
|
||||
{
|
||||
case GO_FACTORY_DOOR:
|
||||
if (m_auiEncounter[TYPE_RHAHKZOR] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
break;
|
||||
case GO_MAST_ROOM_DOOR:
|
||||
if (m_auiEncounter[TYPE_SNEED] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
break;
|
||||
case GO_FOUNDRY_DOOR:
|
||||
if (m_auiEncounter[TYPE_GILNID] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
break;
|
||||
case GO_IRON_CLAD_DOOR:
|
||||
if (m_auiEncounter[TYPE_IRON_CLAD_DOOR] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
|
||||
|
||||
break;
|
||||
case GO_DEFIAS_CANNON:
|
||||
case GO_SMITE_CHEST:
|
||||
case GO_MYSTERIOUS_CHEST:
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
m_mGoEntryGuidStore[pGo->GetEntry()] = pGo->GetObjectGuid();
|
||||
}
|
||||
|
||||
void instance_deadmines::OnCreatureDeath(Creature* pCreature)
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
{
|
||||
case NPC_RHAHKZOR: SetData(TYPE_RHAHKZOR, DONE); break;
|
||||
case NPC_SNEED: SetData(TYPE_SNEED, DONE); break;
|
||||
case NPC_GILNID: SetData(TYPE_GILNID, DONE); break;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_deadmines::SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case TYPE_RHAHKZOR:
|
||||
{
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_FACTORY_DOOR);
|
||||
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
}
|
||||
case TYPE_SNEED:
|
||||
{
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_MAST_ROOM_DOOR);
|
||||
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
}
|
||||
case TYPE_GILNID:
|
||||
{
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(GO_FOUNDRY_DOOR);
|
||||
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
}
|
||||
case TYPE_IRON_CLAD_DOOR:
|
||||
{
|
||||
// delayed door animation to sync with Defias Cannon animation
|
||||
if (uiData == DONE)
|
||||
m_uiIronDoorTimer = 500;
|
||||
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uiData == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 instance_deadmines::GetData(uint32 uiType) const
|
||||
{
|
||||
if (uiType < MAX_ENCOUNTER)
|
||||
return m_auiEncounter[uiType];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void instance_deadmines::Load(const char* chrIn)
|
||||
{
|
||||
if (!chrIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(chrIn);
|
||||
|
||||
std::istringstream loadStream(chrIn);
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3];
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
void instance_deadmines::Update(uint32 uiDiff)
|
||||
{
|
||||
if (m_uiIronDoorTimer)
|
||||
{
|
||||
if (m_uiIronDoorTimer <= uiDiff)
|
||||
{
|
||||
switch (m_uiDoorStep)
|
||||
{
|
||||
case 0:
|
||||
DoUseDoorOrButton(GO_IRON_CLAD_DOOR, 0, true);
|
||||
|
||||
if (Creature* pMrSmite = GetSingleCreatureFromStorage(NPC_MR_SMITE))
|
||||
DoScriptText(INST_SAY_ALARM1, pMrSmite);
|
||||
|
||||
if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_IRON_CLAD_DOOR))
|
||||
{
|
||||
// should be static spawns, fetch the closest ones at the pier
|
||||
if (Creature* pi1 = GetClosestCreatureWithEntry(pDoor, NPC_PIRATE, 40.0f))
|
||||
{
|
||||
pi1->SetWalk(false);
|
||||
pi1->GetMotionMaster()->MovePoint(0, pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ());
|
||||
}
|
||||
|
||||
if (Creature* pi2 = GetClosestCreatureWithEntry(pDoor, NPC_SQUALLSHAPER, 40.0f))
|
||||
{
|
||||
pi2->SetWalk(false);
|
||||
pi2->GetMotionMaster()->MovePoint(0, pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
++m_uiDoorStep;
|
||||
m_uiIronDoorTimer = 15000;
|
||||
break;
|
||||
case 1:
|
||||
if (Creature* pMrSmite = GetSingleCreatureFromStorage(NPC_MR_SMITE))
|
||||
DoScriptText(INST_SAY_ALARM2, pMrSmite);
|
||||
|
||||
m_uiDoorStep = 0;
|
||||
m_uiIronDoorTimer = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiIronDoorTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
InstanceData* GetInstanceData_instance_deadmines(Map* pMap)
|
||||
{
|
||||
return new instance_deadmines(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_deadmines()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "instance_deadmines";
|
||||
pNewScript->GetInstanceData = &GetInstanceData_instance_deadmines;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
44
src/modules/SD2/scripts/eastern_kingdoms/dun_morogh.cpp
Normal file
44
src/modules/SD2/scripts/eastern_kingdoms/dun_morogh.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ScriptData
|
||||
* SDName: Dun_Morogh
|
||||
* SD%Complete: 0
|
||||
* SDComment: Placeholder
|
||||
* SDCategory: Dun Morogh
|
||||
* EndScriptData
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentData
|
||||
* EndContentData
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void AddSC_dun_morogh()
|
||||
{
|
||||
}
|
||||
364
src/modules/SD2/scripts/eastern_kingdoms/eastern_plaguelands.cpp
Normal file
364
src/modules/SD2/scripts/eastern_kingdoms/eastern_plaguelands.cpp
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ScriptData
|
||||
* SDName: Eastern_Plaguelands
|
||||
* SD%Complete: 100
|
||||
* SDComment: Quest support: 7622.
|
||||
* SDCategory: Eastern Plaguelands
|
||||
* EndScriptData
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentData
|
||||
* npc_eris_havenfire
|
||||
* EndContentData
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
/*######
|
||||
## npc_eris_havenfire
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_PHASE_HEAL = -1000815,
|
||||
SAY_EVENT_END = -1000816,
|
||||
SAY_EVENT_FAIL_1 = -1000817,
|
||||
SAY_EVENT_FAIL_2 = -1000818,
|
||||
SAY_PEASANT_APPEAR_1 = -1000819,
|
||||
SAY_PEASANT_APPEAR_2 = -1000820,
|
||||
SAY_PEASANT_APPEAR_3 = -1000821,
|
||||
|
||||
// SPELL_DEATHS_DOOR = 23127, // damage spells cast on the peasants
|
||||
// SPELL_SEETHING_PLAGUE = 23072,
|
||||
SPELL_ENTER_THE_LIGHT_DND = 23107,
|
||||
SPELL_BLESSING_OF_NORDRASSIL = 23108,
|
||||
|
||||
NPC_INJURED_PEASANT = 14484,
|
||||
NPC_PLAGUED_PEASANT = 14485,
|
||||
NPC_SCOURGE_ARCHER = 14489,
|
||||
NPC_SCOURGE_FOOTSOLDIER = 14486,
|
||||
NPC_THE_CLEANER = 14503, // can be summoned if the priest has more players in the party for help. requires further research
|
||||
|
||||
QUEST_BALANCE_OF_LIGHT_AND_SHADOW = 7622,
|
||||
|
||||
MAX_PEASANTS = 12,
|
||||
MAX_ARCHERS = 8,
|
||||
};
|
||||
|
||||
static const float aArcherSpawn[8][4] =
|
||||
{
|
||||
{3327.42f, -3021.11f, 170.57f, 6.01f},
|
||||
{3335.4f, -3054.3f, 173.63f, 0.49f},
|
||||
{3351.3f, -3079.08f, 178.67f, 1.15f},
|
||||
{3358.93f, -3076.1f, 174.87f, 1.57f},
|
||||
{3371.58f, -3069.24f, 175.20f, 1.99f},
|
||||
{3369.46f, -3023.11f, 171.83f, 3.69f},
|
||||
{3383.25f, -3057.01f, 181.53f, 2.21f},
|
||||
{3380.03f, -3062.73f, 181.90f, 2.31f},
|
||||
};
|
||||
|
||||
static const float aPeasantSpawnLoc[3] = {3360.12f, -3047.79f, 165.26f};
|
||||
static const float aPeasantMoveLoc[3] = {3335.0f, -2994.04f, 161.14f};
|
||||
|
||||
static const int32 aPeasantSpawnYells[3] = {SAY_PEASANT_APPEAR_1, SAY_PEASANT_APPEAR_2, SAY_PEASANT_APPEAR_3};
|
||||
|
||||
struct npc_eris_havenfireAI : public ScriptedAI
|
||||
{
|
||||
npc_eris_havenfireAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
|
||||
|
||||
uint32 m_uiEventTimer;
|
||||
uint32 m_uiSadEndTimer;
|
||||
uint8 m_uiPhase;
|
||||
uint8 m_uiCurrentWave;
|
||||
uint8 m_uiKillCounter;
|
||||
uint8 m_uiSaveCounter;
|
||||
|
||||
ObjectGuid m_playerGuid;
|
||||
GuidList m_lSummonedGuidList;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiEventTimer = 0;
|
||||
m_uiSadEndTimer = 0;
|
||||
m_uiPhase = 0;
|
||||
m_uiCurrentWave = 0;
|
||||
m_uiKillCounter = 0;
|
||||
m_uiSaveCounter = 0;
|
||||
|
||||
m_playerGuid.Clear();
|
||||
m_lSummonedGuidList.clear();
|
||||
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
switch (pSummoned->GetEntry())
|
||||
{
|
||||
case NPC_INJURED_PEASANT:
|
||||
case NPC_PLAGUED_PEASANT:
|
||||
float fX, fY, fZ;
|
||||
pSummoned->GetRandomPoint(aPeasantMoveLoc[0], aPeasantMoveLoc[1], aPeasantMoveLoc[2], 10.0f, fX, fY, fZ);
|
||||
pSummoned->GetMotionMaster()->MovePoint(1, fX, fY, fZ);
|
||||
m_lSummonedGuidList.push_back(pSummoned->GetObjectGuid());
|
||||
break;
|
||||
case NPC_SCOURGE_FOOTSOLDIER:
|
||||
case NPC_THE_CLEANER:
|
||||
if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid))
|
||||
{
|
||||
pSummoned->AI()->AttackStart(pPlayer);
|
||||
}
|
||||
break;
|
||||
case NPC_SCOURGE_ARCHER:
|
||||
// ToDo: make these ones attack the peasants
|
||||
break;
|
||||
}
|
||||
|
||||
m_lSummonedGuidList.push_back(pSummoned->GetObjectGuid());
|
||||
}
|
||||
|
||||
void SummonedMovementInform(Creature* pSummoned, uint32 uiMotionType, uint32 uiPointId) override
|
||||
{
|
||||
if (uiMotionType != POINT_MOTION_TYPE || !uiPointId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (uiPointId)
|
||||
{
|
||||
++m_uiSaveCounter;
|
||||
pSummoned->GetMotionMaster()->Clear();
|
||||
|
||||
pSummoned->RemoveAllAuras();
|
||||
pSummoned->CastSpell(pSummoned, SPELL_ENTER_THE_LIGHT_DND, false);
|
||||
pSummoned->ForcedDespawn(10000);
|
||||
|
||||
// Event ended
|
||||
if (m_uiSaveCounter >= 50 && m_uiCurrentWave == 5)
|
||||
{
|
||||
DoBalanceEventEnd();
|
||||
}
|
||||
// Phase ended
|
||||
else if (m_uiSaveCounter + m_uiKillCounter == m_uiCurrentWave * MAX_PEASANTS)
|
||||
{
|
||||
DoHandlePhaseEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureJustDied(Creature* pSummoned) override
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_INJURED_PEASANT || pSummoned->GetEntry() == NPC_PLAGUED_PEASANT)
|
||||
{
|
||||
++m_uiKillCounter;
|
||||
|
||||
// If more than 15 peasants have died, then fail the quest
|
||||
if (m_uiKillCounter == MAX_PEASANTS)
|
||||
{
|
||||
if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid))
|
||||
{
|
||||
pPlayer->FailQuest(QUEST_BALANCE_OF_LIGHT_AND_SHADOW);
|
||||
}
|
||||
|
||||
DoScriptText(SAY_EVENT_FAIL_1, m_creature);
|
||||
m_uiSadEndTimer = 4000;
|
||||
}
|
||||
else if (m_uiSaveCounter + m_uiKillCounter == m_uiCurrentWave * MAX_PEASANTS)
|
||||
{
|
||||
DoHandlePhaseEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoSummonWave(uint32 uiSummonId = 0)
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
|
||||
if (!uiSummonId)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_PEASANTS; ++i)
|
||||
{
|
||||
uint32 uiSummonEntry = roll_chance_i(70) ? NPC_INJURED_PEASANT : NPC_PLAGUED_PEASANT;
|
||||
m_creature->GetRandomPoint(aPeasantSpawnLoc[0], aPeasantSpawnLoc[1], aPeasantSpawnLoc[2], 10.0f, fX, fY, fZ);
|
||||
if (Creature* pTemp = m_creature->SummonCreature(uiSummonEntry, fX, fY, fZ, 0, TEMPSUMMON_DEAD_DESPAWN, 0))
|
||||
{
|
||||
// Only the first mob needs to yell
|
||||
if (!i)
|
||||
{
|
||||
DoScriptText(aPeasantSpawnYells[urand(0, 2)], pTemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++m_uiCurrentWave;
|
||||
}
|
||||
else if (uiSummonId == NPC_SCOURGE_FOOTSOLDIER)
|
||||
{
|
||||
uint8 uiRand = urand(2, 3);
|
||||
for (uint8 i = 0; i < uiRand; ++i)
|
||||
{
|
||||
m_creature->GetRandomPoint(aPeasantSpawnLoc[0], aPeasantSpawnLoc[1], aPeasantSpawnLoc[2], 15.0f, fX, fY, fZ);
|
||||
m_creature->SummonCreature(NPC_SCOURGE_FOOTSOLDIER, fX, fY, fZ, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
|
||||
}
|
||||
}
|
||||
else if (uiSummonId == NPC_SCOURGE_ARCHER)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ARCHERS; ++i)
|
||||
{
|
||||
m_creature->SummonCreature(NPC_SCOURGE_ARCHER, aArcherSpawn[i][0], aArcherSpawn[i][1], aArcherSpawn[i][2], aArcherSpawn[i][3], TEMPSUMMON_DEAD_DESPAWN, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoHandlePhaseEnd()
|
||||
{
|
||||
if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid))
|
||||
{
|
||||
pPlayer->CastSpell(pPlayer, SPELL_BLESSING_OF_NORDRASSIL, true);
|
||||
}
|
||||
|
||||
DoScriptText(SAY_PHASE_HEAL, m_creature);
|
||||
|
||||
// Send next wave
|
||||
if (m_uiCurrentWave < 5)
|
||||
{
|
||||
DoSummonWave();
|
||||
}
|
||||
}
|
||||
|
||||
void DoStartBalanceEvent(Player* pPlayer)
|
||||
{
|
||||
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
m_playerGuid = pPlayer->GetObjectGuid();
|
||||
m_uiEventTimer = 5000;
|
||||
}
|
||||
|
||||
void DoBalanceEventEnd()
|
||||
{
|
||||
if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid))
|
||||
{
|
||||
pPlayer->AreaExploredOrEventHappens(QUEST_BALANCE_OF_LIGHT_AND_SHADOW);
|
||||
}
|
||||
|
||||
DoScriptText(SAY_EVENT_END, m_creature);
|
||||
DoDespawnSummons(true);
|
||||
EnterEvadeMode();
|
||||
}
|
||||
|
||||
void DoDespawnSummons(bool bIsEventEnd = false)
|
||||
{
|
||||
for (GuidList::const_iterator itr = m_lSummonedGuidList.begin(); itr != m_lSummonedGuidList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
|
||||
{
|
||||
if (bIsEventEnd && (pTemp->GetEntry() == NPC_INJURED_PEASANT || pTemp->GetEntry() == NPC_PLAGUED_PEASANT))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pTemp->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (m_uiEventTimer)
|
||||
{
|
||||
if (m_uiEventTimer <= uiDiff)
|
||||
{
|
||||
switch (m_uiPhase)
|
||||
{
|
||||
case 0:
|
||||
DoSummonWave(NPC_SCOURGE_ARCHER);
|
||||
m_uiEventTimer = 5000;
|
||||
break;
|
||||
case 1:
|
||||
DoSummonWave();
|
||||
m_uiEventTimer = urand(60000, 80000);
|
||||
break;
|
||||
default:
|
||||
// The summoning timer of the soldiers isn't very clear
|
||||
DoSummonWave(NPC_SCOURGE_FOOTSOLDIER);
|
||||
m_uiEventTimer = urand(5000, 30000);
|
||||
break;
|
||||
}
|
||||
++m_uiPhase;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiEventTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle event end in case of fail
|
||||
if (m_uiSadEndTimer)
|
||||
{
|
||||
if (m_uiSadEndTimer <= uiDiff)
|
||||
{
|
||||
DoScriptText(SAY_EVENT_FAIL_2, m_creature);
|
||||
m_creature->ForcedDespawn(5000);
|
||||
DoDespawnSummons();
|
||||
m_uiSadEndTimer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiSadEndTimer -= uiDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_eris_havenfire(Creature* pCreature)
|
||||
{
|
||||
return new npc_eris_havenfireAI(pCreature);
|
||||
}
|
||||
|
||||
bool QuestAccept_npc_eris_havenfire(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_BALANCE_OF_LIGHT_AND_SHADOW)
|
||||
{
|
||||
if (npc_eris_havenfireAI* pErisAI = dynamic_cast<npc_eris_havenfireAI*>(pCreature->AI()))
|
||||
{
|
||||
pErisAI->DoStartBalanceEvent(pPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_eastern_plaguelands()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_eris_havenfire";
|
||||
pNewScript->GetAI = &GetAI_npc_eris_havenfire;
|
||||
pNewScript->pQuestAcceptNPC = &QuestAccept_npc_eris_havenfire;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
231
src/modules/SD2/scripts/eastern_kingdoms/elwynn_forest.cpp
Normal file
231
src/modules/SD2/scripts/eastern_kingdoms/elwynn_forest.cpp
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Elwynn_Forest
|
||||
SD%Complete: 100
|
||||
SDComment: Hogger event
|
||||
SDCategory: Elwynn Forest
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_hogger
|
||||
EndContentData */
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
/*######
|
||||
## npc_hogger
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_CALL_HELP = -1004000,
|
||||
WHISPER_EATING = -1004001, // note: this type may need to be updated in the future
|
||||
SAY_HOGGER_BEATEN = -1004002,
|
||||
|
||||
SPELL_EATING = 87351,
|
||||
SPELL_SUMMON_MINIONS = 87366,
|
||||
SPELL_VICIOUS_SLICE = 87337,
|
||||
SPELL_BLOODY_STRIKE = 87359,
|
||||
|
||||
NPC_MINION_OF_HOOGER = 46932,
|
||||
NPC_GENERAL_BUNNY = 45979,
|
||||
};
|
||||
|
||||
struct npc_hoggerAI : public ScriptedAI
|
||||
{
|
||||
npc_hoggerAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
|
||||
|
||||
uint32 m_uiViciousSliceTimer;
|
||||
uint32 m_uiEatingEndTimer;
|
||||
uint32 m_uiBloodyStrikeTimer;
|
||||
bool m_bHasSpawnedMinions;
|
||||
bool m_bEncounterFinished;
|
||||
|
||||
ObjectGuid m_bunnyGuid;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiViciousSliceTimer = urand(15000, 20000);
|
||||
m_uiEatingEndTimer = 0;
|
||||
m_uiBloodyStrikeTimer = 1000;
|
||||
m_bHasSpawnedMinions = false;
|
||||
m_bEncounterFinished = false;
|
||||
}
|
||||
|
||||
void EnterEvadeMode() override
|
||||
{
|
||||
m_creature->RemoveAllAurasOnEvade();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(true);
|
||||
|
||||
// start epilogue event
|
||||
if (m_bEncounterFinished)
|
||||
{
|
||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
m_creature->GetMotionMaster()->MoveWaypoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_creature->IsAlive())
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* pWho) override
|
||||
{
|
||||
// special case for epilogue
|
||||
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
|
||||
return;
|
||||
|
||||
ScriptedAI::AttackStart(pWho);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* pWho) override
|
||||
{
|
||||
// special case for epilogue
|
||||
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
|
||||
return;
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(pWho);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 uiMoveType, uint32 uiPointId) override
|
||||
{
|
||||
if (uiMoveType != POINT_MOTION_TYPE || !uiPointId)
|
||||
return;
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_EATING);
|
||||
m_uiEatingEndTimer = 12000;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_MINION_OF_HOOGER)
|
||||
pSummoned->AI()->AttackStart(m_creature->getVictim());
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* pDealer, uint32& uiDamage) override
|
||||
{
|
||||
// evade and start epilogue when near death
|
||||
if (uiDamage >= m_creature->GetHealth())
|
||||
{
|
||||
uiDamage = 0;
|
||||
|
||||
if (!m_bEncounterFinished)
|
||||
{
|
||||
m_bEncounterFinished = true;
|
||||
m_creature->AI()->EnterEvadeMode();
|
||||
DoScriptText(SAY_HOGGER_BEATEN, m_creature);
|
||||
|
||||
if (pDealer->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)pDealer)->KilledMonsterCredit(m_creature->GetEntry());
|
||||
}
|
||||
}
|
||||
|
||||
// start eating at 50% hp
|
||||
if (!m_bHasSpawnedMinions && !m_bEncounterFinished && m_creature->GetHealthPercent() < 50.0f)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_MINIONS) == CAST_OK)
|
||||
{
|
||||
DoScriptText(SAY_CALL_HELP, m_creature);
|
||||
DoScriptText(WHISPER_EATING, m_creature, pDealer);
|
||||
|
||||
SetCombatMovement(false);
|
||||
if (Creature* pBunny = GetClosestCreatureWithEntry(m_creature, NPC_GENERAL_BUNNY, 25.0f))
|
||||
{
|
||||
float fX, fY, fZ;
|
||||
pBunny->GetContactPoint(m_creature, fX, fY, fZ);
|
||||
m_creature->GetMotionMaster()->MovePoint(1, fX, fY, fZ);
|
||||
m_bunnyGuid = pBunny->GetObjectGuid();
|
||||
}
|
||||
|
||||
m_bHasSpawnedMinions = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
return;
|
||||
|
||||
// resume combat after eat
|
||||
if (m_uiEatingEndTimer)
|
||||
{
|
||||
if (m_uiEatingEndTimer <= uiDiff)
|
||||
{
|
||||
SetCombatMovement(true);
|
||||
DoStartMovement(m_creature->getVictim());
|
||||
m_uiEatingEndTimer = 0;
|
||||
}
|
||||
else
|
||||
m_uiEatingEndTimer -= uiDiff;
|
||||
|
||||
if (m_uiBloodyStrikeTimer < uiDiff)
|
||||
{
|
||||
if (Creature* pTarget = m_creature->GetMap()->GetCreature(m_bunnyGuid))
|
||||
{
|
||||
if (DoCastSpellIfCan(pTarget, SPELL_BLOODY_STRIKE) == CAST_OK)
|
||||
m_uiBloodyStrikeTimer = 2000;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiBloodyStrikeTimer -= uiDiff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_uiViciousSliceTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_VICIOUS_SLICE) == CAST_OK)
|
||||
m_uiViciousSliceTimer = urand(15000, 20000);
|
||||
}
|
||||
else
|
||||
m_uiViciousSliceTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_hogger(Creature* pCreature)
|
||||
{
|
||||
return new npc_hoggerAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_elwynn_forest()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_hogger";
|
||||
pNewScript->GetAI = &GetAI_npc_hogger;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
579
src/modules/SD2/scripts/eastern_kingdoms/eversong_woods.cpp
Normal file
579
src/modules/SD2/scripts/eastern_kingdoms/eversong_woods.cpp
Normal file
|
|
@ -0,0 +1,579 @@
|
|||
/**
|
||||
* ScriptDev2 is an extension for mangos providing enhanced features for
|
||||
* area triggers, creatures, game objects, instances, items, and spells beyond
|
||||
* the default database scripting in mangos.
|
||||
*
|
||||
* Copyright (C) 2006-2013 ScriptDev2 <http://www.scriptdev2.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Eversong_Woods
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 8483, 8488, 8490, 9686
|
||||
SDCategory: Eversong Woods
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_kelerun_bloodmourn
|
||||
go_harbinger_second_trial
|
||||
npc_prospector_anvilward
|
||||
npc_apprentice_mirveda
|
||||
npc_infused_crystal
|
||||
EndContentData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "escort_ai.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
/*######
|
||||
## npc_kelerun_bloodmourn
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
NPC_KELERUN = 17807,
|
||||
NPC_BLOODWRATH = 17809,
|
||||
NPC_LIGHTREND = 17810,
|
||||
NPC_SWIFTBLADE = 17811,
|
||||
NPC_SUNSTRIKER = 17812,
|
||||
|
||||
GO_SECOND_TRIAL = 182052,
|
||||
QUEST_SECOND_TRIAL = 9686,
|
||||
MAX_CHALLENGER = 4
|
||||
};
|
||||
|
||||
const uint32 uiChallengerId[4] = {NPC_BLOODWRATH, NPC_LIGHTREND, NPC_SWIFTBLADE, NPC_SUNSTRIKER};
|
||||
|
||||
const int32 uiSayId[4] =
|
||||
{
|
||||
-1000319,
|
||||
-1000320,
|
||||
-1000321,
|
||||
-1000322
|
||||
};
|
||||
|
||||
float fChallengerLoc[4][4] =
|
||||
{
|
||||
{10110.667f, -6628.059f, 4.100f, 2.708f},
|
||||
{10093.919f, -6634.340f, 4.098f, 1.106f},
|
||||
{10087.565f, -6617.282f, 4.098f, 5.887f},
|
||||
{10104.807f, -6611.145f, 4.101f, 4.265f}
|
||||
};
|
||||
|
||||
struct npc_kelerun_bloodmournAI : public ScriptedAI
|
||||
{
|
||||
npc_kelerun_bloodmournAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_uiNpcFlags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS);
|
||||
Reset();
|
||||
}
|
||||
|
||||
uint32 m_uiNpcFlags;
|
||||
ObjectGuid m_playerGuid;
|
||||
ObjectGuid m_aChallengerGuids[MAX_CHALLENGER];
|
||||
|
||||
uint8 m_uiChallengerCount;
|
||||
|
||||
uint32 m_uiTimeOutTimer;
|
||||
uint32 m_uiCheckAliveStateTimer;
|
||||
uint32 m_uiEngageTimer;
|
||||
|
||||
bool m_bIsEventInProgress;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, m_uiNpcFlags);
|
||||
|
||||
m_playerGuid.Clear();
|
||||
|
||||
m_uiChallengerCount = 0;
|
||||
|
||||
m_uiTimeOutTimer = 60000;
|
||||
m_uiCheckAliveStateTimer = 2500;
|
||||
m_uiEngageTimer = 0;
|
||||
|
||||
m_bIsEventInProgress = false;
|
||||
for (uint8 i = 0; i < MAX_CHALLENGER; ++i) // Despawn challengers
|
||||
{
|
||||
if (Creature* pChallenger = m_creature->GetMap()->GetCreature(m_aChallengerGuids[i]))
|
||||
{ pChallenger->ForcedDespawn(1000); }
|
||||
m_aChallengerGuids[i].Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void StartEvent()
|
||||
{
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
m_bIsEventInProgress = true;
|
||||
}
|
||||
|
||||
bool CanProgressEvent(Player* pPlayer)
|
||||
{
|
||||
if (m_bIsEventInProgress)
|
||||
{
|
||||
m_playerGuid = pPlayer->GetObjectGuid();
|
||||
DoSpawnChallengers();
|
||||
m_uiEngageTimer = 15000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DoSpawnChallengers()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_CHALLENGER; ++i)
|
||||
{
|
||||
if (Creature* pCreature = m_creature->SummonCreature(uiChallengerId[i],
|
||||
fChallengerLoc[i][0], fChallengerLoc[i][1],
|
||||
fChallengerLoc[i][2], fChallengerLoc[i][3],
|
||||
TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 600000))
|
||||
{
|
||||
m_aChallengerGuids[i] = pCreature->GetObjectGuid();
|
||||
pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (m_bIsEventInProgress)
|
||||
{
|
||||
if (m_uiTimeOutTimer)
|
||||
{
|
||||
if (m_uiTimeOutTimer <= uiDiff)
|
||||
{
|
||||
if (!m_playerGuid) // player are expected to use GO within a minute, if not, event will fail.
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
m_uiTimeOutTimer = 0;
|
||||
}
|
||||
else
|
||||
{ m_uiTimeOutTimer -= uiDiff; }
|
||||
}
|
||||
|
||||
if (m_uiCheckAliveStateTimer < uiDiff)
|
||||
{
|
||||
Creature* pChallenger = m_creature->GetMap()->GetCreature(m_aChallengerGuids[m_uiChallengerCount]);
|
||||
if (pChallenger && !pChallenger->IsAlive())
|
||||
{
|
||||
Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid);
|
||||
if (!pPlayer || !pPlayer->IsAlive())
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
++m_uiChallengerCount;
|
||||
|
||||
// count starts at 0
|
||||
if (m_uiChallengerCount == MAX_CHALLENGER)
|
||||
{
|
||||
pPlayer->GroupEventHappens(QUEST_SECOND_TRIAL, m_creature);
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ m_uiEngageTimer = 15000; }
|
||||
}
|
||||
m_uiCheckAliveStateTimer = 2500;
|
||||
}
|
||||
else
|
||||
{ m_uiCheckAliveStateTimer -= uiDiff; }
|
||||
|
||||
if (m_uiEngageTimer)
|
||||
{
|
||||
if (m_uiEngageTimer <= uiDiff)
|
||||
{
|
||||
Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid);
|
||||
if (!pPlayer || !pPlayer->IsAlive())
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Creature* pCreature = m_creature->GetMap()->GetCreature(m_aChallengerGuids[m_uiChallengerCount]))
|
||||
{
|
||||
DoScriptText(uiSayId[m_uiChallengerCount], m_creature, pPlayer);
|
||||
pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
pCreature->AI()->AttackStart(pPlayer);
|
||||
}
|
||||
|
||||
m_uiEngageTimer = 0;
|
||||
}
|
||||
else
|
||||
{ m_uiEngageTimer -= uiDiff; }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_kelerun_bloodmourn(Creature* pCreature)
|
||||
{
|
||||
return new npc_kelerun_bloodmournAI(pCreature);
|
||||
}
|
||||
|
||||
// easiest way is to expect database to respawn GO at quest accept (quest_start_script)
|
||||
bool QuestAccept_npc_kelerun_bloodmourn(Player* /*pPlayer*/, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_SECOND_TRIAL)
|
||||
{
|
||||
if (npc_kelerun_bloodmournAI* pKelrunAI = dynamic_cast<npc_kelerun_bloodmournAI*>(pCreature->AI()))
|
||||
{ pKelrunAI->StartEvent(); }
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GOUse_go_harbinger_second_trial(Player* pPlayer, GameObject* pGO)
|
||||
{
|
||||
if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
|
||||
{
|
||||
if (Creature* pCreature = GetClosestCreatureWithEntry(pGO, NPC_KELERUN, 30.0f))
|
||||
{
|
||||
if (npc_kelerun_bloodmournAI* pKelrunAI = dynamic_cast<npc_kelerun_bloodmournAI*>(pCreature->AI()))
|
||||
{ pKelrunAI->CanProgressEvent(pPlayer); }
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*######
|
||||
## npc_prospector_anvilward
|
||||
######*/
|
||||
enum
|
||||
{
|
||||
SAY_ANVIL1 = -1000209,
|
||||
SAY_ANVIL2 = -1000210,
|
||||
|
||||
GOSSIP_ITEM_MOMENT = -3000108,
|
||||
GOSSIP_ITEM_SHOW = -3000110,
|
||||
|
||||
GOSSIP_TEXT_ID_MOMENT = 8239,
|
||||
GOSSIP_TEXT_ID_SHOW = 8240,
|
||||
|
||||
FACTION_HOSTILE = 24,
|
||||
|
||||
QUEST_THE_DWARVEN_SPY = 8483
|
||||
};
|
||||
|
||||
struct npc_prospector_anvilwardAI : public npc_escortAI
|
||||
{
|
||||
// CreatureAI functions
|
||||
npc_prospector_anvilwardAI(Creature* pCreature) : npc_escortAI(pCreature) {Reset();}
|
||||
|
||||
void Reset() override { }
|
||||
|
||||
// Pure Virtual Functions
|
||||
void WaypointReached(uint32 uiPointId) override
|
||||
{
|
||||
Player* pPlayer = GetPlayerForEscort();
|
||||
|
||||
if (!pPlayer)
|
||||
{ return; }
|
||||
|
||||
switch (uiPointId)
|
||||
{
|
||||
case 0:
|
||||
DoScriptText(SAY_ANVIL1, m_creature, pPlayer);
|
||||
break;
|
||||
case 5:
|
||||
DoScriptText(SAY_ANVIL2, m_creature, pPlayer);
|
||||
break;
|
||||
case 6:
|
||||
m_creature->SetFactionTemporary(FACTION_HOSTILE, TEMPFACTION_RESTORE_REACH_HOME | TEMPFACTION_RESTORE_RESPAWN);
|
||||
AttackStart(pPlayer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_prospector_anvilward(Creature* pCreature)
|
||||
{
|
||||
return new npc_prospector_anvilwardAI(pCreature);
|
||||
}
|
||||
|
||||
bool GossipHello_npc_prospector_anvilward(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(QUEST_THE_DWARVEN_SPY) == QUEST_STATUS_INCOMPLETE)
|
||||
{ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MOMENT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); }
|
||||
|
||||
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_ID_MOMENT, pCreature->GetObjectGuid());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GossipSelect_npc_prospector_anvilward(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
|
||||
{
|
||||
switch (uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SHOW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_ID_SHOW, pCreature->GetObjectGuid());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
|
||||
if (npc_prospector_anvilwardAI* pEscortAI = dynamic_cast<npc_prospector_anvilwardAI*>(pCreature->AI()))
|
||||
{ pEscortAI->Start(false, pPlayer); }
|
||||
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*######
|
||||
## npc_apprentice_mirveda
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
QUEST_UNEXPECTED_RESULT = 8488,
|
||||
|
||||
SPELL_FIREBALL = 20811,
|
||||
|
||||
NPC_GHARSUL = 15958,
|
||||
NPC_ANGERSHADE = 15656
|
||||
};
|
||||
|
||||
struct npc_apprentice_mirvedaAI : public ScriptedAI
|
||||
{
|
||||
npc_apprentice_mirvedaAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
|
||||
|
||||
uint8 m_uiMobCount;
|
||||
uint32 m_uiFireballTimer;
|
||||
ObjectGuid m_playerGuid;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiMobCount = 0;
|
||||
m_playerGuid.Clear();
|
||||
m_uiFireballTimer = 0;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/) override
|
||||
{
|
||||
Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid);
|
||||
|
||||
if (pPlayer && pPlayer->GetQuestStatus(QUEST_UNEXPECTED_RESULT) == QUEST_STATUS_INCOMPLETE)
|
||||
{ pPlayer->SendQuestFailed(QUEST_UNEXPECTED_RESULT); }
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
pSummoned->AI()->AttackStart(m_creature);
|
||||
++m_uiMobCount;
|
||||
}
|
||||
|
||||
void SummonedCreatureJustDied(Creature* /*pKilled*/) override
|
||||
{
|
||||
--m_uiMobCount;
|
||||
|
||||
if (m_uiMobCount)
|
||||
{ return; }
|
||||
|
||||
Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid);
|
||||
|
||||
if (pPlayer && pPlayer->GetQuestStatus(QUEST_UNEXPECTED_RESULT) == QUEST_STATUS_INCOMPLETE)
|
||||
{ pPlayer->GroupEventHappens(QUEST_UNEXPECTED_RESULT, m_creature); }
|
||||
|
||||
m_playerGuid.Clear();
|
||||
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
}
|
||||
|
||||
void StartEvent(Player* pPlayer)
|
||||
{
|
||||
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
m_playerGuid = pPlayer->GetObjectGuid();
|
||||
|
||||
m_creature->SummonCreature(NPC_GHARSUL, 8745.0f, -7134.32f, 35.22f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 4000);
|
||||
m_creature->SummonCreature(NPC_ANGERSHADE, 8745.0f, -7134.32f, 35.22f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 4000);
|
||||
m_creature->SummonCreature(NPC_ANGERSHADE, 8745.0f, -7134.32f, 35.22f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 4000);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
{ return; }
|
||||
|
||||
if (m_uiFireballTimer < uiDiff)
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FIREBALL) == CAST_OK)
|
||||
{ m_uiFireballTimer = urand(4000, 6000); }
|
||||
}
|
||||
else
|
||||
{ m_uiFireballTimer -= uiDiff; }
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool QuestAccept_unexpected_results(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_UNEXPECTED_RESULT)
|
||||
if (npc_apprentice_mirvedaAI* pMirvedaAI = dynamic_cast<npc_apprentice_mirvedaAI*>(pCreature->AI()))
|
||||
{ pMirvedaAI->StartEvent(pPlayer); }
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_npc_apprentice_mirvedaAI(Creature* pCreature)
|
||||
{
|
||||
return new npc_apprentice_mirvedaAI(pCreature);
|
||||
}
|
||||
|
||||
/*######
|
||||
## npc_infused_crystal
|
||||
######*/
|
||||
|
||||
enum
|
||||
{
|
||||
QUEST_POWERING_OUR_DEFENSES = 8490,
|
||||
SAY_DEFENSE_FINISH = -1000668,
|
||||
NPC_ENRAGED_WRAITH = 17086,
|
||||
};
|
||||
|
||||
static const float aSummonPos[6][4] =
|
||||
{
|
||||
{8250.539f, -7239.028f, 139.7099f, 0.8975816f},
|
||||
{8263.437f, -7181.188f, 139.4102f, 5.237229f},
|
||||
{8317.124f, -7210.098f, 140.1064f, 3.022202f},
|
||||
{8293.848f, -7179.062f, 138.6693f, 4.153376f},
|
||||
{8239.229f, -7207.673f, 139.1196f, 0.06059111f},
|
||||
{8301.548f, -7247.548f, 139.974f, 1.828518f}
|
||||
};
|
||||
|
||||
struct npc_infused_crystalAI : public Scripted_NoMovementAI
|
||||
{
|
||||
npc_infused_crystalAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
|
||||
{
|
||||
m_bFirstWave = true;
|
||||
m_uiWaveTimer = 1000;
|
||||
m_uiKilledCount = 0;
|
||||
m_uiFinishTimer = 60 * IN_MILLISECONDS;
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool m_bFirstWave;
|
||||
uint32 m_uiWaveTimer;
|
||||
uint8 m_uiKilledCount;
|
||||
uint32 m_uiFinishTimer;
|
||||
|
||||
void Reset() override {}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
{
|
||||
pSummoned->AI()->AttackStart(m_creature);
|
||||
}
|
||||
|
||||
void SummonedCreatureJustDied(Creature* /*pSummoned*/) override
|
||||
{
|
||||
++m_uiKilledCount;
|
||||
|
||||
if (m_uiKilledCount == 3)
|
||||
{ m_uiWaveTimer = std::min(m_uiWaveTimer, (uint32)10000); }
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (m_uiWaveTimer)
|
||||
{
|
||||
if (m_uiWaveTimer <= uiDiff)
|
||||
{
|
||||
if (m_bFirstWave)
|
||||
{
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{ m_creature->SummonCreature(NPC_ENRAGED_WRAITH, aSummonPos[i][0], aSummonPos[i][1], aSummonPos[i][2], aSummonPos[i][3], TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 5 * MINUTE); }
|
||||
m_uiWaveTimer = 29000;
|
||||
m_bFirstWave = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8 i = 3; i < 6; ++i)
|
||||
{ m_creature->SummonCreature(NPC_ENRAGED_WRAITH, aSummonPos[i][0], aSummonPos[i][1], aSummonPos[i][2], aSummonPos[i][3], TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 5 * MINUTE); }
|
||||
m_uiWaveTimer = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ m_uiWaveTimer -= uiDiff; }
|
||||
}
|
||||
|
||||
if (m_uiFinishTimer)
|
||||
{
|
||||
if (m_uiFinishTimer <= uiDiff)
|
||||
{
|
||||
DoScriptText(SAY_DEFENSE_FINISH, m_creature);
|
||||
if (m_creature->IsTemporarySummon())
|
||||
{
|
||||
TemporarySummon* pTemporary = (TemporarySummon*)m_creature;
|
||||
|
||||
if (Player* pPlayer = m_creature->GetMap()->GetPlayer(pTemporary->GetSummonerGuid()))
|
||||
{ pPlayer->KilledMonsterCredit(m_creature->GetEntry(), m_creature->GetObjectGuid()); }
|
||||
}
|
||||
m_uiFinishTimer = 0;
|
||||
m_creature->ForcedDespawn(1000);
|
||||
}
|
||||
else
|
||||
{ m_uiFinishTimer -= uiDiff; }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_infused_crystalAI(Creature* pCreature)
|
||||
{
|
||||
return new npc_infused_crystalAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_eversong_woods()
|
||||
{
|
||||
Script* pNewScript;
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_kelerun_bloodmourn";
|
||||
pNewScript->GetAI = &GetAI_npc_kelerun_bloodmourn;
|
||||
pNewScript->pQuestAcceptNPC = &QuestAccept_npc_kelerun_bloodmourn;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "go_harbinger_second_trial";
|
||||
pNewScript->pGOUse = &GOUse_go_harbinger_second_trial;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_prospector_anvilward";
|
||||
pNewScript->GetAI = &GetAI_npc_prospector_anvilward;
|
||||
pNewScript->pGossipHello = &GossipHello_npc_prospector_anvilward;
|
||||
pNewScript->pGossipSelect = &GossipSelect_npc_prospector_anvilward;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_apprentice_mirveda";
|
||||
pNewScript->GetAI = &GetAI_npc_apprentice_mirvedaAI;
|
||||
pNewScript->pQuestAcceptNPC = &QuestAccept_unexpected_results;
|
||||
pNewScript->RegisterSelf();
|
||||
|
||||
pNewScript = new Script;
|
||||
pNewScript->Name = "npc_infused_crystal";
|
||||
pNewScript->GetAI = &GetAI_npc_infused_crystalAI;
|
||||
pNewScript->RegisterSelf();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue