Dropped the new SD2 Module in

This commit is contained in:
Antz 2015-01-20 22:15:07 +00:00 committed by Antz
parent 5260602e28
commit 1ed51d35e9
650 changed files with 183227 additions and 0 deletions

View 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>

File diff suppressed because it is too large Load diff

View 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
View 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.

View 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

View 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

View 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);
}
}

View 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

View 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);
}
}
}

View 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

View 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);
}
}

View 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

View 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);
}
}
}

View 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

View 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

View 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"

View 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/

View 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);`.

View 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

View 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"

View 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

View 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);
}
}

View 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

View 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

View 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);
}

View 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

View 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;
}
}
}

View 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

View 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();
}

View 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: Alterac_Mountains
* SD%Complete: 0
* SDComment: Placeholder
* SDCategory: Alterac Mountains
* EndScriptData
*/
/**
* ContentData
* EndContentData
*/
#include "precompiled.h"
void AddSC_alterac_mountains()
{
}

View 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();
}

View file

@ -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()
{
}

View file

@ -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 */

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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 */

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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()
{
}

View file

@ -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

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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()
{
}

View file

@ -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

View 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();
}

View 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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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

View file

@ -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();
}

View 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()
{
}

View 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();
}

View 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();
}

View 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