diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..9fa544d91 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,16 @@ +# Lineendings +*.sln eol=crlf +*.vcproj eol=crlf +*.vcxproj* eol=crlf + +# Whitespace rules +# strict (no trailing, no tabs) +*.cpp whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol +*.h whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol + +# normal (no trailing) +*.sql whitespace=trailing-space,space-before-tab,cr-at-eol +*.txt whitespace=trailing-space,space-before-tab,cr-at-eol + +# special files which must ignore whitespace +*.patch whitespace=-trailing-space diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..1d1ea0d3c --- /dev/null +++ b/.gitignore @@ -0,0 +1,109 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# NOTE! Please use 'git-ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# +# Normal rules +# +.* +*.o +*.o.* +*.a +*.so +*.so.dbg +*.bin +*.gz + +# +# Top-level generic files +# +tags +TAGS +INSTALL + +!.gitignore +!.gitattributes + +# +# Build generated files +# +aclocal.m4 +autom4te.cache +compile +config.guess +config.h.in +config.log +config.status +config.sub +configure +depcomp +libtool +install-sh +ltmain.sh +missing +stamp-h1 + +Makefile.in +Makefile + +# +# Editors / debuggers / other output files +# +*~ +*.bak +*.orig +callgrind.out.* + +# +# Git stuff +# +# stgit directories +patches-* + +# +# System-internal temporary files +# +revision.h + +# +# VS binaries output +# +bin/* + +# +# VS temporary files +# +*.ncb +*.suo +*.sdf +*.opensdf +*.sln.cache +*.vsp +ipch +*.user + +*__Win32_Debug* +*__x64_Debug* +*__Win32_Release* +*__x64_Release* + +# +# CMake temporary files +# +CMakeFiles +CMakeCache.txt +cmake_install.cmake + +# +# OS specific +# +# MacOS +.DS_Store + +# +# Special exceptions +# diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..7f54011c8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,143 @@ +# +# Copyright (C) 2005-2011 MaNGOS +# +# 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 +# + +## magic to include revision data in SD2 version string +# revision.h: FORCE +# $(top_builddir)/src/tools/genrevision/genrevision $(srcdir) + +file(GLOB_RECURSE mangosscript_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h) + +source_group("Other" + REGULAR_EXPRESSION .* +) + +foreach(SRC ${mangosscript_SRCS}) + get_filename_component(PTH ${SRC} PATH) + if(PTH) + if(NOT XCODE) # FIXME: Xcode Generator has bug with nested dirs + string(REPLACE "/" "\\\\" PTH ${PTH}) + endif() + source_group(${PTH} FILES ${SRC}) + endif() +endforeach(SRC) + +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 + ${CMAKE_SOURCE_DIR}/dep/include + ${CMAKE_BINARY_DIR} + ${ACE_INCLUDE_DIR} + ${MYSQL_INCLUDE_DIR} +) + +if(PCH) + include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ) +endif() + +add_library(mangosscript SHARED + ${mangosscript_SRCS} +) + +if(WIN32) + target_link_libraries(mangosscript + mangosd # FIXME: could this be done for unix? because unix won't generate exe.libs + ${ACE_LIBRARIES} + debug ${WIN_DEBUGLIBS} + ) +endif() + +add_dependencies(mangosscript revision.h) +if(NOT ACE_USE_EXTERNAL) + add_dependencies(mangosscript ACE_Project) +# 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() + +# Because size for linker is to big - seriously ?! +if(WIN32) + set_target_properties(mangosscript PROPERTIES + LINK_FLAGS_DEBUG "/DEBUG /INCREMENTAL:NO" + ) +endif() + +## libtool settings +# API versioning +# Link against dependencies +# How to increase version info: +# - only bug fixes implemented: +# bump the version to LTMANGOS_CURRENT:LTMANGOS_REVISION+1:LTMANGOS_AGE +# - augmented the interface: +# bump the version to LTMANGOS_CURRENT+1:0:LTMANGOS_AGE+1 +# - broken old interface: +# bump the version to LTMANGOS_CURRENT+1:0:0 +# set(LTMANGOS_CURRENT 0) +# set(LTMANGOS_REVISION 0) +# set(LTMANGOS_AGE 0) +# set_target_properties(script PROPERTIES LINK_FLAGS +# "-version-info ${LTMANGOS_CURRENT}:${LTMANGOS_REVISION}:${LTMANGOS_AGE}" +# ) + +# Generate precompiled header +if(PCH) + if(MSVC OR XCODE) + if(MSVC) + set(mangosscript_pch "${CMAKE_CURRENT_SOURCE_DIR}/include/precompiled.cpp") + endif() + add_native_precompiled_header(mangosscript ${CMAKE_CURRENT_SOURCE_DIR}/include/precompiled.h) + elseif(CMAKE_COMPILER_IS_GNUCXX) + add_precompiled_header(mangosscript ${CMAKE_CURRENT_SOURCE_DIR}/include/precompiled.h) + endif() +endif() + +# LIBRARY = dyld / so, RUNTIME = dll +install(TARGETS mangosscript + LIBRARY DESTINATION ${LIBS_DIR} + RUNTIME DESTINATION ${LIBS_DIR} +) + +install(FILES scriptdev2.conf.dist.in DESTINATION ${CONF_DIR} RENAME scriptdev2.conf.dist) diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 5067f6620..000000000 --- a/Makefile.am +++ /dev/null @@ -1,613 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# 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 -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse -SUBDIRS = sql - -BUILT_SOURCES = revision.h -CLEANFILES = revision.h -## CPP flags for includes, defines, etc. -AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../shared/ -I$(srcdir)/../../framework/ -I$(srcdir)/../../game/ -I$(srcdir)/include/ -I$(srcdir)/base/ -DSYSCONFDIR=\"$(sysconfdir)/\" - -## Build MaNGOS script library as shared library. -# libmangosscript shared library will later be reused by world server daemon. -lib_LTLIBRARIES = libmangosscript.la -libmangosscript_la_SOURCES = \ -ScriptMgr.cpp \ -ScriptMgr.h \ -config.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 \ -include/precompiled.cpp \ -include/precompiled.h \ -include/sc_creature.cpp \ -include/sc_creature.h \ -include/sc_gossip.h \ -include/sc_grid_searchers.cpp \ -include/sc_grid_searchers.h \ -include/sc_instance.cpp \ -include/sc_instance.h \ -scripts/battlegrounds/battleground.cpp \ -scripts/eastern_kingdoms/alterac_mountains.cpp \ -scripts/eastern_kingdoms/arathi_highlands.cpp \ -scripts/eastern_kingdoms/blasted_lands.cpp \ -scripts/eastern_kingdoms/boss_kruul.cpp \ -scripts/eastern_kingdoms/burning_steppes.cpp \ -scripts/eastern_kingdoms/dun_morogh.cpp \ -scripts/eastern_kingdoms/eastern_plaguelands.cpp \ -scripts/eastern_kingdoms/elwynn_forest.cpp \ -scripts/eastern_kingdoms/eversong_woods.cpp \ -scripts/eastern_kingdoms/ghostlands.cpp \ -scripts/eastern_kingdoms/hinterlands.cpp \ -scripts/eastern_kingdoms/ironforge.cpp \ -scripts/eastern_kingdoms/isle_of_queldanas.cpp \ -scripts/eastern_kingdoms/loch_modan.cpp \ -scripts/eastern_kingdoms/redridge_mountains.cpp \ -scripts/eastern_kingdoms/searing_gorge.cpp \ -scripts/eastern_kingdoms/silvermoon_city.cpp \ -scripts/eastern_kingdoms/silverpine_forest.cpp \ -scripts/eastern_kingdoms/stormwind_city.cpp \ -scripts/eastern_kingdoms/stranglethorn_vale.cpp \ -scripts/eastern_kingdoms/swamp_of_sorrows.cpp \ -scripts/eastern_kingdoms/tirisfal_glades.cpp \ -scripts/eastern_kingdoms/undercity.cpp \ -scripts/eastern_kingdoms/western_plaguelands.cpp \ -scripts/eastern_kingdoms/westfall.cpp \ -scripts/eastern_kingdoms/wetlands.cpp \ -scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp \ -scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h \ -scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp \ -scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp \ -scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp \ -scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h \ -scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp \ -scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp \ -scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp \ -scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp \ -scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp \ -scripts/eastern_kingdoms/deadmines/deadmines.cpp \ -scripts/eastern_kingdoms/deadmines/deadmines.h \ -scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp \ -scripts/eastern_kingdoms/gnomeregan/boss_thermaplugg.cpp \ -scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp \ -scripts/eastern_kingdoms/gnomeregan/gnomeregan.h \ -scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp \ -scripts/eastern_kingdoms/karazhan/boss_curator.cpp \ -scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp \ -scripts/eastern_kingdoms/karazhan/boss_midnight.cpp \ -scripts/eastern_kingdoms/karazhan/boss_moroes.cpp \ -scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp \ -scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp \ -scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp \ -scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp \ -scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp \ -scripts/eastern_kingdoms/karazhan/bosses_opera.cpp \ -scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp \ -scripts/eastern_kingdoms/karazhan/karazhan.cpp \ -scripts/eastern_kingdoms/karazhan/karazhan.h \ -scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp \ -scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp \ -scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp \ -scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp \ -scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp \ -scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp \ -scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h \ -scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp \ -scripts/eastern_kingdoms/molten_core/boss_garr.cpp \ -scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp \ -scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp \ -scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp \ -scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp \ -scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp \ -scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp \ -scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp \ -scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp \ -scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp \ -scripts/eastern_kingdoms/molten_core/molten_core.cpp \ -scripts/eastern_kingdoms/molten_core/molten_core.h \ -scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp \ -scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h \ -scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp \ -scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp \ -scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp \ -scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp \ -scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp \ -scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp \ -scripts/eastern_kingdoms/scholomance/boss_kormok.cpp \ -scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp \ -scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp \ -scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp \ -scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp \ -scripts/eastern_kingdoms/scholomance/boss_vectus.cpp \ -scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp \ -scripts/eastern_kingdoms/scholomance/scholomance.h \ -scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp \ -scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp \ -scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h \ -scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp \ -scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp \ -scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp \ -scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp \ -scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp \ -scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp \ -scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp \ -scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp \ -scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp \ -scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp \ -scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp \ -scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp \ -scripts/eastern_kingdoms/stratholme/stratholme.cpp \ -scripts/eastern_kingdoms/stratholme/stratholme.h \ -scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp \ -scripts/eastern_kingdoms/sunken_temple/sunken_temple.h \ -scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h \ -scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp \ -scripts/eastern_kingdoms/uldaman/uldaman.cpp \ -scripts/eastern_kingdoms/uldaman/uldaman.h \ -scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp \ -scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp \ -scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp \ -scripts/eastern_kingdoms/zulaman/boss_janalai.cpp \ -scripts/eastern_kingdoms/zulaman/boss_malacrass.cpp \ -scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp \ -scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp \ -scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp \ -scripts/eastern_kingdoms/zulaman/zulaman.cpp \ -scripts/eastern_kingdoms/zulaman/zulaman.h \ -scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_marli.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp \ -scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp \ -scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp \ -scripts/eastern_kingdoms/zulgurub/zulgurub.h \ -scripts/examples/example_creature.cpp \ -scripts/examples/example_escort.cpp \ -scripts/examples/example_gossip_codebox.cpp \ -scripts/examples/example_misc.cpp \ -scripts/kalimdor/ashenvale.cpp \ -scripts/kalimdor/azshara.cpp \ -scripts/kalimdor/azuremyst_isle.cpp \ -scripts/kalimdor/bloodmyst_isle.cpp \ -scripts/kalimdor/boss_azuregos.cpp \ -scripts/kalimdor/darkshore.cpp \ -scripts/kalimdor/desolace.cpp \ -scripts/kalimdor/dustwallow_marsh.cpp \ -scripts/kalimdor/felwood.cpp \ -scripts/kalimdor/feralas.cpp \ -scripts/kalimdor/moonglade.cpp \ -scripts/kalimdor/mulgore.cpp \ -scripts/kalimdor/orgrimmar.cpp \ -scripts/kalimdor/silithus.cpp \ -scripts/kalimdor/stonetalon_mountains.cpp \ -scripts/kalimdor/tanaris.cpp \ -scripts/kalimdor/teldrassil.cpp \ -scripts/kalimdor/the_barrens.cpp \ -scripts/kalimdor/thousand_needles.cpp \ -scripts/kalimdor/thunder_bluff.cpp \ -scripts/kalimdor/ungoro_crater.cpp \ -scripts/kalimdor/winterspring.cpp \ -scripts/kalimdor/blackfathom_deeps/blackfathom_deeps.h \ -scripts/kalimdor/blackfathom_deeps/instance_blackfathom_deeps.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp \ -scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp \ -scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp \ -scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp \ -scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp \ -scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h \ -scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp \ -scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp \ -scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp \ -scripts/kalimdor/caverns_of_time/hyjal/hyjal.h \ -scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp \ -scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h \ -scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp \ -scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp \ -scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp \ -scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp \ -scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp \ -scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp \ -scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h \ -scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp \ -scripts/kalimdor/maraudon/boss_landslide.cpp \ -scripts/kalimdor/maraudon/boss_noxxion.cpp \ -scripts/kalimdor/maraudon/boss_princess_theradras.cpp \ -scripts/kalimdor/onyxias_lair/boss_onyxia.cpp \ -scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp \ -scripts/kalimdor/onyxias_lair/onyxias_lair.h \ -scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp \ -scripts/kalimdor/razorfen_downs/razorfen_downs.cpp \ -scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp \ -scripts/kalimdor/razorfen_kraul/razorfen_kraul.h \ -scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp \ -scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h \ -scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp \ -scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h \ -scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp \ -scripts/kalimdor/wailing_caverns/wailing_caverns.h \ -scripts/kalimdor/zulfarrak/boss_zumrah.cpp \ -scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp \ -scripts/kalimdor/zulfarrak/zulfarrak.cpp \ -scripts/kalimdor/zulfarrak/zulfarrak.h \ -scripts/northrend/borean_tundra.cpp \ -scripts/northrend/dalaran.cpp \ -scripts/northrend/dragonblight.cpp \ -scripts/northrend/grizzly_hills.cpp \ -scripts/northrend/icecrown.cpp \ -scripts/northrend/sholazar_basin.cpp \ -scripts/northrend/storm_peaks.cpp \ -scripts/northrend/howling_fjord.cpp \ -scripts/northrend/zuldrak.cpp \ -scripts/northrend/azjol-nerub/ahnkahet/boss_jedoga.cpp \ -scripts/northrend/azjol-nerub/ahnkahet/boss_nadox.cpp \ -scripts/northrend/azjol-nerub/ahnkahet/boss_taldaram.cpp \ -scripts/northrend/azjol-nerub/ahnkahet/boss_volazj.cpp \ -scripts/northrend/azjol-nerub/ahnkahet/ahnkahet.h \ -scripts/northrend/azjol-nerub/ahnkahet/instance_ahnkahet.cpp \ -scripts/northrend/azjol-nerub/azjol-nerub/azjol-nerub.h \ -scripts/northrend/azjol-nerub/azjol-nerub/boss_anubarak.cpp \ -scripts/northrend/azjol-nerub/azjol-nerub/boss_hadronox.cpp \ -scripts/northrend/azjol-nerub/azjol-nerub/boss_krikthir.cpp \ -scripts/northrend/azjol-nerub/azjol-nerub/instance_azjol-nerub.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h \ -scripts/northrend/draktharon_keep/boss_novos.cpp \ -scripts/northrend/draktharon_keep/boss_tharonja.cpp \ -scripts/northrend/draktharon_keep/boss_trollgore.cpp \ -scripts/northrend/draktharon_keep/draktharon_keep.h \ -scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp \ -scripts/northrend/gundrak/boss_colossus.cpp \ -scripts/northrend/gundrak/boss_eck.cpp \ -scripts/northrend/gundrak/boss_galdarah.cpp \ -scripts/northrend/gundrak/boss_moorabi.cpp \ -scripts/northrend/gundrak/boss_sladran.cpp \ -scripts/northrend/gundrak/gundrak.h \ -scripts/northrend/gundrak/instance_gundrak.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falryn.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_krick_and_ick.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.h \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_bronjahm.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.h \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp \ -scripts/northrend/naxxramas/boss_anubrekhan.cpp \ -scripts/northrend/naxxramas/boss_faerlina.cpp \ -scripts/northrend/naxxramas/boss_four_horsemen.cpp \ -scripts/northrend/naxxramas/boss_gluth.cpp \ -scripts/northrend/naxxramas/boss_gothik.cpp \ -scripts/northrend/naxxramas/boss_grobbulus.cpp \ -scripts/northrend/naxxramas/boss_heigan.cpp \ -scripts/northrend/naxxramas/boss_kelthuzad.cpp \ -scripts/northrend/naxxramas/boss_loatheb.cpp \ -scripts/northrend/naxxramas/boss_maexxna.cpp \ -scripts/northrend/naxxramas/boss_noth.cpp \ -scripts/northrend/naxxramas/boss_patchwerk.cpp \ -scripts/northrend/naxxramas/boss_razuvious.cpp \ -scripts/northrend/naxxramas/boss_sapphiron.cpp \ -scripts/northrend/naxxramas/boss_thaddius.cpp \ -scripts/northrend/naxxramas/naxxramas.h \ -scripts/northrend/naxxramas/instance_naxxramas.cpp \ -scripts/northrend/nexus/nexus/boss_anomalus.cpp \ -scripts/northrend/nexus/nexus/boss_keristrasza.cpp \ -scripts/northrend/nexus/nexus/boss_ormorok.cpp \ -scripts/northrend/nexus/nexus/boss_telestra.cpp \ -scripts/northrend/nexus/nexus/nexus.h \ -scripts/northrend/nexus/nexus/instance_nexus.cpp \ -scripts/northrend/obsidian_sanctum/boss_sartharion.cpp \ -scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp \ -scripts/northrend/obsidian_sanctum/obsidian_sanctum.h \ -scripts/northrend/ruby_sanctum/boss_halion.cpp \ -scripts/northrend/ruby_sanctum/boss_baltharus.cpp \ -scripts/northrend/ruby_sanctum/boss_saviana.cpp \ -scripts/northrend/ruby_sanctum/boss_zarithian.cpp \ -scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp \ -scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp \ -scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp \ -scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp \ -scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h \ -scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp \ -scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp \ -scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp \ -scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp \ -scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h \ -scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp \ -scripts/northrend/ulduar/ulduar/assembly_of_iron.cpp \ -scripts/northrend/ulduar/ulduar/boss_algalon.cpp \ -scripts/northrend/ulduar/ulduar/boss_auriaya.cpp \ -scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp \ -scripts/northrend/ulduar/ulduar/boss_freya.cpp \ -scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp \ -scripts/northrend/ulduar/ulduar/boss_hodir.cpp \ -scripts/northrend/ulduar/ulduar/boss_ignis.cpp \ -scripts/northrend/ulduar/ulduar/boss_kologarn.cpp \ -scripts/northrend/ulduar/ulduar/boss_mimiron.cpp \ -scripts/northrend/ulduar/ulduar/boss_razorscale.cpp \ -scripts/northrend/ulduar/ulduar/boss_thorim.cpp \ -scripts/northrend/ulduar/ulduar/boss_xt_002.cpp \ -scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp \ -scripts/northrend/ulduar/ulduar/instance_ulduar.cpp \ -scripts/northrend/ulduar/ulduar/ulduar.cpp \ -scripts/northrend/ulduar/ulduar/ulduar.h \ -scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar.cpp \ -scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp \ -scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_and_dalronn.cpp \ -scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp \ -scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp \ -scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h \ -scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_gortok.cpp \ -scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp \ -scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp \ -scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp \ -scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_utgarde_pinnacle.cpp \ -scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h \ -scripts/northrend/violet_hold/instance_violet_hold.cpp \ -scripts/northrend/violet_hold/violet_hold.cpp \ -scripts/northrend/violet_hold/violet_hold.h \ -scripts/outland/blades_edge_mountains.cpp \ -scripts/outland/boss_doomlord_kazzak.cpp \ -scripts/outland/boss_doomwalker.cpp \ -scripts/outland/hellfire_peninsula.cpp \ -scripts/outland/nagrand.cpp \ -scripts/outland/netherstorm.cpp \ -scripts/outland/shadowmoon_valley.cpp \ -scripts/outland/shattrath_city.cpp \ -scripts/outland/terokkar_forest.cpp \ -scripts/outland/zangarmarsh.cpp \ -scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp \ -scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp \ -scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp \ -scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp \ -scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp \ -scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp \ -scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h \ -scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp \ -scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp \ -scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp \ -scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp \ -scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp \ -scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h \ -scripts/outland/black_temple/black_temple.cpp \ -scripts/outland/black_temple/black_temple.h \ -scripts/outland/black_temple/boss_bloodboil.cpp \ -scripts/outland/black_temple/boss_illidan.cpp \ -scripts/outland/black_temple/boss_mother_shahraz.cpp \ -scripts/outland/black_temple/boss_reliquary_of_souls.cpp \ -scripts/outland/black_temple/boss_shade_of_akama.cpp \ -scripts/outland/black_temple/boss_supremus.cpp \ -scripts/outland/black_temple/boss_teron_gorefiend.cpp \ -scripts/outland/black_temple/boss_warlord_najentus.cpp \ -scripts/outland/black_temple/illidari_council.cpp \ -scripts/outland/black_temple/instance_black_temple.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/boss_hydross_the_unstable.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/boss_leotheras_the_blind.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/instance_serpent_shrine.cpp \ -scripts/outland/coilfang_reservoir/serpent_shrine/serpent_shrine.h \ -scripts/outland/coilfang_reservoir/steam_vault/boss_hydromancer_thespia.cpp \ -scripts/outland/coilfang_reservoir/steam_vault/boss_mekgineer_steamrigger.cpp \ -scripts/outland/coilfang_reservoir/steam_vault/boss_warlord_kalithresh.cpp \ -scripts/outland/coilfang_reservoir/steam_vault/instance_steam_vault.cpp \ -scripts/outland/coilfang_reservoir/steam_vault/steam_vault.h \ -scripts/outland/coilfang_reservoir/underbog/boss_hungarfen.cpp \ -scripts/outland/gruuls_lair/boss_gruul.cpp \ -scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp \ -scripts/outland/gruuls_lair/gruuls_lair.h \ -scripts/outland/gruuls_lair/instance_gruuls_lair.cpp \ -scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h \ -scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp \ -scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp \ -scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp \ -scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp \ -scripts/outland/hellfire_citadel/hellfire_ramparts/boss_nazan_and_vazruden.cpp \ -scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp \ -scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp \ -scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h \ -scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp \ -scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp \ -scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp \ -scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h \ -scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp \ -scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp \ -scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp \ -scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp \ -scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h \ -scripts/outland/tempest_keep/arcatraz/arcatraz.cpp \ -scripts/outland/tempest_keep/arcatraz/arcatraz.h \ -scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp \ -scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp \ -scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp \ -scripts/outland/tempest_keep/botanica/boss_laj.cpp \ -scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp \ -scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp \ -scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp \ -scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp \ -scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp \ -scripts/outland/tempest_keep/the_eye/the_eye.cpp \ -scripts/outland/tempest_keep/the_eye/the_eye.h \ -scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp \ -scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp \ -scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp \ -scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp \ -scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp \ -scripts/outland/tempest_keep/the_mechanar/mechanar.h \ -scripts/world/areatrigger_scripts.cpp \ -scripts/world/boss_emeriss.cpp \ -scripts/world/boss_lethon.cpp \ -scripts/world/boss_taerar.cpp \ -scripts/world/boss_ysondre.cpp \ -scripts/world/go_scripts.cpp \ -scripts/world/guards.cpp \ -scripts/world/item_scripts.cpp \ -scripts/world/mob_generic_creature.cpp \ -scripts/world/npc_professions.cpp \ -scripts/world/npcs_special.cpp \ -scripts/world/spell_scripts.cpp \ -system/ScriptLoader.cpp \ -system/ScriptLoader.h \ -system/system.cpp \ -system/system.h \ -revision.h - - -## magic to include revision data in SD2 version string -revision.h: FORCE - $(top_builddir)/src/tools/genrevision/genrevision $(srcdir) - -FORCE: - -## libtool settings -# API versioning -# Link against dependencies -# How to increase version info: -# - only bug fixes implemented: -# bump the version to LTMANGOS_CURRENT:LTMANGOS_REVISION+1:LTMANGOS_AGE -# - augmented the interface: -# bump the version to LTMANGOS_CURRENT+1:0:LTMANGOS_AGE+1 -# - broken old interface: -# bump the version to LTMANGOS_CURRENT+1:0:0 -LTMANGOS_CURRENT = 0 -LTMANGOS_REVISION = 0 -LTMANGOS_AGE = 0 -libmangosscript_la_LIBFLAGS = -version-info $(LTMANGOS_CURRENT):$(LTMANGOS_REVISION):$(LTMANGOS_AGE) - -## Additional files to include when running 'make dist' -# Scripts defaults. -EXTRA_DIST = \ - Scripts/sc_default.cpp \ - Scripts/sc_defines.cpp \ - Scripts/sc_defines.h \ - scriptdev2.conf.dist - -## Additional files to install -sysconf_DATA = \ - scriptdev2.conf.dist - -install-data-hook: - @list='$(sysconf_DATA)'; for p in $$list; do \ - dest=`echo $$p | sed -e s/.dist//`; \ - if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \ - echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \ - else \ - echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \ - $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \ - fi; \ - done - -clean-local: - rm -f $(sysconf_DATA) diff --git a/README b/README new file mode 100644 index 000000000..f8b028460 --- /dev/null +++ b/README @@ -0,0 +1,111 @@ +@package RSA scripts for ScriptDev2 +@version 0.4a +@revision (current) +@copyright (c) 2009-2011 /dev/rsa +@license GNU Public License + +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 + +Attention please! My project now support only Cmake-way compilation! +No special VC configs provided. + +In this repository you found this custom scripts: + +- many scripts from Insider42 +- Ulduar (from Xfurry, partially rewrite by me) +- Trial of the Champion (by Syntec, big rewrite by me) +- Violet hold (by ckegg, big rewrite by me) +- Ahn'kahet (renewed, by Tassadar with my corrects) +- Draktaron (by Tassadar) +- Culling of Stratholme (by MaxXx2021 AKA Mioka) +- Obsidian Sanctum (by MaxXx2021) +- Azjol-Nerub (by MaxXx2021) +- Forge of souls (by Maxxx2021 and me) +- Halls of reflection (by Maxxx2021 and me) +- Vault of Archavon (by Insider42) +- Trial of the Crusader (by me) +- Icecrown Citadel (by me) +- Ruby Sanctum (by me, partially from notagain) +- npc_arena_honor by tempura +- NPC special (partially by me, thanks for all) +- Eye of Acherus quest (from traponinet and me) +- Light of Down (basic by ckegg, big rewrite by all) +- Oculus (originally from TC with MaxXx2021 and my modifications) +- Eye of Ethernity (originally from Tassadar with PSZ and my modifications) +- simple scripts from Xfurry + +Thanks to: +- Vladimir Mangos - MaNGOS project; +- Insider42 - for your work; +- MaxXx2021 aka Mioka - for your scripts; +- Tassadar; +- notagain - base placeholders and spell research for Ruby sanctum; +- griffonheart (original texts/sounds for TOC); +- Cristy (re-translation to english); +- Selector - Faction champions base script, testing, bugreports; +- Boxa - changes for Windows compilers and bugreports; +- Wowka321 - core support; +- Dron01, Lordronn, Vinolentus - bugreports and valuable advice; +- gladden, ghostart - bugreports; +- Xfurry - Ulduar instance, simple scripts +- Schmoozerd - instances, scrips code +- all - testing. + +Ladies and gentlemen, and friends! If you want to compile my scripts with a compiler different from the GNU C, then the config files, projects or whatever else you need to create your own! I do only Makefile. +And please do not send me a compilation error. So what lies in my repository, absolute accuracy compiles fine and works on live servers. + +Уважаемые дамы и господа, а также товарищи! Если Вы хотите скомпилировать мои скрипты с помощью компилятора, отличного от GNU C, то конфиг-файлы, проекты или что там еще Вам придется создавать самостоятельно! Я делаю только Makefile. +И пожалуйста, не присылайте мне ошибки компиляции. То что лежит в моем репозитории, абсолютно точно компилируется нормально и работает на живых серверах. + +== ScriptDev2 README == + + Copyright (C) 2006 - 2011 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 ( http://www.getmangos.com ), 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. diff --git a/ScriptMgr.cpp b/ScriptMgr.cpp index 5a01c7c23..5a6f84022 100644 --- a/ScriptMgr.cpp +++ b/ScriptMgr.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -11,16 +11,25 @@ #include "ProgressBar.h" #include "../system/ScriptLoader.h" #include "../system/system.h" +#include "../../../game/ScriptMgr.h" int num_sc_scripts; Script *m_scripts[MAX_SCRIPTS]; Config SD2Config; +QueryResult* strSD2Pquery(char* str) +{ +return SD2Database.Query(str); +} +// Not registered scripts storage +std::map m_scriptStorage; + void FillSpellSummary(); void LoadDatabase() { + std::string strSD2DBinfo = SD2Config.GetStringDefault("ScriptDev2DatabaseInfo", ""); if (strSD2DBinfo.empty()) @@ -47,8 +56,6 @@ void LoadDatabase() return; } - SD2Database.HaltDelayThread(); - } struct TSpellSummary { @@ -57,7 +64,7 @@ struct TSpellSummary { }extern *SpellSummary; MANGOS_DLL_EXPORT -void ScriptsFree() +void FreeScriptLibrary() { // Free Spell Summary delete []SpellSummary; @@ -66,11 +73,15 @@ void ScriptsFree() for(int i=0; i::iterator itr = m_scriptStorage.begin(); itr != m_scriptStorage.end(); ++itr) + delete itr->second; + num_sc_scripts = 0; + SD2Database.HaltDelayThread(); } MANGOS_DLL_EXPORT -void ScriptsInit() +void InitScriptLibrary() { //ScriptDev2 startup outstring_log(""); @@ -106,6 +117,8 @@ void ScriptsInit() for(int i=0; iuiType) { case CHAT_TYPE_SAY: - pSource->MonsterSay(iTextEntry, pData->uiLanguage, pTarget ? pTarget->GetGUID() : 0); + pSource->MonsterSay(iTextEntry, pData->uiLanguage, pTarget); break; case CHAT_TYPE_YELL: - pSource->MonsterYell(iTextEntry, pData->uiLanguage, pTarget ? pTarget->GetGUID() : 0); + pSource->MonsterYell(iTextEntry, pData->uiLanguage, pTarget); break; case CHAT_TYPE_TEXT_EMOTE: - pSource->MonsterTextEmote(iTextEntry, pTarget ? pTarget->GetGUID() : 0); + pSource->MonsterTextEmote(iTextEntry, pTarget); break; case CHAT_TYPE_BOSS_EMOTE: - pSource->MonsterTextEmote(iTextEntry, pTarget ? pTarget->GetGUID() : 0, true); + pSource->MonsterTextEmote(iTextEntry, pTarget, true); break; case CHAT_TYPE_WHISPER: { if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) - pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID()); + pSource->MonsterWhisper(iTextEntry, pTarget); else error_log("SD2: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry); @@ -187,14 +200,14 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget) case CHAT_TYPE_BOSS_WHISPER: { if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) - pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID(), true); + pSource->MonsterWhisper(iTextEntry, pTarget, true); else error_log("SD2: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry); break; } case CHAT_TYPE_ZONE_YELL: - pSource->MonsterYellToZone(iTextEntry, pData->uiLanguage, pTarget ? pTarget->GetGUID() : 0); + pSource->MonsterYellToZone(iTextEntry, pData->uiLanguage, pTarget); break; } } @@ -213,9 +226,9 @@ void Script::RegisterSelf(bool bReportError) else { if (bReportError) - error_log("SD2: Script registering but ScriptName %s is not assigned in database. Script will not be used.", (this)->Name.c_str()); + error_log("SD2: Script registering but ScriptName %s is not assigned in database.", (this)->Name.c_str()); - delete this; + m_scriptStorage.insert(std::make_pair(Name.c_str(), this)); } } @@ -223,15 +236,9 @@ void Script::RegisterSelf(bool bReportError) //*** Functions to be Exported *** MANGOS_DLL_EXPORT -char const* ScriptsVersion() +char const* GetScriptLibraryVersion() { - if (!strSD2Version.empty()) - { - strSD2Version.append(_FULLVERSION); - return strSD2Version.c_str(); - } - - return _FULLVERSION; + return strSD2Version.c_str(); } MANGOS_DLL_EXPORT @@ -252,12 +259,12 @@ bool GOGossipHello(Player *pPlayer, GameObject *pGo) { Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pGOGossipHello) + if (!tmpscript || !tmpscript->pGossipHelloGO) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pGOGossipHello(pPlayer, pGo); + return tmpscript->pGossipHelloGO(pPlayer, pGo); } MANGOS_DLL_EXPORT @@ -270,7 +277,9 @@ bool GossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 if (!tmpscript || !tmpscript->pGossipSelect) return false; - pPlayer->PlayerTalkClass->ClearMenus(); +// pPlayer->PlayerTalkClass->ClearMenus(); +// this expression is wrong, where 'return false' from script's GossipSelect +// not return menu ID (cleared in this string) and not allow to work with database-based menus return tmpscript->pGossipSelect(pPlayer, pCreature, uiSender, uiAction); } @@ -282,12 +291,12 @@ bool GOGossipSelect(Player *pPlayer, GameObject *pGo, uint32 sender, uint32 acti Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pGOGossipSelect) + if (!tmpscript || !tmpscript->pGossipSelectGO) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pGOGossipSelect(pPlayer, pGo, sender, action); + return tmpscript->pGossipSelectGO(pPlayer, pGo, sender, action); } MANGOS_DLL_EXPORT @@ -312,12 +321,12 @@ bool GOGossipSelectWithCode(Player *pPlayer, GameObject *pGo, uint32 sender, uin Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pGOGossipSelectWithCode) + if (!tmpscript || !tmpscript->pGossipSelectGOWithCode) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pGOGossipSelectWithCode(pPlayer, pGo, sender, action, sCode); + return tmpscript->pGossipSelectGOWithCode(pPlayer, pGo, sender, action, sCode); } MANGOS_DLL_EXPORT @@ -325,114 +334,75 @@ bool QuestAccept(Player* pPlayer, Creature* pCreature, const Quest* pQuest) { Script *tmpscript = m_scripts[pCreature->GetScriptId()]; - if (!tmpscript || !tmpscript->pQuestAccept) - return false; - - pPlayer->PlayerTalkClass->ClearMenus(); - - return tmpscript->pQuestAccept(pPlayer, pCreature, pQuest); -} - -MANGOS_DLL_EXPORT -bool QuestSelect(Player* pPlayer, Creature* pCreature, const Quest* pQuest) -{ - Script *tmpscript = m_scripts[pCreature->GetScriptId()]; - - if (!tmpscript || !tmpscript->pQuestSelect) - return false; - - pPlayer->PlayerTalkClass->ClearMenus(); - - return tmpscript->pQuestSelect(pPlayer, pCreature, pQuest); -} - -MANGOS_DLL_EXPORT -bool QuestComplete(Player* pPlayer, Creature* pCreature, const Quest* pQuest) -{ - Script *tmpscript = m_scripts[pCreature->GetScriptId()]; - - if (!tmpscript || !tmpscript->pQuestComplete) + if (!tmpscript || !tmpscript->pQuestAcceptNPC) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pQuestComplete(pPlayer, pCreature, pQuest); + return tmpscript->pQuestAcceptNPC(pPlayer, pCreature, pQuest); } MANGOS_DLL_EXPORT -bool ChooseReward(Player* pPlayer, Creature* pCreature, const Quest* pQuest, uint32 opt) +bool QuestRewarded(Player* pPlayer, Creature* pCreature, Quest const* pQuest) { Script *tmpscript = m_scripts[pCreature->GetScriptId()]; - if (!tmpscript || !tmpscript->pChooseReward) + if (!tmpscript || !tmpscript->pQuestRewardedNPC) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pChooseReward(pPlayer, pCreature, pQuest, opt); + return tmpscript->pQuestRewardedNPC(pPlayer, pCreature, pQuest); } MANGOS_DLL_EXPORT -uint32 NPCDialogStatus(Player* pPlayer, Creature* pCreature) +uint32 GetNPCDialogStatus(Player* pPlayer, Creature* pCreature) { Script *tmpscript = m_scripts[pCreature->GetScriptId()]; - if (!tmpscript || !tmpscript->pNPCDialogStatus) + if (!tmpscript || !tmpscript->pDialogStatusNPC) return 100; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pNPCDialogStatus(pPlayer, pCreature); + return tmpscript->pDialogStatusNPC(pPlayer, pCreature); } MANGOS_DLL_EXPORT -uint32 GODialogStatus(Player* pPlayer, GameObject* pGo) +uint32 GetGODialogStatus(Player* pPlayer, GameObject* pGo) { Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pGODialogStatus) + if (!tmpscript || !tmpscript->pDialogStatusGO) return 100; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pGODialogStatus(pPlayer, pGo); -} - -MANGOS_DLL_EXPORT -bool ItemHello(Player* pPlayer, Item *_Item, const Quest* pQuest) -{ - Script *tmpscript = m_scripts[_Item->GetProto()->ScriptId]; - - if (!tmpscript || !tmpscript->pItemHello) - return false; - - pPlayer->PlayerTalkClass->ClearMenus(); - - return tmpscript->pItemHello(pPlayer,_Item, pQuest); + return tmpscript->pDialogStatusGO(pPlayer, pGo); } MANGOS_DLL_EXPORT -bool ItemQuestAccept(Player* pPlayer, Item *_Item, const Quest* pQuest) +bool ItemQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) { - Script *tmpscript = m_scripts[_Item->GetProto()->ScriptId]; + Script *tmpscript = m_scripts[pItem->GetProto()->ScriptId]; - if (!tmpscript || !tmpscript->pItemQuestAccept) + if (!tmpscript || !tmpscript->pQuestAcceptItem) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pItemQuestAccept(pPlayer,_Item, pQuest); + return tmpscript->pQuestAcceptItem(pPlayer, pItem, pQuest); } MANGOS_DLL_EXPORT -bool GOHello(Player* pPlayer, GameObject* pGo) +bool GOUse(Player* pPlayer, GameObject* pGo) { Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pGOHello) + if (!tmpscript || !tmpscript->pGOUse) return false; - return tmpscript->pGOHello(pPlayer, pGo); + return tmpscript->pGOUse(pPlayer, pGo); } MANGOS_DLL_EXPORT @@ -440,25 +410,25 @@ bool GOQuestAccept(Player* pPlayer, GameObject* pGo, const Quest* pQuest) { Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pGOQuestAccept) + if (!tmpscript || !tmpscript->pQuestAcceptGO) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pGOQuestAccept(pPlayer, pGo, pQuest); + return tmpscript->pQuestAcceptGO(pPlayer, pGo, pQuest); } MANGOS_DLL_EXPORT -bool GOChooseReward(Player* pPlayer, GameObject* pGo, const Quest* pQuest, uint32 opt) +bool GOQuestRewarded(Player* pPlayer, GameObject* pGo, Quest const* pQuest) { Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pGOChooseReward) + if (!tmpscript || !tmpscript->pQuestRewardedGO) return false; pPlayer->PlayerTalkClass->ClearMenus(); - return tmpscript->pGOChooseReward(pPlayer, pGo, pQuest,opt); + return tmpscript->pQuestRewardedGO(pPlayer, pGo, pQuest); } MANGOS_DLL_EXPORT @@ -473,9 +443,10 @@ bool AreaTrigger(Player* pPlayer, AreaTriggerEntry const* atEntry) } MANGOS_DLL_EXPORT -bool ProcessEventId(uint32 uiEventId, Object* pSource, Object* pTarget, bool bIsStart) +bool ProcessEvent(uint32 uiEventId, Object* pSource, Object* pTarget, bool bIsStart) { Script *tmpscript = m_scripts[GetEventIdScriptId(uiEventId)]; + if (!tmpscript || !tmpscript->pProcessEventId) return false; @@ -484,7 +455,7 @@ bool ProcessEventId(uint32 uiEventId, Object* pSource, Object* pTarget, bool bIs } MANGOS_DLL_EXPORT -CreatureAI* GetAI(Creature* pCreature) +CreatureAI* GetCreatureAI(Creature* pCreature) { Script *tmpscript = m_scripts[pCreature->GetScriptId()]; @@ -495,51 +466,51 @@ CreatureAI* GetAI(Creature* pCreature) } MANGOS_DLL_EXPORT -bool ItemUse(Player* pPlayer, Item* _Item, SpellCastTargets const& targets) +bool ItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { - Script *tmpscript = m_scripts[_Item->GetProto()->ScriptId]; + Script *tmpscript = m_scripts[pItem->GetProto()->ScriptId]; if (!tmpscript || !tmpscript->pItemUse) return false; - return tmpscript->pItemUse(pPlayer,_Item,targets); + return tmpscript->pItemUse(pPlayer, pItem, targets); } MANGOS_DLL_EXPORT -bool EffectDummyCreature(Unit *pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature *pCreatureTarget) +bool EffectDummyCreature(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget) { - Script *tmpscript = m_scripts[pCreatureTarget->GetScriptId()]; + Script *tmpscript = m_scripts[pTarget->GetScriptId()]; - if (!tmpscript || !tmpscript->pEffectDummyCreature) + if (!tmpscript || !tmpscript->pEffectDummyNPC) return false; - return tmpscript->pEffectDummyCreature(pCaster, spellId, effIndex, pCreatureTarget); + return tmpscript->pEffectDummyNPC(pCaster, spellId, effIndex, pTarget); } MANGOS_DLL_EXPORT -bool EffectDummyGameObj(Unit *pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject *pGameObjTarget) +bool EffectDummyGameObject(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget) { - Script *tmpscript = m_scripts[pGameObjTarget->GetGOInfo()->ScriptId]; + Script *tmpscript = m_scripts[pTarget->GetGOInfo()->ScriptId]; - if (!tmpscript || !tmpscript->pEffectDummyGameObj) + if (!tmpscript || !tmpscript->pEffectDummyGO) return false; - return tmpscript->pEffectDummyGameObj(pCaster, spellId, effIndex, pGameObjTarget); + return tmpscript->pEffectDummyGO(pCaster, spellId, effIndex, pTarget); } MANGOS_DLL_EXPORT -bool EffectDummyItem(Unit *pCaster, uint32 spellId, SpellEffectIndex effIndex, Item *pItemTarget) +bool EffectDummyItem(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Item* pTarget) { - Script *tmpscript = m_scripts[pItemTarget->GetProto()->ScriptId]; + Script *tmpscript = m_scripts[pTarget->GetProto()->ScriptId]; if (!tmpscript || !tmpscript->pEffectDummyItem) return false; - return tmpscript->pEffectDummyItem(pCaster, spellId, effIndex, pItemTarget); + return tmpscript->pEffectDummyItem(pCaster, spellId, effIndex, pTarget); } MANGOS_DLL_EXPORT -bool EffectAuraDummy(const Aura* pAura, bool apply) +bool AuraDummy(Aura const* pAura, bool apply) { Script *tmpscript = m_scripts[((Creature*)pAura->GetTarget())->GetScriptId()]; @@ -550,14 +521,21 @@ bool EffectAuraDummy(const Aura* pAura, bool apply) } MANGOS_DLL_EXPORT -InstanceData* CreateInstanceData(Map *map) +InstanceData* CreateInstanceData(Map* pMap) { - if (!map->IsDungeon()) - return NULL; + Script *tmpscript = m_scripts[pMap->GetScriptId()]; - Script *tmpscript = m_scripts[((InstanceMap*)map)->GetScriptId()]; if (!tmpscript || !tmpscript->GetInstanceData) return NULL; - return tmpscript->GetInstanceData(map); + return tmpscript->GetInstanceData(pMap); } + +Script* GetScriptByName(std::string scriptName) +{ + std::map::const_iterator itr = m_scriptStorage.find(scriptName); + if (itr != m_scriptStorage.end()) + return itr->second; + else + return NULL; +} \ No newline at end of file diff --git a/ScriptMgr.h b/ScriptMgr.h index c2b4ab726..816c9dbc2 100644 --- a/ScriptMgr.h +++ b/ScriptMgr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,6 +7,7 @@ #include "Common.h" #include "DBCStructure.h" +#include "Database/DatabaseEnv.h" class Player; class Creature; @@ -29,45 +30,42 @@ class Object; struct Script { Script() : - pGossipHello(NULL), pGOGossipHello(NULL), pGossipSelect(NULL), pGOGossipSelect(NULL), - pGossipSelectWithCode(NULL), pGOGossipSelectWithCode(NULL), - pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), - pChooseReward(NULL), pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pProcessEventId(NULL), pItemQuestAccept(NULL), - pQuestAccept(NULL), pGOQuestAccept(NULL), pGOChooseReward(NULL), pItemUse(NULL), - pEffectDummyCreature(NULL), pEffectDummyGameObj(NULL), pEffectDummyItem(NULL), pEffectAuraDummy(NULL), + 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), pProcessEventId(NULL), + pEffectDummyNPC(NULL), pEffectDummyGO(NULL), pEffectDummyItem(NULL), pEffectAuraDummy(NULL), GetAI(NULL), GetInstanceData(NULL) {} std::string Name; - //Methods to be scripted bool (*pGossipHello )(Player*, Creature*); - bool (*pGOGossipHello )(Player*, GameObject*); - bool (*pQuestAccept )(Player*, Creature*, const Quest*); + bool (*pGossipHelloGO )(Player*, GameObject*); bool (*pGossipSelect )(Player*, Creature*, uint32, uint32); - bool (*pGOGossipSelect )(Player*, GameObject*, uint32, uint32); + bool (*pGossipSelectGO )(Player*, GameObject*, uint32, uint32); bool (*pGossipSelectWithCode )(Player*, Creature*, uint32, uint32, const char*); - bool (*pGOGossipSelectWithCode )(Player*, GameObject*, uint32, uint32, const char*); - bool (*pQuestSelect )(Player*, Creature*, const Quest*); - bool (*pQuestComplete )(Player*, Creature*, const Quest*); - uint32 (*pNPCDialogStatus )(Player*, Creature*); - uint32 (*pGODialogStatus )(Player*, GameObject*); - bool (*pChooseReward )(Player*, Creature*, const Quest*, uint32); - bool (*pItemHello )(Player*, Item*, const Quest*); - bool (*pGOHello )(Player*, GameObject*); + 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 (*pProcessEventId )(uint32, Object*, Object*, bool); - bool (*pItemQuestAccept )(Player*, Item*, const Quest*); - bool (*pGOQuestAccept )(Player*, GameObject*, const Quest*); - bool (*pGOChooseReward )(Player*, GameObject*, const Quest*, uint32); - bool (*pItemUse )(Player*, Item*, SpellCastTargets const&); - bool (*pEffectDummyCreature )(Unit*, uint32, SpellEffectIndex, Creature*); - bool (*pEffectDummyGameObj )(Unit*, uint32, SpellEffectIndex, GameObject*); + bool (*pEffectDummyNPC )(Unit*, uint32, SpellEffectIndex, Creature*); + bool (*pEffectDummyGO )(Unit*, uint32, SpellEffectIndex, GameObject*); bool (*pEffectDummyItem )(Unit*, uint32, SpellEffectIndex, Item*); bool (*pEffectAuraDummy )(const Aura*, bool); - CreatureAI* (*GetAI)(Creature*); - InstanceData* (*GetInstanceData)(Map*); + CreatureAI* (*GetAI )(Creature*); + InstanceData* (*GetInstanceData )(Map*); void RegisterSelf(bool bReportError = true); }; @@ -75,6 +73,12 @@ struct Script //Generic scripting text function void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget = NULL); +//DB query +QueryResult* strSD2Pquery(char*); + +// Not registered scripts storage +Script* GetScriptByName(std::string scriptName); + #if COMPILER == COMPILER_GNU #define FUNC_PTR(name,callconvention,returntype,parameters) typedef returntype(*name)parameters __attribute__ ((callconvention)); #else diff --git a/VC100/100ScriptDev2.vcxproj b/VC100/100ScriptDev2.vcxproj deleted file mode 100644 index 1f5932b8d..000000000 --- a/VC100/100ScriptDev2.vcxproj +++ /dev/null @@ -1,785 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - ScriptDev2 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96} - ScriptDev2 - Win32Proj - - - - DynamicLibrary - MultiByte - - - DynamicLibrary - MultiByte - - - DynamicLibrary - MultiByte - - - DynamicLibrary - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\..\..\bin\win32_debug\ - .\ScriptDev2__$(Platform)_$(Configuration)\ - true - ..\..\..\..\bin\x64_debug\ - .\ScriptDev2__$(Platform)_$(Configuration)\ - true - ..\..\..\..\bin\win32_release\ - .\ScriptDev2__$(Platform)_$(Configuration)\ - false - ..\..\..\..\bin\x64_release\ - .\ScriptDev2__$(Platform)_$(Configuration)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - mangosscript - mangosscript - mangosscript - mangosscript - - - - Disabled - ..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - Use - precompiled.h - Level3 - ProgramDatabase - true - true - true - - - mangosd.lib;ACEd.lib;framework.lib;%(AdditionalDependencies) - ..\..\..\..\win\VC100\mangosd__Win32_Debug;..\..\..\..\win\VC100\framework__Win32_Debug;..\..\..\..\dep\lib\win32_debug\;%(AdditionalLibraryDirectories) - true - Windows - false - - - $(OutDir)mangosscript.lib - MachineX86 - - - - - X64 - - - Disabled - ..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;MANGOS_DEBUG;_WINDOWS;_USRDLL;SCRIPT;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - Use - precompiled.h - Level3 - ProgramDatabase - true - true - true - - - mangosd.lib;ACEd.lib;framework.lib;%(AdditionalDependencies) - ..\..\..\..\win\VC100\mangosd__x64_Debug;..\..\..\..\win\VC100\framework__x64_Debug;..\..\..\..\dep\lib\x64_Debug\;%(AdditionalLibraryDirectories) - true - Windows - false - - - $(OutDir)mangosscript.lib - MachineX64 - - - - - /MP %(AdditionalOptions) - ..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;SCRIPT;_SECURE_SCL=0;%(PreprocessorDefinitions) - false - MultiThreadedDLL - Use - precompiled.h - Level3 - ProgramDatabase - true - true - true - - - mangosd.lib;ACE.lib;framework.lib;%(AdditionalDependencies) - ..\..\..\..\win\VC100\mangosd__Win32_Release;..\..\..\..\win\VC100\framework__Win32_Release;..\..\..\..\dep\lib\win32_release\;%(AdditionalLibraryDirectories) - true - Windows - true - true - false - - - $(OutDir)mangosscript.lib - - - - - X64 - - - /MP %(AdditionalOptions) - ..\..\..\..\dep\include\;..\..\..\shared\;..\..\..\framework\;..\..\..\game\;..\include\;..\base\;..\..\..\..\dep\ACE_wrappers\;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;SCRIPT;_SECURE_SCL=0;%(PreprocessorDefinitions) - MultiThreadedDLL - Use - precompiled.h - Level3 - ProgramDatabase - true - true - true - - - mangosd.lib;ACE.lib;framework.lib;%(AdditionalDependencies) - ..\..\..\..\win\VC100\mangosd__x64_Release;..\..\..\..\win\VC100\framework__x64_Release;..\..\..\..\dep\lib\x64_release\;%(AdditionalLibraryDirectories) - true - Windows - true - true - false - - - $(OutDir)mangosscript.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extracting revision - cd "$(SolutionDir)" -"$(SolutionDir)..\..\..\win\VC100\genrevision__Win32_$(Configuration)\genrevision.exe" - - .svn/entries;%(AdditionalInputs) - revision.h;%(Outputs) - Extracting revision - cd "$(SolutionDir)" -"$(SolutionDir)..\..\..\win\VC100\genrevision__Win32_$(Configuration)\genrevision.exe" - - .svn/entries;%(AdditionalInputs) - revision.h;%(Outputs) - Extracting revision - cd "$(SolutionDir)" -"$(SolutionDir)..\..\..\win\VC100\genrevision__Win32_$(Configuration)\genrevision.exe" - - .svn/entries;%(AdditionalInputs) - revision.h;%(Outputs) - Extracting revision - cd "$(SolutionDir)" -"$(SolutionDir)..\..\..\win\VC100\genrevision__Win32_$(Configuration)\genrevision.exe" - - .svn/entries;%(AdditionalInputs) - revision.h;%(Outputs) - - - - - - - \ No newline at end of file diff --git a/VC100/100ScriptDev2.vcxproj.filters b/VC100/100ScriptDev2.vcxproj.filters deleted file mode 100644 index 76c2b8fe4..000000000 --- a/VC100/100ScriptDev2.vcxproj.filters +++ /dev/null @@ -1,1908 +0,0 @@ - - - - - {3b1307a9-bc58-4773-9a93-0e9ceff55c82} - - - {b7b35df3-4231-4370-aed5-5859ab4c312e} - - - {ced0a1e2-6867-4f01-a762-390a3d1f01d3} - - - {af3d4b4d-a585-41c4-ba95-79669a614ea8} - - - {ca2551e0-68d0-4331-88f3-ab0cdaa2bf9a} - - - {45c59280-02fb-482f-859b-bd47cc230f0f} - - - {5631f38e-66c8-4efd-ad3a-2834fbb49a6e} - - - {31605090-12b9-4d42-a5e9-1cbfac8ab384} - - - {08fb5b22-710d-46d6-9893-f567aa75a5e6} - - - {cef5c3c5-f434-4b9f-9bad-8c106d46c755} - - - {66bc2cec-8372-4191-991c-1c23275fa13c} - - - {af465469-5a16-4908-aa08-39c77d02cd88} - - - {920d1832-b347-4afd-bd05-4c943e5555f0} - - - {6ffd42e5-ac49-4635-8087-77ad2b7b0866} - - - {dd4995a8-6d86-4f21-82bc-a18acc2c688f} - - - {2a3a25e5-51f1-4ab3-a1a0-1b9ec9c45d1a} - - - {7a028ad9-afa1-42ea-b147-20a40c5e716c} - - - {66401dac-d94c-4ed6-b912-229dda0906d6} - - - {385f26dc-dcaf-4022-921d-3a562617bf93} - - - {25be39dd-536d-450d-ac94-6372d37a4fae} - - - {1d718eaa-2a8d-4cb9-9abf-17fcf0d91f83} - - - {c929f54b-22dd-49b4-862c-92dfa9a2d1f7} - - - {60b91cfe-7dff-40de-9957-41f8d03144cc} - - - {22eca3e6-662f-4c53-9344-6e749c09c86b} - - - {070541ef-a813-43f5-a8a6-e6674fe1a47e} - - - {5cda7bda-399b-46b7-8bc2-5786f0202fa2} - - - {226d4dc8-830b-4249-b28a-313ac21080a9} - - - {404b30fd-bdaa-44d1-ab3a-384886ebb8ec} - - - {5833dbce-1fa8-49eb-b678-145a2d58a067} - - - {dc38d3fe-d1fe-49f2-bd8f-758cd270dd62} - - - {2552ab59-1f73-4778-a6db-6f03e405622d} - - - {8206776b-4d43-431d-bca5-5f6cff157ea4} - - - {02135a7c-33cc-444e-af90-48a5193e5a6f} - - - {014ada9a-13bf-4540-a0ce-5132bdc36fcf} - - - {9feb59d0-e6bd-4328-9a50-7ddb9852936e} - - - {00f03f8d-4af1-40d9-a95a-e2dc1a81ca7d} - - - {de2e959a-1ef4-41ef-9235-15a1f3f8a19d} - - - {8f8a60e0-223e-4517-918c-243e523a7892} - - - {416ccfc8-a1bb-43a5-b202-d7656981094a} - - - {ba031a13-787e-41da-bcaf-1986fdea8069} - - - {0412262e-b05b-4827-adef-97507204cb69} - - - {e775610e-fa3c-4355-9c4c-473a6a5e57d5} - - - {6c5f7fd4-671b-4cba-aa95-7758b93dc844} - - - {71e87e58-3b30-41e7-8f8a-16886508a4d9} - - - {3cf8e088-da94-4561-993f-2970908d6642} - - - {bc0156b2-6544-4ebc-9ed6-fe45ac1902a4} - - - {b59c73a8-c480-43b2-8a2e-65f5a54978eb} - - - {5eb6a84a-97e6-477e-97e3-23681f29f675} - - - {d7e0e45a-fd89-48a6-8d24-f4922058160e} - - - {71617682-fe62-4d7c-a2de-7181fb3f46f6} - - - {9c5d9a0f-8967-4cf6-a047-3b724f81dc29} - - - {42501e94-f91e-40be-a02a-472b5ca1e22c} - - - {aac6b8be-6055-4d7d-a50a-41650b8d464e} - - - {e7ee3113-f4d0-4e28-acc7-dc80f42d41df} - - - {e603d4b3-3c2f-4011-aa2b-040243163d3f} - - - {36c79ad7-420c-4909-8da3-c90d3cc83b31} - - - {d47410b0-3184-40e2-8704-cea9b97e20ed} - - - {1b2f0d99-82b0-4a96-aaac-c485830eb1b3} - - - {fd594031-4dc2-40de-b37b-93063ee6e3e9} - - - {ef27a557-e12d-4b02-9e86-c258329f201e} - - - {b7e4ad7d-8515-4981-ae27-9e542c223618} - - - {04b1d59c-38b6-4b5c-a50d-b9ff1d39bb30} - - - {ee364414-732a-4aad-820f-a5b73cb8b093} - - - {638d5426-652e-4d1f-9abe-3ed95d7e7e69} - - - {a21893a5-0f34-4a73-b0aa-49b175822834} - - - {728148f8-18a0-4606-a2ec-2c9eae4e5e7e} - - - {88c327d5-0768-465f-b954-30eca0d31f45} - - - {b20efa19-1e16-42e4-bc29-a9c8e282d17c} - - - {fec1fbfa-5119-4bb0-98bc-f8d4583521f7} - - - {1cb43523-dc33-4c49-a5b7-6e700fe0ecd6} - - - {7289cc07-6956-4b09-8dc5-753c82abe8c9} - - - {e834cf7b-88ad-4bae-9fc8-8e027136c63b} - - - {cfb08e82-63e6-49ca-bff2-533f8647797b} - - - {2be3084e-c5c0-4e2f-bbb4-2ebb22bfff19} - - - {6dc08e92-3e86-4a7f-bab9-9a8cec6a201b} - - - {01da56d1-ee04-455c-846c-4e53869314f6} - - - {5e79ca74-cd29-47ff-a08e-3fada858ddd7} - - - {32b92545-4821-4cc8-ae39-f631b0176d46} - - - {044e4dbc-e2fc-437c-b359-b6fb5a3439ff} - - - {4cbcf193-4d98-4518-a9c4-6c8b4bedbf44} - - - {5c32221e-3532-4c32-bdba-9a85213006af} - - - {2df99085-aee2-4202-b4d1-38a5cc35f3e2} - - - {0a109c31-6dd3-4030-8d6c-6c0e147481be} - - - {ddada980-2eed-4f2b-a9f7-dbb9cca7ca3d} - - - {d6843352-6425-48da-85b6-6b26f6217ba8} - - - {6a68396b-343f-4c79-938c-93741acdeb41} - - - {974fc97c-e585-442c-b35e-b21a17804619} - - - {ba709b56-d5db-4730-9591-79b8f9788ca1} - - - {1fa90250-9c5b-450c-be64-d9eee910c4a8} - - - {7b3c1c18-03e9-493e-a364-5beb1a6936eb} - - - {575420cc-581f-4d08-a9da-7814f221ab47} - - - {9c5997ee-accc-4737-815f-b031d422577b} - - - {579f2f5c-acf1-410a-bce6-d353d6912546} - - - {04e4571d-55ee-4f2e-ac4e-46fc2610341f} - - - {79a3e62b-bd96-4d16-8c23-bda17f968d19} - - - {ca7213e9-56c1-4084-a48b-19ff57dee433} - - - {2fd46769-c050-4e47-9533-461ef8695d6a} - - - {90f3df6a-a1d0-4a6e-b8d7-d1d993fc795b} - - - {e35abead-2389-4eb9-88bd-70e6fe5636b5} - - - - - base - - - base - - - base - - - scripts\battlegrounds - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackrock_spire - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\blackwing_lair - - - scripts\eastern_kingdoms\deadmines - - - scripts\eastern_kingdoms\deadmines - - - scripts\eastern_kingdoms\gnomeregan - - - scripts\eastern_kingdoms\gnomeregan - - - scripts\eastern_kingdoms\gnomeregan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\magisters_terrace - - - scripts\eastern_kingdoms\magisters_terrace - - - scripts\eastern_kingdoms\magisters_terrace - - - scripts\eastern_kingdoms\magisters_terrace - - - scripts\eastern_kingdoms\magisters_terrace - - - scripts\eastern_kingdoms\magisters_terrace - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\scarlet_enclave - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\shadowfang_keep - - - scripts\eastern_kingdoms\shadowfang_keep - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\sunken_temple - - - scripts\eastern_kingdoms\sunken_temple - - - scripts\eastern_kingdoms\sunwell_plateau - - - scripts\eastern_kingdoms\sunwell_plateau - - - scripts\eastern_kingdoms\sunwell_plateau - - - scripts\eastern_kingdoms\uldaman - - - scripts\eastern_kingdoms\uldaman - - - scripts\eastern_kingdoms\uldaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\eastern_kingdoms\zulgurub - - - scripts\examples - - - scripts\examples - - - scripts\examples - - - scripts\examples - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor - - - scripts\kalimdor\blackfathom_deeps - - - scripts\kalimdor\caverns_of_time\culling_of_stratholme - - - scripts\kalimdor\caverns_of_time\culling_of_stratholme - - - scripts\kalimdor\caverns_of_time\dark_portal - - - scripts\kalimdor\caverns_of_time\dark_portal - - - scripts\kalimdor\caverns_of_time\dark_portal - - - scripts\kalimdor\caverns_of_time\dark_portal - - - scripts\kalimdor\caverns_of_time\dark_portal - - - scripts\kalimdor\caverns_of_time\hyjal - - - scripts\kalimdor\caverns_of_time\hyjal - - - scripts\kalimdor\caverns_of_time\hyjal - - - scripts\kalimdor\caverns_of_time\hyjal - - - scripts\kalimdor\caverns_of_time\old_hillsbrad - - - scripts\kalimdor\caverns_of_time\old_hillsbrad - - - scripts\kalimdor\caverns_of_time\old_hillsbrad - - - scripts\kalimdor\caverns_of_time\old_hillsbrad - - - scripts\kalimdor\caverns_of_time\old_hillsbrad - - - scripts\kalimdor\maraudon - - - scripts\kalimdor\maraudon - - - scripts\kalimdor\maraudon - - - scripts\kalimdor\maraudon - - - scripts\kalimdor\onyxias_lair - - - scripts\kalimdor\onyxias_lair - - - scripts\kalimdor\razorfen_downs - - - scripts\kalimdor\razorfen_downs - - - scripts\kalimdor\razorfen_kraul - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\wailing_caverns - - - scripts\kalimdor\zulfarrak - - - scripts\kalimdor\zulfarrak - - - scripts\kalimdor\zulfarrak - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend - - - scripts\northrend\azjol-nerub\ahnkahet - - - scripts\northrend\azjol-nerub\ahnkahet - - - scripts\northrend\azjol-nerub\ahnkahet - - - scripts\northrend\azjol-nerub\ahnkahet - - - scripts\northrend\azjol-nerub\ahnkahet - - - scripts\northrend\azjol-nerub\azjol-nerub - - - scripts\northrend\azjol-nerub\azjol-nerub - - - scripts\northrend\azjol-nerub\azjol-nerub - - - scripts\northrend\azjol-nerub\azjol-nerub - - - scripts\northrend\crusaders_coliseum\trial_of_the_champion - - - scripts\northrend\crusaders_coliseum\trial_of_the_champion - - - scripts\northrend\crusaders_coliseum\trial_of_the_champion - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\draktharon_keep - - - scripts\northrend\draktharon_keep - - - scripts\northrend\draktharon_keep - - - scripts\northrend\draktharon_keep - - - scripts\northrend\gundrak - - - scripts\northrend\gundrak - - - scripts\northrend\gundrak - - - scripts\northrend\gundrak - - - scripts\northrend\gundrak - - - scripts\northrend\gundrak - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\naxxramas - - - scripts\northrend\nexus\nexus - - - scripts\northrend\nexus\nexus - - - scripts\northrend\nexus\nexus - - - scripts\northrend\nexus\nexus - - - scripts\northrend\nexus\nexus - - - scripts\northrend\obsidian_sanctum - - - scripts\northrend\obsidian_sanctum - - - scripts\northrend\ulduar\halls_of_lightning - - - scripts\northrend\ulduar\halls_of_lightning - - - scripts\northrend\ulduar\halls_of_lightning - - - scripts\northrend\ulduar\halls_of_lightning - - - scripts\northrend\ulduar\halls_of_lightning - - - scripts\northrend\ulduar\halls_of_stone - - - scripts\northrend\ulduar\halls_of_stone - - - scripts\northrend\ulduar\halls_of_stone - - - scripts\northrend\ulduar\halls_of_stone - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\utgarde_keep\utgarde_keep - - - scripts\northrend\utgarde_keep\utgarde_keep - - - scripts\northrend\utgarde_keep\utgarde_keep - - - scripts\northrend\utgarde_keep\utgarde_keep - - - scripts\northrend\utgarde_keep\utgarde_keep - - - scripts\northrend\utgarde_keep\utgarde_pinnacle - - - scripts\northrend\utgarde_keep\utgarde_pinnacle - - - scripts\northrend\utgarde_keep\utgarde_pinnacle - - - scripts\northrend\utgarde_keep\utgarde_pinnacle - - - scripts\northrend\utgarde_keep\utgarde_pinnacle - - - scripts\northrend\violet_hold - - - scripts\northrend\violet_hold - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\icecrown_citadel - - - scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron - - - scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron - - - scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron - - - scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron - - - scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron - - - scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection - - - scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection - - - scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection - - - scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls - - - scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls - - - scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland - - - scripts\outland\auchindoun\auchenai_crypts - - - scripts\outland\auchindoun\mana_tombs - - - scripts\outland\auchindoun\mana_tombs - - - scripts\outland\auchindoun\sethekk_halls - - - scripts\outland\auchindoun\sethekk_halls - - - scripts\outland\auchindoun\sethekk_halls - - - scripts\outland\auchindoun\shadow_labyrinth - - - scripts\outland\auchindoun\shadow_labyrinth - - - scripts\outland\auchindoun\shadow_labyrinth - - - scripts\outland\auchindoun\shadow_labyrinth - - - scripts\outland\auchindoun\shadow_labyrinth - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\black_temple - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\steam_vault - - - scripts\outland\coilfang_reservoir\steam_vault - - - scripts\outland\coilfang_reservoir\steam_vault - - - scripts\outland\coilfang_reservoir\steam_vault - - - scripts\outland\coilfang_reservoir\underbog - - - scripts\outland\gruuls_lair - - - scripts\outland\gruuls_lair - - - scripts\outland\gruuls_lair - - - scripts\outland\hellfire_citadel\blood_furnace - - - scripts\outland\hellfire_citadel\blood_furnace - - - scripts\outland\hellfire_citadel\blood_furnace - - - scripts\outland\hellfire_citadel\blood_furnace - - - scripts\outland\hellfire_citadel\hellfire_ramparts - - - scripts\outland\hellfire_citadel\hellfire_ramparts - - - scripts\outland\hellfire_citadel\hellfire_ramparts - - - scripts\outland\hellfire_citadel\hellfire_ramparts - - - scripts\outland\hellfire_citadel\magtheridons_lair - - - scripts\outland\hellfire_citadel\magtheridons_lair - - - scripts\outland\hellfire_citadel\shattered_halls - - - scripts\outland\hellfire_citadel\shattered_halls - - - scripts\outland\hellfire_citadel\shattered_halls - - - scripts\outland\hellfire_citadel\shattered_halls - - - scripts\outland\tempest_keep\arcatraz - - - scripts\outland\tempest_keep\arcatraz - - - scripts\outland\tempest_keep\arcatraz - - - scripts\outland\tempest_keep\botanica - - - scripts\outland\tempest_keep\botanica - - - scripts\outland\tempest_keep\botanica - - - scripts\outland\tempest_keep\the_eye - - - scripts\outland\tempest_keep\the_eye - - - scripts\outland\tempest_keep\the_eye - - - scripts\outland\tempest_keep\the_eye - - - scripts\outland\tempest_keep\the_eye - - - scripts\outland\tempest_keep\the_mechanar - - - scripts\outland\tempest_keep\the_mechanar - - - scripts\outland\tempest_keep\the_mechanar - - - scripts\outland\tempest_keep\the_mechanar - - - scripts\outland\tempest_keep\the_mechanar - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - scripts\world - - - include - - - include - - - include - - - include - - - system - - - system - - - - scripts\northrend\ruby_sanctum - - - scripts\northrend\ruby_sanctum - - - scripts\northrend\ruby_sanctum - - - scripts\northrend\ruby_sanctum - - - - - base - - - base - - - base - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\blackrock_depths - - - scripts\eastern_kingdoms\deadmines - - - scripts\eastern_kingdoms\gnomeregan - - - scripts\eastern_kingdoms\karazhan - - - scripts\eastern_kingdoms\magisters_terrace - - - scripts\eastern_kingdoms\molten_core - - - scripts\eastern_kingdoms\scarlet_monastery - - - scripts\eastern_kingdoms\scholomance - - - scripts\eastern_kingdoms\shadowfang_keep - - - scripts\eastern_kingdoms\stratholme - - - scripts\eastern_kingdoms\sunken_temple - - - scripts\eastern_kingdoms\sunwell_plateau - - - scripts\eastern_kingdoms\uldaman - - - scripts\eastern_kingdoms\zulaman - - - scripts\eastern_kingdoms\zulgurub - - - scripts\kalimdor\blackfathom_deeps - - - scripts\kalimdor\caverns_of_time\culling_of_stratholme - - - scripts\kalimdor\caverns_of_time\dark_portal - - - scripts\kalimdor\caverns_of_time\hyjal - - - scripts\kalimdor\caverns_of_time\hyjal - - - scripts\kalimdor\caverns_of_time\old_hillsbrad - - - scripts\kalimdor\onyxias_lair - - - scripts\kalimdor\razorfen_kraul - - - scripts\kalimdor\ruins_of_ahnqiraj - - - scripts\kalimdor\temple_of_ahnqiraj - - - scripts\kalimdor\wailing_caverns - - - scripts\kalimdor\zulfarrak - - - scripts\northrend\azjol-nerub\ahnkahet - - - scripts\northrend\azjol-nerub\azjol-nerub - - - scripts\northrend\crusaders_coliseum\trial_of_the_champion - - - scripts\northrend\crusaders_coliseum\trial_of_the_crusader - - - scripts\northrend\draktharon_keep - - - scripts\northrend\gundrak - - - scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls - - - scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron - - - scripts\northrend\naxxramas - - - scripts\northrend\nexus\nexus - - - scripts\northrend\obsidian_sanctum - - - scripts\northrend\ulduar\halls_of_lightning - - - scripts\northrend\ulduar\halls_of_stone - - - scripts\northrend\ulduar\ulduar - - - scripts\northrend\utgarde_keep\utgarde_keep - - - scripts\northrend\utgarde_keep\utgarde_pinnacle - - - scripts\northrend\violet_hold - - - scripts\outland\auchindoun\sethekk_halls - - - scripts\outland\auchindoun\shadow_labyrinth - - - scripts\outland\black_temple - - - scripts\outland\coilfang_reservoir\serpent_shrine - - - scripts\outland\coilfang_reservoir\steam_vault - - - scripts\outland\gruuls_lair - - - scripts\outland\hellfire_citadel\blood_furnace - - - scripts\outland\hellfire_citadel\hellfire_ramparts - - - scripts\outland\hellfire_citadel\magtheridons_lair - - - scripts\outland\hellfire_citadel\shattered_halls - - - scripts\outland\tempest_keep\arcatraz - - - scripts\outland\tempest_keep\the_eye - - - scripts\outland\tempest_keep\the_mechanar - - - include - - - include - - - include - - - include - - - include - - - system - - - system - - - - - - - - \ No newline at end of file diff --git a/VC80/80ScriptDev2.vcproj b/VC80/80ScriptDev2.vcproj deleted file mode 100644 index d539d0d95..000000000 --- a/VC80/80ScriptDev2.vcproj +++ /dev/null @@ -1,2976 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VC90/90ScriptDev2.vcproj b/VC90/90ScriptDev2.vcproj deleted file mode 100644 index 80d14c485..000000000 --- a/VC90/90ScriptDev2.vcproj +++ /dev/null @@ -1,2975 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/addition/1_mangos_vault_of_archavon.sql b/addition/1_mangos_vault_of_archavon.sql new file mode 100644 index 000000000..fd70c8ea1 --- /dev/null +++ b/addition/1_mangos_vault_of_archavon.sql @@ -0,0 +1,9 @@ +UPDATE `creature_template` SET `ScriptName`='boss_archavon' WHERE `entry`=31125; +UPDATE `creature_template` SET `ScriptName`='boss_emalon' WHERE `entry`=33993; +UPDATE `creature_template` SET `ScriptName`='npc_tempest_minion' WHERE `entry`=33998; +UPDATE `creature_template` SET `ScriptName`='npc_tempest_warder' WHERE `entry`=34015; +UPDATE `creature_template` SET `ScriptName`='boss_koralon' WHERE `entry`=35013; +UPDATE `creature_template` SET `AIName`='', ScriptName='boss_toravon' WHERE `entry`=38433; +UPDATE `instance_template` SET `ScriptName`='instance_vault_of_archavon' WHERE `map`=624; +DELETE FROM `spell_script_target` WHERE `entry` IN (72034,72096); +INSERT INTO `spell_script_target` VALUES (72034,1,38433),(72096,1,38433); diff --git a/addition/1_naxxramass_cleanup_mangos.sql b/addition/1_naxxramass_cleanup_mangos.sql new file mode 100644 index 000000000..6d4cedb61 --- /dev/null +++ b/addition/1_naxxramass_cleanup_mangos.sql @@ -0,0 +1,34 @@ +-- cleanup instance Naxxramas (use once!) + +UPDATE `creature_template` SET `ScriptName`='', `AIName`='EventAI' WHERE `entry` IN +(16124,16127, 16286, 16126, 16150, 16125, 16148, 16573, 15929, 15930); + +UPDATE `creature_template` SET `ScriptName`='' WHERE `entry` IN +(16506, 16363, 16360, 15384, 29912 ); + +DELETE FROM scripted_areatrigger WHERE entry=4112; +INSERT INTO scripted_areatrigger VALUES (4112,'at_naxxramas'); + +UPDATE instance_template SET ScriptName='instance_naxxramas' WHERE map=533; +UPDATE creature_template SET ScriptName='boss_anubrekhan' WHERE entry=15956; +UPDATE creature_template SET ScriptName='boss_faerlina' WHERE entry=15953; +UPDATE creature_template SET ScriptName='boss_maexxna' WHERE entry=15952; +UPDATE creature_template SET ScriptName='npc_web_wrap' WHERE entry=16486; +UPDATE creature_template SET ScriptName='boss_noth' WHERE entry=15954; +UPDATE creature_template SET ScriptName='boss_heigan' WHERE entry=15936; +UPDATE creature_template SET ScriptName='boss_loatheb' WHERE entry=16011; +UPDATE creature_template SET ScriptName='boss_razuvious' WHERE entry=16061; +UPDATE creature_template SET ScriptName='boss_gothik' WHERE entry=16060; +UPDATE creature_template SET ScriptName='spell_anchor' WHERE entry=16137; +UPDATE creature_template SET ScriptName='boss_thane_korthazz' WHERE entry=16064; +UPDATE creature_template SET ScriptName='boss_sir_zeliek' WHERE entry=16063; +UPDATE creature_template SET ScriptName='boss_lady_blaumeux' WHERE entry=16065; +UPDATE creature_template SET ScriptName='boss_rivendare_naxx' WHERE entry=30549; +UPDATE creature_template SET ScriptName='boss_patchwerk' WHERE entry=16028; +UPDATE creature_template SET ScriptName='boss_grobbulus' WHERE entry=15931; +UPDATE creature_template SET ScriptName='boss_gluth' WHERE entry=15932; +-- UPDATE creature_template SET ScriptName='boss_thaddius' WHERE entry=15928; +-- UPDATE creature_template SET ScriptName='boss_stalagg' WHERE entry=15929; +-- UPDATE creature_template SET ScriptName='boss_feugen' WHERE entry=15930; +UPDATE creature_template SET ScriptName='boss_sapphiron' WHERE entry=15989; +UPDATE creature_template SET ScriptName='boss_kelthuzad' WHERE entry=15990; diff --git a/addition/3_mangos_teleguy.sql b/addition/3_mangos_teleguy.sql new file mode 100644 index 000000000..8de7022d9 --- /dev/null +++ b/addition/3_mangos_teleguy.sql @@ -0,0 +1,3 @@ +DELETE FROM `creature_template` WHERE `entry`=99001; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `PowerType`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `vehicle_id`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES +(99001, 0, 0, 0, 0, 0, 18, 0, 18, 0, 'Slappy McFry', 'The Teleport Guy', NULL, 0, 59, 61, 6700, 24000, 0, 5598, 5875, 4049, 35, 35, 1, 1.48, 1.14286, 1, 0, 98, 147, 0, 37, 1.4, 1400, 1400, 2, 0, 0, 0, 0, 0, 0, 0, 78, 118, 30, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 'mob_teleguy'); diff --git a/addition/4_mangos_arena_honor.sql b/addition/4_mangos_arena_honor.sql new file mode 100644 index 000000000..02184d747 --- /dev/null +++ b/addition/4_mangos_arena_honor.sql @@ -0,0 +1,4 @@ +-- npc arena-honor exchange +DELETE FROM `creature_template` WHERE `entry` = 7; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `PowerType`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `vehicle_id`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES +(7, 0, 0, 0, 0, 0, 17858, 0, 17858, 0, 'Besdoban Durnoye', 'Arena-Honor Exchange', NULL, 0, 59, 61, 6700, 24000, 0, 5598, 5875, 4009, 35, 35, 1, 1.48, 1.14286, 1, 0, 91, 137, 0, 34, 1.4, 1400, 1400, 2, 0, 0, 0, 0, 0, 0, 0, 73, 110, 27, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 'npc_arena_honor'); diff --git a/addition/4_scriptdev2_arena_honor.sql b/addition/4_scriptdev2_arena_honor.sql new file mode 100644 index 000000000..2017b053d --- /dev/null +++ b/addition/4_scriptdev2_arena_honor.sql @@ -0,0 +1,14 @@ +-- npc arena-honor exchange + +DELETE FROM `script_texts` WHERE `entry` in (-1001007, -1001008); +INSERT INTO `script_texts` (`entry`,`content_loc8`, `content_default`, `sound`, `type`, `language`, `emote`, `comment`) VALUES +('-1001007','Недостаточно ХонорПойнтов!','Your not has enough HonorPoints!','','0','0','0','Unsuccesfull - honorpoint.'), +('-1001008','Недостаточно АренаПойнтов!','Your not has enough AranaPoints!','','0','0','0','Unsuccesfull - arenapoint.'); + +-- Gossips +DELETE FROM `gossip_texts` WHERE `entry` BETWEEN -3000774 AND -3000769; +INSERT INTO `gossip_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `comment`) VALUES +('-3000770', "Exchange 100 ArenaPoints to 2000 HonorPoints", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Обменять 100 АренаПойнтов на 2000 ХонорПойнтов", "npc_arena_honor gossip 1"), +('-3000771', "Exchange 1000 ArenaPoints to 20000 HonorPoints", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Обменять 1000 АренаПойнтов на 20000 ХонорПойнтов", "npc_arena_honor gossip 2"), +('-3000772', "Exchange 1000 HonorPoints to 50 ArenaPoints", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Обменять 1000 ХонорПойнтов на 50 АренаПойнтов", "npc_arena_honor gossip 3"), +('-3000773', "Exchange 10000 HonorPoints to 500 ArenaPoints", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Обменять 10000 ХонорПойнтов на 500 АренаПойнтов", "npc_arena_honor gossip 4"); diff --git a/addition/4_scriptdev2_sapphiron.sql b/addition/4_scriptdev2_sapphiron.sql new file mode 100644 index 000000000..5a92ea06c --- /dev/null +++ b/addition/4_scriptdev2_sapphiron.sql @@ -0,0 +1,6 @@ +DELETE FROM `script_texts` where entry in ('-1533082','-1533083'); +INSERT INTO `script_texts` (entry,content_default,sound,type,language,emote,comment) VALUES +(-1533082,'%s takes in a deep breath.',0,3,0,0,'sapphiron EMOTE_BREATH'), +(-1533083,'%s lifts off into the air!',0,3,0,0,'sapphiron EMOTE_FLY'), +(-1533160,'%s resumes hit attacks!',0,3,0,0,'sapphiron EMOTE_GROUND'), +(-1533161,'%s enrages!',0,3,0,0,'sapphiron EMOTE_ENRAGE'); diff --git a/addition/710_quest_scripts_scriptdev2.sql b/addition/710_quest_scripts_scriptdev2.sql new file mode 100644 index 000000000..13b5e420f --- /dev/null +++ b/addition/710_quest_scripts_scriptdev2.sql @@ -0,0 +1,138 @@ +-- Quest The Light of Dawn + +DELETE FROM `script_texts` WHERE entry BETWEEN -1609286 AND -1609201; +INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +-- The Light of Dawn +-- pre text + (-1609201, 'Soldiers of the Scourge, stand ready! You will soon be able to unleash your fury upon the Argent Dawn!',14677,1,0,0,'Highlord Darion Mograine'), + (-1609202, 'The sky weeps at the devastation of sister earth! Soon, tears of blood will rain down upon us!',14678,1,0,0,'Highlord Darion Mograine'), + (-1609203, 'Death knights of Acherus, the death march begins!',14681,1,0,0,'Highlord Darion Mograine'), +-- intro + (-1609204, 'Soldiers of the Scourge, death knights of Acherus, minions of the darkness: hear the call of the Highlord!',14679,1,0,22,'Highlord Darion Mograine'), + (-1609205, 'RISE!',14680,1,0,15,'Highlord Darion Mograine'), + (-1609206, 'The skies turn red with the blood of the fallen! The Lich King watches over us, minions! Onward! Leave only ashes and misery in your destructive wake!',14682,1,0,25,'Highlord Darion Mograine'), +-- During the fight + (-1609207, 'Scourge armies approach!',0,1,0,0,'Korfax, Champion of the Light'), + (-1609208, 'Stand fast, brothers and sisters! The Light will prevail!',14487,1,0,0,'Lord Maxwell Tyrosus'), + (-1609209, 'Kneel before the Highlord!',14683,0,0,0,'Highlord Darion Mograine'), + (-1609210, 'You stand no chance!',14684,0,0,0,'Highlord Darion Mograine'), + (-1609211, 'The Scourge will destroy this place!',14685,0,0,0,'Highlord Darion Mograine'), + (-1609212, 'Your life is forfeit.',14686,0,0,0,'Highlord Darion Mograine'), + (-1609213, 'Life is meaningless without suffering.',14687,0,0,0,'Highlord Darion Mograine'), + (-1609214, 'How much longer will your forces hold out?',14688,0,0,0,'Highlord Darion Mograine'), + (-1609215, 'The Argent Dawn is finished!"',14689,0,0,0,'Highlord Darion Mograine'), + (-1609216, 'Spare no one!',14690,0,0,0,'Highlord Darion Mograine'), + (-1609217, 'What is this?! My... I cannot strike...',14691,0,0,0,'Highlord Darion Mograine'), + (-1609218, 'Obey me, blade!',14692,1,0,0,'Highlord Darion Mograine'), + (-1609219, 'You will do as I command! I am in control here!',14693,0,0,0,'Highlord Darion Mograine'), + (-1609220, 'I can not... the blade fights me.',14694,0,0,0,'Highlord Darion Mograine'), + (-1609221, 'What is happening to me?',14695,0,0,0,'Highlord Darion Mograine'), + (-1609222, 'Power...wanes...',14696,0,0,0,'Highlord Darion Mograine'), + (-1609223, 'Ashbringer defies me...',14697,0,0,0,'Highlord Darion Mograine'), + (-1609224, 'Minions, come to my aid!',14698,0,0,0,'Highlord Darion Mograine'), +-- After the fight + (-1609225, 'You cannot win, Darion!',14584,1,0,0,'Highlord Tirion Fordring'), + (-1609226, 'Bring them before the chapel!',14585,1,0,0,'Highlord Tirion Fordring'), + (-1609227, 'Stand down, death knights. We have lost... The Light... This place... No hope...',14699,0,0,68,'Highlord Darion Mograine'), + (-1609228, 'Have you learned nothing, boy? You have become all that your father fought against! Like that coward, Arthas, you allowed yourself to be consumed by the darkness...the hate... Feeding upon the misery of those you tortured and killed!',14586,0,0,378,'Highlord Tirion Fordring'), + (-1609229, 'Your master knows what lies beneath the chapel. It is why he dares not show his face! He\'s sent you and your death knights to meet their doom, Darion.',14587,0,0,25,'Highlord Tirion Fordring'), + (-1609230, 'What you are feeling right now is the anguish of a thousand lost souls! Souls that you and your master brought here! The Light will tear you apart, Darion!',14588,0,0,1,'Highlord Tirion Fordring'), + (-1609231, 'Save your breath, old man. It might be the last you ever draw.',14700,0,0,25,'Highlord Darion Mograine'), + (-1609232, 'My son! My dear, beautiful boy!',14493,0,0,0,'Highlord Alexandros Mograine'), + (-1609233, 'Father!',14701,0,0,5,'Highlord Darion Mograine'), + (-1609234, 'Argh...what...is...',14702,0,0,68,'Highlord Darion Mograine'), + (-1609235, 'Father, you have returned!',14703,0,0,0,'Darion Mograine'), + (-1609236, 'You have been gone a long time, father. I thought...',14704,0,0,0,'Darion Mograine'), + (-1609237, 'Nothing could have kept me away from here, Darion. Not from my home and family.',14494,0,0,1,'Highlord Alexandros Mograine'), + (-1609238, 'Father, I wish to join you in the war against the undead. I want to fight! I can sit idle no longer!',14705,0,0,6,'Darion Mograine'), + (-1609239, 'Darion Mograine, you are barely of age to hold a sword, let alone battle the undead hordes of Lordaeron! I couldn\'t bear losing you. Even the thought...',14495,0,0,1,'Highlord Alexandros Mograine'), + (-1609240, 'If I die, father, I would rather it be on my feet, standing in defiance against the undead legions! If I die, father, I die with you!',14706,0,0,6,'Darion Mograine'), + (-1609241, 'My son, there will come a day when you will command the Ashbringer and, with it, mete justice across this land. I have no doubt that when that day finally comes, you will bring pride to our people and that Lordaeron will be a better place because of you. But, my son, that day is not today.',14496,0,0,1,'Highlord Alexandros Mograine'), + (-1609242, 'Do not forget...',14497,0,0,6,'Highlord Alexandros Mograine'), + (-1609243, 'Touching...',14803,1,0,0,'The Lich King'), + (-1609244, 'You have\'ve betrayed me! You betrayed us all you monster! Face the might of Mograine!',14707,1,0,0,'Highlord Darion Mograine'), + (-1609245, 'He\'s mine now...',14805,0,0,0,'The Lich King'), + (-1609246, 'Pathetic...',14804,0,0,0,'The Lich King'), + (-1609247, 'You\'re a damned monster, Arthas!',14589,0,0,25,'Highlord Tirion Fordring'), + (-1609248, 'You were right, Fordring. I did send them in to die. Their lives are meaningless, but yours...',14806,0,0,1,'The Lich King'), + (-1609249, 'How simple it was to draw the great Tirion Fordring out of hiding. You\'ve left yourself exposed, paladin. Nothing will save you...',14807,0,0,1,'The Lich King'), + (-1609250, 'ATTACK!!!',14488,1,0,0,'Lord Maxwell Tyrosus'), + (-1609251, 'APOCALYPSE!',14808,1,0,0,'The Lich King'), + (-1609252, 'That day is not today...',14708,0,0,0,'Highlord Darion Mograine'), + (-1609253, 'Tirion!',14709,1,0,0,'Highlord Darion Mograine'), + (-1609254, 'ARTHAS!!!!',14591,1,0,0,'Highlord Tirion Fordring'), + (-1609255, 'What is this?',14809,1,0,0,'The Lich King'), + (-1609256, 'Your end.',14592,1,0,0,'Highlord Tirion Fordring'), + (-1609257, 'Impossible...',14810,1,0,0,'The Lich King'), + (-1609258, 'This... isn\'t... over...',14811,1,0,25,'The Lich King'), + (-1609259, 'When next we meet it won\'t be on holy ground, paladin.',14812,1,0,1,'The Lich King'), + (-1609260, 'Rise, Darion, and listen...',14593,0,0,0,'Highlord Tirion Fordring'), + (-1609261, 'We have all been witness to a terrible tragedy. The blood of good men has been shed upon this soil! Honorable knights, slain defending their lives - our lives!',14594,0,0,0,'Highlord Tirion Fordring'), + (-1609262, 'And while such things can never be forgotten, we must remain vigilant in our cause!',14595,0,0,0,'Highlord Tirion Fordring'), + (-1609263, 'The Lich King must answer for what he has done and must not be allowed to cause further destruction to our world.',14596,0,0,0,'Highlord Tirion Fordring'), + (-1609264, 'I make a promise to you now, brothers and sisters: The Lich King will be defeated! On this day, I call for a union.',14597,0,0,0,'Highlord Tirion Fordring'), + (-1609265, 'The Argent Dawn and the Order of the Silver Hand will come together as one! We will succeed where so many before us have failed!',14598,0,0,0,'Highlord Tirion Fordring'), + (-1609266, 'We will take the fight to Arthas and tear down the walls of Icecrown!',14599,0,0,15,'Highlord Tirion Fordring'), + (-1609267, 'The Argent Crusade comes for you, Arthas!',14600,1,0,15,'Highlord Tirion Fordring'), + (-1609268, 'So too do the Knights of the Ebon Blade... While our kind has no place in your world, we will fight to bring an end to the Lich King. This I vow!',14710,0,0,1,'Highlord Darion Mograine'), +-- Emotes + (-1609269, 'Thousands of Scourge rise up at the Highlord\'s command.',0,2,0,0,''), + (-1609270, 'The army marches towards Light\'s Hope Chapel.',0,2,0,0,''), + (-1609271, 'After over a hundred Defenders of the Light fall, Highlord Tirion Fordring arrives.',0,2,0,0,''), + (-1609272, '%s flee',0,2,0,0,'Orbaz'), + (-1609273, '%s kneels in defeat before Tirion Fordring.',0,2,0,0,'Highlord Darion Mograine'), + (-1609274, '%s arrives.',0,2,0,0,'Highlord Alexandros Mograine'), + (-1609275, '%s becomes a shade of his past, and walks up to his father.',0,2,0,0,'Highlord Darion Mograine'), + (-1609276, '%s hugs his father.',0,2,0,0,'Darion Mograine'), + (-1609277, '%s disappears, and the Lich King appears.',0,2,0,0,'Alexandros'), + (-1609278, '%s becomes himself again...and is now angry.',0,2,0,0,'Highlord Darion Mograine'), + (-1609279, '%s casts a spell on Tirion.',0,2,0,0,'The Lich King'), + (-1609280, '%s gasps for air.',0,2,0,0,'Highlord Tirion Fordring'), + (-1609281, '%s casts a powerful spell, killing the Defenders and knocking back the others.',0,2,0,0,'The Lich King'), + (-1609282, '%s throws the Corrupted Ashbringer to Tirion, who catches it. Tirion becomes awash with Light, and the Ashbringer is cleansed.',0,2,0,0,'Highlord Darion Mograine'), + (-1609283, '%s collapses.',0,2,0,0,'Highlord Darion Mograine'), + (-1609284, '%s charges towards the Lich King, Ashbringer in hand and strikes the Lich King.',0,2,0,0,'Highlord Tirion Fordring'), + (-1609285, '%s disappears. Tirion walks over to where Darion lay',0,2,0,0,'The Lich King'), + (-1609286, 'Light washes over the chapel �X the Light of Dawn is uncovered.',0,2,0,0,''); + +DELETE FROM `script_texts` WHERE entry BETWEEN -1609293 AND -1609289; +INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +-- Emotes + (-1609289, "Orbaz flees.",0,2,0,0,"Orbaz"), + (-1609290, "Highlord Darion Mograine kneels in defeat before Tirion Fordring.",0,3,0,0,"Highlord Darion Mograine"), + (-1609291, "Darion Mograine hugs his father.",0,2,0,0,"Darion Mograine"), + (-1609292, "Highlord Tirion Fordring gasps for air.",0,2,0,0,"Highlord Tirion Fordring"), + (-1609293, "Highlord Darion Mograine collapses.",0,2,0,0,"Highlord Darion Mograine"); + +DELETE FROM `script_waypoint` WHERE entry=29173; +INSERT INTO `script_waypoint` VALUES + (29173, 0, 2431.639, -5137.05, 83.843, 0, 'intro'), + (29173, 1, 2319.242, -5266.486, 82.825, 0, 'summon & on hold'), + (29173, 2, 2318.775, -5266.832, 82.783, 0, 'cast light of dawn'), + (29173, 3, 2280.812, -5284.091, 82.608, 0, 'move to here and start'), + (29173, 4, 2280.727, -5286.839, 82.930, 0, 'move forward to talk'), + (29173, 5, 2280.812, -5284.091, 82.608, 0, 'when baba pop'), + (29173, 6, 2281.461, -5263.014, 81.164, 0, 'charge to lich king'), + (29173, 7, 2257.479, -5296.702, 82.165, 0, 'being kicked by Lich King'), + (29173, 8, 2261.237, -5294.983, 82.167, 0, 'throw'), + (29173, 9, 2259.34, -5294.379, 82.167, 0, 'event end'); + +-- Quest The Gift That Keeps On Giving - script texts +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1609300 AND -1609311; +INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +(-1609300, "Smell flesh... close...",0,0,0,0,"SAY_SCARLET_GHOUL_SPAWN1"), +(-1609301, "The grave calls to us all!",0,0,0,0,"SAY_SCARLET_GHOUL_SPAWN2"), +(-1609302, "GIVE ME BRAINS!",0,0,0,0,"SAY_SCARLET_GHOUL_SPAWN3"), +(-1609303, "Poppy!",0,0,0,0,"SAY_SCARLET_GHOUL_SPAWN4"), +(-1609304, "Mommy?",0,0,0,0,"SAY_SCARLET_GHOUL_SPAWN5"), +(-1609305, "So hungry...",0,0,0,0,"SAY_SCARLET_GHOUL_SPAWN6"), +(-1609306, "The pit calls, minion. Go to it, NOW!",0,0,0,0,"SAY_SCARLET_GOTHIK1"), +(-1609307, "GHOUL! PIT! NOW!",0,0,0,0,"SAY_SCARLET_GOTHIK2"), +(-1609308, "Back you mindless wretch! Back to the pit!",0,0,0,0,"SAY_SCARLET_GOTHIK3"), +(-1609309, "It puts the ghoul in the pit or else it gets the lash!",0,0,0,0,"SAY_SCARLET_GOTHIK4"), +(-1609310, "Get in the pit you worthless pile of garbage!",0,0,0,0,"SAY_SCARLET_GOTHIK5"); + +-- Quest: Powering Our Defenses (8490) +DELETE FROM script_texts WHERE entry=-1999811; +INSERT INTO script_texts (entry,content_default,type,comment) VALUES +(-1999811,'%s releases the last of its energies into nearby runestone, succesfully reactivating it.',2,'INFUSED_CRYSTAL_EMOTE'); diff --git a/addition/710_quests_scripts_mangos.sql b/addition/710_quests_scripts_mangos.sql new file mode 100644 index 000000000..70ff1b66e --- /dev/null +++ b/addition/710_quests_scripts_mangos.sql @@ -0,0 +1,100 @@ +-- quest 12801 +UPDATE `creature_template` SET `AIName` = '', `ScriptName`='npc_highlord_darion_mograine' WHERE `entry`='29173'; +UPDATE `creature_template` SET `AIName` = '', `ScriptName`='npc_the_lich_king_tirion_dawn' WHERE `entry` in (29183,29175); +UPDATE `creature_template` SET `AIName` = '', `ScriptName`='npc_minibosses_dawn_of_light' WHERE `entry` IN (29199,29204,29200); +UPDATE `creature_template` SET `AIName` = '', `ScriptName`='mob_acherus_ghoul' WHERE `entry`='29219'; +UPDATE `creature_template` SET `AIName` = '', `ScriptName`='mob_warrior_of_the_frozen_wastes' WHERE `entry`='29206'; + +UPDATE `creature_template` SET `AIName`='EventAI', `unit_flags`=0,`type_flags`=8 WHERE entry IN (29174,29182,29186,29190,29219,29206,29176,29178,29179,29180,29177,29181); + +DELETE FROM `spell_script_target` WHERE `entry` in (53658, 53679, 53701, 53705, 53706, 53677, 53685); +INSERT INTO `spell_script_target` VALUES (53679, 1, 29183); +INSERT INTO `spell_script_target` VALUES (53701, 1, 29175); +INSERT INTO `spell_script_target` VALUES (53705, 1, 29183); +INSERT INTO `spell_script_target` VALUES (53706, 1, 29183); +INSERT INTO `spell_script_target` VALUES (53677, 1, 29227); +INSERT INTO `spell_script_target` VALUES (53685, 1, 29175); + +DELETE FROM `creature_ai_scripts` WHERE `id` BETWEEN 90051 AND 90084; +INSERT INTO `creature_ai_scripts` VALUES ('90063', '29174', '14', '0', '100', '3', '10000', '20', '5000', '10000', '11', '29427', '6', '1', '0', '0', '0', '0', '0', '0', '0', '0', 'Defender of the Light - SPELL_HOLY_LIGHT1'); +INSERT INTO `creature_ai_scripts` VALUES ('90064', '29174', '4', '0', '100', '0', '0', '0', '0', '0', '11', '53625', '1', '5', '0', '0', '0', '0', '0', '0', '0', '0', 'Defender of the Light aggro'); +INSERT INTO `creature_ai_scripts` VALUES ('90065', '29174', '0', '0', '100', '3', '10000', '20000', '10000', '20000', '11', '53625', '5', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Defender of the Light - SPELL_HEROIC_LEAP'); +INSERT INTO `creature_ai_scripts` VALUES ('90066', '29174', '0', '0', '100', '3', '10000', '20000', '10000', '20000', '11', '53643', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Defender of the Light - SPELL_HOLY_STRIKE'); +INSERT INTO `creature_ai_scripts` VALUES ('90067', '29174', '0', '0', '100', '3', '10000', '20000', '10000', '20000', '11', '53638', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Defender of the Light - SPELL_HOLY_WRATH'); +INSERT INTO `creature_ai_scripts` VALUES ('90068', '29174', '0', '0', '100', '3', '10000', '20000', '10000', '20000', '11', '53629', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Defender of the Light - SPELL_UPPERCUT'); +INSERT INTO `creature_ai_scripts` VALUES ('90069', '29182', '14', '0', '100', '3', '10000', '20', '5000', '10000', '11', '33642', '6', '1', '0', '0', '0', '0', '0', '0', '0', '0', 'Rimblat Earthshatter - SPELL_CHAIN_HEAL'); +INSERT INTO `creature_ai_scripts` VALUES ('90070', '29182', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '53630', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Rimblat Earthshatter - SPELL_THUNDER'); +INSERT INTO `creature_ai_scripts` VALUES ('90071', '29186', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '53633', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Rampaging Abomination - SPELL_CLEAVE1'); +INSERT INTO `creature_ai_scripts` VALUES ('90072', '29186', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '50335', '5', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Rampaging Abomination - SPELL_SCOURGE_HOOK'); +INSERT INTO `creature_ai_scripts` VALUES ('90073', '29190', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '53634', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Flesh Behemoth - SPELL_SCOURGE_HOOK'); +INSERT INTO `creature_ai_scripts` VALUES ('90074', '29190', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '36706', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Flesh Behemoth - SPELL_THUNDERCLAP'); +INSERT INTO `creature_ai_scripts` VALUES ('90075', '29190', '0', '0', '100', '3', '5000', '10000', '5000', '10000', '11', '53627', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Flesh Behemoth - SPELL_THUNDERCLAP'); +INSERT INTO `creature_ai_scripts` VALUES ('90076', '29219', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '53632', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Volatile Ghoul - SPELL_GHOULPLOSION'); +INSERT INTO `creature_ai_scripts` VALUES ('90077', '29206', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '53631', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Warrior of the Frozen Wastes - SPELL_CLEAVE'); +INSERT INTO `creature_ai_scripts` VALUES ('90078', '29176', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '53631', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Korfax - SPELL_CLEAVE'); +INSERT INTO `creature_ai_scripts` VALUES ('90079', '29176', '0', '0', '100', '3', '10000', '20000', '10000', '10000', '11', '53625', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Korfax - SPELL_CLEAVE'); +INSERT INTO `creature_ai_scripts` VALUES ('90080', '29177', '14', '0', '100', '3', '10000', '20', '5000', '10000', '11', '37979', '6', '1', '0', '0', '0', '0', '0', '0', '0', '0', 'Commander Eligor Dawnbringer - SPELL_HOLY_LIGHT2'); +INSERT INTO `creature_ai_scripts` VALUES ('90081', '29181', '14', '0', '100', '3', '10000', '20', '5000', '10000', '11', '20664', '6', '1', '0', '0', '0', '0', '0', '0', '0', '0', 'Rayne - SPELL_REJUVENATION'); +INSERT INTO `creature_ai_scripts` VALUES ('90082', '29181', '14', '0', '100', '3', '10000', '20', '5000', '10000', '11', '25817', '6', '1', '0', '0', '0', '0', '0', '0', '0', '0', 'Rayne - SPELL_TRANQUILITY'); +INSERT INTO `creature_ai_scripts` VALUES ('90083', '29181', '0', '0', '100', '3', '10000', '20000', '10000', '20000', '11', '20678', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Rayne - SPELL_STARFALL'); +INSERT INTO `creature_ai_scripts` VALUES ('90084', '29181', '0', '0', '100', '3', '10000', '20000', '10000', '20000', '11', '21807', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Rayne - SPELL_WRATH'); + +-- YTDB cleanup +DELETE FROM `creature` WHERE `map` = 609 AND `guid` IN (116863); +DELETE FROM `creature` WHERE `map` = 609 AND `id` IN (29219,29206,29190); + +-- quest 12701 +DELETE FROM `spell_target_position` WHERE `id` = 52462; +INSERT INTO `spell_target_position` (id,target_map,target_position_x,target_position_y,target_position_z,target_orientation) VALUES (52462,609,2388.507568, -5900.213867, 108.645972, 3.797623); + +-- Quest: Drake Hunt (11940/11919) +UPDATE `creature_template` SET ScriptName='npc_nexus_drake', AIName='' WHERE entry = 26127; + +-- Quest: Merciful Freedom (11676) +UPDATE gameobject_template SET ScriptName='go_scourge_cage' WHERE entry IN (187854,187855,187856,187857,187858,187859,187860,187862,187863,187864,187865,187866,187867,187868,187870,187871,187872,187873,187874,187861,190803); + +-- Quest The Gift That Keeps On Giving +-- item spell script targets (Scarlet Miners) +DELETE FROM spell_script_target WHERE entry = 52479; +INSERT INTO spell_script_target VALUES +(52479, 1, 28819), +(52479, 1, 28822), +(52479, 1, 28841); + +UPDATE `creature_template` SET `AIName` = "EventAI" WHERE `entry` = 28846; +UPDATE `creature_template` SET `ScriptName` = "mob_scarlet_ghoul" WHERE `entry` = 28845; + +DELETE FROM `creature_ai_texts` WHERE `entry` IN (-286102, -286101, -286100); +INSERT INTO `creature_ai_texts` VALUES +(-286100, "Die, Scourge filth!", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Scarlet Ghost SAY1"), +(-286101, "It won't be that easy, friend!", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Scarlet Ghost SAY2"), +(-286102, "I'll take you with me!", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Scarlet Ghost SAY3"); + +DELETE FROM `creature_ai_scripts` WHERE `creature_id` = 28846; +INSERT INTO `creature_ai_scripts` VALUES +(2884601, 28846, 11, 0, 100, 0, 0, 0, 0, 0, 1, -286100, -286101, -286102, 0, 0, 0, 0, 0, 0, 0, 0, "Scarlet Ghost - Random say at spawn"); + +-- Quest: Abduction (11590) +UPDATE `creature_template` SET +minhealth=6387, +maxhealth=7185, +minlevel=64, +maxlevel=70, +minmana=7031, +maxmana=7196 +WHERE entry=25474; + +UPDATE `creature_template` SET +`ScriptName`='npc_beryl_sorcerer' , AIName='' +WHERE entry=25316; + +-- Quest: Powering Our Defenses (8490) +UPDATE `creature_template` SET ScriptName='npc_infused_crystal' WHERE entry = 16364; + +-- Enraged Wraith +DELETE FROM `creature` WHERE id = 17086; +UPDATE `creature_template` SET AIName='EventAI', flags_extra=flags_extra|64 WHERE entry=17086; + +DELETE FROM `creature_ai_scripts` WHERE creature_id = 17086; +INSERT INTO `creature_ai_scripts` VALUES +(1708601,17086,2,0,100,0,25,0,0,0,11,8599,0,1,1,-106,0,0,0,0,0,0,'Enraged Wraith - Cast Enrage on 50% HP'); diff --git a/addition/712_halls_of_stone_mangos.sql b/addition/712_halls_of_stone_mangos.sql new file mode 100644 index 000000000..072e680c4 --- /dev/null +++ b/addition/712_halls_of_stone_mangos.sql @@ -0,0 +1,9 @@ +UPDATE `creature_template` SET `ScriptName` = 'boss_krystallus' WHERE `entry` =27977 LIMIT 1 ; + +UPDATE `gameobject` SET `state` = '1' WHERE `guid` =53556; +UPDATE `gameobject` SET `state` = '1' WHERE `guid` =53560; + +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `entry` =191293; +UPDATE `gameobject_template` SET `faction` = '0', `flags` = '0' WHERE `entry` IN (193996,190586); +UPDATE `gameobject` SET `phaseMask` = '65535' WHERE `guid` =37577; +UPDATE `gameobject` SET `phaseMask` = '65535' WHERE `guid` =37583; diff --git a/addition/712_halls_of_stone_scriptdev2.sql b/addition/712_halls_of_stone_scriptdev2.sql new file mode 100644 index 000000000..94be15d20 --- /dev/null +++ b/addition/712_halls_of_stone_scriptdev2.sql @@ -0,0 +1,14 @@ +DELETE FROM `script_texts` WHERE `entry` IN +('-1712001','-1712002','-1712003','-1712004','-1712005','-1712006','-1712007','-1712008'); + +INSERT IGNORE INTO `script_texts` +(`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) +VALUES +('-1712001', 'Soft meat! Come to me!', 'Soft meat! Come to me!', NULL, NULL, NULL, NULL, NULL, NULL, 'Мягкие пришли! Заходите!', '0', '0', '0', '0', NULL), +('-1712002', 'Get it!', 'Get it!', NULL, NULL, NULL, NULL, NULL, NULL, 'Лови кирпич!', '0', '0', '0', '0', NULL), +('-1712003', 'Into the ice!', 'Into the ice!', NULL, NULL, NULL, NULL, NULL, NULL, 'Всех заморожу!', '0', '0', '0', '0', NULL), +('-1712004', 'Stone curse!', 'Stone curse!', NULL, NULL, NULL, NULL, NULL, NULL, 'Окаменей!', '0', '0', '0', '0', NULL), +('-1712005', 'Gr-r-r-r!', 'Gr-r-r-r!', NULL, NULL, NULL, NULL, NULL, NULL, 'Ух, как я зол!', '0', '0', '0', '0', NULL), +('-1712006', 'It is cool!', 'It is cool!', NULL, NULL, NULL, NULL, NULL, NULL, 'Что, съел?', '0', '0', '0', '0', NULL), +('-1712007', 'O, no...', 'O, no...', NULL, NULL, NULL, NULL, NULL, NULL, 'Не может быть...', '0', '0', '0', '0', NULL), +('-1712008', 'Enrage!', 'Enrage!', NULL, NULL, NULL, NULL, NULL, NULL, 'Ну все, вы меня достали...', '0', '0', '0', '0', NULL); diff --git a/addition/715_trial_of_the_champion_mangos.sql b/addition/715_trial_of_the_champion_mangos.sql new file mode 100644 index 000000000..1c50d7396 --- /dev/null +++ b/addition/715_trial_of_the_champion_mangos.sql @@ -0,0 +1,27 @@ +-- instance +UPDATE instance_template SET ScriptName='instance_trial_of_the_champion' WHERE map=650; + +-- announcers +UPDATE creature_template SET npcflag=1, scriptname='npc_toc5_announcer' WHERE entry IN (35004, 35005); + +-- grand champions +UPDATE creature_template SET scriptname='mob_toc5_warrior' WHERE entry IN (34705, 35572); +UPDATE creature_template SET scriptname='mob_toc5_mage' WHERE entry IN (34702, 35569); +UPDATE creature_template SET scriptname='mob_toc5_shaman' WHERE entry IN (34701, 35571); +UPDATE creature_template SET scriptname='mob_toc5_hunter' WHERE entry IN (34657, 35570); +UPDATE creature_template SET scriptname='mob_toc5_rogue' WHERE entry IN (34703, 35617); + +-- argent challenge +UPDATE creature_template SET scriptname='boss_eadric' WHERE entry=35119; +UPDATE creature_template SET scriptname='boss_paletress' WHERE entry=34928; +UPDATE creature_template SET scriptname='mob_toc5_memory' WHERE entry IN (35052, 35041, 35033, 35046, 35043, 35047, 35044, 35039, 35034, 35049, 35030, 34942, 35050, 35042, 35045, 35037, 35031, 35038, 35029, 35048, 35032, 35028, 35040, 35036, 35051); + +-- black knight +UPDATE creature_template SET faction_a=14, faction_h=14, scriptname='mob_toc5_risen_ghoul' WHERE entry IN (35545, 35564); +UPDATE creature_template SET scriptname='boss_black_knight' WHERE entry=35451; + +-- free spells for creatures +UPDATE `creature_template` SET `spell1` = '0',`spell2` = '0',`spell3` = '0',`spell4` = '0' WHERE `creature_template`.`entry` IN +(34705,34702,34701,34657,34703,35572,35569,35571,35570,35617,35119,34928,35451,35545,35564,35004,35005,35052,35041,35033,35046,35043,35047,35044,35039,35034,35049,35030,34942,35050,35042,35045,35037,35031,35038,35029,35048,35032,35028,35040,35036,35051); +UPDATE `creature_template` SET `spell1` = '0',`spell2` = '0',`spell3` = '0',`spell4` = '0' WHERE `creature_template`.`entry` IN +(12002,12001,12000,12003,12004,12010,12484,12485,12447,12454,12441,12438,12453,12443,12437,12445,12725,12452,12486,12442,12482,12440,12483,12451,12456,12449,12455,12450,12487,12446,12011,12012,12436,12005,12007,12006,12009,12008); diff --git a/addition/716_the_violet_hold_mangos.sql b/addition/716_the_violet_hold_mangos.sql new file mode 100644 index 000000000..347994291 --- /dev/null +++ b/addition/716_the_violet_hold_mangos.sql @@ -0,0 +1,46 @@ +/* VIOLET HOLD */ +UPDATE `instance_template` SET `ScriptName`='instance_violet_hold' WHERE `map`=608; + +UPDATE `creature_template` SET `ScriptName`='boss_erekem' WHERE entry=29315; +UPDATE `creature_template` SET `ScriptName`='mob_erekem_guard' WHERE entry=29395; +UPDATE `creature_template` SET `ScriptName`='boss_moragg' WHERE entry=29316; +UPDATE `creature_template` SET `ScriptName`='boss_ichoron' WHERE entry=29313; +UPDATE `creature_template` SET `ScriptName`='mob_ichor_globule' WHERE entry=29321; +UPDATE `creature_template` SET `ScriptName`='boss_xevozz' WHERE entry=29266; +UPDATE `creature_template` SET `ScriptName`='mob_ethereal_sphere' WHERE entry=29271; +UPDATE `creature_template` SET `ScriptName`='boss_lavanthor' WHERE entry=29312; +UPDATE `creature_template` SET `ScriptName`='boss_zuramat'WHERE entry=29314; +UPDATE `creature_template` SET `ScriptName`='mob_zuramat_sentry' WHERE entry=29364; +UPDATE `creature_template` SET `ScriptName`='boss_cyanigosa' WHERE entry=31134; +UPDATE `creature_template` SET `ScriptName`='npc_azure_saboteur' WHERE entry=31079; +UPDATE `creature_template` SET `ScriptName`='mob_vh_dragons', AIName='' WHERE entry IN (30666,30668,30667,32191,30660,30695,30663,30661,30664,30662); +UPDATE `creature_template` SET `ScriptName`='npc_sinclari', `npcflag`=1 WHERE entry=30658; +UPDATE `creature_template` SET `ScriptName`='npc_violet_portal' WHERE entry=31011; +UPDATE `creature_template` SET `ScriptName`='npc_door_seal_vh' WHERE entry=30896; + +-- Lieuntenant Sinclari (30658) +UPDATE `creature` SET `Spawntimesecs`=180 WHERE id=30658; + + +-- void sentry template (29364) + +UPDATE `creature_template` SET faction_A=16, faction_H=16, minlevel=77, maxlevel=77, maxhealth=500, minhealth=500 WHERE entry=29364; +UPDATE `creature_template` SET `faction_A`=16,`faction_H`=16 WHERE `entry`=31518; +UPDATE `creature_template` SET `AIName`='' WHERE entry IN (31011,30695,31079,30666,30668,30667,32191,30660,30695,30663,30661,30664,30662,31118,29395,31513); + +-- triggers +UPDATE `creature_template` SET flags_extra=flags_extra|128 WHERE entry IN (30857,30883,29326,30896); + +DELETE FROM `creature` WHERE id=31011; + +DELETE FROM `spell_script_target` WHERE `entry` =54160; +INSERT INTO `spell_script_target` VALUES (54160, 1, 29266); +DELETE FROM `spell_script_target` WHERE `entry`=59474; +INSERT INTO `spell_script_target` VALUES +(59474,1,29266), +(59474,1,31511); + +-- immune masks (charm, fear, root, silence, sleep, snare, stun, freeze, knockout, polymorph, banish, shackle, horror, sapped) + +UPDATE `creature_template` SET mechanic_immune_mask=mechanic_immune_mask|1|16|64|256|512|1024|2048|4096|8192|65536|131072|524288|8388608|536870912 +WHERE `entry` IN (29315,29395,29316,29313,29321,29266,29271,29312,29314,31134,31511,31514,31509,31508,31512,31507,31510,31515,31513,31506); diff --git a/addition/716_the_violet_hold_scriptdev2_text.sql b/addition/716_the_violet_hold_scriptdev2_text.sql new file mode 100644 index 000000000..37dc11e0b --- /dev/null +++ b/addition/716_the_violet_hold_scriptdev2_text.sql @@ -0,0 +1,76 @@ +-- -1 608 000 VIOLET HOLD +DELETE FROM `script_texts` WHERE entry BETWEEN -1608000 AND -1608066; +INSERT IGNORE INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES +-- common +(-1608008,'Ichoron\'s Protective Bubble shatters!',0,3,0,'EMOTE_ICHORON_PROTECTIVE_BUBBLE'), +-- Lieutenant Sinclari (30658) +(-1608009,'You did it! You held the Blue Dragonblight back and defeated their commander. Amazing work!',0,1,0,'sinclair SAY_END'), +-- Erekem +(-1608010, 'Notcawwget in way ofrrak-rrakflee!', 14219, 1, 0, 'erekem SAY_AGGRO'), +(-1608011, '...', 14222, 1, 0, 'erekem SAY_SLAY_1'), +(-1608012, 'Precious life ... wasted.', 14223, 1, 0, 'erekem SAY_SLAY_2'), +(-1608013, 'Only strong ... survive.', 14224, 1, 0, 'erekem SAY_SLAY_3'), +(-1608014, 'Nokaw, kawflee...', 14225, 1, 0, 'erekem SAY_DEATH'), +(-1608015, 'Free tommfly onw. Ra-aak... Not find usekh-ekh! Escape!', 14218, 1, 0, 'erekem SAY_SPAWN'), +(-1608016, 'My-raaakfavorite! Awk awk awk! Raa-kaa!', 14220, 1, 0, 'erekem SAY_ADD_KILLED'), +(-1608017, 'Nasty little...A-ak, kaw! Kill! Yes, kill you!', 14221, 1, 0, 'erekem SAY_BOTH_ADDS_KILLED'), +-- Ichoron +(-1608018, 'Stand aside, mortals!', 14230, 1, 0, 'ichoron SAY_AGGRO'), +(-1608019, 'I am a force of nature!', 14234, 1, 0, 'ichoron SAY_SLAY_1'), +(-1608020, 'I shall pass!', 14235, 1, 0, 'ichoron SAY_SLAY_2'), +(-1608021, 'You can not stop the tide!', 14236, 1, 0, 'ichoron SAY_SLAY_3'), +(-1608022, 'I... recede.', 14237, 1, 0, 'ichoron SAY_DEATH'), +(-1608023, 'I... am fury... unrestrained!', 14239, 1, 0, 'ichoron SAY_SPAWN'), +(-1608024, 'I shall consume, decimate, devastate, and destroy! Yield now to the wrath of the pounding sea!', 14231, 1, 0, 'ichoron SAY_ENRAGE'), +(-1608025, 'I will not be contained! Ngyah!!', 14233, 1, 0, 'ichoron SAY_SHATTER'), +(-1608026, 'Water can hold any form, take any shape... overcome any obstacle.', 14232, 1, 0, 'ichoron SAY_BUBBLE'), +-- Xevozz +(-1608027, 'It seems my freedom must be bought with blood...', 14499, 1, 0, 'xevozz SAY_AGGRO'), +(-1608028, 'Nothing personal.', 14504, 1, 0, 'xevozz SAY_SLAY_1'), +(-1608029, 'Business concluded.', 14505, 1, 0, 'xevozz SAY_SLAY_2'), +(-1608030, 'Profit!', 14506, 1, 0, 'xevozz SAY_SLAY_3'), +(-1608031, 'This is an... unrecoverable... loss.', 14507, 1, 0, 'xevozz SAY_DEATH'), +(-1608032, 'Back in business! Now to execute an exit strategy.', 14498, 1, 0, 'xevozz SAY_SPAWNED'), +(-1608033, 'It would seem that a renegotiation is in order.', 14503, 1, 0, 'xevozz SAY_CHARGED'), +(-1608034, 'The air teems with latent energy... quite the harvest!', 14501, 1, 0, 'xevozz SAY_REPEAT_SUMMON_1'), +(-1608035, 'Plentiful, exploitable resources... primed for acquisition!', 14502, 1, 0, 'xevozz SAY_REPEAT_SUMMON_2'), +(-1608036, 'Intriguing... a high quantity of arcane energy is near. Time for some prospecting...', 14500, 1, 0, 'xevozz SAY_SUMMON_ENERGY'), +-- Zuramat +(-1608037, 'Eradicate.', 13996, 1, 0, 'zuramat SAY_AGGRO'), +(-1608038, 'More... energy.', 13999, 1, 0, 'zuramat SAY_SLAY_1'), +(-1608039, 'Relinquish.', 14000, 1, 0, 'zuramat SAY_SLAY_2'), +(-1608040, 'Fall... to shadow.', 14001, 1, 0, 'zuramat SAY_SLAY_3'), +(-1608041, 'Disperse.', 14002, 1, 0, 'zuramat SAY_DEATH'), +(-1608042, 'I am... renewed.', 13995, 1, 0, 'zuramat SAY_SPAWN'), +(-1608043, 'Know... my... pain.', 13997, 1, 0, 'zuramat SAY_SHIELD'), +(-1608044, 'Gaze... into the void.', 13998, 1, 0, 'zuramat SAY_WHISPER'), +-- Cyanigosa +(-1608045,'A valiant defense, but this city must be razed. I will fulfill Malygos wishes myself!', 13946, 1, 0,'A_VH_Cyanigosa_Spawn'), +(-1608046,'We finish this now, champions of Kirin Tor!',13947,1,0,'A_VH_Cyanigosa_Aggro'), +(-1608047,'Shiver and die!',13948,1,0,'A_VH_Cyanigosa_BreathAttack'), +(-1608048,'The world has forgotten what true magic is! Let this be a reminder!',13949,1,0,'A_VH_Cyanigosa_SpecialAttack01'), +(-1608049,'Who among you can withstand my power?',13950,1,0,'A_VH_Cyanigosa_SpecialAttack02'), +(-1608050,'Am I interrupting?',13951,1,0,'A_VH_Cyanigosa_Disruption'), +(-1608051,'I will end the Kirin Tor!',13952,1,0,'A_VH_Cyanigosa_Slay01'), +(-1608052,'Dalaran will fall!',13953,1,0,'A_VH_Cyanigosa_Slay02'), +(-1608053,'So ends your defiance of the Spell-Weaver!',13954,1,0,'A_VH_Cyanigosa_Slay03'), +(-1608054,'Perhaps... we have... underestimated... you.',13955,1,0,'A_VH_Cyanigosa_Death01'), +-- Azures +(-1608055,'The Kirin Tor must be stopped!',0,0,0,'AZURE_SAY_AGGRO_1'), +(-1608056,'Dalaran must fall!',0,0,0,'AZURE_SAY_AGGRO_2'), +(-1608057,'The Nexus War will not be stopped!',0,0,0,'AZURE_SAY_AGGRO_3'), +(-1608058,'For the Spellweaver!',0,0,0,'AZURE_SAY_AGGRO_4'), +(-1608059,'The destruction of Dalaran is inevitable!',0,1,0,'Portal Keeper/Guardian AGGRO_1'), +(-1608060,'The portal has stabilized! Attack!',0,1,0,'Portal Keeper/Guardian AGGRO_2'), +(-1608064,'The way into Dalaran has been opened!',0,1,0,'Portal Guardian AGGRO_3'), +(-1608061,'More portals will take this one\'s place!',0,1,0,'Portal Keeper/Guardian DEATH_1'), +(-1608062,'Why do you defend the Kirin Tor...',0,1,0,'Portal Keeper/Guardian DEATH_2'), +(-1608063,'My death will not stop the invasion!',0,1,0,'Portal Keeper/Guardian DEATH_2'), +(-1608065,'Destroy all who stand against us!',0,0,0,'Azure Captain AGGRO_1'); + +-- gossips +-- Lieutenant Sinclari (30658) +DELETE FROM `gossip_texts` WHERE `entry` IN (-3608001,-3608000); +INSERT INTO `gossip_texts` (entry,content_default,comment) VALUES +(-3608001,'Get your people to safety, we\'ll keep the Blue Dragonflight\'s forces at bay.','sinclari GOSSIP_ITEM_START'), +(-3608000,'Activate the crystals when we get in trouble, right?','sinclari GOSSIP_ITEM_INTRO'); diff --git a/addition/717_culling_of_stratholme_mangos.sql b/addition/717_culling_of_stratholme_mangos.sql new file mode 100644 index 000000000..dc93cb922 --- /dev/null +++ b/addition/717_culling_of_stratholme_mangos.sql @@ -0,0 +1,49 @@ +-- Remove old versions +DELETE FROM `creature` WHERE `guid` IN (4456649,4456653,4458724,4458725,4458738,4458739,4458740,4458741,4459981,4459615); +DELETE FROM `creature` WHERE `id` IN (27731,27734,28249,27736,27915,30571,26499,26497,26528,27891,27892,27884,32273,28439); + +UPDATE `creature` SET `spawntimesecs`= 36000 WHERE `id` IN (31127, 31126, 28167, 28169); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) values('58825','1','27733'); +REPLACE INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_start_active`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`) values('35481','4100','0','0','0','0','0','1','1'); +REPLACE INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_start_active`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`) values('35480','4100','0','0','0','0','0','0','1'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('58825', '1', '27733'); + +UPDATE `instance_template` SET `ScriptName` = 'instance_culling_of_stratholme' WHERE map=595; + +UPDATE `creature_template` SET `ScriptName`='npc_mike' WHERE entry=30571; +UPDATE `creature_template` SET `ScriptName`='npc_chromi_start' WHERE entry=26527; +UPDATE `creature_template` SET `ScriptName`='npc_roger' WHERE entry=27903; +UPDATE `creature_template` SET `ScriptName`='npc_morigan' WHERE entry=27877; +UPDATE `creature_template` SET `ScriptName`='npc_stratholme_crates' WHERE entry=30996; +UPDATE `creature_template` SET `ScriptName`='npc_jena' WHERE entry=27885; +UPDATE `creature_template` SET `ScriptName`='npc_malcolm' WHERE entry=27891; +UPDATE `creature_template` SET `ScriptName`='npc_bartleby_cs' WHERE entry=27907; +UPDATE `creature_template` SET `ScriptName`='npc_chromi_middle' WHERE entry=27915; +UPDATE `creature_template` SET `ScriptName`='npc_uther' WHERE entry=26528; +UPDATE `creature_template` SET `ScriptName`='npc_arthas' WHERE entry=26499; +UPDATE `creature_template` SET `ScriptName`='npc_arthas_priest' WHERE entry=27747; +UPDATE `creature_template` SET `ScriptName`='npc_arthas_marine' WHERE entry=27745; +UPDATE `creature_template` SET `ScriptName`='npc_dark_conversion' WHERE entry IN (31127, 31126, 28167, 28169); +UPDATE `creature_template` SET `ScriptName`='npc_cs_gnoul' WHERE entry=28249; +UPDATE `creature_template` SET `ScriptName`='npc_cs_necromancer' WHERE entry=28200; +UPDATE `creature_template` SET `ScriptName`='npc_cs_field' WHERE entry=27734; +UPDATE `creature_template` SET `ScriptName`='npc_cs_acolyte' WHERE entry=27731; +UPDATE `creature_template` SET `ScriptName`='npc_cs_butcher' WHERE entry=27736; +UPDATE `creature_template` SET `ScriptName`='boss_meathook' WHERE entry=26529; +UPDATE `creature_template` SET `ScriptName`='boss_salramm' WHERE entry=26530; +UPDATE `creature_template` SET `ScriptName`='npc_salramm_gnoul' WHERE entry=27733; +UPDATE `creature_template` SET `ScriptName`='boss_lord_epoch' WHERE entry=26532; +UPDATE `creature_template` SET `ScriptName`='boss_malganis' WHERE entry=26533; +UPDATE `creature_template` SET `ScriptName`='npc_time_riftCS' WHERE entry=28409; +UPDATE `creature_template` SET `ScriptName`='boss_infinite_corruptor' WHERE entry=32273; + +DELETE FROM `creature` WHERE `id` in (27915, 26499, 26497, 26528, 27891, 27892, 32273, 28439); +INSERT INTO `creature` (id, map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, DeathState, MovementType) VALUES +(27915, 595, 3, 1, 0, 0, 1812.49, 1284.81, 142.248, 4.03364, 300, 0, 0, 17010, 0, 0, 0), +(26499, 595, 3, 1, 0, 1613, 1920.87, 1287.12, 142.935, 6.25562, 43200, 0, 0, 44100, 7988, 0, 0), +(26497, 595, 3, 1, 0, 1221, 1896.39, 1292.91, 143.711, 0.016332, 25, 5, 0, 100800, 88140, 0, 0), +(26528, 595, 3, 1, 0, 1819, 1761.42, 1285.75, 139.945, 4.93874, 25, 5, 0, 126000, 59910, 0, 0), +(27891, 595, 3, 1, 0, 0, 1603.38, 805.988, 123.272, 1.90688, 25, 5, 0, 8982, 0, 0, 0), +(27892, 595, 3, 1, 0, 0, 1602.3, 809.385, 123.454, 5.02884, 25, 5, 0, 8982, 0, 0, 0), +(32273, 595, 2, 1, 0, 1839, 2330.93, 1275.59, 132.848, 3.60489, 86400, 5, 0, 417911, 0, 0, 0), +(28439, 595, 2, 1, 0, 0, 2336.56, 1277.9, 132.885, 3.47923, 25, 5, 0, 1, 0, 0, 0); diff --git a/addition/717_culling_of_stratholme_scriptdev2.sql b/addition/717_culling_of_stratholme_scriptdev2.sql new file mode 100644 index 000000000..b90c16c20 --- /dev/null +++ b/addition/717_culling_of_stratholme_scriptdev2.sql @@ -0,0 +1,214 @@ +REPLACE INTO script_texts (entry, content_default, content_loc8, sound, type, language, emote, comment) VALUES +# TAVERN EVENT +(-1557270, 'Hey! Stop rooting around in my cellar! Clear out!', 'Эй! А ну, хорош рыться в моей кладовке! Проваливайте!', 0,0,0,1, '34587'), +(-1557271, 'This whole situation seems a bit paranoid, don\'t you think?', 'По-моему, все это сильно смахивает на паранойю, вы не находите?', 0,0,0,25, '34587'), +(-1557272, 'Orders are orders, if prince says jump...', 'Приказ есть приказ. Если принц говорит прыгать...', 0,0,0,1, '34587'), +(-1557273, 'It\'s strange order, you cant deny Suspicious food? Under that definition, you should arrest Belfast!', 'Странный приказ, что верно, то верно. Подозрительная пища? Тогда уж и Белфаста арестовывайте!', 0,0,0,1, '34587'), +(-1557274, 'I HEARD THAT! No more ale for you! Not a drop!', 'Я ВСЕ СЛЫШАЛ! Больше эля ты не получишь! Ни капли!', 0,0,0,25, '34587'), +(-1557275, 'Enough, Michael. Business is hurting enough with this scare as it is. We can use every copper.', 'Довольно, Майкл. Наши дела и так страдают из-за этой угрозы. Сейчас каждый медяк на счету.', 0,0,0,274, '34587'), +(-1557276, 'The soldiers are doing important work. The safely of the people is more important, Mal, if you\'re interested in your customers living to spend another day.', 'Солдаты заняты очень важным делом, Мал. Если ты хочешь, чтобы твои покупатели дожили до завтрашнего дня - надо обеспечить их безопасность.', 0,0,0,1, '34587'), +(-1557277, 'I can\'t argue with that.', 'С этим не поспоришь.', 0,0,0,1, '34587'), +(-1557278, 'Don\'t worry too much. By the time I went odd duty, we hadnt a scrap of befouled grain here.', 'Не стоит так сильно волноваться. К тому времени, как я сдал пост, мы не нашли здесь и следа этого мерзского зерна.', 0,0,0,274, '34587'), +(-1557279, 'Thank the Light for that.', 'Скажи спасибо Свету.', 0,0,0,1, '34587'), +# ROGER EVENT +(-1557280, 'Wait, what\'s that smell?', 'Стоп, что за вонь?', 0,0,0,1, '34587'), +(-1557281, 'Can\'t be me, I took a bath 3 days ago!', 'Это не от меня, я мылся 3 дня назад!', 0,0,0,1, '34587'), +(-1557282, 'Oh, close call. It\'s just the grain here.', 'О, это всего лишь зерно.', 0,0,0,1, '34587'), +(-1557283, 'Wait a second. Grain isn\'t supposed to smell like THAT! I better go find a guard.', 'Погоди. Зерно не может ТАК вонять! Я лучше пойду поищу стражника.', 0,0,0,1, '34587'), +# MORIGAN EVENT +(-1557284, 'You don\'t mind me checking out your merchandise for signs of tampering, do you?', 'Вы же не возражаете, чтобы я проверил ваши товары?', 0,0,0,1, '34587'), +(-1557285, 'No, sir.', 'Нет, сэр.', 0,0,0,1, '34587'), +(-1557286, 'Wait, what is it? Youve been holding out on me, Perelli!', 'Подождите-ка, что это? Ты скрывал это от меня, Перелли!', 0,0,0,0, '34587'), +(-1557287, 'What are you talking about, Sergeant?', 'О чем вы говорите, сержант?', 0,0,0,1, '34587'), +(-1557288, 'I am confiscating this suspicious grain, Perelli. We were looking for signs of tampered food, and it would be in your best interest to stay put while Prince Arthas checks this out.', 'Я конфискую это подозрительное зерно, Перелли. Мы искали признаки подозрительной еды, и было бы в твоих лучших интересах оставаться на месте, пока принц Артас разбирается в происходящем.', 0,0,0,1, '34587'), +(-1557289, 'You have to belive me, I am innocent!', 'Вы должны верить мне, я не виновен!', 0,0,0,20, '34587'), +(-1557290, 'Well see about that. Perelli. Well see about that.', 'Это мы посмотрим, Перелли. Это мы посмотрим.', 0,0,0,1, '34587'), +# JENA EVENT +(-1557291, 'Martha. I am out of flour for bread. You wouldn\'t happen to have any grain from that recent, would you?', 'Марта, я не нашла у себя муки для выпечки хлеба. Вы не одолжите мне зерна?', 0,0,0,1, '34587'), +(-1557292, 'Oh hello, Jena. Of Course you can borrow some grain. Help yourself.', 'О, привет Джена. Конечно я одолжу вам зерна. Возьмите сами.', 0,0,0,1, '34587'), +(-1557293, 'Thanks. Martha! I owe you one.', 'Спасибо. Марта! Я твоя должница.', 0,0,0,1, '34587'), +(-1557294, 'Martha, somethings wrong with this grain! Some of the Princes soldiers were looking for this. Im going to go look for one.', 'Марта, с этим зерном что-то не так! Солдаты Принца что-то говорили о нем. Пойду-ка поищу кого-нибудь из них.', 0,0,0,1, '34587'), +(-1557295, 'Oh, my.', 'Боже мой.', 0,0,0,1, '34587'), +# MALCOLM EVENT +(-1557296, 'Looks like a storms coming in, Scruffy...', 'Похоже на приближающуюся бурю, Лохмач...', 0,0,0,0, '34587'), +(-1557297, 'Whats wrong, pal?', 'Что случилось, друг?', 0,0,0,1, '34587'), +(-1557298, 'What did you find, boy?', 'Что ты нашел, парень?', 0,0,0,0, '34587'), +(-1557299, 'This is no good, Scruffy. Stay here and guard the house. I need to go find a soldier.', 'Выглядит плохо, Лохмач. Стой тут и охраняй дом, а я пока сбегаю - поищу солдат.', 0,0,0,0, '34587'), +# BARTLEBY EVENT +(-1557300, 'I knew I should have secured the wagon lock better when I was in Andorhal.', 'Надо было получше запереть фургон в Андорале.', 0,0,0,1, '34587'), +(-1557301, 'This grain shipmend has been nothing but trouble!', 'От этого зерна пока одни лишь хлопоты!', 0,0,0,1, '34587'), +(-1557302, 'Well, guess I should load everything back into the cart.', 'Ну, наверное, мне нужно сложить все обратно в телегу.', 0,0,0,0, '34587'), +(-1557303, 'Oh, come on! My cart broke, my horse a shoe, and now the cargo goes bad!', 'О, черт! Моя телега сломалась, моя лошадь потеряла подкову, а теперь еще и с грузом проблемы!', 0,0,0,1, '34587'), +(-1557304, 'I guess I\'ll go find the authorites. If I\'m lucky theyll tell me it\'s the plague and that were all to die!', 'Похоже, мне придется идти искать представителей закона. Если мне повезет, они скажут, что это чума и что скоро мы все умрем!', 0,0,0,1, '34587'), +# ARTHAS INTRO EVENT +(-1594071, 'Glad you could make it, Uther.', 'Я рад, что ты пришел, Утер!', 12828,0,0,1, '34587'), +(-1594072, 'Watch your tone with me boy. You may be the prince, but I am still your superior as a paladin!', 'Следи за своим тоном, юноша. Хоть ты и принц, но, как паладин, ты все еще находишься под моим командованием.', 12839,0,0,25, '34587'), +(-1594073, 'As if I could forget. Listen, Uther, there\'s something about the plague you should know...', 'Как будто я не помню. Послушай, Утер, я должен рассказать тебе кое-что про чуму...', 12829,0,0,0, '34587'), +(-1594074, 'Oh, no. Were too late. These people have all been infected! They may look fine now, but it\'s just a matter of time before they turn into the undead!', 'О нет. Мы опоздали. Все эти люди заражены чумой! Сейчас это еще незаметно, но скоро все они превратятся в нежить!', 12830,0,0,1, '34587'), +(-1594075, 'What?', 'Что?', 12840,0,0,5, '34587'), +(-1594076, 'This entire city must be purged.', 'Весь город должен быть очищен.', 12831,0,0,1, '34587'), +(-1594077, 'How can you even consider that? There\'s got to be some other way.', 'Как ты мог даже подумать об этом?! Должен быть какой-то другой путь!', 12841,0,0,1, '34587'), +(-1594078, 'Damn it, Uther! As your future king, I order you to purge this city!', 'Проклятие, Утер! Как будущий король, я приказываю тебе очистить этот город!', 12832,1,0,5, '34587'), +(-1594079, 'You are not my king yet, boy! Nor would I obey that command even if you were!', 'Пока ты еще не король, юноша. Но этот приказ я не выполнил бы, будь ты хоть трижды королем!', 12842,1,0,22, '34587'), +(-1594080, 'Then I must consider this an act of treason.', 'Тогда я буду расценивать это как измену.', 12833,0,0,0, '34587'), +(-1594081, 'Treason? Have you lost your mind, Arthas?', 'Измену? Ты совсем лишился рассудка, Артас?', 12843,0,0,5, '34587'), +(-1594082, 'Have I? Lord Uther, by my right of succession and the sovereignty of my crown, I hereby relieve you of your commnad and suspend your paladins from service.', 'Неужели? Лорд Утер, властью, данной мне по праву наследования, я отстраняю вас от командования и освобождаю от службы ваших паладинов.', 12834,0,0,1, '34587'), +(-1594083, 'Arthas! You cant just...', 'Артас! Ты не можешь так просто...', 12837,0,0,1, '34587'), +(-1594084, 'It\'s done! those of you who have the will to save this land, follow me! The rest of you... get out of my sight!', 'Это уже сделано! Те из вас, кто действительно хочет спасти эту землю - за мной! Остальные - прочь с глаз моих!', 12835,0,0,0, '34587'), +(-1594085, 'You\'ve just crossed a terrible inreshold, Arthas!', 'Ты пересек опасную черту, Артас.', 12844,0,0,25, '34587'), +(-1594086, 'Jaina?', 'Джайна?', 12836,0,0,1, '34587'), +(-1594087, 'Im sorry Arthas. I can\'t watch you do this.', 'Прости, Артас. Я не могу на это смотреть.', 12838,0,0,1, '34587'), +(-1594088, 'Take position here and I will lead a small force inside Stratholme to begin the culling. We must contain and purge the infected for the sake of all of Lordaeron!', 'Займите позицию, а я поведу небольшой отряд в Стратхольм и начну очищение. Мы должны изолировать и уничтожить зараженных жителей ради всего Лордерона!', 14327,1,0,1, '34587'), +#ARTHAS ENTER IN THE CITY +(-1594089, 'Everyone looks ready. Remember, these people are all infected with the plague and will die soon. We must purge Stratholme to protect the remainder of Lordaeron from the Scourge. Lets go!', 'Похоже, все готовы. Помните, эти люди заражены чумой и скоро умрут. Мы должны очистить Стратхольм и защитить Лордерон от Плети. Вперед.', 14293,0,0,1, '26499'), +(-1594090, 'Prince Arthas, may the light be praised. Many people in the town have begun to fall seriously ill. Can you help us?', 'Принц Артас, слава Свету! Многие горожане серьезно больны. Можете ли вы помочь нам?', 0,0,0,1, '26499'), +(-1594091, 'I can help you only with a clean death.', 'Я могу помочь вам лишь быстрой смертью.', 14294,0,0,0, '26499'), +(-1594092, 'What? This cant be!', 'Что? Этого не может быть!', 0,0,0,0, '26499'), +(-1594093, 'Oh... My g...', 'О... Мой б...', 0,0,0,0, '26499'), +(-1594094, 'This is begining!', 'Это было только начало.', 14295,0,0,1, '26499'), +(-1594095, 'Yes, this is the beginning. I\'ve been waiting for you, young prince. I am Mal\'Ganis.', 'Да, это начало. Я ждал тебя, юный принц. Я Мал\'Ганис.', 14410,0,0,1, '26499'), +(-1594096, 'As you can see, your people are now mine. I will now turn this city, household by household, until the flame of life has been snuffed out forever.', 'Как видишь, твои люди отныне принадлежат мне. Дом за домом я порабощу этот город, и огонь жизни угаснет здесь навсегда...',14411,0,0,1, '26499'), +(-1594097, 'I will not allow this, Mal\'Ganis. Better these people will die from my hand, than become your slaves after death.', 'Я не допущу этого, Мал\'Ганис! Лучше эти люди погибнут от моей руки, чем станут твоими рабами после смерти!',14296,0,0,5, '26499'), +(-1594098, 'Mal\'Ganis will send his Scourge henchmen to meet us. Skilled warriors and mages go and destroy enemies. I will lead the remaining troops in the purification of Stratholme from infection.', 'Мал\'Ганис отправит своих прислужников из Плети навстречу нам. Опытные воины и маги, ступайте и уничтожьте врагов. Я возглавлю оставшиеся войска в деле очищения Стратхольма от заразы.',14885,0,0,1, '26499'), +#MEATHOOK +(-1594110, 'Play time!', 'Поиграем!',13428,0,0,0, '26499'), +(-1594111, 'New toys!', 'Новые игрушки!',13429,1,0,0, '26499'), +(-1594112, 'This not fun...', 'Это не смешно...',13433,1,0,0, '26499'), +(-1594113, 'Boring...', 'Скучно...',13430,1,0,0, '26499'), +(-1594114, 'Why you stop moving?', 'Почему ты не двигаться?',13431,1,0,0, '26499'), # ! +(-1594115, 'Get up! Me not done!', 'Вставай! Я не закончил!',13432,1,0,0, '26499'), # ! +#SALRAMM +(-1594129, 'You are too late, champion of Lordaeron. The dead shall have their day.', 'Слишком поздно, герой Лордерона! Пришло время мертвых.',0,1,0,0, '26499'), +(-1594130, 'Ah, the entertainment has arrived!', 'А, развлечемся!',0,1,0,0, '26499'), +(-1594131, 'You only advance... the master\'s plan...', 'Вы всего лишь часть плана хозяина...',0,1,0,0, '26499'), +(-1594132, 'The fun is just beginning!', 'Веселье только начинается!',0,1,0,0, '26499'), +(-1594133, 'Aah, quality materials!', 'Аааа, качественный материал...',0,1,0,0, '26499'), +(-1594134, 'Don\'t worry, I\'ll make good use of you.', 'Не волнуйся, я найду куда тебя приспособить...',0,1,0,0, '26499'), +(-1594135, 'I want a sample...', 'Мне нужен образец!',0,1,0,0, '26499'), +(-1594136, 'Such strength... it must be mine!', 'Столько силы... Она будет моей....',0,1,0,0, '26499'), +(-1594137, 'Your flesh betrays you.', 'Твоя плоть предает тебя!',0,1,0,0, '26499'), +(-1594138, 'Say hello to some friends of mine.', 'Познакомтесь с моими друзьями...',0,1,0,0, '26499'), +(-1594139, 'Come, citizen of Stratholme! Meet your saviors.', 'Жители Стратхольма, встречайте ваших спасителей...',0,1,0,0, '26499'), +(-1594140, 'BOOM! Hahahahah...', 'Бум... Ха-ха-ха-ха...',0,1,0,0, '26499'), +(-1594141, 'Blood... destruction... EXHILARATING!', 'Кровь... Разрушение... Восхитительно...',0,1,0,0, '26499'), +#ARTHAS - HOUSE +(-1594142, 'Heroes, hurry up, we\'ll meet near town hall. We must fight with Mal\'Ganis on its territory!', 'Герои, поспешите, встретимся у городской ратуши. Мы должны сразиться с Мал\'Ганисом на его территории!',14297,1,0,0, '26499'), +(-1594143, 'Follow me, I know the way.', 'Идите за мной. Я знаю дорогу.',14298,0,0,1, '26499'), +(-1594144, 'Ah, You\'ve finaly arrived, Prince Arthas. You\'re here just in the nick of time.', 'О, вы наконец-то прибыли, принц Артас. Вы едва успели.',0,0,0,1, '26499'), +(-1594145, 'Yes! I\'m glad to get here before plague!', 'Да! Я рад, что смог добраться сюда раньше чумы.',14299,0,0,1, '26499'), +(-1594146, 'What kind of magic is this?', 'Что это за магия?',14300,0,0,0, '26499'), +(-1594147, 'Theres no need for you in understand Arthas. All you need to do is die!', 'Тебе и не надо этого понимать, Артас. Все, что от тебя требуется – это умереть.',0,0,0,11, '26499'), +(-1594148, 'Seems that Mal\'Ganis has something else except Scourge. Let\'s hurry.', 'Кажется у Мал\'Ганиса в распоряжении есть еще кое что кроме Плети. Давайте поспешим.',14301,0,0,0, '26499'), +(-1594149, 'Dark magic again... Be ready for all.', 'Снова черная магия... Будьте готовы ко всему!',14302,0,0,0, '26499'), +(-1594150, 'Come on.', 'Идем дальше.',14303,0,0,0, '26499'), +(-1594151, 'Be on the alert. We were surrounded.', 'Будьте начеку. Нас окружили.',14304,0,0,0, '26499'), +(-1594152, 'Mal\'Ganis doesn\'t want to make our life easier...', 'Мал\'Ганис не собирается облегчить нам жизнь.',14305,0,0,0, '26499'), +(-1594153, 'They are stubborn.', 'Они упрямы.',14306,0,0,0, '26499'), +(-1594154, 'What else he will put on my way?', 'Что еще он поставит у меня на пути?',14307,0,0,0, '26499'), +(-1594155, 'Prince Arthas Menethil, in this day mighty evil devoured your soul. Death, which you had to bring to others, today will come for you.', 'Принц Артас Менетил, в этот самый день могущественное зло поглотило твою душу. Смерть, которую ты должен был принести другим, сегодня придет за тобой.',13408,0,0,0, '26499'), +(-1594156, 'I do for Lordaeron that should, and words and deeds will not stop me.', 'Я делаю для Лордерона то, что должен, и никакие слова и поступки меня не остановят.',14309,0,0,5, '26499'), +(-1594157, 'Let\'s see, young prince...', 'Ну что ж, посмотрим, юный принц.',13409,0,0,0, '26499'), +#Epoch +(-1594119, 'We\'ll see about that, young prince.', 'Поcмотрим, молодой принц.',13416,0,0,0, '26499'), +(-1594120, 'There is no future for you.', 'У тебя нет будущего...',13413,1,0,0, '26499'), +(-1594121, 'This is the hour of our greatest triumph!', 'Пробил час нашего величайшего триумфа..',13414,1,0,0, '26499'), +(-1594122, 'You were destined to fail.', 'Тебе было суждено потерпеть поражение...',13415,1,0,0, '26499'), +(-1594123, 'Tick tock, tick tock...', 'Тик-так... Тик-так...',13410,1,0,0, '26499'), +(-1594124, 'Not quick enough!', 'Слишком медленно...',13411,1,0,0, '26499'), +(-1594125, 'Let\'s get this over with.', 'Пора заканчивать...',13412,1,0,0, '26499'), +#Street +(-1594158, 'It will take not much time.', 'Это займет совсем немного времени.',14310,0,0,0, '26499'), +(-1594159, 'Thanks Light, backdoor still works!', 'Слава Свету, что потайной ход еще работает.',14311,0,0,0, '26499'), +(-1594160, 'Let\'s pass through this area as soon as possible. If we do not perish from the undead, we can die from this fire.', 'Давайте пройдем этот участок как можно быстрее. Если мы не погибнем от нежити, то можем погибнуть от этого огня.',14312,0,0,0, '26499'), +(-1594161, 'Breather a little bit, but keep in mind, we will soon again in the path.', 'Отдышитесь немного. Но имейте в виду, нам скоро снова в путь.',14313,0,0,0, '26499'), +(-1594162, 'The rest is over, let\'s go. Mal\'Ganis waits.', 'Отдых окончен, надо идти. Мал\'Ганис ждет.',14314,0,0,0, '26499'), +(-1594163, 'Finally, we even like that lucky! The fire has not yet reached the commercial area. Mal\'Ganis should be in Square of Knights, which is not far from here. Tell me when you\'re ready to go.', 'Наконец нам хоть как-то повезло. Огонь еще не добрался до Торгового ряда. Мал\'Ганис должен быть на Площади рыцарей, которая находится недалеко отсюда. Скажите мне, как будете готовы идти дальше.',14315,0,0,0, '26499'), +(-1594164, 'Let\'s justice will be here.', 'Да свершится правосудие.',14316,0,0,0, '26499'), +#malganis +(-1594170, 'This will be a fine test, Prince Arthas.', 'Это будет достойное испытание, принц Артас.',14413,1,0,0, '26499'), +(-1594171, 'All too easy.', 'Слишком просто...',14416,1,0,0, '26499'), +(-1594172, 'The dark lord is displeased with your interference.', 'Темный повелитель не доволен твоим вмешательством...',14417,1,0,0, '26499'), +(-1594173, 'It is Prince Arthas I want, not you.', 'Мне нужен Принц Артас, а не ты...',14418,1,0,0, '26499'), +(-1594174, 'Anak\'Keri...', 'Анак Кири...',14422,1,0,0, '26499'), +(-1594175, 'My onslaught will wash over the Lich King\'s forces...', 'Мой натиск сметет силы Короля-Лича...',14423,1,0,0, '26499'), +(-1594176, 'Your death is in vain, tiny mortal...', 'Твоя смерть была напрасна насекомое...',14424,1,0,0, '26499'), +(-1594177, 'Your time has come to an end!', 'Твое время вышло...',14425,1,0,0, '26499'), +(-1594178, '*Struggling sounds* I spent too much time in that weak little shell...', 'Аррррхххх... Я и так провел слишком много времени в этой слабой оболочке...',14426,1,0,0, '26499'), +(-1594179, 'I AM MAL\'GANIS! I AM ETERNAL!', 'Ирл Нарат... Я Мал\'Ганис.... Я вечен...',14427,1,0,0, '26499'), +(-1594180, 'You\'ll never defeat the Lich King without my forces! I\'ll have my revenge...on him, AND you...', 'Тебе никогда не победить короля - лича без моих войск! Я отомщу и тебе и ему...',14429,1,0,0, '26499'), +(-1594181, 'We\'re going to finish this right now, Mal\'Ganis!', 'Мы покончим с этим сейчас же, Мал\'Ганис. Один на один.',14317,0,0,0, '26499'), +(-1594182, 'Your journey has just begun, young prince. Gather your forces, and meet me in the arctic land of Northrend. It is there we shall settle the score between us. It is there that your true destiny will unfold.', 'Твое путешествие начинается, юный принц. Собирай свои войска и отправляйся в царство вечных снегов, в Нордскол. Там мы и уладим все наши дела, там ты узнаешь свою судьбу.',14412,0,0,0, '26499'), +(-1594183, 'I\'ll hunt you to the ends of the earth if I have to! Do you hear me? To the ends of the earth!', 'Я отыщу тебя на краю земли! Ты слышишь меня? На краю земли!',14318,1,0,5, '26499'), +(-1594184, 'You performed well this day. Anything that Mal\'Ganis has left behind is yours. Take it as your reward. I must now begin plans for an expedition to Northrend.', 'Вы славно сражались сегодня. Все, что Мал\'Ганис оставил тут – ваша награда. А мне нужно начинать готовиться к экспедиции в Нордскол.',14319,0,0,5, '26499'), +(-1594185, 'Time out...', 'Отдохни!',14414,1,0,0, '26499'), +(-1594186, 'You seem tired.', 'Ты выглядишь усталым!',14415,1,0,0, '26499'), +(-1594187, 'ENOUGH! I waste my time here...I must gather my strength on the home world...', 'Я лишь зря трачу тут свое время. Мне нужно собраться силами в моем родном мире.',14428,1,0,0, '26499'); + +DELETE FROM script_waypoint WHERE entry=26528; +DELETE FROM script_waypoint WHERE entry=26499; +INSERT INTO script_waypoint VALUES +#Uther + (26528, 0, 1772.707,1263.927,138.867, 0, 'WP1'), + (26528, 1, 1810.249,1276.557,141.854, 0, 'WP2'), + (26528, 2, 1810.249,1276.557,141.854, 0, 'WP3'), + (26528, 3, 1851.476,1281.370,144.106, 0, 'WP4 - Arthas Move'), + (26528, 4, 1898.716,1288.757,143.461, 90000, 'WP5 - Pause Escort'), + (26528, 5, 1851.476,1281.370,144.106, 0, 'WP6'), + (26528, 6, 1794.357,1272.183,140.558, 0, 'WP7 - Uther Despawn'), +#Arthas + (26499, 0, 1902.959,1295.127,143.388, 0, 'WP1'), + (26499, 1, 1916.657,1287.327,141.946, 0, 'WP2'), + (26499, 2, 1913.726,1287.407,141.927, 10000, 'WP3 - Dialog'), + (26499, 3, 1990.833,1293.391,145.467, 0, 'WP4'), + (26499, 4, 1997.003,1317.776,142.963, 0, 'WP5'), + (26499, 5, 2019.631,1326.084,142.929, 0, 'WP6'), + (26499, 6, 2026.469,1287.088,143.596, 0, 'WP7'), + (26499, 7, 2054.879,1287.505,142.422, 0, 'WP8'), + (26499, 8, 2050.660,1287.333,142.671, 0, 'WP9 - Pause Escort'), + (26499, 9, 2050.652,1287.382,142.672, 12000, 'WP10'), + (26499, 10, 2081.447,1287.770,141.324, 2000, 'wp11'), + (26499, 11, 2099.876,1280.210,138.550, 0, 'WP12'), + (26499, 12, 2120.757,1286.970,136.343, 0, 'WP13'), + (26499, 13, 2165.073,1279.338,133.400, 0, 'WP14'), + (26499, 14, 2186.441,1234.445,136.524, 0, 'WP15'), + (26499, 15, 2210.385,1207.550,136.259, 0, 'WP16'), + (26499, 16, 2243.594,1177.705,137.144, 0, 'WP17'), + (26499, 17, 2286.883,1177.262,137.631, 0, 'WP18'), + (26499, 18, 2320.374,1179.954,133.926, 0, 'WP19'), + (26499, 19, 2354.626,1192.099,130.535, 0, 'WP20'), + (26499, 20, 2363.374,1194.101,131.414, 0, 'WP21 - pause'), + (26499, 21, 2364.749,1194.660,131.672, 3000, 'WP22 - say'), + (26499, 22, 2390.256,1204.235,134.125, 0, 'WP21 - pause escort and start event'), #2500 2396.035 1206.942 134.038 + (26499, 23, 2442.023,1219.205,133.999, 0, 'WP22'), + (26499, 24, 2446.945,1192.559,148.100, 0, 'WP23'), + (26499, 25, 2443.161,1191.442,148.076, 5000, 'WP24 - summon portal'), + (26499, 26, 2428.901,1192.164,148.076, 0, 'WP25'), + (26499, 27, 2418.487,1196.059,148.076, 0, 'WP26'), + (26499, 28, 2401.221,1191.705,148.076, 0, 'WP27'), + (26499, 29, 2409.143,1157.000,148.190, 1000, 'WP28 - trap'), + (26499, 30, 2417.584,1121.026,148.082, 10000, 'WP29'), + (26499, 31, 2420.949,1119.944,148.075, 29000, 'WP30 - pause'), + (26499, 32, 2444.682,1111.705,148.076, 0, 'WP31 - Stop'), + + (26499, 33, 2457.133,1120.941,150.008, 0, 'House WP11'), + (26499, 34, 2459.694,1127.012,150.008, 0, 'House WP12'), + (26499, 35, 2469.617,1122.274,150.008, 0, 'House WP13'), + (26499, 36, 2470.437,1122.794,150.008, 3000, 'Open Shkaf'), + (26499, 37, 2471.662,1123.077,150.035, 3000, 'Shkaf Dialog'), + (26499, 38, 2483.183,1125.042,149.905, 0, 'Secret WP1'), + (26499, 39, 2487.867,1099.760,144.858, 0, 'Secret WP2'), + (26499, 40, 2498.270,1101.929,144.599, 0, 'Secret WP3'), + (26499, 41, 2492.114,1128.238,139.967, 0, 'Secret WP4'), + (26499, 42, 2500.286,1130.183,139.982, 0, 'Room WP1'), + (26499, 43, 2503.010,1119.241,139.978, 0, 'Room WP2'), + (26499, 44, 2517.820,1122.645,132.066, 0, 'Room WP3'), + (26499, 45, 2540.479,1129.061,130.868, 7000, 'Fire Street WP1'), + (26499, 46, 2568.619,1157.794,126.906, 0, 'Fire Street WP2'), + (26499, 47, 2556.074,1222.058,125.412, 0, 'Fire Street WP3'), + (26499, 48, 2521.531,1295.209,130.573, 20000, 'Fire Street WP4'), + (26499, 49, 2504.362,1348.667,132.944, 0, 'Fire Street WP5'), + (26499, 50, 2450.594,1431.544,131.361, 0, 'Fire Street WP6'), + (26499, 51, 2353.485,1404.839,128.531, 0, 'Stop Malganis'), + (26499, 52, 2329.882,1406.273,128.013, 0, 'wp'), + (26499, 53, 2300.415,1489.316,128.362, 0, 'wp stop'), + (26499, 54, 2329.882,1406.273,128.013, 0, 'wp'); diff --git a/addition/718_draktharon_mangos.sql b/addition/718_draktharon_mangos.sql new file mode 100644 index 000000000..8947389fc --- /dev/null +++ b/addition/718_draktharon_mangos.sql @@ -0,0 +1,66 @@ +DELETE FROM `creature` WHERE `id`=26712; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`) VALUES +(927500, 26712, 600, 3, 1, 17188, 0, -365.477, -724.849, 32.2241, 3.92699, 3600, 5, 0, 4050, 0, 0, 1), +(927501, 26712, 600, 3, 1, 17188, 0, -365.368, -751.128, 32.3213, 2.35619, 3600, 5, 0, 4050, 0, 0, 1), +(927502, 26712, 600, 3, 1, 17188, 0, -392.123, -750.941, 32.2796, 0.680678, 3600, 5, 0, 4050, 0, 0, 1), +(927503, 26712, 600, 3, 1, 17188, 0, -392.455, -724.809, 32.1685, 5.35816, 3600, 5, 0, 4050, 0, 0, 1); + +DELETE FROM `creature_template` WHERE (`entry`=26710); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (26710, 0, 0, 0, 0, 0, 2536, 1160, 9829, 14952, 'Channel Target', '', '', 0, 1, 1, 8, 8, 0, 0, 7, 190, 190, 0, 1, 1, 0, 2, 2, 0, 24, 7.5, 2000, 0, 1, 33587200, 0, 0, 0, 0, 0, 0, 1, 1, 100, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 4, 0.2, 1, 0, 0, 0, 0, 0, 0, 0, 100, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE (`entry`=26712); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (26712, 0, 0, 0, 0, 0, 169, 0, 17188, 0, 'Crystal Channel Target', '', '', 0, 70, 70, 4050, 4050, 0, 0, 6719, 16, 16, 0, 1, 1, 0, 252, 357, 0, 304, 1, 2000, 0, 1, 33554436, 0, 0, 0, 0, 0, 0, 215, 320, 44, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 'crystal_channel'); + +DELETE FROM `creature_template` WHERE (`entry`=26714); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (26714, 0, 0, 0, 0, 0, 2536, 1160, 9829, 14952, 'Dead Crystal Holder', '', '', 0, 1, 1, 8, 8, 0, 0, 7, 190, 190, 0, 1, 1, 0, 2, 2, 0, 24, 7.5, 2000, 0, 1, 32768, 0, 0, 0, 0, 0, 0, 1, 1, 100, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 4, 0.2, 1, 0, 0, 0, 0, 0, 0, 0, 100, 1, 0, 0, 0, ''); + +/*King Dred*/ + +DELETE FROM creature WHERE id in (27709, 27753, 27490); + +DELETE FROM `creature` WHERE `id`=26632; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`) VALUES +(152490, 26632, 600, 3, 1, 0, 0, -237.176, -675.768, 131.866, 4.66859, 25, 0, 0, 512278, 4169, 0, 0); + +DELETE FROM `creature_template` WHERE (`entry`=26632); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (26632, 31360, 0, 0, 0, 0, 27072, 0, 27072, 0, 'The Prophet Tharon\'ja', '', '', 76, 77, 275025, 275025, 0, 0, 0, 16, 16, 0, 1, 1, 1, 350, 450, 0, 400, 7.5, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 450, 75, 6, 72, 26632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 25, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 'boss_tharonja'); + +DELETE FROM `creature_template` WHERE (`entry`=31360); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (31360, 0, 0, 0, 0, 0, 27072, 0, 27072, 0, 'The Prophet Tharon\'ja (1)', '', '', 82, 82, 512278, 512278, 4169, 4169, 0, 16, 16, 0, 1, 1, 1, 450, 650, 0, 750, 13, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 530, 100, 6, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 38, 1, 0, 43670, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, ''); + +DELETE FROM `spell_script_target` WHERE `entry` = 49555; +INSERT INTO `spell_script_target` VALUES (49555, 2, 27753); + +UPDATE `creature_template` SET minhealth = 1885, maxhealth = 1885 WHERE entry = 27753; + +DELETE FROM `creature_template` WHERE (`entry`=26627); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (26627, 31344, 0, 0, 0, 0, 24500, 0, 24500, 0, 'Crystal Handler', '', '', 0, 75, 75, 21270, 21270, 0, 0, 0, 15, 15, 0, 1, 1, 1, 500, 1000, 0, 500, 1, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 2.5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 'crystal_handler'); + +DELETE FROM `creature_template` WHERE (`entry`=31344); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (31344, 0, 0, 0, 0, 0, 24500, 0, 24500, 0, 'Crystal Handler (1)', '', '', 0, 81, 81, 41704, 41704, 8979, 8979, 0, 15, 15, 0, 1, 1, 1, 1000, 1500, 0, 500, 2, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE (`entry`=27597); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (27597, 31348, 0, 0, 0, 0, 22337, 0, 22337, 0, 'Hulking Corpse', '', '', 0, 74, 74, 12338, 12338, 0, 0, 0, 15, 15, 0, 1, 1, 1, 500, 1000, 0, 500, 1, 2000, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1.2, 1, 0, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE (`entry`=31348); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (31348, 0, 0, 0, 0, 0, 22337, 0, 22337, 0, 'Hulking Corpse (1)', '', '', 0, 80, 80, 25200, 25200, 0, 0, 0, 15, 15, 0, 1, 1, 1, 1000, 1500, 0, 500, 2, 2000, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE (`entry`=27598); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (27598, 31873, 0, 0, 0, 0, 10978, 0, 10972, 0, 'Fetid Troll Corpse', '', '', 0, 74, 74, 2056, 2056, 0, 0, 0, 15, 15, 0, 1, 1, 0, 200, 400, 0, 500, 1, 2000, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 0.2, 1, 0, 0, 0, 0, 0, 0, 0, 73, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE (`entry`=31873); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (31873, 0, 0, 0, 0, 0, 10978, 0, 10972, 0, 'Fetid Troll Corpse (1)', '', '', 0, 80, 80, 3780, 3780, 0, 0, 0, 15, 15, 0, 1, 1, 0, 500, 1000, 0, 500, 2, 2000, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 0.3, 1, 0, 0, 0, 0, 0, 0, 0, 73, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE (`entry`=27600); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (27600, 31356, 0, 0, 0, 0, 2606, 0, 2606, 0, 'Risen Shadowcaster', '', '', 0, 74, 74, 1645, 1645, 7809, 7809, 0, 15, 15, 0, 1, 1, 0, 200, 400, 0, 500, 1, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EventAI', 0, 3, 0.2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE (`entry`=31356); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (31356, 0, 0, 0, 0, 0, 2606, 0, 2606, 0, 'Risen Shadowcaster (1)', '', '', 0, 81, 81, 3128, 3128, 8979, 8979, 0, 15, 15, 0, 1, 1, 0, 500, 1000, 0, 500, 2, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 0.3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, ''); + +UPDATE `creature_template` set AIName = '', ScriptName = 'boss_trollgore' where entry = 26630; +UPDATE `creature_template` set AIName = '', ScriptName = 'boss_novos' where entry = 26631; +UPDATE `creature_template` set AIName = '', ScriptName = 'crystal_handler' where entry = 26627; +UPDATE `creature_template` set AIName = '', ScriptName = 'crystal_channel' where entry = 26712; +UPDATE `creature_template` set AIName = '', ScriptName = 'risen_shadowcaster' where entry = 27600; +UPDATE `creature_template` set AIName = '', ScriptName = 'boss_dred' where entry = 27483; +UPDATE `creature_template` set AIName = '', ScriptName = 'boss_tharonja' where entry = 26632; diff --git a/addition/718_draktharon_scriptdev2.sql b/addition/718_draktharon_scriptdev2.sql new file mode 100644 index 000000000..5d89cff15 --- /dev/null +++ b/addition/718_draktharon_scriptdev2.sql @@ -0,0 +1,4 @@ +DELETE FROM script_texts WHERE entry in (-1600020, -1600021); +INSERT INTO script_texts (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) values +('-1600020','King Dred raises his talon menacingly!','0','5','0','King Dred Talon'), +('-1600021','King Dred calls for a raptor!','0','5','0','King Dred Call for Raptor'); \ No newline at end of file diff --git a/addition/719_ankahet_mangos.sql b/addition/719_ankahet_mangos.sql new file mode 100644 index 000000000..36cd3d5b0 --- /dev/null +++ b/addition/719_ankahet_mangos.sql @@ -0,0 +1,116 @@ +-- Ahnkahet from Tassadar +UPDATE `instance_template` SET `ScriptName` = 'instance_ahnkahet' WHERE `map`=619; +UPDATE `creature_template` SET `ScriptName` = 'boss_jedoga', `AIName`='' WHERE `entry`=29310; +UPDATE `creature_template` SET `ScriptName` = 'boss_nadox', `AIName`='' WHERE `entry`=29309; +UPDATE `creature_template` SET `ScriptName` = 'boss_taldaram', `AIName`='' WHERE `entry`=29308; +UPDATE `gameobject_template` SET `ScriptName` = 'go_nerubian_device' WHERE `entry` IN (193093,193094); +UPDATE `creature_template` SET `ScriptName` = 'boss_volazj', `AIName`='' WHERE `entry`=29311; + +DELETE FROM `creature_template_addon` WHERE `entry` IN (30385, 31474); +INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `b2_0_sheath`, `b2_1_pvp_state`, `emote`, `moveflags`, `auras`) VALUES +(30385, 0, 8, 1, 0, 0, 0, ''); +INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `b2_0_sheath`, `b2_1_pvp_state`, `emote`, `moveflags`, `auras`) VALUES +(31474, 0, 8, 1, 0, 0, 0, ''); + +DELETE FROM `creature_template` WHERE entry IN (31474, 30385, 29310, 31465); +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES +(29310, 31465, 0, 0, 0, 0, 26777, 0, 26777, 0, 'Jedoga Shadowseeker', '', '', 0, 75, 75, 212700, 212700, 0, 0, 8204, 16, 16, 0, 1, 1, 339, 481, 0, 370, 7.5, 2000, 0, 2, 0, 0, 0, 0, 0, 0, 0, 293, 436, 53, 7, 0, 29310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4176, 6960, '', 0, 3, 20, 20, 0, 0, 0, 0, 0, 0, 0, 172, 1, 1575, 0, 0, 'boss_jedoga'), +(30385, 31474, 0, 0, 0, 0, 27382, 27384, 27383, 27385, 'Twilight Volunteer', '', '', 0, 74, 74, 25705, 25705, 0, 0, 0, 16, 16, 0, 1, 1, 0, 0, 0, 0, 1, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 2.5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 93, 0, 0, 'npc_twilight_volunteer'), +(31465, 0, 0, 0, 0, 0, 26777, 0, 26777, 0, 'Jedoga Shadowseeker (1)', '', '', 0, 82, 82, 431392, 431392, 0, 0, 10253, 16, 16, 0, 1, 1, 463, 640, 0, 726, 13, 2000, 0, 2, 0, 0, 0, 0, 0, 0, 0, 360, 520, 91, 7, 0, 31465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8352, 13920, '', 0, 3, 32, 20, 0, 0, 0, 0, 0, 0, 0, 172, 1, 0, 0, 1, ''), +(31474, 0, 0, 0, 0, 0, 27382, 27384, 27383, 27385, 'Twilight Volunteer (1)', '', '', 0, 81, 81, 58648, 58648, 0, 0, 0, 16, 16, 0, 1, 1, 0, 0, 0, 0, 1, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 4.5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, ''); + +UPDATE `creature_template` SET `unit_flags` = '0' WHERE `entry` IN (30114,31473); + +DELETE FROM `creature_addon` WHERE guid=131953; +DELETE FROM `creature` WHERE guid IN (131953, 115064); +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `DeathState`, `MovementType`) VALUES +(131953, 29310, 619, 3, 1, 26777, 0, 357.353, -692.808, -10.7028, 5.56541, 14400, 5, 0, 212700, 0, 0, 1); + +DELETE FROM `gameobject` WHERE `guid` = 911321; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(911321, 194394, 619, 2, 1, 371.842, -701.621, -16.1797, 5.67851, 0, 0, 0.297751, -0.954644, -10, 0, 1); + +UPDATE `creature_template` SET `unit_flags` = 0, `difficulty_entry_1` = 0 WHERE `entry` IN (30258, 30391, 30435); +UPDATE `creature_template` SET `ScriptName` ='npc_amanitar_mushroom', `AIName`='' WHERE `entry` IN (30391, 30435); +UPDATE `creature_template` SET `ScriptName` ='boss_amanitar', `AIName`='', `mindmg` = 488, `maxdmg` = 648, `attackpower` = 782, `dmg_multiplier` = 13 WHERE `entry` = 30258; + +DELETE FROM `creature` WHERE `map` = 619 AND `id` IN (30258,30391); + +INSERT INTO `creature` (`id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `DeathState`, `MovementType`) VALUES +#Amanitar +(30258, 619, 2, 1, 0, 0, 340.433, -884.8, -74.6965, 6.10105, 9800, 0, 0, 1, 0, 0, 0), + +#Mushrooms +(30391, 619, 2, 1, 0, 0, 358.386, -885.553, -76.1054, 3.06235, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 355.893, -871.712, -76.1473, 2.37356, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 350.343, -874.985, -76.7057, 3.40793, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 339.429, -875.16, -75.6668, 2.76233, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 333.095, -874.652, -73.8099, 3.95457, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 324.208, -878.923, -70.915, 3.95457, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 319.612, -893.614, -66.4438, 6.25892, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 335.775, -899.115, -76.1423, 0.282045, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 344.644, -898.122, -77.6435, 0.282045, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 353.341, -894.159, -77.208, 0.282045, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 363.279, -897.252, -79.5129, 0.282045, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 364.47, -903.557, -80.3345, 4.7651, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 366.219, -915.939, -82.5392, 5.04784, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 368.297, -920.562, -82.5588, 5.59919, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 381.647, -923.685, -82.4737, 0.190153, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 389.079, -916.929, -81.4451, 1.40831, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 386.916, -909.718, -79.9835, 1.40831, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 386.976, -898.374, -79.2561, 2.5652, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 390.349, -882.168, -76.0919, 1.56146, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 387.136, -871.625, -75.4158, 2.15051, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 378.056, -864.542, -73.8699, 3.01759, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 363.749, -858.04, -75.1185, 3.01759, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 352.564, -862.387, -74.7834, 3.01759, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 343.924, -860.44, -74.5909, 2.23533, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 339.94, -852.104, -74.3732, 0.995972, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 347.839, -848.228, -73.7097, 6.23065, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 324.306, -858.725, -75.0947, 3.68596, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 347.971, -882.318, -75.884, 3.55872, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 347.965, -889.829, -76.747, 3.55872, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 368.578, -877.354, -75.676, 1.46878, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 378.003, -852.353, -73.5427, 0.519235, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 361.828, -841.2, -70.86, 2.94298, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 346.972, -839.523, -73.5286, 2.94298, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 337.009, -843.074, -74.3865, 2.94298, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 330.036, -847.017, -74.318, 3.25321, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 328.839, -838.69, -72.921, 1.8929, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 322.452, -829.799, -73.5624, 2.6563, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 316.367, -822.016, -73.1033, 1.71618, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 320.592, -812.011, -73.8038, 0.957487, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 322.619, -803.898, -72.9384, 2.07668, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 331.481, -811.702, -72.9227, 5.46332, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 341.894, -826.849, -73.049, 5.46332, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 387.58, -856.341, -71.0935, 5.72486, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 401.977, -867.49, -73.3215, 5.27247, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 408.72, -872.115, -73.0256, 6.03823, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 416.438, -875.336, -70.4833, 5.08397, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 403.004, -895.527, -75.561, 5.60391, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 409.35, -902.562, -77.2837, 5.22927, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 414.538, -911.69, -79.8006, 5.22927, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 419.727, -920.818, -80.7403, 5.22927, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 428.151, -920.833, -79.0992, 0.892305, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 436.712, -911.759, -78.8367, 0.0605679, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 461.167, -910.276, -77.4777, 0.0605679, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 419.827, -930.386, -77.7951, 4.29465, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 418.017, -939.624, -80.2493, 4.29465, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 417.247, -948.532, -79.3315, 4.29465, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 409.236, -952.042, -80.6495, 4.29465, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 410.077, -959.059, -78.9977, 4.29465, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 403.871, -964.208, -77.8873, 4.29465, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 401.693, -970.428, -77.3012, 4.90255, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 402.379, -980.099, -75.4585, 4.60567, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 399.272, -984.535, -75.9494, 3.15425, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 380.102, -984.145, -74.2926, 2.13402, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 369.565, -973.481, -77.4914, 2.56756, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 360.748, -967.779, -79.832, 2.56756, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 350.138, -958.988, -79.4422, 2.16229, 30, 0, 0, 1, 0, 0, 0), +(30391, 619, 2, 1, 0, 0, 342.879, -944.352, -79.8533, 1.64157, 30, 0, 0, 1, 0, 0, 0); + +UPDATE `creature_template` SET `AIname`='EventAI' WHERE `entry` = 30176; +DELETE FROM `creature_ai_scripts` WHERE `creature_id` = 30176; +INSERT INTO `creature_ai_scripts` (`id`, `creature_id`, `event_type`, `event_inverse_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action1_type`, `action1_param1`, `action1_param2`, `action1_param3`, `action2_type`, `action2_param1`, `action2_param2`, `action2_param3`, `action3_type`, `action3_param1`, `action3_param2`, `action3_param3`, `comment`) VALUES +('3017610', '30176', '11', '0', '100', '6', '0', '0', '0', '0', '11', '56151', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', ''), +('3017611', '30176', '8', '0', '100', '6', '56153', '0', '0', '0', '28', '0', '56153', '0', '0', '0', '0', '0', '0', '0', '0', '0', ''); diff --git a/addition/721_icecrown_eventai_mangos.sql b/addition/721_icecrown_eventai_mangos.sql new file mode 100644 index 000000000..2e4550033 --- /dev/null +++ b/addition/721_icecrown_eventai_mangos.sql @@ -0,0 +1,554 @@ +# ICC trash mobs from Xfurry +-- ########### +-- LOWER SPIRE +-- ########### + +-- The Damned +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37011; +DELETE FROM `creature_ai_scripts` WHERE `id`=3701101; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3701101,37011,0,0,100,30,10000,15000,10000,15000,11,70960,0,0,0,0,0,0,0,0,0,0, 'The Dammed - cast Bone Flurry'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3701102; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3701102,37011,6,0,100,30,0,0,0,0,11,70961,0,0,0,0,0,0,0,0,0,0, 'The Dammed - cast Shattred Bones'); +-- Ancient Skeletal Soldier +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37012; +DELETE FROM `creature_ai_scripts` WHERE `id`=3701201; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3701201,37012,0,0,100,31,5000,7000,5000,7000,11,70964,1,0,0,0,0,0,0,0,0,0, 'Ancient skeletal soldier - shield bash'); +-- Servant of the Throne +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36724; +DELETE FROM `creature_ai_scripts` WHERE `id`=3672401; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3672401,36724,0,0,100,31,3000,5000,7000,9000,11,71029,0,0,0,0,0,0,0,0,0,0, 'Servant of the throne - glacial blast'); +-- Nerub'ar Broodkeeper +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36725; +DELETE FROM `creature_ai_scripts` WHERE `id`=3672501; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3672501,36725,10,0,100,31,1,60,0,0,38,0,0,0,0,0,0,0,0,0,0,0, 'Nerubar broodkeeper - set aggressive'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3672502; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3672502,36725,0,0,100,31,5000,7000,5000,7000,11,70965,4,0,0,0,0,0,0,0,0,0, 'Nerubar Broodkeeper - crypt scarabs'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3672503; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3672503,36725,14,0,100,31,50,30,8000,13000,11,36725,6,0,0,0,0,0,0,0,0,0, 'Nerubar broodkeeper - dark mending'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3672504; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3672504,36725,0,0,100,31,7000,11000,7000,11000,11,70980,4,0,0,0,0,0,0,0,0,0, 'Nerubar broodkeeper - web wrap'); +-- Deathbound Ward +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37007; +DELETE FROM `creature_ai_scripts` WHERE `id`=3700701; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3700701,37007,10,0,100,31,1,80,0,0,38,0,0,0,0,0,0,0,0,0,0,0, 'Deathbound ward - set aggressive'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3700702; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3700702,37007,0,0,100,31,5000,7000,5000,7000,11,71021,1,0,0,0,0,0,0,0,0,0, 'Deathbound ward - saber lash'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3700703; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3700703,37007,0,0,100,31,15000,20000,20000,30000,11,71022,0,0,0,0,0,0,0,0,0,0, 'Deathbound ward - disrupting shout'); + +-- ##################### +-- ORATORY OF THE DAMMED +-- ##################### + +-- Deathspeaker High Priest +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36829; +DELETE FROM `creature_ai_scripts` WHERE `id`=3682901; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3682901,36829,4,0,100,30,0,0,0,0,11,69491,0,0,0,0,0,0,0,0,0,0, 'Deathspeaker high priest - aura of darkness'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3682902; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3682902,36829,0,0,100,31,5000,7000,10000,12000,11,69483,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker High Priest - dark reckoning'); +-- Deathspeaker Attendant +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36811; +DELETE FROM `creature_ai_scripts` WHERE `id`=3681101; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3681101,36811,0,0,100,31,3000,5000,6000,8000,11,69387,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker attendant - shadow bolt'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3681102; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3681102,36811,0,0,100,11,10000,15000,10000,15000,11,69355,0,0,0,0,0,0,0,0,0,0, 'Deathspeaker attendant - shadow nova 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3681103; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3681103,36811,0,0,100,21,10000,15000,10000,15000,11,71106,0,0,0,0,0,0,0,0,0,0, 'Deathspeaker attendant - shadow nova 25'); +-- Deathspeaker Disciple +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36807; +DELETE FROM `creature_ai_scripts` WHERE `id`=3680701; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680701,36807,0,0,100,31,3000,6000,7000,10000,11,69387,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker disciple - shadow bolt'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3680702; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680702,36807,16,0,100,31,69391,30,5000,9000,11,69391,6,0,0,0,0,0,0,0,0,0, 'Deathspeaker disciple - dark blessing'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3680703; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680703,36807,14,0,100,11,50,50,7000,11000,11,69389,6,0,0,0,0,0,0,0,0,0, 'Deathspeaker disciple - shadow mend 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3680704; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680704,36807,14,0,100,21,50,50,7000,11000,11,71107,6,0,0,0,0,0,0,0,0,0, 'Deathspeaker disciple - shadow mend 25'); +-- Deathspeaker Servant +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36805; +DELETE FROM `creature_ai_scripts` WHERE `id`=3680501; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680501,36805,0,0,100,31,7000,10000,7000,10000,11,69405,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker Servant - consuming shadows'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3680502; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680502,36805,0,0,100,11,4000,7000,4000,7000,11,69576,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker servant - chaos bolt 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3680503; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680503,36805,0,0,100,21,4000,7000,4000,7000,11,71108,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker servant - chaos bolt 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3680504; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680504,36805,0,0,100,11,7000,13000,7000,13000,11,69404,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker servant - curse of agony 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3680505; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680505,36805,0,0,100,21,7000,13000,7000,13000,11,71112,4,0,0,0,0,0,0,0,0,0, 'Deathspeaker servant - curse of agony 25'); +-- Deathspeaker Zealot +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36808; +DELETE FROM `creature_ai_scripts` WHERE `id`=3680801; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3680801,36808,0,0,100,31,3000,6000,3000,6000,11,69492,1,0,0,0,0,0,0,0,0,0, 'Deathspeaker zealot - shadow cleave'); + +-- ################ +-- RAMPART OF SKULL +-- ################ + +-- Frenzied Abomination +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37546; +DELETE FROM `creature_ai_scripts` WHERE `id`=3754601; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3754601,37546,0,0,100,31,3000,5000,3000,5000,11,70191,1,0,0,0,0,0,0,0,0,0, 'Frenzied abomination - abomination cleave'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3754602; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3754602,37546,2,0,100,30,10,9,0,0,11,70371,0,0,0,0,0,0,0,0,0,0, 'Frenzied abomination - enrage'); +-- Spire Gargoyle +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37544; +DELETE FROM `creature_ai_scripts` WHERE `id`=3754401; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3754401,37544,0,0,100,31,3000,5000,3000,5000,11,70189,4,0,0,0,0,0,0,0,0,0, 'Spire gargoyle - poison spit'); +-- Spire Minion +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37545; +DELETE FROM `creature_ai_scripts` WHERE `id`=3754501; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3754501,37545,0,0,100,31,3000,6000,3000,6000,11,70396,1,0,0,0,0,0,0,0,0,0, 'Spire minion - ghoul slash'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3754502; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3754502,37545,0,0,100,31,30000,30000,30000,30000,11,70363,0,0,0,0,0,0,0,0,0,0, 'Spire minion - cannibalize'); + +-- ########### +-- PLAGUEWORKS +-- ########### + +-- Blighted Abomination +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37022; +DELETE FROM `creature_ai_scripts` WHERE `id`=3702201; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3702201,37022,0,0,100,31,2000,5000,2000,5000,11,40504,1,0,0,0,0,0,0,0,0,0, 'Blighted abomination - cleave'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3702202; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3702202,37022,0,0,100,31,7000,15000,20000,30000,11,71150,0,0,0,0,0,0,0,0,0,0, 'Blighted abomination - plague cloud'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3702203; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3702203,37022,0,0,100,31,5000,10000,10000,15000,11,71140,4,0,0,0,0,0,0,0,0,0, 'Blighted abomination - scourge hook'); +-- Plague Scientist +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37023; +DELETE FROM `creature_ai_scripts` WHERE `id`=3702301; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3702301,37023,0,0,100,31,10000,10000,10000,10000,11,71103,4,0,0,0,0,0,0,0,0,0, 'Plague scientist - combobulating spray'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3702302; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3702302,37023,0,0,100,31,8000,11000,8000,11000,11,73079,4,0,0,0,0,0,0,0,0,0, 'Plague scientist - plague blast'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3702303; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3702303,37023,0,0,100,31,15000,20000,15000,20000,11,69871,6,0,0,0,0,0,0,0,0,0, 'Plague scientist - plague stream'); + +-- Vengefull fleshreaper +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37038; +DELETE FROM `creature_ai_scripts` WHERE `id`=3703801; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3703801,37038,0,0,100,31,5000,10000,5000,10000,11,71164,5,0,0,0,0,0,0,0,0,0, 'Vengefull fleshreaper - leaping face maul'); +-- Decaying colossus +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36880; +DELETE FROM `creature_ai_scripts` WHERE `id`=3688001; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3688001,36880,0,0,100,11,5000,9000,10000,15000,11,71114,0,0,0,0,0,0,0,0,0,0, 'Decaying colossus - massive stomp 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3688002; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3688002,36880,0,0,100,21,5000,9000,10000,15000,11,71115,0,0,0,0,0,0,0,0,0,0, 'Decaying colossus - massive stomp 25'); + +-- ############# +-- CRIMSON HALLS +-- ############# + +-- Darkfallen Archmage +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37664; +DELETE FROM `creature_ai_scripts` WHERE `id`=3766401; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766401,37664,0,0,100,11,5000,10000,30000,35000,11,70408,0,0,0,0,0,0,0,0,0,0, 'Darkfallen archmage - amplify magic 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766402; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766402,37664,0,0,100,21,5000,10000,30000,35000,11,72336,0,0,0,0,0,0,0,0,0,0, 'Darkfallen archmage - amplify magic 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766403; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766403,37664,0,0,100,11,7000,11000,7000,11000,11,70407,0,0,0,0,0,0,0,0,0,0, 'Darkfallen archmage - blast wave 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766404; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766404,37664,0,0,100,21,7000,11000,7000,11000,11,71151,0,0,0,0,0,0,0,0,0,0, 'Darkfallen archmage - blast wave 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766405; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766405,37664,0,0,100,11,9000,13000,9000,13000,11,70409,4,0,0,0,0,0,0,0,0,0, 'Darkfallen archmage - fireball 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766406; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766406,37664,0,0,100,21,9000,13000,9000,13000,11,71153,4,0,0,0,0,0,0,0,0,0, 'Darkfallen archmage - fireball 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766407; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766407,37664,0,0,100,31,10000,10000,10000,10000,11,70410,5,0,0,0,0,0,0,0,0,0, 'Darkfallen archmage - polymorph spider'); +-- Darkfallen Blood Knight +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37595; +DELETE FROM `creature_ai_scripts` WHERE `id`=3759501; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3759501,37595,4,0,100,6,0,0,0,0,11,71736,0,0,0,0,0,0,0,0,0,0, 'Darkfallen blood knight - vampiric aura'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3759502; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3759502,37595,0,0,100,31,5000,9000,5000,9000,11,70450,1,0,0,0,0,0,0,0,0,0, 'Darkfallen blood knight - blood mirror'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3759503; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3759503,37595,0,0,100,31,3000,6000,3000,6000,11,70437,1,0,0,0,0,0,0,0,0,0, 'Darkfallen blood knight - unholy strike'); +-- Darkfallen Noble +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37663; +DELETE FROM `creature_ai_scripts` WHERE `id`=3766301; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766301,37663,0,0,100,31,7000,11000,7000,11000,11,70645,4,0,0,0,0,0,0,0,0,0, 'Darkfallen noble - chains of shadow'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766302; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766302,37663,0,0,100,11,3000,6000,3000,6000,11,72960,4,0,0,0,0,0,0,0,0,0, 'Darkfallen noble - shadow bolt 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766303; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766303,37663,0,0,100,21,3000,6000,3000,6000,11,72961,4,0,0,0,0,0,0,0,0,0, 'Darkfallen noble - shadow bolt 25'); +-- Darkfallen Advisor +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37571; +DELETE FROM `creature_ai_scripts` WHERE `id`=3757101; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3757101,37571,0,0,100,11,5000,9000,5000,9000,11,72057,4,0,0,0,0,0,0,0,0,0, 'Darkfallen advisor - lich slap 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3757102; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3757102,37571,0,0,100,21,5000,9000,5000,9000,11,72421,4,0,0,0,0,0,0,0,0,0, 'Darkfallen advisor - lich slap 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3757103; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3757103,37571,16,0,100,31,72066,40,10000,20000,11,72066,6,0,0,0,0,0,0,0,0,0, 'Darkfallen advisor - shroud of spell warding'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3757104; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3757104,37571,16,0,100,31,72065,50,10000,20000,11,72065,6,0,0,0,0,0,0,0,0,0, 'Darkfallen advisor - shroud of protection'); +-- Darkfallen Lieutenant +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37665; +DELETE FROM `creature_ai_scripts` WHERE `id`=3766501; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766501,37665,0,0,100,11,5000,7000,5000,7000,11,70435,1,0,0,0,0,0,0,0,0,0, 'Darkfallen lieutenant - rend flesh 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766502; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766502,37665,0,0,100,21,5000,7000,5000,7000,11,71154,1,0,0,0,0,0,0,0,0,0, 'Darkfallen lieutenant - rend flesh 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766503; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766503,37665,0,0,100,31,5000,7000,20000,25000,11,70423,1,0,0,0,0,0,0,0,0,0, 'Darkfallen lieutenant - vampiric curse'); +-- Darkfallen Tactician +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37666; +DELETE FROM `creature_ai_scripts` WHERE `id`=3766601; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766601,37666,0,0,100,31,5000,7000,10000,13000,11,70432,1,0,0,0,0,0,0,0,0,0, 'Darkfallen tactitian - blood sap'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766602; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766602,37666,0,0,100,31,7000,10000,7000,10000,11,70437,1,0,0,0,0,0,0,0,0,0, 'Darkfallen tactitian - unholy strike'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766603; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766603,37666,4,0,100,6,0,0,0,0,11,70431,0,0,0,0,0,0,0,0,0,0, 'Darkfallen tactitian - shadowstep'); +-- Darkfallen Commander +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37662; +DELETE FROM `creature_ai_scripts` WHERE `id`=3766201; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766201,37662,4,0,100,6,0,0,0,0,11,70750,0,0,0,0,0,0,0,0,0,0, 'Darkfallen commander - battle shout'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766202; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766202,37662,0,0,100,11,3000,5000,5000,7000,11,70449,5,0,0,0,0,0,0,0,0,0, 'Darkfallen commander - vampire rush 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3766203; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3766203,37662,0,0,100,21,3000,5000,5000,7000,11,71155,5,0,0,0,0,0,0,0,0,0, 'Darkfallen commander - vampire rush 25'); + +-- ######### +-- FROSTWING +-- ######### + +-- Frostwarden handler +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37531; +DELETE FROM `creature_ai_scripts` WHERE `id`=3753101; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3753101,37531,0,0,100,11,6000,11000,6000,11000,11,71337,0,0,0,0,0,0,0,0,0,0, 'Frostwarde handler - concussive shock 10'); +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37531; +DELETE FROM `creature_ai_scripts` WHERE `id`=3753102; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3753102,37531,0,0,100,21,6000,11000,6000,11000,11,71338,0,0,0,0,0,0,0,0,0,0, 'Frostwarde handler - concussive shock 10'); +-- Frostwing whelp +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37532; +DELETE FROM `creature_ai_scripts` WHERE `id`=3753201; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3753201,37532,0,0,100,31,5000,7000,10000,13000,11,71350,4,0,0,0,0,0,0,0,0,0, 'Frostwing whelp - focus fire'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3753202; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3753202,37532,0,0,100,11,4000,5000,4000,5000,11,71361,4,0,0,0,0,0,0,0,0,0, 'Frostwing whelp - frost blast 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3753203; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3753203,37532,0,0,100,21,4000,5000,4000,5000,11,71362,4,0,0,0,0,0,0,0,0,0, 'Frostwing whelp - frost blast 25'); +-- Ymirjar battle maiden +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37132; +DELETE FROM `creature_ai_scripts` WHERE `id`=3713201; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713201,37132,0,0,100,31,4000,6000,10000,11000,11,71258,0,0,0,0,0,0,0,0,0,0, 'Ymirjar battle maiden - adrenaline rush'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3713202; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713202,37132,0,0,100,31,5000,7000,5000,7000,11,71257,3,0,0,0,0,0,0,0,0,0, 'Ymirjar battle maiden - barbaric strike'); +-- Ymirjar deathbringer +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=38125; +DELETE FROM `creature_ai_scripts` WHERE `id`=3812501; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3812501,38125,0,0,100,31,4000,6000,6000,8000,11,71298,4,0,0,0,0,0,0,0,0,0, 'Ymirjar deathbringer - banish'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3812502; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3812502,38125,0,0,100,11,7000,13000,15000,20000,11,71299,0,0,0,0,0,0,0,0,0,0, 'Ymirjar deathbringer - deaths embrace 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3812503; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3812503,38125,0,0,100,21,7000,13000,15000,20000,11,71300,0,0,0,0,0,0,0,0,0,0, 'Ymirjar deathbringer - deaths embrace 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3812504; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3812504,38125,0,0,100,11,4000,7000,4000,7000,11,71296,4,0,0,0,0,0,0,0,0,0, 'Ymirjar deathbringer - shadow bolt 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3812505; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3812505,38125,0,0,100,21,4000,7000,4000,7000,11,71297,4,0,0,0,0,0,0,0,0,0, 'Ymirjar deathbringer - shadow bolt 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3812506; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3812506,38125,16,0,100,31,69929,30,35000,50000,11,69929,6,0,0,0,0,0,0,0,0,0, 'Ymirjar deathbringer - spirit steam'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3812507; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3812507,38125,0,0,100,31,20000,25000,25000,30000,11,71303,0,0,0,0,0,0,0,0,0,0, 'Ymirjar deathbringer - summon ymirjar'); +-- Ymirjar warlord +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37133; +DELETE FROM `creature_ai_scripts` WHERE `id`=3713301; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713301,37133,0,0,100,31,8000,13000,8000,13000,11,41056,0,0,0,0,0,0,0,0,0,0, 'Ymirjar warlord - whirlwind'); +-- Ymirjar huntress +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37134; +DELETE FROM `creature_ai_scripts` WHERE `id`=3713401; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713401,37134,0,0,100,31,5000,10000,7000,14000,11,71249,0,0,0,0,0,0,0,0,0,0, 'Ymirjar huntress - ice trap'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3713402; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713402,37134,0,0,100,31,8000,13000,10000,15000,11,71251,0,0,0,0,0,0,0,0,0,0, 'Ymirjar huntress - rapid shot'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3713403; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713403,37134,0,0,100,31,2000,4000,2000,4000,11,71253,4,0,0,0,0,0,0,0,0,0, 'Ymirjar huntress - shoot'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3713404; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713404,37134,0,0,100,31,6000,8000,7000,10000,11,71252,4,0,0,0,0,0,0,0,0,0, 'Ymirjar huntress - volley'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3713405; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3713405,37134,4,0,100,6,0,0,0,0,11,71705,0,0,0,0,0,0,0,0,0,0, 'Ymirjar huntress - summon warhawk'); +-- Ymirjar frostbinder +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37127; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712701; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712701,37127,0,0,100,31,7000,10000,7000,10000,11,71306,5,0,0,0,0,0,0,0,0,0, 'Ymirjar frostbinder - twisted winds'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712702; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712702,37127,0,0,100,31,15000,20000,15000,20000,11,71274,5,0,0,0,0,0,0,0,0,0, 'Ymirjar frostbinder - frozen orb'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712703; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712703,37127,4,0,100,6,0,0,0,0,11,71270,0,0,0,0,0,0,0,0,0,0, 'Ymirjar frostbinder - arctic chill'); + +#-- ############### +#-- VALITHRIA EVENT +#-- ############### + +#-- Grottnous abomination +#UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37886; +#DELETE FROM `creature_ai_scripts` WHERE `id`=3788601; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3788601,37886,0,0,100,3,7000,13000,7000,13000,11,70633,0,0,0,0,0,0,0,0,0,0, 'Gluttnous abomination - gut spray 10n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3788602; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3788602,37886,0,0,100,5,7000,13000,7000,13000,11,71283,0,0,0,0,0,0,0,0,0,0, 'Gluttnous abomination - gut spray 25n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3788603; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3788603,37886,0,0,100,9,7000,13000,7000,13000,11,72025,0,0,0,0,0,0,0,0,0,0, 'Gluttnous abomination - gut spray 10h'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3788604; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3788604,37886,0,0,100,17,7000,13000,7000,13000,11,72026,0,0,0,0,0,0,0,0,0,0, 'Gluttnous abomination - gut spray 25h'); +#-- Blistering Zombies +#UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37934; +#DELETE FROM `creature_ai_scripts` WHERE `id`=3793401; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3793401,37934,4,0,100,31,0,0,0,0,11,70749,0,0,0,0,0,0,0,0,0,0, 'Blistering zombies - corrosion'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3793402; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3793402,37934,6,0,100,3,0,0,0,0,11,70744,0,0,0,0,0,0,0,0,0,0, 'Blistering zombies - acid burst 10n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3793403; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3793403,37934,6,0,100,5,0,0,0,0,11,71733,0,0,0,0,0,0,0,0,0,0, 'Blistering zombies - acid burst 25n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3793404; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3793404,37934,6,0,100,9,0,0,0,0,11,72017,0,0,0,0,0,0,0,0,0,0, 'Blistering zombies - acid burst 10h'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3793405; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3793405,37934,6,0,100,17,0,0,0,0,11,72018,0,0,0,0,0,0,0,0,0,0, 'Blistering zombies - acid burst 25h'); +#-- Suppresser +#UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37863; +#DELETE FROM `creature_ai_scripts` WHERE `id`=3786301; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3786301,37863,4,0,100,31,0,0,0,0,11,70588,1,0,0,0,0,0,0,0,0,0, 'Suppresser - suppression'); +#-- Blazing Skeleton +#UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36791; +#DELETE FROM `creature_ai_scripts` WHERE `id`=3679101; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3679101,36791,0,0,100,3,5000,10000,5000,10000,11,70754,4,0,0,0,0,0,0,0,0,0, 'Blazin skeleton - fireball 10n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3679102; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3679102,36791,0,0,100,5,5000,10000,5000,10000,11,71748,4,0,0,0,0,0,0,0,0,0, 'Blazin skeleton - fireball 25n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3679103; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3679103,36791,0,0,100,9,5000,10000,5000,10000,11,72023,4,0,0,0,0,0,0,0,0,0, 'Blazin skeleton - fireball 10h'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3679104; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3679104,36791,0,0,100,17,5000,10000,5000,10000,11,72024,4,0,0,0,0,0,0,0,0,0, 'Blazin skeleton - fireball 25h'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3679105; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3679105,36791,0,0,100,11,10000,15000,10000,15000,11,69325,0,0,0,0,0,0,0,0,0,0, 'Blazin skeleton - lay waste 10'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3679106; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3679106,36791,0,0,100,21,10000,15000,10000,15000,11,71730,0,0,0,0,0,0,0,0,0,0, 'Blazin skeleton - lay waste 10'); +-- Mana void +-- UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=38068; +-- DELETE FROM `creature_ai_scripts` WHERE `id`=3806801; +-- INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +-- (3806801,38068,4,0,100,31,0,0,0,0,11,71085,0,0,0,0,0,0,0,0,0,0, 'Mana void - mana void aura'); +#UPDATE `creature_template` SET `modelid1` = 11686 WHERE `entry` = 38068; +#-- Risen archmage +#UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37868; +#DELETE FROM `creature_ai_scripts` WHERE `id`=3786801; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3786801,37868,0,0,100,3,7000,11000,7000,11000,11,70759,0,0,0,0,0,0,0,0,0,0, 'Risen archmage - frostbolt volley 10n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3786802; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3786802,37868,0,0,100,5,7000,11000,7000,11000,11,71889,0,0,0,0,0,0,0,0,0,0, 'Risen archmage - frostbolt volley 25n'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3786803; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3786803,37868,0,0,100,9,7000,11000,7000,11000,11,72015,0,0,0,0,0,0,0,0,0,0, 'Risen archmage - frostbolt volley 10h'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3786804; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3786804,37868,0,0,100,17,7000,11000,7000,11000,11,72016,0,0,0,0,0,0,0,0,0,0, 'Risen archmage - frostbolt volley 25h'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3786805; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3786805,37868,0,0,100,11,25000,30000,25000,30000,11,71179,0,0,0,0,0,0,0,0,0,0, 'Risen archmage - mana void 10'); +#DELETE FROM `creature_ai_scripts` WHERE `id`=3786806; +#INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +#(3786806,37868,0,0,100,21,25000,30000,25000,30000,11,71741,0,0,0,0,0,0,0,0,0,0, 'Risen archmage - mana void 10'); + +-- ############ +-- SVALNA EVENT +-- ############ + +-- Captain Rupert +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37125; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712501; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712501,37125,0,0,100,31,5000,7000,7000,11000,11,71787,4,0,0,0,0,0,0,0,0,0, 'Captain Rupert - fel bomb'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712502; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712502,37125,0,0,100,31,7000,9000,9000,13000,11,71594,4,0,0,0,0,0,0,0,0,0, 'Captain Rupert - machine gun'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712503; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712503,37125,0,0,100,31,10000,13000,15000,17000,11,71786,4,0,0,0,0,0,0,0,0,0, 'Captain Rupert - rocket'); +-- Captain Grondel +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37124; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712401; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712401,37124,0,0,100,31,10000,10000,10000,10000,11,71553,5,0,0,0,0,0,0,0,0,0, 'Captain Groundel - charge'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712402; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712402,37124,0,0,100,31,5000,10000,10000,15000,11,71554,3,0,0,0,0,0,0,0,0,0, 'Captain Groundel - sunder armor'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712403; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712403,37124,0,0,100,31,5000,7000,5000,7000,11,71552,1,0,0,0,0,0,0,0,0,0, 'Captain Groundel - mortal strike'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712404; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712404,37124,0,0,100,31,5000,9000,10000,15000,11,71785,4,0,0,0,0,0,0,0,0,0, 'Captain Groundel - conflagration'); +-- Captain Brandon +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37123; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712301; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712301,37123,0,0,100,31,10000,10000,10000,10000,11,71549,1,0,0,0,0,0,0,0,0,0, 'Captain Brandon - crusader strike'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712302; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712302,37123,2,0,100,30,25,24,0,0,11,71550,0,0,0,0,0,0,0,0,0,0, 'Captain Brandon - divine shield'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712303; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712303,37123,0,0,100,31,5000,8000,7000,10000,11,71784,4,0,0,0,0,0,0,0,0,0, 'Captain Brandon - hammer of betrayal'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712304; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712304,37123,0,0,100,31,7000,10000,8000,12000,11,71551,4,0,0,0,0,0,0,0,0,0, 'Captain Brandon - judgement of command'); +-- Captain Arnath +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37122; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712201; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712201,37122,14,0,100,31,50,30,5000,10000,11,71595,6,0,0,0,0,0,0,0,0,0, 'Captain Arnath - flash heal'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712202; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712202,37122,0,0,100,21,15000,20000,20000,25000,11,14515,4,0,0,0,0,0,0,0,0,0, 'Captain Arnath - dominate mind'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712203; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712203,37122,16,0,100,31,71548,30,30000,35000,11,71548,6,0,0,0,0,0,0,0,0,0, 'Captain Arnath - power shield'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712204; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712204,37122,0,0,100,3,5000,10000,9000,15000,11,71546,4,0,0,0,0,0,0,0,0,0, 'Captain Arnath - smite 10n'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712205; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712205,37122,0,0,100,5,5000,10000,9000,15000,11,71547,4,0,0,0,0,0,0,0,0,0, 'Captain Arnath - smite 25n'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712206; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712206,37122,0,0,100,9,5000,10000,9000,15000,11,71778,4,0,0,0,0,0,0,0,0,0, 'Captain Arnath - smite 10h'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712207; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712207,37122,0,0,100,17,5000,10000,9000,15000,11,71779,4,0,0,0,0,0,0,0,0,0, 'Captain Arnath - smite 25h'); +-- Crok and Svalna need SD2 script +-- this is just a basic of spells +-- Crok Scourgebane +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37129; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712901; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712901,37129,0,0,100,31,5000,7000,7000,9000,11,71489,1,0,0,0,0,0,0,0,0,0, 'Crock Scrougebane - deathstrike'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712902; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712902,37129,0,0,100,31,7000,9000,10000,12000,11,71488,1,0,0,0,0,0,0,0,0,0, 'Crock Scrougebane - scourgestrike'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712903; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712903,37129,0,0,100,21,10000,15000,10000,15000,11,71490,4,0,0,0,0,0,0,0,0,0, 'Crock Scrougebane - deathcoil'); +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37129; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712904; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712904,37129,4,0,100,6,0,0,0,0,39,30,0,0,0,0,0,0,0,0,0,0, 'Crock Scrougebane - call for help'); +-- Svalna spear +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=38248; +DELETE FROM `creature_ai_scripts` WHERE `id`=3824801; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3824801,38248,4,0,100,30,0,0,0,0,11,71443,3,0,0,0,0,0,0,0,0,0, 'Svalna spear - impale'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3824802; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3824802,38248,6,0,100,30,0,0,0,0,28,1,71443,0,0,0,0,0,0,0,0,0, 'Svalna spear - remove impale'); +-- Svalna +UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=37126; +DELETE FROM `creature_ai_scripts` WHERE `id`=3712601; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712601,37126,4,0,100,6,0,0,0,0,11,71465,0,0,0,0,0,0,0,0,0,0, 'Sister Svalna - divine surge'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712602; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712602,37126,0,0,100,11,15000,20000,20000,25000,11,71468,0,0,0,0,0,0,0,0,0,0, 'Sister Svalna - aether burst 10'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712603; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712603,37126,0,0,100,21,15000,20000,20000,25000,11,71469,0,0,0,0,0,0,0,0,0,0, 'Sister Svalna - aether burst 25'); +DELETE FROM `creature_ai_scripts` WHERE `id`=3712604; +INSERT INTO `creature_ai_scripts` (`id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`,`comment`) VALUES +(3712604,37126,0,0,100,31,25000,30000,60000,70000,11,70196,5,0,11,71463,0,0,0,0,0,0, 'Sister Svalna - sprear'); diff --git a/addition/721_icecrown_mangos.sql b/addition/721_icecrown_mangos.sql new file mode 100644 index 000000000..6ee568b63 --- /dev/null +++ b/addition/721_icecrown_mangos.sql @@ -0,0 +1,225 @@ +-- Entrance +UPDATE `areatrigger_teleport` SET `required_level` = '80' WHERE `areatrigger_teleport`.`id` =5670; + +UPDATE `creature` SET `spawntimesecs` = 7200 WHERE `map` = 631 AND (`spawntimesecs` BETWEEN 200 AND 7100 ); + +DELETE FROM `gameobject` WHERE `guid` = 913334; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(913334, 202244, 631, 3, 1, -209.5, 2211.91, 199.97, 3.07661, 0, 0, 0.999472, 0.0324833, 0, 0, 1); + +UPDATE `gameobject_template` SET `flags` = 0, `ScriptName` = 'go_icecrown_teleporter' WHERE `entry` IN (202242,202243,202244,202245,202235,202223,202246); +UPDATE `gameobject` SET `phaseMask` = 1 WHERE `id` IN (202242,202243,202244,202245,202235,202223,202246); +DELETE FROM `areatrigger_teleport` WHERE `id` = 5718 AND `target_map` = 631; + +DELETE FROM `creature` WHERE `id` = 99322; +DELETE FROM `creature_template` WHERE `entry` = 99322; +DELETE FROM `locales_npc_text` WHERE `entry` = 99322; +DELETE FROM `npc_text` WHERE `ID` = 99322; +DELETE FROM `locales_npc_text` WHERE `entry` = 99323; +DELETE FROM `npc_text` WHERE `ID` = 99323; +DELETE FROM `gameobject` WHERE `guid` IN (913334); + +UPDATE `instance_template` SET `ScriptName`='instance_icecrown_spire' WHERE `map`=631; + +-- Saurfang +UPDATE `creature_template` SET `vehicle_id` = 639, `AIName`='', `PowerType` = 3, `ScriptName`='boss_deathbringer_saurfang' WHERE `entry`=37813; +UPDATE `creature_template` SET `vehicle_id` = 639, `AIName`='', `PowerType` = 3 WHERE `entry` IN (38402,38582,38583); +UPDATE `creature` SET `position_x` = -476.621,`position_y` = 2211.11,`position_z` = 541.197, `spawntimesecs` = 604800 WHERE `id` = 37813; +UPDATE `creature_template` SET `ScriptName`='mob_blood_beast', `AIName`='' WHERE `entry`= 38508; +DELETE FROM `spell_script_target` WHERE `entry` IN (72260, 72202, 72278,72279,72280); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +('72260', '1', '37813'), +('72278', '1', '37813'), +('72279', '1', '37813'), +('72280', '1', '37813'), +('72202', '1', '37813'); + +DELETE FROM `spell_proc_event` WHERE entry IN (72176,72178, 72256); +INSERT INTO `spell_proc_event` VALUES +(72256, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(72178, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(72176, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- Deathwhisper +UPDATE `creature_template` SET `ScriptName`='boss_lady_deathwhisper' WHERE `entry`=36855; +UPDATE `creature_template` SET `faction_A`=14, `faction_H`=14,`ScriptName`='mob_vengeful_shade', `AIName`='' WHERE `entry`= 38222; +UPDATE `creature_template` SET `ScriptName`='mob_cult_adherent', `AIName`='' WHERE `entry`= 37949; +UPDATE `creature_template` SET `ScriptName`='mob_cult_fanatic', `AIName`='' WHERE `entry`= 37890; + +-- Marrowgar +UPDATE `creature_template` SET `ScriptName`='boss_lord_marrowgar' WHERE `entry`= 36612; +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201910,201911); +UPDATE `gameobject` SET `state` = '1' WHERE `guid` IN (72526,72525); +UPDATE `creature_template` SET `ScriptName`='mob_coldflame', `minlevel` = 82, `maxlevel` = 82, `modelid_1` = 11686, `modelid_2` = 11686, `modelid_3` = 11686, `modelid_4` = 11686, `faction_A` = 14, `faction_H` = 14 WHERE `entry`= 36672; +UPDATE `creature_template` SET `ScriptName`='mob_bone_spike' WHERE `entry`= 38711; + +-- Gunship battle +UPDATE `creature_template` SET `ScriptName`='mob_spire_frostwyrm', `AIName`='' WHERE `entry`= 37230; +DELETE FROM `creature_ai_scripts` WHERE `creature_id` = 37230; +UPDATE `creature_template` SET `ScriptName`='mob_frost_giant', `AIName`='' WHERE `entry` IN (38490, 38494) ; +DELETE FROM `creature_ai_scripts` WHERE `creature_id` IN (38490, 38494); +DELETE FROM `creature` WHERE `guid` = 94094 AND `id` = 38490; + +-- Gunship armory (override) +DELETE FROM `gameobject` WHERE `id` IN (201872,201873,201874,201875,202177,202178,202179,202180); +UPDATE `gameobject_template` SET `flags` = 0 WHERE `gameobject_template`.`entry` IN (201872,201873,201874,201875,202177,202178,202179,202180); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(972541, 201872, 631, 1, 1, -428.141, 2421.34, 191.233, 3.10389, 0, 0, 0.999822, 0.0188489, -604800, 100, 1), +(972543, 201873, 631, 2, 1, -428.141, 2421.34, 191.233, 3.10389, 0, 0, 0.999822, 0.0188489, -604800, 100, 1), +(972545, 201874, 631, 4, 1, -428.141, 2421.34, 191.233, 3.10389, 0, 0, 0.999822, 0.0188489, -604800, 100, 1), +(972547, 201875, 631, 8, 1, -428.141, 2421.34, 191.233, 3.10389, 0, 0, 0.999822, 0.0188489, -604800, 100, 1), +(972551, 202177, 631, 1, 1, -447.493, 2003.5, 191.235, 0.153939, 0, 0, 0.0768933, 0.997039, -604800, 100, 1), +(972553, 202178, 631, 2, 1, -447.493, 2003.5, 191.235, 0.153939, 0, 0, 0.0768933, 0.997039, -604800, 100, 1), +(972555, 202179, 631, 4, 1, -447.493, 2003.5, 191.235, 0.153939, 0, 0, 0.0768933, 0.997039, -604800, 100, 1), +(972557, 202180, 631, 8, 1, -447.493, 2003.5, 191.235, 0.153939, 0, 0, 0.0768933, 0.997039, -604800, 100, 1); + +-- Plague wing +-- Rotface +UPDATE `creature_template` SET `ScriptName`='boss_rotface', `AIName`='' WHERE `entry`= 36627; +UPDATE `gameobject_template` SET `faction` = '114' WHERE `gameobject_template`.`entry` IN (201370); +UPDATE `gameobject` SET `state` = '0' WHERE `id` IN (201370); +UPDATE `creature_template` SET `ScriptName`='mob_small_ooze', `AIName`='' WHERE `entry`= 36897; +UPDATE `creature_template` SET `ScriptName`='mob_big_ooze', `AIName`='' WHERE `entry`= 36899; +UPDATE `creature_template` SET `ScriptName`='mob_ooze_spray_stalker', `AIName`='' WHERE `entry`= 37986; +UPDATE `creature_template` SET `minlevel` = 80, `maxlevel` = 80, `AIName` ='', `faction_A`= 14, `faction_H` = 14, `ScriptName`='mob_sticky_ooze', `AIName`='' WHERE `entry`= 37006; +UPDATE `creature_template` SET `minlevel` = 80, `maxlevel` = 80, `AIName` ='', `faction_A`= 14, `faction_H` = 14, `ScriptName`='', `AIName`='' WHERE `entry` IN (37013); +UPDATE `creature_template` SET `minlevel` = 80, `maxlevel` = 80, `AIName` ='', `faction_A`= 14, `faction_H` = 14, `ScriptName`='mob_ooze_explode_stalker', `AIName`='' WHERE `entry` = 38107; +DELETE FROM `spell_script_target` WHERE `entry` = 69783; +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69783', '1', '37013'); +DELETE FROM `spell_script_target` WHERE `entry` = 69508; +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69508', '1', '37986'); + + +-- Festergut +UPDATE `creature_template` SET `ScriptName`='boss_festergut', `AIName`='' WHERE `entry`= 36626; +UPDATE `gameobject_template` SET `faction` = '114' WHERE `gameobject_template`.`entry` IN (201371); +UPDATE `gameobject` SET `state` = '0' WHERE `id` IN (201371); +UPDATE `creature_template` SET `ScriptName`='mob_vile_gas_stalker', `AIName`='' WHERE `entry`= 38548; +UPDATE `creature_template` SET `faction_A` = 14, `faction_H` = 14, `ScriptName`='', `AIName`='' WHERE `entry`= 36659; +-- original auras from YTDB +-- INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `auras`) VALUES +-- (36659, 0, 0, 1, 0, 0, '69126 69152 69154'); +-- DELETE FROM `creature_template_addon` WHERE `entry` = 36659; +-- Visual effect mobs from Timmit +UPDATE `creature` SET `spawnMask` = 15, `modelid` = 11686, `spawntimesecs` = 300 WHERE `id`=37013; + +-- Professor putricide +UPDATE `creature_template` SET `ScriptName`='boss_proffesor_putricide', `AIName`='' WHERE `entry`= 36678; +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201372,201614,201613, 201612); +UPDATE `gameobject` SET `state` = '1' WHERE `id` IN (201612,201614,201613); +UPDATE `gameobject` SET `state` = '0' WHERE `id` IN (201372); +UPDATE `creature_template` SET `ScriptName`='mob_icc_gas_cloud', `AIName`='' WHERE `entry`= 37562; +UPDATE `creature_template` SET `ScriptName`='mob_icc_volatile_ooze', `AIName`='' WHERE `entry`= 37697; +UPDATE `creature_template` SET `ScriptName`='mob_choking_gas_bomb', `AIName`='',`minlevel` = 82, `maxlevel` = 82, `faction_A` = 14, `faction_H` = 14, `scale` = 0.5 WHERE `entry`= 38159; +UPDATE `creature_template` SET `ScriptName`='mob_ooze_puddle',`scale` = '1.0', `AIName`='', `minlevel` = 82, `maxlevel` = 82, `modelid_1` = 11686, `modelid_2` = 11686, `modelid_3` = 11686, `modelid_4` = 11686, `faction_A` = 14, `faction_H` = 14 WHERE `entry`= 37690; +UPDATE `gameobject_template` SET `faction` = '0', `ScriptName` = 'go_plague_sigil' WHERE `gameobject_template`.`entry` IN (202182); +-- Abomination +DELETE FROM `creature_template_addon` WHERE (`entry`=37672); +INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES (37672, '70385 70405'); +UPDATE `creature_template` SET `vehicle_id`=587 WHERE `entry` in (36678,38431,38585,38586); +UPDATE `creature_template` SET `vehicle_id`=591 WHERE `entry` in (37672,38605,38786,38787); +DELETE FROM `spell_script_target` WHERE `entry` IN (70360); +INSERT INTO `spell_script_target` VALUES (70360,1,37690); + +-- Blood wing +UPDATE `gameobject_template` SET `faction` = '0', `ScriptName` = 'go_bloodwing_sigil' WHERE `gameobject_template`.`entry` IN (202183); +DELETE FROM `spell_script_target` WHERE `entry` IN (70952, 70981, 70982); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +('70952', '1', '37970'), +('70981', '1', '37972'), +('70982', '1', '37973'); + +-- Lanathel intro +UPDATE `creature_template` SET `ScriptName`='boss_blood_queen_lanathel_intro', `AIName`='' WHERE `entry`= 38004; +-- UPDATE `creature_template` SET `ScriptName`='npc_blood_orb_control', `AIName`='' WHERE `entry`= 38008; +-- Taldaram +UPDATE `creature_template` SET `ScriptName`='boss_taldaram_icc', `AIName`='' WHERE `entry`= 37973; +UPDATE `creature_template` SET `ScriptName`='mob_ball_of_flames', `AIName`='',`minlevel` = 82, `maxlevel` = 82, `faction_A` = 14, `faction_H` = 14 WHERE `entry` IN (38332,38451); +-- Valanar +UPDATE `creature_template` SET `ScriptName`='boss_valanar_icc', `AIName`='' WHERE `entry`= 37970; +UPDATE `creature_template` SET `ScriptName`='mob_kinetic_bomb', `AIName`='',`minlevel` = 82, `maxlevel` = 82, `faction_A` = 14, `faction_H` = 14 WHERE `entry`= 38454; +UPDATE `creature_template` SET `ScriptName`='mob_shock_vortex', `AIName`='',`minlevel` = 82, `maxlevel` = 82, `faction_A` = 14, `faction_H` = 14 WHERE `entry`= 38422; +UPDATE `creature_template` SET `ScriptName`='mob_kinetic_bomb_target', `AIName`='' WHERE `entry`= 38458; +-- Keleseth +UPDATE `creature_template` SET `ScriptName`='boss_keleseth_icc', `AIName`='' WHERE `entry`= 37972; +UPDATE `creature_template` SET `ScriptName`='mob_dark_nucleus', `AIName`='',`minlevel` = 82, `maxlevel` = 82, `faction_A` = 14, `faction_H` = 14 WHERE `entry`= 38369; + +DELETE FROM `creature_template_addon` WHERE `entry` IN (37972,37973,37970,38401,38784,38785,38399,38769,38770,38400,38771,38772); +INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `emote`, `moveflags`, `auras`) VALUES +(37970, 0, 0, 0, 0, '71598'), +(37972, 0, 0, 0, 0, '71598'), +(37973, 0, 0, 0, 0, '71598'), +(38401, 0, 0, 0, 0, '71598'), +(38784, 0, 0, 0, 0, '71598'), +(38785, 0, 0, 0, 0, '71598'), +(38399, 0, 0, 0, 0, '71598'), +(38769, 0, 0, 0, 0, '71598'), +(38770, 0, 0, 0, 0, '71598'), +(38400, 0, 0, 0, 0, '71598'), +(38771, 0, 0, 0, 0, '71598'), +(38772, 0, 0, 0, 0, '71598'); + +-- Loot and deathstate for blood council (correct YTDB bugs, flags - from already killed princes) +UPDATE `creature_template` SET `unit_flags` = '0' WHERE `entry` IN (37972,37973,37970,38401,38784,38785,38399,38769,38770,38400,38771,38772); + +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201920,201377,201378); +UPDATE `gameobject` SET `state` = '1' WHERE `id` IN (201920,201377,201378); +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201376); +UPDATE `gameobject` SET `state` = '0' WHERE `id` IN (201376); + +-- Qween Lana'thel +UPDATE `creature_template` SET `ScriptName`='boss_blood_queen_lanathel', `AIName`='' WHERE `entry`= 37955; +UPDATE `creature_template` SET `minlevel` = 80, `maxlevel` = 80, `AIName` ='', `faction_A`= 14, `faction_H` = 14,`ScriptName`='mob_swarming_shadows' WHERE `entry`= 38163; +UPDATE `gameobject_template` SET `faction` = '0', `ScriptName` = 'go_frostwing_sigil' WHERE `gameobject_template`.`entry` IN (202181); +DELETE FROM `spell_proc_event` WHERE entry IN (70871); +INSERT INTO `spell_proc_event` VALUES +(70871, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- Valithria dreamwalker +UPDATE `creature_template` SET `faction_A` = 35, `faction_H` = 35, `ScriptName`='boss_valithria_dreamwalker' WHERE `entry`= 36789; +UPDATE `creature_template` SET `faction_A` = 35, `faction_H` = 35 WHERE `entry`= 38174; +UPDATE `creature_template` SET `faction_A` = 14, `faction_H` = 14, `ScriptName`='mob_nightmare_portal', `AIName`='' WHERE `entry`= 38429; +UPDATE `creature_template` SET `ScriptName`='mob_mana_void', `AIName`='' WHERE `entry`= 38068; +DELETE FROM `creature` WHERE `guid` = 47738 AND `id` = 38589; + +UPDATE `gameobject_template` SET `faction` = '0',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201375,201373); +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201374); +UPDATE `gameobject` SET `state` = '1' WHERE `id` IN (201374); +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201380,201381,201382,201383); +UPDATE `gameobject_template` SET `faction` = '0' WHERE `entry` IN (201380,201381,201382,201383); +UPDATE `gameobject` SET `state` = '1' WHERE `id` IN (201380,201381,201382,201383); + +-- Sindragosa +UPDATE `creature_template` SET `ScriptName`='boss_sindragosa' WHERE `entry`= 36853; +UPDATE `creature_template` SET `ScriptName`='mob_rimefang', `AIName`='' WHERE `entry`= 37533; +UPDATE `creature_template` SET `ScriptName`='mob_spinestalker', `AIName`='' WHERE `entry`= 37534; + +UPDATE `creature_template` SET `ScriptName`='mob_ice_tomb', `AIName`='' WHERE `entry`= 36980; +UPDATE `creature_template` SET `ScriptName`='mob_frost_bomb', `AIName`='' WHERE `entry`= 37186; +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (201369,201379); +UPDATE `gameobject` SET `state` = '1' WHERE `id` IN (201369,201379); +-- frost bomb target from Lordronn +DELETE FROM `creature_template_addon` WHERE `entry` = 37186; +INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES (37186, '70022 0'); + + +-- Lich King +UPDATE `creature_template` SET `ScriptName`='boss_the_lich_king_icc', `AIName`='' WHERE `entry`= 36597; +UPDATE `creature_template` SET `ScriptName`='boss_tirion_icc', `npcflag`=1, `AIName`='' WHERE `entry`= 38995; +INSERT IGNORE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('71614', '1', '38995'); + +UPDATE `creature_template` SET `ScriptName`='mob_ice_sphere_icc', `AIName`='' WHERE `entry`= 36633; +UPDATE `creature_template` SET `ScriptName`='mob_defiler_icc', `AIName`='' WHERE `entry`= 38757; +UPDATE `creature_template` SET `ScriptName`='mob_strangulate_vehicle', `AIName`='' WHERE `entry`= 36598; +UPDATE `creature_template` SET `ScriptName`='mob_vile_spirit', `AIName`='' WHERE `entry`= 37799; +UPDATE `creature_template` SET `ScriptName`='mob_raging_spirit', `AIName`='' WHERE `entry`= 36701; + +DELETE FROM `npc_text` WHERE `ID` IN (721001,721002); +INSERT INTO `npc_text` (`ID`, `Text0_0`) VALUES +(721001, 'Greetings $N! Are you ready to battle with Lich King?'), +(721002, 'Instance script designed by /dev/rsa especially for\n http://wow.teletoria.ru\n Thanks to:\n Vladimir Mangos\n Insider42\n Wowka321\n Selector\n and many other !\n'); + +DELETE FROM `locales_npc_text` WHERE `entry` IN (721001,721002); +INSERT INTO `locales_npc_text` (`entry`, `Text0_0_loc1`, `Text0_0_loc2`, `Text0_0_loc3`, `Text0_0_loc4`, `Text0_0_loc5`, `Text0_0_loc6`, `Text0_0_loc7`, `Text0_0_loc8`) VALUES +(721001, 'Greetings $N! Are you ready to battle with Lich King?', NULL, NULL, NULL, NULL, NULL, NULL, 'Приветствую, $N! Поможешь мне прихлопнуть главного засранца WOW?'), +(721002, 'Instance script designed by /dev/rsa especially for\n http://wow.teletoria.ru\n Thanks to:\n Vladimir Mangos\n Insider42\n Wowka321\n Selector\n and many other !\n', NULL, NULL, NULL, NULL, NULL, NULL, 'Скрипт инстанса разработан специально для\n http://wow.teletoria.ru\n Благодарности:\n Vladimir Mangos\n Insider42\n Wowka321\n Selector\n и многим другим!\n (c) /dev/rsa 2010 год'); diff --git a/addition/721_icecrown_scriptdev2.sql b/addition/721_icecrown_scriptdev2.sql new file mode 100644 index 000000000..90e2288b4 --- /dev/null +++ b/addition/721_icecrown_scriptdev2.sql @@ -0,0 +1,199 @@ +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1631600 AND -1631000; +INSERT INTO `script_texts` (`entry`,`content_loc8`, `content_default`, `sound`, `type`, `language`, `emote`, `comment`) VALUES + +-- Lord Marrowgar +('-1631000','Это начало и конец, смертные. Никто не может войти в Храм!','This is the beginning AND the end, mortals. None may enter the master\'s sanctum!','16950','6','0','0','marrowgar SAY_INTRO'), +('-1631001','Проклятые несут миру смерть и разрушение!','The Scourge will wash over this world as a swarm of death and destruction!','16941','6','0','0','marrowgar SAY_AGGRO'), +('-1631002','Шторм костей!','BONE STORM!','16946','3','0','0','marrowgar SAY_BONESTORM'), +('-1631003','Проткнут костью!','Bound by bone!','16947','3','0','0','marrowgar SAY_BONESPIKE1'), +('-1631004','Кости вокруг!','Stick Around!','16948','3','0','0','marrowgar SAY_BONESPIKE2'), +('-1631005','Выход - только смерть!','The only escape is death!','16949','6','0','0','marrowgar SAY_BONESPIKE3'), +('-1631006','Больше костей!','More bones for the offering!','16942','6','0','0','marrowgar SAY_KILL1'), +('-1631007','Будьте прокляты!','Languish in damnation!','16943','6','0','0','marrowgar SAY_KILL2'), +('-1631008','ЯРОСТЬ МАСТЕРА ТЕЧЕТ ЧЕРЕЗ МЕНЯ!','THE MASTER\'S RAGE COURSES THROUGH ME!','16945','3','0','0','marrowgar SAY_ENRAGE'), +('-1631009','Я вижу... Только тьму...','I see... only darkness...','16944','6','0','0','marrowgar SAY_DEATH'), + +-- Lady Deathwhisper +('-1631020','Взгляните на ваши мягкие руки! Сухожилия, мясо, кровь! Это слабость! Серьезная ошибка! Шутка создателя со своими творениями! Чем раньше вы поймете что жизнь - это дефект, тем раньше вы сможете преодолеть вашу слабость!','Fix your eyes upon your crude hands! The sinew, the soft meat, the dark blood coursing within! It is a weakness! A crippling flaw! A joke played by the creators upon their own creations! The sooner you come to accept your condition as a defect, the sooner you will find yourselves in a position to transcend it!','16878','6','0','0','deathwhisper SAY_INTRO1'), +('-1631021','Через нашего Мастера все возможно! Его сила не имеет предела, и его воля непреклонна! Те, кто против него будут истреблены! А те, кто служат, которые подчиняются полностью, беспрекословно, с беззаветной преданностью ума и души? Возвышены!','Through our master all things are possible! His power is without limit, and his will unbending! Those who oppose him will be destroyed utterly! And those who serve, who serve wholly, unquestioningly, with utter devotion of mind and soul? Elevated! To heights beyond your ken!','16879','6','0','0','deathwhisper SAY_INTRO2'), +('-1631022','Вы нашли свой путь здесь, потому что вы принадлежите к числу немногих одаренных истинным видением мира, проклятого слепотой! Вы можете видеть сквозь туман, что висит над этим миром, как саван, и понять, где истинная сила лжи!','You have found your way here, because you are among the few gifted with true vision in a world cursed with blindness! You can see through the fog that hangs over this world like a shroud and grasp where true power lies!','16880','6','0','0','deathwhisper SAY_INTRO3'), +('-1631023','Что это за беспорядок?! Вы смеете гадить на этой священной земле? Вот вам и место последнего упокоения!','What is this disturbance?! You dare trespass upon this hallowed ground? This shall be your final resting place.','16868','6','0','0','deathwhisper SAY_AGGRO'), +('-1631024','Однако! Я вижу что пора взять дело в свои руки.','Enough! I see I must take matters into my own hands!','16877','6','0','0','deathwhisper SAY_PHASE2'), +('-1631025','Вы слабы и бессильны против меня!','You are weak, powerless to resist my will!','16876','6','0','0','deathwhisper SAY_DOMINATEMIND'), +('-1631026','Возьмите это благословение и покажите этим злоумышленникам где раки зимуют!','Take this blessing and show these intruders a taste of our master\'s power.','16873','6','0','0','deathwhisper SAY_DARKEMPOWERMENT'), +('-1631027','Мои слуги! Я освобождаю вас от проклятия плоти!','Loyal adherent! I release you from the curse of flesh!','16874','6','0','0','deathwhisper SAY_DARKTRANSFORMATION'), +('-1631028','Встань и предстань в истинном виде!','Arise and exalt in your pure form!','16875','6','0','0','deathwhisper SAY_ANIMATEDEAD'), +('-1631029','Вы еще не осознали бесполезность своих действий?','Do you yet grasp of the futility of your actions?','16869','6','0','0','deathwhisper SAY_KILL1'), +('-1631030','Прими Тьму! Тьма вечна...','Embrace the darkness... Darkness eternal!','16870','6','0','0','deathwhisper SAY_KILL2'), +('-1631031','Это игра продолжается слишком долго!','This charade has gone on long enough.','16872','3','0','0','deathwhisper SAY_BERSERK'), +('-1631032','Все - части плана Мастера! Ваш конец неизбежен...','All part of the masters plan! Your end is... inevitable!','16871','6','0','0','deathwhisper SAY_DEATH'), + +-- Saurfang +('-1631100','Во имя Короля-Лича!','BY THE MIGHT OF THE LICH KING!','16694','6','0','0','saurfang SAY_AGGRO'), +('-1631101','Земля обагрится вашей кровью!','The ground runs red with your blood!','16699','6','0','0','saurfang SAY_FALLENCHAMPION'), +('-1631102','Веселитесь, слуги мои!','Feast, my minions!','16700','3','0','0','saurfang SAY_BLOODBEASTS'), +('-1631103','Ты никто!','You are nothing!','16695','6','0','0','saurfang SAY_KILL1'), +('-1631104','Ваши души не найдут здесь избавления!','Your soul will find no redemption here!','16696','6','0','0','saurfang SAY_KILL2'), +('-1631105','Я вижу приближение смерти!','I have become... death!','16698','3','0','0','saurfang SAY_BERSERK'), +('-1631106','Я... Освободился...','I... Am... Released.','16697','6','0','0','saurfang SAY_DEATH'), +('-1631107','Все павшие воины орды, все дохлые псы альянса - все пополнят армию Короля-Лича! Даже сейчас валькиры воскрешают ваших покойников, чтобы они стали частью Плети!','For every Horde soldier that you killed, for every Alliance dog that fell, the Lich King\'s armies grew. Even now the Val\'kyr work to raise your fallen... As Scourge.','16701','6','0','0','saurfang SAY_INTRO'), +('-1631108','Сейчас все будет еще хуже. Идите сюда, я покажу вам, какой силой меня наделил Король-Лич!','Things are about to get much worse. Come, taste the power that the Lich King has bestowed upon me!','16702','6','0','0','saurfang SAY_BERSERK'), +('-1631109','Ха-ха-ха. Дворфы!','Hahahaha! Dwarves.','16703','6','0','0','saurfang SAY'), + +-- Festergut +('-1631201','Отличные новости народ! Я починил трубы для подачи ядовитой смеси!','Good news, everyone! I\'ve fixed the poison slime pipes!','17123','6','0','0','Putricide Valve01'), +('-1631202','Тухлопуз! Ты всегда был моим любимчиком, как и Гниломорд... Молодец, что оставил столько газа. Я его даже чувствую.','Oh, Festergut. You were always my favorite. Next to Rotface. The good news is you left behind so much gas, I can practically taste it!','17124','6','0','0','Putricide Festergut Dead'), +('-1631203','Повеселимся!','Fun time!','16901','6','0','0','Festergut Aggro'), +('-1631204','Папочка! У меня получилось!','Daddy, I did it!','16902','6','0','0','Festergut Slay 01'), +('-1631205','Мертвец! Мертвец! Мертвец!','Dead, dead, dead!','16903','6','0','0','Festergut Slay 02'), +('-1631206','А-а-а-а-а...','Da ... Ddy...','16904','6','0','0','Festergut Death'), +('-1631207','Веселью конец!','Fun time over!','16905','6','0','0','Festergut Berserk'), +('-1631208','Что-то мне нехорошо...','Gyah! Uhhh, I not feel so good...','16906','6','0','0','Festergut Explunge Blight'), +('-1631209','Нет! Вы убили Вонючку! Сейчас получите!','NOOOO! You kill Stinky! You pay!','16907','6','0','0','Festergut Stinky Death '), +('-1631210','Их-ха!','...','16908','6','0','0','Festergut say '), +('-1631211','Ы-ы-ы!','...','16909','6','0','0','Festergut say '), +('-1631212','(Непереводимо)','...','16910','6','0','0','Festergut say '), +('-1631213','Пук.','...','16911','6','0','0','Festergut brrr '), + +-- Rotface +('-1631220','Отличные новости народ! Слизь снова потекла!','Great news, everyone! The slime is flowing again!','17126','6','0','0','Putricide Slime Flow'), +('-1631221','Й-й-йя-хахаха!','WEEEEEE!','16986','6','0','0','Rotface Aggro'), +('-1631222','Я ЭТО заломал!','I brokes-ded it...','16987','6','0','0','Rotface Slay 01'), +('-1631223','Папочка сделает новые игрушки из тебя!','Daddy make toys out of you!','16988','6','0','0','Rotface Slay 02'), +('-1631224','Папочка, не огорчайся...','Bad news daddy.','16989','6','0','0','Rotface Death'), +('-1631225','Тихий час!','Sleepy Time!','16990','6','0','0','Rotface Berserk'), +('-1631226','Липучка-вонючка!','Icky sticky.','16991','6','0','0','Rotface Infection'), +('-1631227','Я сделал очень злую каку! Сейчас взорвется!','I think I made an angry poo-poo. It gonna blow!','16992','6','0','0','Rotface Unstable Ooze'), +('-1631228','Что? Прелесть? Не-е-е-т!','What? Precious? Noooooooooo!!!','16993','6','0','0','Rotface Precious played when precious dies'), +('-1631229','Й-а-а-а!','...','16994','6','0','0','Rotface say'), +('-1631230','Ах!','...','16995','6','0','0','Rotface say'), +('-1631231','А-а-у!','...','16996','6','0','0','Rotface say'), + +-- Professor Putricide +('-1631240','Отличные новости народ! Я усовершенствовал штамм чумы, которая уничтожит весь Азерот!','Good news, everyone! I think I perfected a plague that will destroy all life on Azeroth!','17114','6','0','0','Putricide Aggro'), +('-1631241','М-м-м. Интересно.','Hmm... Interesting...','17115','6','0','0','Putricide Slay 01'), +('-1631242','О, как неожиданно!','That was unexpected!','17116','6','0','0','Putricide Slay 02'), +('-1631243','Плохие новости, народ... Похоже, у меня ничего не выйдет.','Bad news, everyone! I don\'t think I\'m going to make it.','17117','6','0','0','Putricide Death'), +('-1631244','Прекрасные новости, народ!','Great news, everyone!','17118','6','0','0','Putricide Berserk'), +('-1631245','Это обычное облако газа. Но будьте осторожны, не такое уж оно и обычное...','Just an ordinary gas cloud. But watch out, because that\'s no ordinary gas cloud!','17119','6','0','0','Putricide Gas Explosion'), +('-1631246','Что-то я ничего не чувствую. Что? Это еще откуда?','Hmm. I don\'t feel a thing. Whaa...? Where\'d those come from?','17120','6','0','0','Putricide Transform 01'), +('-1631247','На вкус как вишенка. Ой, извините...','Tastes like... Cherry! Oh! Excuse me!','17121','6','0','0','Putricide Transform 02'), +('-1631248','Два слизнюка в одной комнате? Может получиться что-то любопытное...','Two oozes, one room! So many delightful possibilities...','17122','6','0','0','Putricide Summon Ooze'), +('-1631249','Вы слишком грязные чтобы тут расхаживать! Надо сперва соскрести эту мерзкую плоть.','You can\'t come in here all dirty like that! You need that nasty flesh scrubbed off first!','17125','6','0','0','Putricide Airlock01 Before fight'), + +-- Blood Prince Council +('-1631301','Глупые смертные! Думали, что одолели нас? Санлейн, непобедимые воины Короля-Лича! Теперь наши силы едины!','Foolish mortals. You thought us defeated so easily? The San\'layn are the Lich King\'s immortal soldiers! Now you shall face their might combined!','16795','6','0','0','Lanathel Intro Princes'), +('-1631302','Кушать подано!','Dinner... is served.','16681','6','0','0','Valanar Slay 01'), +('-1631303','Теперь вы видите, насколько мы сильны?','Do you see NOW the power of the Darkfallen?','16682','6','0','0','Valanar Slay 02'), +('-1631304','Охохо...','...why...?','16683','6','0','0','Valanar Death'), +('-1631305','Хорош тянуть время перед Санлейн!','BOW DOWN BEFORE THE SAN\'LAYN!','16684','6','0','0','Valanar Berserk'), +('-1631306','Наксанар был досадным недоразумением! Силы сферы позволят Валанару свершить отмщение!','Naxxanar was merely a setback! With the power of the orb, Valanar will have his vengeance!','16685','6','0','0','Valanar Empower'), +('-1631307','Моя чаша полна','My cup runneth over.','16686','6','0','0','Valanar Special'), +('-1631308','Йих!','...','16687','6','0','0','Princes say'), +('-1631309','Э-эх!','...','16688','6','0','0','Princes say'), +('-1631310','До-хо!','...','16689','6','0','0','Princes say'), +('-1631311','Восстаньте, братья, и уничтожьте наших врагов!','','16796','6','0','0','Lanathel resurrect Princes'), + +-- Blood Queen Lana'thel +('-1631321','Это было неразумное решение!','You have made an... unwise... decision.','16782','6','0','0','Lanathel Aggro'), +('-1631322','Я только попробую на вкус...','Just a taste...','16783','6','0','0','Lanathel Bite 01'), +('-1631323','Я голодна!','Know my hunger!','16784','6','0','0','Lanathel Bite 02'), +('-1631324','Смерть вас не спасет!','Death is no escape!','16785','6','0','0','Lanathel Add'), +('-1631325','Страдайте же!','SUFFER!','16786','6','0','0','Lanathel Special 01'), +('-1631326','Как вам такое?','Can you handle this?','16787','6','0','0','Lanathel Special 02'), +('-1631327','Начинаем представление!','Here it comes.','16788','6','0','0','Lanathel Special 03'), +('-1631328','Не повезло...','How... Unfortunate...','16789','6','0','0','Lanathel Reset'), +('-1631329','Нет. Моя прелесть, приятного аппетита!','Yes... feed my precious one! You\'re mine now!','16790','6','0','0','Lanathel Mind Control'), +('-1631330','Вот как... У тебя не получилось?','Really...? Is that all you\'ve got?','16791','6','0','0','Lanathel Slay 01'), +('-1631331','Какая жалость...','Such a pity!','16792','6','0','0','Lanathel Slay 02'), +('-1631332','Сейчас все кончится!','THIS! ENDS! NOW!','16793','6','0','0','Lanathel Berserk'), +('-1631333','Но... Мы ведь так хорошо ладили...','But... we were getting along... so well...','16794','6','0','0','Lanathel Death'), +('-1631334','Восстаньте братья! И уничтожьте наших врагов!','Rise up brothers! And destroy our enemies!','16796','6','0','0','Lanathel Empower'), +('-1631335','Ха-х!','Ha!','16797','6','0','0','Lanathel say'), +('-1631338','Ах-ха...','Oo...','16798','6','0','0','Lanathel say'), +('-1631339','Ых...','Oh...','16799','6','0','0','Lanathel say'), + +-- Valithria Dreamwalker +('-1631401','Герои! Вы должны мне помочь! Мои силы на исходе... Залечите мои раны...','Heroes, lend me your aid! I... I cannot hold them off much longer! You must heal my wounds!','17064','6','0','0','Valithria Aggro'), +('-1631402','Одержимые не знают отдыха...','No rest for the wicked...','17065','6','0','0','Valithria Slay Bad Hostile NPC'), +('-1631403','Прискобная потеря.','A tragic loss...','17066','6','0','0','Valithria Slay Good - Player'), +('-1631404','Неудачники!','FAILURES!','17067','6','0','0','Valithria Berserk'), +('-1631405','Я открыла портал в изумрудный сон. Там вы найдете спасение, герои!','I have opened a portal into the Dream. Your salvation lies within, heroes.','17068','6','0','0','Valithria Dream World Open'), +('-1631406','Я долго не продержусь!','I will not last much longer!','17069','6','0','0','Valithria Health Low'), +('-1631407','Силы возвращаются ко мне! Герои, еще немного!','My strength is returning! Press on, heroes!','17070','6','0','0','Valithria Health High'), +('-1631408','Я излечилась! Изера, даруй мне силу покончить с этими нечестивыми тварями!','I am renewed! Ysera grants me the favor to lay these foul creatures to rest!','17071','6','0','0','Valithria Win'), +('-1631409','Простите меня, я не могу остано... ВСЕ ВО ВЛАСТИ КОШМАРА!','Forgive me for what I do! I... cannot... stop... ONLY NIGHTMARES REMAIN!','17072','6','0','0','Valithria Lose'), + +-- Sindragosa +('-1631420','Глупцы! Зачем вы сюда явились? Ледяные ветра Нордскола унесут ваши души!','You are fools who have come to this place! The icy winds of Northrend will consume your souls!','17007','6','0','0','Sindragosa Aggro'), +('-1631421','Погибни!','Perish!','17008','6','0','0','Sindragosa Slay 01'), +('-1631422','Удел смертных!','A flaw of mortality...','17009','6','0','0','Sindragosa Slay 02'), +('-1631423','Наконец-то! Свободна!','Free...at last...','17010','6','0','0','Sindragosa Death'), +('-1631424','Хватит! Эти игры меня утомляют!','Enough! I tire of these games!','17011','6','0','0','Sindragosa Berserk'), +('-1631425','Здесь ваше вторжение и окончится! Никто не уцелеет!','Your incursion ends here! None shall survive!','17012','6','0','0','Sindragosa Take Off - fly'), +('-1631426','Вы чувствуете, как ледяная ладонь смерти сжимает сердце?','Can you feel the cold hand of death upon your heart?','17013','6','0','0','Sindragosa Freeze'), +('-1631427','Трепещите, смертные! Ибо ваша жалкая магия теперь бессильна!','Suffer, mortals, as your pathetic magic betrays you!','17014','6','0','0','Sindragosa Arcane'), +('-1631428','А-а-а! Жжот! Что это за колдовство?','Suffer, mortals, as your pathetic magic betrays you!','17015','6','0','0','Sindragosa Special'), +('-1631429','А теперь почувствуйте всю мощь Господина и погрузитесь в отчаяние!','Now feel my master\'s limitless power and despair!','17016','6','0','0','Sindragosa Low HP'), + +-- Lich king +('-1631501','Неужели прибыли, наконец, хваленые силы света? Мне бросить Ледяную скорбь и сдаться на твою милость, Фордринг?','So...the Light\'s vaunted justice has finally arrived. Shall I lay down Frostmourne and throw myself at your mercy, Fordring?','17349','6','0','0','Lich King SAY_INTRO1'), +('-1631503','Ты пройдешь через эти мучения сам.','You will learn of that first hand. When my work is complete, you will beg for mercy -- and I will deny you. Your anguished cries will be testament to my unbridled power.','17350','6','0','0','Lich King SAY_INTRO3'), +('-1631505','Я оставлю тебя в живых, чтобы ты увидел финал! Не могу допустить чтобы величайший служитель света пропустил рождение МОЕГО мира!','I\'ll keep you alive to witness the end, Fordring. I would not want the Light\'s greatest champion to miss seeing this wretched world remade in my image.','17351','6','0','0','Lich King SAY_AGGRO'), +('-1631506','Ну же, герои! В вашей ярости - МОЯ сила!','Come then champions, feed me your rage!','17352','6','0','0','Lich King SAY'), +('-1631507','Сомнений нет - вы сильнейшие герои Азерота! Вы преодолели все препятствия, которые я воздвиг перед вами! Сильнейшие из моих слуг пали под вашим натиском, сгорели в пламени вашей ярости!','No question remains unanswered. No doubts linger. You are Azeroth\'s greatest champions! You overcame every challenge I laid before you. My mightiest servants have fallen before your relentless onslaught, your unbridled fury..','17353','6','0','0','Lich King SAY'), +('-1631508','Что движет вами? Праведность? Не знаю...','Is it truly righteousness that drives you? I wonder.','17354','6','0','0','Lich King SAY'), +('-1631509','Ты отлично их обучил, Фордринг! Ты привел сюда лучших воинов, которых знал мир! И отдал их в мои руки. Как я и рассчитывал.','You trained them well, Fordring. You delivered the greatest fighting force this world has ever known... right into my hands -- exactly as I intended. You shall be rewarded for your unwitting sacrifice.','17355','6','0','0','Lich King SAY'), +('-1631510','Смотри как я буду воскрешать их и превращать в воинов Плети! Они повергнут этот мир в пучину хаоса. Азерот падет от их рук. И ты станешь первой жертвой. ','Watch now as I raise them from the dead to become masters of the Scourge. They will shroud this world in chaos and destruction. Azeroth\'s fall will come at their hands -- and you will be the first to die.','17356','6','0','0','Lich King SAY'), +('-1631511','Мне по душе эта ирония!','I delight in the irony.','17357','6','0','0','Lich King SAY'), +('-1631512','Невозможно!','Impossible...','17358','6','0','0','Lich King SAY'), +('-1631513','Да! Вы меня и правда ранили. Я слишком долго с вами играл. Испытайте на себе возмездие Смерти!','You gnats actually hurt me! Perhaps I\'ve toyed with you long enough, now taste the vengeance of the grave!','17359','6','0','0','Lich King SAY'), +('-1631514','А-а-х!','...','17360','6','0','0','Lich King SAY'), +('-1631515','И вот я стою как лев пред агнцами. И не дрожат они.','Now I stand, the lion before the lambs... and they do not fear.','17361','6','0','0','Lich King SAY'), +('-1631516','Им неведом страх!','They cannot fear.','17362','6','0','0','Lich King SAY'), +('-1631517','Надежда тает!','Hope wanes!','17363','6','0','0','Lich King SAY'), +('-1631518','Пришел конец!','The end has come!','17364','6','0','0','Lich King SAY'), +('-1631519','Встречайте трагический финал!','Face now your tragic end!','17365','6','0','0','Lich King SAY_KILL'), +('-1631520','Ледяная скорбь жаждет крови!','Frostmourne hungers...','17366','6','0','0','Lich King SAY'), +('-1631521','Ледяная скорбь, повинуйся мне!','Argh... Frostmourne, obey me!','17367','6','0','0','Lich King SAY'), +('-1631522','Ледяная скорбь поглотит душу вашего товарища!','Frostmourne feeds on the soul of your fallen ally!','17368','6','0','0','Lich King SAY_KILL'), +('-1631523','Я проморожу вас насквозь и вы разлетитесь на ледяные осколки!','I will freeze you from within until all that remains is an icy husk!','17369','6','0','0','Lich King SAY'), +('-1631524','Смотрите, как мир рушится вокруг вас!','Watch as the world around you collapses!','17370','6','0','0','Lich King SAY_WIN'), +('-1631525','Конец света!','Apocalypse!','17371','6','0','0','Lich King SAY'), +('-1631526','Склонись перед своим господином и повелителем!','Bow down before your lord and master!','17372','6','0','0','Lich King SAY'), +('-1631527','Валькирия! Твой господин зовет!','Val\'kyr, your master calls!','17373','6','0','0','Lich King SAY_SUMMON'), +('-1631528','...','...','17374','6','0','0','Lich King SAY_DEATH'), +('-1631531','Оскверняю!','Defile!','0','3','0','0','Lich King SAY'), + +-- Tirion +('-1631552','Мы даруем тебе быструю смерть, Артас! Более быструю чем ты заслуживаешь за то что замучил и погубил десятки тысяч жизней!','We will grant you a swift death, Arthas. More than can be said for the thousands you\'ve tortured and slain.','17390','6','0','0','Tirion SAY_INTRO2'), +('-1631554','Да будет так! Герои, в атаку','So be it. Champions, attack!','17391','6','0','0','Tirion SAY_INTRO4'), +('-1631555','Свет! Даруй мне последнее благословение! Дай мне разбить эти оковы!','LIGHT, GRANT ME ONE FINAL BLESSING. GIVE ME THE STRENGTH... TO SHATTER THESE BONDS!','17392','6','0','0','Tirion SAY'), +('-1631556','Хватит, Артас! Твоя ненависть не заберет больше ни одной жизни!','No more, Arthas! No more lives will be consumed by your hatred!','17393','6','0','0','Tirion SAY'), + +-- Menethil +('-1631557','Вы пришли чтобы вершить суд над Артасом? Чтобы уничтожить короля-лича?','You have come to bring Arthas to justice? To see the Lich King destroyed?','17394','6','0','0','Terenas Menethil II SAY'), +('-1631558','Вы не должны оказаться во власти Ледяной скорби. Иначе, как и я, будете навеки порабощены этим проклятым клинком.','First, you must escape Frostmourne\'s hold, or be damned as I am; trapped within this cursed blade for all eternity.','17395','6','0','0','Terenas Menethil II SAY'), +('-1631559','Помогите мне уничтожить эти истерзанные души. Вместе мы вытянем силу из ледяной скорби и ослабим короля-лича.','Aid me in destroying these tortured souls! Together we will loosen Frostmourne\'s hold and weaken the Lich King from within!','17396','6','0','0','Terenas Menethil II SAY'), +('-1631560','Наконец я свободен. Все кончено, сын мой. Настал час расплаты.','Free at last! It is over, my son. This is the moment of reckoning.','17397','6','0','0','Terenas Menethil II SAY'), +('-1631561','Поднимитесь, воины света!','Rise up, champions of the Light!','17398','6','0','0',' SAY'), + +-- Adds +('-1631590','Р-р-р-рота, подъем!','','0','6','0','0','custom message'), +('-1631591','Хилы, не спать!','','0','6','0','0','custom message'), +('-1631592','ДД поднажали!','','0','6','0','0','custom message'), +('-1631593','Лидер, гони лентяев из рейда! А то еще час возиться будете!','','0','6','0','0','custom message'), +('-1631594','Ну вот вы и прикончили Артаса. Теперь будем ждать Катаклизм.','','0','6','0','0','custom message'); + +-- Gossips +DELETE FROM `gossip_texts` WHERE `entry` BETWEEN -3631610 AND -3631600; +INSERT INTO `gossip_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `comment`) VALUES +('-3631600', "Light\'s Hammer", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Молот света", "IceCrown citadel teleporter text 1"), +('-3631601', "Oratory of the Damned", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Молельня проклятых", "IceCrown citadel teleporter text 2"), +('-3631602', "Rampart of Skulls", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Черепной вал", "IceCrown citadel teleporter text 3"), +('-3631603', "Deathbringer\'s Rise", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Подъем Смертоносного", "IceCrown citadel teleporter text 4"), +('-3631604', "Icecrown Citadel", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Цитадель Ледяной Короны", "IceCrown citadel teleporter text 5"), +('-3631605', "The Sanctum of Blood", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Святилище крови", "IceCrown citadel teleporter text 6"), +('-3631606', "Frost Queen\'s Lair", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Логово Королевы льда", "IceCrown citadel teleporter text 7"), +('-3631607', "Frozen Throne", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Ледяной трон", "IceCrown citadel teleporter text 8"), +('-3631608', "We are ready, Tirion!", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Всегда готовы, дедуля!", "IceCrown citadel Tirion gossip"); diff --git a/addition/721_icecrown_spelltable_scriptdev2.sql b/addition/721_icecrown_spelltable_scriptdev2.sql new file mode 100644 index 000000000..d90bd6efa --- /dev/null +++ b/addition/721_icecrown_spelltable_scriptdev2.sql @@ -0,0 +1,426 @@ +-- Icecrown citadel spelltable + +-- Lord Marrowgar +DELETE FROM `boss_spell_table` WHERE `entry` = 36612; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36612, 71021, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(36612, 69138, 0, 0, 0, 6000, 0, 0, 0, 12000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36612, 71580, 0, 0, 0, 6000, 0, 0, 0, 12000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36612, 69146, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36612, 69057, 0, 0, 0, 17000, 0, 0, 0, 27000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(36612, 69076, 0, 0, 0, 60000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36612, 69075, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 5, 0, 0, 12, 0, 1), +(36612, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36612, 38711, 20000, 40000, 1, 1, 2, 2, 1, 5, 0, 9), +(36612, 36672, 45000, 45000, 1, 1, 2, 2, 75, 100, 0, 9); +-- Cold flame +DELETE FROM `boss_spell_table` WHERE `entry` = 36672; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36672, 69145, 0, 0, 0, 15000, 0, 0, 0, 15000, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 1, 0, 0), +(36672, 69147, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 15000, 15000, 30000, 30000, 0, 0, 0, 1, 0, 0), +(36672, 69146, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36672, 36672, 30000, 30000, 1, 1, 1, 1, 0, 0, 0, 11); +-- Bone spike +DELETE FROM `boss_spell_table` WHERE `entry` = 38711; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(38711, 46598, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 18, 0, 0), +(38711, 69065, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 6, 0, 0); + +-- Lady Deathwhisper +DELETE FROM `boss_spell_table` WHERE `entry` = 36855; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36855, 70842, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 1, 0, 0), +(36855, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 1, 0, 0), +(36855, 71254, 72008, 72008, 72504, 5000, 0, 0, 0, 8000, 0, 0, 0, 4, 0, 0), +(36855, 71420, 72501, 72007, 72502, 15000, 0, 0, 0, 25000, 0, 0, 0, 4, 0, 0), +(36855, 71001, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 4, 0, 0), +(36855, 71204, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 3, 0, 0), +(36855, 70901, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 6, 0, 0), +(36855, 71289, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 4, 0, 0), +(36855, 71494, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 1, 0, 0); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36855, 37890, 45000, 75000, 1, 1, 2, 2, 75, 100, 0, 11), +(36855, 37949, 45000, 75000, 1, 1, 2, 2, 75, 100, 0, 11), +(36855, 38010, 45000, 45000, 1, 1, 2, 2, 75, 100, 0, 9), +(36855, 38222, 8000, 15000, 1, 1, 1, 1, 75, 100, 0, 9), +(36855, 38009, 45000, 45000, 1, 1, 2, 2, 75, 100, 0, 9); +-- Vengeful shade +DELETE FROM `boss_spell_table` WHERE `entry` = 38222; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(38222, 71494, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 1, 0, 0), +(38222, 71544, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 3, 0, 0); +-- Adherent +DELETE FROM `boss_spell_table` WHERE `entry` = 37949; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37949, 71129, 0, 0, 0, 15000, 0, 0, 0, 20000, 0, 0, 0, 3, 0, 0), +(37949, 70594, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 4, 0, 0), +(37949, 71254, 0, 0, 0, 5000, 0, 0, 0, 15000, 0, 0, 0, 4, 0, 0), +(37949, 70906, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 4, 0, 0), +(37949, 70903, 0, 0, 0, 1000, 0, 0, 0, 2000, 0, 0, 0, 1, 0, 0), +(37949, 71237, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 3, 0, 0), +(37949, 70768, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 4, 0, 0), +(37949, 41236, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 1, 0, 0), +(37949, 71234, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 4, 0, 0); +-- Fanatic +DELETE FROM `boss_spell_table` WHERE `entry` = 37890; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37890, 70659, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 3, 0, 0), +(37890, 70670, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 3, 0, 0), +(37890, 70674, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 1, 0, 0); + +-- Gunship battle +-- Frost wyrm +DELETE FROM `boss_spell_table` WHERE `entry` = 37230; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37230, 70116, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 4, 0, 0), +(37230, 70362, 0, 0, 0, 20000, 0, 0, 0, 25000, 0, 0, 0, 4, 0, 0), +(37230, 70361, 0, 0, 0, 3000, 0, 0, 0, 5000, 0, 0, 0, 3, 0, 0), +(37230, 47008, 0, 0, 0, 180000, 0, 0, 0, 180000, 0, 0, 0, 1, 0, 0); + +-- Rotted frost giant +DELETE FROM `boss_spell_table` WHERE `entry` IN (38490, 38494); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(38490, 64652, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 4, 0, 0), +(38490, 72865, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 4, 0, 0), +(38490, 47008, 0, 0, 0, 300000, 0, 0, 0, 300000, 0, 0, 0, 1, 0, 0); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(38494, 64652, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 4, 0, 0), +(38494, 72865, 0, 0, 0, 25000, 0, 0, 0, 40000, 0, 0, 0, 4, 0, 0), +(38494, 47008, 0, 0, 0, 300000, 0, 0, 0, 300000, 0, 0, 0, 1, 0, 0); + +-- Deathbringer Saurfang +DELETE FROM `boss_spell_table` WHERE `entry` = 37813; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`,`data1`, `data2`, `data3`, `data4`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37813, 72178, 0, 0, 0, 20000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 72371, 0, 0, 0, 3000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 72256, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 72293, 0, 0, 0, 35000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(37813, 72737, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37813, 72385, 0, 0, 0, 20000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37813, 72380, 0, 0, 0, 25000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37813, 72408, 0, 0, 0, 20000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37813, 72172, 0, 0, 0, 45000, 0, 0, 0, 45000, 0, 0, 0, 2, 5, 2, 5, 1, 0, 0), +(37813, 72173, 0, 0, 0, 45000, 0, 0, 0, 45000, 0, 0, 0, 2, 5, 2, 5, 1, 0, 0), +(37813, 72356, 0, 0, 0, 45000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 72357, 0, 0, 0, 45000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 72358, 0, 0, 0, 45000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 72769, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37813, 72723, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 72242, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37813, 47008, 0, 0, 0, 480000, 0, 0, 0, 480000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(37813, 38508, 45000, 45000, 1, 1, 2, 2, 15, 25, 0, 9); +-- Blood beast +DELETE FROM `boss_spell_table` WHERE `entry` = 38508; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(38508, 72176, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 1, 0, 0), +(38508, 72723, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 1, 0, 0), +(38508, 72769, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 1, 0, 0), +(38508, 21150, 0, 0, 0, 15000, 0, 0, 0, 27000, 0, 0, 0, 1, 0, 0); + + +-- Festergut +DELETE FROM `boss_spell_table` WHERE `entry` = 36626; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +( 36626, 69157, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69162, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69164, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69126, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +( 36626, 69152, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +( 36626, 69154, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +( 36626, 69165, 0, 0, 0, 10000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69195, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69278, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69279, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69290, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 69291, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 6, 0, 1), +( 36626, 72219, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +( 36626, 72227, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 6, 0, 1), +( 36626, 72272, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +( 36626, 69244, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +( 36626, 69248, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +( 36626, 72287, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +( 36626, 71379, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 6, 0, 1), +( 36626, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36626, 38548, 12000, 12000, 1, 1, 1, 1, 10, 20, 0, 11); + +-- Rotface +DELETE FROM `boss_spell_table` WHERE `entry` = 36627; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`,`data1`, `data2`, `data3`, `data4`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36627, 69508, 0, 0, 0, 15000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36627, 69674, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(36627, 70003, 0, 0, 0, 15000, 0, 0, 0, 15000, 0, 0, 0, 1, 2, 1, 3, 6, 0, 0), +(36627, 69788, 0, 0, 0, 20000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36627, 69783, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(36627, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36627, 69789, 0, 0, 0, 20000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36627, 36897, 12000, 12000, 1, 1, 1, 1, 1, 5, 0, 9), +(36627, 37986, 15000, 15000, 1, 1, 1, 1, 10, 20, 0, 11), +(36627, 37013, 15000, 15000, 1, 1, 1, 1, 0, 0, 0, 11); +-- Small ooze +DELETE FROM `boss_spell_table` WHERE `entry` = 36897; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36897,69774, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 4, 0, 0), +(36897,69750, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 1, 0, 0), +(36897,69644, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 6, 0, 0), +(36897,69889, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 6, 0, 0); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36897, 36899, 12000, 12000, 1, 1, 1, 1, 1, 5, 0, 9); +-- Big ooze +DELETE FROM `boss_spell_table` WHERE `entry` = 36899; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36899,69774, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 4, 0, 0), +(36899,69839, 0, 0, 0, 6000, 0, 0, 0, 6000, 0, 0, 0, 1, 0, 0), +(36899,69760, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 1, 0, 0), +(36899,69644, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 1, 0, 0), +(36899,69558, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 1, 0, 0), +(36899,69889, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 6, 0, 0); +-- Ooze explode stalker +DELETE FROM `boss_spell_table` WHERE `entry` = 38107; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(38107,69840, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 1, 0, 0); + +-- Professor Putricide +DELETE FROM `boss_spell_table` WHERE `entry` = 36678; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36678,70351, 0, 0, 0, 40000, 0, 0, 0, 60000, 0, 0, 0, 0, 1, 0, 0), +(36678,71617, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 3, 0, 0), +(36678,71615, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 100, 12, 0, 0), +(36678,71618, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 100, 12, 0, 0), +(36678,71621, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 3, 0, 0), +(36678,71278, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 3, 0, 0), +(36678,71279, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 3, 0, 0), +(36678,71893, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 3, 0, 0), +(36678,71273, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 1, 0, 0), +(36678,71275, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 1, 0, 0), +(36678,71276, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 1, 0, 0), +(36678,71702, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 1, 0, 0), +(36678,71703, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 1, 0, 0), +(36678,71603, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 3, 0, 0), +(36678,70311, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 1, 0, 0), +(36678,47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 1, 0, 0), +(36678,71518, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 6, 0, 1), +(36678,72672, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 3, 0, 0); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36678,70342, 0, 0, 0, 30000, 0, 0, 0, 60000, 0, 0, 0, 10, 40, 0, 15, 0, 0), +(36678,70852, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 10, 30, 0, 15, 0, 0); + +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36678, 37562, 20000, 40000, 1, 1, 1, 1, 5, 10, 0, 9), +(36678, 38159, 8000, 20000, 1, 1, 1, 1, 20, 40, 0, 9), +(36678, 37690, 40000, 60000, 1, 1, 1, 1, 10, 40, 0, 9), +(36678, 37697, 20000, 40000, 1, 1, 1, 1, 5, 10, 0, 9); +-- Gas cloud +DELETE FROM `boss_spell_table` WHERE `entry` = 37562; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37562,70672, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 0), +(37562,70215, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 0), +(37562,71770, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 1), +(37562,70812, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 1), +(37562,70701, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 0); +-- Volatile ooze +DELETE FROM `boss_spell_table` WHERE `entry` = 37697; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37697,70492, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 1, 0, 0), +(37697,70530, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 1), +(37697,71770, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 1), +(37697,70447, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 6, 0, 0); +-- Mutated abomination (pet?) +DELETE FROM `boss_spell_table` WHERE `entry` = 37672; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37672,70311, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 1, 0, 0), +(37672,72527, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 3, 0, 0), +(37672,72539, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 3, 0, 0), +(37672,70542, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 3, 0, 0), +(37672,70405, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 1, 0, 0); + +-- Taldaram +DELETE FROM `boss_spell_table` WHERE `entry` = 37973; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37973, 71807, 0, 0, 0, 50000, 0, 0, 0, 10000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(37973, 71718, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37973, 71719, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 15, 0, 0), +(37973, 72040, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37973, 72041, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 15, 0, 0), +(37973, 70952, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37973, 70981, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37973, 70982, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37973, 71598, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37973, 70983, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37973, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Valanar +DELETE FROM `boss_spell_table` WHERE `entry` = 37970; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37970, 72053, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37970, 71598, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37970, 38459, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 11, 0, 0), +(37970, 72037, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37970, 38422, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 11, 0, 0), +(37970, 71945, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(37970, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37970, 70983, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37970, 70981, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37970, 70982, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37970, 70952, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37970, 72039, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0); + +-- Keleseth +DELETE FROM `boss_spell_table` WHERE `entry` = 37972; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37972, 71405, 0, 0, 0, 5000, 0, 0, 0, 8000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(37972, 71598, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37972, 71815, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(37972, 71943, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37972, 71822, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37972, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37972, 70952, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37972, 70981, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37972, 70982, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37972, 70983, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Lanathel +DELETE FROM `boss_spell_table` WHERE `entry` = 37955; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37955, 72981, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37955, 71623, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(37955, 70451, 70451, 71510, 71510, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(37955, 70445, 70445, 70821, 70821, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(37955, 71726, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37955, 70867, 71473, 71532, 71533, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37955, 70871, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37955, 70923, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37955, 71340, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37955, 71264, 0, 0, 0, 20000, 0, 0, 0, 35000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37955, 71446, 0, 0, 0, 7000, 0, 0, 0, 12000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37955, 71772, 0, 0, 0, 40000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37955, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37955, 72934, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(37955, 71952, 0, 0, 0, 5000, 0, 0, 0, 8000, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Valithria +DELETE FROM `boss_spell_table` WHERE `entry` = 36789; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36789, 71977, 0, 0, 0, 30000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36789, 71987, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 1, 0), +(36789, 72481, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36789, 70873, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36789, 71189, 0, 0, 0, 3000, 0, 0, 0, 3000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36789, 72724, 0, 0, 0, 3000, 0, 0, 0, 3000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36789, 70904, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 1, 0, 1), +(36789, 71196, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36789, 70702, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 16, 0, 1); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36789, 38429, 30000, 40000, 1, 1, 1, 1, 5, 70, 0, 9), +(36789, 37868, 30000, 45000, 1, 1, 1, 1, 1, 3, 0, 11), +(36789, 37863, 30000, 45000, 1, 1, 1, 1, 1, 3, 0, 11), +(36789, 36791, 30000, 45000, 1, 1, 1, 1, 1, 3, 0, 11), +(36789, 37934, 30000, 45000, 1, 1, 1, 1, 1, 3, 0, 11), +(36789, 37886, 30000, 45000, 1, 1, 1, 1, 1, 3, 0, 11); +-- Nightmare portal +DELETE FROM `boss_spell_table` WHERE `entry` = 38429; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(38429, 70873, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 1, 0, 1); + +-- Sindragosa +DELETE FROM `boss_spell_table` WHERE `entry` = 36853; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36853, 70084, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36853, 57764, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 1, 0), +(36853, 19983, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(36853, 71077, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36853, 69649, 0, 0, 0, 20000, 0, 0, 0, 35000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36853, 70107, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36853, 69762, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36853, 69766, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(36853, 69846, 0, 0, 0, 15000, 0, 0, 0, 20000, 0, 0, 0, 50.0, 100.0, 0, 15, 0, 0), +(36853, 70117, 0, 0, 0, 30000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36853, 70123, 0, 0, 0, 20000, 0, 0, 0, 35000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36853, 70126, 0, 0, 0, 90000, 0, 0, 0, 90000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36853, 70157, 0, 0, 0, 6000, 0, 0, 0, 6000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(36853, 71665, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(36853, 69845, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36853, 36980, 0, 0, 0, 90000, 0, 0, 0, 90000, 0, 0, 0, 0, 0, 0, 9, 0, 0), +(36853, 47008, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36853, 72289, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 12, 0, 1), +(36853, 70128, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 30.0, 0, 0, 12, 0, 0); + +UPDATE`boss_spell_table` SET `data1` = 2, `data2` = 5, `data3` = 2, `data4` =5 WHERE `entry` = 36853 AND `spellID_N10` = 70126; +UPDATE`boss_spell_table` SET `data1` = 4, `data2` = 4, `data3` = 4, `data4` =4 WHERE `entry` = 36853 AND `spellID_N10` = 69845; + +-- Rimefang +DELETE FROM `boss_spell_table` WHERE `entry` = 37533; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37533, 71387, 0, 0, 0, 0, 0, 0, 0, 3600000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37533, 71386, 0, 0, 0, 5000, 0, 0, 0, 8000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(37533, 71376, 0, 0, 0, 4000, 0, 0, 0, 8000, 0, 0, 0, 0, 0, 0, 4, 0, 0); +-- Spinestalker +DELETE FROM `boss_spell_table` WHERE `entry` = 37534; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37534, 36922, 0, 0, 0, 8000, 0, 0, 0, 24000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37534, 40505, 0, 0, 0, 5000, 0, 0, 0, 8000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(37534, 71369, 0, 0, 0, 4000, 0, 0, 0, 8000, 0, 0, 0, 0, 0, 0, 4, 0, 0); +-- Ice tomb +DELETE FROM `boss_spell_table` WHERE `entry` = 36980; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36980, 70157, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 6, 0, 0); + +-- Lich king +DELETE FROM `boss_spell_table` WHERE `entry` = 36597; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36597, 70541, 0, 0, 0, 6000, 0, 0, 0, 12000, 0, 0, 0, 60, 0, 0, 12, 0, 0), +(36597, 70337, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36597, 74074, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36597, 69409, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(36597, 72762, 0, 0, 0, 20000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36597, 68980, 0, 0, 0, 1500, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36597, 68981, 0, 0, 0, 60000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 72133, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 72262, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 69201, 0, 0, 0, 5000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 1), +(36597, 69200, 0, 0, 0, 5000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(36597, 69242, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 69103, 0, 0, 0, 3000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 69099, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 69108, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 70358, 0, 0, 0, 40000, 0, 0, 0, 70000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 70372, 0, 0, 0, 40000, 0, 0, 0, 70000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 72149, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 72143, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 70503, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 69037, 0, 0, 0, 20000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 36609, 0, 0, 0, 20000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 9, 0, 0), +(36597, 71769, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 70063, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 1), +(36597, 47008, 0, 0, 0, 900000, 0, 0, 0, 900000, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(36597, 74352, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 1, 0, 0); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(36597, 37799, 60000, 60000, 8, 10, 10, 10, 15, 25, 0, 11), +(36597, 70498, 3600001, 3600001, 12, 12, 15, 15, 15, 25, 0, 1); +-- ice sphere +DELETE FROM `boss_spell_table` WHERE `entry` = 36633; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36633, 69099, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(36633, 69108, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(36633, 69090, 0, 0, 0, 8000, 0, 0, 0, 24000, 0, 0, 0, 0, 0, 0, 1, 0, 0); +-- vile spirit +DELETE FROM `boss_spell_table` WHERE `entry` = 37799; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(37799, 70503, 0, 0, 0, 10000, 0, 0, 0, 10000, 0, 0, 0, 0, 0, 0, 1, 0, 0); +-- raging spirit +DELETE FROM `boss_spell_table` WHERE `entry` = 36701; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(36701, 69242, 0, 0, 0, 2000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 3, 0, 0); diff --git a/addition/722_eye_of_eternity_mangos.sql b/addition/722_eye_of_eternity_mangos.sql new file mode 100644 index 000000000..9534c4d8c --- /dev/null +++ b/addition/722_eye_of_eternity_mangos.sql @@ -0,0 +1,31 @@ +-- Eye of Eternity from Tassadar && bwsrv +UPDATE `instance_template` SET `ScriptName`='instance_eye_of_eternity' WHERE map=616; +UPDATE `gameobject_template` SET `ScriptName`='go_focusing_iris' WHERE entry IN (193958, 193960); +UPDATE `creature_template` SET `ScriptName`='boss_malygos' WHERE entry=28859; +UPDATE `creature_template` SET `ScriptName`='npc_power_spark' WHERE entry=30084; +UPDATE `creature_template` SET `ScriptName`='npc_nexus_lord' WHERE entry=30245; +UPDATE `creature_template` SET `ScriptName`='npc_scion_of_eternity' WHERE entry=30249; +UPDATE `creature_template` SET `ScriptName`='npc_hover_disk' WHERE entry=30248; +UPDATE `creature_template` SET `PowerType` = 3, `InhabitType` = 3, `ScriptName`='npc_whyrmrest_skytalon' WHERE entry=30161; +UPDATE `creature_template` SET `PowerType` = 3, `InhabitType` = 3 WHERE entry=31752; +UPDATE `creature_template` SET `ScriptName`='npc_alexstrasza' WHERE entry=32295; + +REPLACE INTO `creature_template_addon` VALUES (30161,0,0,0,0,0,0,'57403'); +REPLACE INTO `creature_template_addon` VALUES (31752,0,0,0,0,0,0,'57403'); + +-- spawn Alexstrasza's Gift and Heart of Magic +DELETE FROM `gameobject` WHERE id IN (193905, 193967, 194158, 194159); +INSERT INTO `gameobject` (id, map, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state) VALUES +(193905, 616, 1, 1, 754.544, 1301.71, 220.083, 0, 0, 0, 0, 0, -604800, 100, 1), +(193967, 616, 2, 1, 754.544, 1301.71, 220.083, 0, 0, 0, 0, 0, -604800, 100, 1), +(194158, 616, 1, 1, 759.544, 1306.71, 225.083, 0, 0, 0, 0, 0, -604800, 100, 1), +(194159, 616, 2, 1, 759.544, 1306.71, 225.083, 0, 0, 0, 0, 0, -604800, 100, 1); + +-- vehicle data for Hover Disks and Wyrmrest Skytalons (normal and heroic) +UPDATE `creature_template` SET vehicle_id=220, Spell1=56091, Spell2=56092, Spell3=57090, Spell4=57143, Spell5=57108, Spell6=57092 WHERE entry IN (30161, 31752); + +UPDATE `creature_template` SET vehicle_id=223 WHERE entry IN (30248, 31749); + +DELETE FROM `npc_spellclick_spells` WHERE npc_entry=30248; +INSERT INTO `npc_spellclick_spells` (npc_entry, spell_id, quest_start, quest_start_active, quest_end, cast_flags) VALUES +(30248, 48754, 0, 0, 0, 1); diff --git a/addition/722_eye_of_eternity_scriptdev2.sql b/addition/722_eye_of_eternity_scriptdev2.sql new file mode 100644 index 000000000..8f0f8b6d9 --- /dev/null +++ b/addition/722_eye_of_eternity_scriptdev2.sql @@ -0,0 +1,38 @@ +-- Eye of Eternity +-- russian translation from lanc +REPLACE INTO `script_texts` (entry, content_default, content_loc1, content_loc2, content_loc3, content_loc4, content_loc5, content_loc6, content_loc7, content_loc8, sound, type, language, emote, comment) VALUES +(-1616000, 'Lesser beings, intruding here! A shame that your excess courage does not compensate for your stupidity!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Низшие создания, вторгшиеся сюда! Как жаль что ваш ум не так силен как ваша храбрость!', '14512', '1', '0', '457', NULL), +(-1616001, 'None but the blue dragonflight are welcome here! Perhaps this is the work of Alexstrasza? Well then, she has sent you to your deaths.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Никому кроме синих драконов не позволено находится здесь! Возможно, это происки Алекстразы? Что ж, значит она послала вас на верную смерть.', '14513', '1', '0', '457', NULL), +(-1616002, 'What could you hope to accomplish, to storm brazenly into my domain? To employ MAGIC? Against ME? ', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'А что вы планировали, беспардонно ворваться в мои владения? Использовать МАГИЮ? Против МЕНЯ?', '14514', '1', '0', '457', NULL), +(-1616003, 'I am without limits here... the rules of your cherished reality do not apply... In this realm, I am in control...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Здесь меня ничто не ограничивает... Законы вашей драгоценной реальности тут неприменимы... В этом мире Я главный...', '14515', '1', '0', '457', NULL), +(-1616004, 'I give you one chance. Pledge fealty to me, and perhaps I won''t slaughter you for your insolence!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я дам вам шанс. Присягните на верность мне и, может быть, я не уничтожу вас за вашу наглость!', '14516', '1', '0', '457', NULL), +(-1616005, 'My patience has reached its limit, I WILL BE RID OF YOU!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Мое терпение лопнуло, ПОРА ОТ ВАС ИЗБАВИТЬСЯ!', '14517', '1', '0', '1', NULL), +(-1616006, 'Watch helplessly as your hopes are swept away...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Смотрите беспомощно, как утекают ваши надежды...', '14525', '1', '0', '1', NULL), +(-1616007, 'I AM UNSTOPPABLE!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'МЕНЯ НЕ ОСТАНОВИТЬ!', '14533', '1', '0', '1', NULL), +(-1616008, 'Your stupidity has finally caught up to you!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Ну вот ты и встретился со своей глупостью!', '14519', '1', '0', '1', NULL), +(-1616009, 'More artifacts to confiscate...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Еще один экспонат для моей коллекции...', '14520', '1', '0', '1', NULL), +(-1616010, ' How very... naive...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Мха! Ха! Ха! Ха!Ха! Ха! Так... наивно...', '14521', '1', '0', '1', NULL), +(-1616012, 'I had hoped to end your lives quickly, but you have proven more...resilient then I had anticipated. Nonetheless, your efforts are in vain, it is you reckless, careless mortals who are to blame for this war! I do what I must...And if it means your...extinction...THEN SO BE IT!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я надеялся быстро с вами покончить, но вы оказались более... живучими, чем я ожидал. Тем не менее, все ваши попытки тщетны, это вы безрассудные, беспечные, смертные, вы виноваты в этой войне! Я сделаю то что я должен сделать... Если это потребует вашего полного уничтожения... ДА БУДЕТ ТАК!', '14522', '1', '0', '1', NULL), +(-1616013, 'Few have experienced the pain I will now inflict upon you!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Немногие испытывали боль, подобной той, что я сейчас причиню вам!', '14523', '1', '0', '1', NULL), +(-1616014, 'YOU WILL NOT SUCCEED WHILE I DRAW BREATH!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', '14518', '1', '0', '1', NULL), +(-1616015, 'Malygos takes a deep breath...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', '0', '3', '0', '1', NULL), +(-1616016, 'I will teach you IGNORANT children just how little you know of magic...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я покажу вам, МАЛОГРАМОТНЫМ детям, как мало вы знаете о магии...', '14524', '1', '0', '1', NULL), +(-1616017, 'ENOUGH! If you intend to reclaim Azeroth magic, then you shall have it...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Хватит! Раз вы хотите магии Азерота, то вы ее получите...', '14529', '1', '0', '1', NULL), +(-1616018, 'Now your benefactors make their appearance...But they are too late. The powers contained here are sufficient to destroy the world ten times over! What do you think they will do to you?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Вот и ваши благодетели появились... Но слишком поздно. Сил находящихся здесь хватит чтобы разрушить этот мир десять раз подряд! А что вы думаете они сделают с вами?', '14530', '1', '0', '1', NULL), +(-1616019, 'SUBMIT!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'СДАВАЙТЕСЬ!', '14531', '1', '0', '1', NULL), +(-1616020, 'Your energy will be put to good use!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Твою энергию используют по назначению!', '14526', '1', '0', '1', NULL), +(-1616021, 'I AM THE SPELL-WEAVER! My power is INFINITE!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я ХРАНИТЕЛЬ МАГИИ! Моя сила БЕЗГРАНИЧНА!', '14527', '1', '0', '1', NULL), +(-1616022, 'Your spirit will linger here forever!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Твой дух будет вечно скитаться здесь!', '14528', '1', '0', '1', NULL), +(-1616023, 'Alexstrasza! Another of your brood falls!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Алекстраза! Еще один из твоих пал!', '14534', '1', '0', '1', NULL), +(-1616024, 'Little more then gnats!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Чуть больше комара!', '14535', '1', '0', '1', NULL), +(-1616025, 'Your red allies will share your fate...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Твоих красных союзников ждет таже участь...', '14536', '1', '0', '1', NULL), +(-1616026, 'The powers at work here exceed anything you could possibly imagine!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Вам не хватит воображения, чтобы оценить мощь сил, задействованных здесь!', '14532', '1', '0', '1', NULL), +(-1616027, 'Still standing? Not for long...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Еще на ногах? Ненадолго...', '14537', '1', '0', '1', NULL), +(-1616028, 'Your cause is lost!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Вы проиграли!', '14538', '1', '0', '1', NULL), +(-1616029, 'Your fragile mind will be shattered!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Ваш хрупкий разум будет сокрушен!', '14539', '1', '0', '1', NULL), +(-1616030, 'UNTHINKABLE! The mortals will destroy... e-everything... my sister... what have you-', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'НЕВЕРОЯТНО! Смертные разрушат... Все... Сестра моя... Что ты...', '14540', '1', '0', '1', NULL), +(-1616031, 'I did what I had to, brother. You gave me no alternative.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', '14406', '1', '0', '1', NULL), +(-1616032, 'And so ends the Nexus War.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Война Нексуса окончена.', '14407', '1', '0', '1', NULL), +(-1616033, 'This resolution pains me deeply, but the destruction, the monumental loss of life had to end. Regardless of Malygos recent transgressions, I will mourn his loss. He was once a guardian, a protector. This day, one of the world mightiest has fallen.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Итоги войны черезмерно печалят меня, но разрушения и колоссальные потери жизней должны были быть остановлены. Несмотря на последние прегрешения Малигоса, Я буду оплакивать его. Когда-то он был заступником, защитником. Сегодня пал один из сильнейших этого мира!', '14408', '1', '0', '1', NULL), +(-1616034, 'The red dragonflight will take on the burden of mending the devastation wrought on Azeroth. Return home to your people and rest. Tomorrow will bring you new challenges, and you must be ready to face them. Life...goes on.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Красные драконы возьмут на себя бремя заживления ран Азерота. Возвращайтесь домой к своим людям и отдохните. Будущее несет вам новые испытания, и вы должны быть готовы к ним. Жизнь... Продолжается.', '14409', '1', '0', '1', NULL), +(-1616035, 'A Power Spark forms from a nearby rift!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', '0', '3', '0', '1', NULL); diff --git a/addition/723_icecrown_down_mangos.sql b/addition/723_icecrown_down_mangos.sql new file mode 100644 index 000000000..4b1ab2db2 --- /dev/null +++ b/addition/723_icecrown_down_mangos.sql @@ -0,0 +1,137 @@ +-- Forge of souls +UPDATE `instance_template` SET `ScriptName`='instance_forge_of_souls' WHERE `map`=632; +UPDATE `creature_template` SET `ScriptName`='boss_bronjahm', `AIName` ='' WHERE `entry`=36497; +UPDATE `creature_template` SET `ScriptName`='mob_soul_fragment', `modelid_1`= 30233, `modelid_3`= 30233, `AIName` ='' WHERE `entry`=36535; +-- UPDATE `creature_template` SET `ScriptName`='mob_soul_storm', `AIName` ='' WHERE `entry`=; + +-- UPDATE `creature_template` SET `ScriptName`='boss_devourer', `AIName` ='' WHERE `entry`=33113; +UPDATE `creature_template` SET `AIName`='', `Scriptname`='boss_devourer_of_souls' where `entry` IN (36502); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_well_of_soul' where `entry` IN (36536); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_unleashed_soul' where `entry` IN (36595); + +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_jaina_and_sylvana_FSintro' where `entry` IN (37597, 37596); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_jaina_and_sylvana_FSextro' where `entry` IN (38160, 38161); +UPDATE `creature_template` SET `scale`='0.8', `equipment_id`='1221' where `entry` IN (37597, 38160, 36993, 38188, 37221, 36955); +UPDATE `creature_template` SET `scale`='0.8' where `entry` IN (36658, 37225, 37223, 37226, 37554); +UPDATE `creature_template` SET `npcflag`='0' where `entry` IN (38160, 38161); +UPDATE `creature_template` SET `npcflag`='3' where `entry` IN (37597, 37596, 36993, 36990); +UPDATE `creature_template` SET `scale`='1' where `entry` IN (38161, 37596, 36990); +UPDATE `creature_template` SET `scale`='1' where `entry` IN (37755); +UPDATE `creature_template` SET `equipment_id`='1290' where `entry` IN (36990, 37596, 38161, 38189, 37223, 37554); +-- UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_soulguard_watchman' where `entry` IN (36478); +-- UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_soulguard_reaper' where `entry` IN (36499); +-- UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_soulguard_adept' where `entry` IN (36620); +-- UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_soulguard_bonecaster' where `entry` IN (36564); +-- UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_soulguard_animator' where `entry` IN (36516); +-- UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_soul_horror' where `entry` IN (36522); +-- UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_npc_spectral_warden' where `entry` IN (36666); + +-- Pit of saron +UPDATE `instance_template` SET `ScriptName`='instance_pit_of_saron' WHERE `map`=658; +UPDATE `creature_template` SET `ScriptName`='boss_ick', `AIName` ='' WHERE `entry`=36476; +UPDATE `creature_template` SET `ScriptName`='boss_krick', `AIName` ='' WHERE `entry`=36477; +UPDATE `creature_template` SET `ScriptName`='mob_exploding_orb', `AIName` ='' WHERE `entry`=36610; +UPDATE `creature_template` SET `ScriptName`='boss_forgemaster_garfrost', `AIName` ='' WHERE `entry`=36494; +UPDATE `creature_template` SET `ScriptName`='boss_scourgelord_tyrannus', `AIName` ='' WHERE `entry`=36658; +UPDATE `creature_template` SET `ScriptName`='boss_rimefang', `AIName` ='' WHERE `entry`=36661; +-- UPDATE `creature_template` SET `ScriptName`='npc_jaina_or_sylvanas_POSintro', `AIName` ='' WHERE `entry` IN (36990,36993); +-- UPDATE `creature_template` SET `ScriptName`='npc_jaina_or_sylvanas_POSoutro', `AIName` ='' WHERE `entry` IN (38189,38188); + +-- Halls of reflection +UPDATE `instance_template` SET `ScriptName` = 'instance_halls_of_reflection' WHERE map=668; +UPDATE `gameobject_template` SET `ScriptName` = '' WHERE `entry` IN (202236,202302); +DELETE FROM `creature` WHERE `map` = 668 AND `id` IN (38177,38176,38173,38172,38567,38175,36940,36941,37069); + +UPDATE `creature_template` SET `ScriptName`='generic_creature' WHERE `entry` IN (38177,38176,38173,38172,38567,38175); + +UPDATE `gameobject_template` SET `faction` = '114' WHERE `entry` IN (197341, 201976); +UPDATE `gameobject_template` SET `faction`='1375' WHERE `entry` IN (197341, 202302, 201385, 201596); + +UPDATE `creature_template` SET `speed_walk`='1.5', `speed_run`='2.0' WHERE `entry` IN (36954, 37226); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_jaina_and_sylvana_HRintro' WHERE `entry` IN (37221, 37223); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='boss_falric' WHERE `entry` IN (38112); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='boss_marwyn' WHERE `entry` IN (38113); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='boss_lich_king_intro_hor' WHERE `entry` IN (36954); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='boss_lich_king_hr' WHERE `entry` IN (37226); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_jaina_and_sylvana_HRextro' WHERE `entry` IN (36955, 37554); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_undead_hor' WHERE `entry` IN (36940,36941,37069); +UPDATE `creature_template` SET `scale`='0.8', `equipment_id`='1221' WHERE `entry` IN (37221, 36955); +UPDATE `creature_template` SET `equipment_id`='1290' WHERE `entry` IN (37223, 37554); +UPDATE `creature_template` SET `equipment_id`='0' WHERE `entry`=36954; +UPDATE `creature_template` SET `scale`='1' WHERE `entry` IN (37223); +UPDATE `creature_template` SET `scale`='0.8' WHERE `entry` IN (36658, 37225, 37223, 37226, 37554); +UPDATE `creature_template` SET `unit_flags`='768', `type_flags`='268435564' WHERE `entry` IN (38177, 38176, 38173, 38172, 38567, 38175); +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_frostworn_general' WHERE `entry`=36723; +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_spiritual_reflection' WHERE `entry`=37068; + +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('70464', '1', '36881'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69708', '1', '37226'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('70194', '1', '37226'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69784', '1', '37014'); + +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69784', '1', '37014'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('70224', '1', '37014'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('70225', '1', '37014'); + +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69431', '1', '37497'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69431', '1', '37496'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69431', '1', '37496'); + +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69431', '1', '37588'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69431', '1', '37584'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69431', '1', '37587'); + +REPLACE INTO `creature_equip_template` VALUES ('38112', '50249', '49777', '0'); #Falric +UPDATE `creature_template` SET `equipment_id`='38112' WHERE `entry` IN (38112); + +REPLACE INTO `creature_equip_template` VALUES ('38113', '50248', '50248', '0'); #Marwyn +UPDATE `creature_template` SET `equipment_id`='38113' WHERE `entry` IN (38113); +REPLACE INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `DeathState`, `MovementType`) VALUES (135341, 38112, 668, 3, 1, 0, 0, 5276.81, 2037.45, 709.32, 5.58779, 604800, 0, 0, 377468, 0, 0, 0); +REPLACE INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `DeathState`, `MovementType`) VALUES (135342, 38113, 668, 3, 1, 0, 0, 5341.72, 1975.74, 709.32, 2.40694, 604800, 0, 0, 539240, 0, 0, 0); + +REPLACE INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES (14531739, 201596, 668, 1, 128, 5275.28, 1694.23, 786.147, 0.981225, 0, 0, 0.471166, 0.882044, 25, 0, 1); + +DELETE from `creature` WHERE `id`=36955; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `DeathState`, `MovementType`) VALUES (135349, 36955, 668, 3, 128, 0, 0, 5547.27, 2256.95, 733.011, 0.835987, 7200, 0, 0, 252000, 881400, 0, 0); + +DELETE from `creature` WHERE `id`=37554; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `DeathState`, `MovementType`) VALUES (135345, 37554, 668, 3, 64, 0, 0, 5547.27, 2256.95, 733.011, 0.835987, 7200, 0, 0, 252000, 881400, 0, 0); + +DELETE from `creature` WHERE `id`=37226; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `DeathState`, `MovementType`) VALUES (135344, 37226, 668, 3, 1, 0, 0, 5551.29, 2261.33, 733.012, 4.0452, 604800, 0, 0, 27890000, 0, 0, 0); + +UPDATE `creature_template` SET `modelid_1` = 11686, `modelid_2` = 11686, `modelid_3` = 11686, `modelid_4` = 11686 WHERE `entry` IN (37014,37704); + +DELETE FROM `gameobject` WHERE `id` IN (201385,201596,202079); + +UPDATE `gameobject_template` SET `faction` = '114',`data0` = '0' WHERE `gameobject_template`.`entry` IN (197341,197342,197343); +UPDATE `gameobject` SET `state` = '1' WHERE `id` IN (197341,197342,197343); + +-- offlike way for icewalls operation +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69768', '1', '37014'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('69767', '1', '37014'); +DELETE from `creature` WHERE `id`=37014; +UPDATE `creature_template` SET `AIName`='', `Scriptname`='npc_queldelar_hor' where `entry` IN (37158); +DELETE from `creature` WHERE `map` = 668 AND `id` IN (37221,37223,37554,36955); + +-- Captains chest (override) +DELETE FROM `gameobject` WHERE `id` IN (202212,201710,202337,202336); +UPDATE `gameobject_template` SET `flags` = 0 WHERE `gameobject_template`.`entry` IN (202212,201710,202337,202336); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(972561, 202212, 668, 1, 65535, 5241.047, 1663.4364, 784.295166, 0.54, 0, 0, 0, 0, -604800, 100, 1), +(972562, 201710, 668, 1, 65535, 5241.047, 1663.4364, 784.295166, 0.54, 0, 0, 0, 0, -604800, 100, 1), +(972563, 202337, 668, 2, 65535, 5241.047, 1663.4364, 784.295166, 0.54, 0, 0, 0, 0, -604800, 100, 1), +(972564, 202336, 668, 2, 65535, 5241.047, 1663.4364, 784.295166, 0.54, 0, 0, 0, 0, -604800, 100, 1); +-- Dalaran portal (override) +DELETE FROM `gameobject` WHERE `guid` IN (972565); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(972565, 202079, 668, 3, 65535, 5250.959961, 1639.359985, 784.302, 0, 0, 0, 0, 0, -604800, 100, 1); + + +/* Original Icewalls from YTDB +REPLACE INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(3485, 201385, 668, 3, 1, 5540.39, 2086.48, 731.066, 1.00057, 0, 0, 0.479677, 0.877445, 604800, 100, 1), +(3438, 201385, 668, 3, 1, 5494.3, 1978.27, 736.689, 1.0885, 0, 0, 0.517777, 0.855516, 604800, 100, 1), +(3386, 201385, 668, 3, 1, 5434.27, 1881.12, 751.303, 0.923328, 0, 0, 0.445439, 0.895312, 604800, 100, 1), +(3383, 201385, 668, 3, 1, 5323.61, 1755.85, 770.305, 0.784186, 0, 0, 0.382124, 0.924111, 604800, 100, 1); +*/ \ No newline at end of file diff --git a/addition/723_icecrown_down_scriptdev2.sql b/addition/723_icecrown_down_scriptdev2.sql new file mode 100644 index 000000000..4c663b4a1 --- /dev/null +++ b/addition/723_icecrown_down_scriptdev2.sql @@ -0,0 +1,315 @@ +-- Pit of saron +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1658100 AND -1658000; +INSERT INTO `script_texts` (`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +-- Garfrost +(-1658001,'Tiny creatures under feet, you bring Garfrost something good to eat!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16912,1,0,0,'garfrost SAY_AGGRO'), +(-1658002,'Will save for snack. For later.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16913,1,0,0,'garfrost SAY_SLAY_1'), +(-1658003,'That one maybe not so good to eat now. Stupid Garfrost! BAD! BAD!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16914,1,0,0,'garfrost SAY_SLAY_2'), +(-1658004,'Garfrost hope giant underpants clean. Save boss great shame. For later.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16915,1,0,0,'garfrost SAY_DEATH'), +(-1658005,'Axe too weak. Garfrost make better and CRUSH YOU!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16916,1,0,0,'garfrost SAY_PHASE2'), +(-1658006,'Garfrost tired of puny mortals. Now your bones will freeze!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16917,1,0,0,'garfrost SAY_PHASE3'), +(-1658007,'Another shall take his place. You waste your time.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16752,1,0,0,'Tyrannus SAY_TYRANNUS_DEATH'), + +-- Krick +(-1658010,'Our work must not be interrupted! Ick! Take care of them!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16926,1,0,0,'Krick SAY_AGGRO'), +(-1658011,'Ooh...We could probably use these parts!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16927,1,0,0,'Krick SAY_SLAY_1'), +(-1658012,'Arms and legs are in short supply...Thanks for your contribution!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16928,1,0,0,'Krick SAY_SLAY_2'), +(-1658013,'Enough moving around! Hold still while I blow them all up!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16929,1,0,0,'Krick SAY_BARRAGE_1'), +(-1658014,'Krick begins rapidly conjuring explosive mines!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Krick SAY_BARRAGE_2'), +(-1658015,'Quickly! Poison them all while they''re still close!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16930,1,0,0,'Krick SAY_POISON_NOVA'), +(-1658016,'No! That one! That one! Get that one!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16931,1,0,0,'Krick SAY_CHASE_1'), +(-1658017,'I''ve changed my mind...go get that one instead!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16932,1,0,0,'Krick SAY_CHASE_2'), +(-1658018,'What are you attacking him for? The dangerous one is over there,fool!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16933,1,0,0,'Krick SAY_CHASE_3'), + +-- Ick +(-1658020,'Ick begins to unleash a toxic poison cloud!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Ick SAY_ICK_POISON_NOVA'), +(-1658021,'Ick is chasing you!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Ick SAY_ICK_CHASE_1'), + +-- Krick OUTRO +(-1658030,'Wait! Stop! Don''t kill me, please! I''ll tell you everything!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16934,1,0,0,'Krick SAY_KRICK_OUTRO_1'), +(-1658031,'I''m not so naive as to believe your appeal for clemency, but I will listen.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16611,1,0,0,'Jaina SAY_JAINA_OUTRO_2'), +(-1658032,'Why should the Banshee Queen spare your miserable life?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17033,1,0,0,'Sylvanas SAY_SYLVANAS_OUTRO_2'), +(-1658033,'What you seek is in the master''s lair, but you must destroy Tyrannus to gain entry. Within the Halls of Reflection you will find Frostmourne. It... it holds the truth.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16935,1,0,0,'Krick SAY_KRICK_OUTRO_3'), +(-1658034,'Frostmourne lies unguarded? Impossible!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16612,1,0,0,'Jaina SAY_JAINA_OUTRO_4'), +(-1658035,'Frostmourne? The Lich King is never without his blade! If you are lying to me...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17034,1,0,0,'Sylvanas SAY_SYLVANAS_OUTRO_4'), +(-1658036,'I swear it is true! Please, don''t kill me!!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16936,1,0,0,'Krick SAY_KRICK_OUTRO_5'), +(-1658037,'Worthless gnat! Death is all that awaits you!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16753,1,0,0,'Tyrannus SAY_TYRANNUS_OUTRO_7'), +(-1658038,'Urg... no!!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16937,1,0,0,'Krick SAY_KRICK_OUTRO_8'), +(-1658039,'Do not think that I shall permit you entry into my master''s sanctum so easily. Pursue me if you dare.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16754,1,0,0,'Tyrannus SAY_TYRANNUS_OUTRO_9'), +(-1658040,'What a cruel end. Come, heroes. We must see if the gnome''s story is true. If we can separate Arthas from Frostmourne, we might have a chance at stopping him.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16613,1,0,0,'Jaina SAY_JAINA_OUTRO_10'), +(-1658041,'A fitting end for a traitor. Come, we must free the slaves and see what is within the Lich King''s chamber for ourselves.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17035,1,0,0,'Sylvanas SAY_SYLVANAS_OUTRO_10'), + +-- Tyrannus +(-1658050,'Your pursuit shall be in vain, adventurers, for the Lich King has placed an army of undead at my command! Behold!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16755,1,0,0,'Tyrannus SAY_AMBUSH_1'), +(-1658051,'Persistent whelps! You will not reach the entrance of my lord''s lair! Soldiers, destroy them!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16756,1,0,0,'Tyrannus SAY_AMBUSH_2'), +(-1658052,'Rimefang! Trap them within the tunnel! Bury them alive!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16757,1,0,0,'Tyrannus SAY_GAUNTLET_START'), +(-1658053,'Alas, brave, brave adventurers, your meddling has reached its end. Do you hear the clatter of bone and steel coming up the tunnel behind you? That is the sound of your impending demise.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16758,1,0,0,'Tyrannus SAY_INTRO_1'), +(-1658054,'Ha, such an amusing gesture from the rabble. When I have finished with you, my master''s blade will feast upon your souls. Die!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16759,1,0,0,'Tyrannus SAY_INTRO_2'), + +(-1658055,'I shall not fail The Lich King! Come and meet your end!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16760,1,0,0,'Tyrannus SAY_AGGRO'), +(-1658056,'Such a shameful display... You are better off dead!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16761,1,0,0,'Tyrannus SAY_SLAY_1'), +(-1658057,'Perhaps you should have stayed in the mountains!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16762,1,0,0,'Tyrannus SAY_SLAY_2'), +(-1658058,'Impossible! Rimefang... Warn...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16763,1,0,0,'Tyrannus SAY_DEATH'), +(-1658059,'Rimefang, destroy this fool!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16764,1,0,0,'Tyrannus SAY_MARK_RIMEFANG_1'), +(-1658060,'The frostwyrm Rimefang gazes at $N and readies an icy attack!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Tyrannus SAY_MARK_RIMEFANG_2'), +(-1658061,'Power... overwhelming!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16765,1,0,0,'Tyrannus SAY_DARK_MIGHT_1'), +(-1658062,'Scourgelord Tyrannus roars and swells with dark might!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Tyrannus SAY_DARK_MIGHT_2'), + +(-1658063,'Brave champions, we owe you our lives, our freedom... Though it be a tiny gesture in the face of this enormous debt, I pledge that from this day forth, all will know of your deeds, and the blazing path of light you cut through the shadow of this dark citadel.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0,'Gorkun SAY_GORKUN_OUTRO_1'), +(-1658064,'This day will stand as a testament not only to your valor, but to the fact that no foe, not even the Lich King himself, can stand when Alliance and Horde set aside their differences and ---',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0,'Gorkun SAY_GORKUN_OUTRO_2'), +(-1658065,'Heroes, to me!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16614,1,0,0,'Jaina SAY_JAYNA_OUTRO_3'), +(-1658066,'Take cover behind me! Quickly!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17037,1,0,0,'Sylvanas SAY_SYLVANAS_OUTRO_3'), +(-1658067,'The Frost Queen is gone. We must keep moving - our objective is near.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16615,0,0,0,'Jaina SAY_JAYNA_OUTRO_4'), +(-1658068,'I thought he''d never shut up. At last, Sindragosa silenced that long-winded fool. To the Halls of Reflection, champions! Our objective is near... I can sense it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17036,0,0,0,'Sylvanas SAY_SYLVANAS_OUTRO_4'), +(-1658069,'I... I could not save them... Damn you, Arthas! DAMN YOU!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16616,0,0,0,'Jaina SAY_JAYNA_OUTRO_5'); + +-- Forge of souls +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1632099 AND -1632000; +INSERT INTO `script_texts` (`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +-- Bronjham +(-1632001,'Finally...a captive audience!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Наконец то! Гости пожаловали!',16595,6,0,0,'Bronjham SAY_AGGRO'), +(-1632002,'Fodder for the engine!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Скормлю тебя машине!',16596,6,0,0,'Bronjham SAY_SLAY_1'), +(-1632003,'Another soul to strengthen the host!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Еще одна душа обогатит вместилище!',16597,6,0,0,'Bronjham SAY_SLAY_2'), +(-1632004,'Oooooo...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Аааааааааааа...',16598,6,0,0,'Bronjham SAY_DEATH'), +(-1632005,'The vortex of the harvested calls to you!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Вихрь погубленных душ, взываю к вам!',16599,3,0,0,'Bronjham SAY_SOUL_STORM'), +(-1632006,'I will sever the soul from your body!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Я вырву душу из твоего тела!',16600,6,0,0,'Bronjham SAY_CORRUPT_SOUL'), + +-- Devourer of Souls +(-1632010,'You dare look upon the host of souls? I SHALL DEVOUR YOU WHOLE!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Вы осмелились взглянуть на вместилище душ! Я сожру вас заживо!',16884,1,0,0,'Devoureur SAY_FACE_ANGER_AGGRO'), +(-1632011,'You dare look upon the host of souls? I SHALL DEVOUR YOU WHOLE!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16890,1,0,0,'Devoureur SAY_FACE_DESIRE_AGGRO'), +(-1632012,'Damnation!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Проклинаю тебя!',16885,1,0,0,'Devoureur SAY_FACE_ANGER_SLAY_1'), +(-1632013,'Damnation!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16896,1,0,0,'Devoureur SAY_FACE_SORROW_SLAY_1'), +(-1632014,'Damnation!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16891,1,0,0,'Devoureur SAY_FACE_DESIRE_SLAY_1'), +(-1632015,'Doomed for eternity!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Обрекаю тебя на вечные муки!',16886,1,0,0,'Devoureur SAY_FACE_ANGER_SLAY_2'), +(-1632016,'Doomed for eternity!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16897,1,0,0,'Devoureur SAY_FACE_SORROW_SLAY_2'), +(-1632017,'Doomed for eternity!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16892,1,0,0,'Devoureur SAY_FACE_DESIRE_SLAY_2'), +(-1632018,'The swell of souls will not be abated! You only delay the inevitable!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Вместилише душ не ослабнет! Вы лишь пытаетесь отсрочить неизбежное.',16887,1,0,0,'Devoureur SAY_FACE_ANGER_DEATH'), +(-1632019,'The swell of souls will not be abated! You only delay the inevitable!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16898,1,0,0,'Devoureur SAY_FACE_SORROW_DEATH'), +(-1632020,'The swell of souls will not be abated! You only delay the inevitable!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16893,1,0,0,'Devoureur SAY_FACE_DESIRE_DEATH'), +(-1632021,'Devourer of Souls begins to cast Mirrored Soul!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Devoureur EMOTE_MIRRORED_SOUL'), +(-1632022,'Devourer of Souls begins to Unleash Souls!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Devoureur EMOTE_UNLEASH_SOUL'), +(-1632023,'SUFFERING! ANGUISH! CHAOS! RISE AND FEED!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Страдание, мучение, хаос! Восстаньте и пируйте!',16888,1,0,0,'Devoureur SAY_FACE_ANGER_UNLEASH_SOUL'), +(-1632024,'SUFFERING! ANGUISH! CHAOS! RISE AND FEED!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16899,1,0,0,'Devoureur SAY_FACE_SORROW_UNLEASH_SOUL'), +(-1632025,'SUFFERING! ANGUISH! CHAOS! RISE AND FEED!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16894,1,0,0,'Devoureur SAY_FACE_DESIRE_UNLEASH_SOUL'), +(-1632026,'Devourer of Souls begins to cast Wailing Souls!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'Devoureur EMOTE_WAILING_SOUL'), +(-1632027,'Stare into the abyss, and see your end!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Вглядитесь в бездну, и узрите свою смерть!',16889,1,0,0,'Devoureur SAY_FACE_ANGER_WAILING_SOUL'), +(-1632028,'Stare into the abyss, and see your end!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16895,1,0,0,'Devoureur SAY_FACE_DESIRE_WAILING_SOUL'), +(-1632029,'Excellent work, champions! We shall set up our base camp in these chambers. My mages will get the Scourge transport device working shortly. Step inside it when you''re ready for your next mission. I will meet you on the other side.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Вы справились. Мы разобьем лагерь в этих покоях. Вскоре мои маги заставят портал плети работать! Войдите в него, когда будете готовы к следующему заданию. Я присоеденусь к вам чуть позже.',16625,1,0,0,'Jaina SAY_JAINA_OUTRO'), +(-1632030,'Excellent work, champions! We shall set up our base camp in these chambers. My mages will get the Scourge transport device working shortly. Step inside when you are ready for your next mission. I will meet you on the other side.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Превосходно! Мы разобьем лагерь в этих покоях! Вскоре мои маги заставят портал плети работать, войдите в него когда будете готовы к следующему заданию! Я присоединюсь к вам позже.',17044,1,0,0,'Sylvanas SAY_SYLVANAS_OUTRO'), + +-- Jaina +(-1632040,'Thank the light for seeing you here safely. We have much work to do if we are to defeat the Lich King and put an end to the Scourge.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Слава свету! Вы целы и невредимы нам предстоит многое сделать, если мы хотим покончить с королем личем и плетью.',16617,0,0,0,'Jaina SAY_INTRO_1'), +(-1632041,'Our allies within the Argent Crusade and the Knights of the Ebon Blade have broken through the front gate of Icecrown and are attempting to establish a foothold within the Citadel.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Серебряный Авангард и рыцари черного клинка прорвались через главные ворота и пытаются укрепить свои позиции в цитадели!',16618,0,0,0,'Jaina SAY_INTRO_2'), +(-1632042,'Their success hinges upon what we discover in these cursed halls. Although our mission is a wrought with peril, we must persevere!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Их успех зависит от того что мы найдем этих ужасных залах. Пусть наша миссия опасна, но мы должны выстоять.',16619,0,0,0,'Jaina SAY_INTRO_3'), +(-1632043,'With the attention of the Lich King drawn toward the front gate, we will be working our way through the side in search of information that will enable us to defeat the Scourge - once and for all.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Пока король лич отвлекся на главные ворота, мы проникнем внутрь другим путем и постараемся узнать как можно покончить с плетью раз и навсегда.',16620,0,0,0,'Jaina SAY_INTRO_4'), +(-1632044,'King Varian''s SI7 agents have gathered information about a private sanctum of the Lich King''s deep within a place called the Halls of Reflection.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Разведчики SI7 отправленные Варианом сообщают что покои короля находятся в глубине дворца! Это место называется Залами отражений.',16621,0,0,0,'Jaina SAY_INTRO_5'), +(-1632045,'We will carve a path through this wretched place and find a way to enter the Halls of Reflection. I sense powerful magic hidden away within those walls... Magic that could be the key to destroy the Scourge.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Мы проложим себе путь сквозь это проклятое место и найдем вход в залы отражений. Я чувствую что в них сокрыта могушественная магия, которая поможет нам сокрушить плеть!',16622,0,0,0,'Jaina SAY_INTRO_6'), +(-1632046,'Your first mission is to destroy the machines of death within this malevolent engine of souls, and clear a path for our soldiers.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Ваша первая задача разрушить машины смерти в этом механизме душ, это откроет путь нашим солдатам.',16623,0,0,0,'Jaina SAY_INTRO_7'), +(-1632047,'Make haste, champions! I will prepare the troops to fall in behind you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Спешите герои, я прикажу солдатам следовать за вами!',16624,0,0,0,'Jaina SAY_INTRO_8'), + +-- Sylvanas +(-1632050,'The Argent Crusade and the Knights of the Ebon Blade have assaulted the gates of Icecrown Citadel and are preparing for a massive attack upon the Scourge. Our missition is a bit more subtle, but equally as important.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Серебряный Авангард и рыцари черного клинка штурмуют ворота цитадели ледяной короны! И готовятся нанести решаюший удар! Мы будем действовать незаметно, но не менее эффективно.',17038,0,0,0,'Sylvanas SAY_INTRO_1'), +(-1632051,'With the attention of the Lich King turned towards the front gate, we''ll be working our way through the side in search of information that will enable us to defeat the Lich King - once and for all.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Пока Король-Лич отвлекся мы проникнем внутрь другим путем и постараемся понять как можно покончить с ним раз и навсегда.',17039,0,0,0,'Sylvanas SAY_INTRO_2'), +(-1632052,'Our scouts have reported that the Lich King has a private chamber, outside of the Frozen Throne, deep within a place called the Halls of Reflection. That is our target, champions.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Наши разведчики сообщили что покои короля лича находятся в глубине дворца, недалеко от ледяного трона. Это место называется залами отражений, туда и лежит наш путь.',17040,0,0,0,'Sylvanas SAY_INTRO_3'), +(-1632053,'We will cut a swath of destruction through this cursed place and find a way to enter the Halls of Reflection. If there is anything of value to be found here, it will be found in the Halls.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Мы проложим себе путь сквозь это проклетое место и найдем и найдем вход в залы отражений! Если в цитадели и есть что то достойное внимания оно ждет нас именно там.',17041,0,0,0,'Sylvanas SAY_INTRO_4'), +(-1632054,'Your first mission is to destroy the machines of death within this wretched engine of souls, and clear a path for our soldiers.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Вашей первой задачей будет разрушение машин смерти в этом гнусном механизме душ, это откроет путь к нашим солдатам',17042,0,0,0,'Sylvanas SAY_INTRO_5'), +(-1632055,'The Dark Lady watches over you. Make haste!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Темная госпожа будет наблюдать за вами, спешите!',17043,0,0,0,'Sylvanas SAY_INTRO_6'); + +-- Halls of reflection (from MaxXx2021 aka Mioka) +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1594540 AND -1594430; +INSERT INTO `script_texts` (`entry`,`content_default`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +# SCENE - Hall Of Reflection (Intro) - PreUther +(-1594433, 'The chill of this place freezes the marrow of my bones!', 'Как же тут холодно... Кровь стынет в жилах.', 16631,0,0,1, '67234'), +(-1594434, 'I... I don\'t believe it! Frostmourne stands before us, unguarded! Just as the Gnome claimed. Come, heroes!', 'Я... Я не верю своим глазам. Ледяная скорбь перед нами без всякой охраны! Как и говорил гном. Вперед герои!', 17049,0,0,1, '67234'), +(-1594435, 'What is that? Up ahead! Could it be ... ? Heroes at my side!', 'Что это там впереди? Неужели? Скорее герои!', 16632,1,0,1, '67234'), +(-1594436, 'Frostmourne ... The blade that destroyed our kingdom ...', 'Ледяная Скорбь, клинок, разрушивший наше королевство...', 16633,1,0,1, '67234'), +(-1594437, 'Standing this close to the blade that ended my life... The pain... It is renewed.', 'Боль снова захлестывает меня, когда я так близко вижу меч, отнявший у меня жизнь.', 17050,0,0,1, '67234'), +(-1594438, 'Stand back! Touch that blade and your soul will be scarred for all eternity! I must attempt to commune with the spirits locked away within Frostmourne. Give me space, back up please!', 'Отойдите. Тот кто коснется этого клинка обречет себя на вечные муки. Я попытаюсь заговорить с душами заключенными в Ледяной скорби. Расступитесь... Чуть назад! Прошу.', 16634,1,0,1, '67234'), +(-1594439, 'I dare not touch it. Stand back! Stand back! As I attempt to commune with the blade. Perhaps our salvation lies within.', 'Я не смею его коснуться. Назад! Отступите! Я попробую установить связь с мечом. Возможно, спасение находится внутри!', 17051,1,0,1, '67234'), +# SCENE - Hall Of Reflection (Intro) - UtherDialog +(-1594440, 'Jaina! Could it truly be you?', 'Джайна? Неужели это ты?', 16666,0,0,1, '67234'), +(-1594441, 'Careful, girl. I\'ve heard talk of that cursed blade saving us before. Look around you and see what has been born of Frostmourne.', 'Осторожней девочка! Однажды мне уже говорили, что этот проклятый меч может нас спасти. Посмотри вокруг, и ты увидишь, что из этого вышло.', 16659,0,0,1, '67234'), +(-1594442, 'Uther! Dear Uther! I... I\'m so sorry.', 'Утер? Милый Утер! Мне... Мне так жаль.', 16635,0,0,1, '67234'), +(-1594443, 'Uther...Uther the Lightbringer. How...', 'Утер? Утер Светоносный? Как...', 17052,0,0,1, '67234'), +(-1594444, 'Jaina, you haven\'t much time. The Lich King sees what the sword sees. He will be here shortly.', 'Джайна, у вас мало времени. Король - Лич видит все что видит Ледяная Скорбь. Вскоре он будет здесь.', 16667,0,0,1, '67234'), +(-1594445, 'You haven\'t much time. The Lich King sees what the sword sees. He will be here shortly.', 'У вас мало времени. Король - Лич видит все что видит Ледяная Скорбь. Вскоре он будет здесь.', 16660,0,0,1, '67234'), +(-1594446, 'Arthas is here? Maybe I...', 'Артас здесь? Может я...', 16636,0,0,1, '67234'), +(-1594447, 'The Lich King is here? Then my destiny shall be fulfilled today!', 'Король - Лич здесь? Значит моя судьба решится сегодня!', 17053,1,0,1, '67234'), +(-1594448, 'No, girl. Arthas is not here. Arthas is merely a presence within the Lich King\'s mind. A dwindling presence...', 'Нет девочка. Артаса здесь нет. Артас лишь тень, мелькающая в сознании Короля - Лича. Смутная тень.', 16668,0,0,1, '67234'), +(-1594449, 'You cannot defeat the Lich King. Not here. You would be a fool to try. He will kill those who follow you and raise them as powerful servants of the Scourge. But for you, Sylvanas, his reward for you would be worse than the last.', 'Вам не победить Короля - Лича. Покрайней мере не здесь. Глупо и пытаться. Он убьет твоих соратников и воскресит их как воинов плети. Но что до тебя Сильвана, он готовит тебе участь еще страшнее, чем в прошлый раз.', 16661,0,0,1, '67234'), +(-1594450, 'But Uther, if there\'s any hope of reaching Arthas. I... I must try.', 'Но если есть малейшая надежда вернуть Артаса... Я должна попытаться!', 16637,0,0,1, '67234'), +(-1594451, 'There must be a way...', 'Должен быть способ!', 17054,0,0,1, '67234'), +(-1594452, 'Jaina, listen to me. You must destroy the Lich King. You cannot reason with him. He will kill you and your allies and raise you all as powerful soldiers of the Scourge.', 'Джайна послушай меня. Вам нужно уничтожить Короля - Лича. С ним нельзя договориться. Он убьет вас всех и превратит в могущественных воинов Плети.', 16669,0,0,1, '67234'), +(-1594453, 'Perhaps, but know this: there must always be a Lich King. Even if you were to strike down Arthas, another would have to take his place, for without the control of the Lich King, the Scourge would wash over this world like locusts, destroying all that they touched.', 'Возможно... Но знай! Король - Лич должен быть всегда. Даже если вы убьете Артаса кто то обязан будет занять его место. Лишившись правителя Плеть налетит на мир как стая саранчи и уничтожит все на своем пути.', 16662,0,0,1, '67234'), +(-1594454, 'Tell me how, Uther? How do I destroy my prince? My...', 'Но как Утер? Как мне убить моего принца, моего...', 16638,0,0,1, '67234'), +(-1594455, 'Who could bear such a burden?', 'Кому по силам такое бремя?', 17055,0,0,1, '67234'), +(-1594456, 'Snap out of it, girl. You must destroy the Lich King at the place where he merged with Ner\'zhul - atop the spire, at the Frozen Throne. It is the only way.', 'Забудь об этом девочка. Короля - Лича нужно уничтожить на том месте, где он слился с Нерзулом. На самой вершине, у Ледяного Трона!', 16670,0,0,1, '67234'), +(-1594457, 'I do not know, Banshee Queen. I suspect that the piece of Arthas that might be left inside the Lich King is all that holds the Scourge from annihilating Azeroth.', 'Не знаю, Королева Баньши... Если бы не Артас, который все еще является частью Короля - Лича, Плеть давно бы уже уничтожила Азерот.', 16663,0,0,1, '67234'), +(-1594458, 'You\'re right, Uther. Forgive me. I... I don\'t know what got a hold of me. We will deliver this information to the King and the knights that battle the Scourge within Icecrown Citadel.', 'Ты прав Утер, прости меня... Я не знаю что на меня нашло. Мы передадим твои слова Королю и рыцарям, которые сражаются с Плетью в Цитадели Ледяной Короны.', 16639,0,0,1, '67234'), +(-1594459, 'There is... something else that you should know about the Lich King. Control over the Scourge must never be lost. Even if you were to strike down the Lich King, another would have to take his place. For without the control of its master, the Scourge would run rampant across the world - destroying all living things.', 'Тебе нужно знать еще кое что о Короле - Личе. Плеть не должна выйти из под контроля. Даже если вы убьете Короля - Лича, кто-то должен будет занять его место. Без Короля Плеть налетит на мир как стая саранчи и уничтожит все живое.', 16671,0,0,1, '67234'), +(-1594460, 'Alas, the only way to defeat the Lich King is to destroy him at the place he was created.', 'Увы единственый способ одолеть Короля - Лича - это убить его там где он был порожден.', 16664,0,0,1, '67234'), +(-1594461, 'Who could bear such a burden?', 'Кому по силам такое бремя?', 16640,0,0,1, '67234'), +(-1594462, 'The Frozen Throne...', 'Ледяной Трон!', 17056,0,0,1, '67234'), +(-1594463, 'A grand sacrifice by a noble soul...', 'Великая жертва, благородной души.', 16672,0,0,1, '67234'), +(-1594464, 'I do not know, Jaina. I suspect that the piece of Arthas that might be left inside the Lich King is all that holds the Scourge from annihilating Azeroth.', 'Не знаю Джайна... мне кажется если бы не Артас, который все еще является частью Короля - Лича, Плеть давно бы уже уничтожила Азерот.', 16673,0,0,1, '67234'), +(-1594465, 'Then maybe there is still hope...', 'Но может еще есть надежда?', 16641,0,0,1, '67234'), +(-1594466, 'No, Jaina! ARRRRRRGHHHH... He... He is coming. You... You must...', 'Нет Джайна... Эээээ... Он... Он приближается... Вы... Вы должны...', 16674,1,0,1, '67234'), +(-1594467, 'Aye. ARRRRRRGHHHH... He... He is coming. You... You must...', 'Да... Эээээ... Он... Он приближается... Вы... Вы должны...', 16665,1,0,1, '67234'), +(-1594468, 'SILENCE, PALADIN!', 'Замолчи, паладин.', 17225,1,0,0, '67234'), +(-1594469, 'So you wish to commune with the dead? You shall have your wish.', 'Так ты хочешь поговорить с мертвыми? Нет ничего проще!', 17226,1,0,0, '67234'), +(-1594470, 'Falric. Marwyn. Bring their corpses to my chamber when you are through.', 'Фалрик, Марвин, когда закончите, принесите их тела в мои покои.', 17227,0,0,0, '67234'), +(-1594471, 'You won\'t deny me this, Arthas! I must know... I must find out...', 'Ты от меня не отмахнешься Артас. Я должна понять, я должна знать.', 16642,1,0,1, '67234'), +(-1594472, 'You will not escape me that easily, Arthas! I will have my vengeance!', 'Ты так просто от меня не уйдешь Артас. Я отомщу тебе!', 17057,1,0,1, '67234'), +(-1594473, '', 'Глупая девчонка! Тот кого ты ищещь давно убит! Теперь он лишь призрак, слабый отзвук в моем сознании!', 17229,1,0,0, '67234'), +(-1594474, '', 'Я не повторю прежней ошибки, Сильвана. На этот раз тебе не спастись. Ты не оправдала моего доверия и теперь тебя ждет только забвение!', 17228,1,0,0, '67234'), +(-1594475, 'As you wish, my lord.', 'Как пожелаете, мой господин!', 16717,1,0,0, '67234'), +(-1594476, 'As you wish, my lord.', 'Как пожелаете, мой господин!', 16741,1,0,0, '67234'), +# SCENE - Hall Of Reflection (Extro) - PreEscape +(-1594477, 'Your allies have arrived, Jaina, just as you promised. You will all become powerful agents of the Scourge.', 'Твои союзники прибыли, Джайна! Как ты и обещала... Ха-ха-ха-ха... Все вы станете могучими солдатами Плети...', 17212,1,0,0, '67234'), +(-1594478, 'I will not make the same mistake again, Sylvanas. This time there will be no escape. You will all serve me in death!', 'Я не повторю прежней ошибки, Сильвана! На этот раз тебе не спастись. Вы все будите служить мне после смерти...', 17213,1,0,0, '67234'), +(-1594479, 'He is too powerful, we must leave this place at once! My magic will hold him in place for only a short time! Come quickly, heroes!', 'Он слишком силен. Мы должны выбраться от сюда как можно скорее. Моя магия задержит его ненадолго, быстрее герои...', 16644,0,0,1, '67234'), +(-1594480, 'He\'s too powerful! Heroes, quickly, come to me! We must leave this place immediately! I will do what I can do hold him in place while we flee.', 'Он слишком силен. Герои скорее, за мной. Мы должны выбраться отсюда немедленно. Я постараюсь его задержать, пока мы будем убегать.', 17058,0,0,1, '67234'), +# SCENE - Hall Of Reflection (Extro) - Escape +(-1594481, 'Death\'s cold embrace awaits.', 'Смерть распростерла ледяные обьятия!', 17221,1,0,0, '67234'), +(-1594482, 'Rise minions, do not left them us!', 'Восстаньте прислужники, не дайте им сбежать!', 17216,1,0,0, '67234'), +(-1594483, 'Minions sees them. Bring their corpses back to me!', 'Схватите их! Принесите мне их тела!', 17222,1,0,0, '67234'), +(-1594484, 'No...', 'Надежды нет!', 17214,1,0,0, '67234'), +(-1594485, 'All is lost!', 'Смирись с судьбой.', 17215,1,0,0, '67234'), +(-1594486, 'There is no escape!', 'Бежать некуда!', 17217,1,0,0, '67234'), +(-1594487, 'I will destroy this barrier. You must hold the undead back!', 'Я разрушу эту преграду, а вы удерживайте нежить на расстоянии!', 16607,1,0,0, '67234'), +(-1594488, 'No wall can hold the Banshee Queen! Keep the undead at bay, heroes! I will tear this barrier down!', 'Никакие стены не удержат Королеву Баньши. Держите нежить на расстоянии, я сокрушу эту преграду.', 17029,1,0,0, '67234'), +(-1594489, 'Another ice wall! Keep the undead from interrupting my incantation so that I may bring this wall down!', 'Опять ледяная стена... Я разобью ее, только не дайте нежити прервать мои заклинания...', 16608,1,0,0, '67234'), +(-1594490, 'Another barrier? Stand strong, champions! I will bring the wall down!', 'Еще одна преграда. Держитесь герои! Я разрушу эту стену!', 17030,1,0,0, '67234'), +(-1594491, 'Succumb to the chill of the grave.', 'Покоритесь Леденящей смерти!', 17218,1,0,0, '67234'), +(-1594492, 'Another dead end.', 'Вы в ловушке!', 17219,1,0,0, '67234'), +(-1594493, 'How long can you fight it?', 'Как долго вы сможете сопротивляться?', 17220,1,0,0, '67234'), +(-1594494, '', 'Он с нами играет. Я покажу ему что бывает когда лед встречается со огнем!', 16609,0,0,0, '67234'), +(-1594495, 'Your barriers can\'t hold us back much longer, monster. I will shatter them all!', 'Твои преграды больше не задержат нас, чудовище. Я смету их с пути!', 16610,1,0,0, '67234'), +(-1594496, 'I grow tired of these games, Arthas! Your walls can\'t stop me!', 'Я устала от этих игр Артас. Твои стены не остановят меня!', 17031,1,0,0, '67234'), +(-1594497, 'You won\'t impede our escape, fiend. Keep the undead off me while I bring this barrier down!', 'Ты не помешаешь нам уйти, монстр. Сдерживайте нежить, а я уничтожу эту преграду.', 17032,1,0,0, '67234'), +(-1594498, 'There\'s an opening up ahead. GO NOW!', 'Я вижу выход, скорее!', 16645,1,0,0, '67234'), +(-1594499, 'We\'re almost there... Don\'t give up!', 'Мы почти выбрались, не сдавайтесь!', 16646,1,0,0, '67234'), +(-1594500, 'There\'s an opening up ahead. GO NOW!', 'Я вижу выход, скорее!', 17059,1,0,0, '67234'), +(-1594501, 'We\'re almost there! Don\'t give up!', 'Мы почти выбрались, не сдавайтесь!', 17060,1,0,0, '67234'), +(-1594502, 'It... It\'s a dead end. We have no choice but to fight. Steel yourself heroes, for this is our last stand!', 'Больше некуда бежать. Теперь нам придется сражаться. Это наша последняя битва!', 16647,1,0,0, '67234'), +(-1594503, 'BLASTED DEAD END! So this is how it ends. Prepare yourselves, heroes, for today we make our final stand!', 'Проклятый тупик, значит все закончится здесь. Готовьтесь герои, это наша последняя битва.', 17061,1,0,0, '67234'), +(-1594504, 'Nowhere to run! You\'re mine now...', 'Ха-ха-ха... Бежать некуда. Теперь вы мои!', 17223,1,0,0, '67234'), +(-1594505, 'Soldiers of Lordaeron, rise to meet your master\'s call!', 'Солдаты Лордерона, восстаньте по зову Господина!', 16714,1,0,0, '67234'), +(-1594506, 'The master surveyed his kingdom and found it... lacking. His judgement was swift and without mercy. Death to all!', 'Господин осмотрел свое королевство и признал его негодным! Его суд был быстрым и суровым - предать всех смерти!', 16738,1,0,0, '67234'), + +#Falric +(-1594507, 'Men, women and children... None were spared the master\'s wrath. Your death will be no different.', 'Мужчины, Женщины и дети... Никто не избежал гнева господина. Вы разделите их участь!', 16710,1,0,0, '67234'), +(-1594508, 'Marwyn, finish them...', 'Марвин... Добей их...', 16713,1,0,0, '67234'), +(-1594509, 'Sniveling maggot!', 'Сопливый червяк!', 16711,1,0,0, '67234'), +(-1594510, 'The children of Stratholme fought with more ferocity!', 'Стратхольмские детишки - и те сражались отчаяннее!', 16712,1,0,0, '67234'), +(-1594511, 'Despair... so delicious...', 'Как сладостно отчаянье!', 16715,1,0,0, '67234'), +(-1594512, 'Fear... so exhilarating...', 'Как приятен страх!', 16716,1,0,0, '67234'), + +#Marwyn +(-1594513, 'Death is all that you will find here!', 'Вы найдете здесь лишь смерть!', 16734,1,0,0, '67234'), +(-1594514, 'Yes... Run... Run to meet your destiny... Its bitter, cold embrace, awaits you.', 'Эээээ... Да... Бегите навстречу судьбе. Ее жестокие и холодные обьятия ждут вас...', 16737,1,0,0, '67234'), +(-1594515, 'I saw the same look in his eyes when he died. Terenas could hardly believe it. Hahahaha!', 'У Теренаса был такой же взгляд в миг смерти, он никак не мог поверить... Ха-ха-ха-ха-ха...', 16735,1,0,0, '67234'), +(-1594516, 'Choke on your suffering!', 'Захлебнись страданием!', 16736,1,0,0, '67234'), +(-1594517, 'Your flesh shall decay before your very eyes!', 'Вы увидите как разлагается ваша плоть!', 16739,1,0,0, '67234'), +(-1594518, 'Waste away into nothingness!', 'Сгиньте без следа!', 16740,1,0,0, '67234'), + +#FrostWorn General +(-1594519, 'You are not worthy to face the Lich King!', 'Вы недостойны предстать перед Королем - Личом!', 16921,1,0,0, '67234'), +(-1594520, 'Master, I have failed...', 'Господин... Я подвел вас...', 16922,1,0,0, '67234'), + +#add +(-1594531, '', 'Ну теперь-то точно пора сваливать.', 0,0,0,0, '67234'), +(-1594532, '', 'Вот вам сундук за работу.', 0,0,0,0, '67234'), +(-1594533, '', 'И, поскольку корабля с оффа не будет, вот вам портал в Даларан.', 0,0,0,0, '67234'); + +# Gossips +DELETE FROM `gossip_texts` WHERE `entry` BETWEEN -3594540 AND -3594530; +INSERT INTO `gossip_texts` (`entry`, `content_default`, `content_loc8`, `comment`) VALUES +(-3594536, 'Lady Jaina, we are ready for next mission!', 'Джайна, мы готовы!',''), +(-3594537, 'Lady Jaina, Let\'s go!', 'Давай быстрее!', ''), +(-3594538, 'Lady Sylvanas, we are ready for next mission!', 'Сильвана, мы готовы!', ''), +(-3594539, 'Lady Sylvanas, Let\'s go!', 'Поехали!', ''), +(-3594540, 'Let\'s go!', 'Побежали!', ''); + +-- Waipoints to escort event on Halls of reflection + +DELETE FROM script_waypoint WHERE entry=36955; +DELETE FROM script_waypoint WHERE entry=37226; +DELETE FROM script_waypoint WHERE entry=37554; + +INSERT INTO script_waypoint VALUES +-- Jaina + + (36955, 0, 5587.682,2228.586,733.011, 0, 'WP1'), + (36955, 1, 5600.715,2209.058,731.618, 0, 'WP2'), + (36955, 2, 5606.417,2193.029,731.129, 0, 'WP3'), + (36955, 3, 5598.562,2167.806,730.918, 0, 'WP4 - Summon IceWall 01'), + (36955, 4, 5556.436,2099.827,731.827, 0, 'WP5 - Spell Channel'), + (36955, 5, 5543.498,2071.234,731.702, 0, 'WP6'), + (36955, 6, 5528.969,2036.121,731.407, 0, 'WP7'), + (36955, 7, 5512.045,1996.702,735.122, 0, 'WP8'), + (36955, 8, 5504.490,1988.789,735.886, 0, 'WP9 - Spell Channel'), + (36955, 9, 5489.645,1966.389,737.653, 0, 'WP10'), + (36955, 10, 5475.517,1943.176,741.146, 0, 'WP11'), + (36955, 11, 5466.930,1926.049,743.536, 0, 'WP12'), + (36955, 12, 5445.157,1894.955,748.757, 0, 'WP13 - Spell Channel'), + (36955, 13, 5425.907,1869.708,753.237, 0, 'WP14'), + (36955, 14, 5405.118,1833.937,757.486, 0, 'WP15'), + (36955, 15, 5370.324,1799.375,761.007, 0, 'WP16'), + (36955, 16, 5335.422,1766.951,767.635, 0, 'WP17 - Spell Channel'), + (36955, 17, 5311.438,1739.390,774.165, 0, 'WP18'), + (36955, 18, 5283.589,1703.755,784.176, 0, 'WP19'), + (36955, 19, 5260.400,1677.775,784.301, 3000, 'WP20'), + (36955, 20, 5262.439,1680.410,784.294, 0, 'WP21'), + (36955, 21, 5260.400,1677.775,784.301, 0, 'WP22'), + +-- Sylvana + + (37554, 0, 5587.682,2228.586,733.011, 0, 'WP1'), + (37554, 1, 5600.715,2209.058,731.618, 0, 'WP2'), + (37554, 2, 5606.417,2193.029,731.129, 0, 'WP3'), + (37554, 3, 5598.562,2167.806,730.918, 0, 'WP4 - Summon IceWall 01'), + (37554, 4, 5556.436,2099.827,731.827, 0, 'WP5 - Spell Channel'), + (37554, 5, 5543.498,2071.234,731.702, 0, 'WP6'), + (37554, 6, 5528.969,2036.121,731.407, 0, 'WP7'), + (37554, 7, 5512.045,1996.702,735.122, 0, 'WP8'), + (37554, 8, 5504.490,1988.789,735.886, 0, 'WP9 - Spell Channel'), + (37554, 9, 5489.645,1966.389,737.653, 0, 'WP10'), + (37554, 10, 5475.517,1943.176,741.146, 0, 'WP11'), + (37554, 11, 5466.930,1926.049,743.536, 0, 'WP12'), + (37554, 12, 5445.157,1894.955,748.757, 0, 'WP13 - Spell Channel'), + (37554, 13, 5425.907,1869.708,753.237, 0, 'WP14'), + (37554, 14, 5405.118,1833.937,757.486, 0, 'WP15'), + (37554, 15, 5370.324,1799.375,761.007, 0, 'WP16'), + (37554, 16, 5335.422,1766.951,767.635, 0, 'WP17 - Spell Channel'), + (37554, 17, 5311.438,1739.390,774.165, 0, 'WP18'), + (37554, 18, 5283.589,1703.755,784.176, 0, 'WP19'), + (37554, 19, 5260.400,1677.775,784.301, 3000, 'WP20'), + (37554, 20, 5262.439,1680.410,784.294, 0, 'WP21'), + (37554, 21, 5260.400,1677.775,784.301, 0, 'WP22'), + +-- Lich King + + (37226, 0, 5577.187,2236.003,733.012, 0, 'WP1'), + (37226, 1, 5587.682,2228.586,733.011, 0, 'WP2'), + (37226, 2, 5600.715,2209.058,731.618, 0, 'WP3'), + (37226, 3, 5606.417,2193.029,731.129, 0, 'WP4'), + (37226, 4, 5598.562,2167.806,730.918, 0, 'WP5'), + (37226, 5, 5559.218,2106.802,731.229, 0, 'WP6'), + (37226, 6, 5543.498,2071.234,731.702, 0, 'WP7'), + (37226, 7, 5528.969,2036.121,731.407, 0, 'WP8'), + (37226, 8, 5512.045,1996.702,735.122, 0, 'WP9'), + (37226, 9, 5504.490,1988.789,735.886, 0, 'WP10'), + + (37226, 10, 5489.645,1966.389,737.653, 0, 'WP10'), + (37226, 11, 5475.517,1943.176,741.146, 0, 'WP11'), + (37226, 12, 5466.930,1926.049,743.536, 0, 'WP12'), + (37226, 13, 5445.157,1894.955,748.757, 0, 'WP13'), + (37226, 14, 5425.907,1869.708,753.237, 0, 'WP14'), + (37226, 15, 5405.118,1833.937,757.486, 0, 'WP15'), + (37226, 16, 5370.324,1799.375,761.007, 0, 'WP16'), + (37226, 17, 5335.422,1766.951,767.635, 0, 'WP17'), + (37226, 18, 5311.438,1739.390,774.165, 0, 'WP18'), + (37226, 19, 5283.589,1703.755,784.176, 0, 'WP19'), + (37226, 20, 5278.694,1697.912,785.692, 0, 'WP20'), + (37226, 21, 5283.589,1703.755,784.176, 0, 'WP19'); diff --git a/addition/723_icecrown_down_spelltable_scriptdev2.sql b/addition/723_icecrown_down_spelltable_scriptdev2.sql new file mode 100644 index 000000000..b01b87b1b --- /dev/null +++ b/addition/723_icecrown_down_spelltable_scriptdev2.sql @@ -0,0 +1,53 @@ +-- Icecrown down spelltable + +-- Boss Bronjahm +DELETE FROM `boss_spell_table` WHERE `entry` = 36497; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(36497, 68793, 0, 3000, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(36497, 36535, 0, 30000, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, NULL), +(36497, 68839, 0, 15000, 0, 25000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(36497, 68858, 0, 1000, 0, 3000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(36497, 68988, 0, 1000, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(36497, 68950, 0, 8000, 0, 12000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(36497, 68872, 0, 1000, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(36497, 68921, 0, 360001, 0, 360001, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 12, 0, 0, 0, NULL), +(36497, 70043, 0, 2000, 0, 6000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL); + +-- Spiritual reflection +DELETE FROM `boss_spell_table` WHERE `entry` = 37068; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(37068, 69933, 0, 4000, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(37068, 69900, 0, 6000, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL); + +-- HOR undead warriors +DELETE FROM `boss_spell_table` WHERE `entry` = 36941; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(36941, 70144, 0, 15000, 0, 25000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(36941, 70080, 0, 4000, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(36941, 70145, 0, 10000, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +DELETE FROM `boss_spell_table` WHERE `entry` = 37069; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(37069, 40505, 0, 5000, 0, 10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL); + +DELETE FROM `boss_spell_table` WHERE `entry` = 36940; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(36940, 70150, 0, 5000, 0, 10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL); + +-- Boss Falric +DELETE FROM `boss_spell_table` WHERE `entry` = 38112; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(38112, 72395, 0, 1000, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(38112, 72426, 0, 15000, 0, 25000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, -1594511, NULL), +(38112, 72435, 0, 25000, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1594512, NULL), +(38112, 72422, 0, 7000, 0, 14000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(38112, 47008, 0, 180000, 0, 180000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +-- Boss Marwin +DELETE FROM `boss_spell_table` WHERE `entry` = 38113; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(38113, 72360, 0, 8000, 0, 12000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(38113, 72368, 0, 15000, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(38113, 72362, 0, 25000, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, -1594518, NULL), +(38113, 72436, 0, 10000, 0, 16000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1594518, NULL), +(38113, 47008, 0, 180000, 0, 180000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); diff --git a/addition/724_trial_of_crusader_mangos.sql b/addition/724_trial_of_crusader_mangos.sql new file mode 100644 index 000000000..494aef1d9 --- /dev/null +++ b/addition/724_trial_of_crusader_mangos.sql @@ -0,0 +1,129 @@ +-- instance +UPDATE `instance_template` SET `ScriptName`='instance_trial_of_the_crusader' WHERE `map`=649; +DELETE FROM `creature` WHERE `map` = 649 AND `id` IN +(34797,34796,34799,35144,34780,34460,34463,34461,34471,34475,34472,34453,34455,34458,34454,34451,34456,34497,34496,34564,34467,35465,34468,35610,34473,34474,34441,34449,34448,34450,34606, 34605, 34607, 34564); + +-- announcers +UPDATE `creature_template` SET `npcflag`=1, `scriptname`='npc_toc_announcer' WHERE `entry`=34816; +DELETE FROM `creature` WHERE `map` = 649 AND `id` = 35766; + +DELETE FROM `npc_text` WHERE `ID` IN (724001, 724002, 724003, 724004, 724005, 724006); +INSERT INTO `npc_text` (`ID`, `Text0_0`) VALUES +(724001, 'Greetings $N! Are you ready to be tested in Crusaders Coliseum?'), +(724002, 'Are you ready for the next stage?'), +(724003, 'Are you ready to fight the champions of the Silver vanguard?'), +(724004, 'Are you ready for the next stage?'), +(724005, 'Are you ready to continue battle with Anub-Arak?'), +(724006, 'Today, the arena is closed. Script dungeon designed specifically for server Pandora http://wow.teletoria.ru (c) /dev/rsa 2010'); + +DELETE FROM `locales_npc_text` WHERE `entry` IN (724001, 724002, 724003, 724004, 724005, 724006); +INSERT INTO `locales_npc_text` (`entry`, `Text0_0_loc1`, `Text0_0_loc2`, `Text0_0_loc3`, `Text0_0_loc4`, `Text0_0_loc5`, `Text0_0_loc6`, `Text0_0_loc7`, `Text0_0_loc8`) VALUES +(724001, 'Greetings $N! Are you ready to be tested in Crusaders Coliseum?', NULL, NULL, NULL, NULL, NULL, NULL, 'Приветствую, $N! Вы готовы пройти Испытание Крестоносца?'), +(724002, 'Are you ready for the next stage?', NULL, NULL, NULL, NULL, NULL, NULL, 'Вы готовы к следующему этапу?'), +(724003, 'Are you ready to fight the champions of the Silver vanguard?', NULL, NULL, NULL, NULL, NULL, NULL, 'Вы готовы драться с чемпионами Серебряного авангарда?'), +(724004, 'Are you ready for the next stage?', NULL, NULL, NULL, NULL, NULL, NULL, 'Вы готовы к следующему этапу?'), +(724005, 'Are you ready to continue battle with Anub-Arak?', NULL, NULL, NULL, NULL, NULL, NULL, 'Вы готовы продолжить бой с Ануб-Араком?'), +(724006, 'Today, the arena is closed. Script dungeon designed specifically for server Pandora http://wow.teletoria.ru (c) /dev/rsa 2010', NULL, NULL, NULL, NULL, NULL, NULL, 'На сегодня арена закрыта. Скрипт инстанса разработан специально для сервера Пандора http://wow.teletoria.ru (c) /dev/rsa 2010'); + +UPDATE `creature_template` SET `scriptname`='boss_lich_king_toc' WHERE `entry`=35877; +UPDATE `creature_template` SET `minhealth`= 20000, `maxhealth` = 20000, `faction_A`= 1770, `faction_H` = 1770, `scriptname`='npc_fizzlebang_toc' WHERE `entry`=35458; +UPDATE `creature_template` SET `flags_extra`=0 WHERE `entry` IN (22517, 35651); +DELETE FROM `creature` WHERE `map` = 649 AND `id` IN (35651, 22517); + +UPDATE `creature_template` SET `scriptname`='npc_tirion_toc' WHERE `entry`=34996; +UPDATE `creature_template` SET `scriptname`='npc_garrosh_toc' WHERE `entry`=34995; +UPDATE `creature_template` SET `scriptname`='npc_rinn_toc' WHERE `entry`=34990; + +-- Grand crusaders +UPDATE `creature_template` SET `scriptname`='mob_toc_warrior', `AIName` ='' WHERE `entry` IN (34475,34453); +UPDATE `creature_template` SET `scriptname`='mob_toc_mage', `AIName` ='' WHERE `entry` IN (34468,34449); +UPDATE `creature_template` SET `scriptname`='mob_toc_shaman', `AIName` ='' WHERE `entry` IN (34463,34455); +UPDATE `creature_template` SET `scriptname`='mob_toc_enh_shaman', `AIName` ='' WHERE `entry` IN (34470,34444); +UPDATE `creature_template` SET `scriptname`='mob_toc_hunter', `AIName` ='' WHERE `entry` IN (34467,34448); +UPDATE `creature_template` SET `scriptname`='mob_toc_rogue', `AIName` ='' WHERE `entry` IN (34472,34454); +UPDATE `creature_template` SET `scriptname`='mob_toc_priest', `AIName` ='' WHERE `entry` IN (34466,34447); +UPDATE `creature_template` SET `scriptname`='mob_toc_shadow_priest', `AIName` ='' WHERE `entry` IN (34473,34441); +UPDATE `creature_template` SET `scriptname`='mob_toc_dk', `AIName` ='' WHERE `entry` IN (34461,34458); +UPDATE `creature_template` SET `scriptname`='mob_toc_paladin', `AIName` ='' WHERE `entry` IN (34465,34445); +UPDATE `creature_template` SET `scriptname`='mob_toc_retro_paladin', `AIName` ='' WHERE `entry` IN (34471,34456); +UPDATE `creature_template` SET `scriptname`='mob_toc_druid', `AIName` ='' WHERE `entry` IN (34460,34451); +UPDATE `creature_template` SET `scriptname`='mob_toc_boomkin', `AIName` ='' WHERE `entry` IN (34469,34459); +UPDATE `creature_template` SET `scriptname`='mob_toc_warlock' WHERE `entry` IN (34474,34450); + +UPDATE `creature_template` SET `scriptname`='mob_toc_pet_warlock', `AIName` ='' WHERE `entry` IN (35465); +UPDATE `creature_template` SET `scriptname`='mob_toc_pet_hunter', `AIName` ='' WHERE `entry` IN (35610); + +UPDATE `creature_template` SET `lootid`= 0 WHERE `entry` IN +(34460,34463,34461,34471,34475,34472,34453,34455,34458,34454,34451,34456,34467,35465,34468,35610,34473,34474,34441,34449,34448,34450); +UPDATE `creature_template` SET `lootid`= 0 WHERE `entry` IN +(12266,12209,12212,12281,12190,12284,12269,12272,12229,12187,12091,12088,12169,12103,12106,12112,12166,12163,12175,12183,12303,12300); +UPDATE `creature_template` SET `lootid`= 0 WHERE `entry` IN +(12267,12210,12213,12282,12191,12285,12270,12273,12230,12188,12092,12089,12170,12104,12107,12113,12167,12164,12181,12184,12304,12301); +UPDATE `creature_template` SET `lootid`= 0 WHERE `entry` IN +(12268,12211,12214,12283,12192,12286,12271,12274,12231,12189,12093,12090,12171,12105,12108,12114,12168,12165,12182,12185,12305,12302); + +-- N10 +DELETE FROM `creature_loot_template` WHERE `entry` IN +(34460,34463,34461,34471,34475,34472,34453,34455,34458,34454,34451,34456,34467,35465,34468,35610,34473,34474,34441,34449,34448,34450); +-- H10 +DELETE FROM `creature_loot_template` WHERE `entry` IN +(12266,12209,12212,12281,12190,12284,12269,12272,12229,12187,12091,12088,12169,12103,12106,12112,12166,12163,12175,12183,12303,12300); +-- N25 +DELETE FROM `creature_loot_template` WHERE `entry` IN +(12267,12210,12213,12282,12191,12285,12270,12273,12230,12188,12092,12089,12170,12104,12107,12113,12167,12164,12181,12184,12304,12301); +-- H25 +DELETE FROM `creature_loot_template` WHERE `entry` IN +(12268,12211,12214,12283,12192,12286,12271,12274,12231,12189,12093,12090,12171,12105,12108,12114,12168,12165,12182,12185,12305,12302); + +-- Nortrend beasts +DELETE FROM `creature_ai_scripts` WHERE `creature_id` IN (34796, 34799, 35144, 34797); +UPDATE `creature_template` SET `scriptname`='boss_gormok', `AIName` ='' WHERE `entry`=34796; +UPDATE `creature_template` SET `scriptname`='mob_snobold_vassal', `AIName` ='' WHERE `entry`=34800; + +UPDATE `creature_template` SET `scriptname`='boss_dreadscale', `AIName` ='' WHERE `entry`=34799; +UPDATE `creature_template` SET `scriptname`='boss_acidmaw', `AIName` ='' WHERE `entry`=35144; +UPDATE `creature_template` SET `scriptname`='mob_slime_pool', `minlevel` = 80, `maxlevel` = 80, `minhealth`= 30000, `maxhealth` = 30000,`AIName` ='', `faction_A`= 14, `faction_H` = 14, `modelid_1` = 11686, `modelid_3` = 11686 WHERE `entry` = 35176; + +UPDATE `creature_template` SET `scriptname`='boss_icehowl', `AIName` ='' WHERE `entry`=34797; + +UPDATE `creature_template` SET `lootid`= 0 WHERE `entry` IN (34796,34799,35144); +DELETE FROM `creature_loot_template` WHERE `entry` IN (34796,34799,35144); + +-- Jaraxxus +UPDATE `creature_template` SET `scriptname`='boss_jaraxxus', `AIName` ='' WHERE `entry`= 34780; +DELETE FROM `creature_ai_scripts` WHERE `creature_id` IN (34780, 34784, 34813, 34815, 34825, 34826); +UPDATE `creature_template` SET `scriptname`='mob_legion_flame', `minlevel` = 82, `maxlevel` = 82, `modelid_1` = 11686, `modelid_2` = 11686, `modelid_3` = 11686, `modelid_4` = 11686, `AIName` ='', `faction_A`= 14, `faction_H` = 14 WHERE `entry` = 34784; +UPDATE `creature_template` SET `scriptname`='mob_infernal_volcano', `AIName` ='' WHERE `entry` = 34813; +UPDATE `creature_template` SET `scriptname`='mob_fel_infernal', `AIName` ='' WHERE `entry` = 34815; +UPDATE `creature_template` SET `scriptname`='mob_nether_portal', `AIName` ='' WHERE `entry` = 34825; +UPDATE `creature_template` SET `scriptname`='mob_mistress_of_pain', `AIName` ='' WHERE `entry` = 34826; + +-- Valkiries +UPDATE `creature_template` SET `scriptname` = 'boss_fjola', `AIName` ='' WHERE `entry`=34497; +UPDATE `creature_template` SET `scriptname` = 'boss_eydis', `AIName` ='' WHERE `entry`=34496; +DELETE FROM `creature_ai_scripts` WHERE `creature_id` IN (34497, 34496, 34568, 34567); +UPDATE `creature_template` SET `npcflag`=1, `scriptname`='mob_light_essence', `AIName` ='' WHERE entry = 34568; +UPDATE `creature_template` SET `npcflag`=1, `scriptname`='mob_dark_essence', `AIName` ='' WHERE entry = 34567; +UPDATE `creature_template` SET `faction_A` = 14, `minlevel` = 82, `maxlevel` = 82,`faction_H` = 14, `AIName` ='', `scriptname`='mob_unleashed_dark' WHERE entry = 34628; +UPDATE `creature_template` SET `faction_A` = 14, `minlevel` = 82, `maxlevel` = 82,`faction_H` = 14, `AIName` ='', `scriptname`='mob_unleashed_light' WHERE entry = 34630; +-- Twin pact by Wowka321 +DELETE FROM `spell_script_target` WHERE `entry` IN (65875,67303,67304,67305,65876,67306,67307,67308); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +('65875', '1', '34497'), +('67303', '1', '34497'), +('67304', '1', '34497'), +('67305', '1', '34497'), +('65876', '1', '34496'), +('67306', '1', '34496'), +('67307', '1', '34496'), +('67308', '1', '34496'); + +-- Anub'arak +UPDATE `creature_template` SET `scriptname`='boss_anubarak_trial', `unit_flags` = 0, `AIName` ='' WHERE `entry`=34564; + +DELETE FROM `creature_ai_scripts` WHERE `creature_id` IN (34606, 34605, 34607, 34564, 34660); +UPDATE `creature_template` SET `modelid_1` = 25144, `modelid_2` = 0, `modelid_3` = 25144, `modelid_4` = 0, `faction_A` = 14, `faction_H` = 14, `AIName` = '', `ScriptName` = 'mob_frost_sphere' WHERE `entry` = 34606; +UPDATE `creature_template` SET `scriptname`='mob_swarm_scarab', `AIName` ='' WHERE `entry`=34605; +UPDATE `creature_template` SET `scriptname`='mob_nerubian_borrower', `AIName` ='' WHERE `entry`=34607; +UPDATE `creature_template` SET `scriptname`='mob_anubarak_spike', `faction_A` = 14, `minlevel` = 80, `maxlevel` = 80,`faction_H` = 14, `AIName` ='' WHERE `entry`=34660; + diff --git a/addition/724_trial_of_crusader_scriptdev2.sql b/addition/724_trial_of_crusader_scriptdev2.sql new file mode 100644 index 000000000..0e4421ce8 --- /dev/null +++ b/addition/724_trial_of_crusader_scriptdev2.sql @@ -0,0 +1,83 @@ +-- TOC original texts/sounds (thanks to griffonheart) +-- english translation by Cristy +-- reworked by rsa + +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1713799 AND -1713499; +INSERT INTO `script_texts` +(`comment`,`sound`, `entry`,`content_loc8`,`type`,`language`,`emote`,`content_default`) VALUES +('34996','16036','-1713500','Добро пожаловать, герои! Вы услышали призыв Серебряного Авангарда и без колебаний откликнулись на него! В этом колизее вам предстоит сразиться с опаснейшими противниками. Те из вас, кто смогут пережить испытания, войдут в ряды Серебряного Авангарда, который направится в Цитадель Ледяной Короны.','6','0','0','Welcome champions, you have heard the call of the argent crusade and you have boldly answered. It is here in the crusaders coliseum that you will face your greatest challenges. Those of you who survive the rigors of the coliseum will join the Argent Crusade on its marsh to ice crown citadel.'), +('34996','16038','-1713501','Из самых глубоких и темных пещер Грозовой Гряды был призван Гормок Пронзающий Бивень! В бой, герои!','6','0','0','Hailing from the deepest, darkest carverns of the storm peaks, Gormok the Impaler! Battle on, heroes!'), +('34990','16069','-1713502','Твои чудовища не чета героям Альянса, Тирион!','6','0','0','Your beast will be no match for my champions Tirion!'), +('34995','16026','-1713702','Я видел и более достойных соперников в багровом круге. Ты напрасно тратишь наше время, паладин.','6','0','0','Your beast will be no match for my champions Tirion!'), +('34796','0','-1713601','Мои рабы! Уничтожьте врага!','3','0','0','My slaves! Destroy the enemy!'), +('34996','16039','-1713503','Приготовьтесь к схватке с близнецами-чудовищами, Кислотной Утробой и Жуткой Чешуей!','6','0','0','Steel yourselves, heroes, for the twin terrors Acidmaw and Dreadscale. Enter the arena!'), +('34799','0','-1713504','После гибели товарища %s приходит в ярость!','3','0','0','After the death of sister %s goes berserk!'), +('34996','16040','-1713505','В воздухе повеяло ледяным дыханием следующего бойца: на арену выходит Ледяной Рев! Сражайтесь или погибните, чемпионы!','6','0','0','The air freezes with the introduction of our next combatant, Icehowl! Kill or be killed, champions!'), +('34797','0','-1713506','%s глядит на |3-3($n) и испускает гортанный вой!','3','0','0','%S looks at |3-3($n) and emits a guttural howl!'), +('34797','0','-1713507','%s врезается в стену Колизея и теряет ориентацию!','3','0','0','%S crashes into a wall of the Colosseum and lose focus!'), +('34797','0','-1713508','|3-3(%s) охватывает кипящая ярость, и он растаптывает всех на своем пути!','3','0','0','|3-3(%s) covers boiling rage, and he tramples all in its path!'), +('34996','16041','-1713509','Все чудовища повержены!','6','0','0','All the monsters defeated!'), +('34996','16042','-1713709','Прискорбно. Как яростно они не бились, чудовища Нордскола оказались сильнее. Почтим память павших героев минутой молчания.','6','0','0',''), +('34996','16043','-1713510','Сейчас великий чернокнижник Вилфред Непопамс призовет вашего нового противника. Готовьтесь к бою!','6','0','0','Grand Warlock Wilfred Fizzlebang will summon forth your next challenge. Stand by for his entry!'), +('35458','16268','-1713511','Благодарю, Верховный лорд. А теперь, смельчаки, я приступаю к ритуалу призыва. Когда я закончу, появится грозный демон!','6','0','0','Thank you, Highlord! Now challengers, I will begin the ritual of summoning! When I am done, a fearsome Doomguard will appear!'), +('35458','16269','-1713512','Готовьтесь к забвению!','6','0','0','Prepare for oblivion!'), +('35458','16270','-1713513','АГА! Получилось! Трепещи перед всевластным Вилфредом Непопамсом, мастером призыва! Ты покорен мне, демон!','6','0','0','Ah ha! Behold the absolute power of Wilfred Fizzlebang, master summoner! You are bound to ME, demon!'), +('34780','16143','-1713514','Ничтожный гном! Тебя погубит твоя самоуверенность!','6','0','0','Trifling gnome, your arrogance will be your undoing!'), +('35458','16271','-1713515','Тут я главный!','6','0','0','But I am in charge here-'), +('35458','0','-1713715','Ну вот, опять я облажался...','6','0','0','Agonized Scream!!!'), +('34996','16044','-1713516','Быстрей, герои, расправьтесь с повелителем демонов, прежде чем он откроет портал в свое темное царство!','6','0','0','Quickly, heroes! Destroy the demon lord before it can open a portal to its twisted demonic realm!'), +('34780','16144','-1713517','Перед вами Джараксус, эредарский повелитель Пылающего Легиона!','6','0','0','You face Jaraxxus, eredar lord of the Burning Legion!'), +('34780','0','-1713518','На вас направлено |cFFFF0000Пламя Легиона!|r','3','0','0','You have been sent |cFFFF0000Plamya Legion!|R'), +('34780','0','-1713519','%s создает врата Пустоты!','3','0','0','%S creates the gates of the Void!'), +('34780','0','-1713520','%s создает |cFF00FF00Вулкан инферналов!|r','3','0','0','%S creates |cFF00FF00Vulkan Infernals!|R'), +('34780','16150','-1713521','Явись, сестра! Господин зовет!','6','0','0','Come forth, sister! Your master calls!'), +('34780','0','-1713522','$n $gподвергся:подверглась; |cFF00FFFFИспепелению плоти!|r Исцелите $gего:ее;!','3','0','0','$N $gpodvergsya:been; |cFF00FFFFIspepeleniyu flesh!|R Heal $gego:it;!'), +('34780','16149','-1713523','ПЛОТЬ ОТ КОСТИ!','6','0','0','FLESH FROM BONE!'), +('34780','16151','-1713524','ИНФЕРНАЛ!','6','0','0','INFERNO!'), +('34780','16147','-1713525','Мое место займут другие. Ваш мир обречен...','6','0','0','Another will take my place. Your world is doomed.'), +('34996','16045','-1713526','Гибель Вилфреда Непопамса весьма трагична и должна послужить уроком тем, кто смеет беспечно играть с темной магией. К счастью, вы победили демона, и теперь вас ждет новый противник.','6','0','0','The loss of Wilfred Fizzlebang, while unfortunate, should be a lesson to those that dare dabble in dark magic. Alas, you are victorious and must now face the next challenge.'), +('34995','16021','-1713527','Подлые собаки Альянса! Вы выпустили повелителя демонов на воинов Орды? Ваша смерть будет быстрой!','6','0','0','Treacherous Alliance dogs! You summon a demon lord against warriors of the Horde!? Your deaths will be swift!'), +('34990','16064','-1713528','Альянсу не нужна помощь повелителя демонов, чтобы справиться с ордынским отродьем, пес!','6','0','0','The Alliance doesnt need the help of a demon lord to deal with Horde filth. Come, pig!'), +('34996','16046','-1713529','Тише! Успокойтесь! Никакого заговора здесь нет. Чернокнижник заигрался и поплатился за это. Турнир продолжается!','6','0','0','Everyone, calm down! Compose yourselves! There is no conspiracy at play here. The warlock acted on his own volition - outside of influences from the Alliance. The tournament must go on!'), +('34996','16047','-1713530','В следующем бою вы встретитесь с могучими рыцарями Серебряного Авангарда! Лишь победив их, вы заслужите достойную награду.','6','0','0','The next battle will be against the Argent Crusades most powerful knights! Only by defeating them will you be deemed worthy...'), +('34995','16023','-1713531','Орда требует справедливости! Мы вызываем Альянс на бой! Позволь нам встать на место твоих рыцарей, паладин. Мы покажем этим псам, как оскорблять Орду!','6','0','0','The Horde demands justice! We challenge the Alliance. Allow us to battle in place of your knights, paladin. We will show these dogs what it means to insult the Horde!'), +('34995','16066','-1713731','Они хотели запятнать честь Альянса, они пытались нас оклеветать! Я требую справедливости! Тириорн, позволь моим чемпионам сражаться вместо твоих рыцарей. Мы бросаем вызов Орде!','6','0','0','Our honor has been besmirched! They make wild claims and false accusations against us. I demand justice! Allow my champions to fight in place of your knights, Tirion. We challenge the Horde!'), +('34996','16048','-1713532','Хорошо. Да будет так. Сражайтесь с честью!','','0','0','Very well, I will allow it. Fight with honor!'), +('34995','16022','-1713533','Не щадите никого, герои Орды! ЛОК-ТАР ОГАР!','6','0','0','Show them no mercy, Horde champions! LOK-TAR OGAR!'), +('34995','16065','-1713733','Сражайтесь во славу Альянса, герои! Во имя вашего короля!','6','0','0','Fight for the glory of the Alliance, heroes! Honor your king and your people!'), +('34990','16067','-1713534','СЛАВА АЛЬЯНСУ!','6','0','0','GLORY OF THE ALLIANCE!'), +('34990','16024','-1713734','Это было лишь пробой того, что ждёт нас в будущем. За Орду!','6','0','0','LOK-TAR OGAR!'), +('34996','16049','-1713535','Пустая и горькая победа. После сегодняшних потерь мы стали слабее как целое. Кто еще, кроме Короля-лича, выиграет от подобной глупости? Пали великие воины. И ради чего? Истинная опасность еще впереди - нас ждет битва с Королем-личом.','6','0','0','A shallow and tragic victory. We are weaker as a whole from the losses suffered today. Who but the Lich King could benefit from such foolishness? Great warriors have lost their lives. And for what? The true threat looms ahead - the Lich King awaits us all in death.'), +('34996','16050','-1713536','Лишь сплотившись, вы сможете пройти последнее испытание. Из глубин Ледяной Короны навстречу вам подымаются две могучие воительницы Плети: жуткие валькирии, крылатые вестницы Короля-лича!','6','0','0','Only by working together will you overcome the final challenge. From the depths of Icecrown come two of the Scourges most powerful lieutenants: fearsome valkyr, winged harbingers of the Lich King!'), +('34996','16037','-1713537','Пусть состязания начнутся!','6','0','0','Let the games begin!'), +('34497','0','-1713538','%s начинает читать заклинание|cFFFFFFFFСветлая воронка!|r Переключение к |cFFFFFFFFСветлой|r сущности!','3','0','0','%S begins to read a spell |cFFFFFFFFSvetlaya funnel!|R switch to |cFFFFFFFFSvetloy|r essence!'), +('34497','0','-1713539','%s начинает читать заклинание Договор близнецов!','3','0','0','%S begins to read the spell Treaty twins!'), +('34496','0','-1713540','%s начинает читать заклинание |cFF9932CDТемная воронка!|r Переключение к |cFF9932CDТемной|r сущности!','3','0','0','%S begins to read a spell |cFF9932CDTemnaya funnel!|R switch to |cFF9932CDTemnoy|r essence!'), +('34497','16272','-1713541','Во имя темного повелителя. Во имя Короля-лича. Вы. Умрете.','6','0','0','In the name of our dark master. For the Lich King. You. Will. Die.'), +('34496','16272','-1713741','Во имя светлого повелителя. Во имя Короля-лича. Вы. Умрете.','6','0','0','In the name of our dark master. For the Lich King. You. Will. Die.'), +('34496','16279','-1713542','Да поглотит вас Свет!','6','0','0','Let the light consume you!'), +('34496','16277','-1713543','Пустое место!','6','0','0','Empty place!'), +('34497','16276','-1713544','Тебя оценили и признали ничтожеством.','6','0','0','You appreciated and acknowledged nothing.'), +('34497','16274','-1713545','ХАОС!','3','0','0','CHAOS!'), +('34496','16278','-1713546','Да поглотит вас Тьма!','6','0','0','Let the dark consume you!'), +('34496','16275','-1713547','Плеть не остановить...','6','0','0','The Scourge cannot be stopped...'), +('34990','16068','-1713548','Против Альянса не выстоять даже самым сильным прислужникам Короля-лича! Все славьте наших героев!','6','0','0','Against the Alliance can not stand even the most powerful henchmen of the Lich King! All glorify our heroes!'), +('34995','16025','-1713748','Ты все еще сомневаешься в могуществе Орды, паладин? Мы примем любой вызов!','6','0','0','Against the Horde does not withstand even the most powerful henchmen of the Lich King! All glorify our heroes!'), +('34996','16051','-1713549','Король-лич понес тяжелую потерю! Вы проявили себя как бесстрашные герои Серебряного Авангарда! Мы вместе нанесем удар по Цитадели Ледяной Короны и разнесем в клочья остатки Плети! Нет такого испытания, которое мы бы не могли пройти сообща!','6','0','0','A mighty blow has been dealt to the Lich King! You have proven yourselves able bodied champions of the Argent Crusade. Together we will strike at Icecrown Citadel and destroy what remains of the Scourge! There is no challenge that we cannot face united!'), +('16980','16321','-1713550','Будет тебе такое испытание, Фордринг.','6','0','0','You will have your challenge, Fordring.'), +('34996','16052','-1713551','Артас! Нас гораздо больше! Сложи Ледяную Скорбь, и я подарю тебе заслуженную смерть.','6','0','0','Arthas! You are hopelessly outnumbered! Lay down Frostmourne and I will grant you a just death.'), +('35877','16322','-1713552','Нерубианцы воздвигли целую империю под льдами Нордскола. Империю, на которой вы так бездумно построили свои дома. МОЮ ИМПЕРИЮ.','6','0','0','The Nerubians built an empire beneath the frozen wastes of Northrend. An empire that you so foolishly built your structures upon. MY EMPIRE.'), +('16980','16323','-1713553','Души твоих павших чемпионов будут принадлежать мне, Фордринг.','6','0','0','The souls of your fallen champions will be mine, Fordring.'), +('34564','16235','-1713554','А вот и гости заявились, как и обещал господин.','6','0','0','Ahhh... Our guests arrived, just as the master promised.'), +('34564','16234','-1713555','Это место станет вашей могилой!','3','0','0','This place will serve as your tomb!'), +('34564','16240','-1713556','Ауум на-л ак-к-к-к, ишшш. Вставайте, слуги мои. Время пожирать...','6','0','0','Auum na-l ak-k-k-k, isshhh. Rise, minions. Devour...'), +('34564','0','-1713557','%s зарывается в землю!','3','0','0','%S buries itself in the earth!'), +('34660','0','-1713558','Шипы %s преследуют $n!','3','0','0','%s spikes pursuing $n!'), +('34564','0','-1713559','%s вылезает на поверхность!','3','0','0','%S getting out of the ground!'), +('34564','16241','-1713560','Стая поглотит вас!','6','0','0','The swarm shall overtake you!'), +('34564','0','-1713561','%s выпускает рой жуков-трупоедов, чтобы восстановить здоровье!','3','0','0','%S produces a swarm of beetles Peon to restore your health!'), +('34564','16236','-1713562','Ф-лаккх шир!','6','0','0','F-lakkh shir!'), +('34564','16237','-1713563','Еще одна душа накормит хозяина.','6','0','0','Another soul to sate the host.'), +('34564','16238','-1713564','Я подвел тебя, господин...','6','0','0','I have failed you, master...'), +('36095','0','-1713565','Чемпионы, вы прошли испытание великого крестоносца! Знайте, что только самые сильные искатели приключений могли рассчитывать завершить это испытание.','6','0','0','Champions, you are alive! Not only have you defeated every challenge of the Trial of the Crusader, but thwarted Arthas directly! Your skill and cunning will prove to be a powerful weapon against the Scourge. Well done! Allow one of my mages to transport you back to the surface!'), +('36095','0','-1713566','Позвольте вручить вам эти сундуки в качестве заслуженной награды, и пусть его содержимое послужит вам верой и правдой в походе против Артаса в самом центре Цитадели Ледяной Короны!','6','0','0','Let me hand you the chests as a reward, and let its contents will serve you faithfully in the campaign against Arthas in the heart of the Icecrown Citadel!'); diff --git a/addition/724_trial_of_crusader_spelltable_scriptdev2.sql b/addition/724_trial_of_crusader_spelltable_scriptdev2.sql new file mode 100644 index 000000000..b5bee961a --- /dev/null +++ b/addition/724_trial_of_crusader_spelltable_scriptdev2.sql @@ -0,0 +1,453 @@ +-- Trial of the crusader spelltable +DELETE FROM `boss_spell_table` WHERE `entry` IN +(34496,34497,34564,34605,34607,34780,34784,34796,34797,34799, 34800, 34813, 34815, 34826, 35144, 35176, 34606, 34660); + +-- Eydis Darkbane +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34496, 64238, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34496, 65768, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34496, 65874, 0, 0, 0, 15000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34496, 65876, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34496, 65879, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34496, 65916, 0, 0, 0, 15000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34496, 66058, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34496, 66069, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(34496, 67282, 0, 0, 0, 8000, 0, 6000, 0, 12000, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(34496, 34628, 45000, 45000, 1, 1, 2, 2, 10, 100, 0, 11); + +-- Fjola Lightbane +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34497, 64238, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34497, 65766, 67270, 67271, 67272, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34497, 65858, 0, 0, 0, 15000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34497, 65875, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34497, 65879, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34497, 65916, 0, 0, 0, 15000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34497, 66046, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34497, 66075, 0, 0, 0, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(34497, 67297, 0, 0, 0, 8000, 0, 6000, 0, 0, 12000, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL); +-- summons +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `timerMin_N10`, `timerMax_N10`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType` ) VALUES +(34497, 34630, 45000, 45000, 1, 1, 2, 2, 10, 100, 0, 11); + +-- AnubArak +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34564, 26662, 26662, 26662, 26662, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34564, 34605, 0, 0, 0, 90000, 0, 0, 0, 90000, 0, 0, 0, 0, 0, 0, 0, 20.0, 100.0, 0, 0, 0, 0, 9, 1, 0, 0, NULL), +(34564, 34660, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 5.0, 10.0, 0, 0, 0, 0, 9, 1, 0, 0, NULL), +(34564, 34606, 0, 0, 0, 5000, 0, 0, 0, 10000, 0, 0, 0, 0, 0, 0, 0, 10.0, 100.0, 0, 0, 0, 0, 9, 1, 0, 0, NULL), +(34564, 34607, 0, 0, 0, 70000, 0, 0, 0, 90000, 0, 0, 0, 0, 0, 0, 0, 20.0, 100.0, 0, 0, 0, 0, 9, 1, 0, 0, NULL), +(34564, 53421, 53421, 53421, 53421, 45000, 45000, 45000, 45000, 60000, 60000, 60000, 60000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, NULL), +(34564, 66169, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34564, 66012, 66012, 66012, 66012, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34564, 66013, 67700, 68509, 68510, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34564, 66339, 66339, 66339, 66339, 5000, 5000, 5000, 5000, 10000, 10000, 10000, 10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, NULL), +(34564, 67574, 0, 0, 0, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0, NULL), +(34564, 66118, 67630, 68646, 68647, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34564, 66240, 0, 0, 0, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34564, 66125, 0, 0, 0, 10000, 0, 0, 0, 10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34564, 67730, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL); + +-- Anub'arak scarab +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34605, 66092, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34605, 67861, 0, 0, 0, 5000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL); + +-- Cold sphere +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34606, 66193, 67855, 67856, 67857, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL); + +-- Anub'arak spike +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34660, 67574, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(34660, 66193, 67855, 67856, 67857, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34660, 65920, 65921, 65922, 65923, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +-- Nerubian Borrower +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34607, 66129, 66129, 66129, 66129, 10000, 10000, 10000, 10000, 20000, 20000, 20000, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(34607, 67322, 67322, 67322, 67322, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, NULL), +(34607, 67847, 67847, 67847, 67847, 5000, 5000, 5000, 5000, 20000, 20000, 20000, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL); + +-- Jaraxxus +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34780, 26662, 26662, 26662, 26662, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34780, 66197, 68123, 68124, 68125, 30000, 30000, 30000, 30000, 45000, 45000, 45000, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34780, 66237, 67049, 67050, 67051, 40000, 40000, 40000, 40000, 90000, 90000, 40000, 90000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(34780, 66242, 67060, 67060, 67060, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34780, 66264, 66264, 68405, 68405, 60000, 60000, 60000, 60000, 60000, 60000, 60000, 60000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 1, 0, NULL), +(34780, 66528, 66528, 67029, 67029, 15000, 15000, 15000, 15000, 25000, 25000, 25000, 25000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34780, 66532, 66963, 66964, 66965, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34780, 67108, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34780, 66255, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34780, 34825, 0, 0, 0, 60000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 0, 20.0, 80.0, 0, 0, 0, 0, 10, 0, 0, 0, NULL), +(34780, 34813, 0, 0, 0, 60000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 0, 20.0, 60.0, 0, 0, 0, 0, 10, 0, 0, 0, NULL); + +-- NPC Legion flame +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34784, 66199, 68127, 68126, 68128, 30000, 30000, 30000, 30000, 45000, 45000, 45000, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL); + +-- Gormok +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34796, 34800, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 20.0, 80.0, 0, 0, 0, 0, 9, 0, 0, 0, NULL), +(34796, 66331, 67477, 67478, 67479, 8000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34796, 66636, 0, 0, 0, 15000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 1, 0, NULL), +(34796, 67648, 0, 0, 0, 15000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +-- Icehowl +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34797, 66683, 67660, 67661, 67662, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34797, 66689, 67650, 67651, 67652, 25000, 25000, 25000, 25000, 40000, 40000, 40000, 40000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34797, 66734, 0, 0, 0, 4000, 4000, 3000, 3000, 4000, 4000, 3000, 3000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(34797, 66770, 67654, 67655, 67656, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(34797, 66758, 0, 0, 0, 15000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34797, 68667, 0, 0, 0, 8000, 0, 0, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 200.0, 0, 0, 0, 0, 0, 12, 0, 1, 0, NULL), +(34797, 66759, 0, 0, 0, 300000, 0, 0, 0, 300000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34797, 67345, 67663, 67664, 67665, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL); + +-- Dreadscale +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34799, 53421, 0, 0, 0, 40000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34799, 66794, 67644, 67645, 67646, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34799, 66796, 67632, 67633, 67634, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34799, 66821, 66821, 66821, 66821, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34799, 66879, 67624, 67625, 67626, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34799, 66902, 67627, 67628, 67629, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(34799, 66883, 67641, 67642, 67643, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(34799, 35176, 0, 0, 0, 30000, 30000, 45000, 60000, 30000, 30000, 45000, 60000, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 11, 0, 0, 0, NULL), +(34799, 68335, 68335, 68335, 68335, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +-- Snobold vassal +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34800, 66313, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(34800, 66317, 0, 0, 0, 10000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(34800, 66318, 0, 0, 0, 10000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, NULL), +(34800, 66406, 0, 0, 0, 10000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, NULL), +(34800, 66407, 0, 0, 0, 10000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(34800, 66408, 0, 0, 0, 10000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(34800, 66636, 0, 0, 0, 15000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 1, 0, NULL); + +-- Infernal volcano +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34813, 66255, 0, 0, 0, 30000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(34813, 66258, 0, 0, 0, 20000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, NULL); + +-- Fel infernal +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34815, 66494, 66494, 66494, 66494, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34815, 67047, 67047, 67047, 67047, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +-- Mistress of pain +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(34826, 66316, 66316, 66316, 66316, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(34826, 67098, 67098, 67098, 67098, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL); + +-- Acidmaw +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(35144, 53421, 0, 0, 0, 40000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, NULL), +(35144, 66794, 67644, 67645, 67646, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(35144, 66819, 66819, 66819, 66819, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(35144, 66824, 67612, 67613, 67614, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, NULL), +(35144, 66880, 67606, 67607, 67608, 15000, 15000, 15000, 15000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(35144, 66901, 0, 0, 0, 15000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(35144, 66883, 67641, 67642, 67643, 20000, 20000, 20000, 20000, 30000, 30000, 30000, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, NULL), +(35144, 35176, 0, 0, 0, 30000, 30000, 45000, 60000, 30000, 30000, 45000, 60000, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 11, 0, 0, 0, NULL), +(35144, 68335, 68335, 68335, 68335, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +-- Slime pool +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(35176, 63084, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, NULL), +(35176, 66882, 0, 0, 0, 500, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL); + +-- Retro Paladins +DELETE FROM `boss_spell_table` WHERE `entry` IN (34471,34456); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34471, 66011, 0, 180000, 180000, 3), +(34471, 66003, 0, 6000, 18000, 3), +(34471, 66010, 0, 0, 3600001, 1), +(34471, 66006, 0, 10000, 10000, 3), +(34471, 66007, 0, 40000, 40000, 3), +(34471, 66009, 0, 300000, 300000, 1), +(34471, 66005, 68018, 8000, 15000, 3), +(34471, 66008, 0, 60000, 60000, 4), +(34471, 66004, 68021, 10000, 15000, 1); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34456, 66011, 0, 180000, 180000, 3), +(34456, 66003, 0, 6000, 18000, 3), +(34456, 66010, 0, 0, 3600001, 1), +(34456, 66006, 0, 10000, 10000, 3), +(34456, 66007, 0, 40000, 40000, 3), +(34456, 66009, 0, 300000, 300000, 1), +(34456, 66005, 68018, 8000, 15000, 3), +(34456, 66008, 0, 60000, 60000, 4), +(34456, 66004, 68021, 10000, 15000, 1); + +-- Pet's +DELETE FROM `boss_spell_table` WHERE `entry` IN (35465,35610); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(35465, 67518, 0, 15000, 30000, 3), +(35465, 67519, 0, 15000, 30000, 3); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(35610, 67793, 67980, 67981, 67982, 5000, 10000, 3); + +-- Druids +DELETE FROM `boss_spell_table` WHERE `entry` IN (34460,34451); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34460, 66093, 67957, 5000, 15000, 14), +(34460, 66066, 67965, 10000, 20000, 14), +(34460, 66067, 67968, 10000, 20000, 14), +(34460, 66065, 67971, 10000, 20000, 14), +(34460, 66086, 67974, 40000, 90000, 1), +(34460, 65860, 0, 45000, 90000, 1), +(34460, 66068, 0, 15000, 30000, 6), +(34460, 66071, 0, 40000, 80000, 1); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34451, 66093, 67957, 10000, 20000, 14), +(34451, 66066, 67965, 10000, 20000, 14), +(34451, 66067, 67968, 10000, 20000, 14), +(34451, 66065, 67971, 10000, 20000, 14), +(34451, 66086, 67974, 40000, 90000, 1), +(34451, 65860, 0, 45000, 90000, 1), +(34451, 66068, 0, 15000, 30000, 6), +(34451, 66071, 0, 40000, 80000, 1); + +-- Warriors +DELETE FROM `boss_spell_table` WHERE `entry` IN (34475,34453); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34475, 65947, 0, 20000, 30000, 1), +(34475, 65930, 0, 10000, 60000, 3), +(34475, 65926, 0, 6000, 25000, 3), +(34475, 68764, 0, 3000, 25000, 3), +(34475, 65935, 0, 20000, 80000, 3), +(34475, 65924, 0, 30000, 90000, 1), +(34475, 65936, 0, 5000, 25000, 3), +(34475, 65940, 0, 10000, 25000, 3), +(34475, 65932, 0, 30000, 60000, 1); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34453, 65947, 0, 20000, 30000, 1), +(34453, 65930, 0, 10000, 60000, 3), +(34453, 65926, 0, 6000, 25000, 3), +(34453, 68764, 0, 3000, 25000, 3), +(34453, 65935, 0, 20000, 80000, 3), +(34453, 65924, 0, 30000, 90000, 1), +(34453, 65936, 0, 5000, 25000, 3), +(34453, 65940, 0, 10000, 25000, 3), +(34453, 65932, 0, 30000, 60000, 1); + +-- Mage +DELETE FROM `boss_spell_table` WHERE `entry` IN (34468,34449); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34468, 65799, 67995, 3000, 10000, 3), +(34468, 65791, 67998, 5000, 15000, 3), +(34468, 65800, 68001, 5000, 15000, 3), +(34468, 65793, 0, 7000, 25000, 1), +(34468, 65807, 68004, 5000, 15000, 4), +(34468, 65790, 0, 5000, 15000, 6), +(34468, 65792, 0, 7000, 15000, 1), +(34468, 65802, 0, 0, 3600001, 1), +(34468, 65801, 0, 15000, 40000, 4); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34449, 65799, 67995, 3000, 10000, 3), +(34449, 65791, 67998, 5000, 15000, 3), +(34449, 65800, 68001, 5000, 15000, 3), +(34449, 65793, 0, 7000, 25000, 1), +(34449, 65807, 68004, 5000, 15000, 4), +(34449, 65790, 0, 5000, 15000, 6), +(34449, 65792, 0, 7000, 15000, 1), +(34449, 65802, 0, 0, 3600001, 1), +(34449, 65801, 0, 15000, 40000, 4); + +-- Shaman +DELETE FROM `boss_spell_table` WHERE `entry` IN (34463,34455); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34463, 66055, 68115, 5000, 15000, 14), +(34463, 66053, 68118, 5000, 15000, 14), +(34463, 66056, 0, 5000, 15000, 14), +(34463, 65983, 0, 30000, 60000, 1), +(34463, 65980, 0, 5000, 15000, 6), +(34463, 66054, 0, 10000, 40000, 4), +(34463, 66063, 0, 5000, 15000, 14), +(34463, 65973, 68100, 5000, 15000, 4); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34455, 66055, 68115, 5000, 15000, 14), +(34455, 66053, 68118, 5000, 15000, 14), +(34455, 66056, 0, 5000, 15000, 14), +(34455, 65983, 0, 30000, 60000, 1), +(34455, 65980, 0, 5000, 15000, 6), +(34455, 66054, 0, 10000, 40000, 4), +(34455, 66063, 0, 5000, 15000, 14), +(34455, 65973, 68100, 5000, 15000, 4); + +-- Enh shaman +DELETE FROM `boss_spell_table` WHERE `entry` IN (34470,34444); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34470, 65973, 0, 5000, 8000, 4), +(34470, 65974, 0, 5000, 8000, 3), +(34470, 65983, 0, 25000, 600000, 1), +(34470, 65970, 0, 5000, 90000, 3); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34444, 65973, 0, 5000, 8000, 4), +(34444, 65974, 0, 5000, 8000, 3), +(34444, 65983, 0, 25000, 600000, 1), +(34444, 65970, 0, 5000, 90000, 3); + +-- Hunter +DELETE FROM `boss_spell_table` WHERE `entry` IN (34467,34448); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34467, 65583, 67978, 3000, 8000, 3), +(34467, 65871, 0, 20000, 120000, 1), +(34467, 65869, 0, 12000, 20000, 1), +(34467, 65866, 67984, 3000, 8000, 3), +(34467, 65880, 0, 12000, 30000, 1), +(34467, 65868, 67989, 4000, 8000, 3), +(34467, 65867, 0, 4000, 8000, 3), +(34467, 66207, 0, 4000, 8000, 3), +(34467, 65877, 0, 7000, 60000, 4); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34448, 65583, 67978, 3000, 8000, 3), +(34448, 65871, 0, 20000, 120000, 1), +(34448, 65869, 0, 12000, 20000, 1), +(34448, 65866, 67984, 3000, 8000, 3), +(34448, 65880, 0, 12000, 30000, 1), +(34448, 65868, 67989, 4000, 8000, 3), +(34448, 65867, 0, 4000, 8000, 3), +(34448, 66207, 0, 4000, 8000, 3), +(34448, 65877, 0, 7000, 60000, 4); + +-- Rogue +DELETE FROM `boss_spell_table` WHERE `entry` IN (34472,34454); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34472, 65955, 0, 8000, 10000, 3), +(34472, 65956, 0, 12000, 120000, 1), +(34472, 65960, 0, 7000, 8000, 6), +(34472, 65961, 0, 20000, 120000, 1), +(34472, 66178, 0, 10000, 8000, 3), +(34472, 65954, 0, 5000, 8000, 3), +(34472, 65957, 68095, 15000, 20000, 3); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34454, 65955, 0, 8000, 10000, 3), +(34454, 65956, 0, 12000, 120000, 1), +(34454, 65960, 0, 7000, 8000, 6), +(34454, 65961, 0, 20000, 120000, 1), +(34454, 66178, 0, 10000, 8000, 3), +(34454, 65954, 0, 5000, 8000, 3), +(34454, 65957, 68095, 15000, 20000, 3); + +-- Priest +DELETE FROM `boss_spell_table` WHERE `entry` IN (34466,34447); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34466, 66177, 68035, 3000, 8000, 14), +(34466, 66099, 68032, 3000, 8000, 14), +(34466, 66104, 68023, 3000, 8000, 14), +(34466, 66100, 68026, 3000, 8000, 4), +(34466, 65546, 0, 3000, 8000, 6), +(34466, 65543, 0, 5000, 25000, 1); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34447, 66177, 68035, 3000, 8000, 14), +(34447, 66099, 68032, 3000, 8000, 14), +(34447, 66104, 68023, 3000, 8000, 14), +(34447, 66100, 68026, 3000, 8000, 4), +(34447, 65546, 0, 3000, 8000, 6), +(34447, 65543, 0, 5000, 25000, 1); + +-- Shadow priest +DELETE FROM `boss_spell_table` WHERE `entry` IN (34473,34441); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34473, 65542, 0, 8000, 15000, 6), +(34473, 65490, 68091, 3000, 8000, 4), +(34473, 65541, 68088, 3000, 8000, 4), +(34473, 65488, 68042, 3000, 8000, 3), +(34473, 65492, 68038, 3000, 8000, 3), +(34473, 65545, 0, 3000, 8000, 3), +(34473, 65544, 0, 1000, 180000, 1), +(34473, 65546, 0, 3000, 8000, 4), +(34473, 65543, 0, 8000, 24000, 1), +(34473, 16592, 0, 3000, 8000, 1); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34441, 65542, 0, 8000, 15000, 6), +(34441, 65490, 68091, 3000, 8000, 4), +(34441, 65541, 68088, 3000, 8000, 4), +(34441, 65488, 68042, 3000, 8000, 3), +(34441, 65492, 68038, 3000, 8000, 3), +(34441, 65545, 0, 3000, 8000, 3), +(34441, 65544, 0, 1000, 180000, 1), +(34441, 65546, 0, 3000, 8000, 4), +(34441, 65543, 0, 8000, 24000, 1), +(34441, 16592, 0, 3000, 8000, 1); + +-- Death knight +DELETE FROM `boss_spell_table` WHERE `entry` IN (34461,34458); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34461, 66020, 0, 5000, 15000, 3), +(34461, 66019, 67930, 5000, 15000, 3), +(34461, 66017, 0, 5000, 15000, 3), +(34461, 66047, 67936, 5000, 15000, 3), +(34461, 66023, 0, 5000, 90000, 1), +(34461, 66021, 67939, 8000, 12000, 3), +(34461, 66018, 0, 10000, 90000, 6); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34458, 66020, 0, 5000, 15000, 3), +(34458, 66019, 67930, 5000, 15000, 3), +(34458, 66017, 0, 5000, 15000, 3), +(34458, 66047, 67936, 5000, 15000, 3), +(34458, 66023, 0, 5000, 90000, 1), +(34458, 66021, 67939, 8000, 12000, 3), +(34458, 66018, 0, 10000, 90000, 6); + +-- Paladin +DELETE FROM `boss_spell_table` WHERE `entry` IN (34465,34445); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34465, 68757, 0, 25000, 40000, 6), +(34465, 66010, 0, 0, 3600001, 14), +(34465, 66116, 0, 5000, 15000, 14), +(34465, 66113, 68008, 5000, 10000, 14), +(34465, 66112, 68011, 5000, 15000, 14), +(34465, 66009, 0, 0, 3600001, 6), +(34465, 66114, 68015, 6000, 15000, 14), +(34465, 66613, 0, 5000, 15000, 4); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34445, 68757, 0, 25000, 40000, 6), +(34445, 66010, 0, 0, 3600001, 14), +(34445, 66116, 0, 5000, 15000, 14), +(34445, 66113, 68008, 5000, 10000, 14), +(34445, 66112, 68011, 5000, 15000, 14), +(34445, 66009, 0, 0, 3600001, 6), +(34445, 66114, 68015, 6000, 15000, 14), +(34445, 66613, 0, 5000, 15000, 4); + +-- Boomkin (druid in moonkin form) +DELETE FROM `boss_spell_table` WHERE `entry` IN (34469,34459); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34469, 65859, 0, 5000, 40000, 4), +(34469, 65857, 0, 5000, 40000, 3), +(34469, 65863, 0, 10000, 40000, 4), +(34469, 65861, 0, 25000, 40000, 3), +(34469, 65855, 67942, 25000, 40000, 4), +(34469, 65856, 67945, 5000, 40000, 3), +(34469, 65854, 67948, 25000, 40000, 3), +(34469, 65860, 0, 5000, 120000, 1), +(34469, 65862, 67952, 25000, 40000, 3); + +-- Warlock +DELETE FROM `boss_spell_table` WHERE `entry` IN (34474,34450); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34474, 65816, 68146, 15000, 30000, 1), +(34474, 65810, 68134, 15000, 30000, 4), +(34474, 65814, 68137, 15000, 30000, 4), +(34474, 65815, 0, 15000, 30000, 4), +(34474, 65809, 0, 4000, 15000, 4), +(34474, 65819, 68149, 15000, 30000, 3), +(34474, 65821, 68152, 3000, 10000, 3), +(34474, 65812, 68155, 2000, 10000, 4); +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_H10`, `timerMin_N10`, `timerMax_N10`, `CastType`) VALUES +(34450, 65816, 68146, 15000, 30000, 1), +(34450, 65810, 68134, 15000, 30000, 4), +(34450, 65814, 68137, 15000, 30000, 4), +(34450, 65815, 0, 15000, 30000, 4), +(34450, 65809, 0, 4000, 15000, 4), +(34450, 65819, 68149, 15000, 30000, 3), +(34450, 65821, 68152, 3000, 10000, 3), +(34450, 65812, 68155, 2000, 10000, 4); + diff --git a/addition/727_fishing_extravaganza_mangos.sql b/addition/727_fishing_extravaganza_mangos.sql new file mode 100644 index 000000000..c7386ac6e --- /dev/null +++ b/addition/727_fishing_extravaganza_mangos.sql @@ -0,0 +1,44 @@ +-- set ai for riggle +UPDATE `creature_template` SET `ScriptName`='npc_riggle_bassbait' WHERE entry=15077; +-- updated start time for event Fishing Extravaganza +UPDATE `game_event` SET `start_time`='2009-06-14 14:00:00', `occurence`=10080, `length`=120 where entry=15; +-- Create Jang +DELETE FROM `creature` WHERE `id`=15078; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`) VALUES +(954687, 15078, 0, 1, 1, 0, 1711, -14438, 473.661, 15.3137, 3.65362, 25, 0, 0, 3200, 0, 0, 0); +-- Create Fishbot 5000 +DELETE FROM `creature` WHERE `id`=15079; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`) VALUES +(954688, 15079, 0, 1, 1, 0, 0, -14440, 477.446, 15.25, 3.71802, 25, 0, 0, 2600, 0, 0, 0); +-- Create Riggle Bassbait +DELETE FROM `creature` WHERE `id`=15077; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`) VALUES +(954689, 15077, 0, 1, 1, 0, 13, -14439.3, 475.42, 15.892, 3.68503, 25, 0, 0, 3700, 0, 0, 0); +-- Create Soapbox gameobject +DELETE FROM `gameobject` WHERE `id`=180403; +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(954391, 180403, 0, 1, 1, -14439.3, 475.42, 15.2791, 3.68503, 0, 0, 0.963311, -0.268388, 25, 0, 1); + +-- new event - Fishing Extravaganza Questgivers +-- Remove NPC and GO from any other event. +DELETE FROM `game_event_creature` WHERE `guid` IN (954687,954688,954689); +DELETE FROM `game_event_gameobject`WHERE `guid`=954391; +-- Create Event +DELETE FROM `game_event` WHERE `entry`=35; +INSERT INTO `game_event` (`entry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `description`) VALUES (35, '2009-03-29 14:00:00', '2020-12-31 00:00:00', 10080, 180, 0, 'Fishing Extravaganza Questgivers'); +-- Add NPCs to Event +DELETE FROM `game_event_creature` WHERE abs(`event`) = 35; +INSERT INTO `game_event_creature` (`guid`, `event`) VALUES (954687,35), (954688,35), (954689,35); +-- Add Soapbox to Event +DELETE FROM `game_event_gameobject` WHERE abs(`event`) = 35; +INSERT INTO `game_event_gameobject` (`guid`, `event`) VALUES (954391,35); +-- Remove Quests from normal DB: +DELETE FROM `creature_questrelation` WHERE quest IN (8193,8194,8225,8224,8221); +-- Add Quests to Event +-- Riggle Bassbait Quest: Master Angler +-- Jang Quest: Apprentice Angler +-- Fishbot 5000 Quest: Rare Fish - Brownell's Blue Striped Racer +-- Fishbot 5000 Quest: Rare Fish - Dezian Queenfish +-- Fishbot 5000 Quest: Rare Fish - Keefer's Angelfish +DELETE FROM `game_event_quest` WHERE `event` = 35; +INSERT INTO `game_event_quest` (`quest`,`event`) VALUES (8193,35), (8194,35), (8225,35), (8224,35), (8221,35); diff --git a/addition/727_fishing_extravaganza_scriptdev2.sql b/addition/727_fishing_extravaganza_scriptdev2.sql new file mode 100644 index 000000000..a033054e4 --- /dev/null +++ b/addition/727_fishing_extravaganza_scriptdev2.sql @@ -0,0 +1,6 @@ +-- add ai text for riggle +DELETE FROM `script_texts` WHERE `entry` IN (-1510356,-1510357,-1510358); +INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +(-1510356, 'Let the Fishing Tournament BEGIN!', 0, 6, 0, 0, 'riggle SAY_START'), +(-1510357, 'We have a winner! $N is the Master Angler!', 0, 6, 0, 0, 'riggle SAY_WINNER'), +(-1510358, 'And the Tastyfish have gone for the week! I will remain for another hour to allow you to turn in your fish!', 0, 6, 0, 0, 'riggle SAY_END'); diff --git a/addition/728_ruby_sanctum_mangos.sql b/addition/728_ruby_sanctum_mangos.sql new file mode 100644 index 000000000..3c7a3fd49 --- /dev/null +++ b/addition/728_ruby_sanctum_mangos.sql @@ -0,0 +1,38 @@ +-- Ruby sanctum +UPDATE `instance_template` SET `ScriptName`='instance_ruby_sanctum' WHERE `map`=724; +-- Halion +UPDATE `creature_template` SET `ScriptName`='boss_halion_real', `AIName` ='' WHERE `entry`=39863; +UPDATE `creature_template` SET `ScriptName`='boss_halion_twilight', `AIName` ='' WHERE `entry`=40142; +UPDATE `creature_template` SET `ScriptName`='mob_halion_meteor', `AIName` ='' WHERE `entry` = 40029; +UPDATE `creature_template` SET `ScriptName`='mob_halion_flame', `AIName` ='' WHERE `entry` IN (40041); +UPDATE `creature_template` SET `ScriptName`='mob_halion_control', `AIName` ='' WHERE `entry` IN (40146); +UPDATE `creature_template` SET `ScriptName`='mob_halion_orb', `AIName` ='' WHERE `entry` IN (40083,40100); +UPDATE `creature_template` SET `ScriptName`='mob_orb_rotation_focus', `AIName` ='' WHERE `entry` = 40091; +UPDATE `creature_template` SET `ScriptName`='mob_orb_carrier', `AIName` ='' WHERE `entry` = 40081; +UPDATE `creature_template` SET `ScriptName`='mob_fiery_combustion', `AIName` ='' WHERE `entry` = 40001; +UPDATE `creature_template` SET `ScriptName`='mob_soul_consumption', `AIName` ='' WHERE `entry` = 40135; +UPDATE `creature_template` SET `ScriptName`='', `AIName` ='' WHERE `entry` IN (40143, 40144, 40145); +# +UPDATE `gameobject_template` SET `data10` = 74807, `faction` = '0', `ScriptName` = 'go_halion_portal_twilight' WHERE `gameobject_template`.`entry` IN (202794,202795); +UPDATE `gameobject_template` SET `faction` = '0', `ScriptName` = 'go_halion_portal_real' WHERE `gameobject_template`.`entry` IN (202796); + +-- Baltharus +UPDATE `creature_template` SET `ScriptName`='boss_baltharus', `AIName` ='', `dmg_multiplier` = 80 WHERE `entry`=39751; +UPDATE `creature_template` SET `ScriptName`='mob_baltharus_clone', `AIName` ='', `dmg_multiplier` = 80 WHERE `entry`=39899; +INSERT IGNORE INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid_1`, `modelid_2`, `modelid_3`, `modelid_4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `minhealth`, `maxhealth`, `minmana`, `maxmana`, `armor`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `PetSpellDataId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `unk16`, `unk17`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES +(39900, 0, 0, 0, 0, 0, 11686, 0, 11686, 0, 'Baltharus Target Dummy', '', NULL, 0, 1, 1, 25, 27, 0, 0, 17, 35, 35, 0, 1, 1.14286, 1, 0, 1, 2, 0, 0, 1, 2000, 2000, 1, 33554432, 0, 0, 0, 0, 0, 0, 1, 2, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 258, ''); +UPDATE `creature_template` SET `ScriptName`='', `AIName` ='' WHERE `entry`=39900; + +-- Zarithian +UPDATE `creature_template` SET `ScriptName`='boss_zarithian', `AIName` ='' WHERE `entry`=39746; +UPDATE `creature` SET `position_x` = '3008.552734',`position_y` = '530.471680',`position_z` = '89.195290',`orientation` = '6.16' WHERE `id` = 39746; +UPDATE `creature_template` SET `ScriptName`='mob_flamecaller_ruby', `AIName` ='' WHERE `entry`=39814; + +-- Saviana Ragefire +UPDATE `creature_template` SET `ScriptName`='boss_ragefire', `AIName` ='' WHERE `entry`=39747; +DELETE FROM `spell_script_target` WHERE `entry` IN (74455); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +('74455', '1', '39747'); + +-- Xerestrasza +UPDATE `creature_template` SET `ScriptName`='mob_xerestrasza', `AIName` ='' WHERE `entry`=40429; diff --git a/addition/728_ruby_sanctum_scriptdev2.sql b/addition/728_ruby_sanctum_scriptdev2.sql new file mode 100644 index 000000000..044872263 --- /dev/null +++ b/addition/728_ruby_sanctum_scriptdev2.sql @@ -0,0 +1,53 @@ +-- sound / text +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1666406 AND -1666000; + +-- xerestrasza +INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES +('-1666000','Help! I am trapped within this tree! I require aid!','Спасите! Я под этим деревом. Мне нужна помощь!','17490','6','0','0','SAY_XERESTRASZA_YELL_1'), +('-1666001','Thank you! I could have not held out for much longer. A terrible thing has happened here.','Спасибо! Без вас я бы долго не продержалась... Здесь произошли страшные события...','17491','0','0','0','SAY_XERESTRASZA_YELL_2'), +('-1666002','We believed that the Sanctum was well fortified, but we were not prepareted for the nature of this assault.','Святилище считалось неприступным, но до сих пор оно не подвергалось такому штурму...','17492','0','0','0','SAY_XERESTRASZA_SAY_1'), +('-1666003','The Black Dragonkin materialized from thin air, and set upon us before we could react.','Черные драконы явились из ниоткуда. Мы даже не успели понять что происходит...','17493','0','0','0','SAY_XERESTRASZA_SAY_2'), +('-1666004','We did not stand a chance. As my brethren perished around me, I managed to retreat hear and bar the entrance.','Силы были неравны, мои братья гибли один за другим. А я спряталась здесь и запечатала вход.','17494','0','0','0','SAY_XERESTRASZA_SAY_3'), +('-1666005','They slaughtered us with cold efficiency, but the true focus of their interest seemed to be the eggs kept here in the sanctum.','Нас убивали с расчетливой жестокостью, но основной целью врага была кладка яиц в святилище.','17495','0','0','0','SAY_XERESTRASZA_SAY_4'), +('-1666006','The commander of the forces on the ground here is a cruel brute named Zarithrian. But I fear there are greater powers at work.',' Атакой руководил кровожадный Заритриан, но, боюсь, тут замешано и более могущественное зло.','17496','0','0','0','SAY_XERESTRASZA_SAY_5'), +('-1666007','In their initial assault I caught a glimpse of their true leader, a fearsome full-grown Twilight Dragon.','В самом начале я ощутила присутствие их настоящего лидера - огромного сумеречного дракона.','17497','0','0','0','SAY_XERESTRASZA_SAY_6'), +('-1666008','I know not the extent of their plans heroes, but I know this: they cannot be allowed to succeed!','Герои, я не знаю чего добиваются эти захватчики. Одно я знаю точно - их нужно остановить!','17498','0','0','0','SAY_XERESTRASZA_SAY_7'), + +-- Halion +('-1666100','Meddlesome insects, you\'re too late! The Ruby Sanctum is lost.','Назойливая мошкара! Вы опоздали. Рубиновое святилище пало!','17499','6','0','0','SAY_HALION_SPAWN'), +('-1666101','Your world teeters on the brink of annihilation. You will all bear witness to the coming of a new age of destruction!','Этот мир вот-вот соскользнет в бездну. Вам выпала честь узреть начало эры РАЗРУШЕНИЯ!','17500','6','0','0','SAY_HALION_AGGRO'), +('-1666102','Another hero falls.','Сколько еще таких героев?','17501','6','0','0','SAY_HALION_SLAY_1'), +('-1666103','Ha Ha Ha!','','17502','6','0','0','SAY_HALION_SLAY_2'), +('-1666104','Relish this victory mortals, for it will be your last. This world will burn with the Master\'s return!','Это ваша последняя победа. Насладитесь сполна ее вкусом. Ибо когда вернется мой господин, этот мир сгинет в огне!','17503','6','0','0','SAY_HALION_DEATH'), +('-1666105','Not good enough!','Надоело!','17504','6','0','0','SAY_HALION_BERSERK'), +('-1666106','The heavens burn!','Небеса в огне!','17505','6','0','0','SAY_HALION_SPECIAL_1'), +('-1666107','Beware the shadow!','','17506','6','0','0','SAY_HALION_SPECIAL_2'), +('-1666108','You will find only suffering within the realm of Twilight. Enter if you dare.','Вы найдете только тьму в мире Сумерек. Входите, если посмеете.','17507','6','0','0','SAY_HALION_PHASE_2'), +('-1666109','I am the light AND the darkness! Cower mortals before the Herald of Deathwing!','Я есть свет и я есть тьма! Трепещите, ничтожные, перед посланником Смертокрыла!','17508','6','0','0','SAY_HALION_PHASE_3'), +('-1666110','The orbining spheres pulse with dark energy!','Во вращающихся сферах пульсирует темная энергия!','0','3','0','0',''), +('-1666111','Your companions\' effort force Halion further into the physical realm!','Ваши союзники протолкнули Халиона дальше в физический мир!','0','3','0','0',''), +('-1666112','Your companions\' effort force Halion further into the twilight realm!','Ваши союзники протолкнули Халиона дальше в реальный мир!','0','3','0','0',''), +('-1666113','Находясь в покое в одном из миров, Халион восстанавливает жизненные силы.','Находясь в покое в одном из миров, Халион восстанавливает жизненные силы.','0','3','0','0',''), + +-- Zarthrian +('-1666200','Alexstrasza has chosen capable allies. A pity that I must end you!','Алекстраза выбрала достойных союзников... Жаль, что придется ПРИКОНЧИТЬ ВАС!','17512','6','0','0','SAY_ZARITHRIAN_AGGRO'), +('-1666201','You thought you stood a chance?','Глупо было и надеяться!','17513','6','0','0','SAY_ZARITHRIAN_SLAY_1'), +('-1666202','It\'s for the best.','Все только к лучшему!','17514','6','0','0','SAY_ZARITHRIAN_SLAY_2'), +('-1666203','Halion! I\'m...aah!','ХАЛИОН! Я...','17515','6','0','0','SAY_ZARITHRIAN_DEATH'), +('-1666204','Turn them to ash, minions!','Слуги! Обратите их в пепел!','17516','6','0','0','SAY_ZARITHRIAN_SPECIAL_1'), + +-- baltharus +('-1666300','Ah, the entertainment has arrived...','А-а-а, цирк приехал.','17520','6','0','0','SAY_BALTHARUS_AGGRO'), +('-1666301','Baltharus leaves no survivors!','Балтар не оставляет живых!','17521','6','0','0','SAY_BALTHARUS_SLAY_1'), +('-1666302','This world has enough heroes!','В мире хватает героев и без тебя...','17522','6','0','0','SAY_BALTHARUS_SLAY_2'), +('-1666303','I...didn\'t see that coming...','Как… это могло произойти?..','17523','1','0','0','SAY_BALTHARUS_DEATH'), +('-1666304','Twice the pain and half the fun!','Вдвое сильнее страдание.','17524','6','0','0','SAY_BALTHARUS_SPECIAL_1'), +('-1666305','Your power wanes, ancient one! Soon, you will join your friends!','Твоя сила на исходе, Древнейшая! Скоро ты присоединишься к своим друзьям!','17525','6','0','0','SAY_BALTHARUS_YELL'), + +-- saviana +('-1666400','You will suffer for this intrusion...','Ваш-ш-ши муки с-cтанут платой за это вторжение!','17528','6','0','0','SAY_SAVIANA_AGGRO'), +('-1666401','As it should be!','Так и должно быть!','17529','6','0','0','SAY_SAVIANA_SLAY_1'), +('-1666402','Halion will be pleased...','Халион будет доволен!','17530','6','0','0','SAY_SAVIANA_SLAY_2'), +('-1666403','','О...','17531','6','0','0','SAY_SAVIANA_DEATH'), +('-1666404','Burn in the master\'s flame!','Горите в огне хозяина!','17532','6','0','0','SAY_SAVIANA_SPECIAL_1'), +('-1666405','','|3-3(%s) впадает в исступление!','0','3','0','0',''); diff --git a/addition/728_ruby_sanctum_spelltable_scriptdev2.sql b/addition/728_ruby_sanctum_spelltable_scriptdev2.sql new file mode 100644 index 000000000..614ccbd70 --- /dev/null +++ b/addition/728_ruby_sanctum_spelltable_scriptdev2.sql @@ -0,0 +1,133 @@ +-- Ruby sanctum spelltable +-- Boss Halion +DELETE FROM `boss_spell_table` WHERE `entry` = 39863; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`) VALUES +(39863, 74637, 0, 0, 0, 30000, 0, 0, 0, 30000, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0), +(39863, 74525, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), +(39863, 74562, 0, 0, 0, 30000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0), +(39863, 74809, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39863, 74808, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39863, 75063, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39863, 26663, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39863, 78243, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0); + +-- Mob Meteor strike +DELETE FROM `boss_spell_table` WHERE `entry` = 40029; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40029, 40041, 0, 0, 0, 20000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0), +(40029, 74641, 0, 0, 0, 500, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(40029, 74648, 0, 0, 0, 4500, 0, 0, 0, 4500, 0, 0, 0, 5, 7, 5, 7, 0, 0, 0, 1, 0, 0); + +-- Mob Meteor flame +DELETE FROM `boss_spell_table` WHERE `entry` = 40041; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40041, 74718, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Mob soul consumption +DELETE FROM `boss_spell_table` WHERE `entry` = 40135; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40135, 74803, 0, 0, 0, 60000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(40135, 74807, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Mob fiery combustion +DELETE FROM `boss_spell_table` WHERE `entry` = 40001; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40001, 74629, 0, 0, 0, 60000, 0, 0, 0, 60000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(40001, 74807, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Twilight Halion +DELETE FROM `boss_spell_table` WHERE `entry` = 40142; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`) VALUES +(40142, 74792, 0, 0, 0, 30000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0), +(40142, 74806, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), +(40142, 78243, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(40142, 74807, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(40142, 26663, 0, 0, 0, 600000, 0, 0, 0, 600000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(40142, 75484, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0); + +-- Mob orb carrier +DELETE FROM `boss_spell_table` WHERE `entry` = 40081; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40081, 77844, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(40081, 74807, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Mobs shadow orbs +DELETE FROM `boss_spell_table` WHERE `entry` = 40083; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40083, 77844, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(40083, 74807, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); +DELETE FROM `boss_spell_table` WHERE `entry` = 40100; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40100, 77844, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(40100, 74807, 0, 0, 0, 2000, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0); + +-- Mob Halion control +DELETE FROM `boss_spell_table` WHERE `entry` = 40146; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`) VALUES +(40146, 74826, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74827, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74828, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74829, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74830, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74831, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74832, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74833, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74834, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74835, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1), +(40146, 74836, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 1); + +/* +-- spelltable from notagain +-- Boss Halion +DELETE FROM `boss_spell_table` WHERE `entry` = 39863; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `timerMin_N10`, `timerMin_N25`, `timerMax_N10`, `timerMax_N25`, `data1`, `data2`, `data3`, `data4`, +`locData_x`, `locData_y`, `locData_z`, `varData`, `StageMask_N`, `StageMask_H`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`, `comment`) VALUES +(39863, 78243, 0, 100, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, NULL), +(39863, 74562, 0, 20000, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(39863, 74792, 0, 20000, 0, 30000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(39863, 75877, 0, 100, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(39863, 74525, 74527, 8000, 8000, 12000, 12000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, NULL), +(39863, 74806, 0, 8000, 0, 12000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, NULL), +(39863, 75484, 75485, 1000, 1000, 1000, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, NULL); +*/ + +-- Boss Baltharus +DELETE FROM `boss_spell_table` WHERE `entry` = 39751; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`) VALUES +(39751, 40504, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), +(39751, 75125, 0, 0, 0, 22000, 0, 0, 0, 22000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39751, 74502, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 40, 0, 0, 4, 0, 1, 0), +(39751, 74505, 0, 0, 0, 22000, 0, 0, 0, 22000, 0, 0, 0, 40, 0, 0, 1, 0, 0, 0), +(39751, 74509, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39751, 74511, 0, 0, 0, 20000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1666304), +(39751, 76221, 0, 0, 0, 1000, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0); +-- mob Baltharus Clone +DELETE FROM `boss_spell_table` WHERE `entry` = 39899; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`) VALUES +(39899, 75125, 0, 0, 0, 22000, 0, 0, 0, 22000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39899, 74502, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 40, 0, 0, 4, 0, 1, 0), +(39899, 40504, 0, 0, 0, 10000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); + +-- Boss Zarithian +DELETE FROM `boss_spell_table` WHERE `entry` = 39746; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`) VALUES +(39746, 74367, 0, 0, 0, 10000, 0, 0, 0, 20000, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), +(39746, 74384, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39746, 74398, 0, 0, 0, 45000, 0, 0, 0, 45000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39746, 39814, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 40, 0, 0, 9, 0, 0, 0); +-- mob Onyx Falmecaller +DELETE FROM `boss_spell_table` WHERE `entry` = 39814; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`) VALUES +(39814, 74392, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39814, 74394, 0, 0, 0, 10000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0); + +-- Boss Saviana Ragefire +DELETE FROM `boss_spell_table` WHERE `entry` = 39747; +INSERT INTO `boss_spell_table` (`entry`, `spellID_N10`, `spellID_N25`, `spellID_H10`, `spellID_H25`, `timerMin_N10`, `timerMin_N25`, `timerMin_H10`, `timerMin_H25`, `timerMax_N10`, `timerMax_N25`, `timerMax_H10`, `timerMax_H25`,`data1`, `data2`, `data3`, `data4`, `locData_x`, `locData_y`, `locData_z`, `CastType`, `isVisualEffect`, `isBugged`, `textEntry`) VALUES +(39747, 78722, 0, 0, 0, 20000, 0, 0, 0, 40000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ,-1666405), +(39747, 74404, 0, 0, 0, 5000, 0, 0, 0, 15000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39747, 74453, 0, 0, 0, 12000, 0, 0, 0, 22000, 0, 0, 0, 2, 5, 3, 5, 0, 0, 0, 6, 0, 0, 0), +(39747, 74452, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39747, 74455, 0, 0, 0, 5000, 0, 0, 0, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(39747, 74456, 0, 0, 0, 15000, 0, 0, 0, 25000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0); + diff --git a/addition/730_obsidian_sanctum_mangos.sql b/addition/730_obsidian_sanctum_mangos.sql new file mode 100644 index 000000000..9f0534413 --- /dev/null +++ b/addition/730_obsidian_sanctum_mangos.sql @@ -0,0 +1,112 @@ +-- Obsidian sanctum (from PSZ and MaxXx2021) +UPDATE creature_template SET ScriptName='mob_fire_cyclone' WHERE entry = 30648; +UPDATE creature_template SET ScriptName='mob_flame_tsunami' WHERE entry = 30616; +UPDATE creature_template SET ScriptName='mob_lava_blaze' WHERE entry = 30643; + +-- CUSTOM hack to different hard mode loot +REPLACE INTO creature_template (entry, difficulty_entry_1, modelid_1, modelid_3, faction_A, faction_H, NAME, subname, minhealth, maxhealth, rank, lootid) VALUES +(288601, 313111, 27035, 27035, 103, 103, 'Sartharion', 'The Onyx Guardian', 1, 1, 3, 288601), +(288602, 313112, 27035, 27035, 103, 103, 'Sartharion', 'The Onyx Guardian', 1, 1, 3, 288602), +(288603, 313113, 27035, 27035, 103, 103, 'Sartharion', 'The Onyx Guardian', 1, 1, 3, 288603), +(313111, 0, 27035, 27035, 103, 103, 'Sartharion', 'The Onyx Guardian', 1, 1, 3, 313111), +(313112, 0, 27035, 27035, 103, 103, 'Sartharion', 'The Onyx Guardian', 1, 1, 3, 313112), +(313113, 0, 27035, 27035, 103, 103, 'Sartharion', 'The Onyx Guardian', 1, 1, 3, 313113); + +-- boss loot +DELETE FROM creature_loot_template WHERE entry IN (30452, 30451, 30449, 28860, 288601, 288602, 288603, 31534, 31520, 31535, 31311, 313111, 313112, 313113); +-- Tenebron, Shadron, Vesperon +UPDATE creature_template SET lootid=30449 WHERE entry IN (30452, 30451, 30449, 31534, 31520, 31535); +INSERT INTO creature_loot_template (entry, item, ChanceOrQuestChance, groupid, mincountOrRef, maxcount, lootcondition, condition_value1, condition_value2) VALUES +(30449, 47241, 100, 0, 1, 1, 0, 0, 0); +-- Sartharion +-- references +DELETE FROM reference_loot_template WHERE entry IN (615000, 615001, 615002, 615010, 615011, 615012); +INSERT INTO reference_loot_template (entry, item, ChanceOrQuestChance, groupid, mincountOrRef, maxcount, lootcondition, condition_value1, condition_value2) VALUES +-- normal, no drakes +(615000, 40426, 0, 2, 1, 1, 0, 0, 0), +(615000, 40427, 0, 2, 1, 1, 0, 0, 0), +(615000, 40428, 0, 2, 1, 1, 0, 0, 0), +(615000, 40429, 0, 2, 1, 1, 0, 0, 0), +(615000, 40430, 0, 2, 1, 1, 0, 0, 0), +(615000, 40613, 0, 1, 1, 1, 0, 0, 0), +(615000, 40614, 0, 1, 1, 1, 0, 0, 0), +(615000, 40615, 0, 1, 1, 1, 0, 0, 0), +(615000, 43345, 100, 0, 1, 1, 0, 0, 0), +(615000, 43347, 100, 0, 1, 1, 0, 0, 0), +-- normal, 1 drake +(615001, 43992, 0, 1, 1, 1, 0, 0, 0), +(615001, 43988, 0, 1, 1, 1, 0, 0, 0), +(615001, 43990, 0, 1, 1, 1, 0, 0, 0), +(615001, 43989, 0, 1, 1, 1, 0, 0, 0), +(615001, 43991, 0, 1, 1, 1, 0, 0, 0), +-- normal, 2 drakes +(615002, 43995, 0, 1, 1, 1, 0, 0, 0), +(615002, 43998, 0, 1, 1, 1, 0, 0, 0), +(615002, 43994, 0, 1, 1, 1, 0, 0, 0), +(615002, 43996, 0, 1, 1, 1, 0, 0, 0), +(615002, 43993, 0, 1, 1, 1, 0, 0, 0), +-- heroic, no drakes +(615010, 40431, 0, 2, 1, 1, 0, 0, 0), +(615010, 40432, 0, 3, 1, 1, 0, 0, 0), +(615010, 40433, 0, 3, 1, 1, 0, 0, 0), +(615010, 40437, 0, 2, 1, 1, 0, 0, 0), +(615010, 40438, 0, 3, 1, 1, 0, 0, 0), +(615010, 40439, 0, 3, 1, 1, 0, 0, 0), +(615010, 40446, 0, 2, 1, 1, 0, 0, 0), +(615010, 40451, 0, 2, 1, 1, 0, 0, 0), +(615010, 40453, 0, 3, 1, 1, 0, 0, 0), +(615010, 40455, 0, 2, 1, 1, 0, 0, 0), +(615010, 40628, 0, 1, 1, 1, 0, 0, 0), +(615010, 40629, 0, 1, 1, 1, 0, 0, 0), +(615010, 40630, 0, 1, 1, 1, 0, 0, 0), +(615010, 43345, 100, 0, 1, 1, 0, 0, 0), +(615010, 43346, 100, 0, 1, 1, 0, 0, 0), +-- heroic, 1 drake +(615011, 44003, 0, 1, 1, 1, 0, 0, 0), +(615011, 44002, 0, 1, 1, 1, 0, 0, 0), +(615011, 44000, 0, 1, 1, 1, 0, 0, 0), +(615011, 44004, 0, 1, 1, 1, 0, 0, 0), +-- heroic, 2 drakes +(615012, 44007, 0, 1, 1, 1, 0, 0, 0), +(615012, 44006, 0, 1, 1, 1, 0, 0, 0), +(615012, 44005, 0, 1, 1, 1, 0, 0, 0), +(615012, 44008, 0, 1, 1, 1, 0, 0, 0), +(615012, 44011, 0, 1, 1, 1, 0, 0, 0); +UPDATE creature_template SET lootid=entry WHERE entry IN (28860, 288601, 288602, 288603, 31311, 313111, 313112, 313113); +INSERT INTO creature_loot_template (entry, item, ChanceOrQuestChance, groupid, mincountOrRef, maxcount, lootcondition, condition_value1, condition_value2) VALUES +-- normal, no drakes +(28860, 615000, 100, 0, -615000, 1, 0, 0, 0), +(28860, 47241, 100, 0, 1, 1, 0, 0, 0), +-- normal, 1 drake +(288601, 615000, 100, 0, -615000, 1, 0, 0, 0), +(288601, 615001, 100, 0, -615001, 1, 0, 0, 0), +(288601, 47241, 100, 0, 2, 2, 0, 0, 0), +-- normal, 2 drakes +(288602, 615000, 100, 0, -615000, 1, 0, 0, 0), +(288602, 615001, 100, 0, -615001, 1, 0, 0, 0), +(288602, 615002, 100, 0, -615002, 1, 0, 0, 0), +(288602, 47241, 100, 0, 3, 3, 0, 0, 0), +-- normal, 3 drakes +(288603, 615000, 100, 0, -615000, 1, 0, 0, 0), +(288603, 615001, 100, 0, -615001, 1, 0, 0, 0), +(288603, 615002, 100, 0, -615002, 1, 0, 0, 0), +(288603, 43986, 100, 0, 1, 1, 0, 0, 0), +(288603, 47241, 100, 0, 4, 4, 0, 0, 0), +-- heroic, no drakes +(31311, 615010, 100, 0, -615010, 1, 0, 0, 0), +(31311, 47241, 100, 0, 1, 1, 0, 0, 0), +-- heroic, 1 drake +(313111, 615010, 100, 0, -615010, 1, 0, 0, 0), +(313111, 615011, 100, 0, -615011, 1, 0, 0, 0), +(313111, 47241, 100, 0, 2, 2, 0, 0, 0), +-- heroic, 2 drakes +(313112, 615010, 100, 0, -615010, 1, 0, 0, 0), +(313112, 615011, 100, 0, -615011, 1, 0, 0, 0), +(313112, 615012, 100, 0, -615012, 1, 0, 0, 0), +(313112, 47241, 100, 0, 3, 3, 0, 0, 0), +-- heroic, 3 drakes +(313113, 615010, 100, 0, -615010, 1, 0, 0, 0), +(313113, 615011, 100, 0, -615011, 1, 0, 0, 0), +(313113, 615012, 100, 0, -615012, 1, 0, 0, 0), +(313113, 43954, 100, 0, 1, 1, 0, 0, 0), +(313113, 47241, 100, 0, 4, 4, 0, 0, 0); diff --git a/addition/730_obsidian_sanctum_scriptdev2.sql b/addition/730_obsidian_sanctum_scriptdev2.sql new file mode 100644 index 000000000..ebd7e1bd8 --- /dev/null +++ b/addition/730_obsidian_sanctum_scriptdev2.sql @@ -0,0 +1,45 @@ +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1615042 AND -1615000; +INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES +(-1615042, '%s begins to open a Twilight Portal!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '%s начинает открывать Врата Сумерек!', 0, 5, 0, 0, 'sartharion drake WHISPER_OPEN_PORTAL'), +(-1615041, 'A Vesperon Disciple appears in the Twilight!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Ученик Весперон появляется в Сумерках!', 0, 5, 0, 0, 'shadron WHISPER_VESPERON_DICIPLE'), +(-1615040, 'Unlike, I have many talents.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'В отличии от вас, я кое что умею.', 14138, 1, 0, 0, 'vesperon SAY_VESPERON_SPECIAL_2'), +(-1615039, 'Aren''t you tricky...I have a few tricks of my own...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'С вами не просто... Но и со мной не легко...', 14137, 1, 0, 0, 'vesperon SAY_VESPERON_SPECIAL_1'), +(-1615038, 'Father was right about you, Sartharion...You are a weakling!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Отец был прав насчет тебя, Сртарион... Ты слаб!', 14139, 1, 0, 0, 'vesperon SAY_VESPERON_RESPOND'), +(-1615037, 'I will pick my teeth with your bones!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я буду ковыряться в зубах вашими костями!', 14136, 1, 0, 0, 'vesperon SAY_VESPERON_BREATH'), +(-1615036, 'I still have some...fight..in...me...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я все еще... могу... драться...', 14140, 1, 0, 0, 'vesperon SAY_VESPERON_DEATH'), +(-1615035, 'Was that the best you can do?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'И это все, что ты можешь сделать?', 14135, 1, 0, 0, 'vesperon SAY_VESPERON_SLAY_2'), +(-1615034, 'The least you could do is put up a fight...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Все, что тебе удалось, это затеять драку...', 14134, 1, 0, 0, 'vesperon SAY_VESPERON_SLAY_1'), +(-1615033, 'You pose no threat, lesser beings...give me your worst!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Вы безобидны, ничтожные создания... покажите мне, на что вы способны!', 14133, 1, 0, 0, 'vesperon SAY_VESPERON_AGGRO'), +(-1615032, 'The lava surrounding %s churns!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Потомство Весперона появляется в Сумерках!', 0, 5, 0, 0, 'sartharion WHISPER_LAVA_CHURN'), +(-1615031, 'This is why we call you lesser beeings.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Вот поэтому мы и называем вас низшими созданиями.', 14097, 1, 0, 0, 'sartharion SAY_SARTHARION_SLAY_3'), +(-1615030, 'You are the grave disadvantage.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Тебе смертельно не повезло.', 14096, 1, 0, 0, 'sartharion SAY_SARTHARION_SLAY_2'), +(-1615029, 'You will make a fine meal for the hatchlings.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Из тебя выйдет хорошая закуска для детенышей.', 14094, 1, 0, 0, 'sartharion SAY_SARTHARION_SLAY_1'), +(-1615028, 'All will be reduced to ash!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'От вас останется всего лишь горстка пепла!', 14102, 1, 0, 0, 'sartharion SAY_SARTHARION_SPECIAL_4'), +(-1615027, 'How much heat can you take?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Посмотрим, как вы переносите жару!', 14101, 1, 0, 0, 'sartharion SAY_SARTHARION_SPECIAL_3'), +(-1615026, 'Your charred bones will litter the floor!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Ваши обугленные кости завалят весь пол!', 14100, 1, 0, 0, 'sartharion SAY_SARTHARION_SPECIAL_2'), +(-1615025, 'Such flammable little insects....', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Мелкая мошка хорошо горит...', 14099, 1, 0, 0, 'sartharion SAY_SARTHARION_SPECIAL_1'), +(-1615024, 'Such is the price... of failure...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Такова цена... неудачи...', 14107, 1, 0, 0, 'sartharion SAY_SARTHARION_DEATH'), +(-1615023, 'Vesperon! The clutch is in danger! Assist me!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Весперон! Кладка в опасности! Помоги мне!', 14104, 1, 0, 0, 'sartharion SAY_SARTHARION_CALL_VESPERON'), +(-1615022, 'Tenebron! The eggs are yours to protect as well!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Тенеброн! Ты тоже должна защищать яйца!', 14106, 1, 0, 0, 'sartharion SAY_SARTHARION_CALL_TENEBRON'), +(-1615021, 'Shadron! Come to me, all is at risk!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Шадрон! На помощь! Все на кону!', 14105, 1, 0, 0, 'sartharion SARTHARION_CALL_SHADRON'), +(-1615020, 'Burn, you miserable wretches!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Гори, злосчастный сброд!', 14098, 1, 0, 0, 'sartharion SAY_SARTHARION_BREATH'), +(-1615019, 'This pathetic siege ends NOW!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Это смехотворное сражение закончиться СЕЙЧАС ЖЕ!', 14103, 1, 0, 0, 'sartharion SAY_SARTHARION_BERSERK'), +(-1615018, 'It is my charge to watch over these eggs. I will see you burn before any harm comes to them!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Моя обязанность - оберегать эти яйца. И вы сгорите прежде, чем хоть пальцем дотронетесь их.', 14093, 1, 0, 0, 'sartharion SAY_SARTHARION_AGGRO'), +(-1615017, '%s begins to hatch eggs in the twilight!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '%s начинает высиживать яйца в сумерках!', 0, 5, 0, 0, 'tenebron WHISPER_HATCH_EGGS'), +(-1615016, 'I am no mere dragon! You will find I am much, much, more...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я не простой дракон! Увидите, совсем, совсем, не простой...', 14127, 1, 0, 0, 'tenebron SAY_TENEBRON_SPECIAL_2'), +(-1615015, 'Arrogant little creatures! To challenge powers you do not yet understand...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Самонадеянные мелкие твари! Вы бросаете вызов силам, от понимания которых, вы еще далеки!', 14126, 1, 0, 0, 'tenebron SAY_TENEBRON_SPECIAL_1'), +(-1615014, 'It is amusing to watch you struggle. Very well, witness how it is done.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Занятно наблюдать, как ты сражаешься. Хорошо, смотри, как надо это делать.', 14128, 1, 0, 0, 'tenebron SAY_TENEBRON_RESPOND'), +(-1615013, 'To darkness I condemn you...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Приговариваю вас к тьме...', 14125, 1, 0, 0, 'tenebron SAY_TENEBRON_BREATH'), +(-1615012, 'I should not... have held back...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Не надо было... вмешиваться...', 14129, 1, 0, 0, 'tenebron SAY_TENEBRON_DEATH'), +(-1615011, 'Typical... Just as I was having fun.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Как обычно... Только я вошла во вкус.', 14124, 1, 0, 0, 'tenebron SAY_TENEBRON_SLAY_2'), +(-1615010, 'No contest.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Не интересно.', 14123, 1, 0, 0, 'tenebron SAY_TENEBRON_SLAY_1'), +(-1615009, 'You have no place here. Your place is among the departed.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Вам здесь не место. Ваше место - среди усопших.', 14122, 1, 0, 0, 'tenebron SAY_TENEBRON_AGGRO'), +(-1615008, 'A Shadron Disciple appears in the Twilight!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Ученик Шадрон появляется в Сумерках!', 0, 5, 0, 0, 'shadron WHISPER_SHADRON_DICIPLE'), +(-1615007, 'On your knees!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'На колени!', 14116, 1, 0, 0, 'shadron SAY_SHADRON_SPECIAL_2'), +(-1615006, 'Father tought me well!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Отец не зря учил меня!', 14115, 1, 0, 0, 'shadron SAY_SHADRON_SPECIAL_1'), +(-1615005, 'I will take pity on you Sartharion, just this once.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я пожалею тебя Сартарион, но только в этот раз.', 14117, 1, 0, 0, 'shadron SAY_SHADRON_RESPOND'), +(-1615004, 'You are easily bested! ', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Вас легко провести!', 14114, 1, 0, 0, 'shadron SAY_SHADRON_BREATH'), +(-1615003, 'We...are superior! How could this...be...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Мы... выше всех! Как это... возможно...', 14118, 1, 0, 0, 'shadron SAY_SHADRON_DEATH'), +(-1615002, 'Such mediocre resistance!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Какое слабое сопротивление!', 14113, 1, 0, 0, 'shadron SAY_SHADRON_SLAY_2'), +(-1615001, 'You are insignificant!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Ты ничтожество!', 14112, 1, 0, 0, 'shadron SAY_SHADRON_SLAY_1'), +(-1615000, 'I fear nothing! Least of all you!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Я не боюсь ничего! Тем более вас!', 14111, 1, 0, 0, 'shadron SAY_SHADRON_AGGRO'); diff --git a/addition/731_npc_special_mangos.sql b/addition/731_npc_special_mangos.sql new file mode 100644 index 000000000..f21481c43 --- /dev/null +++ b/addition/731_npc_special_mangos.sql @@ -0,0 +1,13 @@ +-- Snakes trap +UPDATE `creature_template` SET `ScriptName`='npc_snake_trap_serpents' WHERE `entry` IN (19921, 19833); +-- Mirror Immage +UPDATE `creature_template` SET `speed_walk` = 2.5, `modelid_1` = 11686, `modelid_3` = 11686, `minlevel` = 80, `maxlevel` = 80, `AIName` = '', `ScriptName`='npc_mirror_image' WHERE `entry` = 31216; +-- Rune blade +UPDATE `creature_template` SET `modelid_1` = 11686, `modelid_3` = 11686,`AIName` = '', `ScriptName`='npc_runeblade' WHERE `entry` = 27893; +-- DK Gargoyle +UPDATE `creature_template` SET `ScriptName` = 'npc_death_knight_gargoyle' WHERE `entry` = '27829'; +-- Explosive decoy +UPDATE `creature_template` SET `ScriptName` = 'npc_explosive_decoy' WHERE `entry` = '29134'; +-- Eye of Kilrogg +UPDATE `creature_template` SET `ScriptName` = 'npc_eye_of_kilrogg' WHERE `entry` = '4277'; + diff --git a/addition/732_azjol-nerub_mangos.sql b/addition/732_azjol-nerub_mangos.sql new file mode 100644 index 000000000..e7ec038d5 --- /dev/null +++ b/addition/732_azjol-nerub_mangos.sql @@ -0,0 +1,10 @@ +-- Azjol-Nerub from MaxXx2021 +UPDATE creature_template SET ScriptName = 'npc_watcher_gashra' WHERE entry = 28730; +UPDATE creature_template SET ScriptName = 'npc_watcher_narjil' WHERE entry = 28729; +UPDATE creature_template SET ScriptName = 'boss_krikthir' WHERE entry = 28684; +UPDATE creature_template SET ScriptName = 'npc_watcher_silthik' WHERE entry = 28731; +UPDATE creature_template SET ScriptName = 'boss_hadronox' WHERE entry = 28921; +UPDATE creature_template SET ScriptName = 'npc_anub_ar_warrior' WHERE entry = 28732; +UPDATE creature_template SET ScriptName = 'npc_anub_ar_skirmisher' WHERE entry = 28734; +UPDATE creature_template SET ScriptName = 'npc_anub_ar_shadowcaster' WHERE entry = 28733; +UPDATE creature_template SET ScriptName = 'npc_skittering_infector' WHERE entry = 28736; diff --git a/addition/733_mangos_ulduar_raid.sql b/addition/733_mangos_ulduar_raid.sql new file mode 100644 index 000000000..b2b310629 --- /dev/null +++ b/addition/733_mangos_ulduar_raid.sql @@ -0,0 +1,464 @@ +/* ULDUAR from Xfurry*/ + +-- Flame Leviathan +UPDATE creature_template SET ScriptName = 'boss_flame_leviathan' WHERE entry = 33113; +UPDATE creature_template SET ScriptName = 'mob_defense_turret' WHERE entry = 33142; + +-- Ignis +UPDATE creature_template SET mechanic_immune_mask=617299803, scriptname='boss_ignis' WHERE entry=33118; +UPDATE creature_template SET ScriptName = 'mob_iron_construct' WHERE entry = 33121; +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('64474', '1', '33118'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('64475', '1', '33118'); +-- this may not be correct +UPDATE creature_template SET minlevel=80, maxlevel=80, faction_h=1925, faction_a=1925, scale=0.5, scriptname='mob_scorch_target' WHERE entry=33221; + +-- Razorscale +UPDATE creature_template SET mechanic_immune_mask=617299803, scriptname='boss_razorscale' WHERE entry=33186; +-- original x=587.547, y= -174.927, z = 391.517; make the boss fly before encounter starts +UPDATE creature SET position_x = 590.346741, position_y = -226.947647, position_z = 442.897583 WHERE id = 33186; +UPDATE gameobject_template SET flags= 6553648, ScriptName='go_broken_harpoon' WHERE entry = 194565; +-- only 2 harpoons for 10 man +UPDATE gameobject SET spawnMask = 2 WHERE guid IN (73595, 73592); +-- mole machines & adds +UPDATE creature_template SET ScriptName = 'mob_mole_machine' WHERE entry = 33245; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_watcher' WHERE entry = 33453; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_sentinel' WHERE entry = 33846; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_guardian' WHERE entry = 33388; +UPDATE creature_template SET ScriptName = 'npc_expedition_commander' WHERE entry = 33210; +UPDATE creature_template SET ScriptName = 'mob_devouring_flame_target' WHERE entry IN (34189, 34188); + +-- XT002 +UPDATE creature_template SET mechanic_immune_mask=617299803, scriptname='boss_xt002' WHERE entry=33293; +UPDATE creature_template SET ScriptName = 'mob_pummeler' WHERE entry = 33344; +UPDATE creature_template SET speed_run=0.5, faction_a=1925, faction_h=1925, scriptname='mob_boombot' WHERE entry=33346; +UPDATE creature_template SET speed_run=0.5 WHERE entry=33343; +UPDATE creature_template SET mechanic_immune_mask=652951551, scriptname='mob_xtheart' WHERE entry=33329; +UPDATE creature_template SET ScriptName = 'mob_voidzone' WHERE entry = 34001; +UPDATE creature_template SET minhealth = 176400, maxhealth = 176400, minlevel = 80, maxlevel = 80, faction_a = 14, faction_h = 14, ScriptName = 'mob_lifespark' WHERE entry = 34004; +UPDATE creature SET spawnMask = 0 WHERE id IN (34004); + +-- THIS IS A WORKAROUND FOR THE HARD MODE LOOT, PLEASE REMOVE IF YOU DON'T WANT TO USE IT! +-- hard loot for the heart +UPDATE creature_template SET lootid = 33329 WHERE entry = 33329; +UPDATE creature_template SET lootid = 33995 WHERE entry = 33995; +-- rewrite loot for XT to support hard mode: moved hard mode loot to XT heart +-- 10 man: +-- hard mode loot for the heart +DELETE FROM `creature_loot_template` WHERE (`entry`=33329); +INSERT INTO `creature_loot_template` VALUES +(33329, 45867, 0, 1, 1, 1, 0, 0, 0), +(33329, 45868, 0, 1, 1, 1, 0, 0, 0), +(33329, 45869, 0, 1, 1, 1, 0, 0, 0), +(33329, 45870, 0, 1, 1, 1, 0, 0, 0), +(33329, 45871, 0, 1, 1, 1, 0, 0, 0); +-- 25 man: +-- no hard loot on xt so moving to the heart +DELETE FROM `creature_loot_template` WHERE (`entry`=33995); +INSERT INTO `creature_loot_template` VALUES +(33995, 45445, 0, 1, 1, 1, 0, 0, 0), +(33995, 45443, 0, 1, 1, 1, 0, 0, 0), +(33995, 45444, 0, 1, 1, 1, 0, 0, 0), +(33995, 45446, 0, 1, 1, 1, 0, 0, 0), +(33995, 45442, 0, 1, 1, 1, 0, 0, 0); + +-- Iron council +UPDATE creature_template SET mechanic_immune_mask=619395071, scriptname='boss_brundir' WHERE entry=32857; +UPDATE creature_template SET mechanic_immune_mask=617299803, scriptname='boss_molgeim' WHERE entry=32927; +UPDATE creature_template SET mechanic_immune_mask=617299803, scriptname='boss_steelbreaker' WHERE entry=32867; +UPDATE creature_template SET ScriptName = 'mob_rune_of_power' WHERE entry = 33705; +UPDATE creature_template SET ScriptName = 'mob_rune_of_summoning' WHERE entry = 33051; +UPDATE creature_template SET ScriptName = 'mob_ulduar_lightning_elemental' WHERE entry = 32958; +UPDATE `creature_template` SET `mechanic_immune_mask` = 619397115 WHERE `entry` IN (32857, 33694); + +-- LOOT FOR THESE THREE SHOUDL BE PROGRESSIVE, MAYBE THIS IS NOT THE RIGHT WAY TO DO IT +-- update loot id: +-- brundir +UPDATE `creature_template` SET `lootid` = 32857 WHERE `entry` = 32857; +UPDATE `creature_template` SET `lootid` = 33694 WHERE `entry` = 33694; +-- molgeim = steelbreaker (I dont know exactly which items are missing from molgeim's loot so i'm leaving it the same for now); +UPDATE `creature_template` SET `lootid` = 32867 WHERE `entry` = 32927; +UPDATE `creature_template` SET `lootid` = 33693 WHERE `entry` = 33692; +-- Rewrite loot for council: this will allow us to use hard mode loot because only the last killed boss will be lootable +-- 10 man version +-- Brundir: +DELETE FROM `creature_loot_template` WHERE (`entry`=32857); +INSERT INTO `creature_loot_template` VALUES +(32857, 45322, 0, 2, 1, 1, 0, 0, 0), +(32857, 45324, 0, 1, 1, 1, 0, 0, 0), +(32857, 45329, 0, 2, 1, 1, 0, 0, 0), +(32857, 45330, 0, 1, 1, 1, 0, 0, 0), +(32857, 45331, 0, 2, 1, 1, 0, 0, 0), +(32857, 45332, 0, 1, 1, 1, 0, 0, 0), +(32857, 45333, 0, 2, 1, 1, 0, 0, 0), +(32857, 45378, 0, 2, 1, 1, 0, 0, 0), +(32857, 45418, 0, 1, 1, 1, 0, 0, 0), +(32857, 45423, 0, 1, 1, 1, 0, 0, 0), +-- emblem 100% drop +(32857, 47241, 100, 0, 1, 1, 0, 0, 0); +-- 25 man version +-- Brundir: +DELETE FROM `creature_loot_template` WHERE (`entry`=33694); +INSERT INTO `creature_loot_template` VALUES +(33694, 45224, 0, 3, 1, 1, 0, 0, 0), +(33694, 45228, 0, 3, 1, 1, 0, 0, 0), +(33694, 45233, 0, 3, 1, 1, 0, 0, 0), +(33694, 45234, 0, 3, 1, 1, 0, 0, 0), +(33694, 45236, 0, 3, 1, 1, 0, 0, 0), +(33694, 45226, 0, 2, 1, 1, 0, 0, 0), +(33694, 45235, 0, 2, 1, 1, 0, 0, 0), +(33694, 45237, 0, 2, 1, 1, 0, 0, 0), +(33694, 45238, 0, 2, 1, 1, 0, 0, 0), +(33694, 45239, 0, 2, 1, 1, 0, 0, 0), +(33694, 45193, 0, 1, 1, 1, 0, 0, 0), +(33694, 45225, 0, 1, 1, 1, 0, 0, 0), +(33694, 45227, 0, 1, 1, 1, 0, 0, 0), +(33694, 45232, 0, 1, 1, 1, 0, 0, 0), +(33694, 45240, 0, 1, 1, 1, 0, 0, 0), +(33694, 45038, 10, 0, 1, 1, 0, 0, 0), +(33694, 45087, 33, 0, 1, 2, 0, 0, 0), +(33694, 45089, 5, 0, -45089, 1, 0, 0, 0), +-- emblem 100% drop +(33694, 47241, 100, 0, 1, 1, 0, 0, 0); + +-- Kologarn +DELETE FROM creature WHERE id IN (32933, 32934); +-- fix arms position because of the missing vehicles +INSERT INTO creature (id, map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, DeathState, MovementType) VALUES (32933, 603, 3, 65535, 0, 0, 1799.68, -24.3599, 452.227, 3.14747, 604800, 0, 0, 543855, 0, 0, 0); +INSERT INTO creature (id, map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, DeathState, MovementType) VALUES (32934, 603, 3, 65535, 0, 0, 1799.68, -24.3599, 452.227, 3.14747, 604800, 0, 0, 543855, 0, 0, 0); +UPDATE creature_model_info SET bounding_radius=15, combat_reach=15 WHERE modelid IN (28638, 28822, 28821); +UPDATE creature_template SET mechanic_immune_mask=617299803, unit_flags = 0, scriptname='boss_kologarn' WHERE entry=32930; +UPDATE creature_template SET mechanic_immune_mask=652951551, scriptname='boss_right_arm' WHERE entry=32934; +UPDATE creature_template SET mechanic_immune_mask=652951551, scriptname='boss_left_arm' WHERE entry=32933; +UPDATE creature_template SET ScriptName = 'mob_ulduar_rubble' WHERE entry IN (33768, 33809, 33908, 33942); +UPDATE `gameobject` SET `position_y` = -35.6824, `position_x` = 1837.59 WHERE `id` IN (195047); +UPDATE `creature_template` SET `RegenHealth` = 1 WHERE `entry` = 33910; +UPDATE `creature_template` SET `RegenHealth` = 1 WHERE `entry` = 33911; + +-- Auriaya +UPDATE creature_template SET mechanic_immune_mask=583745371, equipment_id = 103000, scriptname='boss_auriaya' WHERE entry=33515; +UPDATE creature_template SET mechanic_immune_mask=619395071, scriptname='mob_feral_defender' WHERE entry=34035; +UPDATE creature_template SET minlevel=80, maxlevel=80, faction_h=14, faction_a=14, scriptname='mob_seeping_feral_essence' WHERE entry=34098; +UPDATE creature_template SET ScriptName = 'mob_sanctum_sentry' WHERE entry = 34014; +UPDATE `creature_template` SET `mechanic_immune_mask` = 619397115 WHERE `entry` IN (33515, 34175); +DELETE FROM creature_equip_template WHERE entry = 103000; +INSERT INTO creature_equip_template values (103000, 45315, 0, 0); +-- 2 more defenders for 25 man +DELETE FROM creature WHERE guid IN (800010, 800011); +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`) VALUES +(800010, 34014, 603, 2, 65535, 0, 0, 1945.2, 37.2442, 411.356, 3.62107, 7200, 0, 0, 334680, 0, 0, 0), +(800011, 34014, 603, 2, 65535, 0, 0, 1936.11, 49.8233, 411.352, 3.85276, 7200, 0, 0, 334680, 0, 0, 0); +DELETE FROM `creature_movement` WHERE `id`=94378; +INSERT INTO `creature_movement` (`id`,`point`,`position_x`,`position_y`,`position_z`,`waittime`,`textid1`,`textid2`,`textid3`,`textid4`,`textid5`,`emote`,`spell`,`wpguid`,`orientation`,`model1`,`model2`) VALUES +-- UPDATED CREATURE MOVEMENT FOR AURIAYA, SHOULD MOVE AROUND THE CENTER SPIRE +#(94378, 4, 1916.56, -69.9669, 417.718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.2268, 0, 0), -- after hodir up +#(94378, 3, 1900.26, -24.0211, 417.722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.15909, 0, 0), -- center kolgoran +#(94378, 2, 1916.97, 21.1583, 417.748, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.86988, 0, 0), -- before yogg up + +(94378, 1, 1925.012, 30.0067, 411.356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.69685, 0, 0), -- before yogg down +(94378, 2, 1957.04, 49.3067, 411.355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.37071, 0, 0), -- after yogg down +(94378, 3, 1967.38, 51.4931, 417.561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.09545, 0, 0), -- after yogg up +(94378, 4, 2013.07, 44.3788, 417.715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.71365, 0, 0), -- before mimiron up +(94378, 5, 2021.35, 37.9771, 411.387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.25205, 0, 0), -- before mimiron down +(94378, 6, 2046.36, 8.56725, 411.524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.203, 0, 0), -- after mimiron down +(94378, 7, 2053.32, -7.1366, 421.78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.85107, 0, 0), -- before freya up +(94378, 8, 2052.87, -40.8556, 421.706, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.4223, 0, 0), -- after freya up +(94378, 9, 2045.00, -56.79369, 411.359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.20538, 0, 0), -- before thorim down +(94378, 10, 2022.18, -86.5468, 411.355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.60096, 0, 0), -- after thorim down +(94378, 11, 2012.94, -92.7106, 417.717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.28968, 0, 0), -- after thorim up +(94378, 12, 1968.83, -101.0946, 417.722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.662873, 0, 0),-- before hodir up +(94378, 13, 1958.08, -96.7855, 411.864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.763719, 0, 0), -- before hodir down +(94378, 14, 1924.12, -78.5404, 411.488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.210024, 0, 0), -- after hodir down + +(94378, 15, 1958.08, -96.7855, 411.864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.763719, 0, 0), -- before hodir down +(94378, 16, 1968.83, -101.0946, 417.722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.662873, 0, 0),-- before hodir up +(94378, 17, 2012.94, -92.7106, 417.717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.28968, 0, 0), -- after thorim up +(94378, 18, 2022.18, -86.5468, 411.355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.60096, 0, 0), -- after thorim down +(94378, 19, 2045.00, -56.79369, 411.359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.20538, 0, 0), -- before thorim down +(94378, 20, 2052.87, -40.8556, 421.706, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.4223, 0, 0), -- after freya up +(94378, 21, 2053.32, -7.1366, 421.78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.85107, 0, 0), -- before freya up +(94378, 22, 2046.36, 8.56725, 411.524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.203, 0, 0), -- after mimiron down +(94378, 23, 2021.35, 37.9771, 411.387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.25205, 0, 0), -- before mimiron down +(94378, 24, 2013.07, 44.3788, 417.715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.71365, 0, 0), -- before mimiron up +(94378, 25, 1967.38, 51.4931, 417.561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.09545, 0, 0), -- after yogg up +(94378, 26, 1957.04, 49.3067, 411.355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.37071, 0, 0); -- after yogg down + +-- Freya +UPDATE creature_template SET ScriptName = 'boss_freya' WHERE entry = 32906; +UPDATE creature_template SET ScriptName = 'boss_elder_brightleaf' WHERE entry = 32915; +UPDATE creature_template SET ScriptName = 'boss_elder_ironbranch' WHERE entry = 32913; +UPDATE creature_template SET ScriptName = 'boss_elder_stonebark' WHERE entry = 32914; +UPDATE creature_template SET ScriptName = 'mob_iron_roots' WHERE entry IN (33088, 33168); +UPDATE creature_template SET ScriptName = 'mob_freya_ground' WHERE entry IN (33215, 33228, 33170, 33050, 34129); +UPDATE creature_template SET ScriptName = 'mob_freya_spawned' WHERE entry IN (32916, 32919, 33202, 33203, 32918); +-- some aura fixes, this may be wrong +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62525', '1', '32906'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62524', '1', '32906'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62521', '1', '32906'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62385', '1', '32906'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62387', '1', '32906'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62386', '1', '32906'); + +-- Added hack for Freya's gift +DELETE FROM `gameobject` WHERE `id` IN (194324, 194325,194326,194327,194328,194329,194330,194331); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(733324, 194324, 603, 1, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1), +(733325, 194325, 603, 1, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1), +(733326, 194326, 603, 1, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1), +(733327, 194327, 603, 1, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1), +(733328, 194328, 603, 2, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1), +(733329, 194329, 603, 2, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1), +(733330, 194330, 603, 2, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1), +(733331, 194331, 603, 2, 65535, 2374.876221, -78.512665, 425.073608, 3.260976, 0, 0, 0.706026, 0.708186, -604800, 100, 1); +-- Delete bugged spell from mobs +DELETE FROM `creature_ai_scripts` WHERE `creature_id` IN (33430,33732) AND `action1_param1` = 63007; + +-- Hodir +UPDATE creature_template SET ScriptName = 'boss_hodir' WHERE entry = 32845; +UPDATE creature_template SET ScriptName = 'mob_toasty_fire' WHERE entry = 33342; +UPDATE creature_template SET ScriptName = 'mob_flashFreeze' WHERE entry IN (32926); +UPDATE `creature_template` SET `modelid_1` = 15880 WHERE `entry` = 33174; +UPDATE `creature_template` SET `modelid_2` = 28470, ScriptName = 'mob_icicle' WHERE `entry` = 33169; +-- flash freeze that will lock the npcs IN iceblock +UPDATE creature_template SET `modelid_1` = 25865, ScriptName = 'mob_npc_flashFreeze' WHERE entry IN (32938, 33353); +UPDATE creature SET spawnMask = 3 WHERE id IN (32938); +UPDATE creature SET spawnMask = 2 WHERE id IN (32901, 32900, 32950, 32946,33333, 33330, 33326); +UPDATE creature_template SET ScriptName = 'npc_hodir_priest' WHERE entry IN (32897, 33326, 32948, 33330); +UPDATE creature_template SET ScriptName = 'npc_hodir_druid' WHERE entry IN (33325, 32901, 32941, 33333); +UPDATE creature_template SET ScriptName = 'npc_hodir_shaman' WHERE entry IN (33328, 32900, 33332, 32950); +UPDATE creature_template SET ScriptName = 'npc_hodir_mage' WHERE entry IN (32893, 33327, 33331, 32946); + +-- FIXED SOME POSITIONING FOR THE FRIENDLY NPCS, Besides this the freeze aura should also be fixed. +-- fixed npc positioning and added 4 extra flashfreeze for them. +-- 10 man: +-- mage +UPDATE creature SET position_x = 2000.9, position_y = -231.232 WHERE guid = 131930; +-- priest +UPDATE creature SET position_x = 2009.06, position_y = -244.058 WHERE guid = 131933; +DELETE FROM creature WHERE guid IN (800005); +INSERT INTO creature VALUES +(800005, 32897, 603, 3, 128,0,0, 2009.06, -244.058, 432.687, 1.68485, 7200,0,0, 5647, 0, 0, 0); -- aly priest +-- shaman +UPDATE creature SET position_x = 1983.75, position_y = -243.358 WHERE id = 33328; +UPDATE creature SET position_x = 1983.75, position_y = -243.358 WHERE id = 33332; +-- druid +UPDATE creature SET position_x = 2021.12, position_y = -236.648 WHERE id = 32941; +UPDATE creature SET position_x = 2021.12, position_y = -236.648 WHERE id = 33325; +-- 25 man: +-- druid +UPDATE creature SET position_x = 2013.5, position_y = -240.338 WHERE id = 32901; +DELETE FROM creature WHERE guid IN (800006); +INSERT INTO creature VALUES +(800006, 32938, 603, 2, 1,0,0, 2013.5, -240.338, 432.687, 1.68485, 7200,0,0, 5647, 0, 0, 0); +-- shaman: +UPDATE creature SET position_x = 2011.48, position_y = -232.79 WHERE id = 32900; +UPDATE creature SET position_x = 2011.48, position_y = -232.79 WHERE id = 32950; +DELETE FROM creature WHERE guid IN (800007); +INSERT INTO creature VALUES +(800007, 32938, 603, 2, 1,0,0, 2011.48, -232.79, 432.687, 1.68485, 7200,0,0, 5647, 0, 0, 0); +-- mage: +DELETE FROM creature WHERE guid IN (800008, 800010); +INSERT INTO creature VALUES +(800008, 33327, 603, 2, 128,0,0, 1978.49, -241.476, 432.687, 1.68485, 7200,0,0, 5647, 0, 0, 0), -- aly mage +(800010, 32938, 603, 2, 1,0,0, 1978.49, -241.476, 432.687, 1.68485, 7200,0,0, 5647, 0, 0, 0); +-- priest +UPDATE creature SET position_x = 1997.88, position_y = -239.394 WHERE id = 33330; +DELETE FROM creature WHERE guid IN (800009); +INSERT INTO creature VALUES +(800009, 32938, 603, 2, 1,0,0, 1997.88, -239.394, 432.687, 1.68485, 7200,0,0, 5647, 0, 0, 0); + +-- Mimiron +UPDATE `gameobject_template` SET `data0` = '60000' WHERE `entry` =194675; +UPDATE creature_template SET ScriptName = 'boss_mimiron' WHERE entry = 33350; +UPDATE creature_template SET `RegenHealth`= 0, ScriptName = 'boss_leviathan_mk' WHERE entry = 33432; +UPDATE creature_template SET ScriptName = 'leviathan_turret' WHERE entry = 34071; +UPDATE creature_template SET ScriptName = 'mob_mimiron_flames' WHERE entry IN (34363, 34121); +UPDATE creature_template SET `RegenHealth`= 0, ScriptName = 'boss_vx001' WHERE entry = 33651; +UPDATE creature_template SET `RegenHealth`= 0, ScriptName = 'boss_aerial_command_unit' WHERE entry = 33670; +UPDATE creature SET position_x = 2784.35, position_y = 2578.03, orientation = 3.2 WHERE id = 33350; +UPDATE creature SET position_x = 2794.86, position_y = 2597.83, orientation = 3.57, spawnMask = 3 WHERE id = 33432; +UPDATE gameobject_template SET flags = 6553632, data2 = 2000, ScriptName='go_red_button' WHERE entry = 194739; +UPDATE creature_template SET ScriptName = 'mob_proximity_mine' WHERE entry = 34362; +UPDATE creature_template SET ScriptName = 'mob_bomb_bot' WHERE entry IN (33836, 34192); +UPDATE creature_template SET `faction_A` = 14, `faction_H` = 14, `minlevel` = 80, `maxlevel` = 80, ScriptName = 'mob_emergency_bot' WHERE entry = 34147; +UPDATE creature_template SET ScriptName = 'mob_frost_bomb_ulduar' WHERE entry = 34149; +UPDATE creature_template SET ScriptName = 'mob_mimiron_inferno' WHERE entry = 33370; +UPDATE creature_template SET ScriptName = 'mob_assault_bot' WHERE entry = 34057; +UPDATE creature_template SET ScriptName = 'mob_magnetic_core' WHERE entry = 34068; +UPDATE `gameobject` SET `position_x` = 2734.73 WHERE `id` IN (194789, 194956); +-- spells, may not be correct +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('64444', '1', '33670'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('63414', '1', '33651'); +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('65101', '1', '33350'); +-- REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62909', '1', '33350'); + +-- SOME MIMIRON LOOT BOXES ARE MISSING IN YTDB, THIS IS THE FIX FOR IT! +-- mimiron loot fix: +-- INSERT two new boxes +DELETE FROM `gameobject` WHERE `id` IN (194957, 194958); +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(110004, 194957, 603, 1, 65535, 2734.73, 2568.98, 364.314, 0.0139475, 0, 0, 0.00697369, 0.999976, -604800, 100, 1); +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(110005, 194958, 603, 2, 65535, 2734.73, 2568.98, 364.314, 0.0139475, 0, 0, 0.00697369, 0.999976, -604800, 100, 1); +-- 10 man hard: +DELETE FROM `gameobject_loot_template` WHERE (`entry`=194957); +INSERT INTO `gameobject_loot_template` VALUES +(194957, 45089, 5, 0, -45089, 1, 0, 0, 0), +(194957, 45095, 2.0408, 0, 1, 1, 0, 0, 0), +(194957, 45649, 100, 0, -45649, 1, 0, 0, 0), +(194957, 45663, 0.4028, 0, 1, 1, 0, 0, 0), +(194957, 45787, -100, 0, 1, 1, 0, 0, 0), +(194957, 47241, 100, 0, 1, 1, 0, 0, 0), +(194957, 45972, 0, 1, 1, 1, 0, 0, 0), +(194957, 45973, 0, 1, 1, 1, 0, 0, 0), +(194957, 45974, 0, 1, 1, 1, 0, 0, 0), +(194957, 45975, 0, 1, 1, 1, 0, 0, 0), +(194957, 45976, 0, 1, 1, 1, 0, 0, 0), +(194957, 45982, 0, 2, 1, 1, 0, 0, 0), +(194957, 45988, 0, 2, 1, 1, 0, 0, 0), +(194957, 45989, 0, 2, 1, 1, 0, 0, 0), +(194957, 45990, 0, 2, 1, 1, 0, 0, 0), +(194957, 45993, 0, 2, 1, 1, 0, 0, 0); +-- 25 man hard: +DELETE FROM `gameobject_loot_template` WHERE (`entry`=194958); +INSERT INTO `gameobject_loot_template` VALUES +(194958, 45038, 10, 0, 1, 1, 0, 0, 0), +(194958, 45087, 33, 0, 1, 1, 0, 0, 0), +(194958, 45089, 5, 0, -45089, 1, 0, 0, 0), +(194958, 45643, 100, 0, -45643, 1, 0, 0, 0), +(194958, 45816, -100, 0, 1, 1, 0, 0, 0), +(194958, 47241, 100, 0, 1, 1, 0, 0, 0), +(194958, 45489, 0, 1, 1, 1, 0, 0, 0), +(194958, 45490, 0, 1, 1, 1, 0, 0, 0), +(194958, 45491, 0, 1, 1, 1, 0, 0, 0), +(194958, 45492, 0, 1, 1, 1, 0, 0, 0), +(194958, 45493, 0, 1, 1, 1, 0, 0, 0), +(194958, 45494, 0, 2, 1, 1, 0, 0, 0), +(194958, 45495, 0, 2, 1, 1, 0, 0, 0), +(194958, 45496, 0, 2, 1, 1, 0, 0, 0), +(194958, 45497, 0, 2, 1, 1, 0, 0, 0), +(194958, 45663, 0, 2, 1, 1, 0, 0, 0); + +-- Thorim +UPDATE creature_template SET ScriptName = 'boss_thorim' WHERE entry = 32865; +UPDATE creature_template SET ScriptName = 'boss_runic_colossus' WHERE entry = 32872; +UPDATE creature_template SET ScriptName = 'boss_ancient_rune_giant' WHERE entry = 32873; +UPDATE creature_template SET ScriptName = 'npc_lightning_orb' WHERE entry = 33138; +UPDATE creature_template SET ScriptName = 'mob_thorim_trap_bunny' WHERE entry IN (33725, 33054); +UPDATE creature_template SET ScriptName = 'mob_thorim_preadds' WHERE entry IN (32885, 32883, 32907, 32908, 32882); +UPDATE creature SET spawnMask = 3 WHERE id = 32873; +UPDATE creature_template SET ScriptName = 'npc_sif' WHERE entry = 33196; +UPDATE `gameobject` SET `position_y` = -286.67, `position_z` = 419.50 WHERE `id` IN (194312, 194313, 194314, 194315); +UPDATE gameobject_template SET flags = 6553632, ScriptName='go_thorim_lever' WHERE entry = 194264; +-- adds +UPDATE creature_template SET ScriptName = 'mob_dark_rune_acolyte' WHERE entry = 33110; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_champion' WHERE entry = 32876; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_commoner' WHERE entry = 32904; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_warbringer' WHERE entry = 32877; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_ring_guard' WHERE entry = 32874; +UPDATE creature_template SET ScriptName = 'mob_dark_rune_honor_guard' WHERE entry = 33125; + +#DELETE FROM gameobject WHERE id = 194264; +#INSERT INTO gameobject VALUES (110010,194264,603,3,65535,2173.276, -252.805, 420.146, 3.027,0,0,0,0,604800,0,1); +UPDATE `creature` SET `phaseMask` = 128 WHERE `id` IN (32907, 32883); -- horde soldiers: phase 128 for aly: 65535 +UPDATE `creature` SET `phaseMask` = 64 WHERE `id` IN (32885, 32908); -- alliance soldiers: phase 64 for horde +-- reset pos to some creatures +-- SOME POSITION ADJUSTMENTS, CHECK YOUR DB FOR THIS +/* +UPDATE creature SET spawnMask = 0 WHERE guid IN (129413, 129412, 129856, 129857); +UPDATE `creature` SET `position_x` = 2222.69 WHERE `guid` = 129413; +UPDATE `creature` SET `position_x` = 2222.69 WHERE `guid` = 129412; +UPDATE `creature` SET `position_x` = 2227.34 WHERE `guid` = 129856; +UPDATE `creature` SET `position_x` = 2227.34 WHERE `guid` = 129857; + +UPDATE `creature` SET `position_y` = -437.73 WHERE `guid` = 129860; +UPDATE `creature` SET `position_y` = -437.73 WHERE `guid` = 129861; +UPDATE `creature` SET `position_y` = -434.64 WHERE `guid` = 129862; +UPDATE `creature` SET `position_y` = -434.64 WHERE `guid` = 129863; +UPDATE `creature` SET `position_y` = -434.64 WHERE `guid` = 129391; +*/ +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('62565', '1', '32865'); + +-- Vezax +UPDATE creature_template SET unit_flags = 0, ScriptName = 'boss_vezax' WHERE entry = 33271; +UPDATE creature_template SET MinHealth = 23009250, MaxHealth = 23009250, ScriptName = 'boss_vezax' WHERE entry = 33449; +UPDATE `creature_template` SET `mechanic_immune_mask` = 619397115 WHERE `entry` IN (33271, 33449); +UPDATE creature_template SET ScriptName = 'mob_saronite_animus' WHERE entry = 33524; +UPDATE creature_template SET ScriptName = 'mob_saronite_vapor', movementType = 1 WHERE entry = 33488; + +-- Yogg +UPDATE creature_template SET ScriptName = 'boss_yogg_saron' WHERE entry = 33288; +UPDATE creature_template SET `RegenHealth`= 0, `flags_extra` = 1,`type_flags` = 108, ScriptName = 'boss_sara' WHERE entry = 33134; +UPDATE creature SET spawnMask = 3, MovementType = 0 WHERE id = 33134; +UPDATE creature_template SET `RegenHealth`= 0, ScriptName = 'boss_brain_of_yogg_saron' WHERE entry = 33890; +UPDATE creature SET `spawntimesecs` = 604800 WHERE `id` = 33134; +UPDATE creature_template SET ScriptName = 'mob_corruptor_tentacle' WHERE entry = 33985; +UPDATE creature_template SET ScriptName = 'mob_constrictor_tentacle' WHERE entry = 33983; +UPDATE creature_template SET MinHealth = 40000, MaxHealth = 40000, minLevel = 80, maxLevel = 80, ScriptName = 'mob_vision_tentacle' WHERE entry = 33943; +UPDATE creature_template SET MinHealth = 400000, MaxHealth = 400000, ScriptName = 'mob_crusher_tentacle' WHERE entry = 33966; +UPDATE creature_template SET MinHealth = 220000, MaxHealth = 220000, ScriptName = 'mob_guardian_of_yogg_saron' WHERE entry = 33136; +UPDATE creature_template SET ScriptName = 'mob_immortal_guardian' WHERE entry = 33988; +UPDATE creature_template SET `faction_A` = 14, `faction_H` = 14, ScriptName = 'mob_death_orb' WHERE entry = 33882; +UPDATE creature_template SET ScriptName = 'mob_sanity_well' WHERE entry = 33991; +UPDATE creature_template SET scriptname='mob_madness_portal' WHERE `entry`=34072; +UPDATE creature_template SET scriptname='mob_laughing_skull' WHERE `entry`=33990; +UPDATE creature_template SET scriptname='mob_ominous_cloud' WHERE `entry`=33292; +UPDATE creature SET spawnMask = 3 WHERE id = 33292; +-- spells +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES ('63886', '1', '33882'); +-- Keepers +UPDATE creature_template SET ScriptName = 'keeper_hodir' WHERE entry = 33213; +UPDATE creature_template SET ScriptName = 'keeper_freya' WHERE entry = 33241; +UPDATE creature_template SET ScriptName = 'keeper_thorim' WHERE entry = 33242; +UPDATE creature_template SET ScriptName = 'keeper_mimiron' WHERE entry = 33244; +-- INSERT doors & yoggs brain INTO the brain room +DELETE FROM gameobject WHERE id IN (194635); +INSERT INTO gameobject VALUES (110000,194635,603,3,65535,2022.490,-25.389,261.961,0,0,0,0,0,604800,0,1); +DELETE FROM gameobject WHERE guid = 110001; +INSERT INTO gameobject VALUES (110001,194462,603,3,65535,2104.555, -25.635,242.646,0,0,0,0,0,604800,100,1); +DELETE FROM creature WHERE id IN (33890); +INSERT INTO creature VALUES (800000,33890,603,3,65535,0,0,1981.422,-22.442,255.011,0,604800,0,0,1371428,0,0,0); + +-- Algalon +UPDATE creature_template SET ScriptName = 'boss_algalon' WHERE entry = 32871; +UPDATE creature_template SET ScriptName = 'mob_collapsing_star' WHERE entry = 32955; +UPDATE creature_template SET ScriptName = 'mob_living_constellation' WHERE entry = 33052; +UPDATE creature_template SET ScriptName = 'mob_black_hole' WHERE entry = 32953; +UPDATE creature_template SET ScriptName = 'mob_cosmic_smash_target' WHERE entry IN (33105, 33104); +UPDATE creature_template SET minhealth = 39099, maxhealth = 39099 WHERE entry = 33089; +UPDATE gameobject_template SET flags= 6553632, ScriptName='go_celestial_acces' WHERE entry IN (194628, 194752); + +-- Teleporter +UPDATE `gameobject_template` SET `flags` = 0, `ScriptName` = 'go_ulduar_teleporter' WHERE `entry` IN (194569); + +-- Keepers +-- Keepers images +UPDATE creature_template SET `npcflag` = 1, `unit_flags` = 2, ScriptName = 'hodir_image' WHERE entry = 33411; +UPDATE creature_template SET `npcflag` = 1, `unit_flags` = 2, ScriptName = 'freya_image' WHERE entry = 33410; +UPDATE creature_template SET `npcflag` = 1, `unit_flags` = 2, ScriptName = 'thorim_image' WHERE entry = 33413; +UPDATE creature_template SET `npcflag` = 1, `unit_flags` = 2, ScriptName = 'mimiron_image' WHERE entry = 33412; +-- INSERT keepers imagees INTO the db +DELETE FROM creature WHERE guid IN (800001, 800002, 800003, 800004); +INSERT INTO creature VALUES +(800001, 33410, 603, 3, 65535,0,0, 2036.892, 25.621, 411.358, 3.83, 604800,0,0, 5647, 0, 0, 0), -- Freya +(800002, 33412, 603, 3, 65535,0,0, 1939.215, 42.677, 411.355, 5.31, 604800,0,0, 5647, 0, 0, 0), -- Mimiron +(800003, 33411, 603, 3, 65535,0,0, 1939.195, -90.662, 411.357, 1.06, 604800,0,0, 5647, 0, 0, 0), -- Hodir +(800004, 33413, 603, 3, 65535,0,0, 2036.674, -73.814, 411.355, 2.51, 604800,0,0, 5647, 0, 0, 0); -- Thorim + +-- Doors +UPDATE gameobject_template SET faction = 114 WHERE entry IN (194553, 194554, 194556, 194148, 194634, 194635, 194905, 194441, +194442, 194416, 194774, 194775, 194776, 194560, 194557, 194558, 194750, 194910, 194559, 194635, 194636, 194637, 194631, 194255, 194630, 194767); +UPDATE gameobject_template SET faction = 114, `flags` = 4 WHERE entry IN (192075, 194173); -- snowdrifts +-- consoles +UPDATE gameobject_template SET faction = 0 WHERE entry IN (194555, 194628); + +-- loot chests +UPDATE gameobject_template SET faction = 0, data15 = 1 WHERE entry IN (195046, 195047, 194307, 194308, 194200, 194201, 194312, 194313, 194314, 194315, 194821, +194822, 194823, 194324, 194325, 194326, 194327, 194328, 194329, 194330, 194331, 194789, 194956, 194957, 194958); +UPDATE gameobject SET spawntimesecs = -604800 WHERE id IN (195046, 195047, 194307, 194308, 194200, 194201, 194312, 194313, 194314, 194315, 194821, +194822, 194823, 194324, 194325, 194326, 194327, 194328, 194329, 194330, 194331, 194789, 194956); + +-- NOT SURE IF THE TRASH MOBS ARE SCRIPTED BY EVENTAI +-- Mobs +UPDATE creature_template SET ScriptName = 'generic_creature' WHERE entry IN (34086, 34085, 34069, 33237, 34234, 33236, 33264, 34164, 34196, 34199, 34198, +34190, 34197, 33699, 34134, 34135, 34133, 33430, 33528, 33431, 33527, 33526, 33525, 33355, 33354, 34193, 34183, 33110, +32878, 33822, 33818, 33824, 33823, 33772, 33838, 33819, 33820, 32875, 33346, 34057); diff --git a/addition/733_scriptdev2_ulduar.sql b/addition/733_scriptdev2_ulduar.sql new file mode 100644 index 000000000..60140518a --- /dev/null +++ b/addition/733_scriptdev2_ulduar.sql @@ -0,0 +1,313 @@ +/* ULDUAR from Xfurry*/ +-- ids may need to be rewritten +DELETE from `script_texts` where `entry` between -1603500 and -1603000; +-- translate from lanc +REPLACE INTO `script_texts` (entry, content_default, content_loc1, content_loc2, content_loc3, content_loc4, content_loc5, content_loc6, content_loc7, content_loc8, sound, type, language, emote, comment) VALUES +-- Leviathan: needs intro & outro +(-1603201,"Threat assessment routine modified. Current target threat level: zero. Acquiring new target.","","","","","","","","Изменение в протоколе оценки угрозы. Уровень угрозы текущей цели: нулевой. Поиск новой цели.",15521,1,0,0,"Flame Leviathan Slay"), +(-1603202,"Total systems failure. Defense protocols breached. Leviathan Unit shutting down.","","","","","","","","Общий системный сбой. Отказ защитных протоколов. Боевая единица Левиафан завершает свою работу.",15520,1,0,0,"Flame Leviathan Death"), +(-1603203,"Hostile entities detected. Threat assessment protocol active. Primary target engaged. Time minus thirty seconds to re-evaluation.","","","","","","","","Обнаружены противники. Запуск протокола оценки угрозы. Главная цель выявлена. Повторный анализ через тридцать секунд.",15506,1,0,0,"Flame Leviathan Aggro"), +(-1603204,"Threat re-evaluated. Target assessment complete. Changing course.","","","","","","","","Повторный анализ угрозы - завершен. Оценка цели - проведена. Смена курса.",15507,1,0,0,"Flame Leviathan change1"), +(-1603205,"Pursuit objective modified. Changing course.","","","","","","","","Изменение цели преследования. Смена курса.",15508,1,0,0,"Flame Leviathan change2"), +(-1603206,"Hostile entity stratagem predicted. Rerouting battle function. Changing course.","","","","","","","","Вражеский маневр предупрежден. Перерасчет параметра боевых функций. Смена курса.",15509,1,0,0,"Flame Leviathan change3"), +(-1603207,"Unauthorized entity attempting circuit overload. Activating anti-personnel countermeasures.","","","","","","","","Несанкционированное вмешательство в работу. Активация системы подавления живой силы.",15516,1,0,0,"Flame Leviathan player on top"), +(-1603208,"System malfunction. Diverting power to support systems.","","","","","","","","Функциональный сбой. Активация резервных систем.",15517,1,0,0,"Flame Leviathan overload1"), +(-1603209,"Combat matrix overload. Powering do-o-o-own...","","","","","","","","Боевая матрица перегружена. Отключи....",15518,1,0,0,"Flame Leviathan overload2"), +(-1603210,"System restart required. Deactivating weapon systems.","","","","","","","","Требуется перезапуск. Отключение систем вооружения.",15519,1,0,0,"Flame Leviathan overload3"), +(-1603211,"Orbital countermeasures enabled.","","","","","","","","Система орбитального подавления - включена.",15510,1,0,0,"Flame Leviathan hard mode"), +(-1603212,"Alert! Static defense system failure. Orbital countermeasures disabled.","","","","","","","","Тревога! Сбой стационарных средств защиты. Система орбитального подавления - отключена.",15511,1,0,0,"Flame Leviathan towers down"), +(-1603213,"'Hodir's Fury' online. Acquiring target.","","","","","","","","Ярость Ходира - активирована. Поиск цели.",15512,1,0,0,"Flame Leviathan frost"), +(-1603214,"'Mimiron's Inferno' online. Acquiring target.","","","","","","","","Адский огонь Мимирона - активировано. Поиск цели.",15513,1,0,0,"Flame Leviathan fire"), +(-1603215,"'Thorim's Hammer' online. Acquiring target.","","","","","","","","Молот Торима - активирован. Поиск цели.",15515,1,0,0,"Flame Leviathan energy"), +(-1603216,"'Freya's Ward' online. Acquiring target.","","","","","","","","Оберег Фреи - активировано. Поиск цели.",15514,1,0,0,"Flame Leviathan nature"), +(-1603352,'PursueWarn' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_pursue'), + +-- Ignis: +(-1603010, "Insolent whelps! Your blood will temper the weapons used to reclaim this world!", "","","","","","","","Мерзкие глупцы! Ваша кровь закалит оружие, которым был завоеван этот мир!",15564, 1, 0, 0, 'IgnisAggro'), +(-1603011, "Let the inferno consume you!", "","","","","","","","Да поглотит вас пламя преисподней!",15567, 1, 0, 0, 'Ignis Scorch1'), +(-1603012, "BURN! Burn in the makers fire!", "","","","","","","","Горите! Горите в огне творца!",15568, 1, 0, 0, 'Ignis scroch2'), +(-1603013, "I will burn away your impurities!", "","","","","","","","Пройдите очищение огнем!",15566, 1, 0, 0, 'Ignis Slagpot'), +(-1603014, 'Ignis the Furnace Master begins to cast Flame Jets!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_FLAME_JETS'), +(-1603015, "Arise, soldiers of the Iron Crucible! The Makers\' will be done!", "","","","","","","","Вперед, воины Железного Тетинга! Да свершиться воля творца!",15565, 1, 0, 0, 'Ignis summon'), +(-1603016, "More scraps for the scrapheap!", "","","","","","","","Тебе место в мусорной куче!",15569, 1, 0, 0, 'IgnisSlay1'), +(-1603017, "Your bones will serve as kindling!", "","","","","","","","Твой кости пойдут на растопку!",15570, 1, 0, 0, 'IgnisSlay2'), +(-1603018, "Let it be finished!", "","","","","","","","Покончим с этим!",15571, 1, 0, 0, 'IgnisBerserk'), +(-1603019, "I. Have. Failed.", "","","","","","","","Я... Проиграл...",15572, 1, 0, 0, 'Ignis death'), + +-- razorscale +(-1603020,'Welcome, champions! All of our attempts at grounding her have failed. We could use a hand in bring her down with these harpoon guns.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Приветствую вас герои! Все наши попытки сбить ее не увенчались успехом. Нам бы пригодилась ваша помощь, гарпунных пушек на всех хватит.",15647,0,0,0,'razorscale intro - commander'), +(-1603021,'Give us a moment to prepare to build the turrets.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0,'razor aggro 1 - eng'), +(-1603022,'Be on the lookout! Mole machines will be surfacing soon with those nasty Iron dwarves aboard!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0,'razor aggro 2 - commander'), +(-1603023,'Ready to move out, keep those dwarves off of our backs!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0,'razor aggro 3 - eng'), +(-1603024,'Move! Quickly! She won\'t remain grounded for long.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Быстрее! Она скоро снова взлетит.",0,1,0,0,'razor ground - commander'), +(-1603025,'Razorscale takes a deep breath...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'razor deep breath'), +(-1603026,'Fires out! Let\'s rebuild those turrets!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0,'razor extinguish fires'), +(-1603353,'Harpoon Turret is ready for use!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_harpoon'), +(-1603354,'Razorscale grounded permanently!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_ground'), + +-- Xt002 +(-1603030,"You are bad... Toys... Very... Baaaaad!","","","","","","","","Плохие игрушки... Очень... Плохие!",15731,1,0,0,"XT-002 Death"), +(-1603031,"I'm tired of these toys. I don't want to play anymore!","","","","","","","","Какие скучные игрушки. Надоело играть!",15730,1,0,0,"XT-002 Berserk"), +(-1603032,"Time for a new game! My old toys will fight my new toys!","","","","","","","","Новые правила! Старые игрушки против новых!",15732,1,0,0,"XT-002 Adds"), +(-1603033,"I'm ready to play!","","","","","","","","Продолжаем игру!",15726,1,0,0,"XT-002 Heart Closed"), +(-1603034,"So tired. I will rest for just a moment!","","","","","","","","Я так устал. Отдохну чуток!",15725,1,0,0,"XT-002 Heart Opened"), +(-1603035,"I guess it doesn't bend that way.","","","","","","","","Наверное в эту сторону голова не гнулась.",15729,1,0,0,"XT-002 Slay 2"), +(-1603036,"I... I think I broke it.","","","","","","","","Кажется... Я сломал эту игрушку.",15728,1,0,0,"XT-002 Slay 1"), +(-1603037,"NO! NO! NO! NO! NO!","","","","","","","","Неееет! Нет! Нет! Нет! Нет!",15727,1,0,0,"XT-002 Tympanic Tantrum"), +(-1603038,"New toys? For me? I promise I won't break them this time!","","","","","","","","Новые игрушки? Для меня? Обещаю, в этот раз я их не поламаю!",15724,1,0,0,"XT-002 Aggro"), +(-1603350,'XT-002 Deconstructor\'s heart is exposed and leaking energy!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_expose_heart'), +(-1603351,'XT-002 Deconstructor consumes a scrapbot to repair himself.' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_repair'), + +-- Iron Council +-- Molgeim +(-1603040,"Nothing short of total decimation will suffice!","","","","","","","","",15657,1,0,0,"MolgeimAggro"), +(-1603041, "The legacy of storms shall not be undone...", "","","","","","","","",15662, 1, 0, 0, "MolgeimDeath1"), +(-1603042, "What have you gained from my defeat? You are no less doomed, mortals...", "","","","","","","","",15663, 1, 0, 0, 'MolgeimDeath2'), +(-1603043, "Decipher this!", "","","","","","","","",15660, 1, 0, 0, 'MolgeimDeathRune'), +(-1603044, "Face the lightning surge!", "","","","","","","","",15661, 1, 0, 0, 'MolgeimSummon'), +(-1603045, "The world on suffers yet another insignificant loss!", "","","","","","","","",15658, 1, 0, 0, 'MolgeimSlay1'), +(-1603046, "Death is the price of your arrogance.", "","","","","","","","",15659, 1, 0, 0, 'MolgeimSlay2'), +(-1603047, "This meeting of the Assembly of Iron is adjourned!", "","","","","","","","",15664, 1, 0, 0, 'MolgeimBerserk'), +-- Steelbreaker +(-1603050, "You will not defeat the Assembly of Iron so easily, invaders!", "","","","","","","","",15674, 1, 0, 0, 'SteelAggro'), +(-1603051, "My death only serves to hasten your demise.", "","","","","","","","",15678, 1, 0, 0, 'SteelDeath1'), +(-1603052, "Impossible!", "","","","","","","","",15679, 1, 0, 0, 'SteelDeath2'), +(-1603053, "So fragile and weak!", "","","","","","","","",15675, 1, 0, 0, 'SteelSlay1'), +(-1603054, "Flesh... such a hindrance.", "","","","","","","","",15676, 1, 0, 0, 'SteelSlay2'), +(-1603055, "You seek the secrets of Ulduar? Then take them!", "","","","","","","","",15677, 1, 0, 0, 'SteelOverwhelming'), +(-1603056, "This meeting of the Assembly of Iron is adjourned!", "","","","","","","","",15680, 1, 0, 0, 'SteelBerserk'), +-- Brudir +(-1603060, "Whether the world\'s greatest gnats or the world\'s greatest heroes, you\'re still only mortal.", "","","","","","","","",15684, 1, 0, 0, 'BrundirAggro'), +(-1603062, "Stand still and stare into the light!", "","","","","","","","",15687, 1, 0, 0, 'BrundirWhirl'), +(-1603063, "The power of the storm lives on...", "","","","","","","","",15689, 1, 0, 0, 'BrundirDeath1'), +(-1603064, "You rush headlong into the maw of madness!", "","","","","","","","",15690, 1, 0, 0, 'BrundirDeath2'), +(-1603065, "A merciful kill!", "","","","","","","","",15685, 1, 0, 0, 'BrundirSlay1'), +(-1603066, "HAH!", "","","","","","","","",15686, 1, 0, 0, 'BrundirSlay2'), +(-1603067, "This meeting of the Assembly of Iron is adjourned!", "","","","","","","","",15691, 1, 0, 0, 'BrundirBerserk'), +(-1603068, "Let the storm clouds rise and rain down death from above!", "","","","","","","","",15688, 1, 0, 0, 'BrundirFly'), + +-- Kologarn: +(-1603150, "None shall pass!", "","","","","","","","Вам не пройти!",15586, 1, 0, 0, 'KologarnAggro'), +(-1603151, "OBLIVION!", "","","","","","","","Забвение",15591, 1, 0, 0, 'Kologarn shockweave'), +(-1603152, "I will squeeze the life from you!", "","","","","","","","Я лишу тебя жизни!",15592, 1, 0, 0, 'Kologarn grab'), +(-1603153, "Just a scratch!", "","","","","","","","Царапина!",15589, 1, 0, 0, 'left arm lost'), +(-1603154, "Only a flesh wound!", "","","","","","","","Всего лиш плоть!",15590, 1, 0, 0, 'right arm lost'), +(-1603155, "KOL-THARISH!", "","","","","","","","Кол-Таариш!",15587, 1, 0, 0, 'KologarnSlay1'), +(-1603156, "YOU FAIL!", "","","","","","","","Тебе конец!",15588, 1, 0, 0, 'KologarnSlay2'), +(-1603157, "I am invincible!", "","","","","","","","Я не победим!",15594, 1, 0, 0, 'KologarnBerserk'), +(-1603158, "Master, they come...", "","","","","","","","Повелитель, они идут...",15593, 1, 0, 0, 'Kologarndeath'), +(-1603355,'The Right Arm has regrown!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_right hand'), +(-1603356,'The Left Arm has regrown!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_left hand'), +(-1603357,'Kologarn casts Stone Grip!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_stone grip'), + +-- Auriaya: +(-1603070,"Some things are better left alone!","","","","","","","","Вы зря сюда заявились!",15473,1,0,0,"auriaya aggro"), +(-1603071,"The secret dies with you!","","","","","","","","Эта тайна умрет вместе с тобой!",15474,1,0,0,"auriaya Slay 1"), +(-1603072,"There is no escape!","","","","","","","","Спасения нет!",15475,1,0,0,"auriaya Slay 2"), +(-1603073,"You waste my time!","","","","","","","","Вы попусту тратите мое время!",15477,1,0,0,"auriaya berserk"), +(-1603074,"Auriaya screams in agony.","","","","","","","","Ааааааааааааааааааааа!",15476,2,0,0,"auriaya death"), +(-1603358,'Auriaya begins to cast Terrifying Screech.' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_screech'), +(-1603359,'Auriaya begins to activate the Feral Defender!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_defender'), + +-- Hodir +(-1603080,"","","","","","","","","",15556,2,0,0,"Hodir Frozen Blows"), +(-1603081,"Winds of the north consume you!","","","","","","","","Да поглотят вас северные ветры!",15555,1,0,0,"Hodir Flash Freeze"), +(-1603082,"Welcome to the endless winter.","","","","","","","","Отправляйся туда, где вечная зима.",15554,1,0,0,"Hodir Slay 2"), +(-1603083,"Tragic. To come so far, only to fail.","","","","","","","","Как трагично. Проделать такой путь, чтобы умереть.",15553,1,0,0,"Hodir Slay 1"), +(-1603084,"I... I am released from his grasp... at last.","","","","","","","","Наконецто... Я... Свободен... От его оков.",15557,1,0,0,"Hodir Death"), +(-1603085,"You will suffer for this trespass!","","","","","","","","Вы будете наказаны за это вторжение!",15552,1,0,0,"Hodir Aggro"), +(-1603086,"The veil of winter will protect you, champions!","","","","","","","","Герои, вас защитит покров зимы!",15559,1,0,0,"Hodir yogg"), +(-1603087,"Enough! This ends now!","","","","","","","","Ну хватит! Больше вам не жить!",15558,1,0,0,"Hodir berserk"), +(-1603360,'Hodir begins to cast Flash Freeze!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_flash freeze'), +(-1603361,'Hodir gains Frozen Blows!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_frozen blows'), + +-- Freya: +(-1603000,"The Conservatory must be protected!","","","","","","","","Нужно защитить оранжерею!",15526,1,0,0,"freya aggro"), +(-1603001,"Elders, grant me your strength!","","","","","","","","Древние, дайте мне силы!",15527,1,0,0,"freya aggro hard"), +(-1603002,"Eonar, your servant requires aid!","","","","","","","","Эонар, твоей прислужнице нужна помощь!",15528,1,0,0,"summon conservator"), +(-1603003,"Children, assist me!","","","","","","","","Помогите мне, дети мои!",15533,1,0,0,"summon trio"), +(-1603004,"The swarm of the elements shall overtake you!","","","","","","","","Вас захлестнет сила стихий!",15534,1,0,0,"summon lashers"), +(-1603005,"Forgive me.","","","","","","","","Прости меня.",15529,1,0,0,"freya slay1"), +(-1603006,"From your death springs life anew!","","","","","","","","Твоя смерть даст начало новой жизни!",15530,1,0,0,"freya slay2"), +(-1603007,"His hold on me dissipates. I can see clearly once more. Thank you, heroes.","","","","","","","","Он больше не властен надо мной. Мой взор снова ясен. Благадорю вас, герои.",15531,1,0,0,"freya Death"), +(-1603008,"You have strayed too far, wasted too much time!","","","","","","","","Вы проделали весь этот путь, впустую!",15532,1,0,0,"freya berserk"), +(-1603009,"Eonar, your servant calls for your blessing!","","","","","","","","Эонар, прошу тебя даруй свое благословение!",15535,1,0,0,"freya yogg"), +(-1603362,'Allies of Nature have appeared!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_allies'), +(-1603363,'A Lifebinder\'s Gift begins to grow!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_lifebinders'), +(-1603364,'Freya begins to cast Ground Tremor!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_ground tremor'), +(-1603365,'Freya casts Strenghtened Iron Roots!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_iron roots'), +-- Brightleaf +(-1603160,"Matron, the Conservatory has been breached!","","","","","","","","",15483,1,0,0,"brightleaf aggro"), +(-1603161,"Fertilizer.","","","","","","","","",15485,1,0,0,"brightleaf slay1"), +(-1603162,"Your corpse will nourish the soil!","","","","","","","","",15486,1,0,0,"brightleaf slay2"), +(-1603163,"Matron, one has fallen!","","","","","","","","",15487,1,0,0,"brightleaf dead"), +-- Ironbranch +(-1603170,"Mortals have no place here!","","","","","","","","",15493,1,0,0,"ironbranch aggro"), +(-1603171,"I return you whence you came!","","","","","","","","",15494,1,0,0,"ironbranch slay1"), +(-1603172,"BEGONE!","","","","","","","","",15495,1,0,0,"ironbranch slay2"), +(-1603173,"Freya! They come for you.","","","","","","","","",15496,1,0,0,"summon trio"), +-- Stonebark +(-1603180,"This place will serve as your graveyard.","","","","","","","","",15500,1,0,0,"stonebark aggro"), +(-1603181,"","","","","","","","","",15501,1,0,0,"stonebark slay1"), +(-1603182,"Such a waste.","","","","","","","","",15502,1,0,0,"stonebark slay2"), +(-1603183,"Matron, flee! They are ruthless....","","","","","","","","",15503,1,0,0,"stonebark death"), + +-- Thorim: +(-1603221,"Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...","","","","","","","","",15733,1,0,0,"thorim aggro 1"), +(-1603222,"I remember you... In the mountains... But you... what is this? Where am--","","","","","","","","",15734,1,0,0,"thorim aggro 2"), +(-1603223,"Behold the power of the storms and despair!","","","","","","","","",15735,1,0,0,"thorim special 1"), +(-1603224,"Do not hold back! Destroy them!","","","","","","","","",15736,1,0,0,"thorim special 2"), +(-1603225,"Have you begun to regret your intrusion?","","","","","","","","",15737,1,0,0,"thorim special 3"), +(-1603226,"Impertinent whelps! You dare challenge me atop my pedestal! I will crush you myself!","","","","","","","","",15738,1,0,0,"thorim jump"), +(-1603227,"Can't you at least put up a fight!?","","","","","","","","",15739,1,0,0,"thorim slay1"), +(-1603228,"Pathetic!","","","","","","","","",15740,1,0,0,"thorim slay2"), +(-1603229,"My patience has reached its limit!","","","","","","","","",15741,1,0,0,"Thorim berserk"), +(-1603230,"Failures! Weaklings!","","","","","","","","",15742,1,0,0,"thorim arena wipe"), +(-1603231,"Stay your arms! I yield!","","","","","","","","",15743,1,0,0,"thorim defeat"), +(-1603232,"I feel as though I am awakening from a nightmare, but the shadows in this place yet linger.","","","","","","","","",15744,1,0,0,"thorim outro n1"), +(-1603233,"Sif... was Sif here? Impossible--she died by my brother's hand. A dark nightmare indeed....","","","","","","","","",15745,1,0,0,"thorim outro n2"), +(-1603234,"I need time to reflect.... I will aid your cause if you should require it. I owe you at least that much. Farewell.","","","","","","","","",15746,1,0,0,"thorim outro n3"), +(-1603235,"You! Fiend! You are not my beloved! Be gone!","","","","","","","","",15747,1,0,0,"thorim outro hard1"), +(-1603236,"Behold the hand behind all the evil that has befallen Ulduar! Left my kingdom in ruins, corrupted my brother and slain my wife!","","","","","","","","",15748,1,0,0,"thorim outro hard2"), +(-1603237,"And now it falls to you, champions, to avenge us all! The task before you is great, but I will lend you my aid as I am able. You must prevail!","","","","","","","","",15749,1,0,0,"thorim outro hard3"), +(-1603238,"Golganneth, lend me your strengh! Grant my mortal allies the power of thunder!","","","","","","","","",15750,1,0,0,"thorim yogg"), +-- Sif: +(-1603185,"Thorim, my lord, why else would these invaders have come into your sanctum but to slay you? They must be stopped!","","","","","","","","",15668,1,0,0,"sif start"), +(-1603186,"Impossible! Lord Thorim, I will bring your foes a frigid death!","","","","","","","","",15670,1,0,0,"sif event"), +(-1603187,"These pathetic mortals are harmless, beneath my station. Dispose of them!","","","","","","","","",15669,1,0,0,"sif despawn"), +(-1603369,'Runic Colossus surrounds itself with a crackling Runic Barrier!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_barrier'), +(-1603370,'Ancient Rune Giant fortifies nearby allies with runic might!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_barrier'), + +-- Mimiron: +(-1603241,"Oh, my! I wasn't expecting company! The workshop is such a mess! How embarrassing!","","","","","","","","Вот те на! Я не ждал гостей! Тут везде такой безпорядок! Как не ловко!",15611,1,0,0,"mimiron aggro"), +(-1603242,"Now why would you go and do something like that? Didn't you see the sign that said 'DO NOT PUSH THIS BUTTON!'? How will we finish testing with the self-destruct mechanism active?","","","","","","","","Так, зачем вы это сделали? Разве вы не видели табличку 'НЕ НАЖИМАЙТЕ ЭТУ КНОПКУ!'? Ну как мы сумеем завершить испытания при включенном механизме самоликвидации, ааа?",15629,1,0,0,"mimiron hard mode"), +(-1603243,"Oh, my! It would seem that we are out of time, my friends!","","","","","","","","Ааа! Очевидно наше время истекло, друзья мои!",15628,1,0,0,"mimiron berserk"), +(-1603244,"We haven't much time, friends! You're going to help me test out my latest and greatest creation. Now, before you change your minds, remember, that you kind of owe it to me after the mess you made with the XT-002.","","","","","","","","У нас мало времени, друзья! Вы поможете испытать новейшие и величайшие из моих изобретений, и учтите, после того что вы натворили с ХТ002, отказыватся просто не красиво.",15612,1,0,0,"tank active"), +(-1603245,"MEDIC!","","","","","","","","ДОКТОРА!",15613,1,0,0,"tank kill1"), +(-1603246,"I can fix that... or, maybe not! Sheesh, what a mess...","","","","","","","","Я могу починить это... а может и не могу! Ну и бардак...",15614,1,0,0,"tank kill2"), +(-1603247,"WONDERFUL! Positively marvelous results! Hull integrity at 98.9 percent! Barely a dent! Moving right along.","","","","","","","","Превосходно! Просто восхитительный результат! Целостность обшивки 98.9 процента! Почти что не царапинки! Продолжаем.",15615,1,0,0,"tank dead"), +(-1603248,"Behold the VX-001 Anti-personnel Assault Cannon! You might want to take cover.","","","","","","","","Представляю вам противопехотную штормовую пушку - VX-001! советую поискать укрытие.",15616,1,0,0,"torso active"), +(-1603249,"Fascinating. I think they call that a 'clean kill'.","","","","","","","","Потрясающе. Помоему это называется 'Прямо в яблочко'.",15617,1,0,0,"torso kill1"), +(-1603250,"Note to self: Cannon highly effective against flesh.","","","","","","","","Надо запомнить: Пушка крайне эффективна против созданий из плоти и крови.",15618,1,0,0,"torso kill2"), +(-1603251,"Thank you, friends! Your efforts have yielded some fantastic data! Now, where did I put-- oh, there it is!","","","","","","","","Спасибо друзья! Благодаря вам я получил ценнейшие сведения! Так, куда же я дел... ах, вот куда!",15619,1,0,0,"torso dead"), +(-1603252,"Isn't it beautiful? I call it the magnificent aerial command unit!","","","","","","","","Ха! Ха! Ха! Ха! Красота правда? Я называю это непревзойденной воздушной боевой единицей!",15620,1,0,0,"head active"), +(-1603253,"Outplayed!","","","","","","","","Обхитрил!",15621,1,0,0,"head kill1"), +(-1603254,"You can do better than that!","","","","","","","","Плохо стараешся!",15622,1,0,0,"head kill2"), +(-1603255,"Preliminary testing phase complete. Now comes the true test!!","","","","","","","","Фаза предварительной проверки завершена. Пора начать главный тест! Ха! Ха! Ха! Ха!",15623,1,0,0,"head defeat"), +(-1603256,"Gaze upon its magnificence! Bask in its glorious, um, glory! I present you... V-07-TR-0N!","","","","","","","","Насладитесь его великолепием! Грейтесь в его сияющем, эмм, сиянии! Перед вами потрясающий - V-07-ДР-ОН",15624,1,0,0,"robot active"), +(-1603257,"Prognosis: Negative!","","","","","","","","Прогноз: Негативный!",15625,1,0,0,"robot kill1"), +(-1603258,"You're not going to get up from that one, friend.","","","","","","","","От этого тебе не оправится, дружок.",15626,1,0,0,"robot kill2"), +(-1603259,"It would appear that I've made a slight miscalculation. I allowed my mind to be corrupted by the fiend in the prison, overriding my primary directive. All systems seem to be functional now. Clear.","","","","","","","","Очевидно я совершил не большую ошибку в расчетах. Пленный злодей затуманил мой разум и заставил меня отклониться от инструкций. Сейчас все системы в норме. Конец связи!",15627,1,0,0,"robot defeat"), +(-1603260,"Combat matrix enhanced. Behold wonderous rapidity!","","","","","","","","Боевая матрица разширена. Оо, какая невероятная скорость!",15630,1,0,0,"mimiron yogg"), +(-1603371,"Leviathan Mk II begins to cast Plasma Blast!" ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_plasma_blast'), +(-1606241,"Self-destruct sequence initiated.","","","","","","","","Отсчет времени до самоуничтожения начат.",15413,1,0,0,"mimiron aggro"), +(-1606242,"This area will self-destruct in ten minutes.","","","","","","","","Самоуничтожение области через десять минут.",15415,1,0,0,"mimiron aggro"), +(-1606243,"This area will self-destruct in nine minutes.","","","","","","","","Самоуничтожение области через девять минут.",15416,1,0,0,"mimiron aggro"), +(-1606244,"This area will self-destruct in eight minutes.","","","","","","","","Самоуничтожение области через восемь минут.",15417,1,0,0,"mimiron aggro"), +(-1606245,"This area will self-destruct in seven minutes.","","","","","","","","Самоуничтожение области через семь минут.",15418,1,0,0,"mimiron aggro"), +(-1606246,"This area will self-destruct in six minutes.","","","","","","","","Самоуничтожение области через шесть минут.",15419,1,0,0,"mimiron aggro"), +(-1606247,"This area will self-destruct in five minutes.","","","","","","","","Самоуничтожение области через пять минут.",15420,1,0,0,"mimiron aggro"), +(-1606248,"This area will self-destruct in four minutes.","","","","","","","","Самоуничтожение области через четыре минуты.",15421,1,0,0,"mimiron aggro"), +(-1606249,"This area will self-destruct in three minutes.","","","","","","","","Самоуничтожение области через три минуты.",15422,1,0,0,"mimiron aggro"), +(-1606250,"This area will self-destruct in two minutes.","","","","","","","","Самоуничтожение области через две минуты.",15423,1,0,0,"mimiron aggro"), +(-1606251,"This area will self-destruct in one minute.","","","","","","","","Самоуничтожение области через одну минуту.",15424,1,0,0,"mimiron aggro"), +(-1606252,"The self-destruction timer is over. Have a nice day.","","","","","","","","Отсчет времени до самоуничтожения завершен. Всего хорошего.",15425,1,0,0,"mimiron aggro"), +(-1606253,"The self-destruction timer canceled. Exit code A905.","","","","","","","","Отсчет времени до самоуничтожения прерван. Код отмены А905.",15414,1,0,0,"mimiron aggro"), + +-- vezax +(-1603120,'Your destruction will herald a new age of suffering!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Ваша смерть возвестит новую эру страданий!",15542,1,0,0,'vezax aggro'), +(-1603121,'You thought to stand before the legions of death... and survive?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Тебе не выстоять перед легионом смерти...",15543,1,0,0,'vezax kill1'), +(-1603122,'Defiance... a flaw of mortality.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Неповиновение... Ха, ха, ха, ха, это слабость смертных.",15544,1,0,0,'vezax kill2'), +(-1603123,'The black blood of Yogg-Saron courses through me! I. AM. UNSTOPPABLE!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Во мне течет черная кровь Йогг-Сарона! Меня не остановить!",15545,1,0,0,'vezaz surge'), +(-1603124,'Oh, what horrors await....',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Ха! Ха! Ха! Ха... Какие ужасы вас ожидают...",15546,1,0,0,'vezax death'), +(-1603125,'Your defeat was inevitable!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Ваше поражение, было неизбежно!",15547,1,0,0,'vezax enrage'), +(-1603126,'Behold, now! Terror, absolute!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Познайте, же! Абсолютный, ужас!",15548,1,0,0,'vezax hard'), +(-1603366,'A cloud of saronite vapors coalesces nearby!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_vapors'), +(-1603367,'General Vezax roars and surges with dark might!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_might'), +(-1603368,'The saronite vapors mass and swirl violently, merging into a monstrous form!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_animus'), + +-- Yogg: +-- Sara: +(-1603300,'The time to strike at the head of the beast will soon be upon us! Focus your anger and hatred on his minions!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Скоро мы сразимся с главарем этих извергов! Обратите гнев и ненависть против его прислужников!",15775,1,0,0,'sara aggro'), +(-1603301,'Yes! YES! Show them no mercy! Give no pause to your attacks!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Да! ДА! Не щадите их! Бейте без промахов!",15773,1,0,0,'sara help1'), +(-1603302,'Let hatred and rage guide your blows!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Пусть ненависть и ярость направляют ваши удары!",15774,1,0,0,'sara help2'), +(-1603303,'Could they have been saved?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Был ли у них шанс на спасение?",15779,1,0,0,'sara kill1'), +(-1603304,'Powerless to act...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Какое безсилие...",15778,1,0,0,'sara kill 1'), +(-1603305,'Tremble, mortals, before the coming of the end!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Трепищите, смертные, конец близок!",15777,1,0,0,'sara yell2 p2'), +(-1603306,'Suffocate upon your own hate!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Задохнитесь в собственной ненависти!",15776,1,0,0,'sara yell1 p1'), +(-1603307,'Aaaaaaaaaaaaaaaaa... Help me!!! Please got to help me!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Ааааааааа... На помощь! Помогите отделаться от них!",15771,1,0,0,'sara prefight'), +(-1603308,'What do you want from me? Leave me alone!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Что вам нужно? Прочь от меня!",15772,1,0,0,'sara prefight2'), +(-1603309,'Weak-minded fools!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Вот тупица!",15780,4,0,0,'sara slay phase1'), + +-- Yogg: +(-1603321,'I am the lucid dream. The monster in your nightmares. The fiend of a thousand faces. Cower before my true form. BOW DOWN BEFORE THE GOD OF DEATH!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Я... Это сон на яву. Чудовище из ваших кошмаров. Демон с тысячью лиц. Трепещите, ибо Я обретаю истинную форму. ПАДИТЕ ВНИЗ ПЕРЕД БОГОМ СМЕРТИ!",15754,1,0,0,'yogg p2 intro'), +(-1603322,'MADNESS WILL CONSUME YOU!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Безумие поглотит вас!",15756,1,0,0,'yogg vision'), +(-1603323,'Look upon the true face of death and know that your end comes soon!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Взгляните в истинное лицо смерти и знайте, что ваш конец близок!",15755,1,0,0,'yogg phase 3'), +(-1603324,'Hoohehehahahaha... AHAHAHAHAHAHA!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Уммхехехахахаха... ХАХАХАХАХАХАХАХА!",15757,1,0,0,'yogg slay1'), +(-1603325,'Eternal suffering awaits!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Впереди вечные страдания!",15758,1,0,0,'yogg slay2'), +(-1603326,'Your fate is sealed. The end of days is finally upon you and ALL who inhabit this miserable little seedling. Uulwi ifis halahs gag erh\'ongg w\'ssh.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Хахахахахаха! Вы обречены. Не вы, никто другой, не в силах избежать близящегося конца света. Ульви ифи Халаш гага вонг ущь.",15761,1,0,0,'yogg death'), +(-1603327,'Your will is no longer you own...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Вы теперь в моей власти...",15759,4,0,0,'yogg insanity1'), +(-1603328,'Destroy them minion, your master commands it!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Слуга убей их, исполни приказ хозяина!",15760,4,0,0,'yogg insanity2'), +(-1603372,'Portals open into Yogg-Saron\'s mind!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_vision_blast'), +(-1603373,'The illusion shatters and a path to the central chamber opens!' ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_shatter_blast'), +-- Visions: +-- lich king v3 +(-1603330,'Your resilience is admirable.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15598,0,0,0,'v1 lich king1'), +(-1603331,'Arrrrrrgh!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15470,1,0,0,'v1 champ1'), +(-1603332,'I\'m not afraid of you!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15471,0,0,0,'v1 champ2'), +(-1603333,'I will break you as I broke him.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15599,0,0,0,'v1 lich king2'), +(-1603334,'Yrr n\'lyeth... shuul anagg!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15766,0,0,0,'v1 yogg1'), +(-1603335,'He will learn... no king rules forever; only death is eternal!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15767,0,0,0,'v1 yogg2'), +-- dragons v2 +(-1603336,'It is done... All have been given that which must be given. I now seal the Dragon Soul forever...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15631,0,0,0,'v2 neltharion1'), +(-1603337,'That terrible glow... should that be?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15784,0,0,0,'v2 ysera1'), +(-1603338,'For it to be as it must, yes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15632,0,0,0,'v2 neltharion2'), +(-1603339,'It is a weapon like no other. It must be like no other.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15610,0,0,0,'v2 malygos1'), +(-1603340,'His brood learned their lesson before too long, you shall soon learn yours!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15765,0,0,0,'v2 yogg1'), +-- stormwind v1 +(-1603341,'Bad news sire. The clans are united under Blackhand in this assault. They will stand together until Stormwind has fallen.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15538,0,0,0,'v3 garona1'), +(-1603342,'Gul\'dan is bringing up his warlocks by nightfall. Until then, the Blackrock clan will be trying to take the Eastern Wall.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15539,0,0,0,'v3 garona2'), +(-1603343,'A thousand deaths... ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15762,0,0,0,'v3 yogg1'), +(-1603344,'or one murder.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15763,0,0,0,'v3 yogg2'), +(-1603345,'We will hold until the reinforcements come. As long as men with stout hearts are manning the walls and throne Stormwind will hold.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15340,0,0,0,'v3 king llane1'), +(-1603346,'The orc leaders agree with your assessment.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15341,0,0,0,'v3 garona3'), +(-1603347,'Your petty quarrels only make me stronger!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15764,0,0,0,'v3 yogg3'), + +-- Alagon: +(-1603140,'Your actions are illogical. All possible results for this encounter have been calculated. The pantheon will receive the observer\'s message regardless outcome.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Ваши действия не логичны. Все возможные исходы этой схватки просчитаны. Пантеон получит сообщение от наблюдателя в любом случае.",15386,1,0,0,'Agro_algalon the observer'), +(-1603141,'See your world through my eyes. A universe so vast as to be immeasurable. Incomprehensible even to your greatest minds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Взгляните на мир моими глазами. Узрите необьятную вселенную. Непостежимую даже для величайших умов.",15390,1,0,0,'Engaged for the first time algalon'), +(-1603142,'Witness the fury of cosmos!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Космос покарает вас!",15396,1,0,0,'BIG BANG 1_Algalon'), +(-1603143,'Behold the tools of creation!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Узрите чудо созидания!",15397,1,0,0,'BIG BANG 2_Algalon\r\n'), +(-1603144,'Beware!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Берегитесь!",15391,1,0,0,'Phase2_algalon\r\n'), +(-1603145,'Loss of life, unavoidable.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Жизнь, не может быть вечной.",15387,1,0,0,'Killing a player_alagalon\r\n'), +(-1603146,'I do what I must.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Я делаю то, что должен.",15388,1,0,0,'killing a player2_algalon\r\n'), +(-1603147,'You are... out of time.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Ваше время... Вышло.",15394,1,0,0,'BERSEKER_ALGALON'), +(-1603148,'The stars come to my aid.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"Звезды помогут мне.",15392,1,0,0,'Summoning Collapsing Stars_Algalon1'), +(-1603149,'I lack the strength to transmit this signal. You must hurry. Find a place of power, close to the skies.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,"У меня нет сил, чтобы передать сигнал. Поторопитесь, найдите истоичник энергии. Ищите в небесах.",15403,1,0,0,'Summoning Collapsing Stars_Algalon2'), +(-1603279,"Do not worry about my fate . If the signal is not transmitted in time re-origination will proceed regardless. Save. Your. World.","","","","","","","","",15404,1,0,0,"algalon outro 5"), +(-1603278,"I've rearranged the reply code. Your planet will be spared. I cannot be certain of my own calculations anymore.","","","","","","","","Я изменил код отклика. Ваша планета будет спасена. Я больше не могу полагаться на свои расчеты.",15402,1,0,0,"algalon outro 3"), +(-1603277,"Perhaps it is your imperfection that which grants you free will. That allows you to persevere against cosmically calculated odds. You prevailed where the Titans' own perfect creations have failed.","","","","","","","","Похоже ваша сила кроется именно в несовершенстве. Дарованная вам свобода воли позволяет принебрегать законами космоса и выходить победителями, тогда когда идеальные создания Титанов оказываются безсильными.",15401,1,0,0,"algalon outro 2"), +(-1603276,"I have seen worlds bathed in the Makers' flames. Their denizens fading without so much as a whimper. Entire planetary systems born and raised in the time that it takes your mortal hearts to beat once. Yet all throughout, my own heart, devoid of emotion... of empathy. I... have... felt... NOTHING! A million, million lives wasted. Had they all held within them your tenacity? Had they all loved life as you do?","","","","","","","","Я видел миры, охваченные пламенем творцов. Их жители гибли не успев издать ни звука. Я был свидетелм того, как Галактики рождались и умерали в мгновение ока, и все время Я оставался холодным... И безразличным... Я... Не чуствовал! Ничего! Триллионы загубленных судеб, неужели все они были подобны вам? Неужели все они так же любили жизнь?",15393,1,0,0,"algalon outro1"), +(-1603275,"Farewell, mortals. Your bravery is admirable, for such flawed creatures.","","","","","","","","Прощайте, смертные. Я восхищаюсь вашей отвагой, несовершенные существа.",15400,1,0,0,"algalon despwnd 3"), +(-1603274,"Begin uplink: Reply Code: 'Omega'. Planetary re-origination requested.","","","","","","","","Выход на связь. Код отклика: 'Омега'. Запрос на пересоздание планеты.",15399,1,0,0,"algalon despawn 2"), +(-1603273,"Analysis complete. There is partial corruption in the plane's life-support systems as well as complete corruption in most of the planet's defense mechanisms.","","","","","","","","Анализ завершен. Система жизнеобеспечения планеты частично поражена, большинство защитных механизмов поражены полностью.",15398,1,0,0,"algalon despawn1"), +(-1603272,"It is in the universe's best interest to re-originate this planet should my analysis find systemic corruption. Do not interfere.","","","","","","","","Для блага вселенной эту планету необходимо пересоздать. Я запускаю системный анализ, чтобы выявить зоны поражения. Не вмешивайтесь.",15407,1,0,0,"algalon intro3"), +(-1603271,"Stand back, mortals. I am not here to fight you.","","","","","","","","Смертные. Я здесь не для того, чтобы сражаться с вами.",15406,1,0,0,"Algalon intro2"), +(-1603270,"Trans-location complete. Commencing planetary analysis of Azeroth.","","","","","","","","Перемещение завершено. Запуск планитарного анализа Азерота.",15405,1,0,0,"Algalon intro1"); + +-- Archivum dialogue: TODO: +-- Brann +-- Archivum + +-- teleporter from /dev/rsa +DELETE FROM `gossip_texts` WHERE `entry` BETWEEN -3050010 AND -3050000; +INSERT INTO `gossip_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `comment`) VALUES +(-3050001, "Expedition Base Camp", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Лагерь экспедиции", "Ulduar teleporter text 1"), +(-3050002, "Formation Grounds", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Железный двор", "Ulduar teleporter text 2"), +(-3050003, "Colossal Forge", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Колоссальный горн", "Ulduar teleporter text 3"), +(-3050004, "Scrapyard", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Мусорная свалка", "Ulduar teleporter text 4"), +(-3050005, "Antechamber of Ulduar", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Вестибюль Ульдуара", "Ulduar teleporter text 5"), +(-3050006, "Shattered Walkway", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Обвалившаяся галерея", "Ulduar teleporter text 6"), +(-3050007, "Conservatory of Life", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Круг наблюдения", "Ulduar teleporter text 7"), +(-3050008, "Spark of Imagination", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Искра воображения", "Ulduar teleporter text 8"), +(-3050009, "Prison of Yogg-Saron", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Провал безумия", "Ulduar teleporter text 9"); diff --git a/addition/734_serpentshrine_mangos.sql b/addition/734_serpentshrine_mangos.sql new file mode 100644 index 000000000..33b3a8b57 --- /dev/null +++ b/addition/734_serpentshrine_mangos.sql @@ -0,0 +1,2 @@ +UPDATE `creature_template` SET `ScriptName` = 'boss_the_lurker_below' WHERE `entry` =21217; +UPDATE `gameobject_template` SET `ScriptName` = 'go_strange_pool' WHERE `entry` =184956; diff --git a/addition/735_eye_of_acherus_mangos.sql b/addition/735_eye_of_acherus_mangos.sql new file mode 100644 index 000000000..ec481d3d2 --- /dev/null +++ b/addition/735_eye_of_acherus_mangos.sql @@ -0,0 +1,6 @@ +-- Eye of acherus +UPDATE `creature_template` SET `InhabitType` = 3, `ScriptName` = 'npc_eye_of_acherus' WHERE `entry` = 28511; +REPLACE INTO `creature_template_addon` (`entry`,`moveflags`,`auras`) VALUES (28511,33562624,''),(28525,0,'64328'),(28542,0,'64328'),(28543,0,'64328'),(28544,0,'64328'); +REPLACE INTO `spell_script_target` (`entry`,`type`,`targetEntry`) VALUES (51859,1,28525),(51859,1,28542),(51859,1,28543),(51859,1,28544); +DELETE FROM `creature_addon` WHERE `guid` IN (SELECT guid FROM `creature` WHERE `id` IN (28511,28525,28542,28543,28544)); +UPDATE `npc_spellclick_spells` SET `quest_start` = 0, `quest_start_active` = 0 WHERE `npc_entry` = 29501; diff --git a/addition/735_eye_of_acherus_scriptdev2.sql b/addition/735_eye_of_acherus_scriptdev2.sql new file mode 100644 index 000000000..904341eb5 --- /dev/null +++ b/addition/735_eye_of_acherus_scriptdev2.sql @@ -0,0 +1,5 @@ +-- Say's +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1666453 AND -1666050; +INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES +('-1666451','The Eye of Acherus launches towards its destination','Око Акеруса вылетело в пункт назначения','','3','0','0','EOA_LAUNCH'), +('-1666452','The Eye of Acherus is in your control','Око Акеруса под вашим контролем','','3','0','0','EOA_CONTROL'); diff --git a/addition/736_oculus_mangos.sql b/addition/736_oculus_mangos.sql new file mode 100644 index 000000000..0f61eb16e --- /dev/null +++ b/addition/736_oculus_mangos.sql @@ -0,0 +1,116 @@ +-- Oculus instance + +-- from traponinet +/* Belgaristrasz and his companions give Drake, after completed quest (13124) */ +UPDATE `creature_template` SET `npcflag` = npcflag|1 WHERE `entry` IN (27657, 27658, 27659); +UPDATE `creature_template` SET `gossip_menu_id` = 27657 WHERE `entry` = 27657; +UPDATE `creature_template` SET `gossip_menu_id` = 27658 WHERE `entry` = 27658; +UPDATE `creature_template` SET `gossip_menu_id` = 27659 WHERE `entry` = 27659; + +DELETE FROM `gossip_scripts` WHERE `id` IN (27657, 27658, 27659); +INSERT INTO `gossip_scripts` VALUES (27657,0,17,37815,1,0,0,0,0,0,0,0,0,0,0,0,''),(27658,0,17,37860,1,0,0,0,0,0,0,0,0,0,0,0,''),(27659,0,17,37859,1,0,0,0,0,0,0,0,0,0,0,0,''); + +DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (27657, 27658, 27659); +INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `option_id`, `npc_option_npcflag`, `action_menu_id`, `action_poi_id`, `action_script_id`, `box_coded`, `box_money`, `box_text`, `cond_1`, `cond_1_val_1`, `cond_1_val_2`, `cond_2`, `cond_2_val_1`, `cond_2_val_2`, `cond_3`, `cond_3_val_1`, `cond_3_val_2`) VALUES +(27657,0,0,'What\'s can Emerald Drake?.',1,1,13259,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(27657,1,2,'Take the Emerald Essence if you want to fly on the wings of the Green Flight.',1,1,-1,0,27657,0,0,NULL,16,37859,1,16,37815,1,16,37860,1), +(27659,0,0,'What\'s can Bronze Drake?.',1,1,13255,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(27659,1,2,'Take the Amber Essence if you want to fly on the wings of the Bronze Flight.',1,1,-1,0,27659,0,0,NULL,16,37859,1,16,37815,1,16,37860,1), +(27658,0,0,'What\'s can Ruby Drake?.',1,1,13257,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(27658,1,2,'Take the Ruby Essence if you want to fly on the wings of the Red Flight.',1,1,-1,0,27658,0,0,NULL,16,37859,1,16,37815,1,16,37860,1); +-- (27658,0,0,'GOSSIP_OPTION_QUESTGIVER',2,2,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0); + +DELETE FROM `locales_gossip_menu_option` WHERE `menu_id` IN (27657, 27658, 27659); +INSERT INTO `locales_gossip_menu_option` (`menu_id`, `id`, `option_text_loc1`, `option_text_loc2`, `option_text_loc3`, `option_text_loc4`, `option_text_loc5`, `option_text_loc6`, `option_text_loc7`, `option_text_loc8`, `box_text_loc1`, `box_text_loc2`, `box_text_loc3`, `box_text_loc4`, `box_text_loc5`, `box_text_loc6`, `box_text_loc7`, `box_text_loc8`) VALUES +(27657, 0, 'What\'s can Emerald Drake?', NULL, NULL, NULL, NULL, NULL, NULL, 'Что умеет Изумрудный дракон?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), +(27657, 1, 'Take the Emerald Essence if you want to fly on the wings of the Green Flight.', NULL, NULL, NULL, NULL, NULL, NULL, 'Возьмите Изумрудную эссенцию, если Вы хотите лететь на зеленом драконе.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), +(27659, 0, 'What\'s can Bronze Drake?', NULL, NULL, NULL, NULL, NULL, NULL, 'Что умеет Бронзовый дракон?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), +(27659, 1, 'Take the Amber Essence if you want to fly on the wings of the Bronze Flight.', NULL, NULL, NULL, NULL, NULL, NULL, 'Возьмите Янтарную эссенцию, если Вы хотите лететь на бронзовом драконе.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), +(27658, 0, 'What\'s can Red Drake?', NULL, NULL, NULL, NULL, NULL, NULL, 'Что умеет Красный дракон?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), +(27658, 1, 'Take the Ruby Essence if you want to fly on the wings of the Red Flight.', NULL, NULL, NULL, NULL, NULL, NULL, 'Возьмите Рубиновую эссенцию, если Вы хотите лететь на красном драконе.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + +DELETE FROM `gossip_menu` WHERE `entry` IN (27657, 27658, 27659); +INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (27657,13258),(27658,13254),(27659,13256); +DELETE FROM `gossip_menu` WHERE `entry` IN (13259, 13255, 13257); +INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (13259,13259),(13255,13255),(13257,13257); + +-- Fix YTDB bug +UPDATE `npc_text` SET `text0_0` = `text0_1` WHERE `text0_0` = '' AND `ID` IN (13258,13259); +UPDATE `locales_npc_text` SET `Text0_0_loc8` = `Text0_1_loc8` WHERE `Text0_0_loc8` = '' AND `entry` IN (13258,13259); + +UPDATE `creature` SET `spawnMask` = 3 WHERE `map` = 578 AND `spawnMask` = 1; + +-- Eregos chests +UPDATE `gameobject` SET `spawnMask` = 2 WHERE `map` = 578 AND `id` = 193603; +UPDATE `gameobject` SET `spawnMask` = 1 WHERE `map` = 578 AND `id` = 191349; + +UPDATE `creature_template` SET `InhabitType` = 3, spell6 = 0 WHERE `entry` IN (27755,27756,27692); +REPLACE INTO `creature_template_addon` VALUES (27755,0,0,0,0,0,0,'57403'); +REPLACE INTO `creature_template_addon` VALUES (27756,0,0,0,0,0,0,'57403'); +REPLACE INTO `creature_template_addon` VALUES (27692,0,0,0,0,0,0,'57403'); + +/* hack for broken Nexus Portal */ +UPDATE `gameobject_template` SET `data0` = 49665 WHERE `entry` = 189985; +UPDATE `spell_target_position` SET `id` = 49665 WHERE `id` = 49305; + +UPDATE `creature_template` SET `spell6` = 57403, `InhabitType` = 3 WHERE `entry` IN (27692,27755,27756); + +DELETE FROM `gameobject_scripts` WHERE `id` IN +(40557,42275); +INSERT INTO `gameobject_scripts` +(`id`, `delay`, `command`, `datalong`, `datalong2`, `dataint`, `x`, `y`, `z`, `o`) +VALUES +(42275, 1, 6, 571, 0, '0', 3878.0, 6984.0, 106.0, 0), +(40557, 1, 6, 578, 0, '0', 1001.61, 1051.13, 359.48, 3.1); + +-- from lanc +UPDATE `creature_template` SET + spell1 = 50232, + spell2 = 50248, + spell3 = 50240, + spell4 = 50253, + spell5 = 0 +WHERE `entry` IN (27756); + +UPDATE `creature_template` SET + spell1 = 49840, + spell2 = 49838, + spell3 = 49592, + spell4 = 0, + spell5 = 0 +WHERE `entry` IN (27755); + +UPDATE `creature_template` SET + spell1 = 50328, + spell2 = 50341, + spell3 = 50344, + spell4 = 0, + spell5 = 0 +WHERE `entry` IN (27692); + +-- from me +UPDATE `creature_template` SET `AIName` = '', `vehicle_id` = 70, `ScriptName` = 'mob_oculus_dragon' WHERE `entry` IN (27692,27756,27755); +DELETE FROM `spell_script_target` WHERE `entry` IN (49460, 49346, 49464); +INSERT INTO `spell_script_target` VALUES (49460, 1, 27755); +INSERT INTO `spell_script_target` VALUES (49346, 1, 27692); +INSERT INTO `spell_script_target` VALUES (49464, 1, 27756); + +-- from MaxX2021 +UPDATE `instance_template` SET `ScriptName` = 'instance_oculus' WHERE `map` = 578; +UPDATE `creature_template` SET `ScriptName` = 'npc_unstable_sphere' WHERE entry = 28166; +UPDATE `creature_template` SET `ScriptName` = 'boss_drakos' WHERE entry = 27654; +UPDATE `creature_template` SET `ScriptName` = 'boss_eregos' WHERE entry = 27656; +UPDATE `creature_template` SET `ScriptName` = 'boss_varos' WHERE entry = 27447; +UPDATE `creature_template` SET `ScriptName` = 'npc_varos_orb' WHERE entry = 28183; +UPDATE `creature_template` SET `ScriptName` = 'npc_varos_beam_target' WHERE entry = 28239; +UPDATE `creature_template` SET `ScriptName` = 'npc_oculus_robot' WHERE entry = 27641; +UPDATE `creature_template` SET `ScriptName` = 'boss_urom' WHERE entry = 27655; +UPDATE `creature_template` SET `ScriptName` = 'npc_planar_anomaly' WHERE entry = 30879; +UPDATE `creature_template` SET `ScriptName` = 'npc_belgar_image' WHERE entry = 28012; + +REPLACE INTO `spell_script_target` (`entry`, `type`, `targetEntry`) values +(61407, 1, 27447), +(51024, 1, 28239), +(51022, 1, 28239), +(57963, 1, 27656); + diff --git a/addition/736_oculus_scriptdev2.sql b/addition/736_oculus_scriptdev2.sql new file mode 100644 index 000000000..9c4d96b39 --- /dev/null +++ b/addition/736_oculus_scriptdev2.sql @@ -0,0 +1,46 @@ +-- From Lanc (originally from TC) +-- Drakos the Interrogator +REPLACE into `script_texts` (entry, content_default, content_loc8, sound, type, language, emote, comment) VALUES +(-1578000,'The prisoners shall not go free. The word of Malygos is law!','Узники не вырвутся на волю. Слово Малигоса - закон!',13594,1,0,0,'1578000'), +(-1578001,'A fitting punishment!','Заслуженное наказание!',13602,1,0,0,'1578000'), +(-1578002,'Sentence: executed!','Приговор приведен в исполнение!',13603,1,0,0,'1578000'), +(-1578003,'Another casualty of war!','Еще одна жертва войны!',13604,1,0,0,'1578000'), +(-1578004,'The war... goes on.','Война... продолжается.',13605,1,0,0,'1578000'), +(-1578005,'It is too late to run!','Поздно убегать!',13598,1,0,0,'1578000'), +(-1578006,'Gather \'round!','Станьте в круг!',13599,1,0,0,'1578000'), +(-1578007,'None shall escape!','Не кто не уйдет живым!',13600,1,0,0,'1578000'), +(-1578008,'I condemn you to death!','Я приговариваю вас к смерти!',13601,1,0,0,'1578000'), +(-1578009,'Tremble, worms!','Трепещите, черви!',13595,1,0,0,'1578000'), +(-1578010,'I will crush you!','Я раздавлю вас!',13596,1,0,0,'1578000'), +(-1578011,'Can you fly?','Вы умеете летать?',13597,1,0,0,'1578000'), +-- Varos +(-1578022,'There will be no mercy!','Пощады не будет!',13649,1,0,0,'1578000'), +(-1578023,'Oculus ours!','Окулус наш!',13654,1,0,0,'1578000'), +(-1578024,'I warned you!','Тебя предупреждали!',13653,1,0,0,'1578000'), +(-1578025,'They are... too strong! Underestimated their... fortitude.','Они... слишком сильны! Я недооценил... их мужество.',13655,1,0,0,'1578000'), +(-1578026,'Blast them! Destroy them!','Взорвать их! Изничтожить!',13650,1,0,0,'1578000'), +(-1578027,'Take no prisoners! Attack!','Пленных не брать! В Атаку!',13651,1,0,0,'1578000'), +(-1578028,'Strike now! Obliterate them!','Нанесите удар! Уничтожте их!',13652,1,0,0,'1578000'), +(-1578029,'Intruders, your victory will be short-lived. I am Commander Varos Cloudstrider. My drakes control the skies and protest this conduit. I will see to it personally that the Oculus does not fall into your hands!','Чужаки, ваш триумф будет не долгим. Я командир Варос Заоблачный странник. Мои драконы обозревают небеса и защищают это место. Я позабочусь, чтобы Окулус не достался вам!',13648,1,0,0,'1578000'), +-- Urom +(-1578012,'Poor blind fools!','Несчастные слепые глупцы!',13638,1,0,0,'1578000'), +(-1578013,'If only you understood!','Если бы вы только могли понять!',13641,1,0,0,'1578000'), +(-1578014,'Now do you see? Do you?!','Ну что, теперь тебе понятно? Или нет?!',13642,1,0,0,'1578000'), +(-1578015,'Unfortunate, but necessary.','Сожелею, это было необходимо.',13643,1,0,0,'1578000'), +(-1578016,'Everything I\'ve done... has been for Azeroth...','Все что я делал... было во имя Азерота...',13644,1,0,0,'1578000'), +(-1578017,'A taste... just a small taste... of the Spell-Weaver\'s power!','Тень... лиш бледная тень... подленного могущества Хранителя магии!',13639,1,0,0,'1578000'), +(-1578018,'So much unstable energy... but worth the risk to destroy you!','Много неустойчивой энергии... но чтобы уничтожить вас, я готов рискнуть!',13640,1,0,0,'1578000'), +(-1578019,'What do we have here... those would defy the Spell-Weaver? Those without foresight or understanding. How could I make you see? Malygos is saving the world from itself! Bah! You are hardly worth my time!','Так, что у нас тут... ааа вы пришли сразится с Хранителем магии? Это вы то лишенные предвидиния и понимания. Как мне заставить вас прозреть? Малигос спасает мир от самого мира! Эх! На вас жаль тратить время!',13635,1,0,0,'1578000'), +(-1578020,'Clearly my pets failed. Perhaps another demonstration is in order.','Моих слуг постигла неудача. Возможно потребуется еще одно предупреждение.',13636,1,0,0,'1578000'), +(-1578021,'Still you fight. Still you cling to misguided principles. If you survive, you\'ll find me in the center ring.','Вы все еще сражаетесь. Все еще цепляетесь за свои ложные убеждения. Если выживите, встретимся в центральном кругу.',13637,1,0,0,'1578000'), +-- Eregos +(-1578030,'You brash interlopers are out of your element! I will ground you!','Нахальные невежды, вы все в небесах летаете! Сейчас я вас заземлю!',13623,1,0,0,'1578000'), +(-1578031,'It\'s a long way down...','Как больно падать...',13628,1,0,0,'1578000'), +(-1578032,'Back to the earth with you!','Вернемся на землю!',13629,1,0,0,'1578000'), +(-1578033,'Enjoy the fall!','Наслаждайся полетом!',13630,1,0,0,'1578000'), +(-1578034,'Savor this small victory, foolish little creatures. You and your dragon allies have won this battle. But we will win... the Nexus War.','Празнуйте свой мелкий триумф, призренные глупцы. Вы и ваши союзники драконы победили в этой битве. Но мы одержим верх в войне... Нексуса.',13631,1,0,0,'1578000'), +(-1578035,'We command the arcane! It shall not be used against us.','Мы повелеваем тайной магией! Она не будет использована против нас.',13626,1,0,0,'1578000'), +(-1578036,'It is trivial to extinguish your fire!','Как легко погасить ваш огонь!',13627,1,0,0,'1578000'), +(-1578037,'No magic of nature will help you now!','Никакая магия природы теперь вас не спасет!',13625,1,0,0,'1578000'), +(-1578038,'Such insolence... such arrogance... must be PUNISHED!','Какая заносчивость... какая чандливость... вы заслуживаете КАРЫ!',13624,1,0,0,'1578000'), +(-1578039,'Simpletons! You cannot comprehend the forces you have set in motion. The ley line conduit will not be disrupted! Your defeat shall be absolute!','Простаки! Вам и неведомо какие силы вы привели в действие. Поток энергии не прервется! Вас ждет полный разгром!',13622,1,0,0,'1578000'); diff --git a/addition/737_outdoor_pvp_mangos.sql b/addition/737_outdoor_pvp_mangos.sql new file mode 100644 index 000000000..6ec92957f --- /dev/null +++ b/addition/737_outdoor_pvp_mangos.sql @@ -0,0 +1,14 @@ +-- World map scripts (selectors) +DELETE FROM `world_template` WHERE `map` = 0; +INSERT INTO `world_template` VALUES (0,'outdoor_pvp_eastern_kingdoms'); +DELETE FROM `world_template` WHERE `map` = 1; +INSERT INTO `world_template` VALUES (1,'outdoor_pvp_kalimdor'); +DELETE FROM `world_template` WHERE `map` = 530; +INSERT INTO `world_template` VALUES (530,'outdoor_pvp_outland'); +DELETE FROM `world_template` WHERE `map` = 571; +INSERT INTO `world_template` VALUES (571,'outdoor_pvp_northrend'); + +-- from Xfurry +UPDATE gameobject_template SET ScriptName='go_silithyst' WHERE entry IN (181597,181598); +DELETE FROM scripted_areatrigger WHERE entry IN (4162, 4168); +INSERT INTO scripted_areatrigger VALUES (4162,'at_silithus'),(4168,'at_silithus'); diff --git a/addition/boss_spell_table_scriptdev2.sql b/addition/boss_spell_table_scriptdev2.sql new file mode 100644 index 000000000..6ceddc255 --- /dev/null +++ b/addition/boss_spell_table_scriptdev2.sql @@ -0,0 +1,33 @@ +DROP TABLE IF EXISTS `boss_spell_table`; +CREATE TABLE IF NOT EXISTS `boss_spell_table` ( + `entry` mediumint(8) NOT NULL DEFAULT '0' COMMENT 'Creature entry', + `spellID_N10` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell ID for 10 normal', + `spellID_N25` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell ID for 25 normal', + `spellID_H10` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell ID for 10 heroic', + `spellID_H25` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell ID for 25 heroic', + `timerMin_N10` mediumint(8) unsigned NOT NULL DEFAULT '15000' COMMENT 'Minimum timer for this spell (in ms.) for 10 normal', + `timerMin_N25` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Minimum timer for this spell (in ms.) for 25 normal', + `timerMin_H10` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Minimum timer for this spell (in ms.) for 10 heroic', + `timerMin_H25` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Minimum timer for this spell (in ms.) for 25 heroic', + `timerMax_N10` mediumint(8) unsigned NOT NULL DEFAULT '30000' COMMENT 'Maximum timer for this spell (in ms.) for 10 normal', + `timerMax_N25` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum timer for this spell (in ms.) for 25 normal', + `timerMax_H10` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum timer for this spell (in ms.) for 10 heroic', + `timerMax_H25` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum timer for this spell (in ms.) for 25 heroic', + `data1` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Various INT data for this spell or summon for 10 normal', + `data2` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Various INT data for this spell for 25 normal', + `data3` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Various INT data for this spell for 10 heroic', + `data4` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Various INT data for this spell for 25 heroic', + `locData_x` float NOT NULL DEFAULT '0' COMMENT 'Location X data for this spell', + `locData_y` float NOT NULL DEFAULT '0' COMMENT 'Location Y data for this spell', + `locData_z` float NOT NULL DEFAULT '0' COMMENT 'Location Z data for this spell', + `varData` mediumint(8) NOT NULL DEFAULT '0' COMMENT 'Special data field for this spell (basepoint for Aura, for example)', + `StageMask_N` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Stage mask for this spell (don\'t used now)', + `StageMask_H` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Stage mask for this spell - heroic mode (don\'t used now)', + `CastType` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Type of cast (by enum BossSpellTableParameters)', + `isVisualEffect` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Is spell is Visual effect only', + `isBugged` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Is spell bugged and need override', + `textEntry` mediumint(8) NOT NULL DEFAULT '0' COMMENT 'Text from script_texts for this spell casting', + `comment` text, + PRIMARY KEY (`entry`,`spellID_N10`,`CastType`), + INDEX `idx_entry`(`entry`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT 'Boss spell table by /dev/rsa'; diff --git a/addition/here you can find SQL files from patches.txt b/addition/here you can find SQL files from patches.txt new file mode 100644 index 000000000..e69de29bb diff --git a/addition/spell_comment_from_wowd_scriptdev2.sql b/addition/spell_comment_from_wowd_scriptdev2.sql new file mode 100644 index 000000000..a5fec77d0 --- /dev/null +++ b/addition/spell_comment_from_wowd_scriptdev2.sql @@ -0,0 +1,19 @@ +-- Insert comments to scriptdev2 boss_spell_table from WOWD database. +-- Change WOWD database name if you use this! + +CREATE ALGORITHM = TEMPTABLE VIEW `commentlist` +(`entry` ,`spell`, `comment`) +AS SELECT `scriptdev2`.`boss_spell_table`.`entry`, +`spellID_N10`, +CONCAT(`mangos`.`creature_template`.`name`, +' : ', +`mangos`.`wowd_spell`.`SpellName`) +FROM `scriptdev2`.`boss_spell_table` +INNER JOIN `mangos`.`creature_template` ON `mangos`.`creature_template`.`entry` = `scriptdev2`.`boss_spell_table`.`entry` +INNER JOIN `mangos`.`wowd_spell` ON `mangos`.`wowd_spell`.`id` = `scriptdev2`.`boss_spell_table`.`spellID_N10`; + +UPDATE `scriptdev2`.`boss_spell_table` SET `comment` = (SELECT DISTINCT `commentlist`.`comment` +FROM `commentlist` WHERE `scriptdev2`.`boss_spell_table`.`entry` = `commentlist`.`entry` +AND `scriptdev2`.`boss_spell_table`.`spellID_N10` = `commentlist`.`spell` +AND `scriptdev2`.`boss_spell_table`.`comment` IS NULL); +DROP VIEW `commentlist`; diff --git a/base/BSW_ai.cpp b/base/BSW_ai.cpp new file mode 100644 index 000000000..343d8bcb3 --- /dev/null +++ b/base/BSW_ai.cpp @@ -0,0 +1,870 @@ +/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ +#include "precompiled.h" +#include "BSW_ai.h" +#ifdef DEF_BOSS_SPELL_WORKER_H +#include "ace/Process_Mutex.h" + +BSWScriptedAI::BSWScriptedAI(Creature* pCreature) : ScriptedAI(pCreature) +{ + doReset(); + debug_log("BSW: Initialized BSWScriptedAI structure for creature %u difficulty %u",m_creature->GetEntry(),currentDifficulty); +}; + +BSWScriptedAI::~BSWScriptedAI() +{ + m_BSWRecords.clear(); + debug_log("BSW: Removing BSWScriptedAI structure for creature %u",m_creature->GetEntry()); +}; + +void BSWScriptedAI::doReset() +{ + Map* pMap = m_creature->GetMap(); + if (pMap) currentDifficulty = pMap->GetDifficulty(); + else currentDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; + m_BSWRecords.clear(); + setStage(0); + _loadFromDB(); + _fillEmptyDataField(); + resetTimers(); +}; + +void BSWScriptedAI::_resetTimer(uint8 m_uiSpellIdx) +{ + if (m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMin[currentDifficulty] == 0 + && m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS) + { + m_BSWRecords[m_uiSpellIdx].m_SpellTimer = 0; + } + else if (m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMin[currentDifficulty] != m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMax[currentDifficulty]) + { + m_BSWRecords[m_uiSpellIdx].m_SpellTimer = urand(0,m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMax[currentDifficulty]); + } + else m_BSWRecords[m_uiSpellIdx].m_SpellTimer = m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMin[currentDifficulty]; + +}; + +void BSWScriptedAI::_loadFromDB() +{ + // mutex block for process-safe request execute + ACE_Process_Mutex mMutex = ACE_Process_Mutex("BSW_Lock"); + + debug_log("BSW: Loading table of creature %u spell on difficulty %u", m_creature->GetEntry(), currentDifficulty); + + char query[MAX_QUERY_LEN]; + + sprintf(query, "SELECT entry, spellID_N10, spellID_N25, spellID_H10, spellID_H25, timerMin_N10, timerMin_N25, timerMin_H10, timerMin_H25, timerMax_N10, timerMax_N25, timerMax_H10, timerMax_H25, data1, data2, data3, data4, locData_x, locData_y, locData_z, varData, StageMask_N, StageMask_H, CastType, isVisualEffect, isBugged, textEntry FROM `boss_spell_table` WHERE entry = %u;\r\n", m_creature->GetEntry()); + + mMutex.acquire(); + QueryResult* Result = strSD2Pquery(query); + mMutex.release(); + + if (Result) + { + uint32 uiCount = 0; + do + { + BSWRecord m_BSWRecord; + + Field* pFields = Result->Fetch(); + + m_BSWRecord.id = uiCount; + + uint32 m_creatureEntry = pFields[0].GetUInt32(); + + for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j) + m_BSWRecord.m_uiSpellEntry[j] = pFields[1+j].GetUInt32(); + + for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j) + m_BSWRecord.m_uiSpellTimerMin[j] = pFields[1+DIFFICULTY_LEVELS+j].GetUInt32(); + + for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j) + m_BSWRecord.m_uiSpellTimerMax[j] = pFields[1+DIFFICULTY_LEVELS*2+j].GetUInt32(); + + for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j) + m_BSWRecord.m_uiSpellData[j] = pFields[1+DIFFICULTY_LEVELS*3+j].GetUInt32(); + + m_BSWRecord.LocData.x = pFields[1+DIFFICULTY_LEVELS*4].GetFloat(); + m_BSWRecord.LocData.y = pFields[2+DIFFICULTY_LEVELS*4].GetFloat(); + m_BSWRecord.LocData.z = pFields[3+DIFFICULTY_LEVELS*4].GetFloat(); + + m_BSWRecord.varData = pFields[4+DIFFICULTY_LEVELS*4].GetInt32(); + + m_BSWRecord.StageMaskN = pFields[5+DIFFICULTY_LEVELS*4].GetUInt32(); + m_BSWRecord.StageMaskH = pFields[6+DIFFICULTY_LEVELS*4].GetUInt32(); + + m_BSWRecord.m_CastTarget = _getBSWCastType(pFields[7+DIFFICULTY_LEVELS*4].GetUInt8()); + + m_BSWRecord.m_IsVisualEffect = (pFields[8+DIFFICULTY_LEVELS*4].GetUInt8() == 0) ? false : true ; + + m_BSWRecord.m_IsBugged = (pFields[9+DIFFICULTY_LEVELS*4].GetUInt8() == 0) ? false : true ; + + m_BSWRecord.textEntry = pFields[10+DIFFICULTY_LEVELS*4].GetInt32(); + + m_BSWRecords.push_back(m_BSWRecord); + + if (m_creatureEntry != m_creature->GetEntry()) error_log("BSW: Unknown error while load boss_spell_table"); + else ++uiCount; + } while (Result->NextRow()); + + delete Result; + + debug_log("BSW: Loaded %u spell data records for creature %u", bossSpellCount(), m_creature->GetEntry()); + } + else + { + error_log("BSW: BSW table for creature %u is empty.", m_creature->GetEntry()); + }; +} + +bool BSWScriptedAI::_QuerySpellPeriod(uint8 m_uiSpellIdx, uint32 diff, bool ignorecast) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + if (m_creature->IsNonMeleeSpellCasted(false) && !ignorecast) return false; + + if (pSpell->m_SpellTimer <= diff) + { + if (pSpell->m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS) pSpell->m_SpellTimer=HOUR*IN_MILLISECONDS; + else pSpell->m_SpellTimer = urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]); + return true; + } + else + { + pSpell->m_SpellTimer -= diff; + return false; + }; +}; + +CanCastResult BSWScriptedAI::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget) +{ + + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + Unit* pSummon = NULL; + + CanCastResult result = CAST_FAIL_OTHER; + + debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + + if (pSpell->m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS) + m_creature->InterruptNonMeleeSpells(true); + + switch (pSpell->m_CastTarget) { + + case DO_NOTHING: + result = CAST_OK; + break; + + case CAST_ON_SELF: + result = _BSWCastOnTarget(m_creature, m_uiSpellIdx); + break; + + case CAST_ON_SUMMONS: + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case CAST_ON_VICTIM: + pTarget = m_creature->getVictim(); + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case CAST_ON_RANDOM: + pTarget = _doSelect(0, false, 60.0f); + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case CAST_ON_BOTTOMAGGRO: + pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0); + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case CAST_ON_TARGET: + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case APPLY_AURA_SELF: + if (_doAura(m_uiSpellIdx, m_creature, EFFECT_INDEX_0)) + result = CAST_OK; + else result = CAST_FAIL_OTHER; + break; + + case APPLY_AURA_TARGET: + if (!pTarget || !pTarget->IsInMap(m_creature)) + { + result = CAST_FAIL_OTHER; + break; + } + if (_doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0)) + result = CAST_OK; + else result = CAST_FAIL_OTHER; + break; + + case SUMMON_NORMAL: + pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + if(pSummon) result = CAST_OK; + else result = CAST_FAIL_OTHER; + break; + + case SUMMON_TEMP: + pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, + urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty])); + if(pSummon) result = CAST_OK; + else result = CAST_FAIL_OTHER; + break; + + case SUMMON_INSTANT: + pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0); + if(pSummon) result = CAST_OK; + else result = CAST_FAIL_OTHER; + break; + + case CAST_ON_ALLPLAYERS: + { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const& pPlayers = pMap->GetPlayers(); + if (!pPlayers.isEmpty()) + { + for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) + { + pTarget = itr->getSource(); + if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x)) + { + if (!pSpell->m_IsBugged) + { + m_creature->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false); + } + else + { + _BSWDoCast(m_uiSpellIdx, pTarget); + }; + result = CAST_OK; + }; + } + } else result = CAST_FAIL_OTHER; + } + break; + + case CAST_ON_FRENDLY: + pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,0); + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case CAST_ON_FRENDLY_LOWHP: + pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,1); + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case CAST_ON_RANDOM_POINT: + if (!pTarget) pTarget = m_creature; + if (pSpell->LocData.z <= 1.0f) + { + float fPosX, fPosY, fPosZ; + if (!pTarget->IsPositionValid() || !pTarget->IsInMap(m_creature)) + { + if (pTarget->GetTypeId() == TYPEID_PLAYER) + error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); + else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); + result = CAST_FAIL_OTHER; + break; + } + + pTarget->GetPosition(fPosX, fPosY, fPosZ); + pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ); + if ((int)fPosZ == 0) + { + error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug"); + result = CAST_FAIL_OTHER; + break; + } + + if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty])) + if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex)) + if (m_creature->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange) + { + m_creature->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false); + result = CAST_OK; + break; + }; + result = CAST_FAIL_TOO_FAR; + } else result = CAST_FAIL_OTHER; + break; + + case CAST_ON_RANDOM_PLAYER: + if ( pSpell->LocData.x < 1 ) pTarget = _doSelect(0, false, 60.0f); + else pTarget = _doSelect(0, false, (float)pSpell->LocData.x); + result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); + break; + + case APPLY_AURA_ALLPLAYERS: + { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const& pPlayers = pMap->GetPlayers(); + for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) + { + pTarget = itr->getSource(); + if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x)) + { + _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0); + result = CAST_OK; + } + } + } + break; + + case FORCE_CAST: + result = _BSWDoForceCast(m_uiSpellIdx, pTarget); + break; + + case SPELLTABLEPARM_NUMBER: + default: + error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + result = CAST_FAIL_OTHER; + break; + }; + + if (pSpell->textEntry && result == CAST_OK) + { + if (pTarget) + DoScriptText(pSpell->textEntry,m_creature,pTarget); + else + DoScriptText(pSpell->textEntry,m_creature); + }; + + debug_log("BSW: Casted spell number %u, result = %u",pSpell->m_uiSpellEntry[currentDifficulty], result); + + return result; +}; + +CanCastResult BSWScriptedAI::_BSWCastOnTarget(Unit* pTarget, uint8 m_uiSpellIdx) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive()) + { + debug_log("BSW: warning - failed casting (on target) spell number %u - no target or target not in map",pSpell->m_uiSpellEntry[currentDifficulty]); + return CAST_FAIL_OTHER; + } + + debug_log("BSW: Casting (on target) spell %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + + if (!pSpell->m_IsBugged) return _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]); + else if (pSpell->m_IsBugged) return _BSWDoCast(m_uiSpellIdx, pTarget); + else return CAST_FAIL_OTHER; +}; + +bool BSWScriptedAI::_hasAura(uint8 m_uiSpellIdx, Unit* pTarget) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + return _hasAura(pSpell->m_uiSpellEntry[currentDifficulty], pTarget); + +}; + +bool BSWScriptedAI::_hasAura(uint32 SpellID, Unit* pTarget) +{ + if (!pTarget || !pTarget->IsInMap(m_creature)) + { + error_log("BSW: FAILED Query aura for spell %u - no target or target not in map",SpellID); + return false; + } + + return (pTarget->HasAura(SpellID)); + +}; + +uint8 BSWScriptedAI::_auraCount(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + return _auraCount(pSpell->m_uiSpellEntry[currentDifficulty], pTarget, index); + +}; + +uint8 BSWScriptedAI::_auraCount(uint32 SpellID, Unit* pTarget, SpellEffectIndex index) +{ + if (!_hasAura(SpellID,pTarget)) return 0; + + if (Aura* aura = pTarget->GetAura(SpellID, index)) + if (aura->GetStackAmount() > 0) + return aura->GetStackAmount(); + return 0; + +}; + +uint8 BSWScriptedAI::_findSpellIDX(uint32 SpellID) +{ + if (bossSpellCount() > 0) + for(uint8 i = 0; i < bossSpellCount(); ++i) + if (m_BSWRecords[i].m_uiSpellEntry[RAID_DIFFICULTY_10MAN_NORMAL] == SpellID) return i; + + error_log("BSW: spell %u not found in m_creature %u spelltable. Memory or database error?", SpellID, m_creature->GetEntry()); + + return SPELL_INDEX_ERROR; +} + +BSWRecord* BSWScriptedAI::_getRecord(uint32 SpellID) +{ + if (!m_BSWRecords.empty()) + { + for(uint8 i = 0; i < m_BSWRecords.size(); ++i) + if (m_BSWRecords[i].m_uiSpellEntry[RAID_DIFFICULTY_10MAN_NORMAL] == SpellID) return &m_BSWRecords[i]; + } + error_log("BSW: spell %u not found in m_creature %u spelltable. Memory or database error?", SpellID, m_creature->GetEntry()); + return NULL; +} + +BossSpellTableParameters BSWScriptedAI::_getBSWCastType(uint32 pTemp) +{ + switch (pTemp) { + case 0: return DO_NOTHING; + case 1: return CAST_ON_SELF; + case 2: return CAST_ON_SUMMONS; + case 3: return CAST_ON_VICTIM; + case 4: return CAST_ON_RANDOM; + case 5: return CAST_ON_BOTTOMAGGRO; + case 6: return CAST_ON_TARGET; + case 7: return APPLY_AURA_SELF; + case 8: return APPLY_AURA_TARGET; + case 9: return SUMMON_NORMAL; + case 10: return SUMMON_INSTANT; + case 11: return SUMMON_TEMP; + case 12: return CAST_ON_ALLPLAYERS; + case 13: return CAST_ON_FRENDLY; + case 14: return CAST_ON_FRENDLY_LOWHP; + case 15: return CAST_ON_RANDOM_POINT; + case 16: return CAST_ON_RANDOM_PLAYER; + case 17: return APPLY_AURA_ALLPLAYERS; + case 18: return FORCE_CAST; + case 19: return SPELLTABLEPARM_NUMBER; + default: return DO_NOTHING; + }; +}; + +CanCastResult BSWScriptedAI::_BSWDoCast(uint8 m_uiSpellIdx, Unit* pTarget) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive()) + { + error_log("BSW: warning - failed casting bugged spell number %u - no target or target not in map",pSpell->m_uiSpellEntry[currentDifficulty]); + return CAST_FAIL_OTHER; + } + + debug_log("BSW: Casting bugged spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + + pTarget->InterruptNonMeleeSpells(false); + + pTarget->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false); + + return CAST_OK; +}; + +CanCastResult BSWScriptedAI::_BSWDoForceCast(uint8 m_uiSpellIdx, Unit* pTarget) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive()) + { + error_log("BSW: warning - failed forced casting spell number %u - no target or target not in map",pSpell->m_uiSpellEntry[currentDifficulty]); + return CAST_FAIL_OTHER; + } + + debug_log("BSW: Forced casting spell number %u ",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + + pTarget->InterruptNonMeleeSpells(false); + + pTarget->CastSpell(m_creature, pSpell->m_uiSpellEntry[currentDifficulty], true); + + return CAST_OK; +}; + +void BSWScriptedAI::_fillEmptyDataField() +{ + for (uint8 i = 0; i < bossSpellCount(); ++i) + for (uint8 j = 1; j < DIFFICULTY_LEVELS; ++j) + { + if (m_BSWRecords[i].m_uiSpellEntry[j] == 0) + { + SpellEntry const* spell = GetSpellEntryByDifficulty(m_BSWRecords[i].m_uiSpellEntry[0],(Difficulty)j); + if (spell) + m_BSWRecords[i].m_uiSpellEntry[j] = spell->Id; + else m_BSWRecords[i].m_uiSpellEntry[j] = m_BSWRecords[i].m_uiSpellEntry[j-1]; + } + + if (m_BSWRecords[i].m_uiSpellTimerMin[j] == 0) + m_BSWRecords[i].m_uiSpellTimerMin[j] = m_BSWRecords[i].m_uiSpellTimerMin[j-1]; + + if (m_BSWRecords[i].m_uiSpellTimerMax[j] == 0) + m_BSWRecords[i].m_uiSpellTimerMax[j] = m_BSWRecords[i].m_uiSpellTimerMax[j-1]; + + if (m_BSWRecords[i].m_uiSpellData[j] == 0) + m_BSWRecords[i].m_uiSpellData[j] = m_BSWRecords[i].m_uiSpellData[j-1]; + }; +}; + +Unit* BSWScriptedAI::_doSummon(uint8 m_uiSpellIdx, TempSummonType summontype, uint32 delay) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + debug_log("BSW: Summoning creature number %u type %u despawn delay %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget, delay); + + if (pSpell->LocData.z <= 1.0f) + { + float fPosX, fPosY, fPosZ; + if (!m_creature->IsPositionValid()) + { + error_log("BSW: FAILED summoning creature, creature %u has invalid position",m_creature->GetEntry()); + return NULL; + } + m_creature->GetPosition(fPosX, fPosY, fPosZ); + m_creature->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ); + return m_creature->SummonCreature(pSpell->m_uiSpellEntry[currentDifficulty], fPosX, fPosY, fPosZ+0.8f, 0, summontype, delay); + } + else return m_creature->SummonCreature(pSpell->m_uiSpellEntry[currentDifficulty], pSpell->LocData.x, pSpell->LocData.y, pSpell->LocData.z, 0, summontype, delay); +}; + +Unit* BSWScriptedAI::_doSummonAtPosition(uint8 m_uiSpellIdx, float fPosX, float fPosY, float fPosZ) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + switch (pSpell->m_CastTarget) + { + case SUMMON_NORMAL: + return _doSummonAtPosition(pSpell->m_uiSpellEntry[currentDifficulty], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 0, fPosX, fPosY, fPosZ); + break; + + case SUMMON_TEMP: + return _doSummonAtPosition(pSpell->m_uiSpellEntry[currentDifficulty], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]), fPosX, fPosY, fPosZ); + break; + + case SUMMON_INSTANT: + return _doSummonAtPosition(pSpell->m_uiSpellEntry[currentDifficulty], TEMPSUMMON_MANUAL_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]), fPosX, fPosY, fPosZ); + break; + + default: + break; + } + error_log("BSW: FAILED creature number %u type %u ",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + return NULL; +}; + +Unit* BSWScriptedAI::_doSummonAtPosition(uint32 guid, TempSummonType summontype, uint32 delay, float fPosX, float fPosY, float fPosZ) +{ + + debug_log("BSW: Summoning creature number %u despawn delay %u at position %f %f %f", guid, delay, fPosX, fPosY, fPosZ); + + return m_creature->SummonCreature(guid, fPosX, fPosY, fPosZ, 0, summontype, delay); +}; + +bool BSWScriptedAI::_doRemove(uint8 m_uiSpellIdx, Unit* pTarget, uint8 index) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + debug_log("BSW: Removing effects of spell %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + + switch (pSpell->m_CastTarget) + { + case DO_NOTHING: + return true; + break; + + case SUMMON_NORMAL: + case SUMMON_TEMP: + case SUMMON_INSTANT: + return false; + break; + + case CAST_ON_SELF: + case APPLY_AURA_SELF: + pTarget = m_creature; + break; + + case CAST_ON_SUMMONS: + case CAST_ON_VICTIM: + case CAST_ON_BOTTOMAGGRO: + case CAST_ON_TARGET: + case FORCE_CAST: + case APPLY_AURA_TARGET: + if (!pTarget) + return false; + break; + + case CAST_ON_RANDOM: + case CAST_ON_RANDOM_PLAYER: + case APPLY_AURA_ALLPLAYERS: + case CAST_ON_ALLPLAYERS: + _doRemoveFromAll(m_uiSpellIdx); + return true; + break; + + default: + debug_log("BSW: FAILED Removing effects of spell %u type %u - unsupported type",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); + return false; + break; + } + + return _doRemove(pSpell->m_uiSpellEntry[currentDifficulty], pTarget, index); + +}; + +bool BSWScriptedAI::_doRemove(uint32 SpellID, Unit* pTarget, uint8 index) +{ + + if (!_hasAura(SpellID, pTarget)) return false; + + if (index == EFFECT_INDEX_ALL) + { + pTarget->RemoveAurasDueToSpell(SpellID); + } + else if (_auraCount(SpellID,pTarget,(SpellEffectIndex)index) > 1) + { + if (SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(SpellID, pTarget->GetGUID())) + { + if (holder->ModStackAmount(-1)) + { + pTarget->RemoveSpellAuraHolder(holder, AURA_REMOVE_BY_DISPEL); + } else return false; + } + } + else + pTarget->RemoveAurasDueToSpell(SpellID); + + debug_log("BSW: Removed effects of spell %u index %u",SpellID, index); + return true; +}; + +bool BSWScriptedAI::_doRemoveFromAll(uint8 m_uiSpellIdx) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + return _doRemoveFromAll(pSpell->m_uiSpellEntry[currentDifficulty]); +}; + +bool BSWScriptedAI::_doRemoveFromAll(uint32 SpellID) +{ + Map* pMap = m_creature->GetMap(); + Map::PlayerList const& pPlayers = pMap->GetPlayers(); + if (!pPlayers.isEmpty()) + { + debug_log("BSW: Removing effects of spell %u from all players",SpellID); + + for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) + { + Unit* pTarget = itr->getSource(); + if (pTarget && pTarget->IsInWorld()) + { + pTarget->RemoveAurasDueToSpell(SpellID); + if (Pet* pPet = pTarget->GetPet()) + pPet->RemoveAurasDueToSpell(SpellID); + } + } + return true; + } + else + { + debug_log("BSW: Removing effects of spell %u from all players FAILED - no players in map",SpellID); + return false; + } +}; + +bool BSWScriptedAI::_doAura(uint8 m_uiSpellIdx, Unit* pTarget) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + if (!pTarget) + pTarget = m_creature; + + bool result = true; + + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + result = result && _doAura(m_uiSpellIdx, pTarget, SpellEffectIndex(i), !i); + + return result; + +}; + +bool BSWScriptedAI::_doAura(uint32 SpellID, Unit* pTarget) +{ + if (!pTarget) + pTarget = m_creature; + + bool result = true; + + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + result = result && _doAura(SpellID, pTarget, SpellEffectIndex(i), 0, !i); + + return result; + +}; + + +bool BSWScriptedAI::_doAura(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index, bool isStack) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + if (!pTarget) + pTarget = m_creature; + + return _doAura(pSpell->m_uiSpellEntry[currentDifficulty], pTarget, index, pSpell->varData, isStack); + +}; + + +bool BSWScriptedAI::_doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint, bool isStack) +{ + if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive()) + { + error_log("BSW: FAILED adding aura of spell number %u - no target or target not in map or target is dead",SpellID); + return false; + } + + if (_hasAura(SpellID,pTarget)) + debug_log("BSW: adding aura stack from spell %u index %u",SpellID, index); + else debug_log("BSW: adding new aura from spell %u index %u",SpellID, index); + + SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SpellID); + + if (spell) + { + if (IsSpellAppliesAura(spell, (1 << EFFECT_INDEX_0) | (1 << EFFECT_INDEX_1) | (1 << EFFECT_INDEX_2)) || IsSpellHaveEffect(spell, SPELL_EFFECT_PERSISTENT_AREA_AURA)) + { + int32 _basepoint = basepoint ? basepoint - 1 : spell->EffectBasePoints[index] + 1; + + bool addedToExisting = true; + + SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(SpellID, pTarget->GetGUID()); + + Aura* aura = NULL; + + if (!holder) + { + holder = CreateSpellAuraHolder(spell, pTarget, pTarget); + addedToExisting = false; + } + + + if (aura = holder->GetAuraByEffectIndex(index)) + { + if (isStack) + holder->ModStackAmount(1); + } + else + { + aura = CreateAura(spell, index, &_basepoint, holder, pTarget); + holder->SetAuraDuration(aura->GetAuraMaxDuration()); + holder->AddAura(aura, index); + } + + if (addedToExisting) + { + pTarget->AddAuraToModList(aura); + holder->SetInUse(true); + aura->ApplyModifier(true,true); + holder->SetInUse(false); + } + else + pTarget->AddSpellAuraHolder(holder); + + return true; + } + } + + error_log("BSW: FAILED adding aura from spell %u index %u",SpellID, index); + + return false; +}; + +CanCastResult BSWScriptedAI::_DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags, uint64 uiOriginalCasterGUID) +{ + if (!pTarget || !pTarget->IsInWorld() || !pTarget->IsInMap(m_creature)|| !pTarget->isAlive()) return CAST_FAIL_OTHER; + + return DoCastSpellIfCan(pTarget,uiSpell,uiCastFlags,uiOriginalCasterGUID); +} + +// Not threat-based select random player function + +Unit* BSWScriptedAI::_doSelect(uint32 SpellID, bool spellsearchtype, float range, bool includeVictim) +{ + Map* pMap = m_creature->GetMap(); + Map::PlayerList const &pList = pMap->GetPlayers(); + if (pList.isEmpty()) return NULL; + + std::vector _list; + _list.clear(); + + for(Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i) + if (Player* player = i->getSource()) + { + if (player->isGameMaster()) continue; + + if (!player->IsInMap(m_creature)) continue; + + if (player == m_creature->getVictim() && !includeVictim) continue; + + if (player->isAlive() + && player->IsWithinDistInMap(m_creature, range) + && (SpellID == 0 || (player->HasAura(SpellID) == spellsearchtype)) + ) + _list.push_back((Unit*)player); + } + + debug_log("BSW: search random player with criteria = %u, found %u players.",SpellID,_list.size()); + + if (_list.empty()) return NULL; + else return _list[urand(0,_list.size() - 1)]; +}; + +Creature* BSWScriptedAI::doSelectNearestCreature(uint32 id, float range) +{ + Creature* pTarget = GetClosestCreatureWithEntry(m_creature, id, range); + + if (pTarget && pTarget->IsInMap(m_creature) && pTarget != m_creature && pTarget->isAlive()) + { + debug_log("BSW: search creature %u in range %f - found it.",id,range); + return pTarget; + } + else + { + debug_log("BSW: search creature %u in range %f - NOT found.",id,range); + return NULL; + } +} + +uint32 BSWScriptedAI::_getSpellData(uint8 m_uiSpellIdx) +{ + BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; + + return pSpell->m_uiSpellData[currentDifficulty]; +}; + +bool BSWScriptedAI::doCastAll(uint32 diff) +{ + + uint8 succesfulCast = 0; + + if (bossSpellCount() > 0) + { + for(uint8 i = 0; i < bossSpellCount(); ++i) + if (_QuerySpellPeriod(i, diff)) + if (_BSWSpellSelector(i) == CAST_OK) + ++succesfulCast; + + if (succesfulCast) + debug_log("BSW: Casting all spells for creature %u done. Successful casted %u spells from %u.", m_creature->GetEntry(),succesfulCast,bossSpellCount()); + } + else + { + error_log("BSW: Casting all spells for creature %u failed. Database has no spells.", m_creature->GetEntry()); + } + + return (succesfulCast >= 1) ? true : false; + +}; + +bool BSWScriptedAI::_isDifficultyInMask(uint8 mask) +{ + return ((uint8)currentDifficulty & mask); +}; + +#endif \ No newline at end of file diff --git a/base/BSW_ai.h b/base/BSW_ai.h new file mode 100644 index 000000000..9ca3a1979 --- /dev/null +++ b/base/BSW_ai.h @@ -0,0 +1,298 @@ +/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_BOSS_SPELL_WORKER_H +#define DEF_BOSS_SPELL_WORKER_H +#define BSW_VERSION 0.6.12 + +#include "precompiled.h" +#include "Player.h" +#include "SpellAuras.h" +#include "SpellMgr.h" +#include "Unit.h" +#include "Database/DatabaseEnv.h" +#include "../ScriptMgr.h" + + +enum +{ + DIFFICULTY_LEVELS = 4, + EFFECT_INDEX_ALL = 255, + SPELL_INDEX_ERROR = 255, +}; + +enum BossSpellFlag +{ + CAST_NORMAL, + CAST_REMOVE, + CAST_OVERRIDE, + SPELLFLAG_NUMBER +}; + +enum BossSpellTableParameters +{ + DO_NOTHING = 0, + CAST_ON_SELF = 1, + CAST_ON_SUMMONS = 2, + CAST_ON_VICTIM = 3, + CAST_ON_RANDOM = 4, + CAST_ON_BOTTOMAGGRO = 5, + CAST_ON_TARGET = 6, + APPLY_AURA_SELF = 7, + APPLY_AURA_TARGET = 8, + SUMMON_NORMAL = 9, + SUMMON_INSTANT = 10, + SUMMON_TEMP = 11, + CAST_ON_ALLPLAYERS = 12, + CAST_ON_FRENDLY = 13, + CAST_ON_FRENDLY_LOWHP = 14, + CAST_ON_RANDOM_POINT = 15, + CAST_ON_RANDOM_PLAYER = 16, + APPLY_AURA_ALLPLAYERS = 17, + FORCE_CAST = 18, + SPELLTABLEPARM_NUMBER +}; + +struct Locations +{ + float x, y, z, o; + int32 id; +}; + +struct WayPoints +{ + WayPoints(int32 _id, float _x, float _y, float _z) + { + id = _id; + x = _x; + y = _y; + z = _z; + } + int32 id; + float x, y, z; +}; + +struct BSWRecord +{ + + public: + // External (loaded from database) variables + uint32 id; + uint32 m_uiSpellEntry[DIFFICULTY_LEVELS]; // Stores spell entry for difficulty levels + uint32 m_uiSpellTimerMin[DIFFICULTY_LEVELS]; // The timer (min) before the next spell casting, in milliseconds + uint32 m_uiSpellTimerMax[DIFFICULTY_LEVELS]; // The timer (max) before the next spell casting + uint32 m_uiSpellData[DIFFICULTY_LEVELS]; // Additional data for spell casting or summon + Locations LocData; // Float data structure for locations + int varData; // Additional data for spell + uint32 StageMaskN; // Stage mask for this spell (normal) + uint32 StageMaskH; // Stage mask for this spell (heroic) + BossSpellTableParameters m_CastTarget; // Target on casting spell + bool m_IsVisualEffect; // Spellcasting is visual effect or real effect + bool m_IsBugged; // Need override for this spell + int32 textEntry; // Text entry from script_text for this spell + // Internal variables + uint32 m_SpellTimer; // Current timer for this spell +}; + +struct MANGOS_DLL_DECL BSWScriptedAI : public ScriptedAI +{ + public: + explicit BSWScriptedAI(Creature* pCreature); + + ~BSWScriptedAI(); + + void doReset(); + + void resetTimer(uint32 SpellID) + { + if (queryIndex(_findSpellIDX(SpellID))) _resetTimer(_findSpellIDX(SpellID)); + else return; + }; + + void resetTimers() + { + for (uint8 i = 0; i < bossSpellCount(); ++i) + _resetTimer(i); + }; + + bool timedQuery(uint32 SpellID, uint32 diff, bool ignorecast = false) + { + return queryIndex(_findSpellIDX(SpellID)) ? _QuerySpellPeriod(_findSpellIDX(SpellID), diff, ignorecast) : false; + }; + + CanCastResult timedCast(uint32 SpellID, uint32 diff, Unit* pTarget = NULL) + { + if (!queryIndex(_findSpellIDX(SpellID))) return CAST_FAIL_OTHER; + return _QuerySpellPeriod(_findSpellIDX(SpellID), diff) ? _BSWSpellSelector(_findSpellIDX(SpellID), pTarget) : CAST_FAIL_STATE; + }; + + CanCastResult doCast(uint32 SpellID, Unit* pTarget = NULL) + { + return queryIndex(_findSpellIDX(SpellID)) ? _BSWSpellSelector(_findSpellIDX(SpellID), pTarget) : CAST_FAIL_OTHER; + }; + + CanCastResult doCast(Unit* pTarget, uint32 SpellID) + { + if (!pTarget) return CAST_FAIL_OTHER; + return queryIndex(_findSpellIDX(SpellID)) ? _BSWCastOnTarget(pTarget, _findSpellIDX(SpellID)) : CAST_FAIL_OTHER; + }; + + bool doRemove(uint32 SpellID, Unit* pTarget = NULL, uint8 index = EFFECT_INDEX_ALL) + { + return queryIndex(_findSpellIDX(SpellID)) ? _doRemove(_findSpellIDX(SpellID),pTarget,index) : _doRemove(SpellID,pTarget,index); + }; + + bool doRemoveFromAll(uint32 SpellID) + { + return queryIndex(_findSpellIDX(SpellID)) ? _doRemoveFromAll(_findSpellIDX(SpellID)) : _doRemoveFromAll(SpellID); + }; + + bool doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint = 0, bool isStack = true) + { + return queryIndex(_findSpellIDX(SpellID)) ? _doAura(_findSpellIDX(SpellID), pTarget, index, isStack) : _doAura(SpellID, pTarget, index, basepoint, isStack); + }; + + bool doAura(uint32 SpellID, Unit* pTarget = NULL) + { + return queryIndex(_findSpellIDX(SpellID)) ? _doAura(_findSpellIDX(SpellID), pTarget) : _doAura(SpellID, pTarget); + }; + + bool hasAura(uint32 SpellID, Unit* pTarget = NULL) + { + if (!pTarget) pTarget = m_creature; + return queryIndex(_findSpellIDX(SpellID)) ? _hasAura(_findSpellIDX(SpellID),pTarget) : _hasAura(SpellID,pTarget); + }; + + uint8 auraCount(uint32 SpellID, Unit* pTarget = NULL, SpellEffectIndex index = EFFECT_INDEX_0) + { + if (!pTarget) pTarget = m_creature; + return queryIndex(_findSpellIDX(SpellID)) ? _auraCount(_findSpellIDX(SpellID),pTarget,index) : _auraCount(SpellID,pTarget,index); + }; + + Unit* doSummon(uint32 SpellID, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN, uint32 delay = 60000) + { + return queryIndex(_findSpellIDX(SpellID)) ? _doSummon(_findSpellIDX(SpellID), type, delay) : NULL; + }; + + Unit* doSelectRandomPlayer(uint32 SpellID = 0, bool spellsearchtype = false, float range = 100.0f, bool includeVictim = true) + { + return _doSelect(SpellID, spellsearchtype, range, includeVictim); + }; + + Unit* doSelectRandomPlayerAtRange(float range, bool includeVictim = true) + { + return _doSelect(0, false, range, includeVictim); + }; + + Unit* doSummon(uint32 SpellID, float fPosX, float fPosY, float fPosZ, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN, uint32 delay = 60000) + { + return queryIndex(_findSpellIDX(SpellID)) ? _doSummonAtPosition(_findSpellIDX(SpellID), fPosX, fPosY, fPosZ) : _doSummonAtPosition(SpellID, type, delay, fPosX, fPosY, fPosZ); + }; + + uint8 bossSpellCount() + { + return m_BSWRecords.size(); + }; + + bool queryIndex(uint8 m_uiSpellIdx) + { + if (m_uiSpellIdx == SPELL_INDEX_ERROR) return false; + else if (m_uiSpellIdx >= 0 && m_uiSpellIdx < bossSpellCount()) return true; + else return false; + }; + + Creature* doSelectNearestCreature(uint32 guid, float range = 120.0f); + + uint32 getSpellData(uint32 SpellID) + { + return queryIndex(_findSpellIDX(SpellID)) ? _getSpellData(_findSpellIDX(SpellID)) : 0; + }; + + bool doCastAll(uint32 diff); + + uint8 getStage() { return _stage; }; + + void setStage(uint8 stage) { _stage = stage; }; + + bool isHeroic() { Map* pMap = m_creature->GetMap(); return pMap->IsRaid() ? _isDifficultyInMask(12) : _isDifficultyInMask(2); }; + + bool isNormal() { return !isHeroic(); }; + + bool is25() { Map* pMap = m_creature->GetMap(); return pMap->IsRaid() ? _isDifficultyInMask(10) : false; }; + + uint32 getSpellWithDifficulty(uint32 SpellID) { return (queryIndex(_findSpellIDX(SpellID)) ? m_BSWRecords[_findSpellIDX(SpellID)].m_uiSpellEntry[currentDifficulty] : SpellID); }; + + protected: + + Difficulty currentDifficulty; + + std::vector m_BSWRecords; + + private: + + BossSpellTableParameters _getBSWCastType(uint32 pTemp); + + uint8 _findSpellIDX(uint32 SpellID); + + BSWRecord* _getRecord(uint32 SpellID); + + void _loadFromDB(); + + void _resetTimer(uint8 m_uiSpellIdx); + + Unit* _doSelect(uint32 SpellID, bool spellsearchtype = false, float range = 100.0f, bool includeVictim = true); + + Unit* _doSummon(uint8 m_uiSpellIdx, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN, uint32 delay = 60000); + + Unit* _doSummonAtPosition(uint8 m_uiSpellIdx, float fPosX, float fPosY, float fPosZ); + + Unit* _doSummonAtPosition(uint32 guid, TempSummonType type, uint32 delay, float fPosX, float fPosY, float fPosZ); + + CanCastResult _BSWDoCast(uint8 m_uiSpellIdx, Unit* pTarget); + + CanCastResult _BSWDoForceCast(uint8 m_uiSpellIdx, Unit* pTarget); + + CanCastResult _BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget = NULL); + + CanCastResult _BSWCastOnTarget(Unit* pTarget, uint8 m_uiSpellIdx); + + bool _QuerySpellPeriod(uint8 m_uiSpellIdx, uint32 diff, bool ignorecast = false); + + CanCastResult _DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags = 0, uint64 uiOriginalCasterGUID = 0); + + bool _doRemove(uint8 m_uiSpellIdx, Unit* pTarget = NULL, uint8 index = EFFECT_INDEX_ALL); + + bool _doRemove(uint32 SpellID, Unit* pTarget, uint8 index = EFFECT_INDEX_ALL); + + bool _doRemoveFromAll(uint8 m_uiSpellIdx); + + bool _doRemoveFromAll(uint32 SpellID); + + bool _doAura(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index, bool isStack = true); + + bool _doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint = 0, bool isStack = true); + + bool _doAura(uint8 m_uiSpellIdx, Unit* pTarget); + + bool _doAura(uint32 SpellID, Unit* pTarget); + + bool _hasAura(uint8 m_uiSpellIdx, Unit* pTarget); + + bool _hasAura(uint32 SpellID, Unit* pTarget); + + uint8 _auraCount(uint8 m_uiSpellIdx, Unit* pTarget = NULL, SpellEffectIndex index = EFFECT_INDEX_0); + + uint8 _auraCount(uint32 SpellID, Unit* pTarget, SpellEffectIndex index); + + void _fillEmptyDataField(); + + uint32 _getSpellData(uint8 m_uiSpellIdx); + + bool _isDifficultyInMask(uint8 mask); + + uint8 _stage; + +}; + +#endif \ No newline at end of file diff --git a/base/BSW_instance.cpp b/base/BSW_instance.cpp new file mode 100644 index 000000000..d7c695142 --- /dev/null +++ b/base/BSW_instance.cpp @@ -0,0 +1,172 @@ +/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#include "precompiled.h" +#include "BSW_instance.h" + +BSWScriptedInstance::BSWScriptedInstance(Map* pMap) : ScriptedInstance(pMap) +{ + debug_log("BSW: Initialized BSWScriptedInstance structure for map %u difficulty %u",pMap->GetId(),pMap->GetDifficulty()); + m_auiEvent = 0; + m_auiEventTimer = 0; + m_auiCreatureID = 0; + m_auiEventLock = false; + m_pMap = pMap; + m_objectGuidMap.clear(); +}; + +BSWScriptedInstance::~BSWScriptedInstance() +{ + debug_log("BSW: Removing BSWScriptedInstance structure for map %u",m_pMap->GetId()); +}; + +void BSWScriptedInstance::DoCompleteAchievement(uint32 uiAchievmentId) +{ + 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->CompletedAchievement(uiAchievmentId); + } + } + else + debug_log("BSW: DoCompleteAchievement attempt set data, but no players in map."); +} + +void BSWScriptedInstance::DoOpenDoor(uint64 guid) +{ + if (!guid) + return; + + GameObject* pGo = instance->GetGameObject(guid); + + if (pGo) + pGo->SetGoState(GO_STATE_ACTIVE); + else + debug_log("BSW: DoOpenDoor attempt set data to object %u, but no this object", guid); +} + +void BSWScriptedInstance::DoCloseDoor(uint64 guid) +{ + if (!guid) + return; + + GameObject* pGo = instance->GetGameObject(guid); + + if (pGo) + pGo->SetGoState(GO_STATE_READY); + else + debug_log("BSW: DoCloseDoor attempt set data to object %u, but no this object", guid); +} + +uint32 BSWScriptedInstance::GetEvent(uint32 creatureID) +{ + if (m_auiEventLock || m_auiCreatureID != creatureID) + { + return 0; + } + else + { + debug_log("BSW: GetEvent: send event %u to creature %u",m_auiEvent, creatureID); + m_auiEventLock = true; + return m_auiEvent; + } +} + +void BSWScriptedInstance::SetNextEvent(uint32 EventNum, uint32 creatureID, uint32 timer) +{ + m_auiEvent = EventNum; + m_auiCreatureID = creatureID; + m_auiEventTimer = timer; + m_auiEventLock = false; + debug_log("BSW: SetNextEvent: setted event %u to creature %u, timer %u",m_auiEvent, creatureID, timer); +} + +bool BSWScriptedInstance::GetEventTimer(uint32 creatureID, const uint32 diff) +{ + if (m_auiEvent == 0 || m_auiCreatureID != creatureID) + return false; + + if (m_auiEventTimer <= diff) + { + m_auiEventTimer = 0; + return true; + } + else + { + m_auiEventTimer -= diff; + return false; + } +} + +void BSWScriptedInstance::SetObject(Object* object) +{ + if (!object) + return; + + m_objectGuidMap.insert(std::make_pair(object->GetEntry(), object->GetObjectGuid())); + +} + +ObjectGuid const& BSWScriptedInstance::GetInstanceObjectGuid(uint32 entry) +{ + std::map::const_iterator itr = m_objectGuidMap.find(entry); + + if (itr != m_objectGuidMap.end()) + return itr->second; + else + return ObjectGuid(); + +} + +uint64 BSWScriptedInstance::GetInstanceObjectGUID(uint32 entry) +{ + ObjectGuid guid = GetInstanceObjectGuid(entry); + if (guid.IsEmpty()) + return 0; + else + return guid.GetRawValue(); +} + +void BSWScriptedInstance::SetCriteriaState(uint32 criteria_id, bool state, Player* player) +{ + if (!criteria_id) + return; + + if (player && state) + m_personalCriteriaMap.insert(std::make_pair(criteria_id, player->GetObjectGuid())); + else + m_groupCriteriaMap.insert(std::make_pair(criteria_id, state)); + +} + +bool BSWScriptedInstance::GetCriteriaState(uint32 criteria_id, Player const* player) +{ + if (!criteria_id) + return false; + + std::map::const_iterator itr = m_groupCriteriaMap.find(criteria_id); + + if (itr != m_groupCriteriaMap.end()) + if (itr->second) + return true; + + if (player) + { + std::pair::const_iterator, std::multimap::const_iterator> bounds = + m_personalCriteriaMap.equal_range(criteria_id); + + for(std::multimap::const_iterator itr = bounds.first; itr != bounds.second; ++itr) + { + if (itr->second == player->GetObjectGuid()) + return true; + } + + } + + return false; +} diff --git a/base/BSW_instance.h b/base/BSW_instance.h new file mode 100644 index 000000000..0f4eb1336 --- /dev/null +++ b/base/BSW_instance.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef BSW_INSTANCE_H +#define BSW_INSTANCE_H +#define BSW_INSTANCE_VERSION 0.6.20 +#include "sc_instance.h" + +class MANGOS_DLL_DECL BSWScriptedInstance : public ScriptedInstance +{ + public: + + BSWScriptedInstance(Map* pMap); + ~BSWScriptedInstance(); + + //sends completed achievments to all players in instance + void DoCompleteAchievement(uint32 uiAchievmentId); + void DoOpenDoor(uint64 guid); + void DoCloseDoor(uint64 guid); + + uint64 GetInstanceObjectGUID(uint32 entry); + ObjectGuid const& GetInstanceObjectGuid(uint32 entry); + void SetObject(Object* object); + void SetInstanceObject(GameObject* go) { if (go) SetObject((Object*)go); }; + void SetInstanceUnit(Unit* unit) { if (unit) SetObject((Object*)unit); }; + void SetInstanceCreature(Creature* creature) { if (creature) SetObject((Object*)creature); }; + + void SetCriteriaState(uint32 criteria_id, bool state = true, Player* player = NULL); + bool GetCriteriaState(uint32 criteria_id, Player const* player = NULL); + + void SetNextEvent(uint32 EventNum, uint32 creatureID, uint32 timer = 1000); + uint32 GetEvent(uint32 creatureID); + bool GetEventTimer(uint32 creatureID, const uint32 diff); + + private: + uint32 m_auiEvent; + uint32 m_auiCreatureID; + uint32 m_auiEventTimer; + bool m_auiEventLock; + Map* m_pMap; + std::map m_objectGuidMap; + std::map m_groupCriteriaMap; + std::multimap m_personalCriteriaMap; + +}; +#endif diff --git a/base/escort_ai.cpp b/base/escort_ai.cpp index bfce9385e..41eea6f73 100644 --- a/base/escort_ai.cpp +++ b/base/escort_ai.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -517,3 +517,4 @@ void npc_escortAI::SetEscortPaused(bool bPaused) else RemoveEscortState(STATE_ESCORT_PAUSED); } + diff --git a/base/escort_ai.h b/base/escort_ai.h index 8094e3115..9210343b5 100644 --- a/base/escort_ai.h +++ b/base/escort_ai.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/base/follower_ai.cpp b/base/follower_ai.cpp index 754688198..018746274 100644 --- a/base/follower_ai.cpp +++ b/base/follower_ai.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/base/follower_ai.h b/base/follower_ai.h index 8cc70f42d..5f23aff9c 100644 --- a/base/follower_ai.h +++ b/base/follower_ai.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/base/guard_ai.cpp b/base/guard_ai.cpp index 5554d54b2..f3de45194 100644 --- a/base/guard_ai.cpp +++ b/base/guard_ai.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -102,7 +102,7 @@ void guardAI::UpdateAI(const uint32 uiDiff) if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) { //If we are within range melee the target - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { bool bHealing = false; const SpellEntry *pSpellInfo = NULL; diff --git a/base/guard_ai.h b/base/guard_ai.h index 832bd2462..12697b6bf 100644 --- a/base/guard_ai.h +++ b/base/guard_ai.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/base/pet_ai.cpp b/base/pet_ai.cpp new file mode 100644 index 000000000..040484359 --- /dev/null +++ b/base/pet_ai.cpp @@ -0,0 +1,126 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +/* 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) +{} + +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); + } + } +} diff --git a/base/pet_ai.h b/base/pet_ai.h new file mode 100644 index 000000000..8665f488a --- /dev/null +++ b/base/pet_ai.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#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 MANGOS_DLL_DECL ScriptedPetAI : public CreatureAI +{ + public: + explicit ScriptedPetAI(Creature* pCreature); + ~ScriptedPetAI() {} + + void MoveInLineOfSight(Unit* /*pWho*/); + + void AttackStart(Unit* /*pWho*/); + + void AttackedBy(Unit* /*pAttacker*/); + + void KilledUnit(Unit* /*pVictim*/) {} + + void OwnerKilledUnit(Unit* /*pVictim*/) {} + + void UpdateAI(const uint32 uiDiff); + + 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 diff --git a/config.h b/config.h index 16050750a..ba749f939 100644 --- a/config.h +++ b/config.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2009 MaNGOS + * Copyright (C) 2005-2011 MaNGOS * * 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 @@ -21,6 +21,7 @@ #include "Platform/CompilerDefs.h" #include "revision.h" +#include "sd2_revision_nr.h" // Format is YYYYMMDDRR where RR is the change in the conf file // for that day. @@ -35,7 +36,7 @@ #endif #ifndef _VERSION - #define _VERSION "Revision [" REVISION_ID "] " REVISION_DATE " " REVISION_TIME + #define _VERSION "Revision [" SD2_REVISION_NR "] (" REVISION_ID ") " REVISION_DATE " " REVISION_TIME " /dev/rsa branch" #endif // The path to config files diff --git a/config.h.in b/config.h.in deleted file mode 100644 index bb3caf880..000000000 --- a/config.h.in +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * 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 - */ - -#ifndef SC_CONFIG_H -#define SC_CONFIG_H - -#include "Platform/CompilerDefs.h" -#include "revision.h" - -// Format is YYYYMMDDRR where RR is the change in the conf file -// for that day. -#define SD2_CONF_VERSION 2009040501 - -#ifdef WIN32 - #define MANGOS_DLL_EXPORT extern "C" __declspec(dllexport) -#elif defined( __GNUC__ ) - #define MANGOS_DLL_EXPORT extern "C" -#else - #define MANGOS_DLL_EXPORT extern "C" export -#endif - -#ifndef _VERSION - #define _VERSION "Revision [" REVISION_ID "] " REVISION_DATE " " REVISION_TIME -#endif - -// The path to config files -#ifndef SYSCONFDIR - #define SYSCONFDIR "" -#endif - -#if PLATFORM == PLATFORM_WINDOWS - #ifdef _WIN64 - #define _FULLVERSION _VERSION " (Win64)" - #else - #define _FULLVERSION _VERSION " (Win32)" - #endif - #define _SCRIPTDEV2_CONFIG "scriptdev2.conf" -#else - #define _FULLVERSION _VERSION " (Unix)" - #define _SCRIPTDEV2_CONFIG SYSCONFDIR"scriptdev2.conf" -#endif - -#endif diff --git a/docs/How to install.txt b/docs/How to install.txt index 7bf184749..ef7fdecab 100644 --- a/docs/How to install.txt +++ b/docs/How to install.txt @@ -2,28 +2,22 @@ --- How to install ScriptDev2 --- 1) Download MaNGOS (using git clone) +See their forum/ wiki for more details 2) Do the source stuff: +- Clone ScriptDev2 "git clone git://github.com/scriptdev2/scriptdev2.git ScriptDev2" - execute from within src/bindings directory MS Windows: -- Create a new folder under "src\bindings\" within the MaNGOS source called "ScriptDev2" -- Checkout the ScriptDev2 trunk from "https://scriptdev2.svn.sourceforge.net/svnroot/scriptdev2" -- Apply the Git patch to Mangos - "git am src/bindings/ScriptDev2/patches/MaNGOS-XXXX-ScriptDev2.patch" ('XXXX' is revision number for Mangos). (Note this is not required for compile, but needed to avoid deletion of untracked folders/files in GIT-directory when using certain GIT commands (example: git clean -f -d)) -- Compile MaNGOS -- Compile ScriptDev2 using the ScriptVC80 or ScriptVC90 Solution within the ScriptDev2 folder (this will overwrite the Mangoscript dll in the output directory) - -GNU/Linux: -- Checkout the ScriptDev2 to "src/bindings/ScriptDev2" - "svn co https://scriptdev2.svn.sourceforge.net/svnroot/scriptdev2 src/bindings/ScriptDev2" -SVN: -- Apply MaNGOS-XXXX-ScriptDev2.patch to Mangos, where XXXX is the highest version to that of your MaNGOS revision. -GIT: -- Apply the Git patch to Mangos - "git am src/bindings/ScriptDev2/patches/MaNGOS-XXXX-ScriptDev2.patch" +- Compile ScriptDev2 using the scriptVC80, scriptVC90 or scriptVC100 Solution within the ScriptDev2 folder (this will overwrite the Mangoscript dll in the output directory) +GNU/Linux or CMake: +- Apply the Git patch to Mangos - "git am src/bindings/ScriptDev2/patches/MaNGOS-XXXX-ScriptDev2.patch" - Compile MaNGOS (ScriptDev2 will automatically be built when compiling Mangos from here on) + 3) Create the default ScriptDev2 database using -"sql\scriptdev2_create_database.sql", then execute -"sql\scriptdev2_create_structure.sql" on that database. + "sql\scriptdev2_create_database.sql", then execute + "sql\scriptdev2_create_structure.sql" on that database. 4) Execute the following on your ScriptDev2 database. - sql\scriptdev2_script_full.sql @@ -37,17 +31,15 @@ GIT: To update ScriptDev2: +- Enter src/bindings/ScriptDev2 directory (with git-bash) +- Update ScriptDev2 - "git pull" MS Windows: -- All you have to do is open src\bindings\ and right click on the ScriptDev2 folder and click "Update" and then follow steps 4, 6, and 7 again. You must still compile MaNGOS before ScriptDev2 when on the Windows platform. - -GNU/Linux: -- Go to the src/bindings/ScriptDev2 directory - "cd src/bindings/ScriptDev2" -- Update ScriptDev2 - "svn up" +- You must still compile MaNGOS before ScriptDev2 when on the Windows platform. To update your Database with new Scriptdev2 SQL changes you can either: a) apply only the changes that were made during that revision by looking in the sql\update folder or (files named rXXX_scriptdev2.sql should be executed on the scriptdev2 db while rXXX_mangos.sql should be executed on your mangos db) -b) reapply "mangos_scriptname_full.sql" to your MaNGOS database. +b) reapply "mangos_scriptname_full.sql" to your MaNGOS database. - WARNING this will NOT include removed script names! You can view the ScriptDev2 Change Log at: -http://scriptdev2.svn.sourceforge.net/viewvc/scriptdev2/?view=log +https://github.com/scriptdev/scriptdev2/commits/master diff --git a/docs/Script Layout.txt b/docs/Script Layout.txt index a66cb3565..53cfadd63 100644 --- a/docs/Script Layout.txt +++ b/docs/Script Layout.txt @@ -3,30 +3,20 @@ A quick explanation of the layout I hope everyone will follow for scriptdev2. --- Sub Folders --- -Area - Contains scripts used solely by area triggers +battlegrounds - Contains scripts for npcs in Battlegrounds -Boss - Boss scripts for bosses that are not zone specific +custom - Intentionally empty folder from SVN. If you make a custom script please put it here. -Mob - Generic Creature scripts for creatures that are not zone specific +examples - Contains a couple of example scripts showing the most commonly used functions within SD2 -Custom - Intentionally empty folder from SVN. If you make a custom script please put it here. +eastern_kingdoms, kalimdor, northrend, outland - Contain scripts for anything related to npcs or instances on the corresponding continent. +Instances are grouped to subfolders, the normal continent-maps are divided into zones -GO - Contains scripts used solely by Game Objects (GOs) that do not have a specific zone - -Guard - Scripts for Guard NPCs - -Honor - Honor npcs (currently a blank script as these npcs do nothing special) - -Item - Item scripts - -NPC - Scripts for individual NPCs who do not have a specific zone - -Servers - Generic NPC servers script for things such as flightmasters and guildmasters. - -Zone - ALL zone specific scripts should be written within these folders. This includes creature scripts, boss scripts, go scripts, area scripts, and npc scripts. +world - Contains scripts for anything that is not related to a specified zone. +This includes item_scripts, areatrigger_scripts, some npcs that can be found at many places, go_scripts and spell_scripts --- Naming Conventions --- Please keep file names to "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 should follow "void AddSC_creaturename(void);" format. Do not append AI or anything else. +AddSC functions should follow "void AddSC_filename(void);" format. Do not append AI or anything else. diff --git a/include/precompiled.cpp b/include/precompiled.cpp index b4ce73fb1..120f738fe 100644 --- a/include/precompiled.cpp +++ b/include/precompiled.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/include/precompiled.h b/include/precompiled.h index 7bf0d38ae..37e965460 100644 --- a/include/precompiled.h +++ b/include/precompiled.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -10,6 +10,7 @@ #include "sc_gossip.h" #include "sc_grid_searchers.h" #include "sc_instance.h" +#include "sc_outdoor_pvp.h" #ifdef WIN32 # include diff --git a/include/sc_creature.cpp b/include/sc_creature.cpp index a25f7ea86..bae806f38 100644 --- a/include/sc_creature.cpp +++ b/include/sc_creature.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -81,15 +81,7 @@ void ScriptedAI::UpdateAI(const uint32 uiDiff) if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (m_creature->isAttackReady()) - { - //If we are within range melee the target - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) - { - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); - } - } + DoMeleeAttackIfReady(); } void ScriptedAI::EnterEvadeMode() @@ -127,20 +119,6 @@ void ScriptedAI::DoStartNoMovement(Unit* pVictim) m_creature->StopMoving(); } -void ScriptedAI::DoMeleeAttackIfReady() -{ - //Make sure our attack is ready before checking distance - if (m_creature->isAttackReady()) - { - //If we are within range melee the target - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) - { - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); - } - } -} - void ScriptedAI::DoStopAttack() { if (m_creature->getVictim()) @@ -487,10 +465,11 @@ void ScriptedAI::SetCombatMovement(bool bCombatMove) // 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_BROODLORD = 12017, + NPC_VOID_REAVER = 19516, + NPC_JAN_ALAI = 23578, + NPC_SARTHARION = 28860, + NPC_TALON_KING_IKISS = 18473, }; bool ScriptedAI::EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) @@ -525,7 +504,13 @@ bool ScriptedAI::EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) return false; break; case NPC_SARTHARION: // sartharion (calculate box) - if (fX > 3218.86f && fX < 3275.69f && fY < 572.40f && fY > 484.68f) + if (fX > 3203.97f && fX < 3289.40f && fY < 576.70f && 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; default: diff --git a/include/sc_creature.h b/include/sc_creature.h index 0c8a6fd0c..123ccb5d9 100644 --- a/include/sc_creature.h +++ b/include/sc_creature.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -120,9 +120,6 @@ struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI //Start no movement on victim void DoStartNoMovement(Unit* pVictim); - //Do melee swing of current victim if in rnage and ready and not casting - void DoMeleeAttackIfReady(); - //Stop attack of current victim void DoStopAttack(); diff --git a/include/sc_gossip.h b/include/sc_gossip.h index e1034572f..28d7e7a9b 100644 --- a/include/sc_gossip.h +++ b/include/sc_gossip.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/include/sc_grid_searchers.cpp b/include/sc_grid_searchers.cpp index 27343151c..42b662d5c 100644 --- a/include/sc_grid_searchers.cpp +++ b/include/sc_grid_searchers.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/include/sc_grid_searchers.h b/include/sc_grid_searchers.h index a15a637d2..258e270e8 100644 --- a/include/sc_grid_searchers.h +++ b/include/sc_grid_searchers.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/include/sc_instance.cpp b/include/sc_instance.cpp index 30e085bf9..d57048641 100644 --- a/include/sc_instance.cpp +++ b/include/sc_instance.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -56,3 +56,85 @@ void ScriptedInstance::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData) else debug_log("SD2: DoUpdateWorldState attempt send data but no players in map."); } + +void ScriptedInstance::DoCompleteAchievement(uint32 uiAchievmentId) +{ + 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->CompletedAchievement(uiAchievmentId); + } + } + else + debug_log("SD2: DoCompleteAchievement attempt set data but no players in map."); +} + +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; +} + +void ScriptedInstance::DoStartTimedAchievement(AchievementCriteriaTypes tCriteriaType, 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(tCriteriaType, uiTimedCriteriaMiscId); + } + } + else + debug_log("SD2: DoStartTimedAchievement attempt start achievements but no players in map."); +} + +// Open door or Use button - Optional uiWithRestoreTime. If not defined, autoCloseTime will be used (if not 0 by default in *_template) +void ScriptedInstance::DoOpenDoorOrButton(uint64 uiGuid, uint32 uiWithRestoreTime, bool bUseAlternativeState) +{ + if (!uiGuid) + return; + + if (GameObject* pGo = instance->GetGameObject(uiGuid)) + { + if (pGo->GetGoType() == GAMEOBJECT_TYPE_DOOR || pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON) + { + if (pGo->getLootState() == GO_READY) + pGo->UseDoorOrButton(uiWithRestoreTime, bUseAlternativeState); + } + else + error_log("SD2: Script call DoOpenDoorOrButton, but gameobject entry %u is type %u.",pGo->GetEntry(),pGo->GetGoType()); + } +} + +// Close door or Reset button +void ScriptedInstance::DoCloseDoorOrButton(uint64 uiGuid) +{ + if (!uiGuid) + return; + + if (GameObject* pGo = instance->GetGameObject(uiGuid)) + { + if (pGo->GetGoType() == GAMEOBJECT_TYPE_DOOR || pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON) + { + if (pGo->getLootState() == GO_ACTIVATED) + pGo->ResetDoorOrButton(); + } + else + error_log("SD2: Script call DoCloseDoorOrButton, but gameobject entry %u is type %u.",pGo->GetEntry(),pGo->GetGoType()); + } +} diff --git a/include/sc_instance.h b/include/sc_instance.h index 8faacc1a7..f8344b3eb 100644 --- a/include/sc_instance.h +++ b/include/sc_instance.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -30,13 +30,29 @@ class MANGOS_DLL_DECL ScriptedInstance : public InstanceData ScriptedInstance(Map* pMap) : InstanceData(pMap) {} ~ScriptedInstance() {} - //change active state of doors or buttons + // Change active state of doors or buttons void DoUseDoorOrButton(uint64 uiGuid, uint32 uiWithRestoreTime = 0, bool bUseAlternativeState = false); - //Respawns a GO having negative spawntimesecs in gameobject-table + // Open door or Use button + void DoOpenDoorOrButton(uint64 uiGuid, uint32 uiWithRestoreTime = 0, bool bUseAlternativeState = false); + + // Close door or Reset button + void DoCloseDoorOrButton(uint64 uiGuid); + + // Respawns a GO having negative spawntimesecs in gameobject-table void DoRespawnGameObject(uint64 uiGuid, uint32 uiTimeToDespawn = MINUTE); - //sends world state update to all players in instance + // Sends world state update to all players in instance void DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData); + + //sends completed achievments to all players in instance + void DoCompleteAchievement(uint32 uiAchievmentId); + + // Get a Player from map + Player* GetPlayerInMap(bool bOnlyAlive = false, bool bCanBeGamemaster = true); + + // starts a timed achievement criteria for all players in instance + void DoStartTimedAchievement(AchievementCriteriaTypes tCriteriaType, uint32 uiTimedCriteriaMiscId); + }; #endif diff --git a/include/sc_outdoor_pvp.cpp b/include/sc_outdoor_pvp.cpp new file mode 100644 index 000000000..0918cb7da --- /dev/null +++ b/include/sc_outdoor_pvp.cpp @@ -0,0 +1,40 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#include "precompiled.h" + +void OutdoorPvP::DoUpdateWorldState(PlayerSet sPlayerSet, uint32 uiStateId, uint32 uiStateData) +{ + for(PlayerSet::const_iterator itr = sPlayerSet.begin(); itr != sPlayerSet.end(); ++itr) + { + if (Player* pPlayer = instance->GetPlayer(*itr)) + pPlayer->SendUpdateWorldState(uiStateId, uiStateData); + } +} + +Player* OutdoorPvP::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; +} + +void OutdoorPvP::DoApplyTeamBuff(PlayerSet sPlayerSet, Team uiTeamId, uint32 uiSpellId) +{ + for(PlayerSet::const_iterator itr = sPlayerSet.begin(); itr != sPlayerSet.end(); ++itr) + { + if (Player* pPlayer = instance->GetPlayer(*itr)) + { + if (pPlayer->GetTeam() == uiTeamId) + pPlayer->CastSpell(pPlayer, uiSpellId, true); + } + } +} diff --git a/include/sc_outdoor_pvp.h b/include/sc_outdoor_pvp.h new file mode 100644 index 000000000..1f107509d --- /dev/null +++ b/include/sc_outdoor_pvp.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 +* This program is free software licensed under GPL version 2 +* Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef SC_OUTDOOR_PVP_H +#define SC_OUTDOOR_PVP_H + +#include "InstanceData.h" +#include "Map.h" + +#define OUT_SAVE_PVP_DATA debug_log("SD2: Saving OutdoorPvP Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) +#define OUT_SAVE_PVP_DATA_COMPLETE debug_log("SD2: Saving OutdoorPvP Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) +#define OUT_LOAD_PVP_DATA(a) debug_log("SD2: Loading OutdoorPvP Data for Instance %s (Map %d, Instance Id %d). Input is '%s'", instance->GetMapName(), instance->GetId(), instance->GetInstanceId(), a) +#define OUT_LOAD_PVP_DATA_COMPLETE debug_log("SD2: OutdoorPvP Data Load for Instance %s (Map %d, Instance Id: %d) is complete.",instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) +#define OUT_LOAD_PVP_DATA_FAIL error_log("SD2: Unable to load OutdoorPvP Data for Instance %s (Map %d, Instance Id: %d).",instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) + +class MANGOS_DLL_DECL OutdoorPvP : public InstanceData +{ + public: + OutdoorPvP(Map* pMap) : InstanceData(pMap) {} + ~OutdoorPvP() {} + + typedef std::set PlayerSet; + + // Sends world state update to all players in the current zone; they are stored in a PlayerSet + void DoUpdateWorldState(PlayerSet sPlayerSet, uint32 uiStateId, uint32 uiStateData); + + // Get a Player from map + Player* GetPlayerInMap(bool bOnlyAlive = false, bool bCanBeGamemaster = true); + + // Casts a spell to a specific team in a specific zone; they are stored in a PlayerSet + void DoApplyTeamBuff(PlayerSet sPlayerSet, Team uiTeamId, uint32 uiSpellId); +}; +#endif diff --git a/patches/MaNGOS-11167-ScriptDev2.patch b/patches/MaNGOS-11167-ScriptDev2.patch new file mode 100644 index 000000000..c0388de94 --- /dev/null +++ b/patches/MaNGOS-11167-ScriptDev2.patch @@ -0,0 +1,22 @@ +From bdaa99630113b7cb9d5e564a5777497d7530b490 Mon Sep 17 00:00:00 2001 +From: VladimirMangos +Date: Tue, 15 Feb 2011 02:15:26 +0100 +Subject: [PATCH] ScriptDev2 patch + +--- + src/bindings/CMakeLists.txt | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/src/bindings/CMakeLists.txt b/src/bindings/CMakeLists.txt +index fc13e3a..592d773 100644 +--- a/src/bindings/CMakeLists.txt ++++ b/src/bindings/CMakeLists.txt +@@ -16,4 +16,4 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # + +-# add_subdirectory(universal) ++add_subdirectory(ScriptDev2) +-- +1.7.3.1.msysgit.0 + diff --git a/patches/MaNGOS-9519-ScriptDev2.patch b/patches/MaNGOS-9519-ScriptDev2.patch deleted file mode 100644 index 50b80dd03..000000000 --- a/patches/MaNGOS-9519-ScriptDev2.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3a3dda6636d81c33c3c9b143f64b5a518bfadb56 Mon Sep 17 00:00:00 2001 -From: Reve -Date: Fri, 5 Mar 2010 21:41:55 +0100 -Subject: [PATCH] ScriptDev2 patch. - ---- - configure.ac | 6 +++++- - src/bindings/Makefile.am | 2 +- - src/mangosd/Makefile.am | 4 ++-- - 3 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 90b332a..c31ff26 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -308,7 +308,11 @@ AC_CONFIG_FILES([ - src/mangosd/Makefile - src/mangosd/mangosd.conf.dist - src/bindings/Makefile -- src/bindings/universal/Makefile -+ src/bindings/ScriptDev2/Makefile -+ src/bindings/ScriptDev2/scriptdev2.conf.dist -+ src/bindings/ScriptDev2/config.h -+ src/bindings/ScriptDev2/sql/Makefile -+ src/bindings/ScriptDev2/sql/Updates/Makefile - ]) - - ## Configure ACE, if needed -diff --git a/src/bindings/Makefile.am b/src/bindings/Makefile.am -index d7dc654..79ea910 100644 ---- a/src/bindings/Makefile.am -+++ b/src/bindings/Makefile.am -@@ -14,4 +14,4 @@ - # along with this program; if not, write to the Free Software - # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --SUBDIRS = universal -+SUBDIRS = ScriptDev2 -diff --git a/src/mangosd/Makefile.am b/src/mangosd/Makefile.am -index fe1ace1..40b6fdd 100644 ---- a/src/mangosd/Makefile.am -+++ b/src/mangosd/Makefile.am -@@ -40,7 +40,7 @@ mangos_worldd_SOURCES = \ - - ## Link world daemon against the shared library - mangos_worldd_LDADD = \ -- ../bindings/universal/libmangosscript.la \ -+ ../bindings/ScriptDev2/libmangosscript.la \ - ../game/libmangosgame.a \ - ../shared/Database/libmangosdatabase.a \ - ../shared/Config/libmangosconfig.a \ -@@ -51,7 +51,7 @@ mangos_worldd_LDADD = \ - ../../dep/src/g3dlite/libg3dlite.a \ - ../../dep/src/gsoap/libgsoap.a - --mangos_worldd_LDFLAGS = -L../../dep/src/g3dlite -L../../dep/src/gsoap -L../bindings/universal/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic -+mangos_worldd_LDFLAGS = -L../../dep/src/g3dlite -L../../dep/src/gsoap -L../bindings/ScriptDev2/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic - - ## Additional files to include when running 'make dist' - # Include world daemon configuration --- -1.6.5.1.1367.gcd48 - diff --git a/patches/custom/ScriptDev2_1835_to_MaNGOS_0.12.patch b/patches/custom/ScriptDev2_1835_to_MaNGOS_0.12.patch deleted file mode 100644 index e67d0e8b9..000000000 --- a/patches/custom/ScriptDev2_1835_to_MaNGOS_0.12.patch +++ /dev/null @@ -1,284 +0,0 @@ -Index: include/precompiled.h -=================================================================== ---- include/precompiled.h (revision 1838) -+++ include/precompiled.h (working copy) -@@ -11,6 +11,11 @@ - #include "sc_grid_searchers.h" - #include "sc_instance.h" - -+enum backports -+{ -+ UNIT_VIRTUAL_ITEM_SLOT_ID = UNIT_VIRTUAL_ITEM_SLOT_DISPLAY -+}; -+ - #ifdef WIN32 - # include - BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -Index: scripts/kalimdor/azuremyst_isle.cpp -=================================================================== ---- scripts/kalimdor/azuremyst_isle.cpp (revision 1838) -+++ scripts/kalimdor/azuremyst_isle.cpp (working copy) -@@ -103,7 +103,7 @@ - - void SpellHit(Unit* pCaster, const SpellEntry* pSpell) - { -- if (pSpell->SpellFamilyFlags2 & 0x080000000) -+ if (pSpell->Id == 28880) - { - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - m_creature->SetStandState(UNIT_STAND_STATE_STAND); -Index: scripts/kalimdor/onyxias_lair/boss_onyxia.cpp -=================================================================== ---- scripts/kalimdor/onyxias_lair/boss_onyxia.cpp (revision 1838) -+++ scripts/kalimdor/onyxias_lair/boss_onyxia.cpp (working copy) -@@ -299,7 +299,7 @@ - DoScriptText(SAY_PHASE_2_TRANS, m_creature); - - // sort of a hack, it is unclear how this really work but the values appear to be valid -- m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); -+ m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND/* | UNIT_BYTE1_FLAG_UNK_2*/); - m_creature->AddSplineFlag(SPLINEFLAG_FLYING); - - if (m_pPointData) -Index: scripts/northrend/dragonblight.cpp -=================================================================== ---- scripts/northrend/dragonblight.cpp (revision 1838) -+++ scripts/northrend/dragonblight.cpp (working copy) -@@ -101,7 +101,7 @@ - if (uiAction == GOSSIP_ACTION_INFO_DEF+1) - { - pPlayer->CLOSE_GOSSIP_MENU(); -- pPlayer->SendMovieStart(MOVIE_ID_GATES); -+// pPlayer->SendMovieStart(MOVIE_ID_GATES); - } - - return true; -Index: scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp -=================================================================== ---- scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp (revision 1838) -+++ scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp (working copy) -@@ -107,10 +107,10 @@ - DoCastSpellIfCan(m_creature->getVictim(), SPELL_MOONFIRE); - m_uiSpellTimer = 10000; - break; -- case CLASS_DEATH_KNIGHT: -- DoCastSpellIfCan(m_creature->getVictim(), SPELL_PLAGUE_STRIKE); -- m_uiSpellTimer = 10000; -- break; -+// case CLASS_DEATH_KNIGHT: -+// DoCastSpellIfCan(m_creature->getVictim(), SPELL_PLAGUE_STRIKE); -+// m_uiSpellTimer = 10000; -+// break; - } - } - else -Index: scripts/world/item_scripts.cpp -=================================================================== ---- scripts/world/item_scripts.cpp (revision 1838) -+++ scripts/world/item_scripts.cpp (working copy) -@@ -47,7 +47,7 @@ - pPlayer->SendEquipError(EQUIP_ERR_NONE, pItem, NULL); - - if (const SpellEntry* pSpellInfo = GetSpellStore()->LookupEntry(SPELL_ARCANE_CHARGES)) -- Spell::SendCastResult(pPlayer, pSpellInfo, 1, SPELL_FAILED_NOT_ON_GROUND); -+ Spell::SendCastResult(pPlayer, pSpellInfo, 1, SPELL_FAILED_ERROR); - - return true; - } -Index: scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp -=================================================================== ---- scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp (revision 1838) -+++ scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp (working copy) -@@ -91,10 +91,10 @@ - else - DoScriptText(EMOTE_UNLOCK_DOOR_AD, m_creature); - break; -- case 12: -- if (m_uiNpcEntry != NPC_ASH) -- m_creature->HandleEmote(EMOTE_ONESHOT_USESTANDING); -- break; -+// case 12: -+// if (m_uiNpcEntry != NPC_ASH) -+// m_creature->HandleEmote(EMOTE_ONESHOT_USESTANDING); -+// break; - case 13: - if (m_uiNpcEntry == NPC_ASH) - DoScriptText(SAY_POST_DOOR_AS, m_creature); -Index: system/ScriptLoader.cpp -=================================================================== ---- system/ScriptLoader.cpp (revision 1838) -+++ system/ScriptLoader.cpp (working copy) -@@ -263,85 +263,8 @@ - extern void AddSC_winterspring(); - - //northrend --extern void AddSC_boss_jedoga(); //ahnkahet --extern void AddSC_boss_nadox(); --extern void AddSC_boss_taldaram(); --extern void AddSC_boss_volazj(); --extern void AddSC_instance_ahnkahet(); --extern void AddSC_boss_anubarak(); //azjol-nerub --extern void AddSC_boss_hadronox(); --extern void AddSC_boss_krikthir(); --extern void AddSC_instance_azjol_nerub(); --extern void AddSC_boss_anubarak_trial(); //trial_of_the_crusader --extern void AddSC_boss_jaraxxus(); --extern void AddSC_instance_trial_of_the_crusader(); --extern void AddSC_northrend_beasts(); --extern void AddSC_trial_of_the_crusader(); --extern void AddSC_twin_valkyr(); --extern void AddSC_boss_novos(); //draktharon_keep --extern void AddSC_boss_tharonja(); --extern void AddSC_boss_trollgore(); --extern void AddSC_boss_colossus(); //gundrak --extern void AddSC_boss_galdarah(); --extern void AddSC_boss_moorabi(); --extern void AddSC_boss_sladran(); --extern void AddSC_instance_gundrak(); --extern void AddSC_boss_bronjahm(); // ICC, forge_of_souls --extern void AddSC_boss_devourer_of_souls(); --extern void AddSC_instance_forge_of_souls(); --extern void AddSC_boss_anubrekhan(); //naxxramas --extern void AddSC_boss_four_horsemen(); --extern void AddSC_boss_faerlina(); --extern void AddSC_boss_gluth(); --extern void AddSC_boss_gothik(); --extern void AddSC_boss_kelthuzad(); --extern void AddSC_boss_loatheb(); --extern void AddSC_boss_maexxna(); --extern void AddSC_boss_noth(); --extern void AddSC_boss_heigan(); --extern void AddSC_boss_patchwerk(); --extern void AddSC_boss_razuvious(); --extern void AddSC_boss_sapphiron(); --extern void AddSC_instance_naxxramas(); --extern void AddSC_boss_anomalus(); //nexus --extern void AddSC_boss_keristrasza(); --extern void AddSC_boss_ormorok(); --extern void AddSC_boss_telestra(); --extern void AddSC_instance_nexus(); --extern void AddSC_boss_sartharion(); //obsidian_sanctum --extern void AddSC_instance_obsidian_sanctum(); --extern void AddSC_boss_bjarngrim(); //Ulduar, halls_of_lightning --extern void AddSC_boss_ionar(); --extern void AddSC_boss_loken(); --extern void AddSC_boss_volkhan(); --extern void AddSC_instance_halls_of_lightning(); --extern void AddSC_boss_maiden_of_grief(); //Ulduar, halls_of_stone --extern void AddSC_boss_sjonnir(); --extern void AddSC_halls_of_stone(); --extern void AddSC_instance_halls_of_stone(); --extern void AddSC_instance_ulduar(); //ulduar --extern void AddSC_boss_ingvar(); //utgarde_keep --extern void AddSC_boss_keleseth(); --extern void AddSC_boss_skarvald_and_dalronn(); --extern void AddSC_instance_utgarde_keep(); --extern void AddSC_utgarde_keep(); --extern void AddSC_boss_gortok(); //utgarde_pinnacle --extern void AddSC_boss_skadi(); --extern void AddSC_boss_svala(); --extern void AddSC_boss_ymiron(); --extern void AddSC_instance_pinnacle(); --extern void AddSC_instance_violet_hold(); //violet_hold --extern void AddSC_violet_hold(); -+// removed - --extern void AddSC_borean_tundra(); --extern void AddSC_dalaran(); --extern void AddSC_dragonblight(); --extern void AddSC_howling_fjord(); --extern void AddSC_icecrown(); --extern void AddSC_sholazar_basin(); --extern void AddSC_storm_peaks(); --extern void AddSC_zuldrak(); -- - //outland - extern void AddSC_boss_exarch_maladaar(); //auchindoun, auchenai_crypts - extern void AddSC_boss_nexusprince_shaffar(); //auchindoun, mana_tombs -@@ -681,85 +604,8 @@ - AddSC_winterspring(); - - //northrend -- AddSC_boss_jedoga(); //ahnkahet -- AddSC_boss_nadox(); -- AddSC_boss_taldaram(); -- AddSC_boss_volazj(); -- AddSC_instance_ahnkahet(); -- AddSC_boss_anubarak(); //azjol-nerub -- AddSC_boss_hadronox(); -- AddSC_boss_krikthir(); -- AddSC_instance_azjol_nerub(); -- AddSC_boss_anubarak_trial(); //trial_of_the_crusader -- AddSC_boss_jaraxxus(); -- AddSC_instance_trial_of_the_crusader(); -- AddSC_northrend_beasts(); -- AddSC_trial_of_the_crusader(); -- AddSC_twin_valkyr(); -- AddSC_boss_novos(); //draktharon_keep -- AddSC_boss_tharonja(); -- AddSC_boss_trollgore(); -- AddSC_boss_colossus(); //gundrak -- AddSC_boss_galdarah(); -- AddSC_boss_moorabi(); -- AddSC_boss_sladran(); -- AddSC_instance_gundrak(); -- AddSC_boss_bronjahm(); // ICC, forge_of_souls -- AddSC_boss_devourer_of_souls(); -- AddSC_instance_forge_of_souls(); -- AddSC_boss_anubrekhan(); //naxxramas -- AddSC_boss_four_horsemen(); -- AddSC_boss_faerlina(); -- AddSC_boss_gluth(); -- AddSC_boss_gothik(); -- AddSC_boss_kelthuzad(); -- AddSC_boss_loatheb(); -- AddSC_boss_maexxna(); -- AddSC_boss_noth(); -- AddSC_boss_heigan(); -- AddSC_boss_patchwerk(); -- AddSC_boss_razuvious(); -- AddSC_boss_sapphiron(); -- AddSC_instance_naxxramas(); -- AddSC_boss_anomalus(); //nexus -- AddSC_boss_keristrasza(); -- AddSC_boss_ormorok(); -- AddSC_boss_telestra(); -- AddSC_instance_nexus(); -- AddSC_boss_sartharion(); //obsidian_sanctum -- AddSC_instance_obsidian_sanctum(); -- AddSC_boss_bjarngrim(); //Ulduar, halls_of_lightning -- AddSC_boss_ionar(); -- AddSC_boss_loken(); -- AddSC_boss_volkhan(); -- AddSC_instance_halls_of_lightning(); -- AddSC_boss_maiden_of_grief(); //Ulduar, halls_of_stone -- AddSC_boss_sjonnir(); -- AddSC_halls_of_stone(); -- AddSC_instance_halls_of_stone(); -- AddSC_instance_ulduar(); //ulduar -- AddSC_boss_ingvar(); //utgarde_keep -- AddSC_boss_keleseth(); -- AddSC_boss_skarvald_and_dalronn(); -- AddSC_instance_utgarde_keep(); -- AddSC_utgarde_keep(); -- AddSC_boss_gortok(); //utgarde_pinnacle -- AddSC_boss_skadi(); -- AddSC_boss_svala(); -- AddSC_boss_ymiron(); -- AddSC_instance_pinnacle(); -- AddSC_instance_violet_hold(); //violet_hold -- AddSC_violet_hold(); -+ // removed - -- AddSC_borean_tundra(); -- AddSC_dalaran(); -- AddSC_dragonblight(); -- AddSC_howling_fjord(); -- AddSC_icecrown(); -- AddSC_sholazar_basin(); -- AddSC_storm_peaks(); -- AddSC_zuldrak(); -- - //outland - AddSC_boss_exarch_maladaar(); //auchindoun, auchenai_crypts - AddSC_boss_nexusprince_shaffar(); //auchindoun, mana_tombs diff --git a/patches/custom/ScriptDev2_2007_to_MaNGOS_one.patch b/patches/custom/ScriptDev2_2007_to_MaNGOS_one.patch new file mode 100644 index 000000000..822d39d21 --- /dev/null +++ b/patches/custom/ScriptDev2_2007_to_MaNGOS_one.patch @@ -0,0 +1,497 @@ +From d858813d233e400278d18dff699e17600f104869 Mon Sep 17 00:00:00 2001 +From: ScriptDev2 +Date: Thu, 24 Mar 2011 00:16:38 +0100 +Subject: [PATCH] ScriptDev2 - One Compatibility patch + +Signed-off-by: Schmoozerd +--- + include/precompiled.h | 5 + + .../shadowfang_keep/shadowfang_keep.cpp | 8 +- + scripts/kalimdor/azuremyst_isle.cpp | 2 +- + scripts/kalimdor/onyxias_lair/boss_onyxia.cpp | 4 +- + scripts/northrend/dragonblight.cpp | 2 +- + .../auchenai_crypts/boss_exarch_maladaar.cpp | 8 +- + scripts/world/item_scripts.cpp | 2 +- + system/ScriptLoader.cpp | 316 ++----------------- + 8 files changed, 52 insertions(+), 295 deletions(-) + +diff --git a/include/precompiled.h b/include/precompiled.h +index 11b6b31..2f202a3 100644 +--- a/include/precompiled.h ++++ b/include/precompiled.h +@@ -11,6 +11,11 @@ + #include "sc_grid_searchers.h" + #include "sc_instance.h" + ++enum backports ++{ ++ UNIT_VIRTUAL_ITEM_SLOT_ID = UNIT_VIRTUAL_ITEM_SLOT_DISPLAY ++}; ++ + #ifdef WIN32 + # include + BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +diff --git a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp +index 2cb6676..d3b1c0c 100644 +--- a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp ++++ b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp +@@ -91,10 +91,10 @@ struct MANGOS_DLL_DECL npc_shadowfang_prisonerAI : public npc_escortAI + else + DoScriptText(EMOTE_UNLOCK_DOOR_AD, m_creature); + break; +- case 12: +- if (m_uiNpcEntry != NPC_ASH) +- m_creature->HandleEmote(EMOTE_ONESHOT_USESTANDING); +- break; ++// case 12: ++// if (m_uiNpcEntry != NPC_ASH) ++// m_creature->HandleEmote(EMOTE_ONESHOT_USESTANDING); ++// break; + case 13: + if (m_uiNpcEntry == NPC_ASH) + DoScriptText(SAY_POST_DOOR_AS, m_creature); +diff --git a/scripts/kalimdor/azuremyst_isle.cpp b/scripts/kalimdor/azuremyst_isle.cpp +index 94879c4..8aef16e 100644 +--- a/scripts/kalimdor/azuremyst_isle.cpp ++++ b/scripts/kalimdor/azuremyst_isle.cpp +@@ -103,7 +103,7 @@ struct MANGOS_DLL_DECL npc_draenei_survivorAI : public ScriptedAI + + void SpellHit(Unit* pCaster, const SpellEntry* pSpell) + { +- if (pSpell->SpellFamilyFlags2 & 0x080000000) ++ if (pSpell->Id == 28880) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); +diff --git a/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp b/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp +index fadb93d..d446e44 100644 +--- a/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp ++++ b/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp +@@ -312,7 +312,7 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI + DoScriptText(SAY_PHASE_2_TRANS, m_creature); + + // sort of a hack, it is unclear how this really work but the values appear to be valid +- m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); ++ m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND/* | UNIT_BYTE1_FLAG_UNK_2*/); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + + if (m_pPointData) +@@ -438,7 +438,7 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI + return; + + // All and only the Onyxia Deep Breath Spells have these visuals +- if (pSpell->SpellVisual[0] == SPELL_VISUAL_BREATH_A || pSpell->SpellVisual[0] == SPELL_VISUAL_BREATH_B) ++ if (pSpell->SpellVisual == SPELL_VISUAL_BREATH_A || pSpell->SpellVisual == SPELL_VISUAL_BREATH_B) + m_pInstance->SetData(TYPE_ONYXIA, DATA_PLAYER_TOASTED); + } + }; +diff --git a/scripts/northrend/dragonblight.cpp b/scripts/northrend/dragonblight.cpp +index a315b31..3335302 100644 +--- a/scripts/northrend/dragonblight.cpp ++++ b/scripts/northrend/dragonblight.cpp +@@ -101,7 +101,7 @@ bool GossipSelect_npc_alexstrasza_wr_gate(Player* pPlayer, Creature* pCreature, + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + pPlayer->CLOSE_GOSSIP_MENU(); +- pPlayer->SendMovieStart(MOVIE_ID_GATES); ++// pPlayer->SendMovieStart(MOVIE_ID_GATES); + } + + return true; +diff --git a/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp b/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp +index 621649f..26d6622 100644 +--- a/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp ++++ b/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp +@@ -107,10 +107,10 @@ struct MANGOS_DLL_DECL mob_stolen_soulAI : public ScriptedAI + DoCastSpellIfCan(m_creature->getVictim(), SPELL_MOONFIRE); + m_uiSpellTimer = 10000; + break; +- case CLASS_DEATH_KNIGHT: +- DoCastSpellIfCan(m_creature->getVictim(), SPELL_PLAGUE_STRIKE); +- m_uiSpellTimer = 10000; +- break; ++// case CLASS_DEATH_KNIGHT: ++// DoCastSpellIfCan(m_creature->getVictim(), SPELL_PLAGUE_STRIKE); ++// m_uiSpellTimer = 10000; ++// break; + } + } + else +diff --git a/scripts/world/item_scripts.cpp b/scripts/world/item_scripts.cpp +index 4474aa7..8a70bbc 100644 +--- a/scripts/world/item_scripts.cpp ++++ b/scripts/world/item_scripts.cpp +@@ -47,7 +47,7 @@ bool ItemUse_item_arcane_charges(Player* pPlayer, Item* pItem, const SpellCastTa + pPlayer->SendEquipError(EQUIP_ERR_NONE, pItem, NULL); + + if (const SpellEntry* pSpellInfo = GetSpellStore()->LookupEntry(SPELL_ARCANE_CHARGES)) +- Spell::SendCastResult(pPlayer, pSpellInfo, 1, SPELL_FAILED_NOT_ON_GROUND); ++ Spell::SendCastResult(pPlayer, pSpellInfo, 1, SPELL_FAILED_ERROR); + + return true; + } +diff --git a/system/ScriptLoader.cpp b/system/ScriptLoader.cpp +index f30904e..6e7650a 100644 +--- a/system/ScriptLoader.cpp ++++ b/system/ScriptLoader.cpp +@@ -102,7 +102,22 @@ extern void AddSC_boss_majordomo(); + extern void AddSC_boss_ragnaros(); + extern void AddSC_instance_molten_core(); + extern void AddSC_molten_core(); +-extern void AddSC_ebon_hold(); // scarlet_enclave ++extern void AddSC_boss_anubrekhan(); // naxxramas ++extern void AddSC_boss_four_horsemen(); ++extern void AddSC_boss_faerlina(); ++extern void AddSC_boss_gluth(); ++extern void AddSC_boss_gothik(); ++extern void AddSC_boss_grobbulus(); ++extern void AddSC_boss_kelthuzad(); ++extern void AddSC_boss_loatheb(); ++extern void AddSC_boss_maexxna(); ++extern void AddSC_boss_noth(); ++extern void AddSC_boss_heigan(); ++extern void AddSC_boss_patchwerk(); ++extern void AddSC_boss_razuvious(); ++extern void AddSC_boss_sapphiron(); ++extern void AddSC_boss_thaddius(); ++extern void AddSC_instance_naxxramas(); + extern void AddSC_boss_arcanist_doan(); // scarlet_monastery + extern void AddSC_boss_azshir_the_sleepless(); + extern void AddSC_boss_bloodmage_thalnos(); +@@ -214,8 +229,6 @@ extern void AddSC_boss_epoch_hunter(); + extern void AddSC_boss_lieutenant_drake(); + extern void AddSC_instance_old_hillsbrad(); + extern void AddSC_old_hillsbrad(); +-extern void AddSC_culling_of_stratholme(); // COT, culling_of_stratholme +-extern void AddSC_instance_culling_of_stratholme(); + extern void AddSC_dire_maul(); // dire_maul + extern void AddSC_instance_dire_maul(); + extern void AddSC_boss_celebras_the_cursed(); // maraudon +@@ -271,144 +284,7 @@ extern void AddSC_ungoro_crater(); + extern void AddSC_winterspring(); + + // northrend +-extern void AddSC_boss_jedoga(); // azjol-nerub, ahnkahet +-extern void AddSC_boss_nadox(); +-extern void AddSC_boss_taldaram(); +-extern void AddSC_boss_volazj(); +-extern void AddSC_instance_ahnkahet(); +-extern void AddSC_boss_anubarak(); // azjol-nerub, azjol-nerub +-extern void AddSC_boss_hadronox(); +-extern void AddSC_boss_krikthir(); +-extern void AddSC_instance_azjol_nerub(); +-extern void AddSC_trial_of_the_champion(); // CC, trial_of_the_champion +-extern void AddSC_boss_grand_champions(); +-extern void AddSC_instance_trial_of_the_champion(); +-extern void AddSC_boss_anubarak_trial(); // CC, trial_of_the_crusader +-extern void AddSC_boss_faction_champions(); +-extern void AddSC_boss_jaraxxus(); +-extern void AddSC_instance_trial_of_the_crusader(); +-extern void AddSC_northrend_beasts(); +-extern void AddSC_trial_of_the_crusader(); +-extern void AddSC_twin_valkyr(); +-extern void AddSC_boss_novos(); // draktharon_keep +-extern void AddSC_boss_tharonja(); +-extern void AddSC_boss_trollgore(); +-extern void AddSC_instance_draktharon_keep(); +-extern void AddSC_boss_colossus(); // gundrak +-extern void AddSC_boss_eck(); +-extern void AddSC_boss_galdarah(); +-extern void AddSC_boss_moorabi(); +-extern void AddSC_boss_sladran(); +-extern void AddSC_instance_gundrak(); +-extern void AddSC_boss_bronjahm(); // ICC, forge_of_souls +-extern void AddSC_boss_devourer_of_souls(); +-extern void AddSC_instance_forge_of_souls(); +-extern void AddSC_boss_falric(); // ICC, halls_of_reflection +-extern void AddSC_boss_lich_king(); +-extern void AddSC_boss_marwyn(); +-extern void AddSC_halls_of_reflection(); +-extern void AddSC_instance_halls_of_reflection(); +-extern void AddSC_boss_garfrost(); // ICC, pit_of_saron +-extern void AddSC_boss_krick_and_ick(); +-extern void AddSC_boss_tyrannus(); +-extern void AddSC_instance_pit_of_saron(); +-extern void AddSC_pit_of_saron(); +-extern void AddSC_blood_prince_council(); // ICC, icecrown_citadel +-extern void AddSC_boss_blood_queen_lanathel(); +-extern void AddSC_boss_deathbringer_saurfang(); +-extern void AddSC_boss_festergut(); +-extern void AddSC_boss_lady_deathwhisper(); +-extern void AddSC_boss_lord_marrowgar(); +-extern void AddSC_boss_professor_putricide(); +-extern void AddSC_boss_rotface(); +-extern void AddSC_boss_sindragosa(); +-extern void AddSC_boss_the_lich_king(); +-extern void AddSC_boss_valithria_dreamwalker(); +-extern void AddSC_gunship_battle(); +-extern void AddSC_instance_icecrown_citadel(); +-extern void AddSC_boss_anubrekhan(); // naxxramas +-extern void AddSC_boss_four_horsemen(); +-extern void AddSC_boss_faerlina(); +-extern void AddSC_boss_gluth(); +-extern void AddSC_boss_gothik(); +-extern void AddSC_boss_grobbulus(); +-extern void AddSC_boss_kelthuzad(); +-extern void AddSC_boss_loatheb(); +-extern void AddSC_boss_maexxna(); +-extern void AddSC_boss_noth(); +-extern void AddSC_boss_heigan(); +-extern void AddSC_boss_patchwerk(); +-extern void AddSC_boss_razuvious(); +-extern void AddSC_boss_sapphiron(); +-extern void AddSC_boss_thaddius(); +-extern void AddSC_instance_naxxramas(); +-extern void AddSC_boss_malygos(); // nexus, eye_of_eternity +-extern void AddSC_boss_anomalus(); // nexus, nexus +-extern void AddSC_boss_keristrasza(); +-extern void AddSC_boss_ormorok(); +-extern void AddSC_boss_telestra(); +-extern void AddSC_instance_nexus(); +-extern void AddSC_boss_sartharion(); // obsidian_sanctum +-extern void AddSC_instance_obsidian_sanctum(); +-extern void AddSC_boss_baltharus(); // ruby_sanctum +-extern void AddSC_boss_halion(); +-extern void AddSC_boss_saviana(); +-extern void AddSC_boss_zarithrian(); +-extern void AddSC_instance_ruby_sanctum(); +-extern void AddSC_boss_bjarngrim(); // ulduar, halls_of_lightning +-extern void AddSC_boss_ionar(); +-extern void AddSC_boss_loken(); +-extern void AddSC_boss_volkhan(); +-extern void AddSC_instance_halls_of_lightning(); +-extern void AddSC_boss_maiden_of_grief(); // ulduar, halls_of_stone +-extern void AddSC_boss_sjonnir(); +-extern void AddSC_halls_of_stone(); +-extern void AddSC_instance_halls_of_stone(); +-extern void AddSC_boss_assembly_of_iron(); // ulduar, ulduar +-extern void AddSC_boss_algalon(); +-extern void AddSC_boss_auriaya(); +-extern void AddSC_boss_flame_leviathan(); +-extern void AddSC_boss_freya(); +-extern void AddSC_boss_general_vezax(); +-extern void AddSC_boss_hodir(); +-extern void AddSC_boss_ignis(); +-extern void AddSC_boss_kologarn(); +-extern void AddSC_boss_mimiron(); +-extern void AddSC_boss_razorscale(); +-extern void AddSC_boss_thorim(); +-extern void AddSC_boss_xt_002(); +-extern void AddSC_boss_yogg_saron(); +-extern void AddSC_instance_ulduar(); +-extern void AddSC_ulduar(); +-extern void AddSC_boss_ingvar(); // utgarde_keep, utgarde_keep +-extern void AddSC_boss_keleseth(); +-extern void AddSC_boss_skarvald_and_dalronn(); +-extern void AddSC_instance_utgarde_keep(); +-extern void AddSC_utgarde_keep(); +-extern void AddSC_boss_gortok(); // utgarde_keep, utgarde_pinnacle +-extern void AddSC_boss_skadi(); +-extern void AddSC_boss_svala(); +-extern void AddSC_boss_ymiron(); +-extern void AddSC_instance_pinnacle(); +-extern void AddSC_boss_archavon(); // vault_of_archavon +-extern void AddSC_boss_emalon(); +-extern void AddSC_boss_koralon(); +-extern void AddSC_boss_toravon(); +-extern void AddSC_instance_vault_of_archavon(); +-extern void AddSC_boss_erekem(); // violet_hold +-extern void AddSC_boss_ichoron(); +-extern void AddSC_instance_violet_hold(); +-extern void AddSC_violet_hold(); +- +-extern void AddSC_borean_tundra(); +-extern void AddSC_dalaran(); +-extern void AddSC_dragonblight(); +-extern void AddSC_grizzly_hills(); +-extern void AddSC_howling_fjord(); +-extern void AddSC_icecrown(); +-extern void AddSC_sholazar_basin(); +-extern void AddSC_storm_peaks(); +-extern void AddSC_zuldrak(); ++// removed + + // outland + extern void AddSC_boss_exarch_maladaar(); // auchindoun, auchenai_crypts +@@ -592,7 +468,22 @@ void AddScripts() + AddSC_boss_ragnaros(); + AddSC_instance_molten_core(); + AddSC_molten_core(); +- AddSC_ebon_hold(); // scarlet_enclave ++ AddSC_boss_anubrekhan(); // naxxramas ++ AddSC_boss_four_horsemen(); ++ AddSC_boss_faerlina(); ++ AddSC_boss_gluth(); ++ AddSC_boss_gothik(); ++ AddSC_boss_grobbulus(); ++ AddSC_boss_kelthuzad(); ++ AddSC_boss_loatheb(); ++ AddSC_boss_maexxna(); ++ AddSC_boss_noth(); ++ AddSC_boss_heigan(); ++ AddSC_boss_patchwerk(); ++ AddSC_boss_razuvious(); ++ AddSC_boss_sapphiron(); ++ AddSC_boss_thaddius(); ++ AddSC_instance_naxxramas(); + AddSC_boss_arcanist_doan(); // scarlet_monastery + AddSC_boss_azshir_the_sleepless(); + AddSC_boss_bloodmage_thalnos(); +@@ -704,8 +595,6 @@ void AddScripts() + AddSC_boss_lieutenant_drake(); + AddSC_instance_old_hillsbrad(); + AddSC_old_hillsbrad(); +- AddSC_culling_of_stratholme(); // CoT, culling_of_stratholme +- AddSC_instance_culling_of_stratholme(); + AddSC_dire_maul(); // dire_maul + AddSC_instance_dire_maul(); + AddSC_boss_celebras_the_cursed(); // maraudon +@@ -761,144 +650,7 @@ void AddScripts() + AddSC_winterspring(); + + // northrend +- AddSC_boss_jedoga(); // azjol-nerub, ahnkahet +- AddSC_boss_nadox(); +- AddSC_boss_taldaram(); +- AddSC_boss_volazj(); +- AddSC_instance_ahnkahet(); +- AddSC_boss_anubarak(); // azjol-nerub, azjol-nerub +- AddSC_boss_hadronox(); +- AddSC_boss_krikthir(); +- AddSC_instance_azjol_nerub(); +- AddSC_boss_grand_champions(); // CC, trial_of_the_champion +- AddSC_instance_trial_of_the_champion(); +- AddSC_trial_of_the_champion(); +- AddSC_boss_anubarak_trial(); // CC, trial_of_the_crusader +- AddSC_boss_faction_champions(); +- AddSC_boss_jaraxxus(); +- AddSC_instance_trial_of_the_crusader(); +- AddSC_northrend_beasts(); +- AddSC_trial_of_the_crusader(); +- AddSC_twin_valkyr(); +- AddSC_boss_novos(); // draktharon_keep +- AddSC_boss_tharonja(); +- AddSC_boss_trollgore(); +- AddSC_instance_draktharon_keep(); +- AddSC_boss_colossus(); // gundrak +- AddSC_boss_eck(); +- AddSC_boss_galdarah(); +- AddSC_boss_moorabi(); +- AddSC_boss_sladran(); +- AddSC_instance_gundrak(); +- AddSC_boss_bronjahm(); // ICC, FH, forge_of_souls +- AddSC_boss_devourer_of_souls(); +- AddSC_instance_forge_of_souls(); +- AddSC_boss_falric(); // ICC, FH, halls_of_reflection +- AddSC_boss_lich_king(); +- AddSC_boss_marwyn(); +- AddSC_halls_of_reflection(); +- AddSC_instance_halls_of_reflection(); +- AddSC_boss_garfrost(); // ICC, FH, pit_of_saron +- AddSC_boss_krick_and_ick(); +- AddSC_boss_tyrannus(); +- AddSC_instance_pit_of_saron(); +- AddSC_pit_of_saron(); +- AddSC_blood_prince_council(); // ICC, icecrown_citadel +- AddSC_boss_blood_queen_lanathel(); +- AddSC_boss_deathbringer_saurfang(); +- AddSC_boss_festergut(); +- AddSC_boss_lady_deathwhisper(); +- AddSC_boss_lord_marrowgar(); +- AddSC_boss_professor_putricide(); +- AddSC_boss_rotface(); +- AddSC_boss_sindragosa(); +- AddSC_boss_the_lich_king(); +- AddSC_boss_valithria_dreamwalker(); +- AddSC_gunship_battle(); +- AddSC_instance_icecrown_citadel(); +- AddSC_boss_anubrekhan(); // naxxramas +- AddSC_boss_four_horsemen(); +- AddSC_boss_faerlina(); +- AddSC_boss_gluth(); +- AddSC_boss_gothik(); +- AddSC_boss_grobbulus(); +- AddSC_boss_kelthuzad(); +- AddSC_boss_loatheb(); +- AddSC_boss_maexxna(); +- AddSC_boss_noth(); +- AddSC_boss_heigan(); +- AddSC_boss_patchwerk(); +- AddSC_boss_razuvious(); +- AddSC_boss_sapphiron(); +- AddSC_boss_thaddius(); +- AddSC_instance_naxxramas(); +- AddSC_boss_malygos(); // nexus, eye_of_eternity +- AddSC_boss_anomalus(); // nexus, nexus +- AddSC_boss_keristrasza(); +- AddSC_boss_ormorok(); +- AddSC_boss_telestra(); +- AddSC_instance_nexus(); +- AddSC_boss_sartharion(); // obsidian_sanctum +- AddSC_instance_obsidian_sanctum(); +- AddSC_boss_baltharus(); // ruby_sanctum +- AddSC_boss_halion(); +- AddSC_boss_saviana(); +- AddSC_boss_zarithrian(); +- AddSC_instance_ruby_sanctum(); +- AddSC_boss_bjarngrim(); // ulduar, halls_of_lightning +- AddSC_boss_ionar(); +- AddSC_boss_loken(); +- AddSC_boss_volkhan(); +- AddSC_instance_halls_of_lightning(); +- AddSC_boss_maiden_of_grief(); // ulduar, halls_of_stone +- AddSC_boss_sjonnir(); +- AddSC_halls_of_stone(); +- AddSC_instance_halls_of_stone(); +- AddSC_boss_assembly_of_iron(); // ulduar, ulduar +- AddSC_boss_algalon(); +- AddSC_boss_auriaya(); +- AddSC_boss_flame_leviathan(); +- AddSC_boss_freya(); +- AddSC_boss_general_vezax(); +- AddSC_boss_hodir(); +- AddSC_boss_ignis(); +- AddSC_boss_kologarn(); +- AddSC_boss_mimiron(); +- AddSC_boss_razorscale(); +- AddSC_boss_thorim(); +- AddSC_boss_xt_002(); +- AddSC_boss_yogg_saron(); +- AddSC_instance_ulduar(); +- AddSC_ulduar(); +- AddSC_boss_ingvar(); // UK, utgarde_keep +- AddSC_boss_keleseth(); +- AddSC_boss_skarvald_and_dalronn(); +- AddSC_instance_utgarde_keep(); +- AddSC_utgarde_keep(); +- AddSC_boss_gortok(); // UK, utgarde_pinnacle +- AddSC_boss_skadi(); +- AddSC_boss_svala(); +- AddSC_boss_ymiron(); +- AddSC_instance_pinnacle(); +- AddSC_boss_archavon(); // vault_of_archavon +- AddSC_boss_emalon(); +- AddSC_boss_koralon(); +- AddSC_boss_toravon(); +- AddSC_instance_vault_of_archavon(); +- AddSC_boss_erekem(); // violet_hold +- AddSC_boss_ichoron(); +- AddSC_instance_violet_hold(); +- AddSC_violet_hold(); +- +- AddSC_borean_tundra(); +- AddSC_dalaran(); +- AddSC_dragonblight(); +- AddSC_grizzly_hills(); +- AddSC_howling_fjord(); +- AddSC_icecrown(); +- AddSC_sholazar_basin(); +- AddSC_storm_peaks(); +- AddSC_zuldrak(); ++ // removed + + // outland + AddSC_boss_exarch_maladaar(); // auchindoun, auchenai_crypts +-- +1.7.3.1.msysgit.0 + diff --git a/scriptVC100.sln b/scriptVC100.sln deleted file mode 100644 index a08bb2de3..000000000 --- a/scriptVC100.sln +++ /dev/null @@ -1,25 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScriptDev2", "VC100\100ScriptDev2.vcxproj", "{4295C8A9-79B7-4354-8064-F05FB9CA0C96}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|Win32.ActiveCfg = Debug|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|Win32.Build.0 = Debug|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|x64.ActiveCfg = Debug|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|x64.Build.0 = Debug|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|Win32.ActiveCfg = Release|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|Win32.Build.0 = Release|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|x64.ActiveCfg = Release|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/scriptVC80.sln b/scriptVC80.sln deleted file mode 100644 index 420b4d657..000000000 --- a/scriptVC80.sln +++ /dev/null @@ -1,25 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScriptDev2", "VC80\80ScriptDev2.vcproj", "{4295C8A9-79B7-4354-8064-F05FB9CA0C96}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|Win32.ActiveCfg = Debug|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|Win32.Build.0 = Debug|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|x64.ActiveCfg = Debug|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|x64.Build.0 = Debug|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|Win32.ActiveCfg = Release|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|Win32.Build.0 = Release|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|x64.ActiveCfg = Release|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/scriptVC90.sln b/scriptVC90.sln deleted file mode 100644 index 9507f49df..000000000 --- a/scriptVC90.sln +++ /dev/null @@ -1,25 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScriptDev2", "VC90\90ScriptDev2.vcproj", "{4295C8A9-79B7-4354-8064-F05FB9CA0C96}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|Win32.ActiveCfg = Debug|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|Win32.Build.0 = Debug|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|x64.ActiveCfg = Debug|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Debug|x64.Build.0 = Debug|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|Win32.ActiveCfg = Release|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|Win32.Build.0 = Release|Win32 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|x64.ActiveCfg = Release|x64 - {4295C8A9-79B7-4354-8064-F05FB9CA0C96}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/scripts/battlegrounds/battleground.cpp b/scripts/battlegrounds/battleground.cpp index 0e8daef14..5a87e3d60 100644 --- a/scripts/battlegrounds/battleground.cpp +++ b/scripts/battlegrounds/battleground.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -57,7 +57,10 @@ struct MANGOS_DLL_DECL npc_spirit_guideAI : public ScriptedAI { // auto cast the whole time this spell if (!m_creature->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) + { + m_creature->CastSpell(m_creature, SPELL_SPIRIT_HEAL, true); m_creature->CastSpell(m_creature, SPELL_SPIRIT_HEAL_CHANNEL, false); + } } void CorpseRemoved(uint32 &) diff --git a/scripts/custom/npc_arena_honor.cpp b/scripts/custom/npc_arena_honor.cpp new file mode 100644 index 000000000..2c2a1efb3 --- /dev/null +++ b/scripts/custom/npc_arena_honor.cpp @@ -0,0 +1,99 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: npc_arena_honor +SD%Complete: 100% +SDComment: by tempura, corrected by /dev/rsa +SDCategory: custom +EndScriptData */ +#include "precompiled.h" +#include "sc_creature.h" +#include "sc_gossip.h" + +#define GOSSIP_ITEM_ARENA_TO_HONOR -3000770 +#define GOSSIP_ITEM_ARENA_TO_HONOR1 -3000771 +#define GOSSIP_ITEM_HONOR_TO_ARENA -3000772 +#define GOSSIP_ITEM_HONOR_TO_ARENA1 -3000773 + +#define UNSUCCESSFUL_HONOR -1001007 +#define UNSUCCESSFUL_ARENA -1001008 + +bool GossipHello_npc_arena_honor(Player* pPlayer, Creature *pCreature) +{ + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_HONOR_TO_ARENA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_HONOR_TO_ARENA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARENA_TO_HONOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARENA_TO_HONOR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + pPlayer->SEND_GOSSIP_MENU(3961,pCreature->GetGUID()); + return true; +} + +bool GossipSelect_npc_arena_honor(Player *pPlayer, Creature *pCreature, uint32 sender, uint32 action) +{ + if (action == GOSSIP_ACTION_INFO_DEF + 1) + { + if (pPlayer->GetHonorPoints() >= 1000) + { + pPlayer->ModifyHonorPoints(-1000); + pPlayer->ModifyArenaPoints(+50); + } + else + DoScriptText(UNSUCCESSFUL_HONOR, pCreature); + } + if (action == GOSSIP_ACTION_INFO_DEF + 2) + { + if (pPlayer->GetHonorPoints() >= 10000) + { + pPlayer->ModifyHonorPoints(-10000); + pPlayer->ModifyArenaPoints(+500); + } + else + DoScriptText(UNSUCCESSFUL_HONOR, pCreature); + } + if (action == GOSSIP_ACTION_INFO_DEF + 3) + { + if (pPlayer->GetArenaPoints() >= 100) + { + pPlayer->ModifyArenaPoints(-100); + pPlayer->ModifyHonorPoints(+2000); + } + else + DoScriptText(UNSUCCESSFUL_ARENA, pCreature); + } + if (action == GOSSIP_ACTION_INFO_DEF + 4) + { + if (pPlayer->GetArenaPoints() >= 1000) + { + pPlayer->ModifyArenaPoints(-1000); + pPlayer->ModifyHonorPoints(+20000); + } + else + DoScriptText(UNSUCCESSFUL_ARENA, pCreature); + } + pPlayer->CLOSE_GOSSIP_MENU(); + return true; +} + +void AddSC_npc_arena_honor() +{ + Script *newscript; + newscript = new Script; + newscript->Name="npc_arena_honor"; + newscript->pGossipHello = &GossipHello_npc_arena_honor; + newscript->pGossipSelect = &GossipSelect_npc_arena_honor; + newscript->RegisterSelf(); +} diff --git a/scripts/custom/teleguy.cpp b/scripts/custom/teleguy.cpp new file mode 100644 index 000000000..38ae24b63 --- /dev/null +++ b/scripts/custom/teleguy.cpp @@ -0,0 +1,871 @@ +#include "precompiled.h" +long long int money; +int costo; + +bool GossipHello_mob_teleguy(Player *player, Creature *_Creature) +{ + if ( player->GetTeam() == ALLIANCE ) { + player->ADD_GOSSIP_ITEM( 5, "Darnassus. 5 Silver" , GOSSIP_SENDER_MAIN, 1203); + player->ADD_GOSSIP_ITEM( 5, "Exodar. 5 Silver" , GOSSIP_SENDER_MAIN, 1216); + player->ADD_GOSSIP_ITEM( 5, "Stormwind. 5 Silver" , GOSSIP_SENDER_MAIN, 1206); + player->ADD_GOSSIP_ITEM( 5, "Ironforge. 5 Silver" , GOSSIP_SENDER_MAIN, 1224); + player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222); + player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287); + player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205); + player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288); + player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550); + player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554); + } else { + player->ADD_GOSSIP_ITEM( 5, "Orgrimmar. 5 Silver" , GOSSIP_SENDER_MAIN, 1215); + player->ADD_GOSSIP_ITEM( 5, "Silvermoon. 5 Silver" , GOSSIP_SENDER_MAIN, 1217); + player->ADD_GOSSIP_ITEM( 5, "Undercity. 5 Silver" , GOSSIP_SENDER_MAIN, 1213); + player->ADD_GOSSIP_ITEM( 5, "Thunder Bluff. 5 Silver" , GOSSIP_SENDER_MAIN, 1225); + player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222); + player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287); + player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205); + player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288); + player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550); + player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554); + } + player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID()); + return true; +} + + +void SendDefaultMenu_mob_teleguy(Player *player, Creature *_Creature, uint32 action ) +{ + if(!player->getAttackers().empty()) + { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You are in combat!", LANG_UNIVERSAL); + return; + } + + if( player->getLevel() < 8 ) + { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be lvl 8+", LANG_UNIVERSAL); + return; + } + + money = player-> GetMoney(); + costo = 500; + + if (money < costo ) + { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You haven't enough money", LANG_UNIVERSAL); + return; + } + + switch(action) + { + case 5550: //Instances + player->ADD_GOSSIP_ITEM( 5, "Ragefire Chasm. 10 Silver" , GOSSIP_SENDER_MAIN, 1248); + player->ADD_GOSSIP_ITEM( 5, "The Wailing Caverns. 10 Silver" , GOSSIP_SENDER_MAIN, 1249); + player->ADD_GOSSIP_ITEM( 5, "The Stockade. 10 Silver" , GOSSIP_SENDER_MAIN, 1253); + player->ADD_GOSSIP_ITEM( 5, "Deadmines. 10 Silver" , GOSSIP_SENDER_MAIN, 1250); + player->ADD_GOSSIP_ITEM( 5, "Shadowfang Keep. 10 Silver" , GOSSIP_SENDER_MAIN, 1251); + player->ADD_GOSSIP_ITEM( 5, "Blackfathom Deeps. 10 Silver" , GOSSIP_SENDER_MAIN, 1252); + player->ADD_GOSSIP_ITEM( 5, "Razorfen Kraul. 20 Silver" , GOSSIP_SENDER_MAIN, 1254); + player->ADD_GOSSIP_ITEM( 5, "Razorfen Downs. 20 Silver" , GOSSIP_SENDER_MAIN, 1256); + player->ADD_GOSSIP_ITEM( 5, "Scarlet Monastery. 20 Silver" , GOSSIP_SENDER_MAIN, 1257); + player->ADD_GOSSIP_ITEM( 7, "[More] ->" , GOSSIP_SENDER_MAIN, 5551); + player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552); + player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID()); + break; + case 5551: //More Instances + player->ADD_GOSSIP_ITEM( 5, "Uldaman. 30 Silver" , GOSSIP_SENDER_MAIN, 1258); + player->ADD_GOSSIP_ITEM( 5, "Zul'Farrak. 30 Silver" , GOSSIP_SENDER_MAIN, 1259); + player->ADD_GOSSIP_ITEM( 5, "Maraudon. 40 Silver" , GOSSIP_SENDER_MAIN, 1260); + player->ADD_GOSSIP_ITEM( 5, "Maraudon. 40 Silver" , GOSSIP_SENDER_MAIN, 1260); + player->ADD_GOSSIP_ITEM( 5, "The Sunken Temple. 40 Silver" , GOSSIP_SENDER_MAIN, 1261); + player->ADD_GOSSIP_ITEM( 5, "Blackrock Depths. 40 Silver" , GOSSIP_SENDER_MAIN, 1262); + player->ADD_GOSSIP_ITEM( 5, "Dire Maul. 50 Silver" , GOSSIP_SENDER_MAIN, 1263); + player->ADD_GOSSIP_ITEM( 5, "Blackrock Spire. 50 Silver" , GOSSIP_SENDER_MAIN, 1264); + player->ADD_GOSSIP_ITEM( 5, "Stratholme. 50 Silver" , GOSSIP_SENDER_MAIN, 1265); + player->ADD_GOSSIP_ITEM( 5, "Scholomance. 50 Silver" , GOSSIP_SENDER_MAIN, 1266); + player->ADD_GOSSIP_ITEM( 7, "[More] ->" , GOSSIP_SENDER_MAIN, 5553); + player->ADD_GOSSIP_ITEM( 7, "<- [Back]" , GOSSIP_SENDER_MAIN, 5550); + player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552); + player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID()); + break; + +case 5553: //Instances 60-70 +player->ADD_GOSSIP_ITEM( 5, "Karazhan. 1 Gold" , GOSSIP_SENDER_MAIN, 4007); +player->ADD_GOSSIP_ITEM( 5, "Gruul's Lair. 1 Gold" , GOSSIP_SENDER_MAIN, 4008); +player->ADD_GOSSIP_ITEM( 5, "Hellfire Citadel. 1 Gold" , GOSSIP_SENDER_MAIN, 4009); +player->ADD_GOSSIP_ITEM( 5, "Coilfang Reservoir. 1 Gold" , GOSSIP_SENDER_MAIN, 4010); +player->ADD_GOSSIP_ITEM( 5, "Tempest Keep. 1 Gold" , GOSSIP_SENDER_MAIN, 4011); +player->ADD_GOSSIP_ITEM( 5, "Caverns of Time. 1 Gold" , GOSSIP_SENDER_MAIN, 4012); +player->ADD_GOSSIP_ITEM( 5, "Zul'Aman. 1 Gold" , GOSSIP_SENDER_MAIN, 4016); +player->ADD_GOSSIP_ITEM( 5, "Black Temple. 1 Gold" , GOSSIP_SENDER_MAIN, 4013); +player->ADD_GOSSIP_ITEM( 5, "Magister's Terrace. 2 Gold" , GOSSIP_SENDER_MAIN, 4017); +player->ADD_GOSSIP_ITEM( 5, "Sunwell Plateau. 2 Gold" , GOSSIP_SENDER_MAIN, 4018); +player->ADD_GOSSIP_ITEM( 7, "<- [Back]" , GOSSIP_SENDER_MAIN, 5550); +player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552); + + +player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID()); + +break; + +case 5554: //Instances 75-80 NORTHREND +player->ADD_GOSSIP_ITEM( 5, "Utgarde Keep. 20 Gold" , GOSSIP_SENDER_MAIN, 4019); +player->ADD_GOSSIP_ITEM( 5, "The Nexus. 20 Gold" , GOSSIP_SENDER_MAIN, 4020); +player->ADD_GOSSIP_ITEM( 5, "Azjol-Nerub. 20 Gold" , GOSSIP_SENDER_MAIN, 4021); +player->ADD_GOSSIP_ITEM( 5, "Ahn'kahet: The Old Kingdom. 20 Gold" , GOSSIP_SENDER_MAIN, 4022); +player->ADD_GOSSIP_ITEM( 5, "Drak'Tharon Keep. 20 Gold" , GOSSIP_SENDER_MAIN, 4023); +player->ADD_GOSSIP_ITEM( 5, "The Violet Hold. 20 Gold" , GOSSIP_SENDER_MAIN, 4024); +player->ADD_GOSSIP_ITEM( 5, "Gun' Drak. 20 Gold" , GOSSIP_SENDER_MAIN, 4025); +player->ADD_GOSSIP_ITEM( 5, "Utgarde Pinnacle. 20 Gold" , GOSSIP_SENDER_MAIN, 4026); +player->ADD_GOSSIP_ITEM( 5, "Ulduar. 20 Gold" , GOSSIP_SENDER_MAIN, 4027); +player->ADD_GOSSIP_ITEM( 5, "The Obsidian Sanctum. 20 Gold" , GOSSIP_SENDER_MAIN, 4028); +player->ADD_GOSSIP_ITEM( 5, "Naxxramas. 20 Gold" , GOSSIP_SENDER_MAIN, 4029); +player->ADD_GOSSIP_ITEM( 7, "<- [Back]" , GOSSIP_SENDER_MAIN, 5550); +player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552); + + +player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID()); + +break; + +case 5552: //Back To Main Menu + if ( player->GetTeam() == ALLIANCE ) { +player->ADD_GOSSIP_ITEM( 5, "Darnassus. 5 Silver" , GOSSIP_SENDER_MAIN, 1203); +player->ADD_GOSSIP_ITEM( 5, "Exodar. 5 Silver" , GOSSIP_SENDER_MAIN, 1216); +player->ADD_GOSSIP_ITEM( 5, "Stormwind. 5 Silver" , GOSSIP_SENDER_MAIN, 1206); +player->ADD_GOSSIP_ITEM( 5, "Ironforge. 5 Silver" , GOSSIP_SENDER_MAIN, 1224); +player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222); +player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287); +player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205); +player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288); +player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550); +player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554); + + } else { + + +player->ADD_GOSSIP_ITEM( 5, "Orgrimmar. 5 Silver" , GOSSIP_SENDER_MAIN, 1215); +player->ADD_GOSSIP_ITEM( 5, "Silvermoon. 5 Silver" , GOSSIP_SENDER_MAIN, 1217); +player->ADD_GOSSIP_ITEM( 5, "Undercity. 5 Silver" , GOSSIP_SENDER_MAIN, 1213); +player->ADD_GOSSIP_ITEM( 5, "Thunder Bluff. 5 Silver" , GOSSIP_SENDER_MAIN, 1225); +player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222); +player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287); +player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205); +player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288); +player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550); +player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554); + } + +player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID()); + +break; + +case 1203: // Teleport to Darnassus +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(1, 9947.52f, 2482.73f, 1316.21f, 0.0f); +player->ModifyMoney(-1*costo); +break; + +// Teleport to Stormwind +case 1206: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(0, -8960.14f, 516.266f, 96.3568f, 0.0f); +player->ModifyMoney(-1*costo); +break; + +// Teleport to Dalaran +case 1205: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(571, 5804.14f, 624.770f, 647.7670f, 1.64f); +player->ModifyMoney(-1*costo); +break; + +// Teleport to Undercity +case 1213: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(0, 1819.71f, 238.79f, 60.5321f, 0.0f); +player->ModifyMoney(-1*costo); + +break; + +// Teleport to Orgrimmar +case 1215: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(1, 1552.5f, -4420.66f, 8.94802f, 0.0f); +player->ModifyMoney(-1*costo); +break; + +// Teleport to Exodar +case 1216: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(530, -4073.03f, -12020.4f, -1.47f, 0.0f); +player->ModifyMoney(-1*costo); +break; + +// Teleport to Silvermoon +case 1217: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(530, 9338.74f, -7277.27f, 13.7895f, 0.0f); +player->ModifyMoney(-1*costo); + +break; + +case 1222://teleport player to Gnomeregan +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(0, -5163.43f,660.40f,348.28f,4.65f); +player->ModifyMoney(-1*costo); + +break; + +// Teleport to Ironforge +case 1224: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(0, -4924.07f, -951.95f, 501.55f, 5.40f); +player->ModifyMoney(-1*costo); + +break; + +// Teleport to Thunder Bluff +case 1225: +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(1, -1280.19f,127.21f,131.35f,5.16f); +player->ModifyMoney(-1*costo); + +break; + +case 1248://teleport player to Ragefire Chasm + +if( player->getLevel() >= 8) + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, 1800.53f,-4394.68f,-17.93f,5.49f); + player->ModifyMoney(-2*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 8!", LANG_UNIVERSAL); + } + +break; + +case 1249://teleport player to the Wailing Caverns + +if (player->getLevel() >= 10) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, -722.53f,-2226.30f,16.94f,2.71f); + player->ModifyMoney(-2*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 10!", LANG_UNIVERSAL); + } + +break; + +case 1250://teleport player to the Deadmines + +if (player->getLevel() >= 10) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -11212.04f,1658.58f,25.67f,1.45f); + player->ModifyMoney(-2*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 10!", LANG_UNIVERSAL); + } + +break; + +case 1251://teleport player to Shadowfang Keep + + if (player->getLevel() >= 15) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -254.47f,1524.68f,76.89f,1.56f); + player->ModifyMoney(-2*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 15!", LANG_UNIVERSAL); + } + +break; + +case 1252://teleport player to Blackfathom Deeps + + if (player->getLevel() >= 15) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, 4254.58f,664.74f,-29.04f,1.97f); + player->ModifyMoney(-2*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 15!", LANG_UNIVERSAL); + } + +break; + +case 1253://teleport player to the Stockade + + if (player->getLevel() >= 20) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -8769.76f,813.08f,97.63f,2.26f); + player->ModifyMoney(-2*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 20!", LANG_UNIVERSAL); + } + +break; + +case 1254://teleport player to Razorfen Kraul + + if (player->getLevel() >= 24) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, -4484.04f,-1739.40f,86.47f,1.23f); + player->ModifyMoney(-4*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 24!", LANG_UNIVERSAL); + } + +break; + +case 1255://teleport player to Gnomeregan + + if (player->getLevel() >= 20) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -5162.62f,667.81f,248.05f,1.48f); + player->ModifyMoney(-4*costo); + + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 20!", LANG_UNIVERSAL); + } + +break; + +case 1256://teleport player to Razorfen Downs + + if (player->getLevel() >= 25) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, -4645.08f,-2470.85f,85.53f,4.39f); + player->ModifyMoney(-4*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 25!", LANG_UNIVERSAL); + } + +break; + +case 1257://teleport player to the Scarlet Monastery + + if (player->getLevel() >= 25) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, 2843.89f,-693.74f,139.32f,5.11f); + player->ModifyMoney(-4*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 25!", LANG_UNIVERSAL); + } + +break; + +case 1258://teleport player to Uldaman + + if (player->getLevel() >= 35) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -6119.70f,-2957.30f,204.11f,0.03f); + player->ModifyMoney(-6*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 35!", LANG_UNIVERSAL); + } + +break; + +case 1259://teleport player to Zul'Farrak + + if (player->getLevel() >= 35) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, -6839.39f,-2911.03f,8.87f,0.41f); + player->ModifyMoney(-6*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 35!", LANG_UNIVERSAL); + } + +break; + + +case 1260://teleport player to Maraudon + + if (player->getLevel() >= 40) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, -1433.33f,2955.34f,96.21f,4.82f); + player->ModifyMoney(-8*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 40!", LANG_UNIVERSAL); + } + +break; + +case 1261://teleport player to the Sunken Temple + + if (player->getLevel() >= 45) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -10346.92f,-3851.90f,-43.41f,6.09f); + player->ModifyMoney(-8*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 45!", LANG_UNIVERSAL); + } + +break; + +case 1262://teleport player to Blackrock Depths + + if (player->getLevel() >= 45) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -7301.03f,-913.19f,165.37f,0.08f); + player->ModifyMoney(-8*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 45!", LANG_UNIVERSAL); + } + +break; + +case 1263://teleport player to Dire Maul + + if (player->getLevel() >= 50) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, -3982.47f,1127.79f,161.02f,0.05f); + player->ModifyMoney(-10*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL); + } + +break; + +case 1264://teleport player to Blackrock Spire + + if (player->getLevel() >= 50) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -7535.43f,-1212.04f,285.45f,5.29f); + player->ModifyMoney(-10*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL); + } + +break; + +case 1265://teleport player to Stratholme + + if (player->getLevel() >= 50) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, 3263.54f,-3379.46f,143.59f,0.00f); + player->ModifyMoney(-10*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL); + } + +break; + +case 1266://teleport player to Scholomance + + if (player->getLevel() >= 50) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, 1219.01f,-2604.66f,85.61f,0.50f); + player->ModifyMoney(-10*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL); + } + +break; + +case 1287:// Shattrath City + +if( player->getLevel() >= 58) + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, -1850.209961f, 5435.821777f, -10.961435f, 3.403913f); + player->ModifyMoney(-1*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 58!", LANG_UNIVERSAL); + } + +break; + +case 1288://teleport player to Isle Of Quel'Danas + + if (player->getLevel() >= 65) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, 12947.4f,-6893.31f,5.68398f,3.09154f); + player->ModifyMoney(-1*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 65!", LANG_UNIVERSAL); + } + +break; + +case 4007:// Karazhan + + if (player->getLevel() >= 70) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(0, -11118.8f, -2010.84f, 47.0807f, 0.0f); + player->ModifyMoney(-20*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL); + } + +break; + +case 4008:// Gruul's Lair + + if (player->getLevel() >= 65) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, 3539.007568f, 5082.357910f, 1.691071f, 0.0f); + player->ModifyMoney(-20*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 65!", LANG_UNIVERSAL); + } + +break; + +case 4009:// Hellfire Citadel +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(530, -305.816223f, 3056.401611f, -2.473183f, 2.01f); +player->ModifyMoney(-20*costo); +break; + +case 4010:// Coilfang Reservoir +player->CLOSE_GOSSIP_MENU(); +player->TeleportTo(530, 517.288025f, 6976.279785f, 32.007198f, 0.0f); +player->ModifyMoney(-20*costo); +break; + +case 4011:// Tempest Keep + + if (player->getLevel() >= 70) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, 3089.579346f, 1399.046509f, 187.653458f, 4.794070f); + player->ModifyMoney(-20*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL); + } + +break; + +case 4012:// Caverns of Time + + if (player->getLevel() >= 66) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(1, -8173.66f, -4746.36f, 33.8423f, 4.93989f); + player->ModifyMoney(-20*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 66!", LANG_UNIVERSAL); + } + +break; + +case 4016:// Zul'Aman + + if (player->getLevel() >= 70) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, 6846.95f, -7954.5f, 170.028f, 4.61501f); + player->ModifyMoney(-20*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL); + } + +break; + +case 4013:// Black Temple + + if (player->getLevel() >= 70) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, -3610.719482f, 324.987579f, 37.400028f, 3.282981f); + player->ModifyMoney(-20*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL); + } + +break; + +case 4017:// magistrate + + if (player->getLevel() >= 70) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, 12884.6f, -7317.69f, 65.5023f, 4.799f); + player->ModifyMoney(-40*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL); + } + +break; + +case 4018:// sunwell + + if (player->getLevel() >= 70) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(530, 12574.1f, -6774.81f, 15.0904f, 3.13788f); + player->ModifyMoney(-40*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL); + } + +break; + +case 4019:// Utgarde Keep + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 1219.720f, -4865.28f, 41.25f, 0.31f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4020:// The Nexus + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 3776.950f, 6953.80f, 105.05f, 0.345f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4021:// Azjol-Nerub + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 3675.430f, 2169.00f, 35.90f, 2.29f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4022:// Ahn'kahet: The Old Kingdom + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 3646.760f, 2045.17f, 1.79f, 4.37f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4023:// Drak'Tharon Keep + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 4450.860f, -2045.25f, 162.83f, 0.00f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4024:// The Violet Hold + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 5679.820f, 486.80f, 652.40f, 4.08f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4025:// Gun' Drak + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 6937.540f, -4455.98f, 450.68f, 1.00f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4026:// Utgarde Pinnacle + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 1245.690f, -4856.59f, 216.86f, 3.45f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +case 4027:// Ulduar + + if (player->getLevel() >= 80) + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 8976.240f, -1281.33f, 1059.01f, 0.58f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } +break; + +case 4028:// The Obsidian Sanctum + + if (player->getLevel() >= 80) + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 3625.780f, 280.40f, -120.14f, 3.25f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } +break; + +case 4029:// Naxxramas + + if (player->getLevel() >= 80) + + { + player->CLOSE_GOSSIP_MENU(); + player->TeleportTo(571, 3668.719f, -1262.460f, 243.63f, 5.03f); + player->ModifyMoney(-400*costo); + } else { + player->CLOSE_GOSSIP_MENU(); + _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL); + } + +break; + +} + + +} + +bool GossipSelect_mob_teleguy(Player *player, Creature *_Creature, uint32 sender, uint32 action ) +{ + // Main menu + if (sender == GOSSIP_SENDER_MAIN) + { + player->PlayerTalkClass->ClearMenus(); + SendDefaultMenu_mob_teleguy(player, _Creature, action ); + } + return true; +} + +void AddSC_mob_teleguy() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "mob_teleguy"; + newscript->pGossipHello = &GossipHello_mob_teleguy; + newscript->pGossipSelect = &GossipSelect_mob_teleguy; + newscript->RegisterSelf(); +} diff --git a/scripts/eastern_kingdoms/alterac_mountains.cpp b/scripts/eastern_kingdoms/alterac_mountains.cpp index e8f95e14e..52db739af 100644 --- a/scripts/eastern_kingdoms/alterac_mountains.cpp +++ b/scripts/eastern_kingdoms/alterac_mountains.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/arathi_highlands.cpp b/scripts/eastern_kingdoms/arathi_highlands.cpp index a3f2df522..38c807498 100644 --- a/scripts/eastern_kingdoms/arathi_highlands.cpp +++ b/scripts/eastern_kingdoms/arathi_highlands.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -121,6 +121,6 @@ void AddSC_arathi_highlands() newscript = new Script; newscript->Name = "npc_professor_phizzlethorpe"; newscript->GetAI = &GetAI_npc_professor_phizzlethorpe; - newscript->pQuestAccept = &QuestAccept_npc_professor_phizzlethorpe; + newscript->pQuestAcceptNPC = &QuestAccept_npc_professor_phizzlethorpe; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp index 780f89edc..f275ffdb6 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Blackrock_Depths -SD%Complete: 50 -SDComment: Quest support: 4001, 4342, 7604. Vendor Lokhtos Darkbargainer. +SD%Complete: 80 +SDComment: Quest support: 4001, 4342, 7604, 9015. Vendor Lokhtos Darkbargainer. SDCategory: Blackrock Depths EndScriptData */ @@ -38,7 +38,7 @@ EndContentData */ ## go_shadowforge_brazier ######*/ -bool GOHello_go_shadowforge_brazier(Player* pPlayer, GameObject* pGo) +bool GOUse_go_shadowforge_brazier(Player* pPlayer, GameObject* pGo) { if (ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData()) { @@ -54,51 +54,81 @@ bool GOHello_go_shadowforge_brazier(Player* pPlayer, GameObject* pGo) ## npc_grimstone ######*/ +/* Notes about this event: + * Visual: Npc Grimstone should use some visual spell when appear/ disappear / opening/ closing doors + * Texts: The texts and their positions need confirmation + * Event timer might also need adjustment + * Quest-Event: This needs to be clearified - there is some suggestion, that Theldren&Adds also might come as first wave. + */ + enum { - SAY_START_1 = -1230004, - SAY_START_2 = -1230005, - SAY_OPEN_EAST_GATE = -1230006, - SAY_SUMMON_BOSS_1 = -1230007, - SAY_SUMMON_BOSS_2 = -1230008, - SAY_OPEN_NORTH_GATE = -1230009, + SAY_START_1 = -1230004, + SAY_START_2 = -1230005, + SAY_OPEN_EAST_GATE = -1230006, + SAY_SUMMON_BOSS_1 = -1230007, + SAY_SUMMON_BOSS_2 = -1230008, + SAY_OPEN_NORTH_GATE = -1230009, - NPC_GRIMSTONE = 10096, - NPC_THELDREN = 16059, + NPC_GRIMSTONE = 10096, + DATA_BANNER_BEFORE_EVENT = 5, //4 or 6 in total? 1+2+1 / 2+2+2 / 3+3. Depending on this, code should be changed. - MAX_MOB_AMOUNT = 4 + MAX_MOB_AMOUNT = 4, + MAX_THELDREN_ADDS = 4, + MAX_POSSIBLE_THELDREN_ADDS = 8, + + SPELL_SUMMON_THELRIN_DND = 27517, + /* Other spells used by Grimstone + SPELL_ASHCROMBES_TELEPORT_A = 15742 + SPELL_ASHCROMBES_TELEPORT_B = 6422, + SPELL_ARENA_FLASH_A = 15737, + SPELL_ARENA_FLASH_B = 15739, + */ + + QUEST_THE_CHALLENGE = 9015, + NPC_THELDREN_QUEST_CREDIT = 16166, +}; + +enum SpawnPosition +{ + POS_EAST = 0, + POS_NORTH = 1, + POS_GRIMSTONE = 2, }; -static uint32 RingMob[]= +static const float aSpawnPositions[3][4] = { - 8925, // Dredge Worm - 8926, // Deep Stinger - 8927, // Dark Screecher - 8928, // Burrowing Thundersnout - 8933, // Cave Creeper - 8932, // Borer Beetle + {608.960f, -235.322f, -53.907f, 1.857f}, // Ring mob spawn position + {644.300f, -175.989f, -53.739f, 3.418f}, // Ring boss spawn position + {625.559f, -205.618f, -52.735f, 2.609f} // Grimstone spawn position }; -static uint32 RingBoss[]= +static const uint32 aGladiator[MAX_POSSIBLE_THELDREN_ADDS] = {NPC_LEFTY, NPC_ROTFANG, NPC_SNOKH, NPC_MALGEN, NPC_KORV, NPC_REZZNIK, NPC_VAJASHNI, NPC_VOLIDA}; +static const uint32 aRingMob[] = {NPC_WORM, NPC_STINGER, NPC_SCREECHER, NPC_THUNDERSNOUT, NPC_CREEPER, NPC_BEETLE}; +static const uint32 aRingBoss[] = {NPC_GOROSH, NPC_GRIZZLE, NPC_EVISCERATOR, NPC_OKTHOR, NPC_ANUBSHIAH, NPC_HEDRUM}; + +enum Phases { - 9027, // Gorosh - 9028, // Grizzle - 9029, // Eviscerator - 9030, // Ok'thor - 9031, // Anub'shiah - 9032, // Hedrum + PHASE_MOBS = 0, + PHASE_BOSS = 2, + PHASE_GLADIATORS = 3, }; bool AreaTrigger_at_ring_of_law(Player* pPlayer, AreaTriggerEntry const* pAt) { - if (ScriptedInstance* pInstance = (ScriptedInstance*)pPlayer->GetInstanceData()) + if (instance_blackrock_depths* pInstance = (instance_blackrock_depths*)pPlayer->GetInstanceData()) { - if (pInstance->GetData(TYPE_RING_OF_LAW) == IN_PROGRESS || pInstance->GetData(TYPE_RING_OF_LAW) == DONE) + if (pInstance->GetData(TYPE_RING_OF_LAW) == IN_PROGRESS || pInstance->GetData(TYPE_RING_OF_LAW) == DONE || pInstance->GetData(TYPE_RING_OF_LAW) == SPECIAL) + return false; + + if (pPlayer->isGameMaster()) return false; - pInstance->SetData(TYPE_RING_OF_LAW, IN_PROGRESS); - pPlayer->SummonCreature(NPC_GRIMSTONE, 625.559f, -205.618f, -52.735f, 2.609f, TEMPSUMMON_DEAD_DESPAWN, 0); + pInstance->SetData(TYPE_RING_OF_LAW, pInstance->GetData(TYPE_RING_OF_LAW) == DATA_BANNER_BEFORE_EVENT ? SPECIAL : IN_PROGRESS); + + pPlayer->SummonCreature(NPC_GRIMSTONE, aSpawnPositions[POS_GRIMSTONE][0], aSpawnPositions[POS_GRIMSTONE][1], aSpawnPositions[POS_GRIMSTONE][2], aSpawnPositions[POS_GRIMSTONE][3], TEMPSUMMON_DEAD_DESPAWN, 0); + pInstance->SetArenaCenterCoords(pAt->x, pAt->y, pAt->z); return false; } @@ -109,81 +139,116 @@ bool AreaTrigger_at_ring_of_law(Player* pPlayer, AreaTriggerEntry const* pAt) ## npc_grimstone ######*/ -//TODO: implement quest part of event (different end boss) struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI { npc_grimstoneAI(Creature* pCreature) : npc_escortAI(pCreature) { - m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_pInstance = (instance_blackrock_depths*)pCreature->GetInstanceData(); m_uiMobSpawnId = urand(0, 5); + // Select MAX_THELDREN_ADDS(4) random adds for Theldren encounter + uint8 uiCount = 0; + for (uint8 i = 0; i < MAX_POSSIBLE_THELDREN_ADDS && uiCount < MAX_THELDREN_ADDS; ++i) + { + if (urand(0, 1) || i >= MAX_POSSIBLE_THELDREN_ADDS - MAX_THELDREN_ADDS + uiCount) + { + m_uiGladiatorId[uiCount] = aGladiator[i]; + ++uiCount; + } + } + Reset(); } - ScriptedInstance* m_pInstance; + instance_blackrock_depths* m_pInstance; uint8 m_uiEventPhase; uint32 m_uiEventTimer; uint8 m_uiMobSpawnId; - uint8 m_uiMobCount; - uint32 m_uiMobDeathTimer; + uint8 m_uiMobDeadCount; + + Phases m_uiPhase; - uint64 m_auiRingMobGUID[MAX_MOB_AMOUNT]; - uint64 m_uiRingBossGUID; + uint32 m_uiGladiatorId[MAX_THELDREN_ADDS]; - bool m_bCanWalk; + std::list m_lSummonedGUIDList; void Reset() { m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - memset(&m_auiRingMobGUID, 0, sizeof(m_auiRingMobGUID)); m_uiEventTimer = 1000; m_uiEventPhase = 0; - m_uiMobCount = 0; - m_uiMobDeathTimer = 0; - m_uiRingBossGUID = 0; + m_uiMobDeadCount = 0; - m_bCanWalk = false; + m_uiPhase = PHASE_MOBS; } void JustSummoned(Creature* pSummoned) { + if (!m_pInstance) + return; - } - - void SummonedCreatureJustDied(Creature* pSummoned) - { + // Ring mob or boss summoned + float fX, fY, fZ; + float fcX, fcY, fcZ; + m_pInstance->GetArenaCenterCoords(fX, fY, fZ); + m_creature->GetRandomPoint(fX, fY, fZ, 10.0f, fcX, fcY, fcZ); + pSummoned->GetMotionMaster()->MovePoint(1, fcX, fcY, fcZ); + m_lSummonedGUIDList.push_back(pSummoned->GetGUID()); } - - void DoGate(uint32 id, uint32 state) + + void DoChallengeQuestCredit() { - if (GameObject* pGo = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(id))) - pGo->SetGoState(GOState(state)); + Map::PlayerList const &PlayerList = m_creature->GetMap()->GetPlayers(); - debug_log("SD2: npc_grimstone, arena gate update state."); + for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) + { + Player* pPlayer = itr->getSource(); + if (pPlayer && pPlayer->GetQuestStatus(QUEST_THE_CHALLENGE) == QUEST_STATUS_INCOMPLETE) + pPlayer->KilledMonsterCredit(NPC_THELDREN_QUEST_CREDIT); + } } - //TODO: move them to center - void SummonRingMob() + void SummonedCreatureJustDied(Creature* pSummoned) { - if (Creature* pTmp = m_creature->SummonCreature(RingMob[m_uiMobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0)) - m_auiRingMobGUID[m_uiMobCount] = pTmp->GetGUID(); + ++m_uiMobDeadCount; - ++m_uiMobCount; - - if (m_uiMobCount == MAX_MOB_AMOUNT) - m_uiMobDeathTimer = 2500; + switch (m_uiPhase) + { + case PHASE_MOBS: // Ring mob killed + if (m_uiMobDeadCount == MAX_MOB_AMOUNT) + { + m_uiEventTimer = 5000; + m_uiMobDeadCount = 0; + } + break; + case PHASE_BOSS: // Ring boss killed + // One Boss + if (m_uiMobDeadCount == 1) + { + m_uiEventTimer = 5000; + m_uiMobDeadCount = 0; + } + break; + case PHASE_GLADIATORS: // Theldren and his band killed + // Adds + Theldren + if (m_uiMobDeadCount == MAX_THELDREN_ADDS + 1) + { + m_uiEventTimer = 5000; + m_uiMobDeadCount = 0; + DoChallengeQuestCredit(); + } + break; + } } - //TODO: move them to center - void SummonRingBoss() + void SummonRingMob(uint32 uiEntry, SpawnPosition uiPosition) { - if (Creature* pTmp = m_creature->SummonCreature(RingBoss[urand(0, 5)], 644.300f, -175.989f, -53.739f, 3.418f, TEMPSUMMON_DEAD_DESPAWN, 0)) - m_uiRingBossGUID = pTmp->GetGUID(); - - m_uiMobDeathTimer = 2500; + float fX, fY, fZ; + m_creature->GetRandomPoint(aSpawnPositions[uiPosition][0], aSpawnPositions[uiPosition][1], aSpawnPositions[uiPosition][2], 2.0f, fX, fY, fZ); + m_creature->SummonCreature(uiEntry, fX, fY, fZ, 0, TEMPSUMMON_DEAD_DESPAWN, 0); } void WaypointReached(uint32 uiPointId) @@ -192,23 +257,23 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI { case 0: // Middle reached first time DoScriptText(urand(0, 1) ? SAY_START_1 : SAY_START_2, m_creature); - m_bCanWalk = false; + SetEscortPaused(true); m_uiEventTimer = 5000; break; case 1: // Reached wall again DoScriptText(SAY_OPEN_EAST_GATE, m_creature); - m_bCanWalk = false; + SetEscortPaused(true); m_uiEventTimer = 5000; break; case 2: // walking along the wall, while door opened - m_bCanWalk = false; + SetEscortPaused(true); break; case 3: // Middle reached second time DoScriptText(urand(0, 1) ? SAY_SUMMON_BOSS_1 : SAY_SUMMON_BOSS_2, m_creature); break; case 4: // Reached North Gate - DoScriptText(SAY_OPEN_NORTH_GATE, m_creature);//6 - m_bCanWalk = false; + DoScriptText(SAY_OPEN_NORTH_GATE, m_creature); + SetEscortPaused(true); m_uiEventTimer = 5000; break; case 5: @@ -221,49 +286,34 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI } } - void UpdateAI(const uint32 uiDiff) + void UpdateEscortAI(const uint32 uiDiff) { if (!m_pInstance) return; - if (m_uiMobDeathTimer) + if (m_pInstance->GetData(TYPE_RING_OF_LAW) == FAIL) { - if (m_uiMobDeathTimer <= uiDiff) + // Reset Doors + if (m_uiEventPhase >= 9) // North Gate is opened + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_2)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_4)); + } + else if (m_uiEventPhase >= 4) // East Gate is opened { - m_uiMobDeathTimer = 2500; + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_1)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_4)); + } - if (m_uiRingBossGUID) - { - Creature* pBoss = m_creature->GetMap()->GetCreature(m_uiRingBossGUID); - if (pBoss && !pBoss->isAlive() && pBoss->isDead()) - { - m_uiRingBossGUID = 0; - m_uiEventTimer = 5000; - m_uiMobDeathTimer = 0; - return; - } - return; - } + // Despawn Summoned Mobs + for (std::list::const_iterator itr = m_lSummonedGUIDList.begin(); itr != m_lSummonedGUIDList.end(); ++itr) + if (Creature* pSummoned = m_creature->GetMap()->GetCreature(*itr)) + pSummoned->ForcedDespawn(); + m_lSummonedGUIDList.clear(); - for(uint8 i = 0; i < MAX_MOB_AMOUNT; ++i) - { - Creature* pMob = m_creature->GetMap()->GetCreature(m_auiRingMobGUID[i]); - if (pMob && !pMob->isAlive() && pMob->isDead()) - { - m_auiRingMobGUID[i] = 0; - --m_uiMobCount; - - //seems all are gone, so set timer to continue and discontinue this - if (!m_uiMobCount) - { - m_uiEventTimer = 5000; - m_uiMobDeathTimer = 0; - } - } - } - } - else - m_uiMobDeathTimer -= uiDiff; + // Despawn NPC + m_creature->ForcedDespawn(); + return; } if (m_uiEventTimer) @@ -275,14 +325,14 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI case 0: // Shortly after spawn, start walking //DoScriptText(-1000000, m_creature); // no more text on spawn - DoGate(DATA_ARENA4, GO_STATE_READY); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_4)); Start(false); - m_bCanWalk = true; + SetEscortPaused(false); m_uiEventTimer = 0; break; case 1: // Start walking towards wall - m_bCanWalk = true; + SetEscortPaused(false); m_uiEventTimer = 0; break; case 2: @@ -290,50 +340,65 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI break; case 3: // Open East Gate - DoGate(DATA_ARENA1, GO_STATE_ACTIVE); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_1)); m_uiEventTimer = 3000; break; case 4: - m_bCanWalk = true; + SetEscortPaused(false); m_creature->SetVisibility(VISIBILITY_OFF); - SummonRingMob(); + // Summon Ring Mob(s) + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); m_uiEventTimer = 8000; break; case 5: - SummonRingMob(); - SummonRingMob(); + // Summon Ring Mob(s) + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); m_uiEventTimer = 8000; break; case 6: - SummonRingMob(); + // Summon Ring Mob(s) + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); m_uiEventTimer = 0; break; case 7: // Summoned Mobs are dead, continue event m_creature->SetVisibility(VISIBILITY_ON); - DoGate(DATA_ARENA1, GO_STATE_READY); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_1)); //DoScriptText(-1000000, m_creature); // after killed the mobs, no say here - m_bCanWalk = true; + SetEscortPaused(false); m_uiEventTimer = 0; break; case 8: // Open North Gate - DoGate(DATA_ARENA2, GO_STATE_ACTIVE); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_2)); m_uiEventTimer = 5000; break; case 9: // Summon Boss m_creature->SetVisibility(VISIBILITY_OFF); - SummonRingBoss(); + // If banner summoned after start, then summon Thelden after the creatures are dead + if (m_pInstance->GetData(TYPE_RING_OF_LAW) == SPECIAL && m_uiPhase == PHASE_MOBS) + { + m_uiPhase = PHASE_GLADIATORS; + SummonRingMob(NPC_THELDREN, POS_NORTH); + for (uint8 i = 0; i < MAX_THELDREN_ADDS; ++i) + SummonRingMob(m_uiGladiatorId[i], POS_NORTH); + } + else + { + m_uiPhase = PHASE_BOSS; + SummonRingMob(aRingBoss[urand(0, 5)], POS_NORTH); + } m_uiEventTimer = 0; break; case 10: // Boss dead - //if quest, complete - DoGate(DATA_ARENA2, GO_STATE_READY); - DoGate(DATA_ARENA3, GO_STATE_ACTIVE); - DoGate(DATA_ARENA4, GO_STATE_ACTIVE); - m_bCanWalk = true; + m_lSummonedGUIDList.clear(); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_2)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_3)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_4)); + SetEscortPaused(false); m_uiEventTimer = 0; break; } @@ -342,9 +407,6 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI else m_uiEventTimer -= uiDiff; } - - if (m_bCanWalk) - npc_escortAI::UpdateAI(uiDiff); } }; @@ -353,6 +415,19 @@ CreatureAI* GetAI_npc_grimstone(Creature* pCreature) return new npc_grimstoneAI(pCreature); } +bool EffectDummyCreature_spell_banner_of_provocation(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +{ + if (uiSpellId == SPELL_SUMMON_THELRIN_DND && uiEffIndex != EFFECT_INDEX_0) + { + instance_blackrock_depths* pInstance = (instance_blackrock_depths*)pCreatureTarget->GetInstanceData(); + if (pInstance && pInstance->GetData(TYPE_RING_OF_LAW) != DONE && pInstance->GetData(TYPE_RING_OF_LAW) != SPECIAL) + pInstance->SetData(TYPE_RING_OF_LAW, pInstance->GetData(TYPE_RING_OF_LAW) == IN_PROGRESS ? SPECIAL : DATA_BANNER_BEFORE_EVENT); + + return true; + } + return false; +} + /*###### ## mob_phalanx ######*/ @@ -518,12 +593,12 @@ bool GossipSelect_npc_kharan_mighthammer(Player* pPlayer, Creature* pCreature, u enum { FACTION_THORIUM_BROTHERHOOD = 59, - + ITEM_THRORIUM_BROTHERHOOD_CONTRACT = 18628, ITEM_SULFURON_INGOT = 17203, - + QUEST_A_BINDING_CONTRACT = 7604, - + SPELL_CREATE_THORIUM_BROTHERHOOD_CONTRACT = 23059 }; @@ -643,7 +718,7 @@ struct MANGOS_DLL_DECL npc_rocknotAI : public npc_escortAI { if (m_uiBreakKegTimer <= uiDiff) { - DoGo(DATA_GO_BAR_KEG,0); + DoGo(GO_BAR_KEG_SHOT, 0); m_uiBreakKegTimer = 0; m_uiBreakDoorTimer = 1000; } @@ -655,11 +730,11 @@ struct MANGOS_DLL_DECL npc_rocknotAI : public npc_escortAI { if (m_uiBreakDoorTimer <= uiDiff) { - DoGo(DATA_GO_BAR_DOOR, 2); - DoGo(DATA_GO_BAR_KEG_TRAP, 0); //doesn't work very well, leaving code here for future + DoGo(GO_BAR_DOOR, 2); + DoGo(GO_BAR_KEG_TRAP, 0); //doesn't work very well, leaving code here for future //spell by trap has effect61, this indicate the bar go hostile - if (Creature* pTmp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_PHALANX))) + if (Creature* pTmp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_PHALANX))) pTmp->setFaction(14); // for later, this event(s) has alot more to it. @@ -679,7 +754,7 @@ CreatureAI* GetAI_npc_rocknot(Creature* pCreature) return new npc_rocknotAI(pCreature); } -bool ChooseReward_npc_rocknot(Player* pPlayer, Creature* pCreature, const Quest* pQuest, uint32 item) +bool QuestRewarded_npc_rocknot(Player* pPlayer, Creature* pCreature, Quest const* pQuest) { ScriptedInstance* pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); @@ -716,7 +791,7 @@ void AddSC_blackrock_depths() pNewScript = new Script; pNewScript->Name = "go_shadowforge_brazier"; - pNewScript->pGOHello = &GOHello_go_shadowforge_brazier; + pNewScript->pGOUse = &GOUse_go_shadowforge_brazier; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -729,6 +804,11 @@ void AddSC_blackrock_depths() pNewScript->GetAI = &GetAI_npc_grimstone; pNewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "npc_theldren_trigger"; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_spell_banner_of_provocation; + pNewScript->RegisterSelf(); + pNewScript = new Script; pNewScript->Name = "mob_phalanx"; pNewScript->GetAI = &GetAI_mob_phalanx; @@ -749,6 +829,6 @@ void AddSC_blackrock_depths() pNewScript = new Script; pNewScript->Name = "npc_rocknot"; pNewScript->GetAI = &GetAI_npc_rocknot; - pNewScript->pChooseReward = &ChooseReward_npc_rocknot; + pNewScript->pQuestRewardedNPC = &QuestRewarded_npc_rocknot; pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h index 439b97b3f..74310a788 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h +++ b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,6 +7,7 @@ enum { + MAX_ENCOUNTER = 6, TYPE_RING_OF_LAW = 1, TYPE_VAULT = 2, TYPE_BAR = 3, @@ -14,27 +15,142 @@ enum TYPE_LYCEUM = 5, TYPE_IRON_HALL = 6, - DATA_EMPEROR = 10, - DATA_PRINCESS = 11, - DATA_PHALANX = 12, - DATA_HATEREL = 13, - DATA_ANGERREL = 14, - DATA_VILEREL = 15, - DATA_GLOOMREL = 16, - DATA_SEETHREL = 17, - DATA_DOOMREL = 18, - DATA_DOPEREL = 19, - - DATA_ARENA1 = 20, - DATA_ARENA2 = 21, - DATA_ARENA3 = 22, - DATA_ARENA4 = 23, - - DATA_GO_BAR_KEG = 24, - DATA_GO_BAR_KEG_TRAP = 25, - DATA_GO_BAR_DOOR = 26, - DATA_GO_CHALICE = 27, - DATA_GO_TOMB_EXIT = 28 + 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, + + 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, +}; + +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 +}; + +class MANGOS_DLL_DECL instance_blackrock_depths : public ScriptedInstance +{ + public: + instance_blackrock_depths(Map* pMap); + ~instance_blackrock_depths() {} + + void Initialize(); + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + void OnCreatureEvade(Creature* pCreature); + + // 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: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiEmperorGUID; + uint64 m_uiPrincessGUID; + uint64 m_uiPhalanxGUID; + uint64 m_uiHaterelGUID; + uint64 m_uiAngerrelGUID; + uint64 m_uiVilerelGUID; + uint64 m_uiGloomrelGUID; + uint64 m_uiSeethrelGUID; + uint64 m_uiDoomrelGUID; + uint64 m_uiDoperelGUID; + + uint64 m_uiGoArena1GUID; + uint64 m_uiGoArena2GUID; + uint64 m_uiGoArena3GUID; + uint64 m_uiGoArena4GUID; + uint64 m_uiGoShadowLockGUID; + uint64 m_uiGoShadowMechGUID; + uint64 m_uiGoShadowGiantGUID; + uint64 m_uiGoShadowDummyGUID; + uint64 m_uiGoBarKegGUID; + uint64 m_uiGoBarKegTrapGUID; + uint64 m_uiGoBarDoorGUID; + uint64 m_uiGoTombEnterGUID; + uint64 m_uiGoTombExitGUID; + uint64 m_uiGoLyceumGUID; + uint64 m_uiGoGolemNGUID; + uint64 m_uiGoGolemSGUID; + uint64 m_uiGoThroneGUID; + + uint64 m_uiSpectralChaliceGUID; + uint64 m_uiSevensChestGUID; + uint64 m_uiArenaSpoilsGUID; + + uint32 m_uiBarAleCount; + + float m_fArenaCenterX, m_fArenaCenterY, m_fArenaCenterZ; }; #endif diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp index 00786846a..c1d687a11 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp index 5c2063e09..29844960a 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_coren_direbrew.cpp similarity index 52% rename from scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp rename to scripts/eastern_kingdoms/blackrock_depths/boss_coren_direbrew.cpp index a898d2797..267f37bef 100644 --- a/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_coren_direbrew.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,23 +15,14 @@ */ /* ScriptData -SDName: Boss_Gatewatcher_Gyrokill +SDName: boss_coren_direbrew SD%Complete: 0 -SDComment: Place Holder -SDCategory: Tempest Keep, The Mechanar +SDComment: Placeholder +SDCategory: Blackrock Depths EndScriptData */ #include "precompiled.h" -#define SAY_AGGRO -1554000 -#define SAY_SAW_ATTACK1 -1554001 -#define SAY_SAW_ATTACK2 -1554002 -#define SAY_SLAY1 -1554003 -#define SAY_SLAY2 -1554004 -#define SAY_DEATH -1554005 - -#define SPELL_STREAM_OF_MACHINE_FLUID 35311 -#define SPELL_SAW_BLADE 35318 -#define H_SPELL_SAW_BLADE 39192 -#define SPELL_SHADOW_POWER 35322 -#define H_SPELL_SHADOW_POWER 39193 +void AddSC_boss_coren_direbrew() +{ +} diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp index ebf02a2b0..191b6fcbb 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -66,7 +66,7 @@ struct MANGOS_DLL_DECL boss_emperor_dagran_thaurissanAI : public ScriptedAI if (!m_pInstance) return; - if (Creature* pPrincess = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_PRINCESS))) + if (Creature* pPrincess = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_PRINCESS))) { if (pPrincess->isAlive()) { @@ -179,7 +179,7 @@ struct MANGOS_DLL_DECL boss_moira_bronzebeardAI : public ScriptedAI { if (m_pInstance) { - if (Creature* pEmperor = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_EMPEROR))) + if (Creature* pEmperor = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_EMPEROR))) { // if evade, then check if he is alive. If not, start make portal if (!pEmperor->isAlive()) @@ -224,7 +224,7 @@ struct MANGOS_DLL_DECL boss_moira_bronzebeardAI : public ScriptedAI //Heal_Timer if (m_uiHeal_Timer < uiDiff) { - if (Creature* pEmperor = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_EMPEROR))) + if (Creature* pEmperor = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_EMPEROR))) { if (pEmperor->isAlive() && pEmperor->GetHealthPercent() != 100.0f) DoCastSpellIfCan(pEmperor, SPELL_HEAL); diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp index 727ab3500..0acb31d27 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp index 4632c66a2..915345169 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp index 94e97f4e5..e3a38d9dd 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp index d159bd06c..f3f76176d 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp index 07d533fd2..645b25eec 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp index ccf1dba32..3d239c50b 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -80,7 +80,7 @@ bool GossipSelect_boss_gloomrel(Player* pPlayer, Creature* pCreature, uint32 uiS if (ScriptedInstance* pInstance = (ScriptedInstance*)pCreature->GetInstanceData()) { //are 5 minutes expected? go template may have data to despawn when used at quest - pInstance->DoRespawnGameObject(pInstance->GetData64(DATA_GO_CHALICE),MINUTE*5); + pInstance->DoRespawnGameObject(pInstance->GetData64(GO_SPECTRAL_CHALICE), MINUTE*5); } break; } @@ -154,17 +154,17 @@ struct MANGOS_DLL_DECL boss_doomrelAI : public ScriptedAI switch(uiPhase) { case 0: - return m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_ANGERREL)); + return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ANGERREL)); case 1: - return m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SEETHREL)); + return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SEETHREL)); case 2: - return m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_DOPEREL)); + return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_DOPEREL)); case 3: - return m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_GLOOMREL)); + return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_GLOOMREL)); case 4: - return m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_VILEREL)); + return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_VILEREL)); case 5: - return m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_HATEREL)); + return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_HATEREL)); case 6: return m_creature; } diff --git a/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp b/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp index b80aaee7e..deea483c9 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,351 +16,276 @@ /* ScriptData SDName: Instance_Blackrock_Depths -SD%Complete: 20 -SDComment: events: ring of law +SD%Complete: 80 +SDComment: SDCategory: Blackrock Depths EndScriptData */ #include "precompiled.h" #include "blackrock_depths.h" -enum +instance_blackrock_depths::instance_blackrock_depths(Map* pMap) : ScriptedInstance(pMap), + m_uiEmperorGUID(0), + m_uiPrincessGUID(0), + m_uiPhalanxGUID(0), + m_uiHaterelGUID(0), + m_uiAngerrelGUID(0), + m_uiVilerelGUID(0), + m_uiGloomrelGUID(0), + m_uiSeethrelGUID(0), + m_uiDoomrelGUID(0), + m_uiDoperelGUID(0), + + m_uiGoArena1GUID(0), + m_uiGoArena2GUID(0), + m_uiGoArena3GUID(0), + m_uiGoArena4GUID(0), + m_uiGoShadowLockGUID(0), + m_uiGoShadowMechGUID(0), + m_uiGoShadowGiantGUID(0), + m_uiGoShadowDummyGUID(0), + m_uiGoBarKegGUID(0), + m_uiGoBarKegTrapGUID(0), + m_uiGoBarDoorGUID(0), + m_uiGoTombEnterGUID(0), + m_uiGoTombExitGUID(0), + m_uiGoLyceumGUID(0), + m_uiGoGolemNGUID(0), + m_uiGoGolemSGUID(0), + m_uiGoThroneGUID(0), + + m_uiSpectralChaliceGUID(0), + m_uiSevensChestGUID(0), + m_uiArenaSpoilsGUID(0), + + m_uiBarAleCount(0), + + m_fArenaCenterX(0.0f), + m_fArenaCenterY(0.0f), + m_fArenaCenterZ(0.0f) { - MAX_ENCOUNTER = 6, - - 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, - - GO_ARENA1 = 161525, - GO_ARENA2 = 161522, - GO_ARENA3 = 161524, - GO_ARENA4 = 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 -}; + Initialize(); +} -struct MANGOS_DLL_DECL instance_blackrock_depths : public ScriptedInstance +void instance_blackrock_depths::Initialize() { - instance_blackrock_depths(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - uint64 m_uiEmperorGUID; - uint64 m_uiPrincessGUID; - uint64 m_uiPhalanxGUID; - uint64 m_uiHaterelGUID; - uint64 m_uiAngerrelGUID; - uint64 m_uiVilerelGUID; - uint64 m_uiGloomrelGUID; - uint64 m_uiSeethrelGUID; - uint64 m_uiDoomrelGUID; - uint64 m_uiDoperelGUID; - - uint64 m_uiGoArena1GUID; - uint64 m_uiGoArena2GUID; - uint64 m_uiGoArena3GUID; - uint64 m_uiGoArena4GUID; - uint64 m_uiGoShadowLockGUID; - uint64 m_uiGoShadowMechGUID; - uint64 m_uiGoShadowGiantGUID; - uint64 m_uiGoShadowDummyGUID; - uint64 m_uiGoBarKegGUID; - uint64 m_uiGoBarKegTrapGUID; - uint64 m_uiGoBarDoorGUID; - uint64 m_uiGoTombEnterGUID; - uint64 m_uiGoTombExitGUID; - uint64 m_uiGoLyceumGUID; - uint64 m_uiGoGolemNGUID; - uint64 m_uiGoGolemSGUID; - uint64 m_uiGoThroneGUID; - - uint64 m_uiSpectralChaliceGUID; - uint64 m_uiSevensChestGUID; - - uint32 m_uiBarAleCount; - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiEmperorGUID = 0; - m_uiPrincessGUID = 0; - m_uiPhalanxGUID = 0; - m_uiHaterelGUID = 0; - m_uiAngerrelGUID = 0; - m_uiVilerelGUID = 0; - m_uiGloomrelGUID = 0; - m_uiSeethrelGUID = 0; - m_uiDoomrelGUID = 0; - m_uiDoperelGUID = 0; - - m_uiGoArena1GUID = 0; - m_uiGoArena2GUID = 0; - m_uiGoArena3GUID = 0; - m_uiGoArena4GUID = 0; - m_uiGoShadowLockGUID = 0; - m_uiGoShadowMechGUID = 0; - m_uiGoShadowGiantGUID = 0; - m_uiGoShadowDummyGUID = 0; - m_uiGoBarKegGUID = 0; - m_uiGoBarKegTrapGUID = 0; - m_uiGoBarDoorGUID = 0; - m_uiGoTombEnterGUID = 0; - m_uiGoTombExitGUID = 0; - m_uiGoLyceumGUID = 0; - m_uiGoGolemNGUID = 0; - m_uiGoGolemSGUID = 0; - m_uiGoThroneGUID = 0; - - m_uiSpectralChaliceGUID = 0; - m_uiSevensChestGUID = 0; - - m_uiBarAleCount = 0; - } + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - void OnCreatureCreate(Creature* pCreature) +void instance_blackrock_depths::OnCreatureCreate(Creature* pCreature) +{ + switch(pCreature->GetEntry()) { - switch(pCreature->GetEntry()) - { - case NPC_EMPEROR: m_uiEmperorGUID = pCreature->GetGUID(); break; - case NPC_PRINCESS: m_uiPrincessGUID = pCreature->GetGUID(); break; - case NPC_PHALANX: m_uiPhalanxGUID = pCreature->GetGUID(); break; - case NPC_HATEREL: m_uiHaterelGUID = pCreature->GetGUID(); break; - case NPC_ANGERREL: m_uiAngerrelGUID = pCreature->GetGUID(); break; - case NPC_VILEREL: m_uiVilerelGUID = pCreature->GetGUID(); break; - case NPC_GLOOMREL: m_uiGloomrelGUID = pCreature->GetGUID(); break; - case NPC_SEETHREL: m_uiSeethrelGUID = pCreature->GetGUID(); break; - case NPC_DOOMREL: m_uiDoomrelGUID = pCreature->GetGUID(); break; - case NPC_DOPEREL: m_uiDoperelGUID = pCreature->GetGUID(); break; - } + case NPC_EMPEROR: m_uiEmperorGUID = pCreature->GetGUID(); break; + case NPC_PRINCESS: m_uiPrincessGUID = pCreature->GetGUID(); break; + case NPC_PHALANX: m_uiPhalanxGUID = pCreature->GetGUID(); break; + case NPC_HATEREL: m_uiHaterelGUID = pCreature->GetGUID(); break; + case NPC_ANGERREL: m_uiAngerrelGUID = pCreature->GetGUID(); break; + case NPC_VILEREL: m_uiVilerelGUID = pCreature->GetGUID(); break; + case NPC_GLOOMREL: m_uiGloomrelGUID = pCreature->GetGUID(); break; + case NPC_SEETHREL: m_uiSeethrelGUID = pCreature->GetGUID(); break; + case NPC_DOOMREL: m_uiDoomrelGUID = pCreature->GetGUID(); break; + case NPC_DOPEREL: m_uiDoperelGUID = pCreature->GetGUID(); break; } +} - void OnObjectCreate(GameObject* pGo) +void instance_blackrock_depths::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) { - switch(pGo->GetEntry()) - { - case GO_ARENA1: m_uiGoArena1GUID = pGo->GetGUID(); break; - case GO_ARENA2: m_uiGoArena2GUID = pGo->GetGUID(); break; - case GO_ARENA3: m_uiGoArena3GUID = pGo->GetGUID(); break; - case GO_ARENA4: m_uiGoArena4GUID = pGo->GetGUID(); break; - case GO_SHADOW_LOCK: m_uiGoShadowLockGUID = pGo->GetGUID(); break; - case GO_SHADOW_MECHANISM: m_uiGoShadowMechGUID = pGo->GetGUID(); break; - case GO_SHADOW_GIANT_DOOR: m_uiGoShadowGiantGUID = pGo->GetGUID(); break; - case GO_SHADOW_DUMMY: m_uiGoShadowDummyGUID = pGo->GetGUID(); break; - case GO_BAR_KEG_SHOT: m_uiGoBarKegGUID = pGo->GetGUID(); break; - case GO_BAR_KEG_TRAP: m_uiGoBarKegTrapGUID = pGo->GetGUID(); break; - case GO_BAR_DOOR: m_uiGoBarDoorGUID = pGo->GetGUID(); break; - case GO_TOMB_ENTER: m_uiGoTombEnterGUID = pGo->GetGUID(); break; - case GO_TOMB_EXIT: m_uiGoTombExitGUID = pGo->GetGUID(); break; - case GO_LYCEUM: m_uiGoLyceumGUID = pGo->GetGUID(); break; - case GO_GOLEM_ROOM_N: m_uiGoGolemNGUID = pGo->GetGUID(); break; - case GO_GOLEM_ROOM_S: m_uiGoGolemSGUID = pGo->GetGUID(); break; - case GO_THRONE_ROOM: m_uiGoThroneGUID = pGo->GetGUID(); break; - case GO_SPECTRAL_CHALICE: m_uiSpectralChaliceGUID = pGo->GetGUID(); break; - case GO_CHEST_SEVEN: m_uiSevensChestGUID = pGo->GetGUID(); break; - } + case GO_ARENA_1: m_uiGoArena1GUID = pGo->GetGUID(); break; + case GO_ARENA_2: m_uiGoArena2GUID = pGo->GetGUID(); break; + case GO_ARENA_3: m_uiGoArena3GUID = pGo->GetGUID(); break; + case GO_ARENA_4: m_uiGoArena4GUID = pGo->GetGUID(); break; + case GO_SHADOW_LOCK: m_uiGoShadowLockGUID = pGo->GetGUID(); break; + case GO_SHADOW_MECHANISM: m_uiGoShadowMechGUID = pGo->GetGUID(); break; + case GO_SHADOW_GIANT_DOOR: m_uiGoShadowGiantGUID = pGo->GetGUID(); break; + case GO_SHADOW_DUMMY: m_uiGoShadowDummyGUID = pGo->GetGUID(); break; + case GO_BAR_KEG_SHOT: m_uiGoBarKegGUID = pGo->GetGUID(); break; + case GO_BAR_KEG_TRAP: m_uiGoBarKegTrapGUID = pGo->GetGUID(); break; + case GO_BAR_DOOR: m_uiGoBarDoorGUID = pGo->GetGUID(); break; + case GO_TOMB_ENTER: m_uiGoTombEnterGUID = pGo->GetGUID(); break; + case GO_TOMB_EXIT: m_uiGoTombExitGUID = pGo->GetGUID(); break; + case GO_LYCEUM: m_uiGoLyceumGUID = pGo->GetGUID(); break; + case GO_GOLEM_ROOM_N: m_uiGoGolemNGUID = pGo->GetGUID(); break; + case GO_GOLEM_ROOM_S: m_uiGoGolemSGUID = pGo->GetGUID(); break; + case GO_THRONE_ROOM: m_uiGoThroneGUID = pGo->GetGUID(); break; + case GO_SPECTRAL_CHALICE: m_uiSpectralChaliceGUID = pGo->GetGUID(); break; + case GO_CHEST_SEVEN: m_uiSevensChestGUID = pGo->GetGUID(); break; + case GO_ARENA_SPOILS: m_uiArenaSpoilsGUID = pGo->GetGUID(); break; } +} - void SetData(uint32 uiType, uint32 uiData) +void instance_blackrock_depths::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - debug_log("SD2: Instance Blackrock Depths: SetData update (Type: %u Data %u)", uiType, uiData); - - switch(uiType) - { - case TYPE_RING_OF_LAW: - m_auiEncounter[0] = uiData; - break; - case TYPE_VAULT: - m_auiEncounter[1] = uiData; - break; - case TYPE_BAR: - if (uiData == SPECIAL) - ++m_uiBarAleCount; - else - m_auiEncounter[2] = uiData; - break; - case TYPE_TOMB_OF_SEVEN: - switch(uiData) - { - case IN_PROGRESS: - DoUseDoorOrButton(m_uiGoTombEnterGUID); - break; - case FAIL: - if (m_auiEncounter[3] == IN_PROGRESS)//prevent use more than one time - DoUseDoorOrButton(m_uiGoTombEnterGUID); - break; - case DONE: - DoRespawnGameObject(m_uiSevensChestGUID, HOUR*IN_MILLISECONDS); - DoUseDoorOrButton(m_uiGoTombExitGUID); + case TYPE_RING_OF_LAW: + // If finished the arena event after theldren fight + if (uiData == DONE && m_auiEncounter[0] == SPECIAL) + DoRespawnGameObject(m_uiArenaSpoilsGUID, HOUR*IN_MILLISECONDS); + m_auiEncounter[0] = uiData; + break; + case TYPE_VAULT: + m_auiEncounter[1] = uiData; + break; + case TYPE_BAR: + if (uiData == SPECIAL) + ++m_uiBarAleCount; + else + m_auiEncounter[2] = uiData; + break; + case TYPE_TOMB_OF_SEVEN: + switch(uiData) + { + case IN_PROGRESS: + DoUseDoorOrButton(m_uiGoTombEnterGUID); + break; + case FAIL: + if (m_auiEncounter[3] == IN_PROGRESS)//prevent use more than one time DoUseDoorOrButton(m_uiGoTombEnterGUID); - break; - } - m_auiEncounter[3] = uiData; - break; - case TYPE_LYCEUM: - if (uiData == DONE) - { + break; + case DONE: + DoRespawnGameObject(m_uiSevensChestGUID, HOUR*IN_MILLISECONDS); + DoUseDoorOrButton(m_uiGoTombExitGUID); + DoUseDoorOrButton(m_uiGoTombEnterGUID); + break; + } + m_auiEncounter[3] = uiData; + break; + case TYPE_LYCEUM: + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiGoGolemNGUID); + DoUseDoorOrButton(m_uiGoGolemSGUID); + } + m_auiEncounter[4] = uiData; + break; + case TYPE_IRON_HALL: + switch(uiData) + { + case IN_PROGRESS: DoUseDoorOrButton(m_uiGoGolemNGUID); DoUseDoorOrButton(m_uiGoGolemSGUID); - } - m_auiEncounter[4] = uiData; - break; - case TYPE_IRON_HALL: - switch(uiData) - { - case IN_PROGRESS: - DoUseDoorOrButton(m_uiGoGolemNGUID); - DoUseDoorOrButton(m_uiGoGolemSGUID); - break; - case FAIL: - DoUseDoorOrButton(m_uiGoGolemNGUID); - DoUseDoorOrButton(m_uiGoGolemSGUID); - break; - case DONE: - DoUseDoorOrButton(m_uiGoGolemNGUID); - DoUseDoorOrButton(m_uiGoGolemSGUID); - DoUseDoorOrButton(m_uiGoThroneGUID); - break; - } - m_auiEncounter[5] = uiData; - break; - } + break; + case FAIL: + DoUseDoorOrButton(m_uiGoGolemNGUID); + DoUseDoorOrButton(m_uiGoGolemSGUID); + break; + case DONE: + DoUseDoorOrButton(m_uiGoGolemNGUID); + DoUseDoorOrButton(m_uiGoGolemSGUID); + DoUseDoorOrButton(m_uiGoThroneGUID); + break; + } + m_auiEncounter[5] = uiData; + break; + } - if (uiData == DONE) - { - OUT_SAVE_INST_DATA; + 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]; + std::ostringstream saveStream; + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " + << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5]; - strInstData = saveStream.str(); + m_strInstData = saveStream.str(); - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - uint32 GetData(uint32 uiType) +uint32 instance_blackrock_depths::GetData(uint32 uiType) +{ + switch(uiType) { - 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]; - } - return 0; + 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]; + default: + return 0; } +} - uint64 GetData64(uint32 uiData) +uint64 instance_blackrock_depths::GetData64(uint32 uiData) +{ + switch(uiData) { - switch(uiData) - { - case DATA_EMPEROR: - return m_uiEmperorGUID; - case DATA_PRINCESS: - return m_uiPrincessGUID; - case DATA_PHALANX: - return m_uiPhalanxGUID; - case DATA_HATEREL: - return m_uiHaterelGUID; - case DATA_ANGERREL: - return m_uiAngerrelGUID; - case DATA_VILEREL: - return m_uiVilerelGUID; - case DATA_GLOOMREL: - return m_uiGloomrelGUID; - case DATA_SEETHREL: - return m_uiSeethrelGUID; - case DATA_DOOMREL: - return m_uiDoomrelGUID; - case DATA_DOPEREL: - return m_uiDoperelGUID; - - case DATA_ARENA1: - return m_uiGoArena1GUID; - case DATA_ARENA2: - return m_uiGoArena2GUID; - case DATA_ARENA3: - return m_uiGoArena3GUID; - case DATA_ARENA4: - return m_uiGoArena4GUID; - - case DATA_GO_BAR_KEG: - return m_uiGoBarKegGUID; - case DATA_GO_BAR_KEG_TRAP: - return m_uiGoBarKegTrapGUID; - case DATA_GO_BAR_DOOR: - return m_uiGoBarDoorGUID; - case DATA_GO_CHALICE: - return m_uiSpectralChaliceGUID; - case DATA_GO_TOMB_EXIT: - return m_uiGoTombExitGUID; - } - return 0; + case NPC_EMPEROR: return m_uiEmperorGUID; + case NPC_PRINCESS: return m_uiPrincessGUID; + case NPC_PHALANX: return m_uiPhalanxGUID; + case NPC_HATEREL: return m_uiHaterelGUID; + case NPC_ANGERREL: return m_uiAngerrelGUID; + case NPC_VILEREL: return m_uiVilerelGUID; + case NPC_GLOOMREL: return m_uiGloomrelGUID; + case NPC_SEETHREL: return m_uiSeethrelGUID; + case NPC_DOOMREL: return m_uiDoomrelGUID; + case NPC_DOPEREL: return m_uiDoperelGUID; + + case GO_ARENA_1: return m_uiGoArena1GUID; + case GO_ARENA_2: return m_uiGoArena2GUID; + case GO_ARENA_3: return m_uiGoArena3GUID; + case GO_ARENA_4: return m_uiGoArena4GUID; + case GO_BAR_KEG_SHOT: return m_uiGoBarKegGUID; + case GO_BAR_KEG_TRAP: return m_uiGoBarKegTrapGUID; + case GO_BAR_DOOR: return m_uiGoBarDoorGUID; + case GO_SPECTRAL_CHALICE: return m_uiSpectralChaliceGUID; + case GO_TOMB_EXIT: return m_uiGoTombExitGUID; + + default: + return 0; } +} - const char* Save() +void instance_blackrock_depths::Load(const char* chrIn) +{ + if (!chrIn) { - return strInstData.c_str(); + OUT_LOAD_INST_DATA_FAIL; + return; } - void Load(const char* in) - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } + OUT_LOAD_INST_DATA(chrIn); - OUT_LOAD_INST_DATA(in); + std::istringstream loadStream(chrIn); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] + >> m_auiEncounter[4] >> m_auiEncounter[5]; - std::istringstream loadStream(in); - 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; - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; + OUT_LOAD_INST_DATA_COMPLETE; +} - OUT_LOAD_INST_DATA_COMPLETE; +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 < sizeof(aArenaNPCs)/sizeof(uint32); ++i) + { + if (pCreature->GetEntry() == aArenaNPCs[i]) + { + SetData(TYPE_RING_OF_LAW, FAIL); + return; + } + } } -}; +} InstanceData* GetInstanceData_instance_blackrock_depths(Map* pMap) { @@ -369,9 +294,10 @@ InstanceData* GetInstanceData_instance_blackrock_depths(Map* pMap) void AddSC_instance_blackrock_depths() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_blackrock_depths"; - newscript->GetInstanceData = &GetInstanceData_instance_blackrock_depths; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_blackrock_depths"; + pNewScript->GetInstanceData = &GetInstanceData_instance_blackrock_depths; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h b/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h index d17773837..0f7c0498c 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h +++ b/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -70,7 +70,7 @@ class MANGOS_DLL_DECL instance_blackrock_spire : public ScriptedInstance protected: uint32 m_auiEncounter[MAX_ENCOUNTER]; std::string strInstData; - + uint64 m_uiEmberseerGUID; uint64 m_uiNefariusGUID; uint64 m_uiGythGUID; diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp index ba1c63376..79e22a02c 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp index d5a32be71..c9852d3ae 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp index bf6208f8b..93329569b 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp index 3dff5dd2d..997b1e386 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp index 9501d026e..dc66641ea 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp index 4fbfb9f64..a69b3deb4 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -29,7 +29,7 @@ enum SPELL_SHOUT = 23511, SPELL_CLEAVE = 20691, SPELL_KNOCKAWAY = 20686, - + NPC_SPIRESTONE_WARLORD = 9216, NPC_SMOLDERTHORN_BERSERKER = 9268 @@ -71,7 +71,7 @@ struct MANGOS_DLL_DECL boss_overlordwyrmthalakAI : public ScriptedAI pSummoned->AI()->AttackStart(pTarget ? pTarget : m_creature->getVictim()); } } - + void UpdateAI(const uint32 uiDiff) { // Return since we have no target diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp index 57733d06f..148d5ba82 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp index 09e1d1f4a..0d702610a 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp index daab7235b..7beaa9bd2 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp index 168ccdee5..5a22b83e7 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp index 54106ab31..3745a88b4 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -65,7 +65,7 @@ struct MANGOS_DLL_DECL boss_thebeastAI : public ScriptedAI { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_IMMOLATE); - + m_uiImmolateTimer = 8000; } else diff --git a/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp b/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp index 0864098ca..f1d873743 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp b/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp index ce0435d66..c6b957322 100644 --- a/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp +++ b/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -73,7 +73,7 @@ void instance_blackrock_spire::OnObjectCreate(GameObject* pGo) { case GO_EMBERSEER_IN: m_uiEmberseerInDoorGUID = pGo->GetGUID(); - if (GetData(TYPE_ROOM_EVENT) == DONE) + if (GetData(TYPE_ROOM_EVENT) == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_DOORS: diff --git a/scripts/eastern_kingdoms/blackwing_lair/blackwing_lair.h b/scripts/eastern_kingdoms/blackwing_lair/blackwing_lair.h new file mode 100644 index 000000000..c459f111f --- /dev/null +++ b/scripts/eastern_kingdoms/blackwing_lair/blackwing_lair.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * 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, + + 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_NEFARIAN = 10162, + + 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 +}; + +class MANGOS_DLL_DECL instance_blackwing_lair : public ScriptedInstance +{ + public: + instance_blackwing_lair(Map* pMap); + ~instance_blackwing_lair() {} + + void Initialize(); + bool IsEncounterInProgress() const; + + void OnObjectCreate(GameObject* pGo); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + protected: + std::string m_strInstData; + uint32 m_auiEncounter[MAX_ENCOUNTER]; + + // Doors + uint64 m_uiRazorgoreEnterDoorGUID; + uint64 m_uiRazorgoreExitDoorGUID; + uint64 m_uiVaelastraszDoorGUID; + uint64 m_uiLashlayerDoorGUID; + uint64 m_uiChromaggusEnterDoorGUID; + uint64 m_uiChromaggusExitDoorGUID; + uint64 m_uiChromaggusSideDoorGUID; + uint64 m_uiNefarianDoorGUID; +}; + +#endif diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp index 27635ab09..a644314de 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,77 +22,109 @@ SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" -#define SAY_AGGRO -1469000 -#define SAY_LEASH -1469001 +enum +{ + SAY_AGGRO = -1469000, + SAY_LEASH = -1469001, -#define SPELL_CLEAVE 26350 -#define SPELL_BLASTWAVE 23331 -#define SPELL_MORTALSTRIKE 24573 -#define SPELL_KNOCKBACK 25778 + SPELL_CLEAVE = 26350, + SPELL_BLAST_WAVE = 23331, + SPELL_MORTAL_STRIKE = 24573, + SPELL_KNOCK_AWAY = 25778 +}; struct MANGOS_DLL_DECL boss_broodlordAI : public ScriptedAI { - boss_broodlordAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_broodlordAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } - uint32 Cleave_Timer; - uint32 BlastWave_Timer; - uint32 MortalStrike_Timer; - uint32 KnockBack_Timer; + ScriptedInstance* m_pInstance; + + uint32 m_uiCleaveTimer; + uint32 m_uiBlastWaveTimer; + uint32 m_uiMortalStrikeTimer; + uint32 m_uiKnockAwayTimer; void Reset() { - Cleave_Timer = 8000; //These times are probably wrong - BlastWave_Timer = 12000; - MortalStrike_Timer = 20000; - KnockBack_Timer = 30000; + m_uiCleaveTimer = 8000; // These times are probably wrong + m_uiBlastWaveTimer = 12000; + m_uiMortalStrikeTimer = 20000; + m_uiKnockAwayTimer = 30000; } void Aggro(Unit* pWho) { + if (m_pInstance) + m_pInstance->SetData(TYPE_LASHLAYER, IN_PROGRESS); + DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); } - void UpdateAI(const uint32 diff) + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_LASHLAYER, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_LASHLAYER, FAIL); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Cleave_Timer - if (Cleave_Timer < diff) + // Cleave Timer + if (m_uiCleaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE); - Cleave_Timer = 7000; - }else Cleave_Timer -= diff; - - // BlastWave - if (BlastWave_Timer < diff) + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) + m_uiCleaveTimer = 7000; + } + else + m_uiCleaveTimer -= uiDiff; + + // Blast Wave + if (m_uiBlastWaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_BLASTWAVE); - BlastWave_Timer = urand(8000, 16000); - }else BlastWave_Timer -= diff; - - //MortalStrike_Timer - if (MortalStrike_Timer < diff) + 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) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_MORTALSTRIKE); - MortalStrike_Timer = urand(25000, 35000); - }else MortalStrike_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MORTAL_STRIKE) == CAST_OK) + m_uiMortalStrikeTimer = urand(25000, 35000); + } + else + m_uiMortalStrikeTimer -= uiDiff; - if (KnockBack_Timer < diff) + if (m_uiKnockAwayTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_KNOCKBACK); - //Drop 50% aggro + 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_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(), -50); - KnockBack_Timer = urand(15000, 30000); - }else KnockBack_Timer -= diff; + m_uiKnockAwayTimer = urand(15000, 30000); + } + else + m_uiKnockAwayTimer -= uiDiff; DoMeleeAttackIfReady(); - if (EnterEvadeIfOutOfCombatArea(diff)) + if (EnterEvadeIfOutOfCombatArea(uiDiff)) DoScriptText(SAY_LEASH, m_creature); } }; @@ -103,9 +135,10 @@ CreatureAI* GetAI_boss_broodlord(Creature* pCreature) void AddSC_boss_broodlord() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_broodlord"; - newscript->GetAI = &GetAI_boss_broodlord; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_broodlord"; + pNewScript->GetAI = &GetAI_boss_broodlord; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp index 003d13552..a5516538c 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,241 +22,185 @@ 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_VURNALBILTY = 22277, - SPELL_FROST_VURNALBILTY = 22278, - SPELL_SHADOW_VURNALBILTY = 22279, - SPELL_NATURE_VURNALBILTY = 22280, - SPELL_ARCANE_VURNALBILTY = 22281, - - SPELL_INCINERATE = 23308, //Incinerate 23308,23309 - SPELL_TIMELAPSE = 23310, //Time lapse 23310, 23311(old threat mod that was removed in 2.01) - SPELL_CORROSIVEACID = 23313, //Corrosive Acid 23313, 23314 - SPELL_IGNITEFLESH = 23315, //Ignite Flesh 23315,23316 - SPELL_FROSTBURN = 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 + // 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 MANGOS_DLL_DECL boss_chromaggusAI : public ScriptedAI { boss_chromaggusAI(Creature* pCreature) : ScriptedAI(pCreature) { - //Select the 2 breaths that we are going to use until despawned - //5 possiblities for the first breath, 4 for the second, 20 total possiblites - //This way we don't end up casting 2 of the same breath - //TL TL would be stupid - srand(time(NULL)); - switch(urand(0, 19)) - { - //B1 - Incin - case 0: - Breath1_Spell = SPELL_INCINERATE; - Breath2_Spell = SPELL_TIMELAPSE; - break; - case 1: - Breath1_Spell = SPELL_INCINERATE; - Breath2_Spell = SPELL_CORROSIVEACID; - break; - case 2: - Breath1_Spell = SPELL_INCINERATE; - Breath2_Spell = SPELL_IGNITEFLESH; - break; - case 3: - Breath1_Spell = SPELL_INCINERATE; - Breath2_Spell = SPELL_FROSTBURN; - break; - - //B1 - TL - case 4: - Breath1_Spell = SPELL_TIMELAPSE; - Breath2_Spell = SPELL_INCINERATE; - break; - case 5: - Breath1_Spell = SPELL_TIMELAPSE; - Breath2_Spell = SPELL_CORROSIVEACID; - break; - case 6: - Breath1_Spell = SPELL_TIMELAPSE; - Breath2_Spell = SPELL_IGNITEFLESH; - break; - case 7: - Breath1_Spell = SPELL_TIMELAPSE; - Breath2_Spell = SPELL_FROSTBURN; - break; - - //B1 - Acid - case 8: - Breath1_Spell = SPELL_CORROSIVEACID; - Breath2_Spell = SPELL_INCINERATE; - break; - case 9: - Breath1_Spell = SPELL_CORROSIVEACID; - Breath2_Spell = SPELL_TIMELAPSE; - break; - case 10: - Breath1_Spell = SPELL_CORROSIVEACID; - Breath2_Spell = SPELL_IGNITEFLESH; - break; - case 11: - Breath1_Spell = SPELL_CORROSIVEACID; - Breath2_Spell = SPELL_FROSTBURN; - break; - - //B1 - Ignite - case 12: - Breath1_Spell = SPELL_IGNITEFLESH; - Breath2_Spell = SPELL_INCINERATE; - break; - case 13: - Breath1_Spell = SPELL_IGNITEFLESH; - Breath2_Spell = SPELL_CORROSIVEACID; - break; - case 14: - Breath1_Spell = SPELL_IGNITEFLESH; - Breath2_Spell = SPELL_TIMELAPSE; - break; - case 15: - Breath1_Spell = SPELL_IGNITEFLESH; - Breath2_Spell = SPELL_FROSTBURN; - break; - - //B1 - Frost - case 16: - Breath1_Spell = SPELL_FROSTBURN; - Breath2_Spell = SPELL_INCINERATE; - break; - case 17: - Breath1_Spell = SPELL_FROSTBURN; - Breath2_Spell = SPELL_TIMELAPSE; - break; - case 18: - Breath1_Spell = SPELL_FROSTBURN; - Breath2_Spell = SPELL_CORROSIVEACID; - break; - case 19: - Breath1_Spell = SPELL_FROSTBURN; - Breath2_Spell = SPELL_IGNITEFLESH; - break; - }; - - EnterEvadeMode(); + // 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(); } - uint32 Breath1_Spell; - uint32 Breath2_Spell; - uint32 CurrentVurln_Spell; + ScriptedInstance* m_pInstance; + + uint32 m_uiBreathOneSpell; + uint32 m_uiBreathTwoSpell; + uint32 m_uiCurrentVulnerabilitySpell; - uint32 Shimmer_Timer; - uint32 Breath1_Timer; - uint32 Breath2_Timer; - uint32 Affliction_Timer; - uint32 Frenzy_Timer; - bool Enraged; + uint32 m_uiShimmerTimer; + uint32 m_uiBreathOneTimer; + uint32 m_uiBreathTwoTimer; + uint32 m_uiAfflictionTimer; + uint32 m_uiFrenzyTimer; + bool m_bEnraged; void Reset() { - CurrentVurln_Spell = 0; //We use this to store our last vurlnability spell so we can remove it later + 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) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_CHROMAGGUS, IN_PROGRESS); + } - Shimmer_Timer = 0; //Time till we change vurlnerabilites - Breath1_Timer = 30000; //First breath is 30 seconds - Breath2_Timer = 60000; //Second is 1 minute so that we can alternate - Affliction_Timer = 10000; //This is special - 5 seconds means that we cast this on 1 pPlayer every 5 sconds - Frenzy_Timer = 15000; + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_CHROMAGGUS, DONE); + } - Enraged = false; + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_CHROMAGGUS, FAIL); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Shimmer_Timer Timer - if (Shimmer_Timer < diff) + // Shimmer Timer Timer + if (m_uiShimmerTimer < uiDiff) { - //Remove old vurlnability spell - if (CurrentVurln_Spell) - m_creature->RemoveAurasDueToSpell(CurrentVurln_Spell); + // Remove old vulnerability spell + if (m_uiCurrentVulnerabilitySpell) + m_creature->RemoveAurasDueToSpell(m_uiCurrentVulnerabilitySpell); - //Cast new random vurlnabilty on self - uint32 spell; + // Cast new random vurlnabilty on self + uint32 uiSpell; switch(urand(0, 4)) { - case 0: spell = SPELL_FIRE_VURNALBILTY; break; - case 1: spell = SPELL_FROST_VURNALBILTY; break; - case 2: spell = SPELL_SHADOW_VURNALBILTY; break; - case 3: spell = SPELL_NATURE_VURNALBILTY; break; - case 4: spell = SPELL_ARCANE_VURNALBILTY; break; + case 0: uiSpell = SPELL_FIRE_VULNERABILITY; break; + case 1: uiSpell = SPELL_FROST_VULNERABILITY; break; + case 2: uiSpell = SPELL_SHADOW_VULNERABILITY; break; + case 3: uiSpell = SPELL_NATURE_VULNERABILITY; break; + case 4: uiSpell = SPELL_ARCANE_VULNERABILITY; break; } - if (DoCastSpellIfCan(m_creature, spell) == CAST_OK) + if (DoCastSpellIfCan(m_creature, uiSpell) == CAST_OK) { - CurrentVurln_Spell = spell; + m_uiCurrentVulnerabilitySpell = uiSpell; DoScriptText(EMOTE_SHIMMER, m_creature); - Shimmer_Timer = 45000; + m_uiShimmerTimer = 45000; } - }else Shimmer_Timer -= diff; + } + else + m_uiShimmerTimer -= uiDiff; - //Breath1_Timer - if (Breath1_Timer < diff) + // Breath One Timer + if (m_uiBreathOneTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),Breath1_Spell); - Breath1_Timer = 60000; - }else Breath1_Timer -= diff; + if (DoCastSpellIfCan(m_creature, m_uiBreathOneSpell) == CAST_OK) + m_uiBreathOneTimer = 60000; + } + else + m_uiBreathOneTimer -= uiDiff; - //Breath2_Timer - if (Breath2_Timer < diff) + // Breath Two Timer + if (m_uiBreathTwoTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),Breath2_Spell); - Breath2_Timer = 60000; - }else Breath2_Timer -= diff; + if (DoCastSpellIfCan(m_creature, m_uiBreathTwoSpell) == CAST_OK) + m_uiBreathTwoTimer = 60000; + } + else + m_uiBreathTwoTimer -= uiDiff; - //Affliction_Timer - if (Affliction_Timer < diff) + // Affliction Timer + if (m_uiAfflictionTimer < uiDiff) { - uint32 SpellAfflict = 0; + uint32 m_uiSpellAfflict = 0; switch(urand(0, 4)) { - case 0: SpellAfflict = SPELL_BROODAF_BLUE; break; - case 1: SpellAfflict = SPELL_BROODAF_BLACK; break; - case 2: SpellAfflict = SPELL_BROODAF_RED; break; - case 3: SpellAfflict = SPELL_BROODAF_BRONZE; break; - case 4: SpellAfflict = SPELL_BROODAF_GREEN; break; + 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; } - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit) { - //Cast affliction - DoCastSpellIfCan(pUnit, SpellAfflict, CAST_TRIGGERED); + // Cast affliction + DoCastSpellIfCan(pUnit, m_uiSpellAfflict, CAST_TRIGGERED); - //Chromatic mutation if target is effected by all afflictions + // 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) @@ -266,40 +210,45 @@ struct MANGOS_DLL_DECL boss_chromaggusAI : public ScriptedAI //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 + // 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 + // WORKAROUND if (pUnit->GetTypeId() == TYPEID_PLAYER) - pUnit->CastSpell(pUnit, 5, false); + m_creature->CastSpell(pUnit, 5, false); } } } - Affliction_Timer = 10000; - }else Affliction_Timer -= diff; + m_uiAfflictionTimer = 10000; + } + else + m_uiAfflictionTimer -= uiDiff; - //Frenzy_Timer - if (Frenzy_Timer < diff) + // Frenzy Timer + if (m_uiFrenzyTimer < uiDiff) { - if (DoCastSpellIfCan(m_creature,SPELL_FRENZY) == CAST_OK) + if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) { DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature); - Frenzy_Timer = urand(10000, 15000); + m_uiFrenzyTimer = urand(10000, 15000); } - }else Frenzy_Timer -= diff; + } + else + m_uiFrenzyTimer -= uiDiff; - //Enrage if not already enraged and below 20% - if (!Enraged && m_creature->GetHealthPercent() < 20.0f) + // Enrage if not already enraged and below 20% + if (!m_bEnraged && m_creature->GetHealthPercent() < 20.0f) { - DoCastSpellIfCan(m_creature,SPELL_ENRAGE); - Enraged = true; + DoCastSpellIfCan(m_creature, SPELL_ENRAGE); + m_bEnraged = true; } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_chromaggus(Creature* pCreature) { return new boss_chromaggusAI(pCreature); @@ -307,9 +256,10 @@ CreatureAI* GetAI_boss_chromaggus(Creature* pCreature) void AddSC_boss_chromaggus() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_chromaggus"; - newscript->GetAI = &GetAI_boss_chromaggus; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_chromaggus"; + pNewScript->GetAI = &GetAI_boss_chromaggus; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp index 3395a7d92..d7782faee 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,78 +16,97 @@ /* ScriptData SDName: Boss_Ebonroc -SD%Complete: 50 -SDComment: Shadow of Ebonroc needs core support +SD%Complete: 90 +SDComment: Thrash is missing SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" -#define SPELL_SHADOWFLAME 22539 -#define SPELL_WINGBUFFET 18500 -#define SPELL_SHADOWOFEBONROC 23340 -#define SPELL_HEAL 41386 //Thea Heal spell of his Shadow +enum +{ + SPELL_SHADOW_FLAME = 22539, + SPELL_WING_BUFFET = 18500, + SPELL_SHADOW_OF_EBONROC = 23340, + SPELL_THRASH = 3391, // TODO missing +}; struct MANGOS_DLL_DECL boss_ebonrocAI : public ScriptedAI { - boss_ebonrocAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_ebonrocAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 ShadowFlame_Timer; - uint32 WingBuffet_Timer; - uint32 ShadowOfEbonroc_Timer; - uint32 Heal_Timer; + uint32 m_uiShadowFlameTimer; + uint32 m_uiWingBuffetTimer; + uint32 m_uiShadowOfEbonrocTimer; void Reset() { - ShadowFlame_Timer = 15000; //These times are probably wrong - WingBuffet_Timer = 30000; - ShadowOfEbonroc_Timer = 45000; - Heal_Timer = 1000; + m_uiShadowFlameTimer = 15000; // These times are probably wrong + m_uiWingBuffetTimer = 30000; + m_uiShadowOfEbonrocTimer = 45000; } void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); + if (m_pInstance) + m_pInstance->SetData(TYPE_EBONROC, IN_PROGRESS); } - void UpdateAI(const uint32 diff) + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_EBONROC, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_EBONROC, FAIL); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Shadowflame Timer - if (ShadowFlame_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SHADOWFLAME); - ShadowFlame_Timer = urand(12000, 15000); - }else ShadowFlame_Timer -= diff; - - //Wing Buffet Timer - if (WingBuffet_Timer < diff) + // Shadow Flame Timer + if (m_uiShadowFlameTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_WINGBUFFET); - WingBuffet_Timer = 25000; - }else WingBuffet_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_SHADOW_FLAME) == CAST_OK) + m_uiShadowFlameTimer = urand(12000, 15000); + } + else + m_uiShadowFlameTimer -= uiDiff; - //Shadow of Ebonroc Timer - if (ShadowOfEbonroc_Timer < diff) + // Wing Buffet Timer + if (m_uiWingBuffetTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SHADOWOFEBONROC); - ShadowOfEbonroc_Timer = urand(25000, 35000); - }else ShadowOfEbonroc_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_WING_BUFFET) == CAST_OK) + m_uiWingBuffetTimer = 25000; + } + else + m_uiWingBuffetTimer -= uiDiff; - if (m_creature->getVictim()->HasAura(SPELL_SHADOWOFEBONROC, EFFECT_INDEX_0)) + // Shadow of Ebonroc Timer + if (m_uiShadowOfEbonrocTimer < uiDiff) { - if (Heal_Timer < diff) - { - DoCastSpellIfCan(m_creature, SPELL_HEAL); - Heal_Timer = urand(1000, 3000); - }else Heal_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_OF_EBONROC) == CAST_OK) + m_uiShadowOfEbonrocTimer = urand(25000, 35000); } + else + m_uiShadowOfEbonrocTimer -= uiDiff; DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_ebonroc(Creature* pCreature) { return new boss_ebonrocAI(pCreature); @@ -95,9 +114,10 @@ CreatureAI* GetAI_boss_ebonroc(Creature* pCreature) void AddSC_boss_ebonroc() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_ebonroc"; - newscript->GetAI = &GetAI_boss_ebonroc; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_ebonroc"; + pNewScript->GetAI = &GetAI_boss_ebonroc; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp index 312265f0a..17c5310ef 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,65 +16,97 @@ /* ScriptData SDName: Boss_Firemaw -SD%Complete: 100 -SDComment: +SD%Complete: 80 +SDComment: Thrash missing SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" -#define SPELL_SHADOWFLAME 22539 -#define SPELL_WINGBUFFET 23339 -#define SPELL_FLAMEBUFFET 23341 +enum +{ + SPELL_SHADOW_FLAME = 22539, + SPELL_WING_BUFFET = 23339, + SPELL_FLAME_BUFFET = 23341, + SPELL_THRASH = 3391, // TODO, missing +}; struct MANGOS_DLL_DECL boss_firemawAI : public ScriptedAI { - boss_firemawAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_firemawAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 ShadowFlame_Timer; - uint32 WingBuffet_Timer; - uint32 FlameBuffet_Timer; + uint32 m_uiShadowFlameTimer; + uint32 m_uiWingBuffetTimer; + uint32 m_uiFlameBuffetTimer; void Reset() { - ShadowFlame_Timer = 30000; //These times are probably wrong - WingBuffet_Timer = 24000; - FlameBuffet_Timer = 5000; + m_uiShadowFlameTimer = 30000; // These times are probably wrong + m_uiWingBuffetTimer = 24000; + m_uiFlameBuffetTimer = 5000; } void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); + if (m_pInstance) + m_pInstance->SetData(TYPE_FIREMAW, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_FIREMAW, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_FIREMAW, FAIL); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ShadowFlame_Timer - if (ShadowFlame_Timer < diff) + // Shadow Flame Timer + if (m_uiShadowFlameTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SHADOWFLAME); - ShadowFlame_Timer = urand(15000, 18000); - }else ShadowFlame_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_SHADOW_FLAME) == CAST_OK) + m_uiShadowFlameTimer = urand(15000, 18000); + } + else + m_uiShadowFlameTimer -= uiDiff; - //WingBuffet_Timer - if (WingBuffet_Timer < diff) + // Wing Buffet Timer + if (m_uiWingBuffetTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_WINGBUFFET); - if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-75); + 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); - WingBuffet_Timer = 25000; - }else WingBuffet_Timer -= diff; + m_uiWingBuffetTimer = 25000; + } + } + else + m_uiWingBuffetTimer -= uiDiff; - //FlameBuffet_Timer - if (FlameBuffet_Timer < diff) + // Flame Buffet Timer + if (m_uiFlameBuffetTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FLAMEBUFFET); - FlameBuffet_Timer = 5000; - }else FlameBuffet_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_FLAME_BUFFET) == CAST_OK) + m_uiFlameBuffetTimer = 5000; + } + else + m_uiFlameBuffetTimer -= uiDiff; DoMeleeAttackIfReady(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp index 33b5d955b..5e836b04a 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,73 +16,102 @@ /* ScriptData SDName: Boss_Flamegor -SD%Complete: 100 -SDComment: +SD%Complete: 90 +SDComment: Thrash is missing SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" enum { EMOTE_GENERIC_FRENZY = -1000002, - SPELL_SHADOWFLAME = 22539, - SPELL_WINGBUFFET = 23339, - SPELL_FRENZY = 23342 //This spell periodically triggers fire nova + SPELL_SHADOW_FLAME = 22539, + SPELL_WING_BUFFET = 23339, + SPELL_FRENZY = 23342, // This spell periodically triggers fire nova + SPELL_THRASH = 3391, // TODO missing }; struct MANGOS_DLL_DECL boss_flamegorAI : public ScriptedAI { - boss_flamegorAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_flamegorAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 ShadowFlame_Timer; - uint32 WingBuffet_Timer; - uint32 Frenzy_Timer; + uint32 m_uiShadowFlameTimer; + uint32 m_uiWingBuffetTimer; + uint32 m_uiFrenzyTimer; void Reset() { - ShadowFlame_Timer = 21000; //These times are probably wrong - WingBuffet_Timer = 35000; - Frenzy_Timer = 10000; + m_uiShadowFlameTimer = 21000; // These times are probably wrong + m_uiWingBuffetTimer = 35000; + m_uiFrenzyTimer = 10000; } void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); + if (m_pInstance) + m_pInstance->SetData(TYPE_FLAMEGOR, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_FLAMEGOR, DONE); } - void UpdateAI(const uint32 diff) + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_FLAMEGOR, FAIL); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ShadowFlame_Timer - if (ShadowFlame_Timer < diff) + // Shadow Flame Timer + if (m_uiShadowFlameTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SHADOWFLAME); - ShadowFlame_Timer = urand(15000, 22000); - }else ShadowFlame_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_SHADOW_FLAME) == CAST_OK) + m_uiShadowFlameTimer = urand(15000, 22000); + } + else + m_uiShadowFlameTimer -= uiDiff; - //WingBuffet_Timer - if (WingBuffet_Timer < diff) + // Wing Buffet Timer + if (m_uiWingBuffetTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_WINGBUFFET); - if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-75); + 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); - WingBuffet_Timer = 25000; - }else WingBuffet_Timer -= diff; + m_uiWingBuffetTimer = 25000; + } + } + else + m_uiWingBuffetTimer -= uiDiff; - //Frenzy_Timer - if (Frenzy_Timer < diff) + // Frenzy Timer + if (m_uiFrenzyTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) { DoScriptText(EMOTE_GENERIC_FRENZY, m_creature); - Frenzy_Timer = urand(8000, 10000); + m_uiFrenzyTimer = urand(8000, 10000); } - }else Frenzy_Timer -= diff; + } + else + m_uiFrenzyTimer -= uiDiff; DoMeleeAttackIfReady(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp index da5fb00a3..332b7ac29 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,136 +22,184 @@ SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" +#include "TemporarySummon.h" -#define SAY_AGGRO -1469007 -#define SAY_XHEALTH -1469008 -#define SAY_SHADOWFLAME -1469009 -#define SAY_RAISE_SKELETONS -1469010 -#define SAY_SLAY -1469011 -#define SAY_DEATH -1469012 - -#define SAY_MAGE -1469013 -#define SAY_WARRIOR -1469014 -#define SAY_DRUID -1469015 -#define SAY_PRIEST -1469016 -#define SAY_PALADIN -1469017 -#define SAY_SHAMAN -1469018 -#define SAY_WARLOCK -1469019 -#define SAY_HUNTER -1469020 -#define SAY_ROGUE -1469021 - -#define SPELL_SHADOWFLAME_INITIAL 22972 -#define SPELL_SHADOWFLAME 22539 -#define SPELL_BELLOWINGROAR 22686 -#define SPELL_VEILOFSHADOW 7068 -#define SPELL_CLEAVE 20691 -#define SPELL_TAILLASH 23364 -#define SPELL_BONECONTRUST 23363 //23362, 23361 - -#define SPELL_MAGE 23410 //wild magic -#define SPELL_WARRIOR 23397 //beserk -#define SPELL_DRUID 23398 // cat form -#define SPELL_PRIEST 23401 // corrupted healing -#define SPELL_PALADIN 23418 //syphon blessing -#define SPELL_SHAMAN 23425 //totems -#define SPELL_WARLOCK 23427 //infernals -#define SPELL_HUNTER 23436 //bow broke -#define SPELL_ROGUE 23414 //Paralise +enum +{ + SAY_AGGRO = -1469007, + SAY_XHEALTH = -1469008, // at 5% hp + SAY_SHADOWFLAME = -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 MANGOS_DLL_DECL boss_nefarianAI : public ScriptedAI { - boss_nefarianAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_nefarianAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } - uint32 ShadowFlame_Timer; - uint32 BellowingRoar_Timer; - uint32 VeilOfShadow_Timer; - uint32 Cleave_Timer; - uint32 TailLash_Timer; - uint32 ClassCall_Timer; - bool Phase3; + 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() { - ShadowFlame_Timer = 12000; //These times are probably wrong - BellowingRoar_Timer = 30000; - VeilOfShadow_Timer = 15000; - Cleave_Timer = 7000; - TailLash_Timer = 10000; - ClassCall_Timer = 35000; //35-40 seconds - Phase3 = false; + 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* Victim) + void KilledUnit(Unit* pVictim) { if (urand(0, 4)) return; - DoScriptText(SAY_SLAY, m_creature, Victim); + DoScriptText(SAY_SLAY, m_creature, pVictim); } - void JustDied(Unit* Killer) + void JustDied(Unit* pKiller) { DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_NEFARIAN, DONE); } - void Aggro(Unit* pWho) + void JustReachedHome() { - switch(urand(0, 3)) + if (m_pInstance) { - case 0: DoScriptText(SAY_XHEALTH, m_creature); break; - case 1: DoScriptText(SAY_AGGRO, m_creature); break; - case 2: DoScriptText(SAY_SHADOWFLAME, m_creature); break; + 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(); } + } - DoCastSpellIfCan(pWho,SPELL_SHADOWFLAME_INITIAL); + void Aggro(Unit* pWho) + { + DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); + // Remove flying in case Nefarian aggroes before his combat point was reached + if (m_creature->HasSplineFlag(SPLINEFLAG_FLYING)) + { + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + } + + DoCastSpellIfCan(m_creature, SPELL_SHADOWFLAME_INITIAL); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ShadowFlame_Timer - if (ShadowFlame_Timer < diff) + // ShadowFlame_Timer + if (m_uiShadowFlameTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SHADOWFLAME); - ShadowFlame_Timer = 12000; - }else ShadowFlame_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_SHADOWFLAME) == CAST_OK) + { + // ToDo: check if he yells at every cast + DoScriptText(SAY_SHADOWFLAME, m_creature); + m_uiShadowFlameTimer = 12000; + } + } + else + m_uiShadowFlameTimer -= uiDiff; - //BellowingRoar_Timer - if (BellowingRoar_Timer < diff) + // BellowingRoar_Timer + if (m_uiBellowingRoarTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_BELLOWINGROAR); - BellowingRoar_Timer = 30000; - }else BellowingRoar_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_BELLOWING_ROAR) == CAST_OK) + m_uiBellowingRoarTimer = 30000; + } + else + m_uiBellowingRoarTimer -= uiDiff; - //VeilOfShadow_Timer - if (VeilOfShadow_Timer < diff) + // VeilOfShadow_Timer + if (m_uiVeilOfShadowTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_VEILOFSHADOW); - VeilOfShadow_Timer = 15000; - }else VeilOfShadow_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_VEIL_OF_SHADOW) == CAST_OK) + m_uiVeilOfShadowTimer = 15000; + } + else + m_uiVeilOfShadowTimer -= uiDiff; - //Cleave_Timer - if (Cleave_Timer < diff) + // Cleave_Timer + if (m_uiCleaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE); - Cleave_Timer = 7000; - }else Cleave_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) + m_uiCleaveTimer = 7000; + } + else + m_uiCleaveTimer -= uiDiff; - //TailLash_Timer - if (TailLash_Timer < diff) + // TailLash_Timer + if (m_uiTailLashTimer < uiDiff) { - //Cast NYI since we need a better check for behind target - //DoCastSpellIfCan(m_creature->getVictim(),SPELL_TAILLASH); - - TailLash_Timer = 10000; - }else TailLash_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_TAIL_LASH) == CAST_OK) + m_uiTailLashTimer = 10000; + } + else + m_uiTailLashTimer -= uiDiff; - //ClassCall_Timer - if (ClassCall_Timer < diff) + // 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 @@ -161,55 +209,66 @@ struct MANGOS_DLL_DECL boss_nefarianAI : public ScriptedAI { case 0: DoScriptText(SAY_MAGE, m_creature); - DoCastSpellIfCan(m_creature,SPELL_MAGE); + DoCastSpellIfCan(m_creature, SPELL_MAGE); break; case 1: DoScriptText(SAY_WARRIOR, m_creature); - DoCastSpellIfCan(m_creature,SPELL_WARRIOR); + DoCastSpellIfCan(m_creature, SPELL_WARRIOR); break; case 2: DoScriptText(SAY_DRUID, m_creature); - DoCastSpellIfCan(m_creature,SPELL_DRUID); + DoCastSpellIfCan(m_creature, SPELL_DRUID); break; case 3: DoScriptText(SAY_PRIEST, m_creature); - DoCastSpellIfCan(m_creature,SPELL_PRIEST); + DoCastSpellIfCan(m_creature, SPELL_PRIEST); break; case 4: DoScriptText(SAY_PALADIN, m_creature); - DoCastSpellIfCan(m_creature,SPELL_PALADIN); + DoCastSpellIfCan(m_creature, SPELL_PALADIN); break; case 5: DoScriptText(SAY_SHAMAN, m_creature); - DoCastSpellIfCan(m_creature,SPELL_SHAMAN); + DoCastSpellIfCan(m_creature, SPELL_SHAMAN); break; case 6: DoScriptText(SAY_WARLOCK, m_creature); - DoCastSpellIfCan(m_creature,SPELL_WARLOCK); + DoCastSpellIfCan(m_creature, SPELL_WARLOCK); break; case 7: DoScriptText(SAY_HUNTER, m_creature); - DoCastSpellIfCan(m_creature,SPELL_HUNTER); + DoCastSpellIfCan(m_creature, SPELL_HUNTER); break; case 8: DoScriptText(SAY_ROGUE, m_creature); - DoCastSpellIfCan(m_creature,SPELL_ROGUE); + DoCastSpellIfCan(m_creature, SPELL_ROGUE); break; } - ClassCall_Timer = urand(35000, 40000); - }else ClassCall_Timer -= diff; + m_uiClassCallTimer = urand(35000, 40000); + } + else + m_uiClassCallTimer -= uiDiff; - //Phase3 begins when we are below X health - if (!Phase3 && m_creature->GetHealthPercent() < 20.0f) + // Phase3 begins when we are below X health + if (!m_bPhase3 && m_creature->GetHealthPercent() < 20.0f) { - Phase3 = true; + // todo revive all dead dragos as 14605 + 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); @@ -217,9 +276,10 @@ CreatureAI* GetAI_boss_nefarian(Creature* pCreature) void AddSC_boss_nefarian() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_nefarian"; - newscript->GetAI = &GetAI_boss_nefarian; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_nefarian"; + pNewScript->GetAI = &GetAI_boss_nefarian; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp index 41e6645af..82c249360 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,29 +17,36 @@ /* ScriptData SDName: Boss_Razorgore SD%Complete: 50 -SDComment: Needs additional review. Phase 1 NYI (Grethok the Controller) +SDComment: Needs additional review. Phase 1 NYI (Grethok the Controller), Conflagration needs core support SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" -//Razorgore Phase 2 Script +// Razorgore Phase 2 Script enum { - SAY_EGGS_BROKEN1 = -1469022, - SAY_EGGS_BROKEN2 = -1469023, - SAY_EGGS_BROKEN3 = -1469024, - SAY_DEATH = -1469025, - - SPELL_CLEAVE = 19632, - SPELL_WARSTOMP = 24375, - SPELL_FIREBALLVOLLEY = 22425, - SPELL_CONFLAGRATION = 23023 + SAY_EGGS_BROKEN_1 = -1469022, + SAY_EGGS_BROKEN_2 = -1469023, + SAY_EGGS_BROKEN_3 = -1469024, + SAY_DEATH = -1469025, + + SPELL_CLEAVE = 19632, + SPELL_WARSTOMP = 24375, + SPELL_FIREBALL_VOLLEY = 22425, + SPELL_CONFLAGRATION = 23023, }; struct MANGOS_DLL_DECL boss_razorgoreAI : public ScriptedAI { - boss_razorgoreAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_razorgoreAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; uint32 m_uiCleaveTimer; uint32 m_uiWarStompTimer; @@ -48,7 +55,7 @@ struct MANGOS_DLL_DECL boss_razorgoreAI : public ScriptedAI void Reset() { - m_uiCleaveTimer = 15000; //These times are probably wrong + m_uiCleaveTimer = 15000; // These times are probably wrong m_uiWarStompTimer = 35000; m_uiConflagrationTimer = 12000; m_uiFireballVolleyTimer = 7000; @@ -57,14 +64,25 @@ struct MANGOS_DLL_DECL boss_razorgoreAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); + // TODO Temporarily add this InstData setting, must be started with Phase 1 which is not yet implemented + if (m_pInstance) + m_pInstance->SetData(TYPE_RAZORGORE, IN_PROGRESS); } void JustDied(Unit* pKiller) { + if (m_pInstance) + m_pInstance->SetData(TYPE_RAZORGORE, DONE); + DoScriptText(SAY_DEATH, m_creature); } + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_RAZORGORE, FAIL); + } + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) @@ -73,17 +91,17 @@ struct MANGOS_DLL_DECL boss_razorgoreAI : public ScriptedAI // Cleave if (m_uiCleaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE); - m_uiCleaveTimer = urand(7000, 10000); + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) + m_uiCleaveTimer = urand(7000, 10000); } else m_uiCleaveTimer -= uiDiff; - // WarStomp + // War Stomp if (m_uiWarStompTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_WARSTOMP); - m_uiWarStompTimer = urand(15000, 25000); + if (DoCastSpellIfCan(m_creature, SPELL_WARSTOMP) == CAST_OK) + m_uiWarStompTimer = urand(15000, 25000); } else m_uiWarStompTimer -= uiDiff; @@ -91,8 +109,8 @@ struct MANGOS_DLL_DECL boss_razorgoreAI : public ScriptedAI // Fireball Volley if (m_uiFireballVolleyTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_FIREBALLVOLLEY); - m_uiFireballVolleyTimer = urand(12000, 15000); + if (DoCastSpellIfCan(m_creature, SPELL_FIREBALL_VOLLEY) == CAST_OK) + m_uiFireballVolleyTimer = urand(12000, 15000); } else m_uiFireballVolleyTimer -= uiDiff; @@ -100,23 +118,20 @@ struct MANGOS_DLL_DECL boss_razorgoreAI : public ScriptedAI // Conflagration if (m_uiConflagrationTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_CONFLAGRATION); - //We will remove this threat reduction and add an aura check. - - //if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) - //m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50); - - m_uiConflagrationTimer = 12000; + if (DoCastSpellIfCan(m_creature, SPELL_CONFLAGRATION) == CAST_OK) + m_uiConflagrationTimer = 12000; } else m_uiConflagrationTimer -= uiDiff; - // 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); - } + /* 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(); } @@ -129,10 +144,10 @@ CreatureAI* GetAI_boss_razorgore(Creature* pCreature) void AddSC_boss_razorgore() { - Script* newscript; - - newscript = new Script; - newscript->Name = "boss_razorgore"; - newscript->GetAI = &GetAI_boss_razorgore; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_razorgore"; + pNewScript->GetAI = &GetAI_boss_razorgore; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp index 4da306649..a08da6e62 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,216 +22,249 @@ SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" -#define SAY_LINE1 -1469026 -#define SAY_LINE2 -1469027 -#define SAY_LINE3 -1469028 -#define SAY_HALFLIFE -1469029 -#define SAY_KILLTARGET -1469030 +enum +{ + SAY_LINE_1 = -1469026, + SAY_LINE_2 = -1469027, + SAY_LINE_3 = -1469028, + SAY_HALFLIFE = -1469029, + SAY_KILLTARGET = -1469030, + SAY_NEFARIUS_CORRUPT = -1469006, //when he corrupts Vaelastrasz; possible to start the event by arrea trigger id = 3626 + + 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 +}; #define GOSSIP_ITEM "Start Event " -#define SPELL_ESSENCEOFTHERED 23513 -#define SPELL_FLAMEBREATH 23461 -#define SPELL_FIRENOVA 23462 -#define SPELL_TAILSWIPE 15847 -#define SPELL_BURNINGADRENALINE 23620 -#define SPELL_CLEAVE 20684 //Chain cleave is most likely named something different and contains a dummy effect - -struct MANGOS_DLL_DECL boss_vaelAI : public ScriptedAI +struct MANGOS_DLL_DECL boss_vaelastraszAI : public ScriptedAI { - boss_vaelAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_vaelastraszAI(Creature* pCreature) : ScriptedAI(pCreature) { - pCreature->setFaction(35); - pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); + + // TODO Research what actually is supposed to happen here + pCreature->setFaction(35); } - uint64 PlayerGUID; - uint32 SpeachTimer; - uint32 SpeachNum; - uint32 Cleave_Timer; - uint32 FlameBreath_Timer; - uint32 FireNova_Timer; - uint32 BurningAdrenalineCaster_Timer; - uint32 BurningAdrenalineTank_Timer; - uint32 TailSwipe_Timer; - bool HasYelled; - bool DoingSpeach; + ScriptedInstance* m_pInstance; + + uint64 m_uiPlayerGUID; + uint32 m_uiSpeachTimer; + uint32 m_uiSpeachNum; + uint32 m_uiCleaveTimer; + uint32 m_uiFlameBreathTimer; + uint32 m_uiFireNovaTimer; + uint32 m_uiBurningAdrenalineCasterTimer; + uint32 m_uiBurningAdrenalineTankTimer; + uint32 m_uiTailSweepTimer; + bool m_bHasYelled; + bool mbIsDoingSpeach; void Reset() { - PlayerGUID = 0; - SpeachTimer = 0; - SpeachNum = 0; - Cleave_Timer = 8000; //These times are probably wrong - FlameBreath_Timer = 11000; - BurningAdrenalineCaster_Timer = 15000; - BurningAdrenalineTank_Timer = 45000; - FireNova_Timer = 5000; - TailSwipe_Timer = 20000; - HasYelled = false; - DoingSpeach = false; + m_uiPlayerGUID = 0; + m_uiSpeachTimer = 0; + m_uiSpeachNum = 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; + mbIsDoingSpeach = false; } void BeginSpeach(Unit* target) { - //Stand up and begin speach - PlayerGUID = target->GetGUID(); + // Stand up and begin speach + m_uiPlayerGUID = target->GetGUID(); - //10 seconds - DoScriptText(SAY_LINE1, m_creature); + // 10 seconds + DoScriptText(SAY_LINE_1, m_creature); - SpeachTimer = 10000; - SpeachNum = 0; - DoingSpeach = true; + m_uiSpeachTimer = 10000; + m_uiSpeachNum = 0; + mbIsDoingSpeach = true; } - void KilledUnit(Unit *victim) + void KilledUnit(Unit* pVictim) { if (urand(0, 4)) return; - DoScriptText(SAY_KILLTARGET, m_creature, victim); + DoScriptText(SAY_KILLTARGET, m_creature, pVictim); } void Aggro(Unit* pWho) { - DoCastSpellIfCan(m_creature,SPELL_ESSENCEOFTHERED); - m_creature->SetInCombatWithZone(); + if (m_pInstance) + m_pInstance->SetData(TYPE_VAELASTRASZ, IN_PROGRESS); + + DoCastSpellIfCan(m_creature, SPELL_ESSENCE_OF_THE_RED); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_VAELASTRASZ, DONE); } - void UpdateAI(const uint32 diff) + void JustReachedHome() { - //Speach - if (DoingSpeach) + if (m_pInstance) + m_pInstance->SetData(TYPE_VAELASTRASZ, FAIL); + } + + void UpdateAI(const uint32 uiDiff) + { + // Speach + if (mbIsDoingSpeach) { - if (SpeachTimer < diff) + if (m_uiSpeachTimer < uiDiff) { - switch (SpeachNum) + switch (m_uiSpeachNum) { case 0: - //16 seconds till next line - DoScriptText(SAY_LINE2, m_creature); - SpeachTimer = 16000; - ++SpeachNum; + // 16 seconds till next line + DoScriptText(SAY_LINE_2, m_creature); + m_uiSpeachTimer = 16000; + ++m_uiSpeachNum; 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_LINE3, m_creature); - SpeachTimer = 10000; - ++SpeachNum; + // 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_uiSpeachTimer = 10000; + ++m_uiSpeachNum; break; case 2: m_creature->setFaction(103); m_creature->SetHealth(int(m_creature->GetMaxHealth()*.3)); - if (PlayerGUID) + if (m_uiPlayerGUID) { - if (Player* pPlayer = m_creature->GetMap()->GetPlayer(PlayerGUID)) + if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) AttackStart(pPlayer); - DoCastSpellIfCan(m_creature, SPELL_ESSENCEOFTHERED); + DoCastSpellIfCan(m_creature, SPELL_ESSENCE_OF_THE_RED); } - SpeachTimer = 0; - DoingSpeach = false; + m_uiSpeachTimer = 0; + mbIsDoingSpeach = false; break; } - }else SpeachTimer -= diff; + } + else + m_uiSpeachTimer -= uiDiff; } - //Return since we have no target + // 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 && !HasYelled) + if (m_creature->GetHealthPercent() < 15.0f && !m_bHasYelled) { DoScriptText(SAY_HALFLIFE, m_creature); - HasYelled = true; + m_bHasYelled = true; } - //Cleave_Timer - if (Cleave_Timer < diff) + // Cleave Timer + if (m_uiCleaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE); - Cleave_Timer = 15000; - }else Cleave_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) + m_uiCleaveTimer = 15000; + } + else + m_uiCleaveTimer -= uiDiff; - //FlameBreath_Timer - if (FlameBreath_Timer < diff) + // Flame Breath Timer + if (m_uiFlameBreathTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FLAMEBREATH); - FlameBreath_Timer = urand(4000, 8000); - }else FlameBreath_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FLAME_BREATH) == CAST_OK) + m_uiFlameBreathTimer = urand(4000, 8000); + } + else + m_uiFlameBreathTimer -= uiDiff; - //BurningAdrenalineCaster_Timer - if (BurningAdrenalineCaster_Timer < diff) + // Burning Adrenaline Caster Timer + if (m_uiBurningAdrenalineCasterTimer < uiDiff) { - Unit* target = NULL; + Unit* pTarget = NULL; + // TODO Target Selection must be improved! int i = 0 ; while (i < 3) // max 3 tries to get a random target with power_mana { ++i; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1);//not aggro leader - if (target) - if (target->getPowerType() == POWER_MANA) + pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); + if (pTarget) + if (pTarget->getPowerType() == POWER_MANA) i=3; } - if (target) // cast on self (see below) - target->CastSpell(target,SPELL_BURNINGADRENALINE,1); + if (pTarget) // cast on self (see below) + pTarget->CastSpell(pTarget, SPELL_BURNING_ADRENALINE, true); - BurningAdrenalineCaster_Timer = 15000; - }else BurningAdrenalineCaster_Timer -= diff; + m_uiBurningAdrenalineCasterTimer = 15000; + } + else + m_uiBurningAdrenalineCasterTimer -= uiDiff; - //BurningAdrenalineTank_Timer - if (BurningAdrenalineTank_Timer < diff) + // 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_BURNINGADRENALINE,1); + m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_BURNING_ADRENALINE, true); - BurningAdrenalineTank_Timer = 45000; - }else BurningAdrenalineTank_Timer -= diff; + m_uiBurningAdrenalineTankTimer = 45000; + } + else + m_uiBurningAdrenalineTankTimer -= uiDiff; - //FireNova_Timer - if (FireNova_Timer < diff) + // Fire Nova Timer + if (m_uiFireNovaTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FIRENOVA); - FireNova_Timer = 5000; - }else FireNova_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_FIRE_NOVA) == CAST_OK) + m_uiFireNovaTimer = 5000; + } + else + m_uiFireNovaTimer -= uiDiff; - //TailSwipe_Timer - if (TailSwipe_Timer < diff) + // Tail Sweep Timer + if (m_uiTailSweepTimer < uiDiff) { - //Only cast if we are behind - /*if (!m_creature->HasInArc(M_PI, m_creature->getVictim())) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_TAILSWIPE); - }*/ - - TailSwipe_Timer = 20000; - }else TailSwipe_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_TAIL_SWEEP) == CAST_OK) + m_uiTailSweepTimer = 20000; + } + else + m_uiTailSweepTimer -= uiDiff; DoMeleeAttackIfReady(); } }; -bool GossipSelect_boss_vael(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +bool GossipSelect_boss_vaelastrasz(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { - if (uiAction == GOSSIP_ACTION_INFO_DEF + 1) //Fight time + if (uiAction == GOSSIP_ACTION_INFO_DEF + 1) // Fight time { pPlayer->CLOSE_GOSSIP_MENU(); - if (boss_vaelAI* pVaelAI = dynamic_cast(pCreature->AI())) + if (boss_vaelastraszAI* pVaelAI = dynamic_cast(pCreature->AI())) pVaelAI->BeginSpeach((Unit*)pPlayer); } return true; } -bool GossipHello_boss_vael(Player* pPlayer, Creature* pCreature) +bool GossipHello_boss_vaelastrasz(Player* pPlayer, Creature* pCreature) { if (pCreature->isQuestGiver()) pPlayer->PrepareQuestMenu(pCreature->GetGUID()); @@ -242,18 +275,19 @@ bool GossipHello_boss_vael(Player* pPlayer, Creature* pCreature) return true; } -CreatureAI* GetAI_boss_vael(Creature* pCreature) +CreatureAI* GetAI_boss_vaelastrasz(Creature* pCreature) { - return new boss_vaelAI(pCreature); + return new boss_vaelastraszAI(pCreature); } -void AddSC_boss_vael() +void AddSC_boss_vaelastrasz() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_vaelastrasz"; - newscript->GetAI = &GetAI_boss_vael; - newscript->pGossipHello = &GossipHello_boss_vael; - newscript->pGossipSelect = &GossipSelect_boss_vael; - newscript->RegisterSelf(); + 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(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp index 1fab90629..d5f8f93f1 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,272 +22,215 @@ SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" -#define SAY_GAMESBEGIN_1 -1469004 -#define SAY_GAMESBEGIN_2 -1469005 -#define SAY_VAEL_INTRO -1469006 //when he corrupts Vaelastrasz - -#define GOSSIP_ITEM_1 "I've made no mistakes." -#define GOSSIP_ITEM_2 "You have lost your mind, Nefarius. You speak in riddles." -#define GOSSIP_ITEM_3 "Please do." - -#define CREATURE_BRONZE_DRAKANOID 14263 -#define CREATURE_BLUE_DRAKANOID 14261 -#define CREATURE_RED_DRAKANOID 14264 -#define CREATURE_GREEN_DRAKANOID 14262 -#define CREATURE_BLACK_DRAKANOID 14265 - -#define CREATURE_CHROMATIC_DRAKANOID 14302 -#define CREATURE_NEFARIAN 11583 - -#define ADD_X1 -7591.151855f -#define ADD_X2 -7514.598633f -#define ADD_Y1 -1204.051880f -#define ADD_Y2 -1150.448853f -#define ADD_Z1 476.800476f -#define ADD_Z2 476.796570f +enum +{ + SAY_GAMESBEGIN_1 = -1469004, + SAY_GAMESBEGIN_2 = -1469005, + + 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_SHADOWBOLT = 21077, + SPELL_FEAR = 26070, // shouldn't this be 22678? + // shadowbolt vollye = 22665 + // silence = 22666 -> silence a player + // shadow command = 22667 -> charm a player + // shadowblink = 22664, 22681 -> teleport around the room, possibly random + + FACTION_BLACK_DRAGON = 103, + FACTION_FRIENDLY = 35 +}; -#define NEF_X -7445.0f -#define NEF_Y -1332.0f -#define NEF_Z 536.0f +struct SpawnLocation +{ + float m_fX, m_fY, m_fZ; +}; -#define HIDE_X -7592.0f -#define HIDE_Y -1264.0f -#define HIDE_Z 481.0f +static const SpawnLocation aNefarianLocs[5] = +{ + {-7591.151f, -1204.051f, 476.800f}, // adds 1 & 2 + {-7514.598f, -1150.448f, 476.796f}, + {-7445.0f, -1332.0f, 536.0f}, // nefarian + {-7592.0f, -1264.0f, 481.0f}, // hide pos + {-7493.377f, -1258.85f, 478.30f}, // nefarian fly pos +}; -#define SPELL_SHADOWBOLT 21077 -#define SPELL_FEAR 26070 +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 into hiding and stop attacking -//If Nefarian despawns because he killed the players then this guy will EnterEvadeMode +//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 kill himself in his hiding place +//If nefarian dies then he will kill himself then he will be despawned in Nefarian script //To prevent players from doing the event twice struct MANGOS_DLL_DECL boss_victor_nefariusAI : public ScriptedAI { boss_victor_nefariusAI(Creature* pCreature) : ScriptedAI(pCreature) { - NefarianGUID = 0; + // 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(); Reset(); - srand(time(NULL)); - switch(urand(0, 19)) - { - case 0: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 1: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - case 2: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 3: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 4: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 5: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - case 6: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 7: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 8: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 9: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 10: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 11: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 12: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 13: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 14: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - case 15: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 16: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 17: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 18: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 19: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - } } - uint32 SpawnedAdds; - uint32 AddSpawnTimer; - uint32 ShadowBoltTimer; - uint32 FearTimer; - uint32 MindControlTimer; - uint32 ResetTimer; - uint32 DrakType1; - uint32 DrakType2; - uint64 NefarianGUID; - uint32 NefCheckTime; + ScriptedInstance* m_pInstance; + + uint32 m_uiSpawnedAdds; + uint32 m_uiAddSpawnTimer; + uint32 m_uiShadowBoltTimer; + uint32 m_uiFearTimer; + uint32 m_uiMindControlTimer; + uint32 m_uiResetTimer; + uint32 m_uiDrakeTypeOne; + uint32 m_uiDrakeTypeTwo; void Reset() { - SpawnedAdds = 0; - AddSpawnTimer = 10000; - ShadowBoltTimer = 5000; - FearTimer = 8000; - ResetTimer = 900000; //On official it takes him 15 minutes(900 seconds) to reset. We are only doing 1 minute to make testing easier - NefarianGUID = 0; - NefCheckTime = 2000; - - m_creature->SetUInt32Value(UNIT_NPC_FLAGS,1); - m_creature->setFaction(35); + m_uiSpawnedAdds = 0; + m_uiAddSpawnTimer = 10000; + m_uiShadowBoltTimer = 5000; + m_uiFearTimer = 8000; + m_uiResetTimer = 15 * MINUTE * IN_MILLISECONDS; + + // 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) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_NEFARIAN, IN_PROGRESS); + } + + void JustReachedHome() + { + m_creature->setFaction(FACTION_FRIENDLY); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + if (m_pInstance) + m_pInstance->SetData(TYPE_NEFARIAN, FAIL); } - void BeginEvent(Player* target) + void JustSummoned(Creature* pSummoned) { - DoScriptText(SAY_GAMESBEGIN_2, m_creature); + if (pSummoned->GetEntry() == NPC_NEFARIAN) + { + pSummoned->RemoveSplineFlag(SPLINEFLAG_WALKMODE); - //MaNGOS::Singleton::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().begin(); - /* - list ::iterator i = MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().begin(); + // 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->AddSplineFlag(SPLINEFLAG_FLYING); - for (i = MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().begin(); i != MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().end(); ++i) + // Let Nefarian fly towards combat area + pSummoned->GetMotionMaster()->MovePoint(1, aNefarianLocs[4].m_fX, aNefarianLocs[4].m_fY, aNefarianLocs[4].m_fZ); + } + else { - AttackStart((*i)); + ++m_uiSpawnedAdds; + + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); } - */ - m_creature->SetUInt32Value(UNIT_NPC_FLAGS,0); - m_creature->setFaction(103); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - AttackStart(target); + + pSummoned->SetRespawnDelay(7*DAY); } - void MoveInLineOfSight(Unit *who) + void SummonedMovementInform(Creature* pSummoned, uint32 uiMotionType, uint32 uiPointId) { - //We simply use this function to find players until we can use Map->GetPlayers() - - if (who && who->GetTypeId() == TYPEID_PLAYER && m_creature->IsHostileTo(who)) + // If Nefarian has reached combat area, let him attack + if (pSummoned->GetEntry() == NPC_NEFARIAN && uiMotionType == POINT_MOTION_TYPE && uiPointId == 1) { - //Add them to our threat list - m_creature->AddThreat(who); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); } } - void UpdateAI(const uint32 diff) + void SummonedCreatureJustDied(Creature* pSummoned) + { + // Despawn self when Nefarian is killed + if (pSummoned->GetEntry() == NPC_NEFARIAN) + m_creature->ForcedDespawn(); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Only do this if we haven't spawned nef yet - if (SpawnedAdds < 42) + // Only do this if we haven't spawned nef yet + if (m_uiSpawnedAdds < MAX_DRAKE_SUMMONS) { - //ShadowBoltTimer - if (ShadowBoltTimer < diff) - { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) - DoCastSpellIfCan(target,SPELL_SHADOWBOLT); - - ShadowBoltTimer = urand(3000, 10000); - }else ShadowBoltTimer -= diff; - - //FearTimer - if (FearTimer < diff) + // Shadowbolt Timer + if (m_uiShadowBoltTimer < uiDiff) { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) - DoCastSpellIfCan(target,SPELL_FEAR); - - FearTimer = urand(10000, 20000); - }else FearTimer -= diff; + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_SHADOWBOLT) == CAST_OK) + m_uiShadowBoltTimer = urand(3000, 10000); + } + } + else + m_uiShadowBoltTimer -= uiDiff; - //Add spawning mechanism - if (AddSpawnTimer < diff) + // Fear Timer + if (m_uiFearTimer < uiDiff) { - //Spawn 2 random types of creatures at the 2 locations - uint32 CreatureID; - Creature* Spawned = NULL; - Unit* target = NULL; - - //1 in 3 chance it will be a chromatic - if (!urand(0, 2)) - CreatureID = CREATURE_CHROMATIC_DRAKANOID; - else CreatureID = DrakType1; - - ++SpawnedAdds; - - //Spawn creature and force it to start attacking a random target - Spawned = m_creature->SummonCreature(CreatureID,ADD_X1,ADD_Y1,ADD_Z1,5.000f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target && Spawned) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - Spawned->AI()->AttackStart(target); - Spawned->setFaction(103); + if (DoCastSpellIfCan(pTarget, SPELL_FEAR) == CAST_OK) + m_uiFearTimer = urand(10000, 20000); } + } + else + m_uiFearTimer -= uiDiff; - //1 in 3 chance it will be a chromatic - if (!urand(0, 2)) - CreatureID = CREATURE_CHROMATIC_DRAKANOID; - else CreatureID = DrakType2; + // Add spawning mechanism + if (m_uiAddSpawnTimer < uiDiff) + { + //Spawn 2 random types of creatures at the 2 locations + uint32 uiCreatureId = 0; - ++SpawnedAdds; + // 1 in 3 chance it will be a chromatic + uiCreatureId = urand(0, 2) ? m_uiDrakeTypeOne : NPC_CHROMATIC_DRAKANOID; + m_creature->SummonCreature(uiCreatureId, aNefarianLocs[0].m_fX, aNefarianLocs[0].m_fY, aNefarianLocs[0].m_fZ, 5.000f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*MINUTE*IN_MILLISECONDS); - target = NULL; - Spawned = NULL; - Spawned = m_creature->SummonCreature(CreatureID,ADD_X2,ADD_Y2,ADD_Z2,5.000,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target && Spawned) - { - Spawned->AI()->AttackStart(target); - Spawned->setFaction(103); - } + // 1 in 3 chance it will be a chromatic + uiCreatureId = urand(0, 2) ? m_uiDrakeTypeTwo : NPC_CHROMATIC_DRAKANOID; + m_creature->SummonCreature(uiCreatureId, aNefarianLocs[1].m_fX, aNefarianLocs[1].m_fY, aNefarianLocs[1].m_fZ, 5.000, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*MINUTE*IN_MILLISECONDS); - //Begin phase 2 by spawning Nefarian and what not - if (SpawnedAdds >= 42) + //Begin phase 2 by spawning Nefarian + if (m_uiSpawnedAdds >= MAX_DRAKE_SUMMONS) { //Teleport Victor Nefarius way out of the map //MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->CreatureRelocation(m_creature,0,0,-5000,0); @@ -296,46 +239,25 @@ struct MANGOS_DLL_DECL boss_victor_nefariusAI : public ScriptedAI m_creature->InterruptNonMeleeSpells(false); //Root self - DoCastSpellIfCan(m_creature,33356); + DoCastSpellIfCan(m_creature, 33356, CAST_TRIGGERED); //Make super invis - DoCastSpellIfCan(m_creature,8149); + if (m_creature->GetVisibility() != VISIBILITY_OFF) + m_creature->SetVisibility(VISIBILITY_OFF); + // Do not teleport him away, this is not needed (invisible and rooted) //Teleport self to a hiding spot - m_creature->NearTeleportTo(HIDE_X, HIDE_Y, HIDE_Z, 0.0f); - - //Spawn nef and have him attack a random target - Creature* Nefarian = m_creature->SummonCreature(CREATURE_NEFARIAN,NEF_X,NEF_Y,NEF_Z,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000); - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - - if (target && Nefarian) - { - Nefarian->AI()->AttackStart(target); - Nefarian->setFaction(103); - NefarianGUID = Nefarian->GetGUID(); - } - else error_log("SD2: Blackwing Lair: Unable to spawn nefarian properly."); - } + //m_creature->NearTeleportTo(aNefarianLocs[3].m_fX, aNefarianLocs[3].m_fY, aNefarianLocs[3].m_fZ, 0.0f); - AddSpawnTimer = 4000; - }else AddSpawnTimer -= diff; - } - else if (NefarianGUID) - { - if (NefCheckTime < diff) - { - Creature* pNefarian = m_creature->GetMap()->GetCreature(NefarianGUID); - - //If nef is dead then we die to so the players get out of combat - //and cannot repeat the event - if (!pNefarian || !pNefarian->isAlive()) - { - NefarianGUID = 0; - m_creature->ForcedDespawn(); + // 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); } - NefCheckTime = 2000; - }else NefCheckTime -= diff; + m_uiAddSpawnTimer = 4000; + } + else + m_uiAddSpawnTimer -= uiDiff; } } }; @@ -347,8 +269,8 @@ CreatureAI* GetAI_boss_victor_nefarius(Creature* pCreature) bool GossipHello_boss_victor_nefarius(Player* pPlayer, Creature* pCreature) { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1 , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(7134, pCreature->GetGUID()); + 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->GetGUID()); return true; } @@ -357,18 +279,23 @@ bool GossipSelect_boss_victor_nefarius(Player* pPlayer, Creature* pCreature, uin switch(uiAction) { case GOSSIP_ACTION_INFO_DEF+1: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - pPlayer->SEND_GOSSIP_MENU(7198, pCreature->GetGUID()); + 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->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+2: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - pPlayer->SEND_GOSSIP_MENU(7199, pCreature->GetGUID()); + 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->GetGUID()); + DoScriptText(SAY_GAMESBEGIN_1, pCreature); break; case GOSSIP_ACTION_INFO_DEF+3: pPlayer->CLOSE_GOSSIP_MENU(); - DoScriptText(SAY_GAMESBEGIN_1, pCreature); - if (boss_victor_nefariusAI* pNefAI = dynamic_cast(pCreature->AI())) - pNefAI->BeginEvent(pPlayer); + DoScriptText(SAY_GAMESBEGIN_2, pCreature); + // remove gossip, set hostile and attack + pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->setFaction(FACTION_BLACK_DRAGON); + pCreature->CastSpell(pCreature, SPELL_NEFARIUS_BARRIER, false); + pCreature->AI()->AttackStart(pPlayer); break; } return true; @@ -376,12 +303,12 @@ bool GossipSelect_boss_victor_nefarius(Player* pPlayer, Creature* pCreature, uin void AddSC_boss_victor_nefarius() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_victor_nefarius"; - newscript->GetAI = &GetAI_boss_victor_nefarius; - newscript->pGossipHello = &GossipHello_boss_victor_nefarius; - newscript->pGossipSelect = &GossipSelect_boss_victor_nefarius; - newscript->RegisterSelf(); + 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(); } diff --git a/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp b/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp index cdea07be0..a8b9a3f93 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,3 +22,173 @@ SDCategory: Blackwing Lair EndScriptData */ #include "precompiled.h" +#include "blackwing_lair.h" + + +instance_blackwing_lair::instance_blackwing_lair(Map* pMap) : ScriptedInstance(pMap), + m_uiRazorgoreEnterDoorGUID(0), + m_uiRazorgoreExitDoorGUID(0), + m_uiVaelastraszDoorGUID(0), + m_uiLashlayerDoorGUID(0), + m_uiChromaggusEnterDoorGUID(0), + m_uiChromaggusExitDoorGUID(0), + m_uiChromaggusSideDoorGUID(0), + m_uiNefarianDoorGUID(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::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) + { + case GO_DOOR_RAZORGORE_ENTER: + m_uiRazorgoreEnterDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_RAZORGORE_EXIT: + m_uiRazorgoreExitDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_RAZORGORE] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOOR_NEFARIAN: + m_uiNefarianDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_CHROMAGGUS_ENTER: + m_uiChromaggusEnterDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_CHROMAGGUS_SIDE: + m_uiChromaggusSideDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_CHROMAGGUS_EXIT: + m_uiChromaggusExitDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_CHROMAGGUS] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOOR_VAELASTRASZ: + m_uiVaelastraszDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_VAELASTRASZ] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOOR_LASHLAYER: + m_uiLashlayerDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_LASHLAYER] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + } +} + +void instance_blackwing_lair::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) + { + case TYPE_RAZORGORE: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiRazorgoreEnterDoorGUID); + if (uiData == DONE) + DoUseDoorOrButton(m_uiRazorgoreExitDoorGUID); + break; + case TYPE_VAELASTRASZ: + m_auiEncounter[uiType] = uiData; + // Prevent the players from running back to the first room + DoUseDoorOrButton(m_uiRazorgoreExitDoorGUID); + if (uiData == DONE) + DoUseDoorOrButton(m_uiVaelastraszDoorGUID); + break; + case TYPE_LASHLAYER: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiLashlayerDoorGUID); + break; + case TYPE_FIREMAW: + case TYPE_EBONROC: + case TYPE_FLAMEGOR: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_CHROMAGGUS: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiChromaggusEnterDoorGUID); + if (uiData == DONE) + DoUseDoorOrButton(m_uiChromaggusExitDoorGUID); + break; + case TYPE_NEFARIAN: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiNefarianDoorGUID); + 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) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + + return 0; +} + +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(); +} diff --git a/scripts/eastern_kingdoms/blasted_lands.cpp b/scripts/eastern_kingdoms/blasted_lands.cpp index c641d2d22..e7d115cb8 100644 --- a/scripts/eastern_kingdoms/blasted_lands.cpp +++ b/scripts/eastern_kingdoms/blasted_lands.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/boss_kruul.cpp b/scripts/eastern_kingdoms/boss_kruul.cpp index 1c1c9a973..ab0159eb5 100644 --- a/scripts/eastern_kingdoms/boss_kruul.cpp +++ b/scripts/eastern_kingdoms/boss_kruul.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/burning_steppes.cpp b/scripts/eastern_kingdoms/burning_steppes.cpp index 02d73c7ed..fbd6263dc 100644 --- a/scripts/eastern_kingdoms/burning_steppes.cpp +++ b/scripts/eastern_kingdoms/burning_steppes.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/deadmines/deadmines.cpp b/scripts/eastern_kingdoms/deadmines/deadmines.cpp index 0cb977fb3..d3110f03e 100644 --- a/scripts/eastern_kingdoms/deadmines/deadmines.cpp +++ b/scripts/eastern_kingdoms/deadmines/deadmines.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,30 +16,284 @@ /* ScriptData SDName: Deadmines -SD%Complete: 90 -SDComment: Contains GO for event at end door +SD%Complete: 75 +SDComment: Contains boss_mr_smite and GO for event at end door SDCategory: Deadmines EndScriptData */ #include "precompiled.h" #include "deadmines.h" -bool GOHello_go_door_lever_dm(Player* pPlayer, GameObject* pGo) +/*###### +## boss_mr_smite +######*/ + +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, + SPELL_SMITE_STOMP = 6432, + SPELL_SMITE_HAMMER = 6436, + SPELL_THRASH = 12787, // unclear, possible 3417 (only 10% proc chance) + + 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 MANGOS_DLL_DECL boss_mr_smiteAI : public ScriptedAI +{ + boss_mr_smiteAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + + uint32 m_uiPhase; + uint32 m_uiEquipTimer; + uint32 m_uiSlamTimer; + + void Reset() + { + 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) + { + if (m_creature->getVictim()) + return; + + if (m_uiPhase > PHASE_3) + return; + + AttackStart(pAttacker); + } + + void AttackStart(Unit* pWho) + { + 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) + { + 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->instance->GetGameObject(pInstance->GetData64(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 = 5000; + + Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0); + + if (!pVictim) + { + EnterEvadeMode(); + return; + } + + // Takes longer to run further distance. Not accurate, but will probably be sufficient for most cases + if (m_creature->IsWithinDistInMap(pVictim, ATTACK_DISTANCE)) + m_uiEquipTimer -= 1000; + else if (m_creature->IsWithinDistInMap(pVictim, 2*ATTACK_DISTANCE)) + m_uiEquipTimer -= 2000; + else + m_uiEquipTimer -= 3000; + } + + 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) + { + 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(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; + + 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); +} + +bool GOUse_go_door_lever_dm(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); if (!pInstance) return false; - GameObject* pGoDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_DEFIAS_DOOR)); + GameObject* pGoDoor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_IRON_CLAD_DOOR)); - if (pGoDoor && pGoDoor->GetGoState() == 1) + if (pGoDoor && pGoDoor->GetGoState() == GO_STATE_READY) return false; return true; } -bool GOHello_go_defias_cannon(Player* pPlayer, GameObject* pGo) +bool GOUse_go_defias_cannon(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -57,13 +311,18 @@ void AddSC_deadmines() { Script *newscript; + newscript = new Script; + newscript->Name = "boss_mr_smite"; + newscript->GetAI = &GetAI_boss_mr_smite; + newscript->RegisterSelf(); + newscript = new Script; newscript->Name = "go_door_lever_dm"; - newscript->pGOHello = &GOHello_go_door_lever_dm; + newscript->pGOUse = &GOUse_go_door_lever_dm; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "go_defias_cannon"; - newscript->pGOHello = &GOHello_go_defias_cannon; + newscript->pGOUse = &GOUse_go_defias_cannon; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/deadmines/deadmines.h b/scripts/eastern_kingdoms/deadmines/deadmines.h index df5b91d19..b75325bc8 100644 --- a/scripts/eastern_kingdoms/deadmines/deadmines.h +++ b/scripts/eastern_kingdoms/deadmines/deadmines.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,19 +7,32 @@ enum { - MAX_ENCOUNTER = 1, + MAX_ENCOUNTER = 4, TYPE_DEFIAS_ENDDOOR = 1, - DATA_DEFIAS_DOOR = 2, + TYPE_RHAHKZOR = 2, + TYPE_SNEED = 3, + TYPE_GILNID = 4, INST_SAY_ALARM1 = -1036000, INST_SAY_ALARM2 = -1036001, + GO_FACTORY_DOOR = 13965, // rhahk'zor + GO_FOUNDRY_DOOR = 16399, // gilnid + GO_MAST_ROOM_DOOR = 16400, // sneed + GO_HEAVY_DOOR_1 = 17153, // to sneed + GO_HEAVY_DOOR_2 = 17154, // to gilnid GO_DOOR_LEVER = 101833, - GO_IRON_CLAD = 16397, + GO_IRON_CLAD_DOOR = 16397, GO_DEFIAS_CANNON = 16398, + GO_SMITE_CHEST = 144111, // use to get correct location of mr.smites equipment changes + + NPC_RHAHKZOR = 644, + NPC_SNEED = 643, + NPC_GILNID = 1763, NPC_MR_SMITE = 646, - NPC_PIRATE = 657 + NPC_PIRATE = 657, + NPC_SQUALLSHAPER = 1732, }; #endif diff --git a/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp b/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp index 4683b457c..c95c0aece 100644 --- a/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp +++ b/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -30,8 +30,12 @@ struct MANGOS_DLL_DECL instance_deadmines : public ScriptedInstance uint32 m_auiEncounter[MAX_ENCOUNTER]; + uint64 m_uiFactoryDoorGUID; + uint64 m_uiMastRoomDoorGUID; + uint64 m_uiFoundryDoorGUID; uint64 m_uiIronCladGUID; uint64 m_uiCannonGUID; + uint64 m_uiSmiteChestGUID; uint64 m_uiSmiteGUID; uint32 m_uiIronDoor_Timer; @@ -41,8 +45,12 @@ struct MANGOS_DLL_DECL instance_deadmines : public ScriptedInstance { memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + m_uiFactoryDoorGUID = 0; + m_uiMastRoomDoorGUID = 0; + m_uiFoundryDoorGUID = 0; m_uiIronCladGUID = 0; m_uiCannonGUID = 0; + m_uiSmiteChestGUID = 0; m_uiSmiteGUID = 0; m_uiIronDoor_Timer = 0; @@ -57,41 +65,127 @@ struct MANGOS_DLL_DECL instance_deadmines : public ScriptedInstance void OnObjectCreate(GameObject* pGo) { - if (pGo->GetEntry() == GO_IRON_CLAD) - m_uiIronCladGUID = pGo->GetGUID(); + switch(pGo->GetEntry()) + { + case GO_FACTORY_DOOR: + m_uiFactoryDoorGUID = pGo->GetGUID(); + + if (GetData(TYPE_RHAHKZOR) == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + + break; + case GO_MAST_ROOM_DOOR: + m_uiMastRoomDoorGUID = pGo->GetGUID(); + + if (GetData(TYPE_SNEED) == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); - if (pGo->GetEntry() == GO_DEFIAS_CANNON) - m_uiCannonGUID = pGo->GetGUID(); + break; + case GO_FOUNDRY_DOOR: + m_uiFoundryDoorGUID = pGo->GetGUID(); + + if (GetData(TYPE_GILNID) == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + + break; + case GO_IRON_CLAD_DOOR: + m_uiIronCladGUID = pGo->GetGUID(); + break; + case GO_DEFIAS_CANNON: + m_uiCannonGUID = pGo->GetGUID(); + break; + case GO_SMITE_CHEST: + m_uiSmiteChestGUID = pGo->GetGUID(); + break; + } + } + + void 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 SetData(uint32 uiType, uint32 uiData) { - if (uiType == TYPE_DEFIAS_ENDDOOR) + switch(uiType) { - if (uiData == IN_PROGRESS) + case TYPE_RHAHKZOR: + { + if (uiData == DONE) + DoUseDoorOrButton(m_uiFactoryDoorGUID); + + m_auiEncounter[1] = uiData; + break; + } + case TYPE_SNEED: { - if (GameObject* pGo = instance->GetGameObject(m_uiIronCladGUID)) + if (uiData == DONE) + DoUseDoorOrButton(m_uiMastRoomDoorGUID); + + m_auiEncounter[2] = uiData; + break; + } + case TYPE_GILNID: + { + if (uiData == DONE) + DoUseDoorOrButton(m_uiFoundryDoorGUID); + + m_auiEncounter[3] = uiData; + break; + } + case TYPE_DEFIAS_ENDDOOR: + { + if (uiData == IN_PROGRESS) { - pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - m_uiIronDoor_Timer = 3000; + if (GameObject* pGo = instance->GetGameObject(m_uiIronCladGUID)) + { + pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + m_uiIronDoor_Timer = 3000; + } } + m_auiEncounter[0] = uiData; + break; } - m_auiEncounter[0] = uiData; } } uint32 GetData(uint32 uiType) { - if (uiType == TYPE_DEFIAS_ENDDOOR) - return m_auiEncounter[0]; + switch(uiType) + { + case TYPE_DEFIAS_ENDDOOR: + return m_auiEncounter[0]; + case TYPE_RHAHKZOR: + return m_auiEncounter[1]; + case TYPE_SNEED: + return m_auiEncounter[2]; + case TYPE_GILNID: + return m_auiEncounter[3]; + } return 0; } uint64 GetData64(uint32 uiData) { - if (uiData == DATA_DEFIAS_DOOR) - return m_uiIronCladGUID; + switch(uiData) + { + case GO_IRON_CLAD_DOOR: + return m_uiIronCladGUID; + case GO_SMITE_CHEST: + return m_uiSmiteChestGUID; + } return 0; } @@ -112,13 +206,27 @@ struct MANGOS_DLL_DECL instance_deadmines : public ScriptedInstance ++m_uiDoor_Step; break; case 1: - if (Creature* pi1 = pMrSmite->SummonCreature(NPC_PIRATE, 93.68f, -678.63f, 7.71f, 2.09f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 1800000)) - pi1->GetMotionMaster()->MovePoint(0, 100.11f, -670.65f, 7.42f); - if (Creature* pi2 = pMrSmite->SummonCreature(NPC_PIRATE, 102.63f, -685.07f, 7.42f, 1.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 1800000)) - pi2->GetMotionMaster()->MovePoint(0, 100.11f, -670.65f, 7.42f); + { + if (GameObject* pDoor = instance->GetGameObject(m_uiIronCladGUID)) + { + // should be static spawns, fetch the closest ones at the pier + if (Creature* pi1 = GetClosestCreatureWithEntry(pDoor, NPC_PIRATE, 40.0f)) + { + pi1->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pi1->GetMotionMaster()->MovePoint(0, pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ()); + } + + if (Creature* pi2 = GetClosestCreatureWithEntry(pDoor, NPC_SQUALLSHAPER, 40.0f)) + { + pi2->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pi2->GetMotionMaster()->MovePoint(0, pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ()); + } + } + ++m_uiDoor_Step; m_uiIronDoor_Timer = 10000; break; + } case 2: DoScriptText(INST_SAY_ALARM2,pMrSmite); m_uiDoor_Step = 0; diff --git a/scripts/eastern_kingdoms/dun_morogh.cpp b/scripts/eastern_kingdoms/dun_morogh.cpp index ac2f7c64b..8b024548c 100644 --- a/scripts/eastern_kingdoms/dun_morogh.cpp +++ b/scripts/eastern_kingdoms/dun_morogh.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/eastern_plaguelands.cpp b/scripts/eastern_kingdoms/eastern_plaguelands.cpp index 590206645..842209bc3 100644 --- a/scripts/eastern_kingdoms/eastern_plaguelands.cpp +++ b/scripts/eastern_kingdoms/eastern_plaguelands.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/elwynn_forest.cpp b/scripts/eastern_kingdoms/elwynn_forest.cpp index e4ffb29a2..74ed77726 100644 --- a/scripts/eastern_kingdoms/elwynn_forest.cpp +++ b/scripts/eastern_kingdoms/elwynn_forest.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/eversong_woods.cpp b/scripts/eastern_kingdoms/eversong_woods.cpp index 0f56491ec..a6eda8306 100644 --- a/scripts/eastern_kingdoms/eversong_woods.cpp +++ b/scripts/eastern_kingdoms/eversong_woods.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: Eversong_Woods SD%Complete: 100 -SDComment: Quest support: 8483, 8488, 9686 +SDComment: Quest support: 8483, 8488, 8490, 9686 SDCategory: Eversong Woods EndScriptData */ @@ -26,6 +26,7 @@ npc_kelerun_bloodmourn go_harbinger_second_trial npc_prospector_anvilward npc_apprentice_mirveda +npc_infused_crystal EndContentData */ #include "precompiled.h" @@ -229,7 +230,7 @@ bool QuestAccept_npc_kelerun_bloodmourn(Player* pPlayer, Creature* pCreature, co return true; } -bool GOHello_go_harbinger_second_trial(Player* pPlayer, GameObject* pGO) +bool GOUse_go_harbinger_second_trial(Player* pPlayer, GameObject* pGO) { if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER) { @@ -434,6 +435,106 @@ CreatureAI* GetAI_npc_apprentice_mirvedaAI(Creature* pCreature) return new npc_apprentice_mirvedaAI (pCreature); } +/*###### +## npc_infused_crystal +######*/ + +enum +{ + NPC_ENRAGED_WRATH = 17086, + QUEST_POWERING_OUR_DEFENSES = 8490, + INFUSED_CRYSTAL_EMOTE = -1999811 +}; + +float fEnragedWrathPosition[3][4] = +{ + {8259.375977f, -7202.288574f, 139.287430f, 5.0f}, + {8255.425781f, -7222.026367f, 139.607162f, 5.0f}, + {8267.902344f, -7193.510742f, 139.430374f, 5.0f} +}; + +struct MANGOS_DLL_DECL npc_infused_crystalAI : public ScriptedAI +{ + npc_infused_crystalAI(Creature* pCreature) : ScriptedAI(pCreature) + { + SetCombatMovement(false); + Reset(); + } + + uint32 m_uiQuestTimer; + uint32 m_uiSpawnTimer; + uint64 m_uiPlayerGUID; + + bool bCompleted; + + void Reset() + { + m_uiQuestTimer = 60000; + m_uiSpawnTimer = 1000; + m_uiPlayerGUID = 0; + bCompleted = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (pWho->GetTypeId() != TYPEID_PLAYER) + return; + Player* pPlayer = (Player*)pWho; + + if (pPlayer->GetQuestStatus(QUEST_POWERING_OUR_DEFENSES) != QUEST_STATUS_INCOMPLETE) + return; + + m_uiPlayerGUID = pPlayer->GetGUID(); + } + + void Aggro(Unit* pWho){} + + void JustDied(Unit* pWho) + { + if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) + if (pPlayer->GetQuestStatus(QUEST_POWERING_OUR_DEFENSES) == QUEST_STATUS_INCOMPLETE) + pPlayer->FailQuest(QUEST_POWERING_OUR_DEFENSES); + } + + void UpdateAI(const uint32 uiDiff) + { + if (bCompleted) + return; + + if (m_uiSpawnTimer < uiDiff) + { + for (uint8 i = 0; i < 3; ++i) + { + if (Creature* pEnragedWrath = m_creature->SummonCreature(NPC_ENRAGED_WRATH, fEnragedWrathPosition[i][0], fEnragedWrathPosition[i][1], fEnragedWrathPosition[i][2], fEnragedWrathPosition[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) + { + pEnragedWrath->AI()->AttackStart(m_creature); + } + } + m_uiSpawnTimer = 40000; + } + else + m_uiSpawnTimer -= uiDiff; + + if (m_uiQuestTimer < uiDiff) + { + if(Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) + { + pPlayer->KilledMonsterCredit(m_creature->GetEntry()); + DoScriptText(INFUSED_CRYSTAL_EMOTE , m_creature); + m_creature->ForcedDespawn(5000); + } + bCompleted = true; + } + else + m_uiQuestTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_infused_crystal(Creature* pCreature) +{ + return new npc_infused_crystalAI (pCreature); +} + void AddSC_eversong_woods() { Script* pNewScript; @@ -441,12 +542,12 @@ void AddSC_eversong_woods() pNewScript = new Script; pNewScript->Name = "npc_kelerun_bloodmourn"; pNewScript->GetAI = &GetAI_npc_kelerun_bloodmourn; - pNewScript->pQuestAccept = &QuestAccept_npc_kelerun_bloodmourn; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_kelerun_bloodmourn; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_harbinger_second_trial"; - pNewScript->pGOHello = &GOHello_go_harbinger_second_trial; + pNewScript->pGOUse = &GOUse_go_harbinger_second_trial; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -458,7 +559,12 @@ void AddSC_eversong_woods() pNewScript = new Script; pNewScript->Name = "npc_apprentice_mirveda"; - pNewScript->GetAI = GetAI_npc_apprentice_mirvedaAI; - pNewScript->pQuestAccept = &QuestAccept_unexpected_results; + 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_crystal; pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/ghostlands.cpp b/scripts/eastern_kingdoms/ghostlands.cpp index 573184283..bbe586029 100644 --- a/scripts/eastern_kingdoms/ghostlands.cpp +++ b/scripts/eastern_kingdoms/ghostlands.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -263,7 +263,7 @@ void AddSC_ghostlands() newscript = new Script; newscript->Name = "npc_ranger_lilatha"; newscript->GetAI = &GetAI_npc_ranger_lilathaAI; - newscript->pQuestAccept = &QuestAccept_npc_ranger_lilatha; + newscript->pQuestAcceptNPC = &QuestAccept_npc_ranger_lilatha; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/eastern_kingdoms/gnomeregan/boss_thermaplugg.cpp b/scripts/eastern_kingdoms/gnomeregan/boss_thermaplugg.cpp index ef785322f..f1b6ffde8 100644 --- a/scripts/eastern_kingdoms/gnomeregan/boss_thermaplugg.cpp +++ b/scripts/eastern_kingdoms/gnomeregan/boss_thermaplugg.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -235,7 +235,7 @@ bool EffectDummyCreature_spell_boss_thermaplugg(Unit* pCaster, uint32 uiSpellId, return true; } -bool GOHello_go_gnomeface_button(Player* pPlayer, GameObject* pGo) +bool GOUse_go_gnomeface_button(Player* pPlayer, GameObject* pGo) { instance_gnomeregan* pInstance = (instance_gnomeregan*)pPlayer->GetInstanceData(); if (!pInstance) @@ -262,11 +262,11 @@ void AddSC_boss_thermaplugg() pNewScript = new Script; pNewScript->Name = "boss_thermaplugg"; pNewScript->GetAI = &GetAI_boss_thermaplugg; - pNewScript->pEffectDummyCreature = &EffectDummyCreature_spell_boss_thermaplugg; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_spell_boss_thermaplugg; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_gnomeface_button"; - pNewScript->pGOHello = &GOHello_go_gnomeface_button; + pNewScript->pGOUse = &GOUse_go_gnomeface_button; pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp b/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp index 981678bb9..55823c2de 100644 --- a/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp +++ b/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,7 +16,7 @@ /* ScriptData SDName: gnomeregan -SD%Complete: 80 +SD%Complete: 100 SDComment: Grubbis Encounter SDCategory: Gnomeregan EndScriptData */ @@ -42,7 +42,7 @@ enum SAY_INTRO_4 = -1090004, SAY_LOOK_1 = -1090005, SAY_HEAR_1 = -1090006, - SAY_AGGRO = -1090007, + SAY_AGGRO_1 = -1090007, SAY_CHARGE_1 = -1090008, SAY_CHARGE_2 = -1090009, SAY_BLOW_1_10 = -1090010, @@ -59,6 +59,8 @@ enum SAY_BLOW_2 = -1090021, SAY_FINISH_2 = -1090022, + SAY_AGGRO_2 = -1090028, + SAY_GRUBBIS_SPAWN = -1090023, GOSSIP_ITEM_START = -3090000, @@ -75,6 +77,562 @@ enum NPC_CAVERNDEEP_AMBUSHER = 6207 }; +struct sSummonInformation +{ + uint32 uiPosition, uiEntry; + float fX, fY, fZ, fO; +}; + +static const sSummonInformation asSummonInfo[MAX_SUMMON_POSITIONS] = +{ + // Entries must be sorted by pack + // First Cave-In + {1, NPC_CAVERNDEEP_AMBUSHER, -566.8114f, -111.7036f, -151.1891f, 5.986479f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -568.5875f, -113.7559f, -151.1869f, 0.06981317f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -570.2333f, -116.8126f, -151.2272f, 0.296706f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -550.6331f, -108.7592f, -153.965f, 0.8901179f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -558.9717f, -115.0669f, -151.8799f, 0.5235988f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -556.6719f, -112.0526f, -152.8255f, 0.4886922f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -552.6419f, -113.4385f, -153.0727f, 0.8028514f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -549.1248f, -112.1469f, -153.7987f, 0.7504916f}, + {1, NPC_CAVERNDEEP_AMBUSHER, -546.7435f, -112.3051f, -154.2225f, 0.9250245f}, + {2, NPC_CAVERNDEEP_AMBUSHER, -571.4071f, -108.7721f, -150.6547f, 5.480334f}, + {2, NPC_CAVERNDEEP_AMBUSHER, -573.797f, -106.5265f, -150.4106f, 5.550147f}, + {2, NPC_CAVERNDEEP_AMBUSHER, -576.3784f, -108.0483f, -150.4227f, 5.585053f}, + {2, NPC_CAVERNDEEP_AMBUSHER, -576.697f, -111.7413f, -150.6484f, 5.759586f}, + {3, NPC_CAVERNDEEP_AMBUSHER, -571.3161f, -114.4412f, -151.0931f, 6.021386f}, + {3, NPC_CAVERNDEEP_AMBUSHER, -570.3127f, -111.7964f, -151.04f, 2.042035f}, + + // Second Cave-In + {4, NPC_CAVERNDEEP_AMBUSHER, -474.5954f, -104.074f, -146.0483f, 2.338741f}, + {4, NPC_CAVERNDEEP_AMBUSHER, -477.9396f, -108.6563f, -145.7394f, 1.553343f}, + {4, NPC_CAVERNDEEP_AMBUSHER, -475.6625f, -97.12168f, -146.5959f, 1.291544f}, + {4, NPC_CAVERNDEEP_AMBUSHER, -480.5233f, -88.40702f, -146.3772f, 3.001966f}, + {5, NPC_CAVERNDEEP_AMBUSHER, -474.2943f, -105.2212f, -145.9747f, 2.251475f}, + {5, NPC_CAVERNDEEP_AMBUSHER, -481.1831f, -101.4225f, -146.377f, 2.146755f}, + {5, NPC_CAVERNDEEP_BURROWER, -475.0871f, -100.016f, -146.4382f, 2.303835f}, + {5, NPC_CAVERNDEEP_AMBUSHER, -478.8562f, -106.9321f, -145.8533f, 1.658063f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -473.8762f, -107.4022f, -145.838f, 2.024582f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -490.5134f, -92.72843f, -148.0954f, 3.054326f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -491.401f, -88.25341f, -148.0358f, 3.560472f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -479.1431f, -106.227f, -145.9097f, 1.727876f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -475.3185f, -101.4804f, -146.2717f, 2.234021f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -485.1559f, -89.57419f, -146.9299f, 3.071779f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -482.2516f, -96.80614f, -146.6596f, 2.303835f}, + {6, NPC_CAVERNDEEP_AMBUSHER, -477.9874f, -92.82047f, -146.6944f, 3.124139f}, + + // Grubbis and add + {7, NPC_GRUBBIS, -476.3761f, -108.1901f, -145.7763f, 1.919862f}, + {7, NPC_CHOMPER, -473.1326f, -103.0901f, -146.1155f, 2.042035f} +}; + +struct MANGOS_DLL_DECL npc_blastmaster_emi_shortfuseAI : public npc_escortAI +{ + npc_blastmaster_emi_shortfuseAI(Creature* pCreature) : npc_escortAI(pCreature) + { + m_pInstance = (instance_gnomeregan*)pCreature->GetInstanceData(); + // Remove Gossip-Menu in reload case for DONE enounter + if (m_pInstance && m_pInstance->GetData(TYPE_GRUBBIS) == DONE) + pCreature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); + Reset(); + } + + instance_gnomeregan* m_pInstance; + + uint8 m_uiPhase; + uint32 m_uiPhaseTimer; + uint64 m_uiPlayerGUID; + bool m_bDidAggroText, m_bSouthernCaveInOpened, m_bNorthernCaveInOpened; + std::list m_luiSummonedMobGUIDs; + + void Reset() + { + m_bDidAggroText = false; // Used for 'defend' text, is triggered when the npc is attacked + + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + m_uiPhase = 0; + m_uiPhaseTimer = 0; + m_bSouthernCaveInOpened = m_bNorthernCaveInOpened = false; + m_luiSummonedMobGUIDs.clear(); + } + } + + void DoSummonPack(uint8 uiIndex) + { + for (uint8 i = 0; i < MAX_SUMMON_POSITIONS; ++i) + { + // This requires order of the array + if (asSummonInfo[i].uiPosition > uiIndex) + break; + if (asSummonInfo[i].uiPosition == uiIndex) + m_creature->SummonCreature(asSummonInfo[i].uiEntry, asSummonInfo[i].fX, asSummonInfo[i].fY, asSummonInfo[i].fZ, asSummonInfo[i].fO, TEMPSUMMON_DEAD_DESPAWN, 0); + } + } + + void JustSummoned(Creature* pSummoned) + { + switch (pSummoned->GetEntry()) + { + case NPC_CAVERNDEEP_BURROWER: + case NPC_CAVERNDEEP_AMBUSHER: + { + if (GameObject* pDoor = m_creature->GetMap()->GetGameObject(m_pInstance->GetData64(m_uiPhase > 20 ? GO_CAVE_IN_NORTH : GO_CAVE_IN_SOUTH))) + { + float fX, fY, fZ; + pDoor->GetNearPoint(pDoor, fX, fY, fZ, 0.0f, 2.0f, frand(0.0f, 2*M_PI_F)); + pSummoned->GetMotionMaster()->MovePoint(1, fX, fY, fZ); + } + break; + } + case NPC_GRUBBIS: + // Movement of Grubbis and Add to be handled by DB waypoints + DoScriptText(SAY_GRUBBIS_SPAWN, pSummoned); + break; + } + m_luiSummonedMobGUIDs.push_back(pSummoned->GetGUID()); + } + + void SummonedCreatureJustDied(Creature* pSummoned) + { + if (pSummoned->GetEntry() == NPC_GRUBBIS) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GRUBBIS, DONE); + m_uiPhaseTimer = 1000; + } + m_luiSummonedMobGUIDs.remove(pSummoned->GetGUID()); + } + + bool IsPreparingExplosiveCharge() + { + return m_uiPhase == 11 || m_uiPhase == 13 || m_uiPhase == 26 || m_uiPhase == 28; + } + + void MoveInLineOfSight(Unit* pWho) + { + // In case we are preparing the explosive charges, we won't start attacking mobs + if (IsPreparingExplosiveCharge()) + return; + + npc_escortAI::MoveInLineOfSight(pWho); + } + + void AttackStart(Unit* pWho) + { + // In case we are preparing the explosive charges, we won't start attacking mobs + if (IsPreparingExplosiveCharge()) + return; + + npc_escortAI::AttackStart(pWho); + } + + void AttackedBy(Unit* pAttacker) + { + // Possibility for Aggro-Text only once per combat + if (m_bDidAggroText) + return; + + m_bDidAggroText = true; + + if (!urand(0, 2)) + DoScriptText(urand(0, 1) ? SAY_AGGRO_1 : SAY_AGGRO_2, m_creature, pAttacker); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(TYPE_GRUBBIS, FAIL); + + if (m_bSouthernCaveInOpened) // close southern cave-in door + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_CAVE_IN_SOUTH)); + if (m_bNorthernCaveInOpened) // close northern cave-in door + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_CAVE_IN_NORTH)); + + for (std::list::const_iterator itr = m_luiSummonedMobGUIDs.begin(); itr != m_luiSummonedMobGUIDs.end(); ++itr) + { + if (Creature* pSummoned = m_creature->GetMap()->GetCreature(*itr)) + pSummoned->ForcedDespawn(); + } + } + + void StartEvent(uint64 uiPlayerGUID) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(TYPE_GRUBBIS, IN_PROGRESS); + + m_uiPhase = 1; + m_uiPhaseTimer = 1000; + m_uiPlayerGUID = uiPlayerGUID; + } + + void WaypointStart(uint32 uiPointId) + { + switch (uiPointId) + { + case 10: + // Open Southern Cave-In + if (m_pInstance && !m_bSouthernCaveInOpened) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_CAVE_IN_SOUTH)); + m_bSouthernCaveInOpened = true; + break; + case 12: + DoScriptText(SAY_CHARGE_1, m_creature); + break; + case 16: + DoScriptText(SAY_CHARGE_3, m_creature); + // Open Northern Cave-In + if (m_pInstance && !m_bNorthernCaveInOpened) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_CAVE_IN_NORTH)); + m_bNorthernCaveInOpened = true; + break; + } + } + + void WaypointReached(uint32 uiPointId) + { + switch(uiPointId) + { + case 4: + m_uiPhaseTimer = 1000; + break; + case 9: + m_uiPhaseTimer = 2000; + break; + case 11: + m_creature->HandleEmote(EMOTE_STATE_USESTANDING); + m_uiPhaseTimer = 15000; + break; + case 13: + m_creature->HandleEmote(EMOTE_STATE_USESTANDING); + m_uiPhaseTimer = 10000; + break; + case 15: + SetEscortPaused(true); + if (m_pInstance) + { + if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CAVE_IN_SOUTH))) + m_creature->SetFacingToObject(pDoor); + } + DoScriptText(SAY_BLOW_1_10, m_creature); + m_uiPhaseTimer = 5000; + break; + case 16: + m_creature->HandleEmote(EMOTE_STATE_USESTANDING); + m_uiPhaseTimer = 15000; + break; + case 17: + m_creature->HandleEmote(EMOTE_STATE_USESTANDING); + m_uiPhaseTimer = 10000; + break; + case 19: + m_uiPhaseTimer = 2000; + SetEscortPaused(true); // And keep paused from now on! + break; + } + } + + void UpdateEscortAI(uint32 const uiDiff) + { + // the phases are handled OOC (keeps them in sync with the waypoints) + if (m_uiPhaseTimer && !m_creature->getVictim()) + { + if (m_uiPhaseTimer <= uiDiff) + { + switch (m_uiPhase) + { + case 1: + DoScriptText(SAY_START, m_creature); + m_creature->setFaction(FACTION_ESCORT_N_NEUTRAL_PASSIVE); + m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); + m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); + m_uiPhaseTimer = 5000; + break; + case 2: + DoScriptText(SAY_INTRO_1, m_creature); + m_uiPhaseTimer = 3500; // 6s delay, but 2500ms for escortstarting + break; + case 3: + Start(false, m_uiPlayerGUID, NULL, false, false); + m_uiPhaseTimer = 0; + break; + + case 4: // Shortly after reached WP 4 + DoScriptText(SAY_INTRO_2, m_creature); + m_uiPhaseTimer = 0; + break; + + case 5: // Shortly after reached WP 9 + DoScriptText(SAY_INTRO_3, m_creature); + m_uiPhaseTimer = 6000; + break; + case 6: + DoScriptText(SAY_INTRO_4, m_creature); + m_uiPhaseTimer = 9000; + break; + case 7: + if (m_pInstance) + { + if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CAVE_IN_SOUTH))) + m_creature->SetFacingToObject(pDoor); + } + m_uiPhaseTimer = 2000; + break; + case 8: + DoScriptText(SAY_LOOK_1, m_creature); + m_uiPhaseTimer = 5000; + break; + case 9: + DoScriptText(SAY_HEAR_1, m_creature); + m_uiPhaseTimer = 2000; + break; + case 10: // Shortly shortly before starting WP 11 + DoSummonPack(1); + m_uiPhaseTimer = 0; + break; + + case 11: // 15s after reached WP 11 + DoSummonPack(2); + + // Summon first explosive charge + if (m_pInstance) + m_pInstance->SetData(TYPE_EXPLOSIVE_CHARGE, DATA_EXPLOSIVE_CHARGE_1); + // Remove EMOTE_STATE_USESTANDING state-emote + m_creature->HandleEmote(EMOTE_ONESHOT_NONE); + + m_uiPhaseTimer = 1; + break; + case 12: // Empty Phase, used to store information about set charge + m_uiPhaseTimer = 0; + break; + + case 13: // 10s after reached WP 13 + DoSummonPack(3); + + // Summon second explosive charge + if (m_pInstance) + m_pInstance->SetData(TYPE_EXPLOSIVE_CHARGE, DATA_EXPLOSIVE_CHARGE_2); + // Remove EMOTE_STATE_USESTANDING state-emote + m_creature->HandleEmote(EMOTE_ONESHOT_NONE); + + m_uiPhaseTimer = 11000; + break; + case 14: // Empty Phase, used to store information about set charge + m_uiPhaseTimer = 1; + break; + case 15: // shortly before starting WP 14 + if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) + m_creature->SetFacingToObject(pPlayer); + DoScriptText(SAY_CHARGE_2, m_creature); + m_uiPhaseTimer = 0; + break; + + case 16: // 5s after reaching WP 15 + DoScriptText(SAY_BLOW_1_5, m_creature); + m_uiPhaseTimer = 5000; + break; + case 17: + DoScriptText(SAY_BLOW_1, m_creature); + m_uiPhaseTimer = 1000; + break; + case 18: + DoCastSpellIfCan(m_creature, SPELL_EXPLOSION_SOUTH); + m_uiPhaseTimer = 500; + break; + case 19: + // Close southern cave-in and let charges explode + if (m_pInstance) + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_CAVE_IN_SOUTH)); + m_bSouthernCaveInOpened = false; + m_pInstance->SetData(TYPE_EXPLOSIVE_CHARGE, DATA_EXPLOSIVE_CHARGE_USE); + } + m_uiPhaseTimer = 5000; + break; + case 20: + m_creature->HandleEmote(EMOTE_ONESHOT_CHEER); + m_uiPhaseTimer = 6000; + break; + case 21: + DoScriptText(SAY_FINISH_1, m_creature); + m_uiPhaseTimer = 6000; + break; + case 22: + DoScriptText(SAY_LOOK_2, m_creature); + m_uiPhaseTimer = 3000; + break; + case 23: + if (m_pInstance) + { + if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CAVE_IN_NORTH))) + m_creature->SetFacingToObject(pDoor); + } + m_uiPhaseTimer = 3000; + break; + case 24: + DoScriptText(SAY_HEAR_2, m_creature); + m_uiPhaseTimer = 8000; + break; + case 25: // shortly before starting WP 16 + SetEscortPaused(false); + DoSummonPack(4); + m_uiPhaseTimer = 0; + break; + + case 26: // 15s after reaching WP 16 + DoSummonPack(5); + + // Summon third explosive charge + if (m_pInstance) + m_pInstance->SetData(TYPE_EXPLOSIVE_CHARGE, DATA_EXPLOSIVE_CHARGE_3); + // Remove EMOTE_STATE_USESTANDING state-emote + m_creature->HandleEmote(EMOTE_ONESHOT_NONE); + + m_uiPhaseTimer = 1; + break; + case 27: // Empty Phase, used to store information about set charge + m_uiPhaseTimer = 0; + break; + + case 28: // 10s after reaching WP 17 + DoSummonPack(6); + + // Summon forth explosive charge + if (m_pInstance) + m_pInstance->SetData(TYPE_EXPLOSIVE_CHARGE, DATA_EXPLOSIVE_CHARGE_4); + // Remove EMOTE_STATE_USESTANDING state-emote + m_creature->HandleEmote(EMOTE_ONESHOT_NONE); + + m_uiPhaseTimer = 10000; + break; + case 29: // Empty Phase, used to store information about set charge + m_uiPhaseTimer = 1; + break; + case 30: // shortly before starting WP 18 + DoScriptText(SAY_CHARGE_4, m_creature); + m_uiPhaseTimer = 0; + break; + + case 31: // shortly after reaching WP 19 + if (m_pInstance) + { + if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CAVE_IN_NORTH))) + m_creature->SetFacingToObject(pDoor); + } + DoScriptText(SAY_BLOW_2_10, m_creature); + m_uiPhaseTimer = 5000; + break; + case 32: + DoScriptText(SAY_BLOW_2_5, m_creature); + m_uiPhaseTimer = 1000; + break; + case 33: + DoSummonPack(7); // Summon Grubbis and add + m_uiPhaseTimer = 0; + break; + + case 34: // 1 sek after Death of Grubbis + if (m_pInstance) + { + if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CAVE_IN_NORTH))) + m_creature->SetFacingToObject(pDoor); + } + m_creature->HandleEmote(EMOTE_ONESHOT_CHEER); + m_uiPhaseTimer = 5000; + break; + case 35: + DoScriptText(SAY_BLOW_SOON, m_creature); + m_uiPhaseTimer = 5000; + break; + case 36: + DoScriptText(SAY_BLOW_2, m_creature); + m_uiPhaseTimer = 2000; + break; + case 37: + m_creature->HandleEmote(EMOTE_ONESHOT_POINT); + m_uiPhaseTimer = 1000; + break; + case 38: + DoCastSpellIfCan(m_creature, SPELL_EXPLOSION_NORTH); + m_uiPhaseTimer = 500; + break; + case 39: + // Close northern cave-in and let charges explode + if (m_pInstance) + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_CAVE_IN_NORTH)); + m_bNorthernCaveInOpened = false; + m_pInstance->SetData(TYPE_EXPLOSIVE_CHARGE, DATA_EXPLOSIVE_CHARGE_USE); + } + m_uiPhaseTimer = 8000; + break; + case 40: + DoCastSpellIfCan(m_creature, SPELL_FIREWORKS_RED); + DoScriptText(SAY_FINISH_2, m_creature); + m_uiPhaseTimer = 0; + break; + } + ++m_uiPhase; + } + else + m_uiPhaseTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_blastmaster_emi_shortfuse(Creature* pCreature) +{ + return new npc_blastmaster_emi_shortfuseAI(pCreature); +} + +bool GossipHello_npc_blastmaster_emi_shortfuse(Player* pPlayer, Creature* pCreature) +{ + if (instance_gnomeregan* pInstance = (instance_gnomeregan*)pCreature->GetInstanceData()) + { + if (pInstance->GetData(TYPE_GRUBBIS) == NOT_STARTED || pInstance->GetData(TYPE_GRUBBIS) == FAIL) + { + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + } + } + return true; +} + +bool GossipSelect_npc_blastmaster_emi_shortfuse(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + if (instance_gnomeregan* pInstance = (instance_gnomeregan*)pCreature->GetInstanceData()) + { + if (pInstance->GetData(TYPE_GRUBBIS) == NOT_STARTED || pInstance->GetData(TYPE_GRUBBIS) == FAIL) + { + if (npc_blastmaster_emi_shortfuseAI* pEmiAI = dynamic_cast(pCreature->AI())) + pEmiAI->StartEvent(pPlayer->GetGUID()); + } + } + } + pPlayer->CLOSE_GOSSIP_MENU(); + + return true; +} + void AddSC_gnomeregan() { + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "npc_blastmaster_emi_shortfuse"; + pNewScript->GetAI = &GetAI_npc_blastmaster_emi_shortfuse; + pNewScript->pGossipHello = &GossipHello_npc_blastmaster_emi_shortfuse; + pNewScript->pGossipSelect = &GossipSelect_npc_blastmaster_emi_shortfuse; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h b/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h index 4491dae73..db08f6c29 100644 --- a/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h +++ b/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp b/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp index 4d90d08c5..07b4fea60 100644 --- a/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp +++ b/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/hinterlands.cpp b/scripts/eastern_kingdoms/hinterlands.cpp index 6a44f15c0..dfee4f3f3 100644 --- a/scripts/eastern_kingdoms/hinterlands.cpp +++ b/scripts/eastern_kingdoms/hinterlands.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -330,12 +330,12 @@ void AddSC_hinterlands() pNewScript = new Script; pNewScript->Name = "npc_00x09hl"; pNewScript->GetAI = &GetAI_npc_00x09hl; - pNewScript->pQuestAccept = &QuestAccept_npc_00x09hl; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_00x09hl; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_rinji"; pNewScript->GetAI = &GetAI_npc_rinji; - pNewScript->pQuestAccept = &QuestAccept_npc_rinji; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_rinji; pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/ironforge.cpp b/scripts/eastern_kingdoms/ironforge.cpp index 4c54ccd17..4a77ea4e2 100644 --- a/scripts/eastern_kingdoms/ironforge.cpp +++ b/scripts/eastern_kingdoms/ironforge.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/isle_of_queldanas.cpp b/scripts/eastern_kingdoms/isle_of_queldanas.cpp index b8f35e38b..b1877807c 100644 --- a/scripts/eastern_kingdoms/isle_of_queldanas.cpp +++ b/scripts/eastern_kingdoms/isle_of_queldanas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,14 +17,12 @@ /* ScriptData SDName: Isle_of_Queldanas SD%Complete: 100 -SDComment: Quest support: 11524, 11525, 11533, 11543 +SDComment: Quest support: 11524, 11525 SDCategory: Isle Of Quel'Danas EndScriptData */ /* ContentData -npc_ayren_cloudbreaker npc_converted_sentry -npc_unrestrained_dragonhawk EndContentData */ #include "precompiled.h" @@ -33,48 +31,46 @@ EndContentData */ ## npc_converted_sentry ######*/ -#define SAY_CONVERTED_1 -1000188 -#define SAY_CONVERTED_2 -1000189 +enum +{ + SAY_CONVERTED_1 = -1000188, + SAY_CONVERTED_2 = -1000189, -#define SPELL_CONVERT_CREDIT 45009 + SPELL_CONVERT_CREDIT = 45009, + TIME_PET_DURATION = 7500 +}; struct MANGOS_DLL_DECL npc_converted_sentryAI : public ScriptedAI { npc_converted_sentryAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } - bool Credit; - uint32 Timer; + uint32 m_uiCreditTimer; void Reset() { - Credit = false; - Timer = 2500; + m_uiCreditTimer = 2500; } - void MoveInLineOfSight(Unit *who) - { - return; - } + void MoveInLineOfSight(Unit* pWho) {} - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { - if (!Credit) + if (m_uiCreditTimer) { - if (Timer <= diff) + if (m_uiCreditTimer <= uiDiff) { - uint32 i = urand(1,2); - if (i==1) - DoScriptText(SAY_CONVERTED_1, m_creature); - else - DoScriptText(SAY_CONVERTED_2, m_creature); + DoScriptText(urand(0, 1) ? SAY_CONVERTED_1 : SAY_CONVERTED_2, m_creature); - DoCastSpellIfCan(m_creature,SPELL_CONVERT_CREDIT); - ((Pet*)m_creature)->SetDuration(7500); - Credit = true; - }else Timer -= diff; + DoCastSpellIfCan(m_creature, SPELL_CONVERT_CREDIT); + ((Pet*)m_creature)->SetDuration(TIME_PET_DURATION); + m_uiCreditTimer = 0; + } + else + m_uiCreditTimer -= uiDiff; } } }; + CreatureAI* GetAI_npc_converted_sentry(Creature* pCreature) { return new npc_converted_sentryAI(pCreature); @@ -82,10 +78,10 @@ CreatureAI* GetAI_npc_converted_sentry(Creature* pCreature) void AddSC_isle_of_queldanas() { - Script *newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "npc_converted_sentry"; - newscript->GetAI = &GetAI_npc_converted_sentry; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "npc_converted_sentry"; + pNewScript->GetAI = &GetAI_npc_converted_sentry; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/karazhan/boss_curator.cpp b/scripts/eastern_kingdoms/karazhan/boss_curator.cpp index 0991a8c25..1d05193d4 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_curator.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_curator.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp b/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp index 428502117..a54fad24a 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp b/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp index caabba331..cca340e81 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -288,7 +288,7 @@ struct MANGOS_DLL_DECL boss_attumenAI : public ScriptedAI { target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); - if (target && !target->IsWithinDist(m_creature, ATTACK_DISTANCE, false)) + if (target && !m_creature->CanReachWithMeleeAttack(target)) target_list.push_back(target); target = NULL; diff --git a/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp b/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp index 19bdb243a..5ce5209b7 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -303,7 +303,7 @@ struct MANGOS_DLL_DECL boss_moroesAI : public ScriptedAI { pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); - if (pTarget && pTarget->IsWithinDist(m_creature, ATTACK_DISTANCE, false)) + if (pTarget && m_creature->CanReachWithMeleeAttack(pTarget)) vTargetList.push_back(pTarget); } @@ -350,7 +350,7 @@ struct MANGOS_DLL_DECL boss_moroes_guestAI : public ScriptedAI if (!m_pInstance) return; - m_auiGuestGUID[0] = m_pInstance->GetData64(DATA_MOROES); + m_auiGuestGUID[0] = m_pInstance->GetData64(NPC_MOROES); if (Creature* pMoroes = m_creature->GetMap()->GetCreature(m_auiGuestGUID[0])) { @@ -379,6 +379,7 @@ struct MANGOS_DLL_DECL boss_moroes_guestAI : public ScriptedAI return m_creature; } + // TODO double check this design! - with momentarily system DoMeleeAttackIfReady is called before the spells are handled void UpdateAI(const uint32 uiDiff) { if (m_pInstance && !m_pInstance->GetData(TYPE_MOROES)) diff --git a/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp b/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp index 1c6e5efd4..57955e9b3 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -111,7 +111,7 @@ struct MANGOS_DLL_DECL boss_netherspiteAI : public ScriptedAI { m_bIsEnraged = false; m_uiActivePhase = BEAM_PHASE; - + m_uiEnrageTimer = MINUTE*9*IN_MILLISECONDS; m_uiVoidZoneTimer = 15000; m_uiPhaseSwitchTimer = MINUTE*IN_MILLISECONDS; @@ -123,7 +123,6 @@ struct MANGOS_DLL_DECL boss_netherspiteAI : public ScriptedAI m_pInstance->SetData(TYPE_NETHERSPITE, IN_PROGRESS); DoCastSpellIfCan(m_creature, SPELL_NETHERBURN); - m_creature->SetInCombatWithZone(); } void JustDied(Unit* pKiller) @@ -153,10 +152,10 @@ struct MANGOS_DLL_DECL boss_netherspiteAI : public ScriptedAI m_uiActivePhase = BEAM_PHASE; DoScriptText(EMOTE_PHASE_BEAM, m_creature); DoCastSpellIfCan(m_creature, SPELL_NETHERSPITE_ROAR); - + m_uiPhaseSwitchTimer = MINUTE*IN_MILLISECONDS; } - + //reset threat every phase switch DoResetThreat(); } @@ -170,7 +169,7 @@ struct MANGOS_DLL_DECL boss_netherspiteAI : public ScriptedAI SwitchPhases(); else m_uiPhaseSwitchTimer -= uiDiff; - + if (!m_bIsEnraged) { if (m_uiEnrageTimer < uiDiff) @@ -188,7 +187,7 @@ struct MANGOS_DLL_DECL boss_netherspiteAI : public ScriptedAI { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_VOID_ZONE, true); - + m_uiVoidZoneTimer = 15000; } else @@ -201,13 +200,13 @@ struct MANGOS_DLL_DECL boss_netherspiteAI : public ScriptedAI { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_NETHERBREATH); - + m_uiNetherbreathTimer = urand(4000, 5000); } else m_uiNetherbreathTimer -= uiDiff; } - + DoMeleeAttackIfReady(); } }; diff --git a/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp b/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp index 2adc3364e..8d474e087 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -34,3 +34,7 @@ enum SPELL_SMOKING_BLAST = 37057, SPELL_FIREBALL_BARRAGE = 30282 }; + +void AddSC_boss_nightbane() +{ +} diff --git a/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp b/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp index fdd108658..415e6839b 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -574,16 +574,20 @@ struct MANGOS_DLL_DECL boss_malchezaarAI : public ScriptedAI void DoMeleeAttacksIfReady() { - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE) && !m_creature->IsNonMeleeSpellCasted(false)) + // Check if target is valid + if (!m_creature->getVictim()) + return; + + if (!m_creature->IsNonMeleeSpellCasted(false) && m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { //Check for base attack - if (m_creature->isAttackReady() && m_creature->getVictim()) + if (m_creature->isAttackReady()) { m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } //Check for offhand attack - if (m_creature->isAttackReady(OFF_ATTACK) && m_creature->getVictim()) + if (m_creature->isAttackReady(OFF_ATTACK)) { m_creature->AttackerStateUpdate(m_creature->getVictim(), OFF_ATTACK); m_creature->resetAttackTimer(OFF_ATTACK); diff --git a/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp b/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp index cae1e6146..75e562173 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -220,7 +220,7 @@ struct MANGOS_DLL_DECL boss_aranAI : public ScriptedAI { if (m_pInstance) { - if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_GO_LIBRARY_DOOR))) + if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_PRIVATE_LIBRARY_DOOR))) pDoor->SetGoState(GO_STATE_READY); m_uiCloseDoor_Timer = 0; diff --git a/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp b/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp index 625abba83..25caadad2 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -146,8 +146,6 @@ struct MANGOS_DLL_DECL boss_terestianAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); - if (Pet* pKilrek = m_creature->GetPet()) pKilrek->SetInCombatWithZone(); diff --git a/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp b/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp index 11ed97e24..372984cd3 100644 --- a/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp +++ b/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -1302,10 +1302,10 @@ void boss_julianneAI::UpdateAI(const uint32 diff) pRomAI->Phase = PHASE_ROMULO; } - pRomulo->SetInCombatWithZone(); - //why? pRomulo->setFaction(16); + + pRomulo->SetInCombatWithZone(); } SummonedRomulo = true; }else SummonRomuloTimer -= diff; diff --git a/scripts/eastern_kingdoms/karazhan/chess_event.cpp b/scripts/eastern_kingdoms/karazhan/chess_event.cpp new file mode 100644 index 000000000..3e292bc6e --- /dev/null +++ b/scripts/eastern_kingdoms/karazhan/chess_event.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: chess_event +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Karazhan +EndScriptData */ + +#include "precompiled.h" + +void AddSC_chess_event() +{ +} diff --git a/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp b/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp index 554f705be..3b8552bc4 100644 --- a/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp +++ b/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -28,259 +28,269 @@ EndScriptData */ 0 - Attumen + Midnight (optional) 1 - Moroes 2 - Maiden of Virtue (optional) -3 - Hyakiss the Lurker / Rokad the Ravager / Shadikith the Glider -4 - Opera Event -5 - Curator +3 - Opera Event +4 - Curator +5 - Terestian Illhoof (optional) 6 - Shade of Aran (optional) -7 - Terestian Illhoof (optional) -8 - Netherspite (optional) -9 - Chess Event -10 - Prince Malchezzar -11 - Nightbane +7 - Netherspite (optional) +8 - Chess Event +9 - Prince Malchezzar +10 - Nightbane */ -struct MANGOS_DLL_DECL instance_karazhan : public ScriptedInstance +instance_karazhan::instance_karazhan(Map* pMap) : ScriptedInstance(pMap), + m_uiOzDeathCount(0), + + m_uiMoroesGUID(0), + m_uiTerestianGUID(0), + m_uiNightbaneGUID(0), + + m_uiCurtainGUID(0), + m_uiStageDoorLeftGUID(0), + m_uiStageDoorRightGUID(0), + m_uiLibraryDoor(0), + m_uiMassiveDoor(0), + m_uiSideEntranceDoor(0), + m_uiGamesmansDoor(0), + m_uiGamesmansExitDoor(0), + m_uiNetherspaceDoor(0), + m_uiDustCoveredChest(0) { - instance_karazhan(Map* pMap) : ScriptedInstance(pMap) {Initialize();} - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - uint32 m_uiOperaEvent; - uint32 m_uiOzDeathCount; - - uint64 m_uiCurtainGUID; - uint64 m_uiStageDoorLeftGUID; - uint64 m_uiStageDoorRightGUID; - uint64 m_uiTerestianGUID; - uint64 m_uiMoroesGUID; - uint64 m_uiLibraryDoor; // Door at Shade of Aran - uint64 m_uiMassiveDoor; // Door at Netherspite - uint64 m_uiSideEntranceDoor; // Side Entrance - uint64 m_uiGamesmansDoor; // Door before Chess - uint64 m_uiGamesmansExitDoor; // Door after Chess - uint64 m_uiNetherspaceDoor; // Door at Malchezaar - uint64 m_uiDustCoveredChest; // Chest respawn at event complete - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - // 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered. - m_uiOperaEvent = urand(EVENT_OZ,EVENT_RAJ); - m_uiOzDeathCount = 0; - - m_uiCurtainGUID = 0; - m_uiStageDoorLeftGUID = 0; - m_uiStageDoorRightGUID = 0; - - m_uiTerestianGUID = 0; - m_uiMoroesGUID = 0; - - m_uiLibraryDoor = 0; - m_uiMassiveDoor = 0; - m_uiSideEntranceDoor = 0; - m_uiGamesmansDoor = 0; - m_uiGamesmansExitDoor = 0; - m_uiNetherspaceDoor = 0; - m_uiDustCoveredChest = 0; - } + Initialize(); +} - bool IsEncounterInProgress() const - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; +void instance_karazhan::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - return false; - } + // 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered. + m_uiOperaEvent = urand(EVENT_OZ, EVENT_RAJ); +} + +bool instance_karazhan::IsEncounterInProgress() const +{ + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) + return true; + + return false; +} - void OnCreatureCreate(Creature* pCreature) +void instance_karazhan::OnCreatureCreate(Creature* pCreature) +{ + switch (pCreature->GetEntry()) { - switch (pCreature->GetEntry()) - { - case 15688: m_uiTerestianGUID = pCreature->GetGUID(); break; - case 15687: m_uiMoroesGUID = pCreature->GetGUID(); break; - } + case NPC_TERESTIAN: m_uiTerestianGUID = pCreature->GetGUID(); break; + case NPC_MOROES: m_uiMoroesGUID = pCreature->GetGUID(); break; + case NPC_NIGHTBANE: m_uiNightbaneGUID = pCreature->GetGUID(); break; } +} - void OnObjectCreate(GameObject* pGo) +void instance_karazhan::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) { - switch(pGo->GetEntry()) - { - case 183932: m_uiCurtainGUID = pGo->GetGUID(); break; - case 184278: - m_uiStageDoorLeftGUID = pGo->GetGUID(); - if (m_auiEncounter[4] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 184279: - m_uiStageDoorRightGUID = pGo->GetGUID(); - if (m_auiEncounter[4] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 184517: m_uiLibraryDoor = pGo->GetGUID(); break; - case 185521: m_uiMassiveDoor = pGo->GetGUID(); break; - case 184276: m_uiGamesmansDoor = pGo->GetGUID(); break; - case 184277: m_uiGamesmansExitDoor = pGo->GetGUID(); break; - case 185134: m_uiNetherspaceDoor = pGo->GetGUID(); break; - case 184275: - m_uiSideEntranceDoor = pGo->GetGUID(); - if (m_auiEncounter[4] != DONE) - pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); - else - pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); - break; - case 185119: m_uiDustCoveredChest = pGo->GetGUID(); break; - } - - switch(m_uiOperaEvent) - { - //TODO: Set DoRespawnGameObject for Opera based on performance - case EVENT_OZ: - break; - case EVENT_HOOD: - break; - case EVENT_RAJ: - break; - } + case GO_STAGE_CURTAIN: + m_uiCurtainGUID = pGo->GetGUID(); + break; + case GO_STAGE_DOOR_LEFT: + m_uiStageDoorLeftGUID = pGo->GetGUID(); + if (m_auiEncounter[4] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_STAGE_DOOR_RIGHT: + m_uiStageDoorRightGUID = pGo->GetGUID(); + if (m_auiEncounter[4] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_PRIVATE_LIBRARY_DOOR: + m_uiLibraryDoor = pGo->GetGUID(); + break; + case GO_MASSIVE_DOOR: + m_uiMassiveDoor = pGo->GetGUID(); + break; + case GO_GAMESMANS_HALL_DOOR: + m_uiGamesmansDoor = pGo->GetGUID(); + break; + case GO_GAMESMANS_HALL_EXIT_DOOR: + m_uiGamesmansExitDoor = pGo->GetGUID(); + break; + case GO_NETHERSPACE_DOOR: + m_uiNetherspaceDoor = pGo->GetGUID(); + break; + case GO_SIDE_ENTRANCE_DOOR: + m_uiSideEntranceDoor = pGo->GetGUID(); + if (m_auiEncounter[4] != DONE) + pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); + else + pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); + break; + case GO_DUST_COVERED_CHEST: + m_uiDustCoveredChest = pGo->GetGUID(); + break; + + case GO_OZ_BACKDROP: + case GO_OZ_HAY: + // if (m_uiOperaEvent == EVENT_OZ) // TODO - respawn, store for later respawn? + break; + case GO_HOOD_BACKDROP: + case GO_HOOD_TREE: + case GO_HOOD_HOUSE: + // if (m_uiOperaEvent == EVENT_HOOD) // TODO - respawn, store for later respawn? + break; + case GO_RAJ_BACKDROP: + case GO_RAJ_MOON: + case GO_RAJ_BALCONY: + // if (m_uiOperaEvent == EVENT_RAJ) // TODO - respawn, store for later respawn? + break; } +} - void SetData(uint32 uiType, uint32 uiData) +void instance_karazhan::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - switch(uiType) - { - case TYPE_ATTUMEN: m_auiEncounter[0] = uiData; break; - case TYPE_MOROES: - if (m_auiEncounter[1] != DONE) - m_auiEncounter[1] = uiData; - break; - case TYPE_MAIDEN: m_auiEncounter[2] = uiData; break; - case TYPE_OPTIONAL_BOSS: m_auiEncounter[3] = uiData; break; - case TYPE_OPERA: - m_auiEncounter[4] = uiData; - if (uiData == DONE) - { - DoUseDoorOrButton(m_uiStageDoorLeftGUID); - DoUseDoorOrButton(m_uiStageDoorRightGUID); - if (GameObject* pSideEntrance = instance->GetGameObject(m_uiSideEntranceDoor)) - pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); - } - break; - case TYPE_CURATOR: m_auiEncounter[5] = uiData; break; - case TYPE_ARAN: - m_auiEncounter[6] = uiData; - if (uiData != IN_PROGRESS) - DoUseDoorOrButton(m_uiLibraryDoor); - break; - case TYPE_TERESTIAN: m_auiEncounter[7] = uiData; break; - case TYPE_NETHERSPITE: - m_auiEncounter[8] = uiData; - DoUseDoorOrButton(m_uiMassiveDoor); - break; - case TYPE_CHESS: - if (uiData == DONE) - DoRespawnGameObject(m_uiDustCoveredChest,DAY); - m_auiEncounter[9] = uiData; - break; - case TYPE_MALCHEZZAR: m_auiEncounter[10] = uiData; break; - case TYPE_NIGHTBANE: m_auiEncounter[11] = uiData; break; - case DATA_OPERA_OZ_DEATHCOUNT: - if (uiData == SPECIAL) - ++m_uiOzDeathCount; - else if (uiData == IN_PROGRESS) - m_uiOzDeathCount = 0; - 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_auiEncounter[8] << " " - << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11]; - - strInstData = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } + case TYPE_ATTUMEN: + m_auiEncounter[0] = uiData; + break; + case TYPE_MOROES: + if (m_auiEncounter[1] != DONE) + m_auiEncounter[1] = uiData; + break; + case TYPE_MAIDEN: + m_auiEncounter[2] = uiData; + break; + case TYPE_OPERA: + m_auiEncounter[3] = uiData; + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiStageDoorLeftGUID); + DoUseDoorOrButton(m_uiStageDoorRightGUID); + if (GameObject* pSideEntrance = instance->GetGameObject(m_uiSideEntranceDoor)) + pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); + } + break; + case TYPE_CURATOR: + m_auiEncounter[4] = uiData; + break; + case TYPE_TERESTIAN: + m_auiEncounter[5] = uiData; + break; + case TYPE_ARAN: + m_auiEncounter[6] = uiData; + if (uiData != IN_PROGRESS) + DoUseDoorOrButton(m_uiLibraryDoor); + break; + case TYPE_NETHERSPITE: + m_auiEncounter[7] = uiData; + DoUseDoorOrButton(m_uiMassiveDoor); + break; + case TYPE_CHESS: + if (uiData == DONE) + DoRespawnGameObject(m_uiDustCoveredChest, DAY); + m_auiEncounter[8] = uiData; + break; + case TYPE_MALCHEZZAR: + m_auiEncounter[9] = uiData; + break; + case TYPE_NIGHTBANE: + m_auiEncounter[10] = uiData; + break; + + case DATA_OPERA_OZ_DEATHCOUNT: + if (uiData == SPECIAL) + ++m_uiOzDeathCount; + else if (uiData == IN_PROGRESS) + m_uiOzDeathCount = 0; + return; } - const char* Save() + if (uiData == DONE) { - return strInstData.c_str(); + 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_auiEncounter[10]; + + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - uint32 GetData(uint32 uiType) +uint32 instance_karazhan::GetData(uint32 uiType) +{ + switch (uiType) { - switch (uiType) - { - case TYPE_ATTUMEN: return m_auiEncounter[0]; - case TYPE_MOROES: return m_auiEncounter[1]; - case TYPE_MAIDEN: return m_auiEncounter[2]; - case TYPE_OPTIONAL_BOSS: return m_auiEncounter[3]; - case TYPE_OPERA: return m_auiEncounter[4]; - case TYPE_CURATOR: return m_auiEncounter[5]; - case TYPE_ARAN: return m_auiEncounter[6]; - case TYPE_TERESTIAN: return m_auiEncounter[7]; - case TYPE_NETHERSPITE: return m_auiEncounter[8]; - case TYPE_CHESS: return m_auiEncounter[9]; - case TYPE_MALCHEZZAR: return m_auiEncounter[10]; - case TYPE_NIGHTBANE: return m_auiEncounter[11]; - case DATA_OPERA_PERFORMANCE: return m_uiOperaEvent; - case DATA_OPERA_OZ_DEATHCOUNT: return m_uiOzDeathCount; - } - - return 0; + case TYPE_ATTUMEN: return m_auiEncounter[0]; + case TYPE_MOROES: return m_auiEncounter[1]; + case TYPE_MAIDEN: return m_auiEncounter[2]; + case TYPE_OPERA: return m_auiEncounter[3]; + case TYPE_CURATOR: return m_auiEncounter[4]; + case TYPE_TERESTIAN: return m_auiEncounter[5]; + case TYPE_ARAN: return m_auiEncounter[6]; + case TYPE_NETHERSPITE: return m_auiEncounter[7]; + case TYPE_CHESS: return m_auiEncounter[8]; + case TYPE_MALCHEZZAR: return m_auiEncounter[9]; + case TYPE_NIGHTBANE: return m_auiEncounter[10]; + + case DATA_OPERA_PERFORMANCE: return m_uiOperaEvent; + case DATA_OPERA_OZ_DEATHCOUNT: return m_uiOzDeathCount; + + default: + return 0; } +} - uint64 GetData64(uint32 uiData) +uint64 instance_karazhan::GetData64(uint32 uiData) +{ + switch (uiData) { - switch (uiData) - { - case DATA_TERESTIAN: return m_uiTerestianGUID; - case DATA_MOROES: return m_uiMoroesGUID; - case DATA_GO_STAGEDOORLEFT: return m_uiStageDoorLeftGUID; - case DATA_GO_STAGEDOORRIGHT: return m_uiStageDoorRightGUID; - case DATA_GO_CURTAINS: return m_uiCurtainGUID; - case DATA_GO_LIBRARY_DOOR: return m_uiLibraryDoor; - case DATA_GO_MASSIVE_DOOR: return m_uiMassiveDoor; - case DATA_GO_SIDE_ENTRANCE_DOOR: return m_uiSideEntranceDoor; - case DATA_GO_GAME_DOOR: return m_uiGamesmansDoor; - case DATA_GO_GAME_EXIT_DOOR: return m_uiGamesmansExitDoor; - case DATA_GO_NETHER_DOOR: return m_uiNetherspaceDoor; - } - - return 0; + case NPC_MOROES: return m_uiMoroesGUID; + case NPC_TERESTIAN: return m_uiTerestianGUID; + case NPC_NIGHTBANE: return m_uiNightbaneGUID; + + case GO_STAGE_DOOR_LEFT: return m_uiStageDoorLeftGUID; + case GO_STAGE_DOOR_RIGHT: return m_uiStageDoorRightGUID; + case GO_STAGE_CURTAIN: return m_uiCurtainGUID; + case GO_PRIVATE_LIBRARY_DOOR: return m_uiLibraryDoor; + case GO_MASSIVE_DOOR: return m_uiMassiveDoor; + case GO_SIDE_ENTRANCE_DOOR: return m_uiSideEntranceDoor; + case GO_GAMESMANS_HALL_DOOR: return m_uiGamesmansDoor; + case GO_GAMESMANS_HALL_EXIT_DOOR: return m_uiGamesmansExitDoor; + case GO_NETHERSPACE_DOOR: return m_uiNetherspaceDoor; + + default: + return 0; } +} - void Load(const char* chrIn) +void instance_karazhan::Load(const char* chrIn) +{ + if (!chrIn) { - if (!chrIn) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } + OUT_LOAD_INST_DATA_FAIL; + return; + } - OUT_LOAD_INST_DATA(chrIn); + OUT_LOAD_INST_DATA(chrIn); - std::istringstream loadStream(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] >> m_auiEncounter[10] >> m_auiEncounter[11]; + 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] >> m_auiEncounter[10]; - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. - m_auiEncounter[i] = NOT_STARTED; + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. + m_auiEncounter[i] = NOT_STARTED; - OUT_LOAD_INST_DATA_COMPLETE; - } -}; + OUT_LOAD_INST_DATA_COMPLETE; +} InstanceData* GetInstanceData_instance_karazhan(Map* pMap) { @@ -289,9 +299,10 @@ InstanceData* GetInstanceData_instance_karazhan(Map* pMap) void AddSC_instance_karazhan() { - Script* newscript; - newscript = new Script; - newscript->Name = "instance_karazhan"; - newscript->GetInstanceData = &GetInstanceData_instance_karazhan; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_karazhan"; + pNewScript->GetInstanceData = &GetInstanceData_instance_karazhan; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/karazhan/karazhan.cpp b/scripts/eastern_kingdoms/karazhan/karazhan.cpp index 40f1432db..92ffb153b 100644 --- a/scripts/eastern_kingdoms/karazhan/karazhan.cpp +++ b/scripts/eastern_kingdoms/karazhan/karazhan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -167,7 +167,7 @@ struct MANGOS_DLL_DECL npc_barnesAI : public npc_escortAI { case 0: m_creature->CastSpell(m_creature, SPELL_TUXEDO, false); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_STAGEDOORLEFT)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_STAGE_DOOR_LEFT)); break; case 4: m_uiTalkCount = 0; @@ -183,12 +183,12 @@ struct MANGOS_DLL_DECL npc_barnesAI : public npc_escortAI } break; case 8: - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_STAGEDOORLEFT)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_STAGE_DOOR_LEFT)); m_bPerformanceReady = true; break; case 9: PrepareEncounter(); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_CURTAINS)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_STAGE_CURTAIN)); break; } } diff --git a/scripts/eastern_kingdoms/karazhan/karazhan.h b/scripts/eastern_kingdoms/karazhan/karazhan.h index e1d75d973..5cb515f9c 100644 --- a/scripts/eastern_kingdoms/karazhan/karazhan.h +++ b/scripts/eastern_kingdoms/karazhan/karazhan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,36 +7,47 @@ enum { - MAX_ENCOUNTER = 12, - - TYPE_ATTUMEN = 1, - TYPE_MOROES = 2, - TYPE_MAIDEN = 3, - TYPE_OPTIONAL_BOSS = 4, - TYPE_OPERA = 5, - TYPE_CURATOR = 6, - TYPE_ARAN = 7, - TYPE_TERESTIAN = 8, - TYPE_NETHERSPITE = 9, - TYPE_CHESS = 10, - TYPE_MALCHEZZAR = 11, - TYPE_NIGHTBANE = 12, - - DATA_OPERA_PERFORMANCE = 13, - DATA_OPERA_OZ_DEATHCOUNT = 14, - - DATA_TERESTIAN = 16, - DATA_MOROES = 17, - - DATA_GO_CURTAINS = 18, - DATA_GO_STAGEDOORLEFT = 19, - DATA_GO_STAGEDOORRIGHT = 20, - DATA_GO_LIBRARY_DOOR = 21, - DATA_GO_MASSIVE_DOOR = 22, - DATA_GO_NETHER_DOOR = 23, - DATA_GO_GAME_DOOR = 24, - DATA_GO_GAME_EXIT_DOOR = 25, - DATA_GO_SIDE_ENTRANCE_DOOR = 26 + MAX_ENCOUNTER = 11, + + TYPE_ATTUMEN = 0, + TYPE_MOROES = 1, + TYPE_MAIDEN = 2, + TYPE_OPERA = 3, + TYPE_CURATOR = 4, + TYPE_TERESTIAN = 5, + TYPE_ARAN = 6, + TYPE_NETHERSPITE = 7, + TYPE_CHESS = 8, + TYPE_MALCHEZZAR = 9, + TYPE_NIGHTBANE = 10, + + DATA_OPERA_PERFORMANCE = 11, + DATA_OPERA_OZ_DEATHCOUNT = 12, + + NPC_MOROES = 15687, + NPC_TERESTIAN = 15688, + NPC_NIGHTBANE = 17225, + + GO_STAGE_CURTAIN = 183932, + GO_STAGE_DOOR_LEFT = 184278, + GO_STAGE_DOOR_RIGHT = 184279, + GO_PRIVATE_LIBRARY_DOOR = 184517, + GO_MASSIVE_DOOR = 185521, + GO_GAMESMANS_HALL_DOOR = 184276, + GO_GAMESMANS_HALL_EXIT_DOOR = 184277, + GO_NETHERSPACE_DOOR = 185134, + GO_SIDE_ENTRANCE_DOOR = 184275, + GO_DUST_COVERED_CHEST = 185119, + + // Opera event stage decoration + GO_OZ_BACKDROP = 183442, + GO_OZ_HAY = 183496, + GO_HOOD_BACKDROP = 183491, + GO_HOOD_TREE = 183492, + GO_HOOD_HOUSE = 183493, + GO_RAJ_BACKDROP = 183443, + GO_RAJ_MOON = 183494, + GO_RAJ_BALCONY = 183495, }; enum OperaEvents @@ -48,6 +59,48 @@ enum OperaEvents #define ERROR_INST_DATA(a) error_log("SD2: Instance Data for Karazhan not set properly. Encounter for Creature Entry %u may not work properly.", a->GetEntry()); +class MANGOS_DLL_DECL instance_karazhan : public ScriptedInstance +{ + public: + instance_karazhan(Map* pMap); + ~instance_karazhan() {} + + void Initialize(); + bool IsEncounterInProgress() const; + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + void Load(const char* chrIn); + const char* Save() { return m_strInstData.c_str(); } + + private: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint32 m_uiOperaEvent; + uint32 m_uiOzDeathCount; + + uint64 m_uiMoroesGUID; + uint64 m_uiTerestianGUID; + uint64 m_uiNightbaneGUID; + + uint64 m_uiCurtainGUID; + uint64 m_uiStageDoorLeftGUID; + uint64 m_uiStageDoorRightGUID; + uint64 m_uiLibraryDoor; // Door at Shade of Aran + uint64 m_uiMassiveDoor; // Door at Netherspite + uint64 m_uiSideEntranceDoor; // Side Entrance + uint64 m_uiGamesmansDoor; // Door before Chess + uint64 m_uiGamesmansExitDoor; // Door after Chess + uint64 m_uiNetherspaceDoor; // Door at Malchezaar + uint64 m_uiDustCoveredChest; // Chest respawn at event complete +}; + class MANGOS_DLL_DECL npc_fiendish_portalAI : public ScriptedAI { public: diff --git a/scripts/eastern_kingdoms/loch_modan.cpp b/scripts/eastern_kingdoms/loch_modan.cpp index 9671a4ed5..0cffb2169 100644 --- a/scripts/eastern_kingdoms/loch_modan.cpp +++ b/scripts/eastern_kingdoms/loch_modan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -190,6 +190,6 @@ void AddSC_loch_modan() newscript = new Script; newscript->Name = "npc_miran"; newscript->GetAI = &GetAI_npc_miran; - newscript->pQuestAccept = &QuestAccept_npc_miran; + newscript->pQuestAcceptNPC = &QuestAccept_npc_miran; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp b/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp index 17126af40..019eb48fd 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -205,10 +205,11 @@ struct MANGOS_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI DoCastSpellIfCan(m_creature, SPELL_TELEPORT_CENTER, CAST_TRIGGERED); - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) pUnit->CastSpell(pUnit, SPELL_TELEPORT_CENTER, true); @@ -231,10 +232,11 @@ struct MANGOS_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI // players can't cast "fly" spells unless in map 530. Has to be done a while after they get knocked into the air... void CastGravityLapseFly() { - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*i); // Also needs an exception in spell system. if (pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) @@ -244,10 +246,11 @@ struct MANGOS_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI void RemoveGravityLapse() { - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) { diff --git a/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp b/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp index f6f714668..bf023cb72 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -808,10 +808,10 @@ struct MANGOS_DLL_DECL boss_yazzaiAI : public boss_priestess_lackey_commonAI ThreatList const& tList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) { - if (Unit* target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid())) + if (Unit* pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid())) { //if in melee range - if (target->IsWithinDistInMap(m_creature, 5)) + if (m_creature->CanReachWithMeleeAttack(pTarget)) { InMeleeRange = true; break; @@ -891,7 +891,7 @@ struct MANGOS_DLL_DECL boss_warlord_salarisAI : public boss_priestess_lackey_com if (Unit* target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid())) { //if in melee range - if (target->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(target)) { InMeleeRange = true; break; @@ -1007,7 +1007,7 @@ struct MANGOS_DLL_DECL boss_garaxxasAI : public boss_priestess_lackey_commonAI boss_priestess_lackey_commonAI::UpdateAI(diff); - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { if (Wing_Clip_Timer < diff) { diff --git a/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp b/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp index 5f7f23723..938ba97f3 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp b/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp index 34cf1fa2d..b53293042 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp b/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp index 111c2ecf6..5c932ce7e 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp b/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp index 034f8d630..de03f9658 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h b/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h index b97628757..e8345ca83 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h +++ b/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp b/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp index 5f4136d05..0c51a8a8f 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,73 +17,112 @@ /* ScriptData SDName: Boss_Baron_Geddon SD%Complete: 100 -SDComment: +SDComment: Armaggedon is not working properly (core issue) SDCategory: Molten Core EndScriptData */ #include "precompiled.h" +#include "molten_core.h" -#define EMOTE_SERVICE -1409000 +enum +{ + EMOTE_SERVICE = -1409000, -#define SPELL_INFERNO 19695 -#define SPELL_IGNITEMANA 19659 -#define SPELL_LIVINGBOMB 20475 -#define SPELL_ARMAGEDDOM 20479 + SPELL_INFERNO = 19695, + SPELL_IGNITE_MANA = 19659, + SPELL_LIVING_BOMB = 20475, + SPELL_ARMAGEDDON = 20478 +}; struct MANGOS_DLL_DECL boss_baron_geddonAI : public ScriptedAI { - boss_baron_geddonAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_baron_geddonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 Inferno_Timer; - uint32 IgniteMana_Timer; - uint32 LivingBomb_Timer; + bool m_bIsArmageddon; + uint32 m_uiInfernoTimer; + uint32 m_uiIgniteManaTimer; + uint32 m_uiLivingBombTimer; void Reset() { - Inferno_Timer = 45000; //These times are probably wrong - IgniteMana_Timer = 30000; - LivingBomb_Timer = 35000; + m_bIsArmageddon = false; + m_uiInfernoTimer = 45000; + m_uiIgniteManaTimer = 30000; + m_uiLivingBombTimer = 35000; + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GEDDON, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GEDDON, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GEDDON, NOT_STARTED); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //If we are <2% hp cast Armageddom - if (m_creature->GetHealthPercent() <= 2.0f) - { - m_creature->InterruptNonMeleeSpells(true); - - DoCastSpellIfCan(m_creature,SPELL_ARMAGEDDOM); - DoScriptText(EMOTE_SERVICE, m_creature); + if (m_bIsArmageddon) // Do nothing untill armageddon triggers return; - } - //Inferno_Timer - if (Inferno_Timer < diff) + // If we are <2% hp cast Armageddom + if (m_creature->GetHealthPercent() <= 2.0f && !m_bIsArmageddon) { - DoCastSpellIfCan(m_creature,SPELL_INFERNO); - Inferno_Timer = 45000; - }else Inferno_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_ARMAGEDDON, CAST_INTERRUPT_PREVIOUS) == CAST_OK) + { + DoScriptText(EMOTE_SERVICE, m_creature); + m_bIsArmageddon = true; + return; + } + } - //IgniteMana_Timer - if (IgniteMana_Timer < diff) + // Inferno_Timer + if (m_uiInfernoTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_IGNITEMANA); - - IgniteMana_Timer = 30000; - }else IgniteMana_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_INFERNO) == CAST_OK) + m_uiInfernoTimer = 45000; + } + else + m_uiInfernoTimer -= uiDiff; - //LivingBomb_Timer - if (LivingBomb_Timer < diff) + // Ignite Mana Timer + if (m_uiIgniteManaTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_LIVINGBOMB); + if (DoCastSpellIfCan(m_creature, SPELL_IGNITE_MANA) == CAST_OK) + m_uiIgniteManaTimer = 30000; + } + else + m_uiIgniteManaTimer -= uiDiff; - LivingBomb_Timer = 35000; - }else LivingBomb_Timer -= diff; + // 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(); } @@ -96,9 +135,10 @@ CreatureAI* GetAI_boss_baron_geddon(Creature* pCreature) void AddSC_boss_baron_geddon() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_baron_geddon"; - newscript->GetAI = &GetAI_boss_baron_geddon; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_baron_geddon"; + pNewScript->GetAI = &GetAI_boss_baron_geddon; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_garr.cpp b/scripts/eastern_kingdoms/molten_core/boss_garr.cpp index 847c4d14e..e2aa7d50e 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_garr.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_garr.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,56 +17,88 @@ /* ScriptData SDName: Boss_Garr SD%Complete: 50 -SDComment: Adds NYI +SDComment: Garr's enrage is missing SDCategory: Molten Core EndScriptData */ #include "precompiled.h" +#include "molten_core.h" -// Garr spells -#define SPELL_ANTIMAGICPULSE 19492 -#define SPELL_MAGMASHACKLES 19496 -#define SPELL_ENRAGE 19516 //Stacking enrage (stacks to 10 times) - -//Add spells -#define SPELL_ERUPTION 19497 -#define SPELL_IMMOLATE 20294 +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 MANGOS_DLL_DECL boss_garrAI : public ScriptedAI { - boss_garrAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_garrAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 AntiMagicPulse_Timer; - uint32 MagmaShackles_Timer; - uint32 CheckAdds_Timer; - uint64 Add[8]; - bool Enraged[8]; + uint32 m_uiAntiMagicPulseTimer; + uint32 m_uiMagmaShacklesTimer; void Reset() { - AntiMagicPulse_Timer = 25000; //These times are probably wrong - MagmaShackles_Timer = 15000; - CheckAdds_Timer = 2000; + m_uiAntiMagicPulseTimer = 25000; + m_uiMagmaShacklesTimer = 15000; + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GARR, IN_PROGRESS); + + m_creature->CallForHelp(RANGE_CALL_FOR_HELP); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GARR, DONE); } - void UpdateAI(const uint32 diff) + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GARR, FAIL); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //AntiMagicPulse_Timer - if (AntiMagicPulse_Timer < diff) + // AntiMagicPulse_Timer + if (m_uiAntiMagicPulseTimer < uiDiff) { - DoCastSpellIfCan(m_creature,SPELL_ANTIMAGICPULSE); - AntiMagicPulse_Timer = urand(10000, 15000); - }else AntiMagicPulse_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_ANTIMAGICPULSE) == CAST_OK) + m_uiAntiMagicPulseTimer = urand(10000, 15000); + } + else + m_uiAntiMagicPulseTimer -= uiDiff; - //MagmaShackles_Timer - if (MagmaShackles_Timer < diff) + // MagmaShackles_Timer + if (m_uiMagmaShacklesTimer < uiDiff) { - DoCastSpellIfCan(m_creature,SPELL_MAGMASHACKLES); - MagmaShackles_Timer = urand(8000, 12000); - }else MagmaShackles_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_MAGMASHACKLES) == CAST_OK) + m_uiMagmaShacklesTimer = urand(8000, 12000); + } + else + m_uiMagmaShacklesTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -74,33 +106,55 @@ struct MANGOS_DLL_DECL boss_garrAI : public ScriptedAI struct MANGOS_DLL_DECL mob_fireswornAI : public ScriptedAI { - mob_fireswornAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + mob_fireswornAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } - uint32 Immolate_Timer; + ScriptedInstance* m_pInstance; + + uint32 m_uiImmolateTimer; + uint32 m_uiSeparationCheckTimer; void Reset() { - Immolate_Timer = 4000; //These times are probably wrong + m_uiImmolateTimer = urand(4000, 8000); // These times are probably wrong + m_uiSeparationCheckTimer = 5000; } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Immolate_Timer - if (Immolate_Timer < diff) + // 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) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_IMMOLATE); + // Distance guesswork, but should be ok + Creature* pGarr = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_GARR)); + if (pGarr && pGarr->isAlive() && !m_creature->IsWithinDist2d(pGarr->GetPositionX(), pGarr->GetPositionY(), 50.0f)) + DoCastSpellIfCan(m_creature, SPELL_SEPARATION_ANXIETY, CAST_TRIGGERED); - Immolate_Timer = urand(5000, 10000); - }else Immolate_Timer -= diff; + m_uiSeparationCheckTimer = 5000; + } + else + m_uiSeparationCheckTimer -= uiDiff; - //Cast Erruption and let them die + // Cast Erruption and let them die if (m_creature->GetHealthPercent() <= 10.0f) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ERUPTION); + DoCastSpellIfCan(m_creature->getVictim(), SPELL_ERUPTION); m_creature->SetDeathState(JUST_DIED); m_creature->RemoveCorpse(); } @@ -108,6 +162,7 @@ struct MANGOS_DLL_DECL mob_fireswornAI : public ScriptedAI DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_garr(Creature* pCreature) { return new boss_garrAI(pCreature); @@ -120,15 +175,15 @@ CreatureAI* GetAI_mob_firesworn(Creature* pCreature) void AddSC_boss_garr() { - Script *newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "boss_garr"; - newscript->GetAI = &GetAI_boss_garr; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "boss_garr"; + pNewScript->GetAI = &GetAI_boss_garr; + pNewScript->RegisterSelf(); - newscript = new Script; - newscript->Name = "mob_firesworn"; - newscript->GetAI = &GetAI_mob_firesworn; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "mob_firesworn"; + pNewScript->GetAI = &GetAI_mob_firesworn; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp b/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp index f5b181d75..52aa715a2 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,63 +17,105 @@ /* ScriptData SDName: Boss_Gehennas SD%Complete: 90 -SDComment: Adds MC NYI +SDComment: SDCategory: Molten Core EndScriptData */ #include "precompiled.h" +#include "molten_core.h" -#define SPELL_SHADOWBOLT 19728 -#define SPELL_RAINOFFIRE 19717 -#define SPELL_GEHENNASCURSE 19716 +enum +{ + SPELL_SHADOW_BOLT = 19728, // 19729 exists too, but can be reflected + SPELL_RAIN_OF_FIRE = 19717, + SPELL_GEHENNAS_CURSE = 19716 +}; struct MANGOS_DLL_DECL boss_gehennasAI : public ScriptedAI { - boss_gehennasAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_gehennasAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 ShadowBolt_Timer; - uint32 RainOfFire_Timer; - uint32 GehennasCurse_Timer; + uint32 m_uiShadowBoltTimer; + uint32 m_uiRainOfFireTimer; + uint32 m_uiGehennasCurseTimer; void Reset() { - ShadowBolt_Timer = 6000; - RainOfFire_Timer = 10000; - GehennasCurse_Timer = 12000; + m_uiShadowBoltTimer = 6000; + m_uiRainOfFireTimer = 10000; + m_uiGehennasCurseTimer = 12000; + } + + void Aggro(Unit* pwho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GEHENNAS, IN_PROGRESS); + + m_creature->CallForHelp(RANGE_CALL_FOR_HELP); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GEHENNAS, DONE); } - void UpdateAI(const uint32 diff) + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GEHENNAS, FAIL); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ShadowBolt_Timer - if (ShadowBolt_Timer < diff) + // ShadowBolt Timer + if (m_uiShadowBoltTimer < uiDiff) { - if (Unit* bTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) - DoCastSpellIfCan(bTarget,SPELL_SHADOWBOLT); - ShadowBolt_Timer = 7000; - }else ShadowBolt_Timer -= diff; + 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; - //RainOfFire_Timer - if (RainOfFire_Timer < diff) + // Rain of Fire Timer + if (m_uiRainOfFireTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_RAINOFFIRE); - - RainOfFire_Timer = urand(4000, 12000); - }else RainOfFire_Timer -= diff; + 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 (GehennasCurse_Timer < diff) + // GehennasCurse Timer + if (m_uiGehennasCurseTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_GEHENNASCURSE); - GehennasCurse_Timer = urand(22000, 30000); - }else GehennasCurse_Timer -= diff; + 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); @@ -81,9 +123,10 @@ CreatureAI* GetAI_boss_gehennas(Creature* pCreature) void AddSC_boss_gehennas() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_gehennas"; - newscript->GetAI = &GetAI_boss_gehennas; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_gehennas"; + pNewScript->GetAI = &GetAI_boss_gehennas; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp b/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp index 2c776fca8..8fa766ef0 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Golemagg -SD%Complete: 75 -SDComment: Timers need to be confirmed, Golemagg's Trust need to be checked +SD%Complete: 80 +SDComment: Rager need to be tied to boss (Despawn on boss-death) SDCategory: Molten Core EndScriptData */ @@ -26,14 +26,14 @@ EndScriptData */ enum { - SPELL_MAGMASPLASH = 13879, + SPELL_MAGMA_SPLASH = 13879, SPELL_PYROBLAST = 20228, SPELL_EARTHQUAKE = 19798, SPELL_ENRAGE = 19953, SPELL_GOLEMAGG_TRUST = 20553, // Core Rager - EMOTE_LOWHP = -1409002, + EMOTE_LOW_HP = -1409002, SPELL_MANGLE = 19820 }; @@ -54,12 +54,20 @@ struct MANGOS_DLL_DECL boss_golemaggAI : public ScriptedAI void Reset() { - m_uiPyroblastTimer = 7*IN_MILLISECONDS; // These timers are probably wrong - m_uiEarthquakeTimer = 3*IN_MILLISECONDS; - m_uiBuffTimer = 2.5*IN_MILLISECONDS; + 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_MAGMASPLASH, true); + m_creature->CastSpell(m_creature, SPELL_MAGMA_SPLASH, true); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GOLEMAGG, IN_PROGRESS); + + m_creature->CallForHelp(1.5 * RANGE_CALL_FOR_HELP); } void JustDied(Unit* pKiller) @@ -68,6 +76,12 @@ struct MANGOS_DLL_DECL boss_golemaggAI : public ScriptedAI m_pInstance->SetData(TYPE_GOLEMAGG, DONE); } + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GOLEMAGG, FAIL); + } + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) @@ -77,9 +91,10 @@ struct MANGOS_DLL_DECL boss_golemaggAI : public ScriptedAI if (m_uiPyroblastTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, SPELL_PYROBLAST); - - m_uiPyroblastTimer = 7*IN_MILLISECONDS; + { + if (DoCastSpellIfCan(pTarget, SPELL_PYROBLAST) == CAST_OK) + m_uiPyroblastTimer = 7*IN_MILLISECONDS; + } } else m_uiPyroblastTimer -= uiDiff; @@ -87,8 +102,8 @@ struct MANGOS_DLL_DECL boss_golemaggAI : public ScriptedAI // Enrage if (!m_bEnraged && m_creature->GetHealthPercent() < 10.0f) { - DoCastSpellIfCan(m_creature, SPELL_ENRAGE); - m_bEnraged = true; + if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) + m_bEnraged = true; } // Earthquake @@ -96,23 +111,21 @@ struct MANGOS_DLL_DECL boss_golemaggAI : public ScriptedAI { if (m_uiEarthquakeTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_EARTHQUAKE); - m_uiEarthquakeTimer = 3*IN_MILLISECONDS; + 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 = 2.5*IN_MILLISECONDS; + m_uiBuffTimer = 1.5*IN_MILLISECONDS; } else m_uiBuffTimer -= uiDiff; - */ DoMeleeAttackIfReady(); } @@ -138,18 +151,11 @@ struct MANGOS_DLL_DECL mob_core_ragerAI : public ScriptedAI { if (m_creature->GetHealthPercent() < 50.0f) { - if (m_pInstance) + if (m_pInstance && m_pInstance->GetData(TYPE_GOLEMAGG) != DONE) { - if (Creature* pGolemagg = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_GOLEMAGG))) - { - if (pGolemagg->isAlive()) - { - DoScriptText(EMOTE_LOWHP, m_creature); - m_creature->SetHealth(m_creature->GetMaxHealth()); - } - else - uiDamage = m_creature->GetHealth(); - } + DoScriptText(EMOTE_LOW_HP, m_creature); + m_creature->SetHealth(m_creature->GetMaxHealth()); + uiDamage = 0; } } } @@ -162,8 +168,8 @@ struct MANGOS_DLL_DECL mob_core_ragerAI : public ScriptedAI // Mangle if (m_uiMangleTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_MANGLE); - m_uiMangleTimer = 10*IN_MILLISECONDS; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MANGLE) == CAST_OK) + m_uiMangleTimer = 10*IN_MILLISECONDS; } else m_uiMangleTimer -= uiDiff; @@ -184,15 +190,15 @@ CreatureAI* GetAI_mob_core_rager(Creature* pCreature) void AddSC_boss_golemagg() { - Script* newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "boss_golemagg"; - newscript->GetAI = &GetAI_boss_golemagg; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "boss_golemagg"; + pNewScript->GetAI = &GetAI_boss_golemagg; + pNewScript->RegisterSelf(); - newscript = new Script; - newscript->Name = "mob_core_rager"; - newscript->GetAI = &GetAI_mob_core_rager; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "mob_core_rager"; + pNewScript->GetAI = &GetAI_mob_core_rager; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp b/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp index 44dc42ef0..0bbb453f5 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,55 +22,95 @@ SDCategory: Molten Core EndScriptData */ #include "precompiled.h" +#include "molten_core.h" -#define SPELL_IMPENDINGDOOM 19702 -#define SPELL_LUCIFRONCURSE 19703 -#define SPELL_SHADOWSHOCK 20603 +enum +{ + SPELL_IMPENDINGDOOM = 19702, + SPELL_LUCIFRONCURSE = 19703, + SPELL_SHADOWSHOCK = 19460 +}; struct MANGOS_DLL_DECL boss_lucifronAI : public ScriptedAI { - boss_lucifronAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_lucifronAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 ImpendingDoom_Timer; - uint32 LucifronCurse_Timer; - uint32 ShadowShock_Timer; + uint32 m_uiImpendingDoomTimer; + uint32 m_uiLucifronCurseTimer; + uint32 m_uiShadowShockTimer; void Reset() { - ImpendingDoom_Timer = 10000; //Initial cast after 10 seconds so the debuffs alternate - LucifronCurse_Timer = 20000; //Initial cast after 20 seconds - ShadowShock_Timer = 6000; //6 seconds + m_uiImpendingDoomTimer = 10000; + m_uiLucifronCurseTimer = 20000; + m_uiShadowShockTimer = 6000; + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_LUCIFRON, IN_PROGRESS); + + m_creature->CallForHelp(RANGE_CALL_FOR_HELP); } - void UpdateAI(const uint32 diff) + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_LUCIFRON, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_LUCIFRON, FAIL); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Impending doom timer - if (ImpendingDoom_Timer < diff) + // Impending doom timer + if (m_uiImpendingDoomTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_IMPENDINGDOOM); - ImpendingDoom_Timer = 20000; - }else ImpendingDoom_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_IMPENDINGDOOM) == CAST_OK) + m_uiImpendingDoomTimer = 20000; + } + else + m_uiImpendingDoomTimer -= uiDiff; - //Lucifron's curse timer - if (LucifronCurse_Timer < diff) + // Lucifron's curse timer + if (m_uiLucifronCurseTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_LUCIFRONCURSE); - LucifronCurse_Timer = 15000; - }else LucifronCurse_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_LUCIFRONCURSE) == CAST_OK) + m_uiLucifronCurseTimer = 20000; + } + else + m_uiLucifronCurseTimer -= uiDiff; - //Shadowshock - if (ShadowShock_Timer < diff) + // Shadowshock + if (m_uiShadowShockTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SHADOWSHOCK); - ShadowShock_Timer = 6000; - }else ShadowShock_Timer -= diff; + 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); @@ -78,9 +118,10 @@ CreatureAI* GetAI_boss_lucifron(Creature* pCreature) void AddSC_boss_lucifron() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_lucifron"; - newscript->GetAI = &GetAI_boss_lucifron; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_lucifron"; + pNewScript->GetAI = &GetAI_boss_lucifron; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp b/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp index f3bae4976..d73ee07ef 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,68 +17,102 @@ /* ScriptData SDName: Boss_Magmadar SD%Complete: 75 -SDComment: Conflag on ground nyi, fear causes issues without VMAPs +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_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 //This is the spell that the lava bomb casts + SPELL_LAVABOMB = 19411, // This calls a dummy server side effect that isn't implemented yet + SPELL_LAVABOMB_ALT = 19428 }; struct MANGOS_DLL_DECL boss_magmadarAI : public ScriptedAI { - boss_magmadarAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_magmadarAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } - uint32 Frenzy_Timer; - uint32 Panic_Timer; - uint32 Lavabomb_Timer; + ScriptedInstance* m_pInstance; + + uint32 m_uiFrenzyTimer; + uint32 m_uiPanicTimer; + uint32 m_uiLavabombTimer; void Reset() { - Frenzy_Timer = 30000; - Panic_Timer = 20000; - Lavabomb_Timer = 12000; + m_uiFrenzyTimer = 30000; + m_uiPanicTimer = 7000; + m_uiLavabombTimer = 12000; + } + + void Aggro(Unit* pWho) + { + DoCastSpellIfCan(m_creature, SPELL_MAGMASPIT, true); + + if (m_pInstance) + m_pInstance->SetData(TYPE_MAGMADAR, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_MAGMADAR, DONE); + } - m_creature->CastSpell(m_creature,SPELL_MAGMASPIT,true); + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_MAGMADAR, NOT_STARTED); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Frenzy_Timer - if (Frenzy_Timer < diff) + // Frenzy_Timer + if (m_uiFrenzyTimer < uiDiff) { - DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature); - DoCastSpellIfCan(m_creature,SPELL_FRENZY); - Frenzy_Timer = 15000; - }else Frenzy_Timer -= diff; - - //Panic_Timer - if (Panic_Timer < diff) + 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) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_PANIC); - Panic_Timer = 35000; - }else Panic_Timer -= diff; - - //Lavabomb_Timer - if (Lavabomb_Timer < diff) + if (DoCastSpellIfCan(m_creature, SPELL_PANIC) == CAST_OK) + m_uiPanicTimer = 30000; + } + else + m_uiPanicTimer -= uiDiff; + + // Lavabomb_Timer + if (m_uiLavabombTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_LAVABOMB_ALT); - - Lavabomb_Timer = 12000; - }else Lavabomb_Timer -= diff; + 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(); } @@ -91,9 +125,10 @@ CreatureAI* GetAI_boss_magmadar(Creature* pCreature) void AddSC_boss_magmadar() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_magmadar"; - newscript->GetAI = &GetAI_boss_magmadar; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_magmadar"; + pNewScript->GetAI = &GetAI_boss_magmadar; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp b/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp index 24cfb9dfe..cbd6c0842 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,62 +16,92 @@ /* ScriptData SDName: Boss_Majordomo_Executus -SD%Complete: 30 -SDComment: Correct spawning and Event NYI +SD%Complete: 95 +SDComment: Minor weaknesses SDCategory: Molten Core EndScriptData */ #include "precompiled.h" +#include "molten_core.h" +#include "TemporarySummon.h" -#define SAY_AGGRO -1409003 -#define SAY_SPAWN -1409004 -#define SAY_SLAY -1409005 -#define SAY_SPECIAL -1409006 -#define SAY_DEFEAT -1409007 - -#define SAY_SUMMON_MAJ -1409008 -#define SAY_ARRIVAL1_RAG -1409009 -#define SAY_ARRIVAL2_MAJ -1409010 -#define SAY_ARRIVAL3_RAG -1409011 -#define SAY_ARRIVAL5_RAG -1409012 - -#define SPAWN_RAG_X 838.51 -#define SPAWN_RAG_Y -829.84 -#define SPAWN_RAG_Z -232.00 -#define SPAWN_RAG_O 1.70 - -#define SPELL_MAGIC_REFLECTION 20619 -#define SPELL_DAMAGE_REFLECTION 21075 -#define SPELL_BLASTWAVE 20229 -#define SPELL_AEGIS 20620 //This is self casted whenever we are below 50% -#define SPELL_TELEPORT 20618 -#define SPELL_SUMMON_RAGNAROS 19774 - -#define ENTRY_FLAMEWALKER_HEALER 11663 -#define ENTRY_FLAMEWALKER_ELITE 11664 +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 MANGOS_DLL_DECL boss_majordomoAI : public ScriptedAI { boss_majordomoAI(Creature* pCreature) : ScriptedAI(pCreature) { - m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_pInstance = (instance_molten_core*)pCreature->GetInstanceData(); + m_bHasEncounterFinished = false; Reset(); } - ScriptedInstance* m_pInstance; + instance_molten_core* m_pInstance; - uint32 MagicReflection_Timer; - uint32 DamageReflection_Timer; - uint32 Blastwave_Timer; + uint32 m_uiMagicReflectionTimer; + uint32 m_uiDamageReflectionTimer; + uint32 m_uiBlastwaveTimer; + uint32 m_uiTeleportTimer; + uint32 m_uiAegisTimer; + uint32 m_uiSpeechTimer; + + uint64 m_uiRagnarosGUID; + bool m_bHasEncounterFinished; + uint8 m_uiAddsKilled; + uint8 m_uiSpeech; + GUIDList m_luiMajordomoAddsGUIDs; void Reset() { - MagicReflection_Timer = 30000; //Damage reflection first so we alternate - DamageReflection_Timer = 15000; - Blastwave_Timer = 10000; + 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_uiRagnarosGUID = 0; + m_uiAddsKilled = 0; + m_uiSpeech = 0; } - void KilledUnit(Unit* victim) + void KilledUnit(Unit* pVictim) { if (urand(0, 4)) return; @@ -79,60 +109,375 @@ struct MANGOS_DLL_DECL boss_majordomoAI : public ScriptedAI DoScriptText(SAY_SLAY, m_creature); } - void Aggro(Unit *who) + void Aggro(Unit* pWho) { + 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 UpdateAI(const uint32 diff) + void JustReachedHome() { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + if (!m_bHasEncounterFinished) // Normal reached home, FAIL + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_MAJORDOMO, FAIL); + m_pInstance->DoHandleAdds(m_luiMajordomoAddsGUIDs); + } + } + else // Finished the encounter, DONE + { + // Exit combat + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + m_creature->SetLootRecipient(NULL); + + // Set friendly + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->setFaction(FACTION_MAJORDOMO_FRIENDLY); + + // 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 (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_uiRagnarosGUID)) return; - //Cast Ageis if less than 50% hp - if (m_creature->GetHealthPercent() < 50.0f) + DoScriptText(SAY_SUMMON_0, m_creature, pPlayer); + + m_uiSpeechTimer = 5000; + m_uiSpeech = 10; + } + + void JustRespawned() + { + // 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) + { + if (pSummoned->GetEntry() == NPC_FLAMEWAKER_HEALER || pSummoned->GetEntry() == NPC_FLAMEWAKER_ELITE) + { + m_luiMajordomoAddsGUIDs.push_back(pSummoned->GetGUID()); + pSummoned->SetRespawnDelay(2*HOUR); + } + else if (pSummoned->GetEntry() == NPC_RAGNAROS) + { + m_uiRagnarosGUID = pSummoned->GetGUID(); + pSummoned->CastSpell(pSummoned, SPELL_RAGNA_EMERGE, false); + } + } + + void JustDied(Unit* pKiller) + { + if (pKiller->GetTypeId() == TYPEID_UNIT && pKiller->GetEntry() == NPC_RAGNAROS) + DoScriptText(SAY_ARRIVAL4_MAJ, m_creature); + } + + void CorpseRemoved(uint32 &uiRespawnDelay) + { + 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) + { + 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 (std::list::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) + { + if (uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + DoCastSpellIfCan(m_creature, SPELL_AEGIS, CAST_TRIGGERED); + } + } + + void UpdateAI(const uint32 uiDiff) + { + // Handling of his combat-end speech and Ragnaros summoning + if (m_uiSpeech) { - DoCastSpellIfCan(m_creature,SPELL_AEGIS); + 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->instance->GetGameObject(m_pInstance->GetData64(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->instance->GetGameObject(m_pInstance->GetData64(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_OR_DEAD_DESPAWN, 2*HOUR*IN_MILLISECONDS); + ++m_uiSpeech; + m_uiSpeechTimer = 8700; + break; + case 15: + if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_uiRagnarosGUID)) + 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_uiRagnarosGUID)) + DoScriptText(SAY_ARRIVAL3_RAG, pRagnaros); + ++m_uiSpeech; + m_uiSpeechTimer = 16500; + break; + case 18: + if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_uiRagnarosGUID)) + 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; } - //MagicReflection_Timer - // if (MagicReflection_Timer < diff) - // { - // DoCastSpellIfCan(m_creature, SPELL_MAGICREFLECTION); + // 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; + } - //60 seconds until we should cast this agian - // MagicReflection_Timer = 30000; - // }else MagicReflection_Timer -= diff; + // Magic Reflection Timer + if (m_uiMagicReflectionTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_MAGIC_REFLECTION) == CAST_OK) + m_uiMagicReflectionTimer = 30000; + } + else + m_uiMagicReflectionTimer -= uiDiff; - //DamageReflection_Timer - // if (DamageReflection_Timer < diff) - // { - // DoCastSpellIfCan(m_creature, SPELL_DAMAGEREFLECTION); + // Damage Reflection Timer + if (m_uiDamageReflectionTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_DAMAGE_REFLECTION) == CAST_OK) + m_uiDamageReflectionTimer = 30000; + } + else + m_uiDamageReflectionTimer -= uiDiff; - //60 seconds until we should cast this agian - // DamageReflection_Timer = 30000; - // }else DamageReflection_Timer -= diff; + // 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 (Blastwave_Timer < diff) + // Blastwave Timer + if (m_uiBlastwaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_BLASTWAVE); - Blastwave_Timer = 10000; - }else Blastwave_Timer -= diff; + 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->GetGUID()); + } + } + 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->GetGUID()); + 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->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + pPlayer->CLOSE_GOSSIP_MENU(); + if (boss_majordomoAI* pMajoAI = dynamic_cast(pCreature->AI())) + pMajoAI->StartSummonEvent(pPlayer); + break; + } + + return true; +} + +bool EffectDummyCreature_spell_boss_majordomo(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +{ + 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 *newscript; - newscript = new Script; - newscript->Name = "boss_majordomo"; - newscript->GetAI = &GetAI_boss_majordomo; - newscript->RegisterSelf(); + 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(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp b/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp index 2d82991a6..c2354be0d 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,266 +16,328 @@ /* ScriptData SDName: Boss_Ragnaros -SD%Complete: 75 -SDComment: Intro Dialog and event NYI +SD%Complete: 60 +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" -#define SAY_REINFORCEMENTS1 -1409013 -#define SAY_REINFORCEMENTS2 -1409014 -#define SAY_HAND -1409015 -#define SAY_WRATH -1409016 -#define SAY_KILL -1409017 -#define SAY_MAGMABURST -1409018 - -#define SPELL_HANDOFRAGNAROS 19780 -#define SPELL_WRATHOFRAGNAROS 20566 -#define SPELL_LAVABURST 21158 - -#define SPELL_MAGMABURST 20565 //Ranged attack - -#define SPELL_SONSOFFLAME_DUMMY 21108 //Server side effect -#define SPELL_RAGSUBMERGE 21107 //Stealth aura -#define SPELL_RAGEMERGE 20568 -#define SPELL_MELTWEAPON 21388 -#define SPELL_ELEMENTALFIRE 20564 -#define SPELL_ERRUPTION 17731 - -#define ADD_1X 848.740356 -#define ADD_1Y -816.103455 -#define ADD_1Z -229.74327 -#define ADD_1O 2.615287 - -#define ADD_2X 852.560791 -#define ADD_2Y -849.861511 -#define ADD_2Z -228.560974 -#define ADD_2O 2.836073 - -#define ADD_3X 808.710632 -#define ADD_3Y -852.845764 -#define ADD_3Z -227.914963 -#define ADD_3O 0.964207 - -#define ADD_4X 786.597107 -#define ADD_4Y -821.132874 -#define ADD_4Z -226.350128 -#define ADD_4O 0.949377 - -#define ADD_5X 796.219116 -#define ADD_5Y -800.948059 -#define ADD_5Z -226.010361 -#define ADD_5O 0.560603 - -#define ADD_6X 821.602539 -#define ADD_6Y -782.744109 -#define ADD_6Z -226.023575 -#define ADD_6O 6.157440 - -#define ADD_7X 844.924744 -#define ADD_7Y -769.453735 -#define ADD_7Z -225.521698 -#define ADD_7O 4.4539958 - -#define ADD_8X 839.823364 -#define ADD_8Y -810.869385 -#define ADD_8Z -229.683182 -#define ADD_8O 4.693108 - -struct MANGOS_DLL_DECL boss_ragnarosAI : public ScriptedAI +/* There have been quite some bugs about his spells, keep this as reference untill all finished + * Missing features (based on wowwiki) + * Lava Splash - Localized Damage + * Melt Weapon - Proc Aura missing in DBC, or hack missing + */ + +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 = 21388, // Passive aura was spell 21387, TODO need some hack.. + 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 MANGOS_DLL_DECL boss_ragnarosAI : public Scripted_NoMovementAI { - boss_ragnarosAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_ragnarosAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) { - SetCombatMovement(false); + m_pInstance = (instance_molten_core*)pCreature->GetInstanceData(); + m_uiEnterCombatTimer = 0; + m_bHasAggroYelled = false; Reset(); } - uint32 WrathOfRagnaros_Timer; - uint32 HandOfRagnaros_Timer; - uint32 LavaBurst_Timer; - uint32 MagmaBurst_Timer; - uint32 ElementalFire_Timer; - uint32 Erruption_Timer; - uint32 Submerge_Timer; - uint32 Attack_Timer; - Creature *Summoned; - bool HasYelledMagmaBurst; - bool HasSubmergedOnce; - bool WasBanished; - bool HasAura; + 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() { - WrathOfRagnaros_Timer = 30000; - HandOfRagnaros_Timer = 25000; - LavaBurst_Timer = 10000; - MagmaBurst_Timer = 2000; - Erruption_Timer = 15000; - ElementalFire_Timer = 3000; - Submerge_Timer = 180000; - Attack_Timer = 90000; - HasYelledMagmaBurst = false; - HasSubmergedOnce = false; - WasBanished = false; - - m_creature->CastSpell(m_creature,SPELL_MELTWEAPON,true); - HasAura = true; + 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* victim) + void KilledUnit(Unit* pVictim) { - if (urand(0, 4)) + if (pVictim->GetTypeId() != TYPEID_PLAYER) + return; + + if (urand(0, 3)) return; DoScriptText(SAY_KILL, m_creature); } - void UpdateAI(const uint32 diff) + void JustDied(Unit* pKiller) { - if (WasBanished && Attack_Timer < diff) - { - //Become unbanished again - m_creature->setFaction(14); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - DoCastSpellIfCan(m_creature,SPELL_RAGEMERGE); - WasBanished = false; - } else if (WasBanished) - { - Attack_Timer -= diff; - //Do nothing while banished - return; - } + if (m_pInstance) + m_pInstance->SetData(TYPE_RAGNAROS, DONE); + } - //Return since we have no target - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + void Aggro(Unit* pWho) + { + if (pWho->GetTypeId() == TYPEID_UNIT && pWho->GetEntry() == NPC_MAJORDOMO) return; - //WrathOfRagnaros_Timer - if (WrathOfRagnaros_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_WRATHOFRAGNAROS); + if (m_pInstance) + m_pInstance->SetData(TYPE_RAGNAROS, IN_PROGRESS); + } - if (urand(0, 1)) - DoScriptText(SAY_WRATH, m_creature); + void EnterEvadeMode() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_RAGNAROS, FAIL); - WrathOfRagnaros_Timer = 30000; - }else WrathOfRagnaros_Timer -= diff; + // 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); - //HandOfRagnaros_Timer - if (HandOfRagnaros_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_HANDOFRAGNAROS); + ScriptedAI::EnterEvadeMode(); + } - if (urand(0, 1)) - DoScriptText(SAY_HAND, m_creature); + void SummonedCreatureJustDied(Creature* pSummmoned) + { + // If all Sons of Flame are dead, trigger emerge + if (pSummmoned->GetEntry() == NPC_SON_OF_FLAME) + { + m_uiAddCount--; - HandOfRagnaros_Timer = 25000; - }else HandOfRagnaros_Timer -= diff; + // If last add killed then emerge soonish + if (m_uiAddCount == 0) + m_uiAttackTimer = std::min(m_uiAttackTimer, (uint32)1000); + } + } - //LavaBurst_Timer - if (LavaBurst_Timer < diff) + void JustSummoned(Creature* pSummoned) + { + if (pSummoned->GetEntry() == NPC_SON_OF_FLAME) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_LAVABURST); - LavaBurst_Timer = 10000; - }else LavaBurst_Timer -= diff; + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); - //Erruption_Timer - if (LavaBurst_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ERRUPTION); - Erruption_Timer = urand(20000, 45000); - }else Erruption_Timer -= diff; + ++m_uiAddCount; + } + else if (pSummoned->GetEntry() == NPC_FLAME_OF_RAGNAROS) + pSummoned->CastSpell(pSummoned, SPELL_INTENSE_HEAT, true, NULL, NULL, m_creature->GetObjectGuid()); + } - //ElementalFire_Timer - if (ElementalFire_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ELEMENTALFIRE); - ElementalFire_Timer = urand(10000, 14000); - }else ElementalFire_Timer -= diff; + void SpellHitTarget(Unit* pTarget, const SpellEntry* pSpell) + { + // 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; + } - //Submerge_Timer - if (!WasBanished && Submerge_Timer < diff) + void UpdateAI(const uint32 uiDiff) + { + if (m_uiEnterCombatTimer) { - //Creature spawning and ragnaros becomming unattackable - //is not very well supported in the core - //so added normaly spawning and banish workaround and attack again after 90 secs. - - m_creature->InterruptNonMeleeSpells(false); - //Root self - DoCastSpellIfCan(m_creature,23973); - m_creature->setFaction(35); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->HandleEmote(EMOTE_ONESHOT_SUBMERGE); - - if (!HasSubmergedOnce) + if (m_uiEnterCombatTimer <= uiDiff) { - DoScriptText(SAY_REINFORCEMENTS1, m_creature); - - // summon 10 elementals - for(int i = 0; i < 9; ++i) + if (!m_bHasAggroYelled) + { + m_uiEnterCombatTimer = 3000; + m_bHasAggroYelled = true; + DoScriptText(SAY_ARRIVAL5_RAG, m_creature); + } + else { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + 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 (Creature* pSummoned = m_creature->SummonCreature(12143,pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000)) - pSummoned->AI()->AttackStart(pTarget); + 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; - HasSubmergedOnce = true; - WasBanished = true; - DoCastSpellIfCan(m_creature,SPELL_RAGSUBMERGE); - Attack_Timer = 90000; + 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_REINFORCEMENTS2, m_creature); + DoScriptText(SAY_WRATH, m_creature); + m_uiWrathOfRagnarosTimer = 30000; + } + } + else + m_uiWrathOfRagnarosTimer -= uiDiff; - for(int i = 0; i < 9; ++i) + // 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) + { + // Select a target with mana-bar + std::list lValidTargets; + ThreatList const& tList = m_creature->getThreatManager().getThreatList(); + for (ThreatList::const_iterator iter = tList.begin(); iter != tList.end(); ++iter) + { + Unit* pTempTarget = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid()); + if (pTempTarget && pTempTarget->getPowerType() == POWER_MANA) + lValidTargets.push_back(pTempTarget); + } + + if (!lValidTargets.empty()) + { + std::list::const_iterator itr = lValidTargets.begin(); + advance(itr, urand(0, lValidTargets.size() - 1)); + if (DoCastSpellIfCan(*itr, SPELL_MIGHT_OF_RAGNAROS) == CAST_OK) { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - { - if (Creature* pSummoned = m_creature->SummonCreature(12143,pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000)) - pSummoned->AI()->AttackStart(pTarget); - } + 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; - WasBanished = true; - DoCastSpellIfCan(m_creature,SPELL_RAGSUBMERGE); - Attack_Timer = 90000; + 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 = false; + + // 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_DESPAWN_OUT_OF_COMBAT, 1000); } - Submerge_Timer = 180000; - }else Submerge_Timer -= diff; + 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 we are within range melee the target - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { - //Make sure our attack is ready and we arn't currently casting - if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) + // Make sure our attack is ready + if (m_creature->isAttackReady()) { m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); + m_bHasYelledMagmaBurst = false; } } else { - //MagmaBurst_Timer - if (MagmaBurst_Timer < diff) + // Magma Burst Timer + if (m_uiMagmaBlastTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_MAGMABURST); - - if (!HasYelledMagmaBurst) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - DoScriptText(SAY_MAGMABURST, m_creature); - HasYelledMagmaBurst = true; + if (DoCastSpellIfCan(pTarget, SPELL_MAGMA_BLAST) == CAST_OK) + { + if (!m_bHasYelledMagmaBurst) + { + DoScriptText(SAY_MAGMABURST, m_creature); + m_bHasYelledMagmaBurst = true; + } + m_uiMagmaBlastTimer = 1000; // Spamm this! + } } - - MagmaBurst_Timer = 2500; - }else MagmaBurst_Timer -= diff; + } + else + m_uiMagmaBlastTimer -= uiDiff; } } }; + CreatureAI* GetAI_boss_ragnaros(Creature* pCreature) { return new boss_ragnarosAI(pCreature); @@ -283,9 +345,10 @@ CreatureAI* GetAI_boss_ragnaros(Creature* pCreature) void AddSC_boss_ragnaros() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_ragnaros"; - newscript->GetAI = &GetAI_boss_ragnaros; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_ragnaros"; + pNewScript->GetAI = &GetAI_boss_ragnaros; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp b/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp index f5cff54b3..7a83f4c7f 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,96 +17,129 @@ /* ScriptData SDName: Boss_Shazzrah SD%Complete: 75 -SDComment: Teleport NYI +SDComment: Teleport NYI (need core support, remove hack here when implemented) SDCategory: Molten Core EndScriptData */ #include "precompiled.h" +#include "molten_core.h" enum { - SPELL_ARCANEEXPLOSION = 19712, - SPELL_SHAZZRAHCURSE = 19713, - SPELL_DEADENMAGIC = 19714, + SPELL_ARCANE_EXPLOSION = 19712, + SPELL_SHAZZRAH_CURSE = 19713, + SPELL_MAGIC_GROUNDING = 19714, SPELL_COUNTERSPELL = 19715, - SPELL_GATE_DUMMY = 23138 // effect spell: 23139 + SPELL_GATE_OF_SHAZZRAH = 23138 // effect spell: 23139 }; struct MANGOS_DLL_DECL boss_shazzrahAI : public ScriptedAI { - boss_shazzrahAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_shazzrahAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; - uint32 ArcaneExplosion_Timer; - uint32 ShazzrahCurse_Timer; - uint32 DeadenMagic_Timer; - uint32 Countspell_Timer; - uint32 Blink_Timer; + uint32 m_uiArcaneExplosionTimer; + uint32 m_uiShazzrahCurseTimer; + uint32 m_uiMagicGroundingTimer; + uint32 m_uiCounterspellTimer; + uint32 m_uiBlinkTimer; void Reset() { - ArcaneExplosion_Timer = 6000; //These times are probably wrong - ShazzrahCurse_Timer = 10000; - DeadenMagic_Timer = 24000; - Countspell_Timer = 15000; - Blink_Timer = 30000; + m_uiArcaneExplosionTimer = 6000; + m_uiShazzrahCurseTimer = 10000; + m_uiMagicGroundingTimer = 24000; + m_uiCounterspellTimer = 15000; + m_uiBlinkTimer = 30000; + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_SHAZZRAH, IN_PROGRESS); } - void UpdateAI(const uint32 diff) + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_SHAZZRAH, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_SHAZZRAH, NOT_STARTED); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ArcaneExplosion_Timer - if (ArcaneExplosion_Timer < diff) + // Arcane Explosion Timer + if (m_uiArcaneExplosionTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ARCANEEXPLOSION); - ArcaneExplosion_Timer = urand(5000, 9000); - }else ArcaneExplosion_Timer -= diff; - - //ShazzrahCurse_Timer - if (ShazzrahCurse_Timer < diff) + 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) { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_SHAZZRAHCURSE); - - ShazzrahCurse_Timer = urand(25000, 30000); - }else ShazzrahCurse_Timer -= diff; - - //DeadenMagic_Timer - if (DeadenMagic_Timer < diff) + if (DoCastSpellIfCan(m_creature, SPELL_SHAZZRAH_CURSE) == CAST_OK) + m_uiShazzrahCurseTimer = 20000; + } + else + m_uiShazzrahCurseTimer -= uiDiff; + + // Magic Grounding Timer + if (m_uiMagicGroundingTimer < uiDiff) { - DoCastSpellIfCan(m_creature,SPELL_DEADENMAGIC); - DeadenMagic_Timer = 35000; - }else DeadenMagic_Timer -= diff; - - //Countspell_Timer - if (Countspell_Timer < diff) + if (DoCastSpellIfCan(m_creature, SPELL_MAGIC_GROUNDING) == CAST_OK) + m_uiMagicGroundingTimer = 35000; + } + else + m_uiMagicGroundingTimer -= uiDiff; + + // Counterspell Timer + if (m_uiCounterspellTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_COUNTERSPELL); - Countspell_Timer = urand(16000, 20000); - }else Countspell_Timer -= diff; - - //Blink_Timer - if (Blink_Timer < diff) + 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. - DoCastSpellIfCan(m_creature, SPELL_GATE_DUMMY, CAST_TRIGGERED); - - // manual, until added effect of dummy properly - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) - m_creature->NearTeleportTo(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), m_creature->GetOrientation()); - - DoCastSpellIfCan(m_creature, SPELL_ARCANEEXPLOSION); + 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(); - DoResetThreat(); + DoCastSpellIfCan(m_creature, SPELL_ARCANE_EXPLOSION, CAST_TRIGGERED); - Blink_Timer = 45000; - }else Blink_Timer -= diff; + m_uiBlinkTimer = 45000; + } + } + else + m_uiBlinkTimer -= uiDiff; DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_shazzrah(Creature* pCreature) { return new boss_shazzrahAI(pCreature); @@ -114,9 +147,10 @@ CreatureAI* GetAI_boss_shazzrah(Creature* pCreature) void AddSC_boss_shazzrah() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_shazzrah"; - newscript->GetAI = &GetAI_boss_shazzrah; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_shazzrah"; + pNewScript->GetAI = &GetAI_boss_shazzrah; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp b/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp index 1985e5160..ebea28060 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,23 +17,26 @@ /* ScriptData SDName: Boss_Sulfuron_Harbringer SD%Complete: 80 -SDComment: Adds NYI +SDComment: Spells Dark strike and Flamespear need confirmation SDCategory: Molten Core EndScriptData */ #include "precompiled.h" #include "molten_core.h" -#define SPELL_DARKSTRIKE 19777 -#define SPELL_DEMORALIZINGSHOUT 19778 -#define SPELL_INSPIRE 19779 -#define SPELL_KNOCKDOWN 19780 -#define SPELL_FLAMESPEAR 19781 - -//Adds Spells -#define SPELL_HEAL 19775 -#define SPELL_SHADOWWORDPAIN 19776 -#define SPELL_IMMOLATE 20294 +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 MANGOS_DLL_DECL boss_sulfuronAI : public ScriptedAI { @@ -43,77 +46,107 @@ struct MANGOS_DLL_DECL boss_sulfuronAI : public ScriptedAI Reset(); } - uint32 Darkstrike_Timer; - uint32 DemoralizingShout_Timer; - uint32 Inspire_Timer; - uint32 Knockdown_Timer; - uint32 Flamespear_Timer; ScriptedInstance* m_pInstance; + uint32 m_uiDarkstrikeTimer; + uint32 m_uiDemoralizingShoutTimer; + uint32 m_uiInspireTimer; + uint32 m_uiKnockdownTimer; + uint32 m_uiFlamespearTimer; + void Reset() { - Darkstrike_Timer=10000; //These times are probably wrong - DemoralizingShout_Timer = 15000; - Inspire_Timer = 13000; - Knockdown_Timer = 6000; - Flamespear_Timer = 2000; + m_uiDarkstrikeTimer = 10000; + m_uiDemoralizingShoutTimer = 15000; + m_uiInspireTimer = 3000; + m_uiKnockdownTimer = 6000; + m_uiFlamespearTimer = 2000; + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_SULFURON, IN_PROGRESS); + + m_creature->CallForHelp(RANGE_CALL_FOR_HELP); } - void UpdateAI(const uint32 diff) + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_SULFURON, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_SULFURON, FAIL); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //DemoralizingShout_Timer - if (DemoralizingShout_Timer < diff) + // Demoralizing Shout Timer + if (m_uiDemoralizingShoutTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_DEMORALIZINGSHOUT); - DemoralizingShout_Timer = urand(15000, 20000); - }else DemoralizingShout_Timer -= diff; - - //Inspire_Timer - if (Inspire_Timer < diff) + 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* target = NULL; - std::list pList = DoFindFriendlyMissingBuff(45.0f,SPELL_INSPIRE); + Creature* pTarget = NULL; + std::list pList = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE); if (!pList.empty()) { std::list::iterator i = pList.begin(); advance(i, (rand()%pList.size())); - target = (*i); + pTarget = (*i); } - if (target) - DoCastSpellIfCan(target,SPELL_INSPIRE); + if (!pTarget) + pTarget = m_creature; - DoCastSpellIfCan(m_creature,SPELL_INSPIRE); + if (DoCastSpellIfCan(pTarget, SPELL_INSPIRE) == CAST_OK) + m_uiInspireTimer = 10000; + } + else + m_uiInspireTimer -= uiDiff; - Inspire_Timer = urand(20000, 26000); - }else Inspire_Timer -= diff; - - //Knockdown_Timer - if (Knockdown_Timer < diff) + // Hand of Ragnaros Timer + if (m_uiKnockdownTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_KNOCKDOWN); - Knockdown_Timer = urand(12000, 15000); - }else Knockdown_Timer -= diff; - - //Flamespear_Timer - if (Flamespear_Timer < diff) + 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) { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_FLAMESPEAR); - - Flamespear_Timer = urand(12000, 16000); - }else Flamespear_Timer -= diff; + 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; - //DarkStrike_Timer - if (Darkstrike_Timer < diff) + // Dark Strike Timer + if (m_uiDarkstrikeTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_DARKSTRIKE); - Darkstrike_Timer = urand(15000, 18000); - }else Darkstrike_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DARK_STRIKE) == CAST_OK) + m_uiDarkstrikeTimer = urand(15000, 18000); + } + else + m_uiDarkstrikeTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -127,55 +160,59 @@ struct MANGOS_DLL_DECL mob_flamewaker_priestAI : public ScriptedAI Reset(); } - uint32 Heal_Timer; - uint32 ShadowWordPain_Timer; - uint32 Immolate_Timer; + uint32 m_uiHealTimer; + uint32 m_uiShadowWordPainTimer; + uint32 m_uiImmolateTimer; ScriptedInstance* m_pInstance; void Reset() { - Heal_Timer = urand(15000, 30000); - ShadowWordPain_Timer = 2000; - Immolate_Timer = 8000; + m_uiHealTimer = urand(15000, 30000); + m_uiShadowWordPainTimer = 2000; + m_uiImmolateTimer = 8000; } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Casting Heal to Sulfuron or other Guards. - if (Heal_Timer < diff) + // Casting Heal to Sulfuron or other Guards. + if (m_uiHealTimer < uiDiff) { - Unit* pUnit = DoSelectLowestHpFriendly(60.0f, 1); - if (!pUnit) - return; - - DoCastSpellIfCan(pUnit, SPELL_HEAL); - - Heal_Timer = urand(15000, 20000); - }else Heal_Timer -= diff; + if (Unit* pUnit = DoSelectLowestHpFriendly(60.0f, 1)) + { + if (DoCastSpellIfCan(pUnit, SPELL_HEAL) == CAST_OK) + m_uiHealTimer = urand(15000, 20000); + } + } + else + m_uiHealTimer -= uiDiff; - //ShadowWordPain_Timer - if (ShadowWordPain_Timer < diff) + // ShadowWord Pain Timer + if (m_uiShadowWordPainTimer < uiDiff) { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_SHADOWWORDPAIN); - - ShadowWordPain_Timer = urand(18000, 26000); - }else ShadowWordPain_Timer -= diff; + 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 (Immolate_Timer < diff) + // Immolate Timer + if (m_uiImmolateTimer < uiDiff) { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_IMMOLATE); - - Immolate_Timer = urand(15000, 25000); - }else Immolate_Timer -= diff; + 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(); } @@ -193,15 +230,15 @@ CreatureAI* GetAI_mob_flamewaker_priest(Creature* pCreature) void AddSC_boss_sulfuron() { - Script *newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "boss_sulfuron"; - newscript->GetAI = &GetAI_boss_sulfuron; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "boss_sulfuron"; + pNewScript->GetAI = &GetAI_boss_sulfuron; + pNewScript->RegisterSelf(); - newscript = new Script; - newscript->Name = "mob_flamewaker_priest"; - newscript->GetAI = &GetAI_mob_flamewaker_priest; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "mob_flamewaker_priest"; + pNewScript->GetAI = &GetAI_mob_flamewaker_priest; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp b/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp index 70b9fa60a..ab06e175e 100644 --- a/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp +++ b/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,261 +16,300 @@ /* ScriptData SDName: Instance_Molten_Core -SD%Complete: 0 -SDComment: Place Holder +SD%Complete: 25 +SDComment: Majordomos and Ragnaros Event missing SDCategory: Molten Core EndScriptData */ #include "precompiled.h" #include "molten_core.h" -struct MANGOS_DLL_DECL instance_molten_core : public ScriptedInstance +instance_molten_core::instance_molten_core(Map* pMap) : ScriptedInstance(pMap), + m_uiGarrGUID(0), + m_uiSulfuronGUID(0), + m_uiMajordomoGUID(0), + m_uiRuneKoroGUID(0), + m_uiRuneZethGUID(0), + m_uiRuneMazjGUID(0), + m_uiRuneTheriGUID(0), + m_uiRuneBlazGUID(0), + m_uiRuneKressGUID(0), + m_uiRuneMohnGUID(0), + m_uiLavaSteamGUID(0), + m_uiLavaSplashGUID(0), + m_uiFirelordCacheGUID(0) { - instance_molten_core(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; + Initialize(); +} - uint64 m_uiLucifronGUID, m_uiMagmadarGUID, m_uiGehennasGUID, m_uiGarrGUID, m_uiGeddonGUID, m_uiShazzrahGUID, m_uiSulfuronGUID, m_uiGolemaggGUID, m_uiMajorDomoGUID, m_uiRagnarosGUID, m_uiFlamewakerPriestGUID; - uint64 m_uiRuneKoroGUID, m_uiRuneZethGUID, m_uiRuneMazjGUID, m_uiRuneTheriGUID, m_uiRuneBlazGUID, m_uiRuneKressGUID, m_uiRuneMohnGUID, m_uiFirelordCacheGUID; +void instance_molten_core::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - void Initialize() +bool instance_molten_core::IsEncounterInProgress() const +{ + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiLucifronGUID = 0; - m_uiMagmadarGUID = 0; - m_uiGehennasGUID = 0; - m_uiGarrGUID = 0; - m_uiGeddonGUID = 0; - m_uiShazzrahGUID = 0; - m_uiSulfuronGUID = 0; - m_uiGolemaggGUID = 0; - m_uiMajorDomoGUID = 0; - m_uiRagnarosGUID = 0; - m_uiFlamewakerPriestGUID = 0; - - m_uiRuneKoroGUID = 0; - m_uiRuneZethGUID = 0; - m_uiRuneMazjGUID = 0; - m_uiRuneTheriGUID = 0; - m_uiRuneBlazGUID = 0; - m_uiRuneKressGUID = 0; - m_uiRuneMohnGUID = 0; - - m_uiFirelordCacheGUID = 0; + if (m_auiEncounter[i] == IN_PROGRESS) + return true; } - bool IsEncounterInProgress() const + 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()) { - return false; + // Bosses + case NPC_GARR: m_uiGarrGUID = pCreature->GetGUID(); break; + case NPC_SULFURON: m_uiSulfuronGUID = pCreature->GetGUID(); break; + case NPC_MAJORDOMO: m_uiMajordomoGUID = pCreature->GetGUID(); break; + + // Push adds to lists in order to handle respawn + case NPC_FLAMEWAKER_PROTECTOR: m_luiProtectorGUIDs.push_back(pCreature->GetGUID()); break; + case NPC_FLAMEWAKER: m_luiFlamewakerGUIDs.push_back(pCreature->GetGUID()); break; + case NPC_FIRESWORN: m_luiFireswornGUIDs.push_back(pCreature->GetGUID()); break; + case NPC_FLAMEWAKER_PRIEST: m_luiPriestGUIDs.push_back(pCreature->GetGUID()); break; + case NPC_CORE_RAGER: m_luiRagerGUIDs.push_back(pCreature->GetGUID()); break; } +} - void OnObjectCreate(GameObject* pGo) +void instance_molten_core::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) { - switch(pGo->GetEntry()) - { - case 176951: //Sulfuron - m_uiRuneKoroGUID = pGo->GetGUID(); - break; - case 176952: //Geddon - m_uiRuneZethGUID = pGo->GetGUID(); - break; - case 176953: //Shazzrah - m_uiRuneMazjGUID = pGo->GetGUID(); - break; - case 176954: //Golemagg - m_uiRuneTheriGUID = pGo->GetGUID(); - break; - case 176955: //Garr - m_uiRuneBlazGUID = pGo->GetGUID(); - break; - case 176956: //Magmadar - m_uiRuneKressGUID = pGo->GetGUID(); - break; - case 176957: //Gehennas - m_uiRuneMohnGUID = pGo->GetGUID(); - break; - case 179703: - m_uiFirelordCacheGUID = pGo->GetGUID(); //majordomo event chest - break; - } + // Runes + case GO_RUNE_KRESS: m_uiRuneKressGUID = pGo->GetGUID(); break; // Magmadar + case GO_RUNE_MOHN: m_uiRuneMohnGUID = pGo->GetGUID(); break; // Gehennas + case GO_RUNE_BLAZ: m_uiRuneBlazGUID = pGo->GetGUID(); break; // Garr + case GO_RUNE_MAZJ: m_uiRuneMazjGUID = pGo->GetGUID(); break; // Shazzrah + case GO_RUNE_ZETH: m_uiRuneZethGUID = pGo->GetGUID(); break; // Geddon + case GO_RUNE_THERI: m_uiRuneTheriGUID = pGo->GetGUID(); break; // Golemagg + case GO_RUNE_KORO: m_uiRuneKoroGUID = pGo->GetGUID(); break; // Sulfuron + + // Majordomo event chest + case GO_CACHE_OF_THE_FIRE_LORD: m_uiFirelordCacheGUID = pGo->GetGUID(); break; + // Ragnaros GOs + case GO_LAVA_STEAM: m_uiLavaSteamGUID = pGo->GetGUID(); break; + case GO_LAVA_SPLASH: m_uiLavaSplashGUID = pGo->GetGUID(); break; } +} - void OnCreatureCreate(Creature* pCreature) +void instance_molten_core::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - switch(pCreature->GetEntry()) - { - case NPC_LUCIFRON: - m_uiLucifronGUID = pCreature->GetGUID(); - break; - case NPC_MAGMADAR: - m_uiMagmadarGUID = pCreature->GetGUID(); - break; - case NPC_GEHENNAS: - m_uiGehennasGUID = pCreature->GetGUID(); - break; - case NPC_GARR: - m_uiGarrGUID = pCreature->GetGUID(); - break; - case NPC_GEDDON: - m_uiGeddonGUID = pCreature->GetGUID(); - break; - case NPC_SHAZZRAH: - m_uiShazzrahGUID = pCreature->GetGUID(); - break; - case NPC_SULFURON: - m_uiSulfuronGUID = pCreature->GetGUID(); - break; - case NPC_GOLEMAGG: - m_uiGolemaggGUID = pCreature->GetGUID(); - break; - case NPC_DOMO: - m_uiMajorDomoGUID = pCreature->GetGUID(); - break; - case NPC_RAGNAROS: - m_uiRagnarosGUID = pCreature->GetGUID(); - break; - case NPC_FLAMEWAKERPRIEST: - m_uiFlamewakerPriestGUID = pCreature->GetGUID(); - break; - } + case TYPE_LUCIFRON: + m_auiEncounter[uiType] = uiData; + if (uiData == FAIL) + DoHandleAdds(m_luiProtectorGUIDs); + break; + case TYPE_MAGMADAR: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiRuneKressGUID); + break; + case TYPE_GEHENNAS: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiRuneMohnGUID); + m_luiFlamewakerGUIDs.clear(); + } + if (uiData == FAIL) + DoHandleAdds(m_luiFlamewakerGUIDs); + break; + case TYPE_GARR: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiRuneBlazGUID); + m_luiFireswornGUIDs.clear(); + } + if (uiData == FAIL) + DoHandleAdds(m_luiFireswornGUIDs); + break; + case TYPE_SHAZZRAH: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiRuneMazjGUID); + break; + case TYPE_GEDDON: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiRuneZethGUID); + break; + case TYPE_GOLEMAGG: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiRuneTheriGUID); + DoHandleAdds(m_luiRagerGUIDs, false); + m_luiRagerGUIDs.clear(); + } + if (uiData == FAIL) + DoHandleAdds(m_luiRagerGUIDs); + break; + case TYPE_SULFURON: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiRuneKoroGUID); + m_luiPriestGUIDs.clear(); + } + if (uiData == FAIL) + DoHandleAdds(m_luiPriestGUIDs); + break; + case TYPE_MAJORDOMO: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoRespawnGameObject(m_uiFirelordCacheGUID); + break; + case TYPE_RAGNAROS: + m_auiEncounter[uiType] = uiData; + break; } - void SetData(uint32 uiType, uint32 uiData) - { - switch(uiType) - { - case TYPE_SULFURON: - m_auiEncounter[0] = uiData; - break; - case TYPE_GEDDON: - m_auiEncounter[1] = uiData; - break; - case TYPE_SHAZZRAH: - m_auiEncounter[2] = uiData; - break; - case TYPE_GOLEMAGG: - m_auiEncounter[3] = uiData; - break; - case TYPE_GARR: - m_auiEncounter[4] = uiData; - break; - case TYPE_MAGMADAR: - m_auiEncounter[5] = uiData; - break; - case TYPE_GEHENNAS: - m_auiEncounter[6] = uiData; - break; - case TYPE_LUCIFRON: - m_auiEncounter[7] = uiData; - break; - case TYPE_MAJORDOMO: - if (uiData == DONE) - DoRespawnGameObject(m_uiFirelordCacheGUID); - m_auiEncounter[8] = uiData; - break; - case TYPE_RAGNAROS: - m_auiEncounter[9] = uiData; - break; - } + // Check if Majordomo can be summoned + if (uiData == DONE) + DoSpawnMajordomoIfCan(false); - if (uiData == DONE) - { - OUT_SAVE_INST_DATA; + 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]; + 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]; - strInstData = saveStream.str(); + m_strInstData = saveStream.str(); - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - const char* Save() - { - return strInstData.c_str(); - } +uint32 instance_molten_core::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; - bool CanSpawnMajorDomo() + return 0; +} + +// Handle Majordomo summon here +void instance_molten_core::DoSpawnMajordomoIfCan(bool bByPlayerEnter) +{ + // If already spawned return + if (m_uiMajordomoGUID) + return; + + // If both Majordomo and Ragnaros events are finished, return + if (m_auiEncounter[TYPE_MAJORDOMO] == DONE && m_auiEncounter[TYPE_RAGNAROS] == DONE) + return; + + // Check if all rune bosses are done + for(uint8 i = TYPE_MAGMADAR; i < TYPE_MAJORDOMO; i++) { - return m_auiEncounter[0] && m_auiEncounter[1] && m_auiEncounter[2] && m_auiEncounter[3] && - m_auiEncounter[4] && m_auiEncounter[5] && m_auiEncounter[6]; + if (m_auiEncounter[i] != DONE) + return; } - uint32 GetData(uint32 uiType) + 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)) { - switch(uiType) + if (uiSummonPos) // Majordomo encounter already done, set faction { - case TYPE_SULFURON: - return m_auiEncounter[0]; - case TYPE_GEDDON: - return m_auiEncounter[1]; - case TYPE_SHAZZRAH: - return m_auiEncounter[2]; - case TYPE_GOLEMAGG: - return m_auiEncounter[3]; - case TYPE_GARR: - return m_auiEncounter[4]; - case TYPE_MAGMADAR: - return m_auiEncounter[5]; - case TYPE_GEHENNAS: - return m_auiEncounter[6]; - case TYPE_LUCIFRON: - return m_auiEncounter[7]; - case TYPE_MAJORDOMO: - return m_auiEncounter[8]; - case TYPE_RAGNAROS: - return m_auiEncounter[9]; + pMajordomo->setFaction(FACTION_MAJORDOMO_FRIENDLY); + 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); } - return 0; } +} - uint64 GetData64(uint32 uiData) +void instance_molten_core::DoHandleAdds(GUIDList &luiAddsGUIDs, bool bRespawn /*=true*/) +{ + if (luiAddsGUIDs.empty()) + return; + + for (GUIDList::const_iterator itr = luiAddsGUIDs.begin(); itr != luiAddsGUIDs.end(); ++itr) { - switch(uiData) + if (Creature* pAdd = instance->GetCreature(*itr)) { - case DATA_SULFURON: - return m_uiSulfuronGUID; - case DATA_GOLEMAGG: - return m_uiGolemaggGUID; - case DATA_GARR: - return m_uiGarrGUID; - case DATA_MAJORDOMO: - return m_uiMajorDomoGUID; + // Respawn dead mobs (or corpses) + if (bRespawn && !pAdd->isAlive()) + pAdd->Respawn(); + // Kill adds + else if (!bRespawn) + pAdd->DealDamage(pAdd, pAdd->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } - - return 0; } +} - void Load(const char* chrIn) +uint64 instance_molten_core::GetData64(uint32 uiData) +{ + switch (uiData) { - if (!chrIn) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } + case NPC_GARR: return m_uiGarrGUID; + case NPC_SULFURON: return m_uiSulfuronGUID; + case NPC_MAJORDOMO: return m_uiMajordomoGUID; - OUT_LOAD_INST_DATA(chrIn); + case GO_LAVA_STEAM: return m_uiLavaSteamGUID; + case GO_LAVA_SPLASH: return m_uiLavaSplashGUID; - std::istringstream loadStream(chrIn); + default: + return 0; + } +} - 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]; +void instance_molten_core::Load(const char* chrIn) +{ + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. - m_auiEncounter[i] = NOT_STARTED; + std::istringstream loadStream(chrIn); - OUT_LOAD_INST_DATA_COMPLETE; + 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) { @@ -279,9 +318,10 @@ InstanceData* GetInstance_instance_molten_core(Map* pMap) void AddSC_instance_molten_core() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_molten_core"; - newscript->GetInstanceData = &GetInstance_instance_molten_core; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_molten_core"; + pNewScript->GetInstanceData = &GetInstance_instance_molten_core; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/molten_core.cpp b/scripts/eastern_kingdoms/molten_core/molten_core.cpp index 819f9b5e0..864fc53d7 100644 --- a/scripts/eastern_kingdoms/molten_core/molten_core.cpp +++ b/scripts/eastern_kingdoms/molten_core/molten_core.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/molten_core/molten_core.h b/scripts/eastern_kingdoms/molten_core/molten_core.h index f7ed5e9a2..cb4c11c8a 100644 --- a/scripts/eastern_kingdoms/molten_core/molten_core.h +++ b/scripts/eastern_kingdoms/molten_core/molten_core.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,37 +7,139 @@ enum { - MAX_ENCOUNTER = 10, - - NPC_LUCIFRON = 12118, - NPC_MAGMADAR = 11982, - NPC_GEHENNAS = 12259, - NPC_GARR = 12057, - NPC_GEDDON = 12056, - NPC_SHAZZRAH = 12264, - NPC_GOLEMAGG = 11988, - NPC_SULFURON = 12098, - NPC_DOMO = 12018, - NPC_RAGNAROS = 11502, - NPC_FLAMEWAKERPRIEST = 11662, - - TYPE_SULFURON = 1, - TYPE_GEDDON = 2, - TYPE_SHAZZRAH = 3, - TYPE_GOLEMAGG = 4, - TYPE_GARR = 5, - TYPE_MAGMADAR = 6, - TYPE_GEHENNAS = 7, - TYPE_LUCIFRON = 8, - TYPE_MAJORDOMO = 9, - TYPE_RAGNAROS = 10, - - DATA_SULFURON = 11, - DATA_GOLEMAGG = 12, - DATA_GARR = 13, - DATA_MAJORDOMO = 14, - - DATA_BOSSES_DEAD_CHECK = 15 + 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_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} +}; + +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) +}; + +static const float RANGE_CALL_FOR_HELP = 20.0f; + +typedef std::list GUIDList; + +class MANGOS_DLL_DECL instance_molten_core : public ScriptedInstance +{ + public: + instance_molten_core(Map* pMap); + ~instance_molten_core() {} + + void Initialize(); + bool IsEncounterInProgress() const; + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + void OnPlayerEnter(Player* pPlayer); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + // TODO Remove this, when creature linking implemented in MaNGOS + void DoHandleAdds(GUIDList &m_luiAddsGUIDs, bool bRespawn = true); + + protected: + void DoSpawnMajordomoIfCan(bool bByPlayerEnter); + + std::string m_strInstData; + uint32 m_auiEncounter[MAX_ENCOUNTER]; + + // Creatures + uint64 m_uiGarrGUID; + uint64 m_uiSulfuronGUID; + uint64 m_uiMajordomoGUID; + + // Runes + uint64 m_uiRuneKoroGUID; + uint64 m_uiRuneZethGUID; + uint64 m_uiRuneMazjGUID; + uint64 m_uiRuneTheriGUID; + uint64 m_uiRuneBlazGUID; + uint64 m_uiRuneKressGUID; + uint64 m_uiRuneMohnGUID; + + // Ragnaros related GOs + uint64 m_uiLavaSteamGUID; + uint64 m_uiLavaSplashGUID; + // Chests + uint64 m_uiFirelordCacheGUID; + + // Adds lists + GUIDList m_luiProtectorGUIDs; + GUIDList m_luiFlamewakerGUIDs; + GUIDList m_luiFireswornGUIDs; + GUIDList m_luiPriestGUIDs; + GUIDList m_luiRagerGUIDs; }; #endif diff --git a/scripts/eastern_kingdoms/redridge_mountains.cpp b/scripts/eastern_kingdoms/redridge_mountains.cpp index df978bb4a..4520aea48 100644 --- a/scripts/eastern_kingdoms/redridge_mountains.cpp +++ b/scripts/eastern_kingdoms/redridge_mountains.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -93,7 +93,7 @@ struct MANGOS_DLL_DECL npc_corporal_keeshan_escortAI : public npc_escortAI //Combat check if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - + if (m_uiMockingBlowTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_MOCKING_BLOW); @@ -140,6 +140,6 @@ void AddSC_redridge_mountains() NewScript = new Script; NewScript->Name = "npc_corporal_keeshan"; NewScript->GetAI = &GetAI_npc_corporal_keeshan; - NewScript->pQuestAccept = &QuestAccept_npc_corporal_keeshan; + NewScript->pQuestAcceptNPC = &QuestAccept_npc_corporal_keeshan; NewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp b/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp index dc6e6eb1e..fb15ff1d5 100644 --- a/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp +++ b/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Ebon_Hold -SD%Complete: 80 -SDComment: Quest support: 12848, 12733, 12739(and 12742 to 12750), 12727 +SD%Complete: 85 +SDComment: Quest support: 12848, 12733, 12739(and 12742 to 12750), 12727, 12698. SDCategory: Ebon Hold EndScriptData */ @@ -27,10 +27,12 @@ npc_death_knight_initiate npc_unworthy_initiate_anchor npc_unworthy_initiate go_acherus_soul_prison +mob_scarlet_ghoul EndContentData */ #include "precompiled.h" #include "escort_ai.h" +#include "ObjectMgr.h" /*###### ## npc_a_special_surprise @@ -299,7 +301,7 @@ struct MANGOS_DLL_DECL npc_a_special_surpriseAI : public ScriptedAI return; } break; - case RACE_UNDEAD_PLAYER: + case RACE_UNDEAD: switch(m_uiExecuteSpeech_Counter) { case 0: DoScriptText(SAY_EXEC_START_1, m_creature, pPlayer); break; @@ -1133,7 +1135,7 @@ CreatureAI* GetAI_npc_unworthy_initiate(Creature* pCreature) ## go_acherus_soul_prison ######*/ -bool GOHello_go_acherus_soul_prison(Player* pPlayer, GameObject* pGo) +bool GOUse_go_acherus_soul_prison(Player* pPlayer, GameObject* pGo) { if (Creature* pAnchor = GetClosestCreatureWithEntry(pGo, NPC_ANCHOR, INTERACTION_DISTANCE)) { @@ -1144,6 +1146,2110 @@ bool GOHello_go_acherus_soul_prison(Player* pPlayer, GameObject* pGo) return false; } +/*###### +## npc_eye_of_acherus +######*/ + +enum eEyeOfAcherus +{ + DISPLAYID_EYE_HUGE = 26320, + DISPLAYID_EYE_SMALL = 25499, + + SPELL_EYE_PHASEMASK = 70889, + SPELL_EYE_VISUAL = 51892, + //SPELL_EYE_FL_BOOST_RUN = 51923, + SPELL_EYE_FL_BOOST_FLY = 51890, + SPELL_EYE_CONTROL = 51852, + + TEXT_EYE_UNDER_CONTROL = -1666452, + TEXT_EYE_LAUNCHED = -1666451, +}; + +struct MANGOS_DLL_DECL npc_eye_of_acherusAI : public ScriptedAI +{ + npc_eye_of_acherusAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + bool m_isActive; + + void Reset() + { + m_creature->SetDisplayId(DISPLAYID_EYE_HUGE); + m_isActive = false; + } + + void AttackStart(Unit *) + { + } + + void MoveInLineOfSight(Unit *) + { + } + + void JustDied(Unit *) + { + if (Unit* charmer = m_creature->GetCharmer()) + charmer->RemoveAurasDueToSpell(SPELL_EYE_CONTROL); + } + + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if (uiType != POINT_MOTION_TYPE || uiPointId != 0) + return; + + DoScriptText(TEXT_EYE_UNDER_CONTROL, m_creature); + m_creature->SetDisplayId(DISPLAYID_EYE_SMALL); + m_creature->CastSpell(m_creature, SPELL_EYE_FL_BOOST_FLY, true); + } + + void AttackedBy(Unit * attacker) + { + // called on remove SPELL_AURA_MOD_POSSESS + if (!m_creature->isCharmed() && attacker->GetTypeId() == TYPEID_PLAYER) + { + attacker->RemoveAurasDueToSpell(SPELL_EYE_CONTROL); +// m_creature->ForcedDespawn(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_creature->isCharmed()) + { + if (!m_isActive) + { + m_creature->CastSpell(m_creature, SPELL_EYE_PHASEMASK, true); + m_creature->CastSpell(m_creature, SPELL_EYE_VISUAL, true); + m_creature->CastSpell(m_creature, SPELL_EYE_FL_BOOST_FLY, true); + DoScriptText(TEXT_EYE_LAUNCHED, m_creature); + m_creature->GetMotionMaster()->MovePoint(0,1750.8276f, -5873.788f, 147.2266f); + m_isActive = true; + } + } + else + m_creature->ForcedDespawn(); + } +}; + +CreatureAI* GetAI_npc_eye_of_acherus(Creature* pCreature) +{ + return new npc_eye_of_acherusAI(pCreature); +} + +/*###### +## mob_scarlet_ghoul +######*/ + +enum +{ + SPELL_HARVESTER_PING_DUMMY = 52514, + ENTRY_GOTHIK = 28658, + + SAY_SCARLET_GHOUL_SPAWN1 = -1609300, + SAY_SCARLET_GHOUL_SPAWN2 = -1609301, + SAY_SCARLET_GHOUL_SPAWN3 = -1609302, + SAY_SCARLET_GHOUL_SPAWN4 = -1609303, + SAY_SCARLET_GHOUL_SPAWN5 = -1609304, + SAY_SCARLET_GHOUL_SPAWN6 = -1609305, + + SAY_SCARLET_GOTHIK1 = -1609306, + SAY_SCARLET_GOTHIK2 = -1609307, + SAY_SCARLET_GOTHIK3 = -1609308, + SAY_SCARLET_GOTHIK4 = -1609309, + SAY_SCARLET_GOTHIK5 = -1609310, +}; + +struct MANGOS_DLL_DECL mob_scarlet_ghoulAI : public ScriptedAI +{ + mob_scarlet_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsSpawned = false; + fDist = (float)urand(1, 5); + m_uiCreatorGuid = m_creature->GetCreatorGuid(); + if (Player* pOwner = m_creature->GetMap()->GetPlayer(m_uiCreatorGuid) ) + fAngle = m_creature->GetAngle(pOwner); + + Reset(); + } + + + Unit* pTarget; + + ObjectGuid m_uiCreatorGuid; + uint64 m_uiTargetGUID; + uint64 m_uiHarvesterGUID; + + uint32 m_uiWaitForThrowTimer; + + bool m_bWaitForThrow; + bool m_bIsSpawned; + + float fAngle; + float fDist; + + void Reset() + { + m_uiWaitForThrowTimer = 3000; + m_bWaitForThrow = false; + pTarget = NULL; + m_uiTargetGUID = 0; + m_uiHarvesterGUID = 0; + } + + void MoveInLineOfSight(Unit *pWho) + { + if (!m_bWaitForThrow && pWho->GetEntry() == ENTRY_GOTHIK && m_creature->GetDistance(pWho) < 15.0f) + { + m_uiHarvesterGUID = pWho->GetGUID(); + + if (Player* pOwner = m_creature->GetMap()->GetPlayer(m_uiCreatorGuid) ) + { + pOwner->KilledMonsterCredit(m_creature->GetEntry(), m_creature->GetGUID() ); + // this will execute if m_creature survived Harvester's wrath + float x, y, z, o; + o = float(urand(53, 57))/10.0f; + pWho->GetNearPoint(pWho, x, y, z, pWho->GetObjectBoundingRadius(), 5.0f, o); + m_creature->GetMotionMaster()->MovePoint(0, x, y, z); + m_bWaitForThrow = true; + } + } + } + + void AttackStart(Unit *pWho) { return; } + + void UpdateAI(uint32 const uiDiff) + { + if (!m_bIsSpawned) + { + DoScriptText(SAY_SCARLET_GHOUL_SPAWN1 - urand(0, 5), m_creature); + m_bIsSpawned = true; + } + + if (m_bWaitForThrow) + { + if (m_uiWaitForThrowTimer <= uiDiff) + { + if (Creature* pGothik = m_creature->GetMap()->GetCreature(m_uiHarvesterGUID) ) + { + if (pGothik->AI()->DoCastSpellIfCan(m_creature, roll_chance_i(50) ? 52519 : 52521) == CAST_OK) + DoScriptText(SAY_SCARLET_GOTHIK1 - urand(0, 4), pGothik); + + m_uiWaitForThrowTimer = 5000; + m_creature->KnockBackFrom(pGothik, 15.0, 5.0); + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false); + } + else m_bWaitForThrow = false; + } + else m_uiWaitForThrowTimer -= uiDiff; + return; + } + + Player* pOwner = m_creature->GetMap()->GetPlayer(m_uiCreatorGuid); + if (!pOwner || !pOwner->IsInWorld()) + { + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false); + return; + } + + if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != FOLLOW_MOTION_TYPE) + { + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveFollow(pOwner, fDist, fAngle); + } + } +}; + +CreatureAI* GetAI_mob_scarlet_ghoul(Creature* pCreature) +{ + return new mob_scarlet_ghoulAI(pCreature); +}; + +// quest 12801 from Ckegg +/*###### +## Npc Highlord Darion Mograine +######*/ + +void UpdateWorldState(Map *map, uint32 id, uint32 state) +{ + Map::PlayerList const& players = map->GetPlayers(); + + if (!players.isEmpty()) + { + for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + pPlayer->SendUpdateWorldState(id,state); + } + } +} + +enum mograine +{ + ENCOUNTER_DK_NUMBER = 5, // how many player queue to start the quest , or - + ENCOUNTER_DK_TIMER = 10, // *every 5 minutes. These have to be done in instance data + ENCOUNTER_DEFENDER_NUMBER = 20, // how many of defender + ENCOUNTER_EARTHSHATTER_NUMBER = 20, // how many of earthshatter + ENCOUNTER_ABOMINATION_NUMBER = 3, // how many of abomination + ENCOUNTER_BEHEMOTH_NUMBER = 2, // how many of behemoth + ENCOUNTER_GHOUL_NUMBER = 10, // how many of ghoul + ENCOUNTER_WARRIOR_NUMBER = 2, // how many of warrior + ENCOUNTER_TOTAL_DAWN = 300, // Total number + ENCOUNTER_TOTAL_SCOURGE = 10000, + + WORLD_STATE_REMAINS = 3592, + WORLD_STATE_COUNTDOWN = 3603, + WORLD_STATE_EVENT_BEGIN = 3605, + + SAY_LIGHT_OF_DAWN01 = -1609201, // pre text + SAY_LIGHT_OF_DAWN02 = -1609202, + SAY_LIGHT_OF_DAWN03 = -1609203, + SAY_LIGHT_OF_DAWN04 = -1609204, // intro + SAY_LIGHT_OF_DAWN05 = -1609205, + SAY_LIGHT_OF_DAWN06 = -1609206, + SAY_LIGHT_OF_DAWN07 = -1609207, // During the fight - Korfax, Champion of the Light + SAY_LIGHT_OF_DAWN08 = -1609208, // Lord Maxwell Tyrosus + SAY_LIGHT_OF_DAWN09 = -1609209, // Highlord Darion Mograine + SAY_LIGHT_OF_DAWN10 = -1609210, + SAY_LIGHT_OF_DAWN11 = -1609211, + SAY_LIGHT_OF_DAWN12 = -1609212, + SAY_LIGHT_OF_DAWN13 = -1609213, + SAY_LIGHT_OF_DAWN14 = -1609214, + SAY_LIGHT_OF_DAWN15 = -1609215, + SAY_LIGHT_OF_DAWN16 = -1609216, + SAY_LIGHT_OF_DAWN17 = -1609217, + SAY_LIGHT_OF_DAWN18 = -1609218, + SAY_LIGHT_OF_DAWN19 = -1609219, + SAY_LIGHT_OF_DAWN20 = -1609220, + SAY_LIGHT_OF_DAWN21 = -1609221, + SAY_LIGHT_OF_DAWN22 = -1609222, + SAY_LIGHT_OF_DAWN23 = -1609223, + SAY_LIGHT_OF_DAWN24 = -1609224, + SAY_LIGHT_OF_DAWN25 = -1609225, // After the fight + SAY_LIGHT_OF_DAWN26 = -1609226, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN27 = -1609227, // Highlord Darion Mograine + SAY_LIGHT_OF_DAWN28 = -1609228, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN29 = -1609229, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN30 = -1609230, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN31 = -1609231, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN32 = -1609232, // Highlord Alexandros Mograine + SAY_LIGHT_OF_DAWN33 = -1609233, // Highlord Darion Mograine + SAY_LIGHT_OF_DAWN34 = -1609234, // Highlord Darion Mograine + SAY_LIGHT_OF_DAWN35 = -1609235, // Darion Mograine + SAY_LIGHT_OF_DAWN36 = -1609236, // Darion Mograine + SAY_LIGHT_OF_DAWN37 = -1609237, // Highlord Alexandros Mograine + SAY_LIGHT_OF_DAWN38 = -1609238, // Darion Mograine + SAY_LIGHT_OF_DAWN39 = -1609239, // Highlord Alexandros Mograine + SAY_LIGHT_OF_DAWN40 = -1609240, // Darion Mograine + SAY_LIGHT_OF_DAWN41 = -1609241, // Highlord Alexandros Mograine + SAY_LIGHT_OF_DAWN42 = -1609242, // Highlord Alexandros Mograine + SAY_LIGHT_OF_DAWN43 = -1609243, // The Lich King + SAY_LIGHT_OF_DAWN44 = -1609244, // Highlord Darion Mograine + SAY_LIGHT_OF_DAWN45 = -1609245, // The Lich King + SAY_LIGHT_OF_DAWN46 = -1609246, // The Lich King + SAY_LIGHT_OF_DAWN47 = -1609247, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN48 = -1609248, // The Lich King + SAY_LIGHT_OF_DAWN49 = -1609249, // The Lich King + SAY_LIGHT_OF_DAWN50 = -1609250, // Lord Maxwell Tyrosus + SAY_LIGHT_OF_DAWN51 = -1609251, // The Lich King + SAY_LIGHT_OF_DAWN52 = -1609252, // Highlord Darion Mograine + SAY_LIGHT_OF_DAWN53 = -1609253, // Highlord Darion Mograine + SAY_LIGHT_OF_DAWN54 = -1609254, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN55 = -1609255, // The Lich King + SAY_LIGHT_OF_DAWN56 = -1609256, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN57 = -1609257, // The Lich King + SAY_LIGHT_OF_DAWN58 = -1609258, // The Lich King + SAY_LIGHT_OF_DAWN59 = -1609259, // The Lich King + SAY_LIGHT_OF_DAWN60 = -1609260, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN61 = -1609261, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN62 = -1609262, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN63 = -1609263, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN64 = -1609264, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN65 = -1609265, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN66 = -1609266, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN67 = -1609267, // Highlord Tirion Fordring + SAY_LIGHT_OF_DAWN68 = -1609268, // Highlord Darion Mograine + + EMOTE_LIGHT_OF_DAWN01 = -1609269, // Emotes + EMOTE_LIGHT_OF_DAWN02 = -1609270, + EMOTE_LIGHT_OF_DAWN03 = -1609271, + EMOTE_LIGHT_OF_DAWN04 = -1609272, + EMOTE_LIGHT_OF_DAWN05 = -1609273, + EMOTE_LIGHT_OF_DAWN06 = -1609274, + EMOTE_LIGHT_OF_DAWN07 = -1609275, + EMOTE_LIGHT_OF_DAWN08 = -1609276, + EMOTE_LIGHT_OF_DAWN09 = -1609277, + EMOTE_LIGHT_OF_DAWN10 = -1609278, + EMOTE_LIGHT_OF_DAWN11 = -1609279, + EMOTE_LIGHT_OF_DAWN12 = -1609280, + EMOTE_LIGHT_OF_DAWN13 = -1609281, + EMOTE_LIGHT_OF_DAWN14 = -1609282, + EMOTE_LIGHT_OF_DAWN15 = -1609283, + EMOTE_LIGHT_OF_DAWN16 = -1609284, + EMOTE_LIGHT_OF_DAWN17 = -1609285, + EMOTE_LIGHT_OF_DAWN18 = -1609286, + + GO_LIGHT_OF_DAWN = 191330, + SPELL_THE_LIGHT_OF_DAWN_Q = 53606, // quest credit + + // ---- Dark Knight npc -------------------- + // Highlord Darion Mograine + NPC_HIGHLORD_DARION_MOGRAINE = 29173, + SPELL_ANTI_MAGIC_ZONE1 = 52893, + SPELL_DEATH_STRIKE = 53639, + SPELL_DEATH_EMBRACE = 53635, + SPELL_ICY_TOUCH1 = 49723, + SPELL_THE_LIGHT_OF_DAWN = 53658, + SPELL_THE_MIGHT_OF_MOGRAINE = 53642, // on players when begins + SPELL_UNHOLY_BLIGHT = 53640, + SPELL_ALEXANDROS_MOGRAINE_SPAWN = 53667, + SPELL_MOGRAINE_CHARGE = 53679, + SPELL_ASHBRINGER = 53701, + + // Koltira Deathweaver & Orbaz Bloodbane are using the same abilities + NPC_KOLTIRA_DEATHWEAVER = 29199, + NPC_ORBAZ_BLOODBANE = 29204, // this guy fleed + NPC_THASSARIAN = 29200, // he also does SPELL_THE_LIGHT_OF_DAWN 53658 + //SPELL_BLOOD_STRIKE = 52374, + SPELL_DEATH_GRIP = 49576, + //SPELL_ICY_TOUCH = 52372, + SPELL_PLAGUE_STRIKE1 = 50668, + // all do SPELL_HERO_AGGRO_AURA 53627 + + // Lich King + NPC_THE_LICH_KING = 29183, // show up at end + SPELL_APOCALYPSE = 53210, + SPELL_TELEPORT_VISUAL = 52233, + SPELL_SOUL_FEAST_ALEX = 53677, // on Alexandros + SPELL_SOUL_FEAST_TIRION = 53685, // on Tirion + SPELL_ICEBOUND_VISAGE = 53274, // not sure what is it for + SPELL_REBUKE = 53680, + + // others + NPC_RAMPAGING_ABOMINATION = 29186, + SPELL_CLEAVE1 = 53633, + SPELL_SCOURGE_HOOK = 50335, + SPELL_SCOURGE_AGGRO_AURA = 53624, + + NPC_FLESH_BEHEMOTH = 29190, // giant guy + SPELL_STOMP = 53634, + SPELL_THUNDERCLAP = 36706, + SPELL_HERO_AGGRO_AURA = 53627, + + NPC_ACHERUS_GHOUL = 29219, // just ghoul.... + SPELL_GHOULPLOSION = 53632, + + NPC_WARRIOR_OF_THE_FROZEN_WASTES = 29206, // use SPELL_CLEAVE 53631 + + NPC_HIGHLORD_ALEXANDROS_MOGRAINE = 29227, // ghost + NPC_DARION_MOGRAINE = 29228, // ghost + + // ---- Dawn npc -------------------- + // Highlord Tirion Fordring + NPC_HIGHLORD_TIRION_FORDRING = 29175, + EQUIP_HIGHLORD_TIRION_FORDRING = 13262, + SPELL_LAY_ON_HANDS = 53778, + SPELL_REBIRTH_OF_THE_ASHBRINGER = 53702, + SPELL_TIRION_CHARGE = 53705, + SPELL_TIRION_CHARGE_VISUAL = 53706, + + // others + NPC_KORFAX_CHAMPION_OF_THE_LIGHT = 29176, + SPELL_CLEAVE = 53631, + SPELL_HEROIC_LEAP = 53625, + + NPC_LORD_MAXWELL_TYROSUS = 29178, + NPC_LEONID_BARTHALOMEW_THE_REVERED = 29179, + NPC_DUKE_NICHOLAS_ZVERENHOFF = 29180, + + NPC_COMMANDER_ELIGOR_DAWNBRINGER = 29177, + SPELL_HOLY_LIGHT2 = 37979, + + NPC_RAYNE = 29181, + SPELL_REJUVENATION = 20664, + SPELL_STARFALL = 20678, + SPELL_TRANQUILITY = 25817, + SPELL_WRATH = 21807, + + NPC_DEFENDER_OF_THE_LIGHT = 29174, // also does SPELL_HEROIC_LEAP 53625 + SPELL_HOLY_LIGHT1 = 29427, + SPELL_HOLY_STRIKE = 53643, + SPELL_HOLY_WRATH = 53638, + SPELL_UPPERCUT = 53629, + + NPC_RIMBLAT_EARTHSHATTER = 29182, + SPELL_CHAIN_HEAL = 33642, + SPELL_THUNDER = 53630 +}; + +struct Locations +{ + float x, y, z, o; + uint32 id; +}; + +static Locations LightofDawnLoc[]= +{ + {2281.335f, -5300.409f, 85.170f, 0.0f}, // 0 Tirion Fordring loc + {2283.896f, -5287.914f, 83.066f, 1.55f}, // 1 Tirion Fordring loc2 + {2281.461f, -5263.014f, 81.164f, 0.0f}, // 2 Tirion charges + {2262.277f, -5293.477f, 82.167f, 0.0f}, // 3 Tirion run + {2270.286f, -5287.73f, 82.262f, 0.0f}, // 4 Tirion relocate + {2269.511f, -5288.289f, 82.225f, 0.0f}, // 5 Tirion forward + {2262.277f, -5293.477f, 82.167f, 0.0f}, // 6 Tirion runs to Darion + {2270.286f, -5287.73f, 82.262f, 0.0f}, + {2269.511f, -5288.289f, 82.225f, 0.0f}, + {2273.205f, -5288.848f, 82.617f, 0.0f}, // 9 Korfax loc1 + {2274.739f, -5287.926f, 82.684f, 0.0f}, // 10 Korfax loc2 + {2253.673f, -5318.004f, 81.724f, 0.0f}, // 11 Korfax kicked + {2287.028f, -5309.644f, 87.253f, 0.0f}, // 12 Maxwell loc1 + {2286.978f, -5308.025f, 86.83f, 0.0f}, // 13 Maxwell loc2 + {2248.877f, -5307.586f, 82.166f, 0.0f}, // 14 maxwell kicked + {2278.58f, -5316.933f, 88.319f, 0.0f}, // 15 Eligor loc1 + {2278.535f, -5315.479f, 88.08f, 0.0f}, // 16 Eligor loc2 + {2259.416f, -5304.505f, 82.149f, 0.0f}, // 17 eligor kicked + {2289.259f, -5280.355f, 82.112f, 0.0f}, // 18 Koltira loc1 + {2289.02f, -5281.985f, 82.207f, 0.0f}, // 19 Koltira loc2 + {2273.289f, -5273.675f, 81.701f, 0.0f}, // 20 Thassarian loc1 + {2273.332f, -5275.544f, 81.849f, 0.0f}, // 21 Thassarian loc2 + {2281.198f, -5257.397f, 80.224f, 4.66f}, // 22 Alexandros loc1 + {2281.156f, -5259.934f, 80.647f, 0.0f}, // 23 Alexandros loc2 + {2281.294f, -5281.895f, 82.445f, 1.35f}, // 24 Darion loc1 + {2281.093f, -5263.013f, 81.125f, 0.0f}, // 25 Darion loc1 + {2281.313f, -5250.282f, 79.322f, 4.69f}, // 26 Lich King spawns + {2281.523f, -5261.058f, 80.877f, 0.0f}, // 27 Lich king move forwards + {2272.709f, -5255.552f, 78.226f, 0.0f}, // 28 Lich king kicked + {2273.972f, -5257.676f, 78.862f, 0.0f} // 29 Lich king moves forward +}; + +struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI +{ + npc_highlord_darion_mograineAI(Creature *pCreature) : npc_escortAI(pCreature) + { + Reset(); + } + + bool bIsBattle; + uint32 uiStep; + uint32 uiPhase_timer; + uint32 uiFight_duration; + uint32 uiTotal_dawn; + uint32 uiTotal_scourge; + uint32 uiSummon_counter; + + // Darion Mograine + uint32 uiAnti_magic_zone; + uint32 uiDeath_strike; + uint32 uiDeath_embrace; + uint32 uiIcy_touch; + uint32 uiUnholy_blight; + uint32 uiFight_speech; + uint32 uiSpawncheck; + uint32 uiTargetcheck; + + // Dawn + uint64 uiTirionGUID; + uint64 uiAlexandrosGUID; + uint64 uiDarionGUID; + uint64 uiKorfaxGUID; + uint64 uiMaxwellGUID; + uint64 uiEligorGUID; + uint64 uiRayneGUID; + uint64 uiDefenderGUID[ENCOUNTER_DEFENDER_NUMBER]; + uint64 uiEarthshatterGUID[ENCOUNTER_EARTHSHATTER_NUMBER]; + + // Death + uint64 uiKoltiraGUID; + uint64 uiOrbazGUID; + uint64 uiThassarianGUID; + uint64 uiLichKingGUID; + uint64 uiAbominationGUID[ENCOUNTER_ABOMINATION_NUMBER]; + uint64 uiBehemothGUID[ENCOUNTER_BEHEMOTH_NUMBER]; + uint64 uiGhoulGUID[ENCOUNTER_GHOUL_NUMBER]; + uint64 uiWarriorGUID[ENCOUNTER_WARRIOR_NUMBER]; + + // Misc + uint64 uiDawnofLightGUID; + + void Reset() + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + bIsBattle = false; + uiStep = 0; + uiPhase_timer = 3000; + uiFight_duration = 300000; // 5 minutes + uiTotal_dawn = ENCOUNTER_TOTAL_DAWN; + uiTotal_scourge = ENCOUNTER_TOTAL_SCOURGE; + uiSummon_counter = 0; + + uiDawnofLightGUID = 0; + + uiAnti_magic_zone = 1000 + rand()%5000; + uiDeath_strike = 5000 + rand()%5000; + uiDeath_embrace = 5000 + rand()%5000; + uiIcy_touch = 5000 + rand()%5000; + uiUnholy_blight = 5000 + rand()%5000; + + uiFight_speech = 15000; + uiSpawncheck = 1000; + uiTargetcheck = 10000; + + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->Mount(25279); + + UpdateWorldState(m_creature->GetMap(), WORLD_STATE_REMAINS, 0); + //UpdateWorldState(m_creature->GetMap(), WORLD_STATE_COUNTDOWN, 0); + UpdateWorldState(m_creature->GetMap(), WORLD_STATE_EVENT_BEGIN, 0); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + pTemp->SetDeathState(JUST_DIED); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID)) + pTemp->SetDeathState(JUST_DIED); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)) + pTemp->SetDeathState(JUST_DIED); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID)) + pTemp->SetDeathState(JUST_DIED); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiRayneGUID)) + pTemp->SetDeathState(JUST_DIED); + + uiTirionGUID = NULL; + uiKorfaxGUID = NULL; + uiMaxwellGUID = NULL; + uiEligorGUID = NULL; + uiRayneGUID = NULL; + + for (uint8 i = 0; i < ENCOUNTER_DEFENDER_NUMBER; ++i) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDefenderGUID[i])) + pTemp->SetDeathState(JUST_DIED); + uiDefenderGUID[i] = 0; + } + for (uint8 i = 0; i < ENCOUNTER_EARTHSHATTER_NUMBER; ++i) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEarthshatterGUID[i])) + pTemp->SetDeathState(JUST_DIED); + uiEarthshatterGUID[i] = 0; + } + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID)) + pTemp->SetDeathState(JUST_DIED); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiOrbazGUID)) + pTemp->SetDeathState(JUST_DIED); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID)) + pTemp->SetDeathState(JUST_DIED); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + pTemp->SetDeathState(JUST_DIED); + + uiKoltiraGUID = NULL; + uiOrbazGUID = NULL; + uiThassarianGUID = NULL; + uiLichKingGUID = NULL; + for(uint8 i = 0; i < ENCOUNTER_ABOMINATION_NUMBER; ++i) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAbominationGUID[i])) + pTemp->SetDeathState(JUST_DIED); + uiAbominationGUID[i] = 0; + } + for(uint8 i = 0; i < ENCOUNTER_BEHEMOTH_NUMBER; ++i) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiBehemothGUID[i])) + pTemp->SetDeathState(JUST_DIED); + uiBehemothGUID[i] = 0; + } + for(uint8 i = 0; i < ENCOUNTER_GHOUL_NUMBER; ++i) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiGhoulGUID[i])) + pTemp->SetDeathState(JUST_DIED); + uiGhoulGUID[i] = 0; + } + for(uint8 i = 0; i < ENCOUNTER_WARRIOR_NUMBER; ++i) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiWarriorGUID[i])) + pTemp->SetDeathState(JUST_DIED); + uiWarriorGUID[i] = 0; + } + } + } + + void AttackStart(Unit* who) + { + if (!who) + return; + + if (who == m_creature) + return; + + if (m_creature->Attack(who, true)) + { + m_creature->AddThreat(who, 0.0f); + m_creature->SetInCombatWith(who); + who->SetInCombatWith(m_creature); + DoStartMovement(who); + } + } + + void MoveInLineOfSight(Unit* who) + { + if (!who) + return; + + if (who->isTargetableForAttack() && m_creature->IsHostileTo(who)) + if (m_creature->IsWithinDistInMap(who, 20) && m_creature->IsWithinLOSInMap(who)) + AttackStart(who); + } + + void WaypointReached(uint32 i) + { + switch(i) + { + case 0: + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + SetEscortPaused(true); + break; + case 1: + SetEscortPaused(true); + + if (GameObject* pGo = GetClosestGameObjectWithEntry(m_creature, GO_LIGHT_OF_DAWN, 100.0f)) // make dawn of light effect off + { + uiDawnofLightGUID = pGo->GetGUID(); + pGo->SetPhaseMask(0, true); + } + + SpawnNPC(); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN07, pTemp); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN08, pTemp); + + for(uint8 i = 0; i < ENCOUNTER_GHOUL_NUMBER; ++i) + NPCChangeTarget(uiGhoulGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_WARRIOR_NUMBER; ++i) + NPCChangeTarget(uiWarriorGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_ABOMINATION_NUMBER; ++i) + NPCChangeTarget(uiAbominationGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_BEHEMOTH_NUMBER; ++i) + NPCChangeTarget(uiBehemothGUID[i]); + NPCChangeTarget(uiKoltiraGUID); + NPCChangeTarget(uiOrbazGUID); + NPCChangeTarget(uiThassarianGUID); + + m_creature->Unmount(); + m_creature->CastSpell(m_creature, SPELL_THE_MIGHT_OF_MOGRAINE, true); // need to fix, on player only + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID)) + pTemp->Unmount(); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID)) + pTemp->Unmount(); + + bIsBattle = true; + break; + case 2: + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + DoCast(m_creature, SPELL_THE_LIGHT_OF_DAWN); + break; + case 3: + { + Creature* pTirion = m_creature->GetMap()->GetCreature(uiTirionGUID); + + DoScriptText(EMOTE_LIGHT_OF_DAWN05, m_creature); + if (m_creature->HasAura(SPELL_THE_LIGHT_OF_DAWN)) + m_creature->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID)) + { + if (pTemp->HasAura(SPELL_THE_LIGHT_OF_DAWN)) + pTemp->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[19].x, LightofDawnLoc[19].y, LightofDawnLoc[19].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID)) + { + if (pTemp->HasAura(SPELL_THE_LIGHT_OF_DAWN)) + pTemp->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[21].x, LightofDawnLoc[21].y, LightofDawnLoc[21].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID)) + { + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[10].x, LightofDawnLoc[10].y, LightofDawnLoc[10].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)) + { + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[13].x, LightofDawnLoc[13].y, LightofDawnLoc[13].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID)) + { + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[16].x, LightofDawnLoc[16].y, LightofDawnLoc[16].z); + } + JumpToNextStep(10000); + } break; + case 4: + DoScriptText(SAY_LIGHT_OF_DAWN27, m_creature); + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_KNEEL); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID)) + pTemp->SetStandState(UNIT_STAND_STATE_KNEEL); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID)) + pTemp->SetStandState(UNIT_STAND_STATE_KNEEL); + SetEscortPaused(true); + break; + case 5: + DoScriptText(SAY_LIGHT_OF_DAWN33, m_creature); + SetEscortPaused(true); + break; + case 6: + SetEscortPaused(true); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SPECIALATTACK1H); + JumpToNextStep(1000); + break; + case 7: + SetEscortPaused(true); + JumpToNextStep(2000); + break; + case 8: + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP)); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + m_creature->CastSpell(pTemp, SPELL_ASHBRINGER, true); + DoScriptText(EMOTE_LIGHT_OF_DAWN14, m_creature); + SetEscortPaused(true); + break; + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + + if (!bIsBattle) + { + if (uiPhase_timer < diff) + { + // ******* Before battle ***************************************************************** + switch(uiStep) + { + case 0: // countdown + //UpdateWorldState(m_creature->GetMap(), WORLD_STATE_COUNTDOWN, 1); + break; + + case 1: // just delay + //UpdateWorldState(m_creature->GetMap(), WORLD_STATE_REMAINS, 1); + UpdateWorldState(m_creature->GetMap(), WORLD_STATE_COUNTDOWN, 0); + UpdateWorldState(m_creature->GetMap(), WORLD_STATE_EVENT_BEGIN, 1); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + JumpToNextStep(3000); + break; + + case 2: + DoScriptText(SAY_LIGHT_OF_DAWN04, m_creature); + if (Creature* pKoltira = GetClosestCreatureWithEntry(m_creature, NPC_KOLTIRA_DEATHWEAVER, 50.0f)) + uiKoltiraGUID = pKoltira->GetGUID(); + if (Creature* pOrbaz = GetClosestCreatureWithEntry(m_creature, NPC_ORBAZ_BLOODBANE, 50.0f)) + uiOrbazGUID = pOrbaz->GetGUID(); + if (Creature* pThassarian = GetClosestCreatureWithEntry(m_creature, NPC_THASSARIAN, 50.0f)) + uiThassarianGUID = pThassarian->GetGUID(); + JumpToNextStep(10000); + break; + + case 3: // rise + DoScriptText(SAY_LIGHT_OF_DAWN05, m_creature); + JumpToNextStep(3000); + break; + + case 4: // summon ghoul + // Dunno whats the summon spell, so workaround + DoCast(m_creature, 33271); // shack effect + uiPhase_timer = 500; + if (uiSummon_counter < ENCOUNTER_GHOUL_NUMBER) + { + if (Creature* pTemp = m_creature->SummonCreature(NPC_ACHERUS_GHOUL, (m_creature->GetPositionX()-20)+rand()%40, (m_creature->GetPositionY()-20)+rand()%40, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->setFaction(2084); + uiGhoulGUID[uiSummon_counter] = pTemp->GetGUID(); + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + uiStep++; + } + break; + + case 5: // summon abomination + DoCast(m_creature, 33271); // shack effect + uiPhase_timer = 500; + if (uiSummon_counter < ENCOUNTER_ABOMINATION_NUMBER) + { + if (Creature* pTemp = m_creature->SummonCreature(NPC_RAMPAGING_ABOMINATION, (m_creature->GetPositionX()-20)+rand()%40, (m_creature->GetPositionY()-20)+rand()%40, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->setFaction(2084); + uiAbominationGUID[uiSummon_counter] = pTemp->GetGUID(); + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + uiStep++; + } + break; + + case 6: // summon warrior + DoCast(m_creature, 33271); // shack effect + uiPhase_timer = 500; + if (uiSummon_counter < ENCOUNTER_WARRIOR_NUMBER) + { + if (Creature* pTemp = m_creature->SummonCreature(NPC_WARRIOR_OF_THE_FROZEN_WASTES, (m_creature->GetPositionX()-20)+rand()%40, (m_creature->GetPositionY()-20)+rand()%40, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->setFaction(2084); + uiWarriorGUID[uiSummon_counter] = pTemp->GetGUID(); + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + uiStep++; + } + break; + + case 7: // summon warrior + DoCast(m_creature, 33271); // shack effect + uiPhase_timer = 500; + if (uiSummon_counter < ENCOUNTER_BEHEMOTH_NUMBER) + { + if (Creature* pTemp = m_creature->SummonCreature(NPC_FLESH_BEHEMOTH, (m_creature->GetPositionX()-20)+rand()%40, (m_creature->GetPositionY()-20)+rand()%40, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->setFaction(2084); + uiBehemothGUID[uiSummon_counter] = pTemp->GetGUID(); + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + uiStep++; + } + break; + + case 8: // summon announce + DoScriptText(SAY_LIGHT_OF_DAWN06, m_creature); + JumpToNextStep(5000); + break; + + case 9: // charge begins + SetEscortPaused(false); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiOrbazGUID)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z); + } + for(uint8 i = 0; i < ENCOUNTER_ABOMINATION_NUMBER; ++i) + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAbominationGUID[i])) + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z); + for(uint8 i = 0; i < ENCOUNTER_BEHEMOTH_NUMBER; ++i) + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiBehemothGUID[i])) + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z); + for(uint8 i = 0; i < ENCOUNTER_GHOUL_NUMBER; ++i) + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiGhoulGUID[i])) + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z); + for(uint8 i = 0; i < ENCOUNTER_WARRIOR_NUMBER; ++i) + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiWarriorGUID[i])) + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z); + JumpToNextStep(5000); + break; + + // ******* After battle ***************************************************************** + case 11: // Tirion starts to speak + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN28, pTemp); + JumpToNextStep(21000); + break; + + case 12: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN29, pTemp); + JumpToNextStep(13000); + break; + + case 13: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN30, pTemp); + JumpToNextStep(13000); + break; + + case 14: + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_STAND); + DoScriptText(SAY_LIGHT_OF_DAWN31, m_creature); + JumpToNextStep(7000); + break; + + case 15: // summon gate + if (Creature* pTemp = m_creature->SummonCreature(NPC_HIGHLORD_ALEXANDROS_MOGRAINE, LightofDawnLoc[22].x, LightofDawnLoc[22].y, LightofDawnLoc[22].z, LightofDawnLoc[22].o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pTemp->CastSpell(pTemp, SPELL_ALEXANDROS_MOGRAINE_SPAWN, true); + DoScriptText(EMOTE_LIGHT_OF_DAWN06, pTemp); + uiAlexandrosGUID = pTemp->GetGUID(); + } + JumpToNextStep(4000); + break; + + case 16: // Alexandros out + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAlexandrosGUID)) + { + pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[23].x, LightofDawnLoc[23].y, LightofDawnLoc[23].z); + DoScriptText(SAY_LIGHT_OF_DAWN32, pTemp); + } + SetEscortPaused(false); // makes darion turns back + JumpToNextStep(5000); + break; + + case 17: + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_KNEEL); + DoScriptText(SAY_LIGHT_OF_DAWN34, m_creature); + JumpToNextStep(5000); + break; + + case 18: // Darion's spirit out + if (Creature* pTemp = m_creature->SummonCreature(NPC_DARION_MOGRAINE, LightofDawnLoc[24].x, LightofDawnLoc[24].y, LightofDawnLoc[24].z, LightofDawnLoc[24].o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + DoScriptText(SAY_LIGHT_OF_DAWN35, pTemp); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + uiDarionGUID = pTemp->GetGUID(); + } + JumpToNextStep(4000); + break; + + case 19: // runs to father + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDarionGUID)) + { + DoScriptText(EMOTE_LIGHT_OF_DAWN07, pTemp); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[25].x, LightofDawnLoc[25].y, LightofDawnLoc[25].z); + } + JumpToNextStep(4000); + break; + + case 20: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDarionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN36, pTemp); + JumpToNextStep(4000); + break; + + case 21: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDarionGUID)) + DoScriptText(EMOTE_LIGHT_OF_DAWN08, pTemp); + JumpToNextStep(4000); + break; + + case 22: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAlexandrosGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN37, pTemp); + JumpToNextStep(8000); + break; + + case 23: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDarionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN38, pTemp); + JumpToNextStep(8000); + break; + + case 24: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAlexandrosGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN39, pTemp); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) // Tirion moves forward here + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[1].x, LightofDawnLoc[1].y, LightofDawnLoc[1].z); + + JumpToNextStep(15000); + break; + + case 25: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDarionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN40, pTemp); + JumpToNextStep(11000); + break; + + case 26: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAlexandrosGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN41, pTemp); + JumpToNextStep(5000); + break; + + case 27: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDarionGUID)) + pTemp->SetDeathState(JUST_DIED); + JumpToNextStep(24000); + break; + + case 28: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAlexandrosGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN42, pTemp); + JumpToNextStep(6000); + break; + + case 29: // lich king spawns + if (Creature* pTemp = m_creature->SummonCreature(NPC_THE_LICH_KING, LightofDawnLoc[26].x, LightofDawnLoc[26].y, LightofDawnLoc[26].z, LightofDawnLoc[26].o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + DoScriptText(SAY_LIGHT_OF_DAWN43, pTemp); + uiLichKingGUID = pTemp->GetGUID(); + if (Creature* pAlex = m_creature->GetMap()->GetCreature(uiAlexandrosGUID)) + pTemp->CastSpell(pAlex, SPELL_SOUL_FEAST_ALEX, false); + } + JumpToNextStep(2000); + break; + + case 30: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiAlexandrosGUID)) // remove him + { + DoScriptText(EMOTE_LIGHT_OF_DAWN09, pTemp); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + { + pTemp->InterruptNonMeleeSpells(false); + DoScriptText(SAY_LIGHT_OF_DAWN45, pTemp); + } + JumpToNextStep(3000); + break; + + case 31: + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_STAND); + DoScriptText(EMOTE_LIGHT_OF_DAWN10, m_creature); + DoScriptText(SAY_LIGHT_OF_DAWN44, m_creature); + JumpToNextStep(3000); + break; + + case 32: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[27].x, LightofDawnLoc[27].y, LightofDawnLoc[27].z); + JumpToNextStep(6000); + break; + + case 33: // Darion supports to jump to lich king here +// disable if (Creature* pTemp = ((Creature*)Unit::GetUnit((*m_creature), uiLichKingGUID))) +// because mangos DoCast(m_creature, SPELL_MOGRAINE_CHARGE); // jumping charge +// doesn't make it looks well, so workarounds, Darion charges, looks better + m_creature->SetSpeedRate(MOVE_RUN, 3.0f); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + SetEscortPaused(false); + JumpToNextStep(0); + break; + + case 35: // Lich king counterattacks + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + { + pTemp->HandleEmoteCommand(EMOTE_ONESHOT_KICK); + DoScriptText(SAY_LIGHT_OF_DAWN46, pTemp); + } + m_creature->SetSpeedRate(MOVE_RUN, 6.0f); + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_DEAD); + SetEscortPaused(false); // Darion got kicked by lich king + JumpToNextStep(0); + break; + + case 37: // Lich king counterattacks + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_KNEEL); + JumpToNextStep(3000); + break; + + case 38: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN47, pTemp); + JumpToNextStep(8000); + break; + + case 39: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN48, pTemp); + JumpToNextStep(15000); + break; + + case 40: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN49, pTemp); + JumpToNextStep(17000); + break; + + case 41: // Lich king - Apocalypse + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + { + DoScriptText(EMOTE_LIGHT_OF_DAWN11, pTemp); + DoScriptText(SAY_LIGHT_OF_DAWN51, pTemp); + if (Creature* pTirion = m_creature->GetMap()->GetCreature(uiTirionGUID)) + { + ((Unit*)pTirion)->SetStandState(UNIT_STAND_STATE_KNEEL); + //pTemp->CastSpell(pTirion, SPELL_APOCALYPSE, false); // not working + pTemp->CastSpell(pTirion, SPELL_SOUL_FEAST_TIRION, false); + DoScriptText(EMOTE_LIGHT_OF_DAWN12, pTirion); + } + } + JumpToNextStep(2000); + break; + + case 42: // Maxwell yells for attack + { + float fLichPositionX, fLichPositionY, fLichPositionZ; + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + { + fLichPositionX = pTemp->GetPositionX(); + fLichPositionY = pTemp->GetPositionY(); + fLichPositionZ = pTemp->GetPositionZ(); + } + + if (fLichPositionX && fLichPositionY) + { + Creature* pTemp; + if (pTemp = m_creature->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].x+rand()%10, LightofDawnLoc[0].y+rand()%10, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetSpeedRate(MOVE_RUN, 2.0f); + pTemp->setFaction(m_creature->getFaction()); + pTemp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); + uiDefenderGUID[0] = pTemp->GetGUID(); + } + + if (pTemp = m_creature->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].x+rand()%10, LightofDawnLoc[0].y+rand()%10, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetSpeedRate(MOVE_RUN, 2.0f); + pTemp->setFaction(m_creature->getFaction()); + pTemp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); + uiEarthshatterGUID[0] = pTemp->GetGUID(); + } + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetSpeedRate(MOVE_RUN, 2.0f); + pTemp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); + DoScriptText(SAY_LIGHT_OF_DAWN50, pTemp); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetSpeedRate(MOVE_RUN, 2.0f); + pTemp->HandleEmoteCommand(EMOTE_STATE_ATTACK_UNARMED); + pTemp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetSpeedRate(MOVE_RUN, 2.0f); + pTemp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); + } + } + JumpToNextStep(4500); + break; + + case 43: // They all got kicked + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + DoScriptText(EMOTE_LIGHT_OF_DAWN13, pTemp); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + pTemp->SetSpeedRate(MOVE_RUN, 6.0f); + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_DEAD); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[14].x, LightofDawnLoc[14].y, LightofDawnLoc[14].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + pTemp->SetSpeedRate(MOVE_RUN, 6.0f); + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_DEAD); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[11].x, LightofDawnLoc[11].y, LightofDawnLoc[11].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID)) + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + pTemp->SetSpeedRate(MOVE_RUN, 6.0f); + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_DEAD); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[17].x, LightofDawnLoc[17].y, LightofDawnLoc[17].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDefenderGUID[0])) + { + pTemp->SetSpeedRate(MOVE_RUN, 6.0f); + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_DEAD); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%10, LightofDawnLoc[0].y+rand()%10, LightofDawnLoc[0].z); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEarthshatterGUID[0])) + { + pTemp->SetSpeedRate(MOVE_RUN, 6.0f); + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_DEAD); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%10, LightofDawnLoc[0].y+rand()%10, LightofDawnLoc[0].z); + } + JumpToNextStep(3000); + break; + + case 44: // make them stand up + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)) + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_STAND); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID)) + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_STAND); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID)) + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_STAND); + JumpToNextStep(1000); + break; + + case 45: + DoScriptText(SAY_LIGHT_OF_DAWN52, m_creature); + JumpToNextStep(5000); + break; + + case 46: // Darion stand up, "not today" + m_creature->SetSpeedRate(MOVE_RUN, 1.0f); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_STAND); + DoScriptText(SAY_LIGHT_OF_DAWN53, m_creature); + SetEscortPaused(false); // Darion throws sword + JumpToNextStep(7000); + break; + + case 47: // Ashbringer rebirth + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_KNEEL); + DoScriptText(EMOTE_LIGHT_OF_DAWN15, m_creature); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + { + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_STAND); + pTemp->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_HIGHLORD_TIRION_FORDRING)); + pTemp->CastSpell(pTemp, SPELL_REBIRTH_OF_THE_ASHBRINGER, false); + } + JumpToNextStep(1000); + break; + + case 48: // Show the cleansing effect (dawn of light) + if (GameObject* pGo = m_creature->GetMap()->GetGameObject(uiDawnofLightGUID)) + pGo->SetPhaseMask(128, true); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + { + if (pTemp->HasAura(SPELL_REBIRTH_OF_THE_ASHBRINGER)) + pTemp->RemoveAurasDueToSpell(SPELL_REBIRTH_OF_THE_ASHBRINGER); + pTemp->CastSpell(pTemp, 41542, false); // workarounds, light expoded, makes it cool + pTemp->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + pTemp->InterruptNonMeleeSpells(false); + JumpToNextStep(2500); + break; + + case 49: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN54, pTemp); + JumpToNextStep(4000); + break; + + case 50: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN55, pTemp); + JumpToNextStep(5000); + break; + + case 51: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN56, pTemp); + JumpToNextStep(1000); + break; + + case 52: // Tiron charges + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + { + DoScriptText(EMOTE_LIGHT_OF_DAWN16, pTemp); + pTemp->CastSpell(pTemp, SPELL_TIRION_CHARGE, false); // jumping charge + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); + pTemp->SetSpeedRate(MOVE_RUN, 3.0f); // workarounds, make Tirion still running + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[2].x, LightofDawnLoc[2].y, LightofDawnLoc[2].z); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + pTemp->GetMap()->CreatureRelocation(pTemp, LightofDawnLoc[28].x, LightofDawnLoc[28].y, LightofDawnLoc[28].z, 0.0f); // workarounds, he should kick back by Tirion, but here we relocate him + } + JumpToNextStep(1500); + break; + + case 53: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN57, pTemp); + JumpToNextStep(1000); + break; + + case 54: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + { + pTemp->SetSpeedRate(MOVE_RUN, 1.0f); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[29].x, LightofDawnLoc[29].y, LightofDawnLoc[29].z); // 26 + } + JumpToNextStep(4000); + break; + + case 55: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_KNEEL); + JumpToNextStep(2000); + break; + + case 56: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + ((Unit*)pTemp)->SetStandState(UNIT_STAND_STATE_STAND); + JumpToNextStep(1500); + break; + + case 57: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN58, pTemp); + JumpToNextStep(10000); + break; + + case 58: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN59, pTemp); + JumpToNextStep(10000); + break; + + case 59: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) + pTemp->CastSpell(pTemp, SPELL_TELEPORT_VISUAL, false); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) // Tirion runs to Darion + { + pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + pTemp->SetSpeedRate(MOVE_RUN, 1.0f); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[6].x, LightofDawnLoc[6].y, LightofDawnLoc[6].z); + } + JumpToNextStep(2500); + break; + + case 60: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID)) // Lich king disappears here + { + DoScriptText(EMOTE_LIGHT_OF_DAWN17, pTemp); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + JumpToNextStep(10000); + break; + + case 61: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN60, pTemp); + JumpToNextStep(3000); + break; + + case 62: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + { + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[7].x, LightofDawnLoc[7].y, LightofDawnLoc[7].z); + } + JumpToNextStep(5500); + break; + + case 63: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + { + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[8].x, LightofDawnLoc[8].y, LightofDawnLoc[8].z); + DoScriptText(SAY_LIGHT_OF_DAWN61, pTemp); + } + JumpToNextStep(15000); + break; + + case 64: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN62, pTemp); + JumpToNextStep(7000); + break; + + case 65: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN63, pTemp); + JumpToNextStep(10000); + break; + + case 66: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN64, pTemp); + JumpToNextStep(11000); + break; + + case 67: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN65, pTemp); + JumpToNextStep(10000); + break; + + case 68: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN66, pTemp); + JumpToNextStep(8000); + break; + + case 69: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN67, pTemp); + JumpToNextStep(10000); + break; + + case 70: + ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_STAND); + DoScriptText(SAY_LIGHT_OF_DAWN68, m_creature); + JumpToNextStep(10000); + break; + + case 71: + if (GameObject* pGo = m_creature->GetMap()->GetGameObject(uiDawnofLightGUID)) // Turn off dawn of light + pGo->SetPhaseMask(0, true); + + { + Map *map = m_creature->GetMap(); // search players with in 50 yards for quest credit + Map::PlayerList const &PlayerList = map->GetPlayers(); + if (!PlayerList.isEmpty()) + { + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (i->getSource()->isAlive() && m_creature->IsWithinDistInMap(i->getSource(), 50)) + i->getSource()->CastSpell(i->getSource(), SPELL_THE_LIGHT_OF_DAWN_Q, false); + } + } + m_creature->SetVisibility(VISIBILITY_OFF); // respawns another Darion for quest turn in + m_creature->SummonCreature(NPC_HIGHLORD_DARION_MOGRAINE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 180000); + JumpToNextStep(1000); + break; + + case 72: + SetEscortPaused(false); // Escort ends + JumpToNextStep(0); + break; + } + + }else uiPhase_timer -= diff; + } + + // ******* During battle ***************************************************************** + else + { + if (uiAnti_magic_zone < diff) + { + DoCast(m_creature, SPELL_ANTI_MAGIC_ZONE1); + uiAnti_magic_zone = 25000 + rand()%5000; + }else uiAnti_magic_zone -= diff; + + if (uiDeath_strike < diff) + { + DoCast(m_creature->getVictim(), SPELL_DEATH_STRIKE); + uiDeath_strike = 5000 + rand()%5000; + }else uiDeath_strike -= diff; + + if (uiDeath_embrace < diff) + { + DoCast(m_creature->getVictim(), SPELL_DEATH_EMBRACE); + uiDeath_embrace = 5000 + rand()%5000; + }else uiDeath_embrace -= diff; + + if (uiIcy_touch < diff) + { + DoCast(m_creature->getVictim(), SPELL_ICY_TOUCH1); + uiIcy_touch = 5000 + rand()%5000; + }else uiIcy_touch -= diff; + + if (uiUnholy_blight < diff) + { + DoCast(m_creature->getVictim(), SPELL_UNHOLY_BLIGHT); + uiUnholy_blight = 5000 + rand()%5000; + }else uiUnholy_blight -= diff; + + if (uiFight_speech < diff) + { + switch(rand()%15) + { + case 0: DoScriptText(SAY_LIGHT_OF_DAWN09, m_creature);break; + case 1: DoScriptText(SAY_LIGHT_OF_DAWN10, m_creature);break; + case 2: DoScriptText(SAY_LIGHT_OF_DAWN11, m_creature);break; + case 3: DoScriptText(SAY_LIGHT_OF_DAWN12, m_creature);break; + case 4: DoScriptText(SAY_LIGHT_OF_DAWN13, m_creature);break; + case 5: DoScriptText(SAY_LIGHT_OF_DAWN14, m_creature);break; + case 6: DoScriptText(SAY_LIGHT_OF_DAWN15, m_creature);break; + case 7: DoScriptText(SAY_LIGHT_OF_DAWN16, m_creature);break; + case 8: DoScriptText(SAY_LIGHT_OF_DAWN17, m_creature);break; + case 9: DoScriptText(SAY_LIGHT_OF_DAWN18, m_creature);break; + case 10: DoScriptText(SAY_LIGHT_OF_DAWN19, m_creature);break; + case 11: DoScriptText(SAY_LIGHT_OF_DAWN20, m_creature);break; + case 12: DoScriptText(SAY_LIGHT_OF_DAWN21, m_creature);break; + case 13: DoScriptText(SAY_LIGHT_OF_DAWN22, m_creature);break; + case 14: DoScriptText(SAY_LIGHT_OF_DAWN23, m_creature);break; + case 15: DoScriptText(SAY_LIGHT_OF_DAWN24, m_creature);break; + } + uiFight_speech = 15000 + rand()%5000; + }else uiFight_speech -= diff; + + // Check spawns + if (uiSpawncheck < diff) + { + SpawnNPC(); + uiSpawncheck = 1000; + }else uiSpawncheck -= diff; + + // Check targets + if (uiTargetcheck < diff) + { + for(uint8 i = 0; i < ENCOUNTER_GHOUL_NUMBER; ++i) + NPCChangeTarget(uiGhoulGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_WARRIOR_NUMBER; ++i) + NPCChangeTarget(uiWarriorGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_ABOMINATION_NUMBER; ++i) + NPCChangeTarget(uiAbominationGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_BEHEMOTH_NUMBER; ++i) + NPCChangeTarget(uiBehemothGUID[i]); + NPCChangeTarget(uiKoltiraGUID); + NPCChangeTarget(uiOrbazGUID); + NPCChangeTarget(uiThassarianGUID); + + uiTargetcheck = 10000; + }else uiTargetcheck -= diff; + + // Battle end + if (uiFight_duration < diff + 5000) + { + if (!uiTirionGUID) + if (Creature* pTemp = m_creature->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING, LightofDawnLoc[0].x, LightofDawnLoc[0].y, LightofDawnLoc[0].z, 1.528f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000)) + { + pTemp->setFaction(m_creature->getFaction()); + pTemp->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP)); + DoScriptText(SAY_LIGHT_OF_DAWN25, pTemp); + uiTirionGUID = pTemp->GetGUID(); + } + } + if (uiFight_duration < diff) + { + bIsBattle = false; + uiFight_duration = 300000; + + if (m_creature->HasAura(SPELL_THE_MIGHT_OF_MOGRAINE, EFFECT_INDEX_0)) + m_creature->RemoveAurasDueToSpell(SPELL_THE_MIGHT_OF_MOGRAINE); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->InterruptNonMeleeSpells(false); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + + for(uint8 i = 0; i < ENCOUNTER_DEFENDER_NUMBER; ++i) + DespawnNPC(uiDefenderGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_EARTHSHATTER_NUMBER; ++i) + DespawnNPC(uiEarthshatterGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_ABOMINATION_NUMBER; ++i) + DespawnNPC(uiAbominationGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_BEHEMOTH_NUMBER; ++i) + DespawnNPC(uiBehemothGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_GHOUL_NUMBER; ++i) + DespawnNPC(uiGhoulGUID[i]); + for(uint8 i = 0; i < ENCOUNTER_WARRIOR_NUMBER; ++i) + DespawnNPC(uiWarriorGUID[i]); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID)) + { + pTemp->RemoveAllAuras(); + pTemp->DeleteThreatList(); + pTemp->CombatStop(true); + pTemp->AttackStop(); + pTemp->setFaction(m_creature->getFaction()); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[9].x, LightofDawnLoc[9].y, LightofDawnLoc[9].z); + } + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)) + { + pTemp->RemoveAllAuras(); + pTemp->DeleteThreatList(); + pTemp->CombatStop(true); + pTemp->AttackStop(); + pTemp->setFaction(m_creature->getFaction()); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[12].x, LightofDawnLoc[12].y, LightofDawnLoc[12].z); + } + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID)) + { + pTemp->RemoveAllAuras(); + pTemp->DeleteThreatList(); + pTemp->CombatStop(true); + pTemp->AttackStop(); + pTemp->setFaction(m_creature->getFaction()); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[15].x, LightofDawnLoc[15].y, LightofDawnLoc[15].z); + } + DespawnNPC(uiRayneGUID); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID)) + { + pTemp->RemoveAllAuras(); + pTemp->DeleteThreatList(); + pTemp->CombatStop(true); + pTemp->AttackStop(); + pTemp->setFaction(m_creature->getFaction()); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[18].x, LightofDawnLoc[18].y, LightofDawnLoc[18].z); + pTemp->CastSpell(pTemp, SPELL_THE_LIGHT_OF_DAWN, false); + } + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiOrbazGUID)) + DoScriptText(EMOTE_LIGHT_OF_DAWN04, pTemp); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID)) + { + pTemp->RemoveAllAuras(); + pTemp->DeleteThreatList(); + pTemp->CombatStop(true); + pTemp->AttackStop(); + pTemp->setFaction(m_creature->getFaction()); + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[20].x, LightofDawnLoc[20].y, LightofDawnLoc[20].z); + pTemp->CastSpell(pTemp, SPELL_THE_LIGHT_OF_DAWN, false); + } + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID)) + DoScriptText(SAY_LIGHT_OF_DAWN26, pTemp); + + SetEscortPaused(false); + + }else uiFight_duration -= diff; + + DoMeleeAttackIfReady(); + } + } + + void JumpToNextStep(uint32 uiTimer) + { + uiPhase_timer = uiTimer; + uiStep++; + } + + void NPCChangeTarget(uint64 ui_GUID) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(ui_GUID)) + if (pTemp->isAlive()) + if (Unit* pTarger = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (pTarger->isAlive()) + { + ((Creature*)pTemp)->AddThreat(pTarger, 0.0f); + ((Creature*)pTemp)->AI()->AttackStart(pTarger); + ((Creature*)pTemp)->SetInCombatWith(pTarger); + pTarger->SetInCombatWith(pTemp); + } + } + + void SpawnNPC() + { + Creature* pTemp = NULL; + + // Death + for(uint8 i = 0; i < ENCOUNTER_GHOUL_NUMBER; ++i) + { + if (!(pTemp = m_creature->GetMap()->GetCreature(uiGhoulGUID[i]))) + { + pTemp = m_creature->SummonCreature(NPC_ACHERUS_GHOUL, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); + pTemp->setFaction(2084); + uiGhoulGUID[i] = pTemp->GetGUID(); + } + } + for(uint8 i = 0; i < ENCOUNTER_ABOMINATION_NUMBER; ++i) + { + if (!(pTemp = m_creature->GetMap()->GetCreature(uiAbominationGUID[i]))) + { + pTemp = m_creature->SummonCreature(NPC_WARRIOR_OF_THE_FROZEN_WASTES, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); + pTemp->setFaction(2084); + uiAbominationGUID[i] = pTemp->GetGUID(); + } + } + for(uint8 i = 0; i < ENCOUNTER_WARRIOR_NUMBER; ++i) + { + if (!(pTemp = m_creature->GetMap()->GetCreature(uiWarriorGUID[i]))) + { + pTemp = m_creature->SummonCreature(NPC_RAMPAGING_ABOMINATION, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); + pTemp->setFaction(2084); + uiWarriorGUID[i] = pTemp->GetGUID(); + } + } + for(uint8 i = 0; i < ENCOUNTER_BEHEMOTH_NUMBER; ++i) + { + if (!(pTemp = m_creature->GetMap()->GetCreature(uiBehemothGUID[i]))) + { + pTemp = m_creature->SummonCreature(NPC_FLESH_BEHEMOTH, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); + pTemp->setFaction(2084); + uiBehemothGUID[i] = pTemp->GetGUID(); + } + } + + // Dawn + for(uint8 i = 0; i < ENCOUNTER_DEFENDER_NUMBER; ++i) + { + if (!(pTemp = m_creature->GetMap()->GetCreature(uiDefenderGUID[i]))) + { + pTemp = m_creature->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); + pTemp->setFaction(2089); + m_creature->AddThreat(pTemp, 0.0f); + uiDefenderGUID[i] = pTemp->GetGUID(); + } + } + for(uint8 i = 0; i < ENCOUNTER_EARTHSHATTER_NUMBER; ++i) + { + if (!(pTemp = m_creature->GetMap()->GetCreature(uiEarthshatterGUID[i]))) + { + pTemp = m_creature->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); + pTemp->setFaction(2089); + m_creature->AddThreat(pTemp, 0.0f); + uiEarthshatterGUID[i] = pTemp->GetGUID(); + } + } + if (!(pTemp = m_creature->GetMap()->GetCreature(uiKorfaxGUID))) + { + pTemp = m_creature->SummonCreature(NPC_KORFAX_CHAMPION_OF_THE_LIGHT, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000); + pTemp->setFaction(2089); + m_creature->AddThreat(pTemp, 0.0f); + uiKorfaxGUID = pTemp->GetGUID(); + } + if (!(pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID))) + { + pTemp = m_creature->SummonCreature(NPC_LORD_MAXWELL_TYROSUS, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000); + pTemp->setFaction(2089); + m_creature->AddThreat(pTemp, 0.0f); + uiMaxwellGUID = pTemp->GetGUID(); + } + if (!(pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID))) + { + pTemp = m_creature->SummonCreature(NPC_COMMANDER_ELIGOR_DAWNBRINGER, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000); + pTemp->setFaction(2089); + m_creature->AddThreat(pTemp, 0.0f); + uiEligorGUID = pTemp->GetGUID(); + } + if (!(pTemp = m_creature->GetMap()->GetCreature(uiRayneGUID))) + { + pTemp = m_creature->SummonCreature(NPC_RAYNE, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); + pTemp->setFaction(2089); + m_creature->AddThreat(pTemp, 0.0f); + uiRayneGUID = pTemp->GetGUID(); + } + } + + void DespawnNPC(uint64 pGUID) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pGUID)) + if (pTemp->isAlive()) + { + pTemp->SetVisibility(VISIBILITY_OFF); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } +}; + +bool GossipHello_npc_highlord_darion_mograine(Player* pPlayer, Creature* pCreature) +{ + if (pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu( pCreature->GetGUID() ); + + if (pPlayer->GetQuestStatus(12801) == QUEST_STATUS_INCOMPLETE) + pPlayer->ADD_GOSSIP_ITEM( 0, "I am ready.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_highlord_darion_mograine(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + switch (uiAction) + { + case GOSSIP_ACTION_INFO_DEF+1: + pPlayer->CLOSE_GOSSIP_MENU(); + ((npc_highlord_darion_mograineAI*)pCreature->AI())->uiStep = 1; + ((npc_highlord_darion_mograineAI*)pCreature->AI())->Start(false, pPlayer->GetGUID()); + break; + } + return true; +} + +/*###### +## npc the lich king in dawn of light +######*/ +struct MANGOS_DLL_DECL npc_the_lich_king_tirion_dawnAI : public ScriptedAI +{ + npc_the_lich_king_tirion_dawnAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + void Reset() {} + void AttackStart(Unit *who) { return; } // very sample, just don't make them aggreesive + void UpdateAI(const uint32 diff) { return; } + void JustDied(Unit* killer) {} +}; + +/*###### +## npc orbaz, koltira, tassarian +######*/ +struct MANGOS_DLL_DECL npc_minibosses_dawn_of_lightAI : public ScriptedAI +{ + npc_minibosses_dawn_of_lightAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + + uint32 uiIcyTouchTimer; + uint32 uiBloodStrikeTimer; + uint32 uiPlagueStrikeTimer; + + void Reset() + { + uiIcyTouchTimer = urand(10000, 20000); + uiBloodStrikeTimer = urand(10000, 20000); + uiPlagueStrikeTimer = urand(10000, 20000); + } + + bool EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) + { + m_creature->GetMotionMaster()->MoveIdle(); + return false; + } + void EnterEvadeMode() + { + m_creature->GetMotionMaster()->MoveIdle(); + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->getVictim() || !m_creature->SelectHostileTarget() ) + return; + + if (uiIcyTouchTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_ICY_TOUCH); + uiIcyTouchTimer = urand(10000, 20000); + } + else uiIcyTouchTimer -= uiDiff; + + if (uiBloodStrikeTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLOOD_STRIKE); + uiBloodStrikeTimer = urand(10000, 20000); + } + else uiBloodStrikeTimer -= uiDiff; + + if (uiPlagueStrikeTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_PLAGUE_STRIKE1); + uiPlagueStrikeTimer = urand(10000, 20000); + } + else uiPlagueStrikeTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## Acherus Ghoul (29219) +######*/ +struct MANGOS_DLL_DECL mob_acherus_ghoulAI : public ScriptedAI +{ + mob_acherus_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsReady = false; + m_bIsSpawned = false; + m_bIsInBattle = (m_creature->GetPositionX() < 2300.0f) ? true : false; + + m_pMap = m_creature->GetMap(); + + Reset(); + } + + Map *m_pMap; + + uint32 m_uiReadyTimer; + uint32 m_uiGhoulplosionTimer; + + bool m_bIsReady; + bool m_bIsSpawned; + bool m_bIsInBattle; + + void EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) { return; } + + void Reset() + { + m_uiReadyTimer = 4000; + m_uiGhoulplosionTimer = 30000; + } + + void MoveInLineOfSight(Unit *pWho) + { + if (!m_bIsReady) + return; + + ScriptedAI::MoveInLineOfSight(pWho); + } + + void AttackStart(Unit *pWho) + { + if (!m_bIsReady) + return; + + ScriptedAI::AttackStart(pWho); + } + + void UpdateAI(uint32 const uiDiff) + { + if (!m_bIsReady) + { + if (!m_bIsSpawned) + { + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + m_bIsSpawned = true; + } + + if (m_uiReadyTimer <= uiDiff) + m_bIsReady = true; + else m_uiReadyTimer -= uiDiff; + + return; + } + + if (!m_creature->getVictim() || !m_creature->SelectHostileTarget() ) + { + if (m_bIsInBattle && m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CONFUSED_MOTION_TYPE) + m_creature->GetMotionMaster()->MoveConfused(); + + return; + } + + if (m_uiGhoulplosionTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature, SPELL_GHOULPLOSION); + m_uiGhoulplosionTimer = 30000; + } + else m_uiGhoulplosionTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## mob_warrior_of_the_frozen_wastes (53631) +######*/ +struct MANGOS_DLL_DECL mob_warrior_of_the_frozen_wastesAI : public ScriptedAI +{ + mob_warrior_of_the_frozen_wastesAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsReady = false; + m_bIsSpawned = false; + m_bIsInBattle = (m_creature->GetPositionX() < 2300.0f) ? true : false; + + Reset(); + } + + uint32 m_uiReadyTimer; + uint32 m_uiCleaveTimer; + + bool m_bIsReady; + bool m_bIsSpawned; + bool m_bIsInBattle; + + void EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) { return; } + + void Reset() + { + m_uiReadyTimer = 4000; + m_uiCleaveTimer = urand(3000, 5000); + } + + void AttackStart(Unit *pWho) + { + if (!m_bIsReady) + return; + + ScriptedAI::AttackStart(pWho); + } + + void MoveInLineOfSight(Unit *pWho) + { + if (!m_bIsReady) + return; + + CreatureAI::MoveInLineOfSight(pWho); + } + + void UpdateAI(uint32 const uiDiff) + { + if (!m_bIsReady) + { + if (!m_bIsSpawned) + { + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + m_bIsSpawned = true; + } + + if (m_uiReadyTimer <= uiDiff) + m_bIsReady = true; + else m_uiReadyTimer -= uiDiff; + + return; + } + + if (!m_creature->getVictim() || !m_creature->SelectHostileTarget() ) + { + if (m_bIsInBattle && m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CONFUSED_MOTION_TYPE) + m_creature->GetMotionMaster()->MoveConfused(); + + return; + } + + if (m_uiCleaveTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE); + m_uiCleaveTimer = urand(13000, 15000); + } + else m_uiCleaveTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_highlord_darion_mograine(Creature* pCreature) +{ + return new npc_highlord_darion_mograineAI(pCreature); +} + +CreatureAI* GetAI_npc_the_lich_king_tirion_dawn(Creature* pCreature) +{ + return new npc_the_lich_king_tirion_dawnAI(pCreature); +}; + +CreatureAI* GetAI_npc_minibosses_dawn_of_light(Creature* pCreature) +{ + return new npc_minibosses_dawn_of_lightAI (pCreature); +} + +CreatureAI* GetAI_mob_warrior_of_the_frozen_wastes(Creature* pCreature) +{ + return new mob_warrior_of_the_frozen_wastesAI(pCreature); +} + +CreatureAI* GetAI_mob_acherus_ghoul(Creature* pCreature) +{ + return new mob_acherus_ghoulAI(pCreature); +}; + void AddSC_ebon_hold() { Script* pNewScript; @@ -1163,7 +3269,7 @@ void AddSC_ebon_hold() pNewScript = new Script; pNewScript->Name = "npc_koltira_deathweaver"; pNewScript->GetAI = &GetAI_npc_koltira_deathweaver; - pNewScript->pQuestAccept = &QuestAccept_npc_koltira_deathweaver; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_koltira_deathweaver; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -1178,6 +3284,44 @@ void AddSC_ebon_hold() pNewScript = new Script; pNewScript->Name = "go_acherus_soul_prison"; - pNewScript->pGOHello = &GOHello_go_acherus_soul_prison; + pNewScript->pGOUse = &GOUse_go_acherus_soul_prison; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_eye_of_acherus"; + pNewScript->GetAI = &GetAI_npc_eye_of_acherus; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_scarlet_ghoul"; + pNewScript->GetAI = &GetAI_mob_scarlet_ghoul; pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_highlord_darion_mograine"; + pNewScript->GetAI = &GetAI_npc_highlord_darion_mograine; + pNewScript->pGossipHello = &GossipHello_npc_highlord_darion_mograine; + pNewScript->pGossipSelect = &GossipSelect_npc_highlord_darion_mograine; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_the_lich_king_tirion_dawn"; + pNewScript->GetAI = &GetAI_npc_the_lich_king_tirion_dawn; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_minibosses_dawn_of_light"; + pNewScript->GetAI = &GetAI_npc_minibosses_dawn_of_light; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_acherus_ghoul"; + pNewScript->GetAI = &GetAI_mob_acherus_ghoul; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_warrior_of_the_frozen_wastes"; + pNewScript->GetAI = &GetAI_mob_warrior_of_the_frozen_wastes; + pNewScript->RegisterSelf(); + } diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp index f7a09a9ca..7fa26c4c5 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp index ecb71f9d4..26cebf953 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp index 6fe0745cc..a7b992d8e 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp index dbb941ed0..ed726d319 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp index fc13cb4c3..2ea2a4766 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -32,7 +32,7 @@ enum SAY_KILL = -1189003, EMOTE_GENERIC_ENRAGED = -1000003, - SAY_TRAINEE_SPAWN = -1189036, + SAY_TRAINEE_SPAWN = -1189035, SPELL_RUSHINGCHARGE = 8260, SPELL_CLEAVE = 15496, @@ -48,7 +48,7 @@ struct MANGOS_DLL_DECL boss_herodAI : public ScriptedAI bool m_bEnrage; bool m_bTraineeSay; - + uint32 m_uiCleaveTimer; uint32 m_uiWhirlwindTimer; @@ -56,7 +56,7 @@ struct MANGOS_DLL_DECL boss_herodAI : public ScriptedAI { m_bTraineeSay = false; m_bEnrage = false; - + m_uiCleaveTimer = 12000; m_uiWhirlwindTimer = 45000; } diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp index 9725d6dbf..79fdf60c1 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp index ce7f2ae37..973ec8a8e 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp index 346dfe352..1e2dad0a4 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp index a036b9f73..61db1c4bf 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp b/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp index ae35efc27..3f2b01490 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp b/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp index 38b1fe051..d8c7e502a 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp +++ b/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h b/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h index 62e3443ce..19cea3e7b 100644 --- a/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h +++ b/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp b/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp index 0355a2bbd..3c922152d 100644 --- a/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp +++ b/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,36 +17,20 @@ /* ScriptData SDName: Boss_Darkmaster_Gandling SD%Complete: 75 -SDComment: Doors missing +SDComment: TODO: Implement teleport spells in MaNGOS and WorldDB SDCategory: Scholomance EndScriptData */ #include "precompiled.h" #include "scholomance.h" -#define SPELL_ARCANEMISSILES 22272 -#define SPELL_SHADOWSHIELD 22417 //Not right ID. But 12040 is wrong either. -#define SPELL_CURSE 18702 - -#define ADD_1X 170.205 -#define ADD_1Y 99.413 -#define ADD_1Z 104.733 -#define ADD_1O 3.16 - -#define ADD_2X 170.813 -#define ADD_2Y 97.857 -#define ADD_2Z 104.713 -#define ADD_2O 3.16 - -#define ADD_3X 170.720 -#define ADD_3Y 100.900 -#define ADD_3Z 104.739 -#define ADD_3O 3.16 - -#define ADD_4X 171.866 -#define ADD_4Y 99.373 -#define ADD_4Z 104.732 -#define ADD_4O 3.16 +enum +{ + SPELL_ARCANE_MISSILES = 15790, // SpellId not sure, original was 22272 + SPELL_SHADOW_SHIELD = 12040, // SpellID not sure, original was 22417 stated as "wrong, but 12040 is wrong either." + SPELL_CURSE = 18702, + SPELL_SHADOW_PORTAL = 17950 // TODO implement this spell(and other related port spells) in DB and MaNGOS +}; struct MANGOS_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI { @@ -58,58 +42,58 @@ struct MANGOS_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 ArcaneMissiles_Timer; - uint32 ShadowShield_Timer; - uint32 Curse_Timer; - uint32 Teleport_Timer; + uint32 m_uiArcaneMissilesTimer; + uint32 m_uiShadowShieldTimer; + uint32 m_uiCurseTimer; + uint32 m_uiTeleportTimer; Creature *Summoned; void Reset() { - ArcaneMissiles_Timer = 4500; - ShadowShield_Timer = 12000; - Curse_Timer = 2000; - Teleport_Timer = 16000; - } - - void JustDied(Unit *killer) - { - if (m_pInstance) - m_pInstance->SetData(TYPE_GANDLING, DONE); + m_uiArcaneMissilesTimer = 4500; + m_uiShadowShieldTimer = 12000; + m_uiCurseTimer = 2000; + m_uiTeleportTimer = 16000; } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ArcaneMissiles_Timer - if (ArcaneMissiles_Timer < diff) + // Arcane Missiles Timer + if (m_uiArcaneMissilesTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ARCANEMISSILES); - ArcaneMissiles_Timer = 8000; - }else ArcaneMissiles_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ARCANE_MISSILES) == CAST_OK) + m_uiArcaneMissilesTimer = 8000; + } + else + m_uiArcaneMissilesTimer -= uiDiff; - //ShadowShield_Timer - if (ShadowShield_Timer < diff) + // Shadow Shield Timer + if (m_uiShadowShieldTimer < uiDiff) { - DoCastSpellIfCan(m_creature,SPELL_SHADOWSHIELD); - ShadowShield_Timer = urand(14000, 28000); - }else ShadowShield_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_SHADOW_SHIELD) == CAST_OK) + m_uiShadowShieldTimer = urand(14000, 28000); + } + else + m_uiShadowShieldTimer -= uiDiff; - //Curse_Timer - if (Curse_Timer < diff) + // Curse Timer + if (m_uiCurseTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CURSE); - Curse_Timer = urand(15000, 27000); - }else Curse_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CURSE) == CAST_OK) + m_uiCurseTimer = urand(15000, 27000); + } + else + m_uiCurseTimer -= uiDiff; - //Teleporting Random Target to one of the six pre boss rooms and spawn 3-4 skeletons near the gamer. - //We will only telport if gandling has more than 3% of hp so teleported gamers can always loot. + // Teleporting Random Target to one of the six pre boss rooms and spawn 3-4 skeletons near the gamer. + // We will only telport if gandling has more than 3% of hp so teleported gamers can always loot. if (m_creature->GetHealthPercent() > 3.0f) { - if (Teleport_Timer < diff) + if (m_uiTeleportTimer < uiDiff) { Unit* target = NULL; target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); @@ -200,13 +184,16 @@ struct MANGOS_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI break; } } - Teleport_Timer = urand(20000, 35000); - }else Teleport_Timer -= diff; + m_uiTeleportTimer = urand(20000, 35000); + } + else + m_uiTeleportTimer -= uiDiff; } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_darkmaster_gandling(Creature* pCreature) { return new boss_darkmaster_gandlingAI(pCreature); @@ -214,9 +201,10 @@ CreatureAI* GetAI_boss_darkmaster_gandling(Creature* pCreature) void AddSC_boss_darkmaster_gandling() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_darkmaster_gandling"; - newscript->GetAI = &GetAI_boss_darkmaster_gandling; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_darkmaster_gandling"; + pNewScript->GetAI = &GetAI_boss_darkmaster_gandling; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp b/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp index 64a206839..4006f3b75 100644 --- a/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp +++ b/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp b/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp deleted file mode 100644 index 571ad0bd7..000000000 --- a/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_Doctor_Theolen_Krastinov -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ - -#include "precompiled.h" -#include "scholomance.h" - -enum -{ - EMOTE_GENERIC_FRENZY_KILL = -1000001, - - SPELL_REND = 16509, - SPELL_BACKHAND = 18103, - SPELL_FRENZY = 8269 -}; - -struct MANGOS_DLL_DECL boss_theolenkrastinovAI : public ScriptedAI -{ - boss_theolenkrastinovAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 m_uiRend_Timer; - uint32 m_uiBackhand_Timer; - uint32 m_uiFrenzy_Timer; - - void Reset() - { - m_uiRend_Timer = 8000; - m_uiBackhand_Timer = 9000; - m_uiFrenzy_Timer = 1000; - } - - void JustDied(Unit *killer) - { - if (ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData()) - { - pInstance->SetData(TYPE_THEOLEN, DONE); - - if (pInstance->GetData(TYPE_GANDLING) == SPECIAL) - m_creature->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - //Rend_Timer - if (m_uiRend_Timer < uiDiff) - { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_REND); - m_uiRend_Timer = 10000; - } - else - m_uiRend_Timer -= uiDiff; - - //m_uiBackhand_Timer - if (m_uiBackhand_Timer < uiDiff) - { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_BACKHAND); - m_uiBackhand_Timer = 10000; - } - else - m_uiBackhand_Timer -= uiDiff; - - //Frenzy_Timer - if (m_creature->GetHealthPercent() < 26.0f) - { - if (m_uiFrenzy_Timer < uiDiff) - { - if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) - { - DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature); - m_uiFrenzy_Timer = 120000; - } - } - else - m_uiFrenzy_Timer -= uiDiff; - } - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_theolenkrastinov(Creature* pCreature) -{ - return new boss_theolenkrastinovAI(pCreature); -} - -void AddSC_boss_theolenkrastinov() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_doctor_theolen_krastinov"; - newscript->GetAI = &GetAI_boss_theolenkrastinov; - newscript->RegisterSelf(); -} diff --git a/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp b/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp deleted file mode 100644 index d0e004c41..000000000 --- a/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_Illucia_Barov -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ - -#include "precompiled.h" -#include "scholomance.h" - -#define SPELL_CURSEOFAGONY 18671 -#define SPELL_SHADOWSHOCK 20603 -#define SPELL_SILENCE 15487 -#define SPELL_FEAR 6215 - -struct MANGOS_DLL_DECL boss_illuciabarovAI : public ScriptedAI -{ - boss_illuciabarovAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 CurseOfAgony_Timer; - uint32 ShadowShock_Timer; - uint32 Silence_Timer; - uint32 Fear_Timer; - - void Reset() - { - CurseOfAgony_Timer = 18000; - ShadowShock_Timer = 9000; - Silence_Timer = 5000; - Fear_Timer = 30000; - } - - void JustDied(Unit *killer) - { - if (ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData()) - { - pInstance->SetData(TYPE_ILLUCIABAROV, DONE); - - if (pInstance->GetData(TYPE_GANDLING) == SPECIAL) - m_creature->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - //CurseOfAgony_Timer - if (CurseOfAgony_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CURSEOFAGONY); - CurseOfAgony_Timer = 30000; - }else CurseOfAgony_Timer -= diff; - - //ShadowShock_Timer - if (ShadowShock_Timer < diff) - { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_SHADOWSHOCK); - - ShadowShock_Timer = 12000; - }else ShadowShock_Timer -= diff; - - //Silence_Timer - if (Silence_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SILENCE); - Silence_Timer = 14000; - }else Silence_Timer -= diff; - - //Fear_Timer - if (Fear_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FEAR); - Fear_Timer = 30000; - }else Fear_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; -CreatureAI* GetAI_boss_illuciabarov(Creature* pCreature) -{ - return new boss_illuciabarovAI(pCreature); -} - -void AddSC_boss_illuciabarov() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_illucia_barov"; - newscript->GetAI = &GetAI_boss_illuciabarov; - newscript->RegisterSelf(); -} diff --git a/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp b/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp deleted file mode 100644 index c39ad5951..000000000 --- a/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_instructormalicia -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ - -#include "precompiled.h" -#include "scholomance.h" - -#define SPELL_CALLOFGRAVES 17831 -#define SPELL_CORRUPTION 11672 -#define SPELL_FLASHHEAL 10917 -#define SPELL_RENEW 10929 -#define SPELL_HEALINGTOUCH 9889 - -struct MANGOS_DLL_DECL boss_instructormaliciaAI : public ScriptedAI -{ - boss_instructormaliciaAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 CallOfGraves_Timer; - uint32 Corruption_Timer; - uint32 FlashHeal_Timer; - uint32 Renew_Timer; - uint32 HealingTouch_Timer; - uint32 FlashCounter; - uint32 TouchCounter; - - void Reset() - { - CallOfGraves_Timer = 4000; - Corruption_Timer = 8000; - FlashHeal_Timer = 38000; - Renew_Timer = 32000; - HealingTouch_Timer = 45000; - FlashCounter = 0; - TouchCounter = 0; - } - - void JustDied(Unit *killer) - { - if (ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData()) - { - pInstance->SetData(TYPE_MALICIA, DONE); - - if (pInstance->GetData(TYPE_GANDLING) == SPECIAL) - m_creature->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - //CallOfGraves_Timer - if (CallOfGraves_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CALLOFGRAVES); - CallOfGraves_Timer = 65000; - }else CallOfGraves_Timer -= diff; - - //Corruption_Timer - if (Corruption_Timer < diff) - { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_CORRUPTION); - - Corruption_Timer = 24000; - }else Corruption_Timer -= diff; - - //Renew_Timer - if (Renew_Timer < diff) - { - DoCastSpellIfCan(m_creature, SPELL_RENEW); - Renew_Timer = 10000; - }else Renew_Timer -= diff; - - //FlashHeal_Timer - if (FlashHeal_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_FLASHHEAL); - - //5 Flashheals will be casted - if (FlashCounter < 2) - { - FlashHeal_Timer = 5000; - ++FlashCounter; - } - else - { - FlashCounter=0; - FlashHeal_Timer = 30000; - } - }else FlashHeal_Timer -= diff; - - //HealingTouch_Timer - if (HealingTouch_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_HEALINGTOUCH); - - //3 Healingtouchs will be casted - if (HealingTouch_Timer < 2) - { - HealingTouch_Timer = 5500; - ++TouchCounter; - } - else - { - TouchCounter=0; - HealingTouch_Timer = 30000; - } - }else HealingTouch_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; -CreatureAI* GetAI_boss_instructormalicia(Creature* pCreature) -{ - return new boss_instructormaliciaAI(pCreature); -} - -void AddSC_boss_instructormalicia() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_instructor_malicia"; - newscript->GetAI = &GetAI_boss_instructormalicia; - newscript->RegisterSelf(); -} diff --git a/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp b/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp index e8fd9237f..4203ad040 100644 --- a/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp +++ b/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp b/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp index 42601365e..52237d52a 100644 --- a/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp +++ b/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp b/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp deleted file mode 100644 index 9dfb790db..000000000 --- a/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_Lord_Alexei_Barov -SD%Complete: 100 -SDComment: aura applied/defined in database -SDCategory: Scholomance -EndScriptData */ - -#include "precompiled.h" -#include "scholomance.h" - -#define SPELL_IMMOLATE 20294 // Old ID was 15570 -#define SPELL_VEILOFSHADOW 17820 - -struct MANGOS_DLL_DECL boss_lordalexeibarovAI : public ScriptedAI -{ - boss_lordalexeibarovAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 Immolate_Timer; - uint32 VeilofShadow_Timer; - - void Reset() - { - Immolate_Timer = 7000; - VeilofShadow_Timer = 15000; - - m_creature->LoadCreatureAddon(); - } - - void JustDied(Unit *killer) - { - if (ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData()) - { - pInstance->SetData(TYPE_ALEXEIBAROV, DONE); - - if (pInstance->GetData(TYPE_GANDLING) == SPECIAL) - m_creature->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - //Immolate_Timer - if (Immolate_Timer < diff) - { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_IMMOLATE); - - Immolate_Timer = 12000; - }else Immolate_Timer -= diff; - - //VeilofShadow_Timer - if (VeilofShadow_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_VEILOFSHADOW); - VeilofShadow_Timer = 20000; - }else VeilofShadow_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; -CreatureAI* GetAI_boss_lordalexeibarov(Creature* pCreature) -{ - return new boss_lordalexeibarovAI(pCreature); -} - -void AddSC_boss_lordalexeibarov() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_lord_alexei_barov"; - newscript->GetAI = &GetAI_boss_lordalexeibarov; - newscript->RegisterSelf(); -} diff --git a/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp b/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp deleted file mode 100644 index 2c11cae19..000000000 --- a/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_Lorekeeper_Polkelt -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ - -#include "precompiled.h" -#include "scholomance.h" - -#define SPELL_VOLATILEINFECTION 24928 -#define SPELL_DARKPLAGUE 18270 -#define SPELL_CORROSIVEACID 23313 -#define SPELL_NOXIOUSCATALYST 18151 - -struct MANGOS_DLL_DECL boss_lorekeeperpolkeltAI : public ScriptedAI -{ - boss_lorekeeperpolkeltAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 VolatileInfection_Timer; - uint32 Darkplague_Timer; - uint32 CorrosiveAcid_Timer; - uint32 NoxiousCatalyst_Timer; - - void Reset() - { - VolatileInfection_Timer = 38000; - Darkplague_Timer = 8000; - CorrosiveAcid_Timer = 45000; - NoxiousCatalyst_Timer = 35000; - } - - void JustDied(Unit *killer) - { - if (ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData()) - { - pInstance->SetData(TYPE_POLKELT, DONE); - - if (pInstance->GetData(TYPE_GANDLING) == SPECIAL) - m_creature->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - //VolatileInfection_Timer - if (VolatileInfection_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_VOLATILEINFECTION); - VolatileInfection_Timer = 32000; - }else VolatileInfection_Timer -= diff; - - //Darkplague_Timer - if (Darkplague_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_DARKPLAGUE); - Darkplague_Timer = 8000; - }else Darkplague_Timer -= diff; - - //CorrosiveAcid_Timer - if (CorrosiveAcid_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CORROSIVEACID); - CorrosiveAcid_Timer = 25000; - }else CorrosiveAcid_Timer -= diff; - - //NoxiousCatalyst_Timer - if (NoxiousCatalyst_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_NOXIOUSCATALYST); - NoxiousCatalyst_Timer = 38000; - }else NoxiousCatalyst_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; -CreatureAI* GetAI_boss_lorekeeperpolkelt(Creature* pCreature) -{ - return new boss_lorekeeperpolkeltAI(pCreature); -} - -void AddSC_boss_lorekeeperpolkelt() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_lorekeeper_polkelt"; - newscript->GetAI = &GetAI_boss_lorekeeperpolkelt; - newscript->RegisterSelf(); -} diff --git a/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp b/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp deleted file mode 100644 index 3e8d123e9..000000000 --- a/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_Ras_Frostwhisper -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ - -#include "precompiled.h" - -#define SPELL_FROSTBOLT 21369 -#define SPELL_ICEARMOR 18100 //This is actually a buff he gives himself -#define SPELL_FREEZE 18763 -#define SPELL_FEAR 26070 -#define SPELL_CHILLNOVA 18099 -#define SPELL_FROSTVOLLEY 8398 - -struct MANGOS_DLL_DECL boss_rasfrostAI : public ScriptedAI -{ - boss_rasfrostAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 IceArmor_Timer; - uint32 Frostbolt_Timer; - uint32 Freeze_Timer; - uint32 Fear_Timer; - uint32 ChillNova_Timer; - uint32 FrostVolley_Timer; - - void Reset() - { - IceArmor_Timer = 2000; - Frostbolt_Timer = 8000; - ChillNova_Timer = 12000; - Freeze_Timer = 18000; - FrostVolley_Timer = 24000; - Fear_Timer = 45000; - - m_creature->CastSpell(m_creature,SPELL_ICEARMOR,true); - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - //IceArmor_Timer - if (IceArmor_Timer < diff) - { - DoCastSpellIfCan(m_creature, SPELL_ICEARMOR); - IceArmor_Timer = 180000; - }else IceArmor_Timer -= diff; - - //Frostbolt_Timer - if (Frostbolt_Timer < diff) - { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target) DoCastSpellIfCan(target,SPELL_FROSTBOLT); - - Frostbolt_Timer = 8000; - }else Frostbolt_Timer -= diff; - - //Freeze_Timer - if (Freeze_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FREEZE); - Freeze_Timer = 24000; - }else Freeze_Timer -= diff; - - //Fear_Timer - if (Fear_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FEAR); - Fear_Timer = 30000; - }else Fear_Timer -= diff; - - //ChillNova_Timer - if (ChillNova_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CHILLNOVA); - ChillNova_Timer = 14000; - }else ChillNova_Timer -= diff; - - //FrostVolley_Timer - if (FrostVolley_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FROSTVOLLEY); - FrostVolley_Timer = 15000; - }else FrostVolley_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; -CreatureAI* GetAI_boss_rasfrost(Creature* pCreature) -{ - return new boss_rasfrostAI(pCreature); -} - -void AddSC_boss_rasfrost() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_boss_ras_frostwhisper"; - newscript->GetAI = &GetAI_boss_rasfrost; - newscript->RegisterSelf(); -} diff --git a/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp b/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp deleted file mode 100644 index 4a5ce54b6..000000000 --- a/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_the_ravenian -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ - -#include "precompiled.h" -#include "scholomance.h" - -#define SPELL_TRAMPLE 15550 -#define SPELL_CLEAVE 20691 -#define SPELL_SUNDERINCLEAVE 25174 -#define SPELL_KNOCKAWAY 10101 - -struct MANGOS_DLL_DECL boss_theravenianAI : public ScriptedAI -{ - boss_theravenianAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 Trample_Timer; - uint32 Cleave_Timer; - uint32 SunderingCleave_Timer; - uint32 KnockAway_Timer; - bool HasYelled; - - void Reset() - { - Trample_Timer = 24000; - Cleave_Timer = 15000; - SunderingCleave_Timer = 40000; - KnockAway_Timer = 32000; - HasYelled = false; - } - - void JustDied(Unit *killer) - { - if (ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData()) - { - pInstance->SetData(TYPE_RAVENIAN, DONE); - - if (pInstance->GetData(TYPE_GANDLING) == SPECIAL) - m_creature->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - //Trample_Timer - if (Trample_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_TRAMPLE); - Trample_Timer = 10000; - }else Trample_Timer -= diff; - - //Cleave_Timer - if (Cleave_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE); - Cleave_Timer = 7000; - }else Cleave_Timer -= diff; - - //SunderingCleave_Timer - if (SunderingCleave_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SUNDERINCLEAVE); - SunderingCleave_Timer = 20000; - }else SunderingCleave_Timer -= diff; - - //KnockAway_Timer - if (KnockAway_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_KNOCKAWAY); - KnockAway_Timer = 12000; - }else KnockAway_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_theravenian(Creature* pCreature) -{ - return new boss_theravenianAI(pCreature); -} - -void AddSC_boss_theravenian() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_the_ravenian"; - newscript->GetAI = &GetAI_boss_theravenian; - newscript->RegisterSelf(); -} diff --git a/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp b/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp index 2635260b5..2e731251b 100644 --- a/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp +++ b/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp b/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp index 2a14e4d93..1c33cb2b7 100644 --- a/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp +++ b/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,104 +16,251 @@ /* ScriptData SDName: Instance_Scholomance -SD%Complete: 100 -SDComment: +SD%Complete: 80 +SDComment: Door handling for Gandling rooms after player-teleporting (close on Add Aggro, open when all Adds dead) missing SDCategory: Scholomance EndScriptData */ #include "precompiled.h" #include "scholomance.h" -struct MANGOS_DLL_DECL instance_scholomance : public ScriptedInstance +/* Darkmaster Gandling Encounter - Adds handling (MISSING) + * When a player is teleported to another room, there are 3 (perhaps sometimes 4) Adds spawned. + * When the first add Aggroes, the door to the room is closed + * When the last add dies, the door to the room is opened + * + * Also possible that this is better handled within the boss-script, depends on details of implementation of teleport spells + */ + +instance_scholomance::instance_scholomance(Map* pMap) : ScriptedInstance(pMap), + m_uiDarkmasterGandlingGUID(0), + m_uiGateKirtonosGUID(0), + m_uiGateRasGUID(0), + m_uiGateMiliciaGUID(0), + m_uiGateTheolenGUID(0), + m_uiGatePolkeltGUID(0), + m_uiGateRavenianGUID(0), + m_uiGateBarovGUID(0), + m_uiGateIlluciaGUID(0), + m_uiGateGandlingGUID(0) +{ + Initialize(); +} + +void instance_scholomance::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} + +void instance_scholomance::OnPlayerEnter(Player* pPlayer) +{ + // Summon Gandling if can + DoSpawnGandlingIfCan(true); +} + +void instance_scholomance::OnCreatureCreate(Creature* pCreature) +{ + switch (pCreature->GetEntry()) + { + case NPC_DARKMASTER_GANDLING: m_uiDarkmasterGandlingGUID = pCreature->GetGUID(); break; + } +} + +void instance_scholomance::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) + { + case GO_GATE_KIRTONOS: m_uiGateKirtonosGUID = pGo->GetGUID(); break; + case GO_GATE_RAS: m_uiGateRasGUID = pGo->GetGUID(); break; + case GO_GATE_MALICIA: m_uiGateMiliciaGUID = pGo->GetGUID(); break; + case GO_GATE_THEOLEN: m_uiGateTheolenGUID = pGo->GetGUID(); break; + case GO_GATE_POLKELT: m_uiGatePolkeltGUID = pGo->GetGUID(); break; + case GO_GATE_RAVENIAN: m_uiGateRavenianGUID = pGo->GetGUID(); break; + case GO_GATE_BAROV: m_uiGateBarovGUID = pGo->GetGUID(); break; + case GO_GATE_ILLUCIA: m_uiGateIlluciaGUID = pGo->GetGUID(); break; + case GO_GATE_GANDLING: m_uiGateGandlingGUID = pGo->GetGUID(); break; + + case GO_VIEWING_ROOM_DOOR: + // In normal flow of the instance, this door is opened by a dropped key + if (m_auiEncounter[TYPE_RATTLEGORE] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + } +} + +void instance_scholomance::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) + { + case TYPE_KIRTONOS: + // This door is initially closed by DB-scripts, so only use it in case of FAIL, DONE, or on aggro after wipe + if (m_auiEncounter[uiType] != FAIL && uiData == IN_PROGRESS) + return; + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGateKirtonosGUID); + break; + case TYPE_RATTLEGORE: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_RAS_FROSTWHISPER: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGateRasGUID); + break; + case TYPE_MALICIA: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGateMiliciaGUID); + break; + case TYPE_THEOLEN: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGateTheolenGUID); + break; + case TYPE_POLKELT: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGatePolkeltGUID); + break; + case TYPE_RAVENIAN: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGateRavenianGUID); + break; + case TYPE_ALEXEI_BAROV: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGateBarovGUID); + break; + case TYPE_ILLUCIA_BAROV: + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiGateIlluciaGUID); + break; + case TYPE_GANDLING: + m_auiEncounter[uiType] = uiData; + // Close the door to main room, because the encounter will take place only in the main hall and random around all the 6 rooms + // The door to each of the room needs to be controlled by checking the summoned adds + DoUseDoorOrButton(m_uiGateGandlingGUID); + break; + } + + // Summon Gandling + if (uiData == DONE) + DoSpawnGandlingIfCan(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; + } +} + +void instance_scholomance::DoSpawnGandlingIfCan(bool bByPlayerEnter) { - instance_scholomance(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + // Summon only once + if (m_uiDarkmasterGandlingGUID) + return; - uint32 m_auiEncounter[MAX_ENCOUNTER]; + // Do not summon, if event finished + if (m_auiEncounter[TYPE_GANDLING] == DONE) + return; + + Player* pPlayer = GetPlayerInMap(); + if (!pPlayer) + return; + + // Check if all the six bosses are done first + if (m_auiEncounter[TYPE_MALICIA] == DONE && m_auiEncounter[TYPE_THEOLEN] == DONE && m_auiEncounter[TYPE_POLKELT] == DONE && + m_auiEncounter[TYPE_RAVENIAN] == DONE && m_auiEncounter[TYPE_ALEXEI_BAROV] == DONE && m_auiEncounter[TYPE_ILLUCIA_BAROV] == DONE) + { + if (Creature* pGandling = pPlayer->SummonCreature(NPC_DARKMASTER_GANDLING, m_aGandlingSpawnLocs[0].m_fX, m_aGandlingSpawnLocs[0].m_fY, m_aGandlingSpawnLocs[0].m_fZ, m_aGandlingSpawnLocs[0].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) + if (!bByPlayerEnter) + DoScriptText(SAY_GANDLING_SPAWN, pGandling); + } +} + +uint32 instance_scholomance::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; - uint64 m_uiGateKirtonosGUID; - uint64 m_uiGateGandlingGUID; - uint64 m_uiGateMiliciaGUID; - uint64 m_uiGateTheolenGUID; - uint64 m_uiGatePolkeltGUID; - uint64 m_uiGateRavenianGUID; - uint64 m_uiGateBarovGUID; - uint64 m_uiGateIlluciaGUID; + return 0; +} - void Initialize() +void instance_scholomance::Load(const char* chrIn) +{ + if (!chrIn) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiGateKirtonosGUID = 0; - m_uiGateGandlingGUID = 0; - m_uiGateMiliciaGUID = 0; - m_uiGateTheolenGUID = 0; - m_uiGatePolkeltGUID = 0; - m_uiGateRavenianGUID = 0; - m_uiGateBarovGUID = 0; - m_uiGateIlluciaGUID = 0; + OUT_LOAD_INST_DATA_FAIL; + return; } - void OnObjectCreate(GameObject* pGo) + 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; +} + +void instance_scholomance::OnCreatureEnterCombat(Creature* pCreature) +{ + switch (pCreature->GetEntry()) { - switch(pGo->GetEntry()) - { - case GO_GATE_KIRTONOS: m_uiGateKirtonosGUID = pGo->GetGUID(); break; - case GO_GATE_GANDLING: m_uiGateGandlingGUID = pGo->GetGUID(); break; - case GO_GATE_MALICIA: m_uiGateMiliciaGUID = pGo->GetGUID(); break; - case GO_GATE_THEOLEN: m_uiGateTheolenGUID = pGo->GetGUID(); break; - case GO_GATE_POLKELT: m_uiGatePolkeltGUID = pGo->GetGUID(); break; - case GO_GATE_RAVENIAN: m_uiGateRavenianGUID = pGo->GetGUID(); break; - case GO_GATE_BAROV: m_uiGateBarovGUID = pGo->GetGUID(); break; - case GO_GATE_ILLUCIA: m_uiGateIlluciaGUID = pGo->GetGUID(); break; - } + case NPC_KIRTONOS: SetData(TYPE_KIRTONOS, IN_PROGRESS); break; + case NPC_RATTLEGORE: SetData(TYPE_RATTLEGORE, IN_PROGRESS); break; + case NPC_RAS_FROSTWHISPER: SetData(TYPE_RAS_FROSTWHISPER, IN_PROGRESS); break; + case NPC_THEOLEN_KRASTINOV: SetData(TYPE_THEOLEN, IN_PROGRESS); break; + case NPC_LOREKEEPER_POLKELT: SetData(TYPE_POLKELT, IN_PROGRESS); break; + case NPC_RAVENIAN: SetData(TYPE_RAVENIAN, IN_PROGRESS); break; + case NPC_ILLUCIA_BAROV: SetData(TYPE_ILLUCIA_BAROV, IN_PROGRESS); break; + case NPC_ALEXEI_BAROV: SetData(TYPE_ALEXEI_BAROV, IN_PROGRESS); break; + case NPC_INSTRUCTOR_MALICIA: SetData(TYPE_MALICIA, IN_PROGRESS); break; + case NPC_DARKMASTER_GANDLING: SetData(TYPE_GANDLING, IN_PROGRESS); break; } +} - void SetData(uint32 uiType, uint32 uiData) +void instance_scholomance::OnCreatureEvade(Creature* pCreature) +{ + switch (pCreature->GetEntry()) { - switch(uiType) - { - case TYPE_GANDLING: - m_auiEncounter[0] = uiData; - break; - case TYPE_KIRTONOS: - m_auiEncounter[1] = uiData; - break; - case TYPE_ALEXEIBAROV: - m_auiEncounter[2] = uiData; - break; - case TYPE_THEOLEN: - m_auiEncounter[3] = uiData; - break; - case TYPE_RAVENIAN: - m_auiEncounter[4] = uiData; - break; - case TYPE_POLKELT: - m_auiEncounter[5] = uiData; - break; - case TYPE_MALICIA: - m_auiEncounter[6] = uiData; - break; - case TYPE_ILLUCIABAROV: - m_auiEncounter[7] = uiData; - break; - } + case NPC_KIRTONOS: SetData(TYPE_KIRTONOS, FAIL); break; + case NPC_RATTLEGORE: SetData(TYPE_RATTLEGORE, FAIL); break; + case NPC_RAS_FROSTWHISPER: SetData(TYPE_RAS_FROSTWHISPER, FAIL); break; + case NPC_THEOLEN_KRASTINOV: SetData(TYPE_THEOLEN, FAIL); break; + case NPC_LOREKEEPER_POLKELT: SetData(TYPE_POLKELT, FAIL); break; + case NPC_RAVENIAN: SetData(TYPE_RAVENIAN, FAIL); break; + case NPC_ILLUCIA_BAROV: SetData(TYPE_ILLUCIA_BAROV, FAIL); break; + case NPC_ALEXEI_BAROV: SetData(TYPE_ALEXEI_BAROV, FAIL); break; + case NPC_INSTRUCTOR_MALICIA: SetData(TYPE_MALICIA, FAIL); break; + case NPC_DARKMASTER_GANDLING: SetData(TYPE_GANDLING, FAIL); break; } +} - uint32 GetData(uint32 uiType) +void instance_scholomance::OnCreatureDeath(Creature* pCreature) +{ + switch (pCreature->GetEntry()) { - if (uiType == TYPE_GANDLING) - { - if (m_auiEncounter[2] == DONE && m_auiEncounter[3] == DONE && m_auiEncounter[4] == DONE && - m_auiEncounter[5] == DONE && m_auiEncounter[6] == DONE && m_auiEncounter[7] == DONE) - { - m_auiEncounter[0] = SPECIAL; - return SPECIAL; - } - } - - return 0; + case NPC_KIRTONOS: SetData(TYPE_KIRTONOS, DONE); break; + case NPC_RATTLEGORE: SetData(TYPE_RATTLEGORE, DONE); break; + case NPC_RAS_FROSTWHISPER: SetData(TYPE_RAS_FROSTWHISPER, DONE); break; + case NPC_THEOLEN_KRASTINOV: SetData(TYPE_THEOLEN, DONE); break; + case NPC_LOREKEEPER_POLKELT: SetData(TYPE_POLKELT, DONE); break; + case NPC_RAVENIAN: SetData(TYPE_RAVENIAN, DONE); break; + case NPC_ILLUCIA_BAROV: SetData(TYPE_ILLUCIA_BAROV, DONE); break; + case NPC_ALEXEI_BAROV: SetData(TYPE_ALEXEI_BAROV, DONE); break; + case NPC_INSTRUCTOR_MALICIA: SetData(TYPE_MALICIA, DONE); break; + case NPC_DARKMASTER_GANDLING: SetData(TYPE_GANDLING, DONE); break; } -}; +} InstanceData* GetInstanceData_instance_scholomance(Map* pMap) { @@ -122,9 +269,10 @@ InstanceData* GetInstanceData_instance_scholomance(Map* pMap) void AddSC_instance_scholomance() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_scholomance"; - newscript->GetInstanceData = &GetInstanceData_instance_scholomance; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_scholomance"; + pNewScript->GetInstanceData = &GetInstanceData_instance_scholomance; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/scholomance/scholomance.h b/scripts/eastern_kingdoms/scholomance/scholomance.h index 34e759bf5..a906500e2 100644 --- a/scripts/eastern_kingdoms/scholomance/scholomance.h +++ b/scripts/eastern_kingdoms/scholomance/scholomance.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,25 +7,93 @@ enum { - MAX_ENCOUNTER = 8, + MAX_ENCOUNTER = 10, + + TYPE_KIRTONOS = 0, + TYPE_RATTLEGORE = 1, + TYPE_RAS_FROSTWHISPER = 2, + TYPE_MALICIA = 3, + TYPE_THEOLEN = 4, + TYPE_POLKELT = 5, + TYPE_RAVENIAN = 6, + TYPE_ALEXEI_BAROV = 7, + TYPE_ILLUCIA_BAROV = 8, + TYPE_GANDLING = 9, + + NPC_KIRTONOS = 10506, + NPC_RATTLEGORE = 11622, + NPC_RAS_FROSTWHISPER = 10508, + NPC_THEOLEN_KRASTINOV = 11261, + NPC_LOREKEEPER_POLKELT = 10901, + NPC_RAVENIAN = 10507, + NPC_ILLUCIA_BAROV = 10502, + NPC_ALEXEI_BAROV = 10504, + NPC_INSTRUCTOR_MALICIA = 10505, + NPC_DARKMASTER_GANDLING = 1853, GO_GATE_KIRTONOS = 175570, - GO_GATE_GANDLING = 177374, + GO_VIEWING_ROOM_DOOR = 175167, // Must be opened in reload case + GO_GATE_RAS = 177370, GO_GATE_MALICIA = 177375, GO_GATE_THEOLEN = 177377, GO_GATE_POLKELT = 177376, GO_GATE_RAVENIAN = 177372, GO_GATE_BAROV = 177373, GO_GATE_ILLUCIA = 177371, + GO_GATE_GANDLING = 177374, - TYPE_GANDLING = 1, - TYPE_THEOLEN = 2, - TYPE_MALICIA = 3, - TYPE_ILLUCIABAROV = 4, - TYPE_ALEXEIBAROV = 5, - TYPE_POLKELT = 6, - TYPE_RAVENIAN = 7, - TYPE_KIRTONOS = 8 + SAY_GANDLING_SPAWN = -1289000, +}; + +struct sSpawnLocation +{ + float m_fX, m_fY, m_fZ, m_fO; +}; + +static const sSpawnLocation m_aGandlingSpawnLocs[1] = +{ + {180.73f, -9.43856f, 75.507f, 1.61399f} +}; + +class MANGOS_DLL_DECL instance_scholomance : public ScriptedInstance +{ + public: + instance_scholomance(Map* pMap); + ~instance_scholomance() {} + + void Initialize(); + + void OnCreatureEnterCombat(Creature* pCreature); + void OnCreatureEvade(Creature* pCreature); + void OnCreatureDeath(Creature* pCreature); + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + void OnPlayerEnter(Player* pPlayer); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + private: + void DoSpawnGandlingIfCan(bool bByPlayerEnter); + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiDarkmasterGandlingGUID; + + uint64 m_uiGateKirtonosGUID; + uint64 m_uiGateRasGUID; + uint64 m_uiGateMiliciaGUID; + uint64 m_uiGateTheolenGUID; + uint64 m_uiGatePolkeltGUID; + uint64 m_uiGateRavenianGUID; + uint64 m_uiGateBarovGUID; + uint64 m_uiGateIlluciaGUID; + uint64 m_uiGateGandlingGUID; }; #endif diff --git a/scripts/eastern_kingdoms/searing_gorge.cpp b/scripts/eastern_kingdoms/searing_gorge.cpp index 8e0c3aa14..b8c622fe8 100644 --- a/scripts/eastern_kingdoms/searing_gorge.cpp +++ b/scripts/eastern_kingdoms/searing_gorge.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/shadowfang_keep/boss_hummel.cpp b/scripts/eastern_kingdoms/shadowfang_keep/boss_hummel.cpp new file mode 100644 index 000000000..957efaa13 --- /dev/null +++ b/scripts/eastern_kingdoms/shadowfang_keep/boss_hummel.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_hummel +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Shadowfang Keep +EndScriptData */ + +#include "precompiled.h" + +void AddSC_boss_hummel() +{ +} diff --git a/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp b/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp index 440efa0b5..b9271eb33 100644 --- a/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp +++ b/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -87,8 +87,8 @@ struct MANGOS_DLL_DECL instance_shadowfang_keep : public ScriptedInstance case NPC_ASH: m_uiAshGUID = pCreature->GetGUID(); break; case NPC_ADA: m_uiAdaGUID = pCreature->GetGUID(); break; case NPC_FENRUS: m_uiFenrusGUID = pCreature->GetGUID(); break; - case NPC_VINCENT: - m_uiVincentGUID = pCreature->GetGUID(); + case NPC_VINCENT: + m_uiVincentGUID = pCreature->GetGUID(); //if Arugal has done the intro, make Vincent dead! if (m_auiEncounter[4] == DONE) pCreature->SetStandState(UNIT_STAND_STATE_DEAD); @@ -232,7 +232,7 @@ struct MANGOS_DLL_DECL instance_shadowfang_keep : public ScriptedInstance OUT_LOAD_INST_DATA(chrIn); std::istringstream loadStream(chrIn); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] + 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) diff --git a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp index 3300cb325..2cb667652 100644 --- a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp +++ b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -122,7 +122,7 @@ struct MANGOS_DLL_DECL npc_shadowfang_prisonerAI : public npc_escortAI void Reset() {} - //let's prevent Adamant from charging into Ashcrombe's cell + //let's prevent Adamant from charging into Ashcrombe's cell //and beating the crap out of him and vice versa XD void AttackStart(Unit* pWho) { @@ -203,7 +203,7 @@ enum struct MANGOS_DLL_DECL mob_arugal_voidwalkerAI : public ScriptedAI { - mob_arugal_voidwalkerAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_arugal_voidwalkerAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); m_bIsLeader = false; @@ -343,7 +343,7 @@ struct MANGOS_DLL_DECL mob_arugal_voidwalkerAI : public ScriptedAI m_bIsLeader = true; else pLeader ? m_uiLeaderGUID = pLeader->GetGUID() : m_uiLeaderGUID = 0; - + Reset(); } @@ -429,13 +429,13 @@ static const SpawnPoint VWSpawns[]= {-140.203f, 2175.263f, 128.448f, 0.373f}, }; -//roughly the height of Fenrus' room, +//roughly the height of Fenrus' room, //used to tell how he should behave const float HEIGHT_FENRUS_ROOM = 140.0f; struct MANGOS_DLL_DECL boss_arugalAI : public ScriptedAI { - boss_arugalAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_arugalAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); @@ -474,7 +474,7 @@ struct MANGOS_DLL_DECL boss_arugalAI : public ScriptedAI DoCastSpellIfCan(pWho, SPELL_VOID_BOLT); } - void KilledUnit(Unit* pVictim) + void KilledUnit(Unit* pVictim) { if (pVictim->GetTypeId() == TYPEID_PLAYER) DoScriptText(YELL_KILLED_PLAYER, m_creature); @@ -659,14 +659,14 @@ struct MANGOS_DLL_DECL boss_arugalAI : public ScriptedAI DoMeleeAttackIfReady(); } - void AttackStart(Unit* pWho) + void AttackStart(Unit* pWho) { if (!m_bEventMode) ScriptedAI::AttackStart(pWho); } //make the code nice and pleasing to the eye - inline float GetManaPercent() + inline float GetManaPercent() { return (((float)m_creature->GetPower(POWER_MANA) / (float)m_creature->GetMaxPower(POWER_MANA)) * 100); } @@ -725,7 +725,7 @@ enum struct MANGOS_DLL_DECL npc_arugalAI : public ScriptedAI { - npc_arugalAI(Creature* pCreature) : ScriptedAI(pCreature) + npc_arugalAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); @@ -741,7 +741,7 @@ struct MANGOS_DLL_DECL npc_arugalAI : public ScriptedAI m_uiSpeechStep = 0; m_creature->SetVisibility(VISIBILITY_OFF); - + if (m_pInstance && m_pInstance->GetData(TYPE_INTRO) == NOT_STARTED) m_uiSpeechStep = 1; } @@ -842,7 +842,7 @@ enum struct MANGOS_DLL_DECL npc_deathstalker_vincentAI : public ScriptedAI { - npc_deathstalker_vincentAI(Creature* pCreature) : ScriptedAI(pCreature) + npc_deathstalker_vincentAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); @@ -856,7 +856,7 @@ struct MANGOS_DLL_DECL npc_deathstalker_vincentAI : public ScriptedAI m_creature->SetStandState(UNIT_STAND_STATE_DEAD); } - void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) { if (pDoneBy) { @@ -880,7 +880,7 @@ struct MANGOS_DLL_DECL npc_deathstalker_vincentAI : public ScriptedAI { if (m_creature->isInCombat() && m_creature->getFaction() == FACTION_FRIENDLY) EnterEvadeMode(); - + ScriptedAI::UpdateAI(uiDiff); } diff --git a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h index ed8c45c6d..1a7a2b26d 100644 --- a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h +++ b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/eastern_kingdoms/silvermoon_city.cpp b/scripts/eastern_kingdoms/silvermoon_city.cpp index 03b2e3bee..4c7d98de4 100644 --- a/scripts/eastern_kingdoms/silvermoon_city.cpp +++ b/scripts/eastern_kingdoms/silvermoon_city.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -36,6 +36,7 @@ EndContentData */ #define QUEST_REDEEMING_THE_DEAD 9685 #define SPELL_SHIMMERING_VESSEL 31225 #define SPELL_REVIVE_SELF 32343 +#define NPC_BLOOD_KNIGHT_STILLBLADE 17768 struct MANGOS_DLL_DECL npc_blood_knight_stillbladeAI : public ScriptedAI { @@ -70,7 +71,8 @@ struct MANGOS_DLL_DECL npc_blood_knight_stillbladeAI : public ScriptedAI if ((Spellkind->Id == SPELL_SHIMMERING_VESSEL) && !spellHit && (Hitter->GetTypeId() == TYPEID_PLAYER) && (((Player*)Hitter)->IsActiveQuest(QUEST_REDEEMING_THE_DEAD))) { - ((Player*)Hitter)->AreaExploredOrEventHappens(QUEST_REDEEMING_THE_DEAD); + //((Player*)Hitter)->AreaExploredOrEventHappens(QUEST_REDEEMING_THE_DEAD); + ((Player*)Hitter)->KilledMonsterCredit(NPC_BLOOD_KNIGHT_STILLBLADE); DoCastSpellIfCan(m_creature,SPELL_REVIVE_SELF); m_creature->SetStandState(UNIT_STAND_STATE_STAND); m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); diff --git a/scripts/eastern_kingdoms/silverpine_forest.cpp b/scripts/eastern_kingdoms/silverpine_forest.cpp index 39e8fb38a..636a8b247 100644 --- a/scripts/eastern_kingdoms/silverpine_forest.cpp +++ b/scripts/eastern_kingdoms/silverpine_forest.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,12 +17,11 @@ /* ScriptData SDName: Silverpine_Forest SD%Complete: 100 -SDComment: Quest support: 435, 452, 1886 +SDComment: Quest support: 435, 452 SDCategory: Silverpine Forest EndScriptData */ /* ContentData -npc_astor_hadren npc_deathstalker_erland npc_deathstalker_faerleia EndContentData */ @@ -30,57 +29,6 @@ EndContentData */ #include "precompiled.h" #include "escort_ai.h" -/*###### -## npc_astor_hadren -######*/ - -struct MANGOS_DLL_DECL npc_astor_hadrenAI : public ScriptedAI -{ - npc_astor_hadrenAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - void Reset() - { - m_creature->setFaction(68); - } - - void JustDied(Unit *who) - { - m_creature->setFaction(68); - } -}; - -CreatureAI* GetAI_npc_astor_hadren(Creature *_creature) -{ - return new npc_astor_hadrenAI(_creature); -} - -bool GossipHello_npc_astor_hadren(Player* pPlayer, Creature* pCreature) -{ - if (pPlayer->GetQuestStatus(1886) == QUEST_STATUS_INCOMPLETE) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "You're Astor Hadren, right?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - pPlayer->SEND_GOSSIP_MENU(623, pCreature->GetGUID()); - - return true; -} - -bool GossipSelect_npc_astor_hadren(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) -{ - switch(uiAction) - { - case GOSSIP_ACTION_INFO_DEF + 1: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "You've got something I need, Astor. And I'll be taking it now.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - pPlayer->SEND_GOSSIP_MENU(624, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - pPlayer->CLOSE_GOSSIP_MENU(); - pCreature->setFaction(21); - pCreature->AI()->AttackStart(pPlayer); - break; - } - return true; -} - /*##### ## npc_deathstalker_erland #####*/ @@ -394,22 +342,15 @@ void AddSC_silverpine_forest() { Script* newscript; - newscript = new Script; - newscript->Name = "npc_astor_hadren"; - newscript->pGossipHello = &GossipHello_npc_astor_hadren; - newscript->pGossipSelect = &GossipSelect_npc_astor_hadren; - newscript->GetAI = &GetAI_npc_astor_hadren; - newscript->RegisterSelf(); - newscript = new Script; newscript->Name = "npc_deathstalker_erland"; newscript->GetAI = &GetAI_npc_deathstalker_erland; - newscript->pQuestAccept = &QuestAccept_npc_deathstalker_erland; + newscript->pQuestAcceptNPC = &QuestAccept_npc_deathstalker_erland; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_deathstalker_faerleia"; newscript->GetAI = &GetAI_npc_deathstalker_faerleia; - newscript->pQuestAccept = &QuestAccept_npc_deathstalker_faerleia; + newscript->pQuestAcceptNPC = &QuestAccept_npc_deathstalker_faerleia; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/stormwind_city.cpp b/scripts/eastern_kingdoms/stormwind_city.cpp index c65a78d75..879a02dd6 100644 --- a/scripts/eastern_kingdoms/stormwind_city.cpp +++ b/scripts/eastern_kingdoms/stormwind_city.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -251,13 +251,13 @@ void AddSC_stormwind_city() newscript = new Script; newscript->Name = "npc_bartleby"; newscript->GetAI = &GetAI_npc_bartleby; - newscript->pQuestAccept = &QuestAccept_npc_bartleby; + newscript->pQuestAcceptNPC = &QuestAccept_npc_bartleby; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_dashel_stonefist"; newscript->GetAI = &GetAI_npc_dashel_stonefist; - newscript->pQuestAccept = &QuestAccept_npc_dashel_stonefist; + newscript->pQuestAcceptNPC = &QuestAccept_npc_dashel_stonefist; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/eastern_kingdoms/stranglethorn_vale.cpp b/scripts/eastern_kingdoms/stranglethorn_vale.cpp index bcc31573b..b0b2b6e9d 100644 --- a/scripts/eastern_kingdoms/stranglethorn_vale.cpp +++ b/scripts/eastern_kingdoms/stranglethorn_vale.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,15 +17,25 @@ /* ScriptData SDName: Stranglethorn_Vale SD%Complete: 100 -SDComment: Quest support: 592 +SDComment: Quest support: 592, 8193 SDCategory: Stranglethorn Vale EndScriptData */ /* ContentData mob_yenniku +npc_riggle_bassbait EndContentData */ #include "precompiled.h" +#include "GameEventMgr.h" + +enum +{ + SAY_START = -1510356, + SAY_WINNER = -1510357, + SAY_END = -1510358, + QUEST_MASTER_ANGLER = 8193, +}; /*###### ## mob_yenniku @@ -45,7 +55,7 @@ struct MANGOS_DLL_DECL mob_yennikuAI : public ScriptedAI void Reset() { Reset_Timer = 0; - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + m_creature->HandleEmote(EMOTE_STATE_NONE); } void SpellHit(Unit *caster, const SpellEntry *spell) @@ -55,7 +65,7 @@ struct MANGOS_DLL_DECL mob_yennikuAI : public ScriptedAI //Yenniku's Release if (!bReset && ((Player*)caster)->GetQuestStatus(592) == QUEST_STATUS_INCOMPLETE && spell->Id == 3607) { - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); + m_creature->HandleEmote(EMOTE_STATE_STUN); m_creature->CombatStop(); //stop combat m_creature->DeleteThreatList(); //unsure of this m_creature->setFaction(83); //horde generic @@ -81,7 +91,7 @@ struct MANGOS_DLL_DECL mob_yennikuAI : public ScriptedAI else Reset_Timer -= diff; //Return since we have no target - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() ) + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; DoMeleeAttackIfReady(); @@ -93,8 +103,110 @@ CreatureAI* GetAI_mob_yenniku(Creature *_Creature) } /*###### -## +##npc_riggle_bassbait ######*/ +/** + * AI for Riggle Bassbait. + * This is the AI for Riggle Bassbait, see http://www.wowhead.com/?npc=15077 + * @see ScriptedAI + * @author burned, gotisch + */ +struct MANGOS_DLL_DECL npc_riggle_bassbaitAI : public ScriptedAI +{ + /** + * Constructor of the Creature. + * This is called when the creature is spawned. + * @param c The Creature that this AI is for + */ + npc_riggle_bassbaitAI(Creature *c) : ScriptedAI(c) + { + // This will keep the NPC active even if there are no players around! + c->SetActiveObjectState(true); + bEventAnnounced = bEventIsOver = bEventWinnerFound = false; + Reset(); + } + /** + * Flag to check if event was announced. True if event was announced. + */ + bool bEventAnnounced; + /** + * Flag to check if event is over. True if event is over. + */ + bool bEventIsOver; + /** + * Flag to check if someone won the event. True if someone has won. + */ + bool bEventWinnerFound; + + void Reset() { } + + void Aggro(Unit *who) {} + + void UpdateAI(const uint32 diff) + { + // Announce the event max 1 minute after being spawned. But only if Fishing extravaganza is running. + if (!bEventAnnounced && time(NULL) % 60 == 0 && IsHolidayActive(HOLIDAY_FISHING_EXTRAVAGANZA)) + { + debug_log("SD2: npc_riggle_bassbait announce HOLIDAY_FISHING_EXTRAVAGANZA contest"); + DoScriptText(SAY_START, m_creature); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); //Quest&Gossip are now active + bEventAnnounced = true; + } + // The Event was started (announced) & It was not yet ended & One minute passed & the Fish are gone + if ( bEventAnnounced && !bEventIsOver && time(NULL) % 60 == 0 && !IsHolidayActive(HOLIDAY_FISHING_EXTRAVAGANZA)) + { + debug_log("SD2: npc_riggle_bassbait end HOLIDAY_FISHING_EXTRAVAGANZA contest"); + DoScriptText(SAY_END, m_creature); + bEventIsOver = true; + } + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; +/** + * GossipHello for NPC Riggle Bassbait. + * This is called each time a Player tries to talk with the NPC. + */ +bool GossipHello_npc_riggle_bassbait(Player* pPlayer, Creature* pCreature) +{ + if (pCreature->isQuestGiver()) // If the quest is still running. + { + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + pPlayer->SEND_GOSSIP_MENU(7614, pCreature->GetGUID()); + return true; + } + // The Quest is not there anymore + // There is a winner! + pPlayer->SEND_GOSSIP_MENU(7714, pCreature->GetGUID()); + return true; +} + +bool ChooseReward_npc_riggle_bassbait(Player* pPlayer, Creature* pCreature, const Quest* pQuest) +{ + // TODO: check if this can only be called if NPC has QUESTGIVER flag. + if (pQuest->GetQuestId() == QUEST_MASTER_ANGLER && ((npc_riggle_bassbaitAI*)(pCreature->AI()))->bEventWinnerFound == false) + { + DoScriptText(SAY_WINNER, pCreature,pPlayer); + pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + ((npc_riggle_bassbaitAI*)(pCreature->AI()))->bEventWinnerFound = true; + Creature* creature2 = GetClosestCreatureWithEntry(pCreature,15087,60.0f); + if (creature2) + { + creature2->SetFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_QUESTGIVER); + } else { + debug_log("Could not change flag of Jang"); + } + return true; + } + return true; +} + +CreatureAI* GetAI_npc_riggle_bassbait(Creature* pCreature) +{ + return new npc_riggle_bassbaitAI(pCreature); +} void AddSC_stranglethorn_vale() { @@ -104,4 +216,11 @@ void AddSC_stranglethorn_vale() newscript->Name = "mob_yenniku"; newscript->GetAI = &GetAI_mob_yenniku; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_riggle_bassbait"; + newscript->GetAI = &GetAI_npc_riggle_bassbait; + newscript->pGossipHello = &GossipHello_npc_riggle_bassbait; + newscript->pQuestRewardedNPC = &ChooseReward_npc_riggle_bassbait; + newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp b/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp index 9762e5dc4..f326da4e7 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,56 +24,21 @@ EndScriptData */ #include "precompiled.h" #include "stratholme.h" -#define SAY_0 "Intruders! More pawns of the Argent Dawn, no doubt. I already count one of their number among my prisoners. Withdraw from my domain before she is executed!" -#define SAY_1 "You're still here? Your foolishness is amusing! The Argent Dawn wench needn't suffer in vain. Leave at once and she shall be spared!" -#define SAY_2 "I shall take great pleasure in taking this poor wretch's life! It's not too late, she needn't suffer in vain. Turn back and her death shall be merciful!" -#define SAY_3 "May this prisoner's death serve as a warning. None shall defy the Scourge and live!" -#define SAY_4 "So you see fit to toy with the Lich King's creations? Ramstein, be sure to give the intruders a proper greeting." -#define SAY_5 "Time to take matters into my own hands. Come. Enter my domain and challenge the might of the Scourge!" - -#define ADD_1X 4017.403809f -#define ADD_1Y -3339.703369f -#define ADD_1Z 115.057655f -#define ADD_1O 5.487860f - -#define ADD_2X 4013.189209f -#define ADD_2Y -3351.808350f -#define ADD_2Z 115.052254f -#define ADD_2O 0.134280f - -#define ADD_3X 4017.738037f -#define ADD_3Y -3363.478016f -#define ADD_3Z 115.057274f -#define ADD_3O 0.723313f - -#define ADD_4X 4048.877197f -#define ADD_4Y -3363.223633f -#define ADD_4Z 115.054253f -#define ADD_4O 3.627735f - -#define ADD_5X 4051.777588f -#define ADD_5Y -3350.893311f -#define ADD_5Z 115.055351f -#define ADD_5O 3.066176f - -#define ADD_6X 4048.375977f -#define ADD_6Y -3339.966309f -#define ADD_6Z 115.055222f -#define ADD_6O 2.457497f - -#define SPELL_SHADOWBOLT 17393 -#define SPELL_CLEAVE 15284 -#define SPELL_MORTALSTRIKE 15708 - -#define SPELL_UNHOLY_AURA 17467 -#define SPELL_RAISEDEAD 17473 //triggers death pact (17471) - -#define SPELL_RAISE_DEAD1 17475 -#define SPELL_RAISE_DEAD2 17476 -#define SPELL_RAISE_DEAD3 17477 -#define SPELL_RAISE_DEAD4 17478 -#define SPELL_RAISE_DEAD5 17479 -#define SPELL_RAISE_DEAD6 17480 +enum +{ + SPELL_SHADOW_BOLT = 17393, + SPELL_CLEAVE = 15284, + SPELL_MORTAL_STRIKE = 15708, + + SPELL_RAISE_DEAD = 17473, //triggers death pact (17471) + + SPELL_RAISE_DEAD_1 = 17475, + SPELL_RAISE_DEAD_2 = 17476, + SPELL_RAISE_DEAD_3 = 17477, + SPELL_RAISE_DEAD_4 = 17478, + SPELL_RAISE_DEAD_5 = 17479, + SPELL_RAISE_DEAD_6 = 17480 +}; struct MANGOS_DLL_DECL boss_baron_rivendareAI : public ScriptedAI { @@ -85,86 +50,81 @@ struct MANGOS_DLL_DECL boss_baron_rivendareAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 ShadowBolt_Timer; - uint32 Cleave_Timer; - uint32 MortalStrike_Timer; - //uint32 RaiseDead_Timer; - uint32 SummonSkeletons_Timer; - Creature *Summoned; + uint32 m_uiShadowBoltTimer; + uint32 m_uiCleaveTimer; + uint32 m_uiMortalStrikeTimer; + uint32 m_uiRaiseDeadTimer; void Reset() { - ShadowBolt_Timer = 5000; - Cleave_Timer = 8000; - MortalStrike_Timer = 12000; - //RaiseDead_Timer = 30000; - SummonSkeletons_Timer = 34000; - } - - void Aggro(Unit *who) - { - if (m_pInstance) - m_pInstance->SetData(TYPE_BARON,IN_PROGRESS); + m_uiShadowBoltTimer = 5000; + m_uiCleaveTimer = 8000; + m_uiMortalStrikeTimer = 12000; + m_uiRaiseDeadTimer = 30000; } - void JustSummoned(Creature* summoned) + void JustSummoned(Creature* pSummoned) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - summoned->AI()->AttackStart(target); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); } - void JustDied(Unit* Killer) + void SpellHit(Unit* pWho, const SpellEntry* pSpell) { - if (m_pInstance) - m_pInstance->SetData(TYPE_BARON,DONE); + if (pSpell->Id == SPELL_RAISE_DEAD) + { + DoCastSpellIfCan(m_creature, SPELL_RAISE_DEAD_1, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_RAISE_DEAD_2, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_RAISE_DEAD_3, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_RAISE_DEAD_4, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_RAISE_DEAD_5, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_RAISE_DEAD_6, CAST_TRIGGERED); + } } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ShadowBolt - if (ShadowBolt_Timer < diff) + // ShadowBolt + if (m_uiShadowBoltTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SHADOWBOLT); - ShadowBolt_Timer = 10000; - }else ShadowBolt_Timer -= diff; - - //Cleave - if (Cleave_Timer < diff) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_BOLT) == CAST_OK) + m_uiShadowBoltTimer = 10000; + } + } + else + m_uiShadowBoltTimer -= uiDiff; + + // Cleave + if (m_uiCleaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE); - Cleave_Timer = urand(7000, 17000); - }else Cleave_Timer -= diff; - - //MortalStrike - if (MortalStrike_Timer < diff) + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) + m_uiCleaveTimer = urand(7000, 17000); + } + else + m_uiCleaveTimer -= uiDiff; + + // MortalStrike + if (m_uiMortalStrikeTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_MORTALSTRIKE); - MortalStrike_Timer = urand(10000, 25000); - }else MortalStrike_Timer -= diff; - - //RaiseDead - //if (RaiseDead_Timer < diff) - //{ - // DoCastSpellIfCan(m_creature,SPELL_RAISEDEAD); - // RaiseDead_Timer = 45000; - //}else RaiseDead_Timer -= diff; - - //SummonSkeletons - if (SummonSkeletons_Timer < diff) + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MORTAL_STRIKE) == CAST_OK) + m_uiMortalStrikeTimer = urand(10000, 25000); + } + else + m_uiMortalStrikeTimer -= uiDiff; + + // RaiseDead + if (m_uiRaiseDeadTimer < uiDiff) { - m_creature->SummonCreature(11197,ADD_1X,ADD_1Y,ADD_1Z,ADD_1O,TEMPSUMMON_TIMED_DESPAWN,29000); - m_creature->SummonCreature(11197,ADD_2X,ADD_2Y,ADD_2Z,ADD_2O,TEMPSUMMON_TIMED_DESPAWN,29000); - m_creature->SummonCreature(11197,ADD_3X,ADD_3Y,ADD_3Z,ADD_3O,TEMPSUMMON_TIMED_DESPAWN,29000); - m_creature->SummonCreature(11197,ADD_4X,ADD_4Y,ADD_4Z,ADD_4O,TEMPSUMMON_TIMED_DESPAWN,29000); - m_creature->SummonCreature(11197,ADD_5X,ADD_5Y,ADD_5Z,ADD_5O,TEMPSUMMON_TIMED_DESPAWN,29000); - m_creature->SummonCreature(11197,ADD_6X,ADD_6Y,ADD_6Z,ADD_6O,TEMPSUMMON_TIMED_DESPAWN,29000); - - SummonSkeletons_Timer = 40000; - }else SummonSkeletons_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_RAISE_DEAD) == CAST_OK) + m_uiRaiseDeadTimer = 45000; + } + else + m_uiRaiseDeadTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -177,9 +137,10 @@ CreatureAI* GetAI_boss_baron_rivendare(Creature* pCreature) void AddSC_boss_baron_rivendare() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_baron_rivendare"; - newscript->GetAI = &GetAI_boss_baron_rivendare; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_baron_rivendare"; + pNewScript->GetAI = &GetAI_boss_baron_rivendare; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp b/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp index c0590a94b..a94739f9d 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -52,12 +52,6 @@ struct MANGOS_DLL_DECL boss_baroness_anastariAI : public ScriptedAI //Possess_Timer = 35000; } - void JustDied(Unit* Killer) - { - if (m_pInstance) - m_pInstance->SetData(TYPE_BARONESS, DONE); - } - void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) diff --git a/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp b/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp index 6852a7d15..91bdc8615 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp b/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp index a09c55da7..8e12d5262 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -25,6 +25,10 @@ EndScriptData */ enum { + SAY_AGGRO = -1329016, + SAY_TRANSFORM = -1329017, + SAY_DEATH = -1329018, + //Dathrohan spells SPELL_CRUSADERSHAMMER = 17286, //AOE stun SPELL_CRUSADERSTRIKE = 17281, @@ -42,25 +46,31 @@ enum NPC_DATHROHAN = 10812, NPC_BALNAZZAR = 10813, - NPC_ZOMBIE = 10698 //probably incorrect + NPC_SKELETAL_GUARDIAN = 10390, + NPC_SKELETAL_BERSERKER = 10391 }; struct SummonDef { + uint32 m_uiEntry; float m_fX, m_fY, m_fZ, m_fOrient; }; SummonDef m_aSummonPoint[]= { - {3444.156f, -3090.626f, 135.002f, 2.240f}, //G1 front, left - {3449.123f, -3087.009f, 135.002f, 2.240f}, //G1 front, right - {3446.246f, -3093.466f, 135.002f, 2.240f}, //G1 back left - {3451.160f, -3089.904f, 135.002f, 2.240f}, //G1 back, right - - {3457.995f, -3080.916f, 135.002f, 3.784f}, //G2 front, left - {3454.302f, -3076.330f, 135.002f, 3.784f}, //G2 front, right - {3460.975f, -3078.901f, 135.002f, 3.784f}, //G2 back left - {3457.338f, -3073.979f, 135.002f, 3.784f} //G2 back, right + {NPC_SKELETAL_BERSERKER, 3460.356f, -3070.572f, 135.086f, 0.332f}, + {NPC_SKELETAL_BERSERKER, 3465.289f, -3069.987f, 135.086f, 5.480f}, + {NPC_SKELETAL_BERSERKER, 3463.616f, -3074.912f, 135.086f, 5.009f}, + + {NPC_SKELETAL_GUARDIAN, 3460.012f, -3076.041f, 135.086f, 1.187f}, + {NPC_SKELETAL_GUARDIAN, 3467.909f, -3076.401f, 135.086f, 3.770f}, + + {NPC_SKELETAL_BERSERKER, 3509.269f, -3066.474f, 135.080f, 4.817f}, + {NPC_SKELETAL_BERSERKER, 3510.966f, -3069.011f, 135.080f, 3.491f}, + + {NPC_SKELETAL_GUARDIAN, 3516.042f, -3066.873f, 135.080f, 3.997f}, + {NPC_SKELETAL_GUARDIAN, 3513.561f, -3063.027f, 135.080f, 2.356f}, + {NPC_SKELETAL_GUARDIAN, 3518.825f, -3060.926f, 135.080f, 3.944f} }; struct MANGOS_DLL_DECL boss_dathrohan_balnazzarAI : public ScriptedAI @@ -94,12 +104,19 @@ struct MANGOS_DLL_DECL boss_dathrohan_balnazzarAI : public ScriptedAI } + void Aggro(Unit* pWho) + { + DoScriptText(SAY_AGGRO, m_creature); + } + void JustDied(Unit* Victim) { + DoScriptText(SAY_DEATH, m_creature); + static uint32 uiCount = sizeof(m_aSummonPoint)/sizeof(SummonDef); - for (uint8 i=0; iSummonCreature(NPC_ZOMBIE, + for (uint32 i = 0; i < uiCount; ++i) + m_creature->SummonCreature(m_aSummonPoint[i].m_uiEntry, m_aSummonPoint[i].m_fX, m_aSummonPoint[i].m_fY, m_aSummonPoint[i].m_fZ, m_aSummonPoint[i].m_fOrient, TEMPSUMMON_TIMED_DESPAWN, HOUR*IN_MILLISECONDS); } @@ -143,13 +160,13 @@ struct MANGOS_DLL_DECL boss_dathrohan_balnazzarAI : public ScriptedAI //BalnazzarTransform if (m_creature->GetHealthPercent() < 40.0f) { - if (m_creature->IsNonMeleeSpellCasted(false)) - m_creature->InterruptNonMeleeSpells(false); - //restore hp, mana and stun - DoCastSpellIfCan(m_creature,SPELL_BALNAZZARTRANSFORM); - m_creature->UpdateEntry(NPC_BALNAZZAR); - m_bTransformed = true; + if (DoCastSpellIfCan(m_creature, SPELL_BALNAZZARTRANSFORM) == CAST_OK) + { + m_creature->UpdateEntry(NPC_BALNAZZAR); + DoScriptText(SAY_TRANSFORM, m_creature); + m_bTransformed = true; + } } } else diff --git a/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp b/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp index d121bd9dc..d22b368fb 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp b/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp index 171a64286..d67a02757 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -52,12 +52,6 @@ struct MANGOS_DLL_DECL boss_maleki_the_pallidAI : public ScriptedAI DrainLife_Timer = 31000; } - void JustDied(Unit* Killer) - { - if (m_pInstance) - m_pInstance->SetData(TYPE_PALLID, DONE); - } - void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) diff --git a/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp b/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp index 60a39e0a6..6b2dfe750 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -78,12 +78,6 @@ struct MANGOS_DLL_DECL boss_nerubenkanAI : public ScriptedAI Summoned->AI()->AttackStart(victim); } - void JustDied(Unit* Killer) - { - if (m_pInstance) - m_pInstance->SetData(TYPE_NERUB, DONE); - } - void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) diff --git a/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp b/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp index b91856046..e7a59e355 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -105,7 +105,7 @@ struct MANGOS_DLL_DECL boss_silver_hand_bossesAI : public ScriptedAI break; } if (m_pInstance->GetData(TYPE_SH_QUEST) && Killer->GetTypeId() == TYPEID_PLAYER) - ((Player*)Killer)->KilledMonsterCredit(SH_QUEST_CREDIT,m_creature->GetGUID()); + ((Player*)Killer)->KilledMonsterCredit(SH_QUEST_CREDIT, m_creature->GetObjectGuid()); } } diff --git a/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp b/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp index 79364af44..8d87ea9ec 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp b/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp index 450b70846..15b65883a 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -27,8 +27,6 @@ EndScriptData */ #define SPELL_TRAMPLE 5568 #define SPELL_KNOCKOUT 17307 -#define C_MINDLESS_UNDEAD 11030 - struct MANGOS_DLL_DECL boss_ramstein_the_gorgerAI : public ScriptedAI { boss_ramstein_the_gorgerAI(Creature* pCreature) : ScriptedAI(pCreature) @@ -48,15 +46,6 @@ struct MANGOS_DLL_DECL boss_ramstein_the_gorgerAI : public ScriptedAI Knockout_Timer = 12000; } - void JustDied(Unit* Killer) - { - for(uint8 i = 0; i < 30; ++i) - m_creature->SummonCreature(C_MINDLESS_UNDEAD, 3969.35f, -3391.87f, 119.11f, 5.91f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,1800000); - - if (m_pInstance) - m_pInstance->SetData(TYPE_RAMSTEIN,DONE); - } - void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) diff --git a/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp b/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp index 25e63df53..e2d617dd8 100644 --- a/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp +++ b/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp b/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp index 60101f4e6..d52e1ee1e 100644 --- a/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp +++ b/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Instance_Stratholme -SD%Complete: 50 -SDComment: In progress. Undead side 80% implemented, wipe support for doors at slaughterhouse needed, event needs better implementation +SD%Complete: 70 +SDComment: Undead side 90% implemented, event needs better implementation, Barthildas relocation for reload case is missing, Baron Combat handling is buggy. SDCategory: Stratholme EndScriptData */ @@ -26,15 +26,21 @@ EndScriptData */ instance_stratholme::instance_stratholme(Map* pMap) : ScriptedInstance(pMap), m_uiBaronRunTimer(0), + m_uiBarthilasRunTimer(0), + m_uiMindlessSummonTimer(0), m_uiSlaugtherSquareTimer(0), + m_uiYellCounter(0), + m_uiMindlessCount(0), m_uiServiceEntranceGUID(0), m_uiGauntletGate1GUID(0), m_uiPortGauntletGUID(0), m_uiPortSlaugtherGUID(0), m_uiPortElderGUID(0), + m_uiPortSlaughterGateGUID(0), m_auiRamsteinDoorGUID(0), m_auiRivendareDoorGUID(0), + m_uiYsidaCageGUID(0), m_uiBaronGUID(0), m_uiYsidaTriggerGUID(0), @@ -44,7 +50,6 @@ instance_stratholme::instance_stratholme(Map* pMap) : ScriptedInstance(pMap), Initialize(); } - void instance_stratholme::Initialize() { memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); @@ -59,17 +64,19 @@ void instance_stratholme::Initialize() bool instance_stratholme::StartSlaugtherSquare() { - if (m_auiEncounter[1] == SPECIAL && m_auiEncounter[2] == SPECIAL && m_auiEncounter[3] == SPECIAL) + if (m_auiEncounter[TYPE_BARONESS] == SPECIAL && m_auiEncounter[TYPE_NERUB] == SPECIAL && m_auiEncounter[TYPE_PALLID] == SPECIAL) { if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) DoScriptText(SAY_ANNOUNCE_RIVENDARE, pBaron); DoUseDoorOrButton(m_uiPortGauntletGUID); DoUseDoorOrButton(m_uiPortSlaugtherGUID); + + debug_log("SD2: Instance Stratholme: Open slaugther square."); + return true; } - debug_log("SD2: Instance Stratholme: Cannot open slaugther square yet."); return false; } @@ -83,6 +90,7 @@ void instance_stratholme::OnCreatureCreate(Creature* pCreature) case NPC_ABOM_BILE: case NPC_ABOM_VENOM: m_sAbomnationGUID.insert(pCreature->GetGUID()); break; case NPC_THUZADIN_ACOLYTE: m_luiAcolyteGUIDs.push_back(pCreature->GetGUID()); break; + case NPC_BARTHILAS: m_uiBarthilasGUID = pCreature->GetGUID(); break; } } @@ -101,55 +109,68 @@ void instance_stratholme::OnObjectCreate(GameObject* pGo) break; case GO_ZIGGURAT_DOOR_1: m_auiZigguratGUID[0] = pGo->GetGUID(); - if (m_auiEncounter[1] == DONE || m_auiEncounter[1] == SPECIAL) + if (m_auiEncounter[TYPE_BARONESS] == DONE || m_auiEncounter[TYPE_BARONESS] == SPECIAL) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_ZIGGURAT_DOOR_2: m_auiZigguratGUID[1] = pGo->GetGUID(); - if (m_auiEncounter[2] == DONE || m_auiEncounter[2] == SPECIAL) + if (m_auiEncounter[TYPE_NERUB] == DONE || m_auiEncounter[TYPE_NERUB] == SPECIAL) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_ZIGGURAT_DOOR_3: m_auiZigguratGUID[2] = pGo->GetGUID(); - if (m_auiEncounter[3] == DONE || m_auiEncounter[3] == SPECIAL) + if (m_auiEncounter[TYPE_PALLID] == DONE || m_auiEncounter[TYPE_PALLID] == SPECIAL) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_ZIGGURAT_DOOR_4: m_auiRamsteinDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[4] == DONE) + if (m_auiEncounter[TYPE_RAMSTEIN] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_ZIGGURAT_DOOR_5: m_auiRivendareDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[4] == DONE) + if (m_auiEncounter[TYPE_RAMSTEIN] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_PORT_GAUNTLET: m_uiPortGauntletGUID = pGo->GetGUID(); - if (m_auiEncounter[1] == SPECIAL && m_auiEncounter[2] == SPECIAL && m_auiEncounter[3] == SPECIAL) + if (m_auiEncounter[TYPE_BARONESS] == SPECIAL && m_auiEncounter[TYPE_NERUB] == SPECIAL && m_auiEncounter[TYPE_PALLID] == SPECIAL) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_PORT_SLAUGTHER: m_uiPortSlaugtherGUID = pGo->GetGUID(); - if (m_auiEncounter[1] == SPECIAL && m_auiEncounter[2] == SPECIAL && m_auiEncounter[3] == SPECIAL) + if (m_auiEncounter[TYPE_BARONESS] == SPECIAL && m_auiEncounter[TYPE_NERUB] == SPECIAL && m_auiEncounter[TYPE_PALLID] == SPECIAL) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_PORT_SLAUGHTER_GATE: + m_uiPortSlaughterGateGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_RAMSTEIN] == DONE) // Might actually be uneeded pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_PORT_ELDERS: m_uiPortElderGUID = pGo->GetGUID(); break; + case GO_YSIDA_CAGE: + m_uiYsidaCageGUID = pGo->GetGUID(); + break; } } void instance_stratholme::SetData(uint32 uiType, uint32 uiData) { + // TODO: Remove the hard-coded indexes from array accessing switch(uiType) { case TYPE_BARON_RUN: switch(uiData) { case IN_PROGRESS: - if (m_auiEncounter[0] == IN_PROGRESS || m_auiEncounter[0] == FAIL) + if (m_auiEncounter[uiType] == IN_PROGRESS || m_auiEncounter[uiType] == FAIL) break; + + if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + DoScriptText(SAY_ANNOUNCE_RUN_START, pBaron); + m_uiBaronRunTimer = 45*MINUTE*IN_MILLISECONDS; debug_log("SD2: Instance Stratholme: Baron run in progress."); break; @@ -157,111 +178,177 @@ void instance_stratholme::SetData(uint32 uiType, uint32 uiData) //may add code to remove aura from players, but in theory the time should be up already and removed. break; case DONE: - if (Creature* pYsidaT = instance->GetCreature(m_uiYsidaTriggerGUID)) - pYsidaT->SummonCreature(NPC_YSIDA, pYsidaT->GetPositionX(), pYsidaT->GetPositionY(), pYsidaT->GetPositionZ(), pYsidaT->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 1800000); - m_uiBaronRunTimer = 0; break; } - m_auiEncounter[0] = uiData; + m_auiEncounter[uiType] = uiData; break; case TYPE_BARONESS: - m_auiEncounter[1] = uiData; - if (uiData == DONE) - { - DoSortZiggurats(); - DoUseDoorOrButton(m_auiZigguratGUID[0]); - } - if (uiData == SPECIAL) - StartSlaugtherSquare(); - break; case TYPE_NERUB: - m_auiEncounter[2] = uiData; - if (uiData == DONE) - { - DoSortZiggurats(); - DoUseDoorOrButton(m_auiZigguratGUID[1]); - } - if (uiData == SPECIAL) - StartSlaugtherSquare(); - break; case TYPE_PALLID: - m_auiEncounter[3] = uiData; + m_auiEncounter[uiType] = uiData; if (uiData == DONE) { DoSortZiggurats(); - DoUseDoorOrButton(m_auiZigguratGUID[2]); + DoUseDoorOrButton(m_auiZigguratGUID[uiType - TYPE_BARONESS]); } if (uiData == SPECIAL) StartSlaugtherSquare(); break; case TYPE_RAMSTEIN: - if (uiData == IN_PROGRESS) + if (uiData == SPECIAL) { - if (m_auiEncounter[4] != IN_PROGRESS) + if (m_auiEncounter[uiType] != SPECIAL && m_auiEncounter[uiType] != DONE) + { + m_uiSlaugtherSquareTimer = 20000; // TODO - unknown, also possible that this is not the very correct place.. DoUseDoorOrButton(m_uiPortGauntletGUID); + } uint32 uiCount = m_sAbomnationGUID.size(); - for(std::set::iterator i = m_sAbomnationGUID.begin(); i != m_sAbomnationGUID.end(); ++i) + for(std::set::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end();) { - if (Creature* pAbom = instance->GetCreature(*i)) + if (Creature* pAbom = instance->GetCreature(*itr)) { + ++itr; if (!pAbom->isAlive()) --uiCount; } + else + { + // Remove obsolete guid from set and decrement count + m_sAbomnationGUID.erase(itr++); + --uiCount; + } } if (!uiCount) { - //a bit itchy, it should close the door after 10 secs, but it doesn't. skipping it for now. - // TODO - not working correctly! - //DoUseDoorOrButton(m_auiRamsteinDoorGUID, 10); + // Old Comment: a bit itchy, it should close m_auiRamsteinDoorGUID door after 10 secs, but it doesn't. skipping it for now. + // However looks like that this door is no more closed + DoUseDoorOrButton(m_auiRamsteinDoorGUID); + + // No more handlng of Abomnations + m_uiSlaugtherSquareTimer = 0; if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) - pBaron->SummonCreature(NPC_RAMSTEIN, 4032.84f, -3390.24f, 119.73f, 4.71f, TEMPSUMMON_DEAD_DESPAWN, 0); + { + DoScriptText(SAY_ANNOUNCE_RAMSTEIN, pBaron); + if (Creature* pRamstein = pBaron->SummonCreature(NPC_RAMSTEIN, sStratholmeLocation[2].m_fX, sStratholmeLocation[2].m_fY, sStratholmeLocation[2].m_fZ, sStratholmeLocation[2].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) + pRamstein->GetMotionMaster()->MovePoint(0, sStratholmeLocation[3].m_fX, sStratholmeLocation[3].m_fY, sStratholmeLocation[3].m_fZ); - debug_log("SD2: Instance Stratholme: Ramstein spawned."); + debug_log("SD2: Instance Stratholme - Slaugther event: Ramstein spawned."); + } } else - debug_log("SD2: Instance Stratholme: %u Abomnation left to kill.", uiCount); + debug_log("SD2: Instance Stratholme - Slaugther event: %u Abomnation left to kill.", uiCount); } + // After fail aggroing Ramstein means wipe on Ramstein, so close door again + if (uiData == IN_PROGRESS && m_auiEncounter[uiType] == FAIL) + DoUseDoorOrButton(m_uiPortGauntletGUID); if (uiData == DONE) { - m_uiSlaugtherSquareTimer = 5*MINUTE*IN_MILLISECONDS; - debug_log("SD2: Instance Stratholme: Slaugther event will continue in 5 minutes."); + // Open side gate and start summoning skeletons + DoUseDoorOrButton(m_uiPortSlaughterGateGUID); + // use this timer as a bool just to start summoning + m_uiMindlessSummonTimer = 500; + m_uiMindlessCount = 0; + m_luiUndeadGUIDs.clear(); + + // Summon 5 guards + if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + { + for(uint8 i = 0; i < 5; ++i) + { + float fX, fY, fZ; + pBaron->GetRandomPoint(sStratholmeLocation[6].m_fX, sStratholmeLocation[6].m_fY, sStratholmeLocation[6].m_fZ, 5.0f, fX, fY, fZ); + if (Creature* pTemp = pBaron->SummonCreature(NPC_BLACK_GUARD, sStratholmeLocation[6].m_fX, sStratholmeLocation[6].m_fY, sStratholmeLocation[6].m_fZ, sStratholmeLocation[6].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) + m_luiGuardGUIDs.push_back(pTemp->GetGUID()); + } + + debug_log("SD2: Instance Stratholme - Slaugther event: Summoned 5 guards."); + } + } + // Open Door again and stop Abomnation + if (uiData == FAIL && m_auiEncounter[uiType] != FAIL) + { + DoUseDoorOrButton(m_uiPortGauntletGUID); + m_uiSlaugtherSquareTimer = 0; + + // Let already moving Abomnations stop + for (std::set::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end(); ++itr) + { + Creature* pAbom = instance->GetCreature(*itr); + if (pAbom && pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) + pAbom->GetMotionMaster()->MovementExpired(); + } } - m_auiEncounter[4] = uiData; + + m_auiEncounter[uiType] = uiData; break; case TYPE_BARON: if (uiData == IN_PROGRESS) { - if (GetData(TYPE_BARON_RUN) == IN_PROGRESS) + // Reached the Baron within time-limit + if (m_auiEncounter[TYPE_BARON_RUN] == IN_PROGRESS) + SetData(TYPE_BARON_RUN, DONE); + + // Close Slaughterhouse door if needed + DoCloseDoorOrButton(m_uiPortGauntletGUID); + } + if (uiData == DONE) + { + if (m_auiEncounter[TYPE_BARON_RUN] == DONE) { Map::PlayerList const& players = instance->GetPlayers(); - if (!players.isEmpty()) + for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* pPlayer = itr->getSource()) { - if (Player* pPlayer = itr->getSource()) - { - if (pPlayer->HasAura(SPELL_BARON_ULTIMATUM)) - pPlayer->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM); - - if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE) - pPlayer->AreaExploredOrEventHappens(QUEST_DEAD_MAN_PLEA); - } + if (pPlayer->HasAura(SPELL_BARON_ULTIMATUM)) + pPlayer->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM); + + if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE) + pPlayer->AreaExploredOrEventHappens(QUEST_DEAD_MAN_PLEA); } } - SetData(TYPE_BARON_RUN,DONE); + // Open cage and finish rescue event + if (Creature* pYsidaT = instance->GetCreature(m_uiYsidaTriggerGUID)) + { + if (Creature* pYsida = pYsidaT->SummonCreature(NPC_YSIDA, pYsidaT->GetPositionX(), pYsidaT->GetPositionY(), pYsidaT->GetPositionZ(), pYsidaT->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 1800000)) + { + DoScriptText(SAY_EPILOGUE, pYsida); + pYsida->GetMotionMaster()->MovePoint(0, sStratholmeLocation[7].m_fX, sStratholmeLocation[7].m_fY, sStratholmeLocation[7].m_fZ); + } + DoUseDoorOrButton(m_uiYsidaCageGUID); + } } + + // Open Slaughterhouse door again + DoUseDoorOrButton(m_uiPortGauntletGUID); } - if (uiData == DONE) - // Open a few doors again // TODO: needs research, how to handle wipes in this area! + if (uiData == FAIL) DoUseDoorOrButton(m_uiPortGauntletGUID); - m_auiEncounter[5] = uiData; + // combat door + DoUseDoorOrButton(m_auiRivendareDoorGUID); + m_auiEncounter[5] = uiData; // TODO + break; + case TYPE_BARTHILAS_RUN: + if (uiData == IN_PROGRESS) + { + Creature* pBarthilas = instance->GetCreature(m_uiBarthilasGUID); + if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) + { + DoScriptText(SAY_WARN_BARON, pBarthilas); + pBarthilas->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pBarthilas->GetMotionMaster()->MovePoint(0, sStratholmeLocation[0].m_fX, sStratholmeLocation[0].m_fY, sStratholmeLocation[0].m_fZ); + + m_uiBarthilasRunTimer = 8000; + } + } + m_auiEncounter[6] = uiData; // TODO break; case TYPE_SH_AELMAR: @@ -287,7 +374,7 @@ void instance_stratholme::SetData(uint32 uiType, uint32 uiData) std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " - << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5]; + << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6]; strInstData = saveStream.str(); @@ -308,7 +395,7 @@ void instance_stratholme::Load(const char* 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[4] >> m_auiEncounter[5] >> m_auiEncounter[6]; for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) { @@ -347,6 +434,8 @@ uint32 instance_stratholme::GetData(uint32 uiType) return m_auiEncounter[4]; case TYPE_BARON: return m_auiEncounter[5]; + case TYPE_BARTHILAS_RUN: + return m_auiEncounter[6]; default: return 0; } @@ -450,69 +539,226 @@ void instance_stratholme::DoSortZiggurats() } } -void instance_stratholme::OnCreatureDeath(Creature* pCreature) +void instance_stratholme::OnCreatureEnterCombat(Creature* pCreature) { - if (pCreature->GetEntry() == NPC_THUZADIN_ACOLYTE) + switch (pCreature->GetEntry()) { - for (uint8 i = 0; i < MAX_ZIGGURATS; ++i) - { - if (m_alZigguratAcolyteGUID[i].empty()) - continue; // nothing to do anymore for this ziggurat + case NPC_BARONESS_ANASTARI: SetData(TYPE_BARONESS, IN_PROGRESS); break; + case NPC_MALEKI_THE_PALLID: SetData(TYPE_PALLID, IN_PROGRESS); break; + case NPC_NERUBENKAN: SetData(TYPE_NERUB, IN_PROGRESS); break; + case NPC_RAMSTEIN: SetData(TYPE_RAMSTEIN, IN_PROGRESS); break; + // TODO - uncomment when proper working within core! case NPC_BARON: SetData(TYPE_BARON, IN_PROGRESS); break; + + case NPC_ABOM_BILE: + case NPC_ABOM_VENOM: + // Start Slaughterhouse Event + SetData(TYPE_RAMSTEIN, SPECIAL); + break; - m_alZigguratAcolyteGUID[i].remove(pCreature->GetGUID()); - if (m_alZigguratAcolyteGUID[i].empty()) + case NPC_MINDLESS_UNDEAD: + case NPC_BLACK_GUARD: + // Aggro in Slaughterhouse after Ramstein -- Need to close Slaughterhouse Door if not closed (wipe case) + DoCloseDoorOrButton(m_uiPortGauntletGUID); + break; + } +} + +void instance_stratholme::OnCreatureEvade(Creature* pCreature) +{ + switch (pCreature->GetEntry()) + { + case NPC_BARONESS_ANASTARI: SetData(TYPE_BARONESS, FAIL); break; + case NPC_MALEKI_THE_PALLID: SetData(TYPE_PALLID, FAIL); break; + case NPC_NERUBENKAN: SetData(TYPE_NERUB, FAIL); break; + case NPC_RAMSTEIN: SetData(TYPE_RAMSTEIN, FAIL); break; + // TODO - uncomment when proper working within core! case NPC_BARON: SetData(TYPE_BARON, FAIL); break; + + case NPC_ABOM_BILE: + case NPC_ABOM_VENOM: + // Fail in Slaughterhouse Event before Ramstein + SetData(TYPE_RAMSTEIN, FAIL); + break; + case NPC_MINDLESS_UNDEAD: + case NPC_BLACK_GUARD: + // Fail in Slaughterhouse after Ramstein -- Need to open Slaughterhouse Door + DoOpenDoorOrButton(m_uiPortGauntletGUID); + break; + } +} + +void instance_stratholme::OnCreatureDeath(Creature* pCreature) +{ + switch (pCreature->GetEntry()) + { + case NPC_BARONESS_ANASTARI: SetData(TYPE_BARONESS, DONE); break; + case NPC_MALEKI_THE_PALLID: SetData(TYPE_PALLID, DONE); break; + case NPC_NERUBENKAN: SetData(TYPE_NERUB, DONE); break; + case NPC_RAMSTEIN: SetData(TYPE_RAMSTEIN, DONE); break; + case NPC_BARON: SetData(TYPE_BARON, DONE); break; + + case NPC_THUZADIN_ACOLYTE: + for (uint8 i = 0; i < MAX_ZIGGURATS; ++i) { - // A random zone yell after one is cleared - int32 aAnnounceSay[MAX_ZIGGURATS] = {SAY_ANNOUNCE_ZIGGURAT_1, SAY_ANNOUNCE_ZIGGURAT_2, SAY_ANNOUNCE_ZIGGURAT_3}; - if (Creature* pAnnouncer = instance->GetCreature(m_uiAcolyteAnnouncerGUID)) - DoScriptText(aAnnounceSay[i], pAnnouncer); + if (m_alZigguratAcolyteGUID[i].empty()) + continue; // nothing to do anymore for this ziggurat + + m_alZigguratAcolyteGUID[i].remove(pCreature->GetGUID()); + if (m_alZigguratAcolyteGUID[i].empty()) + { + // A random zone yell after one is cleared + int32 aAnnounceSay[MAX_ZIGGURATS] = {SAY_ANNOUNCE_ZIGGURAT_1, SAY_ANNOUNCE_ZIGGURAT_2, SAY_ANNOUNCE_ZIGGURAT_3}; + if (Creature* pAnnouncer = instance->GetCreature(m_uiAcolyteAnnouncerGUID)) + DoScriptText(aAnnounceSay[i], pAnnouncer); - // Kill Crystal - if (Creature* pCrystal = instance->GetCreature(m_auiCrystalSortedGUID[i])) - pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + // Kill Crystal + if (Creature* pCrystal = instance->GetCreature(m_auiCrystalSortedGUID[i])) + pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - switch (i) + switch (i) + { + case 0: SetData(TYPE_BARONESS, SPECIAL); break; + case 1: SetData(TYPE_NERUB, SPECIAL); break; + case 2: SetData(TYPE_PALLID, SPECIAL); break; + } + } + } + break; + + case NPC_ABOM_BILE: + case NPC_ABOM_VENOM: + // Start Slaughterhouse Event + SetData(TYPE_RAMSTEIN, SPECIAL); + break; + + case NPC_MINDLESS_UNDEAD: + m_luiUndeadGUIDs.remove(pCreature->GetGUID()); + if (m_luiUndeadGUIDs.empty()) + { + // Let the black Guards move out of the citadel + for (std::list::const_iterator itr = m_luiGuardGUIDs.begin(); itr != m_luiGuardGUIDs.end(); ++itr) { - case 0: SetData(TYPE_BARONESS, SPECIAL); break; - case 1: SetData(TYPE_NERUB, SPECIAL); break; - case 2: SetData(TYPE_PALLID, SPECIAL); break; + Creature* pGuard = instance->GetCreature(*itr); + if (pGuard && pGuard->isAlive() && !pGuard->isInCombat()) + { + float fX, fY, fZ; + pGuard->GetRandomPoint(sStratholmeLocation[5].m_fX, sStratholmeLocation[5].m_fY, sStratholmeLocation[5].m_fZ, 10.0f, fX, fY, fZ); + pGuard->GetMotionMaster()->MovePoint(0, fX, fY, fZ); + } } } - } + break; + case NPC_BLACK_GUARD: + m_luiGuardGUIDs.remove(pCreature->GetGUID()); + if (m_luiGuardGUIDs.empty()) + { + if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + DoScriptText(SAY_UNDEAD_DEFEAT, pBaron); + DoUseDoorOrButton(m_auiRivendareDoorGUID); + } + break; } } void instance_stratholme::Update(uint32 uiDiff) { + if (m_uiBarthilasRunTimer) + { + if (m_uiBarthilasRunTimer <= uiDiff) + { + Creature* pBarthilas = instance->GetCreature(m_uiBarthilasGUID); + if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) + pBarthilas->NearTeleportTo(sStratholmeLocation[1].m_fX, sStratholmeLocation[1].m_fY, sStratholmeLocation[1].m_fZ, sStratholmeLocation[1].m_fO); + + SetData(TYPE_BARTHILAS_RUN, DONE); + m_uiBarthilasRunTimer = 0; + } + else + m_uiBarthilasRunTimer -= uiDiff; + } + if (m_uiBaronRunTimer) { + if (m_uiYellCounter == 0 && m_uiBaronRunTimer <= 10*MINUTE*IN_MILLISECONDS) + { + if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + DoScriptText(SAY_ANNOUNCE_RUN_10_MIN, pBaron); + ++m_uiYellCounter; + } + else if (m_uiYellCounter == 1 && m_uiBaronRunTimer <= 5*MINUTE*IN_MILLISECONDS) + { + if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + DoScriptText(SAY_ANNOUNCE_RUN_5_MIN, pBaron); + ++m_uiYellCounter; + } + if (m_uiBaronRunTimer <= uiDiff) { - if (GetData(TYPE_BARON_RUN) != DONE) - SetData(TYPE_BARON_RUN, FAIL); + SetData(TYPE_BARON_RUN, FAIL); + + if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + DoScriptText(SAY_ANNOUNCE_RUN_FAIL, pBaron); m_uiBaronRunTimer = 0; - debug_log("SD2: Instance Stratholme: Baron run event reached end. Event has state %u.",GetData(TYPE_BARON_RUN)); + debug_log("SD2: Instance Stratholme: Baron run event reached end. Event has state %u.", GetData(TYPE_BARON_RUN)); } else m_uiBaronRunTimer -= uiDiff; } + if (m_uiMindlessSummonTimer) + { + if (m_uiMindlessCount < 30) + { + if (m_uiMindlessSummonTimer <= uiDiff) + { + if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + { + // Summon mindless skeletons and move them to random point in the center of the square + if (Creature* pTemp = pBaron->SummonCreature(NPC_MINDLESS_UNDEAD, sStratholmeLocation[4].m_fX, sStratholmeLocation[4].m_fY, sStratholmeLocation[4].m_fZ, sStratholmeLocation[4].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) + { + float fX, fY, fZ; + pBaron->GetRandomPoint(sStratholmeLocation[5].m_fX, sStratholmeLocation[5].m_fY, sStratholmeLocation[5].m_fZ, 20.0f, fX, fY, fZ); + pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ); + m_luiUndeadGUIDs.push_back(pTemp->GetGUID()); + ++m_uiMindlessCount; + } + } + m_uiMindlessSummonTimer = 400; + } + else + m_uiMindlessSummonTimer -= uiDiff; + } + else + m_uiMindlessSummonTimer = 0; + } + if (m_uiSlaugtherSquareTimer) { if (m_uiSlaugtherSquareTimer <= uiDiff) { - if (Creature* pBaron = instance->GetCreature(m_uiBaronGUID)) + // Call next Abomnations + for (std::set::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end(); ++itr) { - for(uint8 i = 0; i < 4; ++i) - pBaron->SummonCreature(NPC_BLACK_GUARD, 4032.84f, -3390.24f, 119.73f, 4.71f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 1800000); + Creature* pAbom = instance->GetCreature(*itr); + // Skip killed and already walking Abomnations + if (!pAbom || !pAbom->isAlive() || pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) + continue; - DoUseDoorOrButton(m_auiRamsteinDoorGUID); - DoUseDoorOrButton(m_auiRivendareDoorGUID); - - debug_log("SD2: Instance Stratholme: Black guard sentries spawned. Opening gates to baron."); + // Let Move to somewhere in the middle + if (!pAbom->isInCombat()) + { + if (GameObject* pDoor = instance->GetGameObject(m_uiPortSlaugtherGUID)) + { + float fX, fY, fZ; + pAbom->GetRandomPoint(pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ(), 10.0f, fX, fY, fZ); + pAbom->GetMotionMaster()->MovePoint(0, fX, fY, fZ); + } + } + break; } - m_uiSlaugtherSquareTimer = 0; + + // TODO - how fast are they called? + m_uiSlaugtherSquareTimer = urand(15000, 30000); } else m_uiSlaugtherSquareTimer -= uiDiff; diff --git a/scripts/eastern_kingdoms/stratholme/stratholme.cpp b/scripts/eastern_kingdoms/stratholme/stratholme.cpp index 5b4b98d2b..8919c1eb1 100644 --- a/scripts/eastern_kingdoms/stratholme/stratholme.cpp +++ b/scripts/eastern_kingdoms/stratholme/stratholme.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -31,11 +31,30 @@ EndContentData */ #include "precompiled.h" #include "stratholme.h" +/*###### +## go_service_gate +######*/ + +bool GOUse_go_service_gate(Player* pPlayer, GameObject* pGo) +{ + ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); + + if (!pInstance) + return false; + + if (pInstance->GetData(TYPE_BARTHILAS_RUN) != NOT_STARTED) + return false; + + // if the service gate is used make Barthilas flee + pInstance->SetData(TYPE_BARTHILAS_RUN, IN_PROGRESS); + return false; +} + /*###### ## go_gauntlet_gate (this is the _first_ of the gauntlet gates, two exist) ######*/ -bool GOHello_go_gauntlet_gate(Player* pPlayer, GameObject* pGo) +bool GOUse_go_gauntlet_gate(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -53,21 +72,17 @@ bool GOHello_go_gauntlet_gate(Player* pPlayer, GameObject* pGo) if (!pGroupie) continue; - if (pGroupie->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && - !pGroupie->HasAura(SPELL_BARON_ULTIMATUM, EFFECT_INDEX_0) && - pGroupie->GetMap() == pGo->GetMap()) - pGroupie->CastSpell(pGroupie,SPELL_BARON_ULTIMATUM,true); + if (!pGroupie->HasAura(SPELL_BARON_ULTIMATUM)) + pGroupie->CastSpell(pGroupie, SPELL_BARON_ULTIMATUM, true); } } else { - if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && - !pPlayer->HasAura(SPELL_BARON_ULTIMATUM, EFFECT_INDEX_0) && - pPlayer->GetMap() == pGo->GetMap()) + if (!pPlayer->HasAura(SPELL_BARON_ULTIMATUM)) pPlayer->CastSpell(pPlayer, SPELL_BARON_ULTIMATUM, true); } - pInstance->SetData(TYPE_BARON_RUN,IN_PROGRESS); + pInstance->SetData(TYPE_BARON_RUN, IN_PROGRESS); return false; } @@ -75,15 +90,18 @@ bool GOHello_go_gauntlet_gate(Player* pPlayer, GameObject* pGo) ## mob_freed_soul ######*/ -//Possibly more of these quotes around. -#define SAY_ZAPPED0 -1329000 -#define SAY_ZAPPED1 -1329001 -#define SAY_ZAPPED2 -1329002 -#define SAY_ZAPPED3 -1329003 +// Possibly more of these quotes around. +enum +{ + SAY_ZAPPED0 = -1329000, + SAY_ZAPPED1 = -1329001, + SAY_ZAPPED2 = -1329002, + SAY_ZAPPED3 = -1329003, +}; struct MANGOS_DLL_DECL mob_freed_soulAI : public ScriptedAI { - mob_freed_soulAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + mob_freed_soulAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } void Reset() { @@ -106,61 +124,66 @@ CreatureAI* GetAI_mob_freed_soul(Creature* pCreature) ## mob_restless_soul ######*/ -#define SPELL_EGAN_BLASTER 17368 -#define SPELL_SOUL_FREED 17370 -#define QUEST_RESTLESS_SOUL 5282 -#define ENTRY_RESTLESS 11122 -#define ENTRY_FREED 11136 +enum +{ + QUEST_RESTLESS_SOUL = 5282, + + SPELL_EGAN_BLASTER = 17368, + SPELL_SOUL_FREED = 17370, + + NPC_RESTLESS_SOUL = 11122, + NPC_FREED_SOUL = 11136, +}; struct MANGOS_DLL_DECL mob_restless_soulAI : public ScriptedAI { - mob_restless_soulAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + mob_restless_soulAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } - uint64 Tagger; - uint32 Die_Timer; - bool Tagged; + uint64 m_uiTaggerGUID; + uint32 m_uiDieTimer; + bool m_bIsTagged; void Reset() { - Tagger = 0; - Die_Timer = 5000; - Tagged = false; + m_uiTaggerGUID = 0; + m_uiDieTimer = 5000; + m_bIsTagged = false; } - void SpellHit(Unit *caster, const SpellEntry *spell) + void SpellHit(Unit* pCaster, const SpellEntry* pSpell) { - if (caster->GetTypeId() == TYPEID_PLAYER) + if (pCaster->GetTypeId() == TYPEID_PLAYER) { - if (!Tagged && spell->Id == SPELL_EGAN_BLASTER && ((Player*)caster)->GetQuestStatus(QUEST_RESTLESS_SOUL) == QUEST_STATUS_INCOMPLETE) + if (!m_bIsTagged && pSpell->Id == SPELL_EGAN_BLASTER && ((Player*)pCaster)->GetQuestStatus(QUEST_RESTLESS_SOUL) == QUEST_STATUS_INCOMPLETE) { - Tagged = true; - Tagger = caster->GetGUID(); + m_bIsTagged = true; + m_uiTaggerGUID = pCaster->GetGUID(); } } } - void JustSummoned(Creature *summoned) + void JustSummoned(Creature* pSummoned) { - summoned->CastSpell(summoned,SPELL_SOUL_FREED,false); + pSummoned->CastSpell(pSummoned, SPELL_SOUL_FREED, false); } void JustDied(Unit* Killer) { - if (Tagged) - m_creature->SummonCreature(ENTRY_FREED, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 300000); + if (m_bIsTagged) + m_creature->SummonCreature(NPC_FREED_SOUL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 300000); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { - if (Tagged) + if (m_bIsTagged) { - if (Die_Timer < diff) + if (m_uiDieTimer < uiDiff) { - if (Player* pPlayer = m_creature->GetMap()->GetPlayer(Tagger)) + if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiTaggerGUID)) pPlayer->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } else - Die_Timer -= diff; + m_uiDieTimer -= uiDiff; } } }; @@ -184,48 +207,48 @@ struct MANGOS_DLL_DECL mobs_spectral_ghostly_citizenAI : public ScriptedAI { mobs_spectral_ghostly_citizenAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - uint32 Die_Timer; - bool Tagged; + uint32 m_uiDieTimer; + bool m_bIsTagged; void Reset() { - Die_Timer = 5000; - Tagged = false; + m_uiDieTimer = 5000; + m_bIsTagged = false; } - void SpellHit(Unit *caster, const SpellEntry *spell) + void SpellHit(Unit* pCaster, const SpellEntry* pSpell) { - if (!Tagged && spell->Id == SPELL_EGAN_BLASTER) - Tagged = true; + if (!m_bIsTagged && pSpell->Id == SPELL_EGAN_BLASTER) + m_bIsTagged = true; } void JustDied(Unit* Killer) { - if (Tagged) + if (m_bIsTagged) { - for(uint32 i = 1; i <= 4; ++i) + for(uint32 i = 0; i < 4; ++i) { - float x,y,z; - m_creature->GetRandomPoint(m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),20.0f,x,y,z); + float x, y, z; + m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 20.0f, x, y, z); - //100%, 50%, 33%, 25% chance to spawn - uint32 j = urand(1,i); - if (j==1) - m_creature->SummonCreature(ENTRY_RESTLESS,x,y,z,0,TEMPSUMMON_CORPSE_DESPAWN,600000); + // 100%, 50%, 33%, 25% chance to spawn + uint32 j = urand(0, i); + if (j == 0) + m_creature->SummonCreature(NPC_RESTLESS_SOUL, x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 0); } } } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { - if (Tagged) + if (m_bIsTagged) { - if (Die_Timer < diff) + if (m_uiDieTimer < uiDiff) { m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } else - Die_Timer -= diff; + m_uiDieTimer -= uiDiff; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) @@ -234,16 +257,16 @@ struct MANGOS_DLL_DECL mobs_spectral_ghostly_citizenAI : public ScriptedAI DoMeleeAttackIfReady(); } - void ReceiveEmote(Player* pPlayer, uint32 emote) + void ReceiveEmote(Player* pPlayer, uint32 uiEmote) { - switch(emote) + switch(uiEmote) { case TEXTEMOTE_DANCE: EnterEvadeMode(); break; case TEXTEMOTE_RUDE: - if (m_creature->IsWithinDistInMap(pPlayer, ATTACK_DISTANCE)) - m_creature->CastSpell(pPlayer,SPELL_SLAP,false); + if (m_creature->IsWithinDistInMap(pPlayer, INTERACTION_DISTANCE)) + m_creature->CastSpell(pPlayer, SPELL_SLAP, false); else m_creature->HandleEmote(EMOTE_ONESHOT_RUDE); break; @@ -269,9 +292,14 @@ void AddSC_stratholme() { Script* pNewScript; + pNewScript = new Script; + pNewScript->Name = "go_service_gate"; + pNewScript->pGOUse = &GOUse_go_service_gate; + pNewScript->RegisterSelf(); + pNewScript = new Script; pNewScript->Name = "go_gauntlet_gate"; - pNewScript->pGOHello = &GOHello_go_gauntlet_gate; + pNewScript->pGOUse = &GOUse_go_gauntlet_gate; pNewScript->RegisterSelf(); pNewScript = new Script; diff --git a/scripts/eastern_kingdoms/stratholme/stratholme.h b/scripts/eastern_kingdoms/stratholme/stratholme.h index b6d308974..45d28e140 100644 --- a/scripts/eastern_kingdoms/stratholme/stratholme.h +++ b/scripts/eastern_kingdoms/stratholme/stratholme.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,19 +7,18 @@ enum { - MAX_ENCOUNTER = 6, + MAX_ENCOUNTER = 7, MAX_SILVERHAND = 5, MAX_ZIGGURATS = 3, - TYPE_BARON_RUN = 1, - TYPE_BARONESS = 2, - TYPE_NERUB = 3, - TYPE_PALLID = 4, - TYPE_RAMSTEIN = 5, - TYPE_BARON = 6, - - //DATA_BARON = 10, // Wasn't used, verify that it really was never used! - //DATA_YSIDA_TRIGGER = 11, + TYPE_BARON_RUN = 0, + TYPE_BARONESS = 1, + TYPE_NERUB = TYPE_BARONESS + 1, // Assert that these three TYPEs are in correct order. + TYPE_PALLID = TYPE_BARONESS + 2, + TYPE_RAMSTEIN = 4, + TYPE_RAMSTEIN_OBSOLETE = 5, // Still set in Acid, remove when removed from Acid :) + TYPE_BARON = 6, // Adapt then + TYPE_BARTHILAS_RUN = 7, TYPE_SH_QUEST = 20, TYPE_SH_CATHELA = 21, @@ -28,18 +27,24 @@ enum TYPE_SH_VICAR = 24, TYPE_SH_AELMAR = 25, - NPC_CRYSTAL = 10415, //three ziggurat crystals - NPC_BARON = 10440, - NPC_YSIDA_TRIGGER = 16100, - NPC_THUZADIN_ACOLYTE = 10399, //acolytes in ziggurats + NPC_BARTHILAS = 10435, + NPC_BARONESS_ANASTARI = 10436, + NPC_NERUBENKAN = 10437, + NPC_MALEKI_THE_PALLID = 10438, NPC_RAMSTEIN = 10439, + NPC_BARON = 10440, + NPC_CRYSTAL = 10415, // three ziggurat crystals + NPC_THUZADIN_ACOLYTE = 10399, // acolytes in ziggurats NPC_ABOM_BILE = 10416, NPC_ABOM_VENOM = 10417, - NPC_BLACK_GUARD = 10394, + NPC_MINDLESS_UNDEAD = 11030, // zombies summoned after ramstein + NPC_BLACK_GUARD = 10394, // zombies summoned after ramstein NPC_YSIDA = 16031, + NPC_YSIDA_TRIGGER = 16100, GO_SERVICE_ENTRANCE = 175368, GO_GAUNTLET_GATE1 = 175357, + GO_PORT_SLAUGHTER_GATE = 175358, //port used at the undeads event GO_ZIGGURAT_DOOR_1 = 175380, //baroness GO_ZIGGURAT_DOOR_2 = 175379, //nerub'enkan GO_ZIGGURAT_DOOR_3 = 175381, //maleki @@ -48,6 +53,7 @@ enum GO_PORT_GAUNTLET = 175374, //port from gauntlet to slaugther GO_PORT_SLAUGTHER = 175373, //port at slaugther GO_PORT_ELDERS = 175377, //port at elders square + GO_YSIDA_CAGE = 181071, // cage to open after baron event is done QUEST_DEAD_MAN_PLEA = 8945, SPELL_BARON_ULTIMATUM = 27861, @@ -55,7 +61,33 @@ enum SAY_ANNOUNCE_ZIGGURAT_1 = -1329004, SAY_ANNOUNCE_ZIGGURAT_2 = -1329005, SAY_ANNOUNCE_ZIGGURAT_3 = -1329006, - SAY_ANNOUNCE_RIVENDARE = -1329007 + SAY_ANNOUNCE_RIVENDARE = -1329007, + + SAY_WARN_BARON = -1329008, + SAY_ANNOUNCE_RUN_START = -1329009, + SAY_ANNOUNCE_RUN_10_MIN = -1329010, + SAY_ANNOUNCE_RUN_5_MIN = -1329011, + SAY_ANNOUNCE_RUN_FAIL = -1329012, + SAY_ANNOUNCE_RAMSTEIN = -1329013, + SAY_UNDEAD_DEFEAT = -1329014, + SAY_EPILOGUE = -1329015, +}; + +struct sEventLocation +{ + float m_fX, m_fY, m_fZ, m_fO; +}; + +static sEventLocation sStratholmeLocation[] = +{ + {3725.577f, -3599.484f, 142.367f}, // barthilas door run + {4068.284f, -3535.678f, 122.771f, 2.50f}, // barthilas tele + {4032.643f, -3378.546f, 119.752f, 4.74f}, // ramstein summon loc + {4032.843f, -3390.246f, 119.732f}, // ramstein move loc + {3969.357f, -3391.871f, 119.116f, 5.91f}, // skeletons summon loc + {4033.044f, -3431.031f, 119.055f}, // skeletons move loc + {4032.602f, -3378.506f, 119.752f, 4.74f}, // guards summon loc + {4042.575f, -3337.929f, 115.059f} // ysida move loc }; struct MANGOS_DLL_DECL instance_stratholme : public ScriptedInstance @@ -76,6 +108,8 @@ struct MANGOS_DLL_DECL instance_stratholme : public ScriptedInstance const char* Save() { return strInstData.c_str(); } void Load(const char* chrIn); + void OnCreatureEnterCombat(Creature* pCreature); + void OnCreatureEvade(Creature* pCreature); void OnCreatureDeath(Creature* pCreature); void Update(uint32 uiDiff); @@ -89,8 +123,13 @@ struct MANGOS_DLL_DECL instance_stratholme : public ScriptedInstance std::string strInstData; uint32 m_uiBaronRunTimer; + uint32 m_uiBarthilasRunTimer; + uint32 m_uiMindlessSummonTimer; uint32 m_uiSlaugtherSquareTimer; + uint32 m_uiYellCounter; + uint32 m_uiMindlessCount; + uint64 m_uiServiceEntranceGUID; uint64 m_uiGauntletGate1GUID; uint64 m_auiZigguratGUID[MAX_ZIGGURATS]; @@ -99,9 +138,12 @@ struct MANGOS_DLL_DECL instance_stratholme : public ScriptedInstance uint64 m_uiPortGauntletGUID; uint64 m_uiPortSlaugtherGUID; uint64 m_uiPortElderGUID; + uint64 m_uiPortSlaughterGateGUID; + uint64 m_uiYsidaCageGUID; uint64 m_uiBaronGUID; uint64 m_uiYsidaTriggerGUID; + uint64 m_uiBarthilasGUID; uint64 m_uiAcolyteAnnouncerGUID; uint64 m_auiCrystalSortedGUID[MAX_ZIGGURATS]; @@ -109,6 +151,8 @@ struct MANGOS_DLL_DECL instance_stratholme : public ScriptedInstance std::set m_sAbomnationGUID; std::list m_luiAcolyteGUIDs; std::list m_alZigguratAcolyteGUID[MAX_ZIGGURATS]; + std::list m_luiUndeadGUIDs; + std::list m_luiGuardGUIDs; }; #endif diff --git a/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp b/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp index 715ec262f..dfe212606 100644 --- a/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp +++ b/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp b/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp index 2b4b70c5b..92914fd8e 100644 --- a/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp +++ b/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h b/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h index 84a10197a..b6da8c23b 100644 --- a/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h +++ b/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp b/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp index f8c09810c..8c548754f 100644 --- a/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp +++ b/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp b/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp similarity index 51% rename from scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp rename to scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp index 4cbde3ea4..9f86d21b3 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp +++ b/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,31 +15,14 @@ */ /* ScriptData -SDName: boss_forgemaster_gafrost -SD%Complete: 0% +SDName: boss_eredar_twins +SD%Complete: SDComment: -SDCategory: Pit of Saron +SDCategory: Sunwell Plateau EndScriptData */ #include "precompiled.h" -#include "pit_of_saron.h" -enum +void AddSC_boss_eredar_twins() { - SAY_AGGRO = -1658014, - SAY_SLAY_1 = -1658015, - SAY_BOULDER_HIT = -1658016, - SAY_DEATH = -1658017, - SAY_FORGE_1 = -1658018, - SAY_FORGE_2 = -1658019, - SAY_TYRANNUS_GARFROST = -1658020, - SAY_GENERAL_GARFROST = -1658021, - - EMOTE_THROW_SARONITE = -1658022, - EMOTE_DEEP_FREEZE = -1658023, -}; - -void AddSC_boss_gafrost() -{ - } diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falryn.cpp b/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp similarity index 82% rename from scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falryn.cpp rename to scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp index b7c8771cb..c7d78444e 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falryn.cpp +++ b/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,10 +15,14 @@ */ /* ScriptData -SDName: boss_falryn -SD%Complete: 0% +SDName: boss_felmyst +SD%Complete: SDComment: -SDCategory: Halls of Reflection +SDCategory: Sunwell Plateau EndScriptData */ #include "precompiled.h" + +void AddSC_boss_felmyst() +{ +} diff --git a/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp b/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp index f1c97d6e5..bd10e51d6 100644 --- a/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp +++ b/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -126,7 +126,7 @@ struct MANGOS_DLL_DECL boss_kalecgosAI : public ScriptedAI if (m_pInstance) { // Reset Sathrovarr too - if (Creature* pSath = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SATHROVARR))) + if (Creature* pSath = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SATHROVARR))) { if (pSath->isAlive() && pSath->getVictim()) pSath->AI()->EnterEvadeMode(); @@ -209,7 +209,7 @@ struct MANGOS_DLL_DECL boss_kalecgosAI : public ScriptedAI if (!m_pInstance) return; - if (Creature* pSathrovarr = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SATHROVARR))) + if (Creature* pSathrovarr = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SATHROVARR))) { if (pSathrovarr->isAlive()) { @@ -218,7 +218,7 @@ struct MANGOS_DLL_DECL boss_kalecgosAI : public ScriptedAI } } - if (Creature* pKalec = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_KALECGOS_HUMAN))) + if (Creature* pKalec = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KALECGOS_HUMAN))) { pKalec->DeleteThreatList(); pKalec->SetVisibility(VISIBILITY_OFF); @@ -252,7 +252,7 @@ struct MANGOS_DLL_DECL boss_kalecgosAI : public ScriptedAI if (!m_bEnraged && m_creature->GetHealthPercent() < 10.0f) { - if (Creature* pSathrovarr = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SATHROVARR))) + if (Creature* pSathrovarr = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SATHROVARR))) { if (pSathrovarr->isAlive()) pSathrovarr->CastSpell(pSathrovarr, SPELL_CRAZED_RAGE, true); @@ -378,7 +378,7 @@ struct MANGOS_DLL_DECL boss_sathrovarrAI : public ScriptedAI if (!m_pInstance) return; - if (Creature* pKalec = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_KALECGOS_HUMAN))) + if (Creature* pKalec = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_KALECGOS_HUMAN))) { m_creature->AddThreat(pKalec, 10000000.0f); pKalec->AddThreat(m_creature, 10000000.0f); @@ -400,7 +400,7 @@ struct MANGOS_DLL_DECL boss_sathrovarrAI : public ScriptedAI m_pInstance->SetData(DATA_SET_SPECTRAL_CHECK, 5000); - if (Creature* pKalecgos = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_KALECGOS_DRAGON))) + if (Creature* pKalecgos = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KALECGOS_DRAGON))) { if (boss_kalecgosAI* pKalecgosAI = dynamic_cast(pKalecgos->AI())) { @@ -423,7 +423,7 @@ struct MANGOS_DLL_DECL boss_sathrovarrAI : public ScriptedAI if (!m_bEnraged && m_creature->GetHealthPercent() < 10.0f) { - if (Creature* pKalecgos = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_KALECGOS_DRAGON))) + if (Creature* pKalecgos = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_KALECGOS_DRAGON))) { if (pKalecgos->isAlive()) pKalecgos->CastSpell(pKalecgos, SPELL_CRAZED_RAGE, true); @@ -537,7 +537,7 @@ struct MANGOS_DLL_DECL boss_kalecgos_humanoidAI : public ScriptedAI } }; -bool GOHello_go_spectral_rift(Player* pPlayer, GameObject* pGo) +bool GOUse_go_spectral_rift(Player* pPlayer, GameObject* pGo) { if (pGo->GetGoType() != GAMEOBJECT_TYPE_GOOBER) return true; @@ -616,7 +616,7 @@ void AddSC_boss_kalecgos() newscript->RegisterSelf(); newscript = new Script; - newscript->pGOHello = &GOHello_go_spectral_rift; + newscript->pGOUse = &GOUse_go_spectral_rift; newscript->Name = "go_spectral_rift"; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp b/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp new file mode 100644 index 000000000..2ebb51330 --- /dev/null +++ b/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_kiljaeden +SD%Complete: +SDComment: +SDCategory: Sunwell Plateau +EndScriptData */ + +#include "precompiled.h" + +void AddSC_boss_kiljaeden() +{ +} diff --git a/scripts/northrend/ruby_sanctum/boss_zarithian.cpp b/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp similarity index 83% rename from scripts/northrend/ruby_sanctum/boss_zarithian.cpp rename to scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp index 8d62b32e9..77950d313 100644 --- a/scripts/northrend/ruby_sanctum/boss_zarithian.cpp +++ b/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,10 +15,14 @@ */ /* ScriptData -SDName: boss_zarithian +SDName: boss_muru SD%Complete: -SDComment:placeholder -SDCategory: Ruby Sanctum +SDComment: +SDCategory: Sunwell Plateau EndScriptData */ #include "precompiled.h" + +void AddSC_boss_muru() +{ +} diff --git a/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp b/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp index ecad826ce..04174a6c0 100644 --- a/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp +++ b/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp @@ -1,6 +1,18 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 - * This program is free software licensed under GPL version 2 - * Please see the included DOCS/LICENSE.TXT for more information */ +/* Copyright (C) 2006 - 2011 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 + */ /* ScriptData SDName: Instance_Sunwell_Plateau @@ -21,346 +33,308 @@ EndScriptData */ 5 - Kil'Jaeden */ -struct MANGOS_DLL_DECL instance_sunwell_plateau : public ScriptedInstance -{ - instance_sunwell_plateau(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - +instance_sunwell_plateau::instance_sunwell_plateau(Map* pMap) : ScriptedInstance(pMap), // Creatures - uint64 m_uiKalecgos_DragonGUID; - uint64 m_uiKalecgos_HumanGUID; - uint64 m_uiSathrovarrGUID; - uint64 m_uiBrutallusGUID; - uint64 m_uiFelmystGUID; - uint64 m_uiAlythessGUID; - uint64 m_uiSacrolashGUID; - uint64 m_uiMuruGUID; - uint64 m_uiKilJaedenGUID; - uint64 m_uiKilJaedenControllerGUID; - uint64 m_uiAnveenaGUID; - uint64 m_uiKalecgosGUID; - + m_uiKalecgos_DragonGUID(0), + m_uiKalecgos_HumanGUID(0), + m_uiSathrovarrGUID(0), + m_uiBrutallusGUID(0), + m_uiFelmystGUID(0), + m_uiAlythessGUID(0), + m_uiSacrolashGUID(0), + m_uiMuruGUID(0), + m_uiKilJaedenGUID(0), + m_uiKilJaedenControllerGUID(0), + m_uiAnveenaGUID(0), + m_uiKalecgosGUID(0), // GameObjects - uint64 m_uiForceFieldGUID; // Kalecgos Encounter - uint64 m_uiBossCollision1GUID; - uint64 m_uiBossCollision2GUID; - uint64 m_uiIceBarrierGUID; // Brutallus Encounter - uint64 m_uiDoorFireBarrierGUID; - uint64 m_uiDoorTheFirstGateGUID; // Felmyst Encounter - uint64 m_uiDoorTheSecondGateGUID; // Alythess Encounter - uint64 m_uiDoorRaid_Gate_07GUID; // Sacrolash Encounter - uint64 m_uiDoorRaid_Gate_08GUID; // Muru Encounter - uint64 m_uiDoorTheThirdGateGUID; // Entropius Encounter - + m_uiForceFieldGUID(0), + m_uiBossCollision1GUID(0), + m_uiBossCollision2GUID(0), + m_uiIceBarrierGUID(0), + m_uiDoorFireBarrierGUID(0), + m_uiDoorTheFirstGateGUID(0), + m_uiDoorTheSecondGateGUID(0), + m_uiDoorMuruEnterGateGUID(0), + m_uiDoorMuruExitGateGUID(0), + m_uiDoorTheThirdGateGUID(0), // Misc - uint32 m_uiSpectralRealmTimer; - std::list SpectralRealmList; + m_uiSpectralRealmTimer(5000) +{ + Initialize(); +} - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - // Creatures - m_uiKalecgos_DragonGUID = 0; - m_uiKalecgos_HumanGUID = 0; - m_uiSathrovarrGUID = 0; - m_uiBrutallusGUID = 0; - m_uiFelmystGUID = 0; - m_uiAlythessGUID = 0; - m_uiSacrolashGUID = 0; - m_uiMuruGUID = 0; - m_uiKilJaedenGUID = 0; - m_uiKilJaedenControllerGUID = 0; - m_uiAnveenaGUID = 0; - m_uiKalecgosGUID = 0; - - // GameObjects - m_uiForceFieldGUID = 0; - m_uiBossCollision1GUID = 0; - m_uiBossCollision2GUID = 0; - m_uiIceBarrierGUID = 0; - m_uiDoorFireBarrierGUID = 0; - m_uiDoorTheFirstGateGUID = 0; - m_uiDoorTheSecondGateGUID = 0; - m_uiDoorRaid_Gate_07GUID = 0; - m_uiDoorRaid_Gate_08GUID = 0; - m_uiDoorTheThirdGateGUID = 0; - - // Misc - m_uiSpectralRealmTimer = 5000; - } +void instance_sunwell_plateau::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - bool IsEncounterInProgress() const +bool instance_sunwell_plateau::IsEncounterInProgress() const +{ + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) { - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; - - return false; + if (m_auiEncounter[i] == IN_PROGRESS) + return true; } - void OnCreatureCreate(Creature* pCreature) - { - switch(pCreature->GetEntry()) - { - case 24850: m_uiKalecgos_DragonGUID = pCreature->GetGUID(); break; - case 24891: m_uiKalecgos_HumanGUID = pCreature->GetGUID(); break; - case 24892: m_uiSathrovarrGUID = pCreature->GetGUID(); break; - case 24882: m_uiBrutallusGUID = pCreature->GetGUID(); break; - case 25038: m_uiFelmystGUID = pCreature->GetGUID(); break; - case 25166: m_uiAlythessGUID = pCreature->GetGUID(); break; - case 25165: m_uiSacrolashGUID = pCreature->GetGUID(); break; - case 25741: m_uiMuruGUID = pCreature->GetGUID(); break; - case 25315: m_uiKilJaedenGUID = pCreature->GetGUID(); break; - case 25608: m_uiKilJaedenControllerGUID = pCreature->GetGUID(); break; - case 26046: m_uiAnveenaGUID = pCreature->GetGUID(); break; - case 25319: m_uiKalecgosGUID = pCreature->GetGUID(); break; - } - } + return false; +} - void OnObjectCreate(GameObject* pGo) +void instance_sunwell_plateau::OnCreatureCreate(Creature* pCreature) +{ + switch(pCreature->GetEntry()) { - switch(pGo->GetEntry()) - { - case 188421: - m_uiForceFieldGUID = pGo->GetGUID(); - break; - case 188523: - m_uiBossCollision1GUID = pGo->GetGUID(); - break; - case 188524: - m_uiBossCollision2GUID = pGo->GetGUID(); - break; - case 188119: - m_uiIceBarrierGUID = pGo->GetGUID(); - break; - case 188075: - m_uiDoorFireBarrierGUID = pGo->GetGUID(); - if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 187766: - m_uiDoorTheFirstGateGUID = pGo->GetGUID(); - break; - case 187764: - m_uiDoorTheSecondGateGUID = pGo->GetGUID(); - if (m_auiEncounter[3] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 187990: - m_uiDoorRaid_Gate_07GUID = pGo->GetGUID(); - if (m_auiEncounter[3] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 188118: - m_uiDoorRaid_Gate_08GUID = pGo->GetGUID(); - if (m_auiEncounter[4] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 187765: - m_uiDoorTheThirdGateGUID = pGo->GetGUID(); - if (m_auiEncounter[4] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - } + case NPC_KALECGOS_DRAGON: m_uiKalecgos_DragonGUID = pCreature->GetGUID(); break; + case NPC_KALECGOS_HUMAN: m_uiKalecgos_HumanGUID = pCreature->GetGUID(); break; + case NPC_SATHROVARR: m_uiSathrovarrGUID = pCreature->GetGUID(); break; + case NPC_BRUTALLUS: m_uiBrutallusGUID = pCreature->GetGUID(); break; + case NPC_FELMYST: m_uiFelmystGUID = pCreature->GetGUID(); break; + case NPC_ALYTHESS: m_uiAlythessGUID = pCreature->GetGUID(); break; + case NPC_SACROLASH: m_uiSacrolashGUID = pCreature->GetGUID(); break; + case NPC_MURU: m_uiMuruGUID = pCreature->GetGUID(); break; + case NPC_KILJAEDEN: m_uiKilJaedenGUID = pCreature->GetGUID(); break; + case NPC_KILJAEDEN_CONTROLLER: m_uiKilJaedenControllerGUID = pCreature->GetGUID(); break; + case NPC_ANVEENA: m_uiAnveenaGUID = pCreature->GetGUID(); break; + case NPC_KALECGOS: m_uiKalecgosGUID = pCreature->GetGUID(); break; } +} - uint32 GetData(uint32 uiType) +void instance_sunwell_plateau::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) { - switch(uiType) - { - case TYPE_KALECGOS: return m_auiEncounter[0]; - case TYPE_BRUTALLUS: return m_auiEncounter[1]; - case TYPE_FELMYST: return m_auiEncounter[2]; - case TYPE_EREDAR_TWINS: return m_auiEncounter[3]; - case TYPE_MURU: return m_auiEncounter[4]; - case TYPE_KILJAEDEN: return m_auiEncounter[5]; - } - - return 0; + case GO_FORCEFIELD: + m_uiForceFieldGUID = pGo->GetGUID(); + break; + case GO_BOSS_COLLISION_1: + m_uiBossCollision1GUID = pGo->GetGUID(); + break; + case GO_BOSS_COLLISION_2: + m_uiBossCollision2GUID = pGo->GetGUID(); + break; + case GO_ICE_BARRIER: + m_uiIceBarrierGUID = pGo->GetGUID(); + break; + case GO_FIRE_BARRIER: + m_uiDoorFireBarrierGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_KALECGOS] == DONE && m_auiEncounter[TYPE_BRUTALLUS] == DONE && m_auiEncounter[TYPE_FELMYST] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_FIRST_GATE: + m_uiDoorTheFirstGateGUID = pGo->GetGUID(); + break; + case GO_SECOND_GATE: + m_uiDoorTheSecondGateGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_EREDAR_TWINS] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_MURU_ENTER_GATE: + m_uiDoorMuruEnterGateGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_EREDAR_TWINS] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_MURU_EXIT_GATE: + m_uiDoorMuruExitGateGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_MURU] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_THIRD_GATE: + m_uiDoorTheThirdGateGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_MURU] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; } +} - uint64 GetData64(uint32 id) +void instance_sunwell_plateau::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - switch(id) - { - case DATA_KALECGOS_DRAGON: return m_uiKalecgos_DragonGUID; - case DATA_KALECGOS_HUMAN: return m_uiKalecgos_HumanGUID; - case DATA_SATHROVARR: return m_uiSathrovarrGUID; - case DATA_BRUTALLUS: return m_uiBrutallusGUID; - case DATA_FELMYST: return m_uiFelmystGUID; - case DATA_ALYTHESS: return m_uiAlythessGUID; - case DATA_SACROLASH: return m_uiSacrolashGUID; - case DATA_MURU: return m_uiMuruGUID; - case DATA_KILJAEDEN: return m_uiKilJaedenGUID; - case DATA_KILJAEDEN_CONTROLLER: return m_uiKilJaedenControllerGUID; - case DATA_ANVEENA: return m_uiAnveenaGUID; - case DATA_KALECGOS: return m_uiKalecgosGUID; - case DATA_GO_FORCEFIELD: return m_uiForceFieldGUID; - } - return 0; + case TYPE_KALECGOS: + m_auiEncounter[uiType] = uiData; + // combat doors + DoUseDoorOrButton(m_uiForceFieldGUID); + DoUseDoorOrButton(m_uiBossCollision1GUID); + DoUseDoorOrButton(m_uiBossCollision2GUID); + if (uiData == IN_PROGRESS) + SpectralRealmList.clear(); + break; + case TYPE_BRUTALLUS: + m_auiEncounter[uiType] = uiData; + if (uiData == SPECIAL) + DoUseDoorOrButton(m_uiIceBarrierGUID,MINUTE); + break; + case TYPE_FELMYST: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiDoorFireBarrierGUID); + break; + case TYPE_EREDAR_TWINS: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiDoorTheSecondGateGUID); + DoUseDoorOrButton(m_uiDoorMuruEnterGateGUID); + } + break; + case TYPE_MURU: + m_auiEncounter[uiType] = uiData; + // combat door + DoUseDoorOrButton(m_uiDoorMuruEnterGateGUID); + if (uiData == DONE) + { + DoUseDoorOrButton(m_uiDoorMuruExitGateGUID); + DoUseDoorOrButton(m_uiDoorTheThirdGateGUID); + } + break; + case TYPE_KILJAEDEN: + m_auiEncounter[uiType] = uiData; + break; + case DATA_SET_SPECTRAL_CHECK: + m_uiSpectralRealmTimer = uiData; + break; } - void SetData(uint32 uiType, uint32 uiData) + if (uiData == DONE) { - switch(uiType) - { - case TYPE_KALECGOS: - if (uiData == IN_PROGRESS) - SpectralRealmList.clear(); - - DoUseDoorOrButton(m_uiForceFieldGUID); - DoUseDoorOrButton(m_uiBossCollision1GUID); - DoUseDoorOrButton(m_uiBossCollision2GUID); - - m_auiEncounter[0] = uiData; - break; - case TYPE_BRUTALLUS: - if (uiData == SPECIAL) - DoUseDoorOrButton(m_uiIceBarrierGUID,MINUTE); - - m_auiEncounter[1] = uiData; - break; - case TYPE_FELMYST: - m_auiEncounter[2] = uiData; - if (uiData == DONE) - DoUseDoorOrButton(m_uiDoorFireBarrierGUID); - break; - case TYPE_EREDAR_TWINS: - m_auiEncounter[3] = uiData; - if (uiData == DONE) - { - DoUseDoorOrButton(m_uiDoorTheSecondGateGUID); - DoUseDoorOrButton(m_uiDoorRaid_Gate_07GUID); - } - break; - case TYPE_MURU: - m_auiEncounter[4] = uiData; - if (uiData == DONE) - DoUseDoorOrButton(m_uiDoorRaid_Gate_08GUID); - break; - case TYPE_KILJAEDEN: m_auiEncounter[5] = uiData; break; - case DATA_SET_SPECTRAL_CHECK: m_uiSpectralRealmTimer = uiData; break; - } - - if (uiData == DONE) - { - OUT_SAVE_INST_DATA; + 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]; + std::ostringstream saveStream; + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " + << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5]; - strInstData = saveStream.str(); + strInstData = saveStream.str(); - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} + +void instance_sunwell_plateau::SetData64(uint32 uiType, uint64 uiData) +{ + if (uiType == DATA_PLAYER_SPECTRAL_REALM) + SpectralRealmList.push_back(uiData); +} + +uint32 instance_sunwell_plateau::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; - const char* Save() + return 0; +} + +uint64 instance_sunwell_plateau::GetData64(uint32 uiType) +{ + switch(uiType) { - return strInstData.c_str(); + case NPC_KALECGOS_DRAGON: return m_uiKalecgos_DragonGUID; + case NPC_KALECGOS_HUMAN: return m_uiKalecgos_HumanGUID; + case NPC_SATHROVARR: return m_uiSathrovarrGUID; + case NPC_BRUTALLUS: return m_uiBrutallusGUID; + case NPC_FELMYST: return m_uiFelmystGUID; + case NPC_ALYTHESS: return m_uiAlythessGUID; + case NPC_SACROLASH: return m_uiSacrolashGUID; + case NPC_MURU: return m_uiMuruGUID; + case NPC_KILJAEDEN: return m_uiKilJaedenGUID; + case NPC_KILJAEDEN_CONTROLLER: return m_uiKilJaedenControllerGUID; + case NPC_ANVEENA: return m_uiAnveenaGUID; + case NPC_KALECGOS: return m_uiKalecgosGUID; + case GO_FORCEFIELD: return m_uiForceFieldGUID; } - void SetData64(uint32 uiData, uint64 uiGuid) + return 0; +} + +void instance_sunwell_plateau::EjectPlayer(Player* pPlayer) +{ + debug_log("SD2: Ejecting Player %s from Spectral Realm", pPlayer->GetName()); + + // Put player back in Kalecgos(Dragon)'s threat list + /*if (Creature* pKalecgos = instance->GetCreature(m_uiKalecgos_DragonGUID)) { - if (uiData == DATA_PLAYER_SPECTRAL_REALM) - SpectralRealmList.push_back(uiGuid); + if (pKalecgos->isAlive()) + { + debug_log("SD2: Adding %s in Kalecgos' threatlist", pPlayer->GetName()); + pKalecgos->AddThreat(pPlayer); + } } - void EjectPlayer(Player* pPlayer) + // Remove player from Sathrovarr's threat list + if (Creature* pSath = instance->GetCreature(m_uiSathrovarrGUID)) { - debug_log("SD2: Ejecting Player %s from Spectral Realm", pPlayer->GetName()); - - // Put player back in Kalecgos(Dragon)'s threat list - /*if (Creature* pKalecgos = instance->GetCreature(m_uiKalecgos_DragonGUID)) + if (pSath->isAlive()) { - if (pKalecgos->isAlive()) + if (HostileReference* pRef = pSath->getThreatManager().getOnlineContainer().getReferenceByTarget(pPlayer)) { - debug_log("SD2: Adding %s in Kalecgos' threatlist", pPlayer->GetName()); - pKalecgos->AddThreat(pPlayer); + pRef->removeReference(); + debug_log("SD2: Deleting %s from Sathrovarr's threatlist", pPlayer->GetName()); } } + }*/ - // Remove player from Sathrovarr's threat list - if (Creature* pSath = instance->GetCreature(m_uiSathrovarrGUID)) - { - if (pSath->isAlive()) - { - if (HostileReference* pRef = pSath->getThreatManager().getOnlineContainer().getReferenceByTarget(pPlayer)) - { - pRef->removeReference(); - debug_log("SD2: Deleting %s from Sathrovarr's threatlist", pPlayer->GetName()); - } - } - }*/ + pPlayer->CastSpell(pPlayer, SPELL_SPECTRAL_EXHAUSTION, true); + pPlayer->CastSpell(pPlayer, SPELL_TELEPORT_NORMAL_REALM, true); +} - pPlayer->CastSpell(pPlayer, SPELL_TELEPORT_NORMAL_REALM, true); - pPlayer->CastSpell(pPlayer, SPELL_SPECTRAL_EXHAUSTION, true); - } +void instance_sunwell_plateau::EjectPlayers() +{ + if (SpectralRealmList.empty()) + return; - void EjectPlayers() - { - if (SpectralRealmList.empty()) - return; + Map::PlayerList const& players = instance->GetPlayers(); - Map::PlayerList const& players = instance->GetPlayers(); + for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + Player* plr = itr->getSource(); - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (plr && !plr->HasAura(SPELL_SPECTRAL_REALM)) { - Player* plr = itr->getSource(); - - if (plr && !plr->HasAura(SPELL_SPECTRAL_REALM)) - { - SpectralRealmList.remove(plr->GetGUID()); - EjectPlayer(plr); - } + SpectralRealmList.remove(plr->GetGUID()); + EjectPlayer(plr); } - - //SpectralRealmList.clear(); } - void Update(uint32 uiDiff) + //SpectralRealmList.clear(); +} + +void instance_sunwell_plateau::Update(uint32 uiDiff) +{ + // Only check for Spectral Realm if Kalecgos Encounter is running + if (m_auiEncounter[TYPE_KALECGOS] == IN_PROGRESS) { - // Only check for Spectral Realm if Kalecgos Encounter is running - if (m_auiEncounter[0] == IN_PROGRESS) + if (m_uiSpectralRealmTimer <= uiDiff) { - if (m_uiSpectralRealmTimer <= uiDiff) - { - EjectPlayers(); - m_uiSpectralRealmTimer = 1000; - } - else - m_uiSpectralRealmTimer -= uiDiff; + EjectPlayers(); + m_uiSpectralRealmTimer = 1000; } + else + m_uiSpectralRealmTimer -= uiDiff; } +} - void Load(const char* in) +void instance_sunwell_plateau::Load(const char* in) +{ + if (!in) { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); + OUT_LOAD_INST_DATA_FAIL; + return; + } - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> - m_auiEncounter[3] >> m_auiEncounter[4] >> m_auiEncounter[5]; + OUT_LOAD_INST_DATA(in); - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } + std::istringstream loadStream(in); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> + m_auiEncounter[3] >> m_auiEncounter[4] >> m_auiEncounter[5]; - OUT_LOAD_INST_DATA_COMPLETE; + 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_sunwell_plateau(Map* pMap) { @@ -369,9 +343,10 @@ InstanceData* GetInstanceData_instance_sunwell_plateau(Map* pMap) void AddSC_instance_sunwell_plateau() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_sunwell_plateau"; - newscript->GetInstanceData = &GetInstanceData_instance_sunwell_plateau; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_sunwell_plateau"; + pNewScript->GetInstanceData = &GetInstanceData_instance_sunwell_plateau; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h b/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h index a71dea42f..5b69afa96 100644 --- a/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h +++ b/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h @@ -1,11 +1,11 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ #ifndef DEF_SUNWELLPLATEAU_H #define DEF_SUNWELLPLATEAU_H -enum InstanceSWP +enum { MAX_ENCOUNTER = 6, @@ -16,34 +16,98 @@ enum InstanceSWP TYPE_MURU = 4, TYPE_KILJAEDEN = 5, - DATA_KALECGOS_DRAGON = 6, - DATA_KALECGOS_HUMAN = 7, - DATA_SATHROVARR = 8, - DATA_BRUTALLUS = 9, - DATA_FELMYST = 10, - DATA_ALYTHESS = 11, - DATA_SACROLASH = 12, - DATA_MURU = 13, - DATA_KILJAEDEN = 14, - DATA_KILJAEDEN_CONTROLLER = 15, - DATA_ANVEENA = 16, - DATA_KALECGOS = 17, - - DATA_GO_FORCEFIELD = 18, - DATA_GO_FIRE_BARRIER = 19, - DATA_GO_FIRST_GATE = 20, - DATA_GO_SECOND_GATE = 21, - DATA_GO_RAID_GATE_07 = 22, - DATA_GO_RAID_GATE_08 = 23, - DATA_GO_THIRD_GATE = 24, - - DATA_PLAYER_SPECTRAL_REALM = 25, - DATA_SET_SPECTRAL_CHECK = 26, + DATA_PLAYER_SPECTRAL_REALM = 6, + DATA_SET_SPECTRAL_CHECK = 7, + NPC_KALECGOS_DRAGON = 24850, // kalecgos blue dragon hostile + NPC_KALECGOS_HUMAN = 24891, // kalecgos human form in spectral realm + NPC_SATHROVARR = 24892, + NPC_BRUTALLUS = 24882, + NPC_FELMYST = 25038, + NPC_ALYTHESS = 25166, + NPC_SACROLASH = 25165, + NPC_MURU = 25741, + NPC_KILJAEDEN = 25315, + NPC_KILJAEDEN_CONTROLLER = 25608, // kiljaeden event controller + NPC_ANVEENA = 26046, // related to kiljaeden event + NPC_KALECGOS = 25319, // related to kiljaeden event + + GO_FORCEFIELD = 188421, // kalecgos door + collisions + GO_BOSS_COLLISION_1 = 188523, + GO_BOSS_COLLISION_2 = 188524, + GO_ICE_BARRIER = 188119, // use unk; related to brutallus intro + GO_FIRE_BARRIER = 188075, // door after felmyst + GO_FIRST_GATE = 187766, // door between felmyst and eredar twins + GO_SECOND_GATE = 187764, // door after eredar twins + GO_MURU_ENTER_GATE = 187990, // muru gates + GO_MURU_EXIT_GATE = 188118, + GO_THIRD_GATE = 187765, // door after muru; why another? + + // spells related to kalecgos event SPELL_SPECTRAL_REALM = 46021, SPELL_TELEPORT_NORMAL_REALM = 46020, SPELL_TELEPORT_TO_SPECTRAL_REALM = 46019, SPELL_SPECTRAL_EXHAUSTION = 44867, SPELL_SPECTRAL_REALM_FORCE_FACTION = 44852 }; + +class MANGOS_DLL_DECL instance_sunwell_plateau : public ScriptedInstance +{ + public: + instance_sunwell_plateau(Map* pMap); + ~instance_sunwell_plateau() {} + + void Initialize(); + bool IsEncounterInProgress() const; + + void OnObjectCreate(GameObject* pGo); + void OnCreatureCreate(Creature* pCreature); + + void SetData(uint32 uiType, uint32 uiData); + void SetData64(uint32 uiType, uint64 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiType); + + void Update(uint32 uiDiff); + + const char* Save() { return strInstData.c_str(); } + void Load(const char* chrIn); + + protected: + void EjectPlayer(Player* pPlayer); + void EjectPlayers(); + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string strInstData; + + // Creatures + uint64 m_uiKalecgos_DragonGUID; + uint64 m_uiKalecgos_HumanGUID; + uint64 m_uiSathrovarrGUID; + uint64 m_uiBrutallusGUID; + uint64 m_uiFelmystGUID; + uint64 m_uiAlythessGUID; + uint64 m_uiSacrolashGUID; + uint64 m_uiMuruGUID; + uint64 m_uiKilJaedenGUID; + uint64 m_uiKilJaedenControllerGUID; + uint64 m_uiAnveenaGUID; + uint64 m_uiKalecgosGUID; + + // GameObjects + uint64 m_uiForceFieldGUID; + uint64 m_uiBossCollision1GUID; + uint64 m_uiBossCollision2GUID; + uint64 m_uiIceBarrierGUID; + uint64 m_uiDoorFireBarrierGUID; + uint64 m_uiDoorTheFirstGateGUID; + uint64 m_uiDoorTheSecondGateGUID; + uint64 m_uiDoorMuruEnterGateGUID; + uint64 m_uiDoorMuruExitGateGUID; + uint64 m_uiDoorTheThirdGateGUID; + + // Misc + uint32 m_uiSpectralRealmTimer; + std::list SpectralRealmList; +}; #endif diff --git a/scripts/eastern_kingdoms/swamp_of_sorrows.cpp b/scripts/eastern_kingdoms/swamp_of_sorrows.cpp index 29e109496..dc7649cf1 100644 --- a/scripts/eastern_kingdoms/swamp_of_sorrows.cpp +++ b/scripts/eastern_kingdoms/swamp_of_sorrows.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -160,6 +160,6 @@ void AddSC_swamp_of_sorrows() newscript = new Script; newscript->Name = "npc_galen_goodward"; newscript->GetAI = &GetAI_npc_galen_goodward; - newscript->pQuestAccept = &QuestAccept_npc_galen_goodward; + newscript->pQuestAcceptNPC = &QuestAccept_npc_galen_goodward; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/tirisfal_glades.cpp b/scripts/eastern_kingdoms/tirisfal_glades.cpp index b924039d4..0502a20eb 100644 --- a/scripts/eastern_kingdoms/tirisfal_glades.cpp +++ b/scripts/eastern_kingdoms/tirisfal_glades.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -42,7 +42,7 @@ enum GO_DOOR = 176594 }; -bool GOHello_go_mausoleum_door(Player* pPlayer, GameObject* pGo) +bool GOUse_go_mausoleum_door(Player* pPlayer, GameObject* pGo) { if (pPlayer->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) return false; @@ -57,7 +57,7 @@ bool GOHello_go_mausoleum_door(Player* pPlayer, GameObject* pGo) return false; } -bool GOHello_go_mausoleum_trigger(Player* pPlayer, GameObject* pGo) +bool GOUse_go_mausoleum_trigger(Player* pPlayer, GameObject* pGo) { if (pPlayer->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) return false; @@ -192,17 +192,17 @@ void AddSC_tirisfal_glades() newscript = new Script; newscript->Name = "go_mausoleum_door"; - newscript->pGOHello = &GOHello_go_mausoleum_door; + newscript->pGOUse = &GOUse_go_mausoleum_door; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "go_mausoleum_trigger"; - newscript->pGOHello = &GOHello_go_mausoleum_trigger; + newscript->pGOUse = &GOUse_go_mausoleum_trigger; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_calvin_montague"; newscript->GetAI = &GetAI_npc_calvin_montague; - newscript->pQuestAccept = &QuestAccept_npc_calvin_montague; + newscript->pQuestAcceptNPC = &QuestAccept_npc_calvin_montague; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp b/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp index 80d0f8f08..7e2f9cf26 100644 --- a/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp +++ b/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -42,7 +42,7 @@ enum struct MANGOS_DLL_DECL boss_archaedasAI : public ScriptedAI { - boss_archaedasAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_archaedasAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (instance_uldaman*)pCreature->GetInstanceData(); Reset(); diff --git a/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp b/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp index de4a75808..0e50a6f72 100644 --- a/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp +++ b/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/uldaman/uldaman.cpp b/scripts/eastern_kingdoms/uldaman/uldaman.cpp index 7cf9786b5..666c092e1 100644 --- a/scripts/eastern_kingdoms/uldaman/uldaman.cpp +++ b/scripts/eastern_kingdoms/uldaman/uldaman.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/uldaman/uldaman.h b/scripts/eastern_kingdoms/uldaman/uldaman.h index d89594552..1065bf13e 100644 --- a/scripts/eastern_kingdoms/uldaman/uldaman.h +++ b/scripts/eastern_kingdoms/uldaman/uldaman.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/eastern_kingdoms/undercity.cpp b/scripts/eastern_kingdoms/undercity.cpp index 3b457a8b0..e09360d5c 100644 --- a/scripts/eastern_kingdoms/undercity.cpp +++ b/scripts/eastern_kingdoms/undercity.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -125,7 +125,7 @@ CreatureAI* GetAI_npc_lady_sylvanas_windrunner(Creature* pCreature) return new npc_lady_sylvanas_windrunnerAI(pCreature); } -bool ChooseReward_npc_lady_sylvanas_windrunner(Player* pPlayer, Creature* pCreature, const Quest* pQuest, uint32 slot) +bool QuestRewarded_npc_lady_sylvanas_windrunner(Player* pPlayer, Creature* pCreature, Quest const* pQuest) { if (pQuest->GetQuestId() == 9180) { @@ -242,7 +242,7 @@ void AddSC_undercity() newscript = new Script; newscript->Name = "npc_lady_sylvanas_windrunner"; newscript->GetAI = &GetAI_npc_lady_sylvanas_windrunner; - newscript->pChooseReward = &ChooseReward_npc_lady_sylvanas_windrunner; + newscript->pQuestRewardedNPC = &QuestRewarded_npc_lady_sylvanas_windrunner; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/eastern_kingdoms/western_plaguelands.cpp b/scripts/eastern_kingdoms/western_plaguelands.cpp index bc5f1c2a4..dcaf3df34 100644 --- a/scripts/eastern_kingdoms/western_plaguelands.cpp +++ b/scripts/eastern_kingdoms/western_plaguelands.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/westfall.cpp b/scripts/eastern_kingdoms/westfall.cpp index b65dcab65..eeb91c96c 100644 --- a/scripts/eastern_kingdoms/westfall.cpp +++ b/scripts/eastern_kingdoms/westfall.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -153,7 +153,7 @@ struct MANGOS_DLL_DECL npc_daphne_stilwellAI : public npc_escortAI { m_uiShootTimer = 1000; - if (!m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DISTANCE)) + if (!m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOOT); } @@ -255,12 +255,12 @@ void AddSC_westfall() pNewScript = new Script; pNewScript->Name = "npc_daphne_stilwell"; pNewScript->GetAI = &GetAI_npc_daphne_stilwell; - pNewScript->pQuestAccept = &QuestAccept_npc_daphne_stilwell; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_daphne_stilwell; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_defias_traitor"; pNewScript->GetAI = &GetAI_npc_defias_traitor; - pNewScript->pQuestAccept = &QuestAccept_npc_defias_traitor; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_defias_traitor; pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/wetlands.cpp b/scripts/eastern_kingdoms/wetlands.cpp index 8bbc8c89b..b42f13756 100644 --- a/scripts/eastern_kingdoms/wetlands.cpp +++ b/scripts/eastern_kingdoms/wetlands.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -162,6 +162,6 @@ void AddSC_wetlands() newscript = new Script; newscript->Name = "npc_mikhail"; - newscript->pQuestAccept = &QuestAccept_npc_mikhail; + newscript->pQuestAcceptNPC = &QuestAccept_npc_mikhail; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp b/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp index 20b3ca5bc..e2ad79068 100644 --- a/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp +++ b/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -89,7 +89,6 @@ struct MANGOS_DLL_DECL boss_akilzonAI : public ScriptedAI void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); } void KilledUnit(Unit* pVictim) diff --git a/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp b/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp index f4c9b4afe..dec0090d3 100644 --- a/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp +++ b/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -120,7 +120,6 @@ struct MANGOS_DLL_DECL boss_halazziAI : public ScriptedAI void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); if (m_pInstance) m_pInstance->SetData(TYPE_HALAZZI, IN_PROGRESS); diff --git a/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp b/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp index 648e2096f..e9cbf56a9 100644 --- a/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp +++ b/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -147,7 +147,7 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 fire_breath_timer; + uint32 m_uiFireBreathTimer; std::list m_lBombsGUIDList; std::list m_lEggsRemainingList; @@ -157,16 +157,16 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI uint32 m_uiBombPhase; uint32 m_uiBombCounter; - uint32 enrage_timer; - uint32 hatchertime; + uint32 m_uiEnrageTimer; + uint32 m_uiHatcherTimer; uint32 eggs; - uint32 wipetimer; + uint32 m_uiWipeTimer; bool m_bIsBombing; bool m_bCanBlowUpBombs; bool m_bIsEggRemaining; - bool enraged; - bool enragetime; + bool m_bIsEnraged; + bool m_bCanEnrage; uint64 m_uiHatcher1GUID; uint64 m_uiHatcher2GUID; @@ -190,7 +190,7 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI m_uiHatcher2GUID = 0; } - fire_breath_timer = 8000; + m_uiFireBreathTimer = 8000; m_uiBombTimer = 30000; m_bIsBombing = false; @@ -200,11 +200,11 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI m_bCanBlowUpBombs = false; m_bIsEggRemaining = true; - enrage_timer = MINUTE*5*IN_MILLISECONDS; - hatchertime = 10000; - wipetimer = MINUTE*10*IN_MILLISECONDS; - enraged = false; - enragetime = false; + m_uiEnrageTimer = MINUTE*5*IN_MILLISECONDS; + m_uiHatcherTimer = 10000; + m_uiWipeTimer = MINUTE*10*IN_MILLISECONDS; + m_bIsEnraged = false; + m_bCanEnrage = false; } void JustReachedHome() @@ -317,10 +317,11 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI //Teleport every player into the middle if more than 20 yards away (possibly what spell 43096 should do) void TeleportPlayersOutOfRange() { - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - Unit* pTemp = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pTemp = m_creature->GetMap()->GetUnit(*i); if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && !m_creature->IsWithinDist(pTemp, 20.0f)) m_creature->CastSpell(pTemp, SPELL_SUMMONALL, true); @@ -376,7 +377,7 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI } } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; @@ -384,20 +385,19 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI //blow up bombs happen after bombing is over, so handle this here if (m_bCanBlowUpBombs) { - if (m_uiBombSequenzeTimer < diff) + if (m_uiBombSequenzeTimer < uiDiff) { BlowUpBombs(); m_bCanBlowUpBombs = false; - }else m_uiBombSequenzeTimer -= diff; + } + else + m_uiBombSequenzeTimer -= uiDiff; } if (!m_bIsBombing) // every Spell if NOT Bombing { - if (m_uiBombTimer < diff) + if (m_uiBombTimer < uiDiff) { - if (m_creature->IsNonMeleeSpellCasted(false)) - m_creature->InterruptNonMeleeSpells(false); - DoScriptText(SAY_FIRE_BOMBS, m_creature); //first clear movement @@ -405,7 +405,7 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI m_creature->GetMotionMaster()->MovementExpired(); //then teleport self - DoCastSpellIfCan(m_creature, SPELL_TELETOCENTER, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_TELETOCENTER, CAST_INTERRUPT_PREVIOUS | CAST_TRIGGERED); //then players and create the firewall TeleportPlayersOutOfRange(); @@ -423,31 +423,32 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI //we don't want anything else to happen this Update() return; - }else m_uiBombTimer -=diff; + } + else + m_uiBombTimer -= uiDiff; //FIRE BREATH several videos says every 8Secounds - if (fire_breath_timer < diff) + if (m_uiFireBreathTimer < uiDiff) { if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) DoCastSpellIfCan(target,SPELL_FLAME_BREATH); - fire_breath_timer = 8000; - }else fire_breath_timer -=diff; + m_uiFireBreathTimer = 8000; + }else m_uiFireBreathTimer -= uiDiff; //enrage if under 25% hp before 5 min. - if (m_creature->GetHealthPercent() < 25.0f && !enraged) + if (m_creature->GetHealthPercent() < 25.0f && !m_bIsEnraged) { - enragetime = true; - enrage_timer = 600000; + m_bCanEnrage = true; + m_uiEnrageTimer = 600000; } //Enrage but only if not bombing - if (enragetime && !enraged) + if (m_bCanEnrage && !m_bIsEnraged) { DoScriptText(SAY_BERSERK, m_creature); - m_creature->InterruptNonMeleeSpells(false); - DoCastSpellIfCan(m_creature,SPELL_ENRAGE); - enraged = true; + DoCastSpellIfCan(m_creature, SPELL_ENRAGE, CAST_INTERRUPT_PREVIOUS); + m_bIsEnraged = true; } //Hatch All @@ -455,10 +456,7 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI { DoScriptText(SAY_ALL_EGGS, m_creature); - if (m_creature->IsNonMeleeSpellCasted(false)) - m_creature->InterruptNonMeleeSpells(false); - - DoCastSpellIfCan(m_creature, SPELL_HATCH_ALL_EGGS); + DoCastSpellIfCan(m_creature, SPELL_HATCH_ALL_EGGS, CAST_INTERRUPT_PREVIOUS); DoHatchRemainingEggs(); } @@ -467,12 +465,12 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI } else // every Spell if Bombing { - if (m_uiBombSequenzeTimer < diff) + if (m_uiBombSequenzeTimer < uiDiff) { switch(m_uiBombPhase) { case 0: - m_creature->CastSpell(m_creature,SPELL_FIRE_BOMB_CHANNEL,true); + DoCastSpellIfCan(m_creature, SPELL_FIRE_BOMB_CHANNEL, CAST_TRIGGERED); m_uiBombSequenzeTimer = 500; ++m_uiBombPhase; break; @@ -497,20 +495,24 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI break; } - }else m_uiBombSequenzeTimer -= diff; + } + else + m_uiBombSequenzeTimer -= uiDiff; } //Enrage after 5 minutes - if (enrage_timer < diff) + if (m_uiEnrageTimer < uiDiff) { - enragetime = true; - enrage_timer = 600000; - }else enrage_timer -=diff; + m_bCanEnrage = true; + m_uiEnrageTimer = 600000; + } + else + m_uiEnrageTimer -= uiDiff; //Call Hatcher if (m_bIsEggRemaining) { - if (hatchertime < diff) + if (m_uiHatcherTimer < uiDiff) { if (!m_pInstance || (m_pInstance->GetData(DATA_J_EGGS_LEFT) == 0 && m_pInstance->GetData(DATA_J_EGGS_RIGHT) == 0)) m_bIsEggRemaining = false; @@ -533,24 +535,28 @@ struct MANGOS_DLL_DECL boss_janalaiAI : public ScriptedAI pHatcher->GetMotionMaster()->MovePoint(1, m_aHatcherLeft[1].m_fX, m_aHatcherLeft[1].m_fY, m_aHatcherLeft[1].m_fZ); } - hatchertime = 90000; + m_uiHatcherTimer = 90000; } - }else hatchertime -=diff; + } + else + m_uiHatcherTimer -= uiDiff; } //WIPE after 10 minutes - if (wipetimer < diff) + if (m_uiWipeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature,SPELL_ENRAGE) == CAST_OK) { DoScriptText(SAY_BERSERK, m_creature); - wipetimer = 30000; + m_uiWipeTimer = 30000; } - }else wipetimer -=diff; + } + else + m_uiWipeTimer -= uiDiff; //check for reset ... exploit preventing ... pulled from his podest - EnterEvadeIfOutOfCombatArea(diff); + EnterEvadeIfOutOfCombatArea(uiDiff); } }; @@ -559,27 +565,27 @@ CreatureAI* GetAI_boss_janalaiAI(Creature* pCreature) return new boss_janalaiAI(pCreature); } -struct MANGOS_DLL_DECL mob_jandalai_firebombAI : public ScriptedAI +struct MANGOS_DLL_DECL npc_janalai_firebombAI : public ScriptedAI { - mob_jandalai_firebombAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + npc_janalai_firebombAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} void Reset() {} - void AttackStart(Unit* who) {} + void AttackStart(Unit* pWho) {} - void MoveInLineOfSight(Unit* who) {} + void MoveInLineOfSight(Unit* pWho) {} - void UpdateAI(const uint32 diff) {} + void UpdateAI(const uint32 uiDiff) {} }; -CreatureAI* GetAI_mob_jandalai_firebombAI(Creature* pCreature) +CreatureAI* GetAI_npc_janalai_firebombAI(Creature* pCreature) { - return new mob_jandalai_firebombAI(pCreature); + return new npc_janalai_firebombAI(pCreature); } -struct MANGOS_DLL_DECL mob_amanishi_hatcherAI : public ScriptedAI +struct MANGOS_DLL_DECL npc_amanishi_hatcherAI : public ScriptedAI { - mob_amanishi_hatcherAI(Creature* pCreature) : ScriptedAI(pCreature) + npc_amanishi_hatcherAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); @@ -683,7 +689,7 @@ struct MANGOS_DLL_DECL mob_amanishi_hatcherAI : public ScriptedAI m_creature->ForcedDespawn(); return; } - else if (m_uiHatchlingCount == uiEggsRemaining/2) + else if (m_uiHatchlingCount >= uiEggsRemaining/2) m_uiHatchlingCount = uiEggsRemaining; DoCastSpellIfCan(m_creature,SPELL_HATCH_EGG); @@ -692,19 +698,21 @@ struct MANGOS_DLL_DECL mob_amanishi_hatcherAI : public ScriptedAI ++m_uiHatchlingCount; - }else m_uiHatchlingTimer -= uiDiff; + } + else + m_uiHatchlingTimer -= uiDiff; } } }; -CreatureAI* GetAI_mob_amanishi_hatcherAI(Creature* pCreature) +CreatureAI* GetAI_npc_amanishi_hatcherAI(Creature* pCreature) { - return new mob_amanishi_hatcherAI(pCreature); + return new npc_amanishi_hatcherAI(pCreature); } -struct MANGOS_DLL_DECL mob_hatchlingAI : public ScriptedAI +struct MANGOS_DLL_DECL npc_hatchlingAI : public ScriptedAI { - mob_hatchlingAI(Creature* pCreature) : ScriptedAI(pCreature) + npc_hatchlingAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); @@ -712,24 +720,24 @@ struct MANGOS_DLL_DECL mob_hatchlingAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 buffer_timer; - bool start; + uint32 m_uiBufferTimer; + bool m_bIsStarted; void Reset() { - buffer_timer = 7000; - start = false; + m_uiBufferTimer = 7000; + m_bIsStarted = false; } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { - if (!start) + if (!m_bIsStarted) { if (m_creature->GetPositionY() > 1150) m_creature->GetMotionMaster()->MovePoint(0, hatcherway_l[3][0]+rand()%4-2,hatcherway_l[3][1]+rand()%4-2,hatcherway_l[3][2]); else m_creature->GetMotionMaster()->MovePoint(0,hatcherway_r[3][0]+rand()%4-2,hatcherway_r[3][1]+rand()%4-2,hatcherway_r[3][2]); - start = true; + m_bIsStarted = true; } if (m_pInstance && m_pInstance->GetData(TYPE_JANALAI) == NOT_STARTED) @@ -741,44 +749,46 @@ struct MANGOS_DLL_DECL mob_hatchlingAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (buffer_timer < diff) + if (m_uiBufferTimer < uiDiff) { if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) DoCastSpellIfCan(target,SPELL_FLAMEBUFFED); - buffer_timer = 7000; - }else buffer_timer -=diff; + m_uiBufferTimer = 7000; + } + else + m_uiBufferTimer -= uiDiff; DoMeleeAttackIfReady(); } }; -CreatureAI* GetAI_mob_hatchlingAI(Creature* pCreature) +CreatureAI* GetAI_npc_hatchlingAI(Creature* pCreature) { - return new mob_hatchlingAI(pCreature); + return new npc_hatchlingAI(pCreature); } void AddSC_boss_janalai() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_janalai"; - newscript->GetAI = &GetAI_boss_janalaiAI; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_jandalai_firebomb"; - newscript->GetAI = &GetAI_mob_jandalai_firebombAI; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_amanishi_hatcher"; - newscript->GetAI = &GetAI_mob_amanishi_hatcherAI; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_hatchling"; - newscript->GetAI = &GetAI_mob_hatchlingAI; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_janalai"; + pNewScript->GetAI = &GetAI_boss_janalaiAI; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_janalai_firebomb"; + pNewScript->GetAI = &GetAI_npc_janalai_firebombAI; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_amanishi_hatcher"; + pNewScript->GetAI = &GetAI_npc_amanishi_hatcherAI; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_hatchling"; + pNewScript->GetAI = &GetAI_npc_hatchlingAI; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulaman/boss_malacrass.cpp b/scripts/eastern_kingdoms/zulaman/boss_malacrass.cpp index d1df11ae9..45c437c6d 100644 --- a/scripts/eastern_kingdoms/zulaman/boss_malacrass.cpp +++ b/scripts/eastern_kingdoms/zulaman/boss_malacrass.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -203,8 +203,6 @@ struct MANGOS_DLL_DECL boss_malacrassAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); - DoScriptText(SAY_AGGRO, m_creature); AddsAttack(pWho); diff --git a/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp b/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp index 68548d86e..861119788 100644 --- a/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp +++ b/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp b/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp index 6a4415edf..8b7a30973 100644 --- a/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp +++ b/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp b/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp index f7bbf03c2..f86d744be 100644 --- a/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp +++ b/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulaman/zulaman.cpp b/scripts/eastern_kingdoms/zulaman/zulaman.cpp index 1dbd94c61..7ead77140 100644 --- a/scripts/eastern_kingdoms/zulaman/zulaman.cpp +++ b/scripts/eastern_kingdoms/zulaman/zulaman.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -85,7 +85,7 @@ struct MANGOS_DLL_DECL npc_forest_frogAI : public ScriptedAI if (cEntry == 24408) m_pInstance->SetData(TYPE_RAND_VENDOR_1,DONE); - + if (cEntry == 24409) m_pInstance->SetData(TYPE_RAND_VENDOR_2,DONE); } @@ -198,7 +198,7 @@ bool GossipSelect_npc_harrison_jones_za(Player* pPlayer, Creature* pCreature, ui { if (npc_harrison_jones_zaAI* pHarrisonAI = dynamic_cast(pCreature->AI())) pHarrisonAI->StartEvent(); - + pPlayer->CLOSE_GOSSIP_MENU(); } return true; @@ -214,7 +214,7 @@ CreatureAI* GetAI_npc_harrison_jones_za(Creature* pCreature) ######*/ //Unsure how this Gong must work. Here we always return false to allow Mangos always process further. -bool GOHello_go_strange_gong(Player* pPlayer, GameObject* pGo) +bool GOUse_go_strange_gong(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -257,6 +257,6 @@ void AddSC_zulaman() newscript = new Script; newscript->Name = "go_strange_gong"; - newscript->pGOHello = &GOHello_go_strange_gong; + newscript->pGOUse = &GOUse_go_strange_gong; newscript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulaman/zulaman.h b/scripts/eastern_kingdoms/zulaman/zulaman.h index cc85875f1..3fafc8c95 100644 --- a/scripts/eastern_kingdoms/zulaman/zulaman.h +++ b/scripts/eastern_kingdoms/zulaman/zulaman.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp b/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp index 14cfcf20d..80b2077a3 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,7 +24,7 @@ EndScriptData */ #include "precompiled.h" #include "zulgurub.h" -bool GOHello_go_gong_of_bethekk(Player* pPlayer, GameObject* pGo) +bool GOUse_go_gong_of_bethekk(Player* pPlayer, GameObject* pGo) { if (ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData()) { @@ -279,7 +279,7 @@ void AddSC_boss_arlokk() newscript = new Script; newscript->Name = "go_gong_of_bethekk"; - newscript->pGOHello = &GOHello_go_gong_of_bethekk; + newscript->pGOUse = &GOUse_go_gong_of_bethekk; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp b/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp index 4fe633a8a..9cd78c9cd 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp b/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp index aacb47084..083529baa 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp b/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp index 9e67e3515..c7c473140 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,23 +24,24 @@ EndScriptData */ #include "precompiled.h" #include "zulgurub.h" -#define SAY_AGGRO -1309020 -#define SAY_FLEEING -1309021 -#define SAY_MINION_DESTROY -1309022 //where does it belong? -#define SAY_PROTECT_ALTAR -1309023 //where does it belong? - -#define SPELL_BLOODSIPHON 24322 -#define SPELL_CORRUPTEDBLOOD 24328 -#define SPELL_CAUSEINSANITY 24327 //Not working disabled. -#define SPELL_WILLOFHAKKAR 24178 -#define SPELL_ENRAGE 24318 - -// The Aspects of all High Priests -#define SPELL_ASPECT_OF_JEKLIK 24687 -#define SPELL_ASPECT_OF_VENOXIS 24688 -#define SPELL_ASPECT_OF_MARLI 24686 -#define SPELL_ASPECT_OF_THEKAL 24689 -#define SPELL_ASPECT_OF_ARLOKK 24690 +enum +{ + SAY_AGGRO = -1309020, + SAY_FLEEING = -1309021, + + SPELL_BLOOD_SIPHON = 24324, // Related Spells 24322, 24323, 24324, likely starting spell is 24324 (disabled until proper fixed) + SPELL_CORRUPTED_BLOOD = 24328, + SPELL_CAUSE_INSANITY = 24327, + SPELL_WILL_OF_HAKKAR = 24178, + SPELL_ENRAGE = 24318, + + // The Aspects of all High Priests + SPELL_ASPECT_OF_JEKLIK = 24687, + SPELL_ASPECT_OF_VENOXIS = 24688, + SPELL_ASPECT_OF_MARLI = 24686, + SPELL_ASPECT_OF_THEKAL = 24689, + SPELL_ASPECT_OF_ARLOKK = 24690 +}; struct MANGOS_DLL_DECL boss_hakkarAI : public ScriptedAI { @@ -52,185 +53,178 @@ struct MANGOS_DLL_DECL boss_hakkarAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 BloodSiphon_Timer; - uint32 CorruptedBlood_Timer; - uint32 CauseInsanity_Timer; - uint32 WillOfHakkar_Timer; - uint32 Enrage_Timer; + uint32 m_uiBloodSiphonTimer; + uint32 m_uiCorruptedBloodTimer; + uint32 m_uiCauseInsanityTimer; + uint32 m_uiWillOfHakkarTimer; + uint32 m_uiEnrageTimer; - uint32 CheckJeklik_Timer; - uint32 CheckVenoxis_Timer; - uint32 CheckMarli_Timer; - uint32 CheckThekal_Timer; - uint32 CheckArlokk_Timer; - - uint32 AspectOfJeklik_Timer; - uint32 AspectOfVenoxis_Timer; - uint32 AspectOfMarli_Timer; - uint32 AspectOfThekal_Timer; - uint32 AspectOfArlokk_Timer; - - bool Enraged; + uint32 m_uiAspectOfJeklikTimer; + uint32 m_uiAspectOfVenoxisTimer; + uint32 m_uiAspectOfMarliTimer; + uint32 m_uiAspectOfThekalTimer; + uint32 m_uiAspectOfArlokkTimer; void Reset() { - BloodSiphon_Timer = 90000; - CorruptedBlood_Timer = 25000; - CauseInsanity_Timer = 17000; - WillOfHakkar_Timer = 17000; - Enrage_Timer = 600000; - - CheckJeklik_Timer = 1000; - CheckVenoxis_Timer = 2000; - CheckMarli_Timer = 3000; - CheckThekal_Timer = 4000; - CheckArlokk_Timer = 5000; - - AspectOfJeklik_Timer = 4000; - AspectOfVenoxis_Timer = 7000; - AspectOfMarli_Timer = 12000; - AspectOfThekal_Timer = 8000; - AspectOfArlokk_Timer = 18000; - - Enraged = false; + m_uiBloodSiphonTimer = 90000; + m_uiCorruptedBloodTimer = 25000; + m_uiCauseInsanityTimer = 17000; + m_uiWillOfHakkarTimer = 17000; + m_uiEnrageTimer = 10*MINUTE*IN_MILLISECONDS; + + m_uiAspectOfJeklikTimer = 4000; + m_uiAspectOfVenoxisTimer = 7000; + m_uiAspectOfMarliTimer = 12000; + m_uiAspectOfThekalTimer = 8000; + m_uiAspectOfArlokkTimer = 18000; } void Aggro(Unit *who) { DoScriptText(SAY_AGGRO, m_creature); + + // check if the priest encounters are done + if (m_pInstance) + { + if (m_pInstance->GetData(TYPE_JEKLIK) == DONE) + m_uiAspectOfJeklikTimer = 0; + if (m_pInstance->GetData(TYPE_VENOXIS) == DONE) + m_uiAspectOfVenoxisTimer = 0; + if (m_pInstance->GetData(TYPE_MARLI) == DONE) + m_uiAspectOfMarliTimer = 0; + if (m_pInstance->GetData(TYPE_THEKAL) == DONE) + m_uiAspectOfThekalTimer = 0; + if (m_pInstance->GetData(TYPE_ARLOKK) == DONE) + m_uiAspectOfArlokkTimer = 0; + } } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //BloodSiphon_Timer - if (BloodSiphon_Timer < diff) + /* Disabled as needs core fix// Blood Siphon Timer + * This also will requre spells 24320 24321 to be implemented (and used by the "Son of Hakkar" npcs) + if (m_uiBloodSiphonTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_BLOODSIPHON); - BloodSiphon_Timer = 90000; - }else BloodSiphon_Timer -= diff; - - //CorruptedBlood_Timer - if (CorruptedBlood_Timer < diff) + if (DoCastSpellIfCan(m_creature, SPELL_BLOOD_SIPHON) == CAST_OK) + m_uiBloodSiphonTimer = 90000; + } + else + m_uiBloodSiphonTimer -= uiDiff; */ + + // Corrupted Blood Timer + if (m_uiCorruptedBloodTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_CORRUPTEDBLOOD); - CorruptedBlood_Timer = urand(30000, 45000); - }else CorruptedBlood_Timer -= diff; + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_CORRUPTED_BLOOD) == CAST_OK) + m_uiCorruptedBloodTimer = urand(30000, 45000); + } + } + else + m_uiCorruptedBloodTimer -= uiDiff; - //CauseInsanity_Timer - /*if (CauseInsanity_Timer < diff) + // Cause Insanity Timer + if (m_uiCauseInsanityTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_CAUSEINSANITY); - - CauseInsanity_Timer = urand(35000, 43000); - }else CauseInsanity_Timer -= diff;*/ - - //WillOfHakkar_Timer - if (WillOfHakkar_Timer < diff) + if (m_creature->getThreatManager().getThreatList().size() > 1) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CAUSE_INSANITY) == CAST_OK) + m_uiCauseInsanityTimer = urand(10000, 15000); + } + else // Solo case, check again later + m_uiCauseInsanityTimer = urand(35000, 43000); + } + else + m_uiCauseInsanityTimer -= uiDiff; + + // Will Of Hakkar Timer + if (m_uiWillOfHakkarTimer < uiDiff) { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + if (DoCastSpellIfCan(pTarget, SPELL_WILL_OF_HAKKAR) == CAST_OK) + m_uiWillOfHakkarTimer = urand(25000, 35000); + } + else // solo attempt, try again later + m_uiWillOfHakkarTimer = 25000; + } + else + m_uiWillOfHakkarTimer -= uiDiff; - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_WILLOFHAKKAR); - - WillOfHakkar_Timer = urand(25000, 35000); - }else WillOfHakkar_Timer -= diff; - - if (!Enraged && Enrage_Timer < diff) + if (m_uiEnrageTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_ENRAGE); - Enraged = true; - }else Enrage_Timer -= diff; - - //Checking if Jeklik is dead. If not we cast her Aspect - if (CheckJeklik_Timer < diff) + if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) + m_uiEnrageTimer = 10*MINUTE*IN_MILLISECONDS; + } + else + m_uiEnrageTimer -= uiDiff; + + // Checking if Jeklik is dead. If not we cast her Aspect + if (m_uiAspectOfJeklikTimer) { - if (m_pInstance) + if (m_uiAspectOfJeklikTimer <= uiDiff) { - if (m_pInstance->GetData(TYPE_JEKLIK) != DONE) - { - if (AspectOfJeklik_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ASPECT_OF_JEKLIK); - AspectOfJeklik_Timer = urand(10000, 14000); - }else AspectOfJeklik_Timer -= diff; - } + if (DoCastSpellIfCan(m_creature, SPELL_ASPECT_OF_JEKLIK) == CAST_OK) + m_uiAspectOfJeklikTimer = urand(10000, 14000); } - CheckJeklik_Timer = 1000; - }else CheckJeklik_Timer -= diff; + else + m_uiAspectOfJeklikTimer -= uiDiff; + } - //Checking if Venoxis is dead. If not we cast his Aspect - if (CheckVenoxis_Timer < diff) + // Checking if Venoxis is dead. If not we cast his Aspect + if (m_uiAspectOfVenoxisTimer) { - if (m_pInstance) + if (m_uiAspectOfVenoxisTimer <= uiDiff) { - if (m_pInstance->GetData(TYPE_VENOXIS) != DONE) - { - if (AspectOfVenoxis_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ASPECT_OF_VENOXIS); - AspectOfVenoxis_Timer = 8000; - }else AspectOfVenoxis_Timer -= diff; - } + if (DoCastSpellIfCan(m_creature, SPELL_ASPECT_OF_VENOXIS) == CAST_OK) + m_uiAspectOfVenoxisTimer = 8000; } - CheckVenoxis_Timer = 1000; - }else CheckVenoxis_Timer -= diff; + else + m_uiAspectOfVenoxisTimer -= uiDiff; + } - //Checking if Marli is dead. If not we cast her Aspect - if (CheckMarli_Timer < diff) + // Checking if Marli is dead. If not we cast her Aspect + if (m_uiAspectOfMarliTimer) { - if (m_pInstance) + if (m_uiAspectOfMarliTimer <= uiDiff) { - if (m_pInstance->GetData(TYPE_MARLI) != DONE) - { - if (AspectOfMarli_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_ASPECT_OF_MARLI); - AspectOfMarli_Timer = 10000; - }else AspectOfMarli_Timer -= diff; - - } + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ASPECT_OF_MARLI) == CAST_OK) + m_uiAspectOfMarliTimer = 10000; } - CheckMarli_Timer = 1000; - }else CheckMarli_Timer -= diff; + else + m_uiAspectOfMarliTimer -= uiDiff; + } - //Checking if Thekal is dead. If not we cast his Aspect - if (CheckThekal_Timer < diff) + // Checking if Thekal is dead. If not we cast his Aspect + if (m_uiAspectOfThekalTimer) { - if (m_pInstance) + if (m_uiAspectOfThekalTimer <= uiDiff) { - if (m_pInstance->GetData(TYPE_THEKAL) != DONE) - { - if (AspectOfThekal_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_ASPECT_OF_THEKAL); - AspectOfThekal_Timer = 15000; - }else AspectOfThekal_Timer -= diff; - } + if (DoCastSpellIfCan(m_creature, SPELL_ASPECT_OF_THEKAL) == CAST_OK) + m_uiAspectOfThekalTimer = 15000; } - CheckThekal_Timer = 1000; - }else CheckThekal_Timer -= diff; + else + m_uiAspectOfThekalTimer -= uiDiff; + } - //Checking if Arlokk is dead. If yes we cast her Aspect - if (CheckArlokk_Timer < diff) + // Checking if Arlokk is dead. If yes we cast her Aspect + if (m_uiAspectOfArlokkTimer) { - if (m_pInstance) + if (m_uiAspectOfArlokkTimer <= uiDiff) { - if (m_pInstance->GetData(TYPE_ARLOKK) != DONE) + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ASPECT_OF_ARLOKK) == CAST_OK) { - if (AspectOfArlokk_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_ASPECT_OF_ARLOKK); - DoResetThreat(); - - AspectOfArlokk_Timer = urand(10000, 15000); - }else AspectOfArlokk_Timer -= diff; + DoResetThreat(); + m_uiAspectOfArlokkTimer = urand(10000, 15000); } } - CheckArlokk_Timer = 1000; - }else CheckArlokk_Timer -= diff; + else + m_uiAspectOfArlokkTimer -= uiDiff; + } DoMeleeAttackIfReady(); } @@ -243,9 +237,10 @@ CreatureAI* GetAI_boss_hakkar(Creature* pCreature) void AddSC_boss_hakkar() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_hakkar"; - newscript->GetAI = &GetAI_boss_hakkar; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_hakkar"; + pNewScript->GetAI = &GetAI_boss_hakkar; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp b/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp index 1e7642624..938777c24 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp b/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp index 720fecdc8..33cd8d990 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,21 +24,27 @@ EndScriptData */ #include "precompiled.h" #include "zulgurub.h" -#define SAY_AGGRO -1309002 -#define SAY_RAIN_FIRE -1309003 -#define SAY_DEATH -1309004 - -#define SPELL_CHARGE 22911 -#define SPELL_SONICBURST 23918 -#define SPELL_SCREECH 6605 -#define SPELL_SHADOW_WORD_PAIN 23952 -#define SPELL_MIND_FLAY 23953 -#define SPELL_CHAIN_MIND_FLAY 26044 //Right ID unknown. So disabled -#define SPELL_GREATERHEAL 23954 -#define SPELL_BAT_FORM 23966 - -// Batriders Spell -#define SPELL_BOMB 40332 //Wrong ID but Magmadars bomb is not working... +enum +{ + SAY_AGGRO = -1309002, + SAY_RAIN_FIRE = -1309003, + SAY_DEATH = -1309004, + + SPELL_CHARGE = 22911, + SPELL_SONICBURST = 23918, + SPELL_SCREECH = 6605, + SPELL_SHADOW_WORD_PAIN = 23952, + SPELL_MIND_FLAY = 23953, + SPELL_CHAIN_MIND_FLAY = 26044, // Right ID unknown. So disabled + SPELL_GREATERHEAL = 23954, + SPELL_BAT_FORM = 23966, + + // Batriders Spell + SPELL_BOMB = 40332, // Wrong ID but Magmadars bomb is not working... + + NPC_BLOODSEEKER_BAT = 11368, + NPC_FRENZIED_BAT = 14965, +}; struct MANGOS_DLL_DECL boss_jeklikAI : public ScriptedAI { @@ -50,40 +56,40 @@ struct MANGOS_DLL_DECL boss_jeklikAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 Charge_Timer; - uint32 SonicBurst_Timer; - uint32 Screech_Timer; - uint32 SpawnBats_Timer; - uint32 ShadowWordPain_Timer; - uint32 MindFlay_Timer; - uint32 ChainMindFlay_Timer; - uint32 GreaterHeal_Timer; - uint32 SpawnFlyingBats_Timer; + uint32 m_uiChargeTimer; + uint32 m_uiSonicBurstTimer; + uint32 m_uiScreechTimer; + uint32 m_uiSpawnBatsTimer; + uint32 m_uiShadowWordPainTimer; + uint32 m_uiMindFlayTimer; + uint32 m_uiChainMindFlayTimer; + uint32 m_uiGreaterHealTimer; + uint32 m_uiSpawnFlyingBatsTimer; - bool PhaseTwo; + bool m_bIsPhaseOne; void Reset() { - Charge_Timer = 20000; - SonicBurst_Timer = 8000; - Screech_Timer = 13000; - SpawnBats_Timer = 60000; - ShadowWordPain_Timer = 6000; - MindFlay_Timer = 11000; - ChainMindFlay_Timer = 26000; - GreaterHeal_Timer = 50000; - SpawnFlyingBats_Timer = 10000; - - PhaseTwo = false; + m_uiChargeTimer = 20000; + m_uiSonicBurstTimer = 8000; + m_uiScreechTimer = 13000; + m_uiSpawnBatsTimer = 60000; + m_uiShadowWordPainTimer = 6000; + m_uiMindFlayTimer = 11000; + m_uiChainMindFlayTimer = 26000; + m_uiGreaterHealTimer = 50000; + m_uiSpawnFlyingBatsTimer = 10000; + + m_bIsPhaseOne = true; } - void Aggro(Unit *who) + void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); - DoCastSpellIfCan(m_creature,SPELL_BAT_FORM); + DoCastSpellIfCan(m_creature, SPELL_BAT_FORM); } - void JustDied(Unit* Killer) + void JustDied(Unit* pKiller) { DoScriptText(SAY_DEATH, m_creature); @@ -91,119 +97,123 @@ struct MANGOS_DLL_DECL boss_jeklikAI : public ScriptedAI m_pInstance->SetData(TYPE_JEKLIK, DONE); } - void UpdateAI(const uint32 diff) + void JustSummoned(Creature* pSummoned) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (m_creature->GetHealthPercent() > 50.0f) + if (m_bIsPhaseOne) { - if (Charge_Timer < diff) + // Phase Switch at 50% + if (m_creature->GetHealthPercent() < 50.0f) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_CHARGE); - - Charge_Timer = urand(15000, 30000); - }else Charge_Timer -= diff; + m_creature->RemoveAurasDueToSpell(SPELL_BAT_FORM); + DoResetThreat(); + m_bIsPhaseOne = false; + return; + } - if (SonicBurst_Timer < diff) + if (m_uiChargeTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SONICBURST); - SonicBurst_Timer = urand(8000, 13000); - }else SonicBurst_Timer -= diff; + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (DoCastSpellIfCan(pTarget, SPELL_CHARGE) == CAST_OK) + m_uiChargeTimer = urand(15000, 30000); + } + else + m_uiChargeTimer -= uiDiff; - if (Screech_Timer < diff) + if (m_uiSonicBurstTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SCREECH); - Screech_Timer = urand(18000, 26000); - }else Screech_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_SONICBURST) == CAST_OK) + m_uiSonicBurstTimer = urand(8000, 13000); + } + else + m_uiSonicBurstTimer -= uiDiff; - if (SpawnBats_Timer < diff) + if (m_uiScreechTimer < uiDiff) { - Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - - Creature* Bat = NULL; - Bat = m_creature->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = m_creature->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = m_creature->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = m_creature->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = m_creature->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); + if (DoCastSpellIfCan(m_creature, SPELL_SCREECH) == CAST_OK) + m_uiScreechTimer = urand(18000, 26000); + } + else + m_uiScreechTimer -= uiDiff; - Bat = m_creature->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); + if (m_uiSpawnBatsTimer < uiDiff) + { + // TODO There are some bats in the cave behind the boss, perhaps they should be called + float fX, fY, fZ, fO, fNewX, fNewY, fNewZ; + m_creature->GetRespawnCoord(fX, fY, fZ, &fO); + for (uint8 i = 0; i < 6; ++i) + { + // Get a point a little bit behind Jeklik respawn pos + m_creature->GetRandomPoint(fX - 5.0f, fY + 5.0f, fZ, 5.0f, fNewX, fNewY, fNewZ); + m_creature->SummonCreature(NPC_BLOODSEEKER_BAT, fNewX, fNewY, fNewZ, fO, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); + } - SpawnBats_Timer = 60000; - }else SpawnBats_Timer -= diff; + m_uiSpawnBatsTimer = 60000; + } + else + m_uiSpawnBatsTimer -= uiDiff; } - else + else // Phase Two { - if (PhaseTwo) + if (m_uiShadowWordPainTimer < uiDiff) { - if (PhaseTwo && ShadowWordPain_Timer < diff) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - { - DoCastSpellIfCan(target, SPELL_SHADOW_WORD_PAIN); - ShadowWordPain_Timer = urand(12000, 18000); - } - }ShadowWordPain_Timer -=diff; - - if (MindFlay_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_MIND_FLAY); - MindFlay_Timer = 16000; - }MindFlay_Timer -=diff; - - if (ChainMindFlay_Timer < diff) - { - m_creature->InterruptNonMeleeSpells(false); - DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHAIN_MIND_FLAY); - ChainMindFlay_Timer = urand(15000, 30000); - }ChainMindFlay_Timer -=diff; - - if (GreaterHeal_Timer < diff) - { - m_creature->InterruptNonMeleeSpells(false); - DoCastSpellIfCan(m_creature,SPELL_GREATERHEAL); - GreaterHeal_Timer = urand(25000, 35000); - }GreaterHeal_Timer -=diff; + if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_WORD_PAIN) == CAST_OK) + m_uiShadowWordPainTimer = urand(12000, 18000); + } + } + else + m_uiShadowWordPainTimer -= uiDiff; - if (SpawnFlyingBats_Timer < diff) - { - Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); + if (m_uiMindFlayTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MIND_FLAY) == CAST_OK) + m_uiMindFlayTimer = 16000; + } + else + m_uiMindFlayTimer -= uiDiff; - Creature* FlyingBat = m_creature->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (FlyingBat) - { - if (target) - FlyingBat->AI()->AttackStart(target); - } + if (m_uiChainMindFlayTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHAIN_MIND_FLAY) == CAST_OK) + m_uiChainMindFlayTimer = urand(15000, 30000); + } + else + m_uiChainMindFlayTimer -= uiDiff; - SpawnFlyingBats_Timer = urand(10000, 15000); - } else SpawnFlyingBats_Timer -=diff; + if (m_uiGreaterHealTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_GREATERHEAL, CAST_INTERRUPT_PREVIOUS) == CAST_OK) + m_uiGreaterHealTimer = urand(25000, 35000); } else + m_uiGreaterHealTimer -= uiDiff; + + if (m_uiSpawnFlyingBatsTimer < uiDiff) { - m_creature->SetDisplayId(15219); - DoResetThreat(); - PhaseTwo = true; + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_creature->SummonCreature(NPC_FRENZIED_BAT, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ() + 15.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); + + m_uiSpawnFlyingBatsTimer = urand(10000, 15000); } + else + m_uiSpawnFlyingBatsTimer -= uiDiff; } DoMeleeAttackIfReady(); } }; -//Flying Bat +// Flying Bat struct MANGOS_DLL_DECL mob_batriderAI : public ScriptedAI { mob_batriderAI(Creature* pCreature) : ScriptedAI(pCreature) @@ -214,34 +224,36 @@ struct MANGOS_DLL_DECL mob_batriderAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 Bomb_Timer; - uint32 Check_Timer; + uint32 m_uiBombTimer; + uint32 m_uiCheckTimer; void Reset() { - Bomb_Timer = 2000; - Check_Timer = 1000; + m_uiBombTimer = 2000; + m_uiCheckTimer = 1000; m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } - void UpdateAI (const uint32 diff) + void UpdateAI (const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Bomb_Timer - if (Bomb_Timer < diff) + // Bomb Timer + if (m_uiBombTimer < uiDiff) { - if (Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - DoCastSpellIfCan(target, SPELL_BOMB); - Bomb_Timer = 5000; + DoCastSpellIfCan(pTarget, SPELL_BOMB); + m_uiBombTimer = 5000; } - }else Bomb_Timer -= diff; + } + else + m_uiBombTimer -= uiDiff; - //Check_Timer - if (Check_Timer < diff) + // Check Timer + if (m_uiCheckTimer < uiDiff) { if (m_pInstance) { @@ -252,8 +264,10 @@ struct MANGOS_DLL_DECL mob_batriderAI : public ScriptedAI return; } } - Check_Timer = 1000; - }else Check_Timer -= diff; + m_uiCheckTimer = 1000; + } + else + m_uiCheckTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -271,14 +285,15 @@ CreatureAI* GetAI_mob_batrider(Creature* pCreature) void AddSC_boss_jeklik() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_jeklik"; - newscript->GetAI = &GetAI_boss_jeklik; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_batrider"; - newscript->GetAI = &GetAI_mob_batrider; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_jeklik"; + pNewScript->GetAI = &GetAI_boss_jeklik; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_batrider"; + pNewScript->GetAI = &GetAI_mob_batrider; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp b/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp index 971e59c0d..4f2a2e24e 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,27 +17,41 @@ /* ScriptData SDName: Boss_Jin'do the Hexxer SD%Complete: 85 -SDComment: Mind Control not working because of core bug. Shades visible for all. +SDComment: Mind Control not working because of core bug. Shades invisible is removed as of Attacking (core bug) - MANY HACKZ!! SDCategory: Zul'Gurub EndScriptData */ #include "precompiled.h" #include "zulgurub.h" -#define SAY_AGGRO -1309014 +enum +{ + SAY_AGGRO = -1309014, + + SPELL_BRAINWASH_TOTEM = 24262, + SPELL_POWERFULL_HEALING_WARD = 24309, + SPELL_HEX = 24053, + SPELL_DELUSIONS_OF_JINDO = 24306, + SPELL_SHADE_OF_JINDO = 24308, // Spell was removed from DBC around TBC; will summon npcs manually! + + SPELL_HEALING_WARD_HEAL = 24311, -#define SPELL_BRAINWASHTOTEM 24262 -#define SPELL_POWERFULLHEALINGWARD 24309 //We will not use this spell. We will summon a totem by script cause the spell totems will not cast. -#define SPELL_HEX 24053 -#define SPELL_DELUSIONSOFJINDO 24306 -#define SPELL_SHADEOFJINDO 24308 //We will not use this spell. We will summon a shade by script. + // Shade of Jindo Spell + SPELL_SHADOWSHOCK = 19460, + SPELL_SHADE_OF_JINDO_PASSIVE = 24307, // shade invisibility, needs core support to prevent removing when attacking -//Healing Ward Spell -#define SPELL_HEAL 38588 //Totems are not working right. Right heal spell ID is 24311 but this spell is not casting... + // npcs + NPC_SHADE_OF_JINDO = 14986, + NPC_SACRIFICED_TROLL = 14826, + NPC_POWERFULL_HEALING_WARD = 14987, + + MAX_SKELETONS = 9, +}; -//Shade of Jindo Spell -#define SPELL_SHADOWSHOCK 19460 -#define SPELL_INVISIBLE 24699 +static const float aPitTeleportLocs[4] = +{ + -11583.7783f, -1249.4278f, 77.5471f, 4.745f +}; struct MANGOS_DLL_DECL boss_jindoAI : public ScriptedAI { @@ -49,163 +63,143 @@ struct MANGOS_DLL_DECL boss_jindoAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 BrainWashTotem_Timer; - uint32 HealingWard_Timer; - uint32 Hex_Timer; - uint32 Delusions_Timer; - uint32 Teleport_Timer; + uint32 m_uiBrainWashTotemTimer; + uint32 m_uiHealingWardTimer; + uint32 m_uiHexTimer; + uint32 m_uiDelusionsTimer; + uint32 m_uiTeleportTimer; void Reset() { - BrainWashTotem_Timer = 20000; - HealingWard_Timer = 16000; - Hex_Timer = 8000; - Delusions_Timer = 10000; - Teleport_Timer = 5000; + m_uiBrainWashTotemTimer = 20000; + m_uiHealingWardTimer = 16000; + m_uiHexTimer = 8000; + m_uiDelusionsTimer = 10000; + m_uiTeleportTimer = 5000; } - void Aggro(Unit *who) + void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); } - void UpdateAI(const uint32 diff) + void SummonedCreatureJustDied(Creature* pSummoned) + { + if (pSummoned->GetEntry() == NPC_POWERFULL_HEALING_WARD) + m_uiHealingWardTimer = 15000; // how long delay? + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //BrainWashTotem_Timer - if (BrainWashTotem_Timer < diff) + // Brain Wash Totem Timer + if (m_uiBrainWashTotemTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_BRAINWASHTOTEM); - BrainWashTotem_Timer = urand(18000, 26000); - }else BrainWashTotem_Timer -= diff; - - //HealingWard_Timer - if (HealingWard_Timer < diff) + if (DoCastSpellIfCan(m_creature, SPELL_BRAINWASH_TOTEM) == CAST_OK) + m_uiBrainWashTotemTimer = urand(18000, 26000); + } + else + m_uiBrainWashTotemTimer -= uiDiff; + + // Healing Ward Timer + if (m_uiHealingWardTimer) { - //DoCastSpellIfCan(m_creature, SPELL_POWERFULLHEALINGWARD); - m_creature->SummonCreature(14987, m_creature->GetPositionX()+3, m_creature->GetPositionY()-2, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,30000); - HealingWard_Timer = urand(14000, 20000); - }else HealingWard_Timer -= diff; + if (m_uiHealingWardTimer <= uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_POWERFULL_HEALING_WARD) == CAST_OK) + m_uiHealingWardTimer = 0; + } + else + m_uiHealingWardTimer -= uiDiff; + } - //Hex_Timer - if (Hex_Timer < diff) + // Hex Timer + if (m_uiHexTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_HEX); - - if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-80); - - Hex_Timer = urand(12000, 20000); - }else Hex_Timer -= diff; - - //Casting the delusion curse with a shade. So shade will attack the same target with the curse. - if (Delusions_Timer < diff) + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_HEX) == CAST_OK) + m_uiHexTimer = urand(12000, 20000); + } + else + m_uiHexTimer -= uiDiff; + + // Casting the delusion curse with a shade. So shade will attack the same target with the curse. + if (m_uiDelusionsTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + // random target except the tank + Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); + if (!pTarget) + pTarget = m_creature->getVictim(); + + if (DoCastSpellIfCan(pTarget, SPELL_DELUSIONS_OF_JINDO) == CAST_OK) { - DoCastSpellIfCan(target, SPELL_DELUSIONSOFJINDO); + float fX, fY, fZ; + m_creature->GetRandomPoint(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 5.0f, fX, fY, fZ); + if (Creature* pSummoned = m_creature->SummonCreature(NPC_SHADE_OF_JINDO, fX, fY, fZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) + pSummoned->AI()->AttackStart(pTarget); - Creature *Shade = m_creature->SummonCreature(14986, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Shade) - Shade->AI()->AttackStart(target); + m_uiDelusionsTimer = urand(4000, 12000); } + } + else + m_uiDelusionsTimer -= uiDiff; - Delusions_Timer = urand(4000, 12000); - }else Delusions_Timer -= diff; - - //Teleporting a random gamer and spawning 9 skeletons that will attack this gamer - if (Teleport_Timer < diff) + // Teleporting a random player and spawning 9 skeletons that will attack this player + if (m_uiTeleportTimer < uiDiff) { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); - if (target && target->GetTypeId() == TYPEID_PLAYER) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - DoTeleportPlayer(target, -11583.7783f, -1249.4278f, 77.5471f, 4.745f); - - if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(target,-100); - - Creature *Skeletons; - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()-2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()-4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()+2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()-2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()+4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()-4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+3, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Skeletons) - Skeletons->AI()->AttackStart(target); - } + DoTeleportPlayer(pTarget, aPitTeleportLocs[0], aPitTeleportLocs[1], aPitTeleportLocs[2], aPitTeleportLocs[3]); - Teleport_Timer = urand(15000, 23000); - }else Teleport_Timer -= diff; + // summon 9 skeletons in the pit at random points + float fX, fY, fZ; + for (uint8 i = 0; i < MAX_SKELETONS; ++i) + { + m_creature->GetRandomPoint(aPitTeleportLocs[0], aPitTeleportLocs[1], aPitTeleportLocs[2], 4.0f, fX, fY, fZ); + if (Creature* pSummoned = m_creature->SummonCreature(NPC_SACRIFICED_TROLL, fX, fY, fZ, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) + pSummoned->AI()->AttackStart(pTarget); + } + + m_uiTeleportTimer = urand(15000, 23000); + } + } + else + m_uiTeleportTimer -= uiDiff; DoMeleeAttackIfReady(); } }; -//Healing Ward +// HACK script! Should not need to have totems in sd2 struct MANGOS_DLL_DECL mob_healing_wardAI : public ScriptedAI { - mob_healing_wardAI(Creature* pCreature) : ScriptedAI(pCreature) - { - m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); - Reset(); - } + mob_healing_wardAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } - ScriptedInstance* m_pInstance; - - uint32 Heal_Timer; + uint32 m_uiHealTimer; void Reset() { - Heal_Timer = 2000; + m_uiHealTimer = 3000; // Timer unknown, sources go over 1s, per tick to 3s, keep 3s as in original script } - void UpdateAI (const uint32 diff) + void AttackStart(Unit* pWho) {} + void MoveInLineOfSight(Unit* pWho) {} + + void UpdateAI (const uint32 uiDiff) { - //Heal_Timer - if (Heal_Timer < diff) + // Heal Timer + if (m_uiHealTimer < uiDiff) { - if (m_pInstance) - { - if (Unit *pJindo = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_JINDO))) - { - if (pJindo->isAlive()) - DoCastSpellIfCan(pJindo, SPELL_HEAL); - } - } - Heal_Timer = 3000; - }else Heal_Timer -= diff; - - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - DoMeleeAttackIfReady(); + DoCastSpellIfCan(m_creature, SPELL_HEALING_WARD_HEAL); + m_uiHealTimer = 3000; + } + else + m_uiHealTimer -= uiDiff; } }; -//Shade of Jindo +// TODO Move to Acid struct MANGOS_DLL_DECL mob_shade_of_jindoAI : public ScriptedAI { mob_shade_of_jindoAI(Creature* pCreature) : ScriptedAI(pCreature) @@ -216,25 +210,27 @@ struct MANGOS_DLL_DECL mob_shade_of_jindoAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 ShadowShock_Timer; + uint32 m_uiShadowShockTimer; void Reset() { - ShadowShock_Timer = 1000; - m_creature->CastSpell(m_creature, SPELL_INVISIBLE,true); + m_uiShadowShockTimer = 1000; + DoCastSpellIfCan(m_creature, SPELL_SHADE_OF_JINDO_PASSIVE); } - void UpdateAI (const uint32 diff) + void UpdateAI (const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //ShadowShock_Timer - if (ShadowShock_Timer < diff) + // ShadowShock Timer + if (m_uiShadowShockTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOWSHOCK); - ShadowShock_Timer = 2000; - }else ShadowShock_Timer -= diff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOWSHOCK) == CAST_OK) + m_uiShadowShockTimer = 2000; + } + else + m_uiShadowShockTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -257,20 +253,20 @@ CreatureAI* GetAI_mob_shade_of_jindo(Creature* pCreature) void AddSC_boss_jindo() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_jindo"; - newscript->GetAI = &GetAI_boss_jindo; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_healing_ward"; - newscript->GetAI = &GetAI_mob_healing_ward; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_shade_of_jindo"; - newscript->GetAI = &GetAI_mob_shade_of_jindo; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_jindo"; + pNewScript->GetAI = &GetAI_boss_jindo; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_healing_ward"; + pNewScript->GetAI = &GetAI_mob_healing_ward; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_shade_of_jindo"; + pNewScript->GetAI = &GetAI_mob_shade_of_jindo; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp b/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp index e2eeeca3c..a9cc124dc 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -167,10 +167,10 @@ struct MANGOS_DLL_DECL boss_mandokirAI : public ScriptedAI if (m_pInstance) { - if (Creature* jTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_JINDO))) + if (Creature* pJindo = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_JINDO))) { - if (jTemp->isAlive()) - DoScriptText(SAY_GRATS_JINDO, jTemp); + if (pJindo->isAlive()) + DoScriptText(SAY_GRATS_JINDO, pJindo); } } @@ -191,8 +191,6 @@ struct MANGOS_DLL_DECL boss_mandokirAI : public ScriptedAI { DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); - uint32 uiCount = sizeof(aSpirits)/sizeof(SpawnLocations); for(uint8 i = 0; i < uiCount; ++i) @@ -328,7 +326,7 @@ struct MANGOS_DLL_DECL boss_mandokirAI : public ScriptedAI { Unit* pTarget = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); - if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pTarget, ATTACK_DISTANCE)) + if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && m_creature->CanReachWithMeleeAttack(pTarget)) ++uiTargetInRangeCount; } diff --git a/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp b/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp index 21593e15b..b6ad12deb 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp b/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp index 36c01b60a..d0e53226b 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp b/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp index 23c2ac231..bb1ab7e57 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,35 +24,122 @@ EndScriptData */ #include "precompiled.h" #include "zulgurub.h" -#define SAY_AGGRO -1309009 -#define SAY_DEATH -1309010 - -#define SPELL_MORTALCLEAVE 22859 -#define SPELL_SILENCE 23207 -#define SPELL_FRENZY 23342 -#define SPELL_FORCEPUNCH 24189 -#define SPELL_CHARGE 24408 -#define SPELL_ENRAGE 23537 -#define SPELL_SUMMONTIGERS 24183 -#define SPELL_TIGER_FORM 24169 -#define SPELL_RESURRECT 24173 //We will not use this spell. - -//Zealot Lor'Khan Spells -#define SPELL_SHIELD 25020 -#define SPELL_BLOODLUST 24185 -#define SPELL_GREATERHEAL 24208 -#define SPELL_DISARM 22691 - -//Zealot Lor'Khan Spells -#define SPELL_SWEEPINGSTRIKES 18765 -#define SPELL_SINISTERSTRIKE 15667 -#define SPELL_GOUGE 24698 -#define SPELL_KICK 15614 -#define SPELL_BLIND 21060 - -struct MANGOS_DLL_DECL boss_thekalAI : public ScriptedAI +enum { - boss_thekalAI(Creature* pCreature) : ScriptedAI(pCreature) + SAY_AGGRO = -1309009, + SAY_DEATH = -1309010, + + SPELL_MORTAL_CLEAVE = 22859, + SPELL_SILENCE = 23207, + SPELL_FRENZY = 23342, + SPELL_FORCE_PUNCH = 24189, + SPELL_CHARGE = 24408, + SPELL_ENRAGE = 23537, + SPELL_SUMMON_TIGERS = 24183, + SPELL_TIGER_FORM = 24169, + SPELL_RESURRECT = 24173, + + // Zealot Lor'Khan Spells + SPELL_SHIELD = 25020, + SPELL_BLOODLUST = 24185, + SPELL_GREATER_HEAL = 24208, + SPELL_DISARM = 22691, + + //Zealot Lor'Khan Spells + SPELL_SWEEPING_STRIKES = 18765, + SPELL_SINISTER_STRIKE = 15667, + SPELL_GOUGE = 24698, + SPELL_KICK = 15614, + SPELL_BLIND = 21060, + + PHASE_NORMAL = 1, + PHASE_FAKE_DEATH = 2, + PHASE_WAITING = 3, + PHASE_TIGER = 4, +}; + +// abstract base class for faking death +struct MANGOS_DLL_DECL boss_thekalBaseAI : public ScriptedAI +{ + boss_thekalBaseAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_uiPhase = PHASE_NORMAL; + } + + uint8 m_uiPhase; + + virtual void OnFakeingDeath() {} + virtual void OnRevive() {} + + void DamageTaken(Unit* pKiller, uint32& uiDamage) + { + if (uiDamage < m_creature->GetHealth()) + return; + + // Prevent glitch if in fake death + if (m_uiPhase == PHASE_FAKE_DEATH || m_uiPhase == PHASE_WAITING) + { + uiDamage = 0; + return; + } + + // Only init fake in normal phase + if (m_uiPhase != PHASE_NORMAL) + return; + + uiDamage = 0; + + m_creature->InterruptNonMeleeSpells(true); + m_creature->SetHealth(0); + 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); + + m_uiPhase = PHASE_FAKE_DEATH; + + OnFakeingDeath(); + } + + void Revive(bool bOnlyFlags = false) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + + if (bOnlyFlags) + return; + + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_uiPhase = PHASE_NORMAL; + + DoResetThreat(); + Reset(); + + // Assume Attack + if (m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + + OnRevive(); + } + + void PreventRevive() + { + if (m_creature->IsNonMeleeSpellCasted(true)) + m_creature->InterruptNonMeleeSpells(true); + + m_uiPhase = PHASE_WAITING; + } +}; + +struct MANGOS_DLL_DECL boss_thekalAI : public boss_thekalBaseAI +{ + boss_thekalAI(Creature* pCreature) : boss_thekalBaseAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); @@ -60,455 +147,502 @@ struct MANGOS_DLL_DECL boss_thekalAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 MortalCleave_Timer; - uint32 Silence_Timer; - uint32 Frenzy_Timer; - uint32 ForcePunch_Timer; - uint32 Charge_Timer; - uint32 Enrage_Timer; - uint32 SummonTigers_Timer; - uint32 Check_Timer; - uint32 Resurrect_Timer; + uint32 m_uiMortalCleaveTimer; + uint32 m_uiSilenceTimer; + uint32 m_uiFrenzyTimer; + uint32 m_uiForcePunchTimer; + uint32 m_uiChargeTimer; + uint32 m_uiEnrageTimer; + uint32 m_uiSummonTigersTimer; + uint32 m_uiResurrectTimer; - bool Enraged; - bool PhaseTwo; - bool WasDead; + bool m_bEnraged; void Reset() { - MortalCleave_Timer = 4000; - Silence_Timer = 9000; - Frenzy_Timer = 30000; - ForcePunch_Timer = 4000; - Charge_Timer = 12000; - Enrage_Timer = 32000; - SummonTigers_Timer = 25000; - Check_Timer = 10000; - Resurrect_Timer = 10000; - - Enraged = false; - PhaseTwo = false; - WasDead = false; + m_uiMortalCleaveTimer = 4000; + m_uiSilenceTimer = 9000; + m_uiFrenzyTimer = 30000; + m_uiForcePunchTimer = 4000; + m_uiChargeTimer = 12000; + m_uiEnrageTimer = 32000; + m_uiSummonTigersTimer = 25000; + m_uiResurrectTimer = 10000; + m_uiPhase = PHASE_NORMAL; + + m_bEnraged = false; + + // remove fake death + Revive(true); } - void Aggro(Unit *who) + void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); } - void JustDied(Unit* Killer) + void JustDied(Unit* pKiller) { DoScriptText(SAY_DEATH, m_creature); - if (m_pInstance) - m_pInstance->SetData(TYPE_THEKAL, DONE); + if (!m_pInstance) + return; + + m_pInstance->SetData(TYPE_THEKAL, DONE); + + // remove the two adds + if (Creature* pZath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ZATH))) + pZath->ForcedDespawn(); + if (Creature* pLorkhan = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LORKHAN))) + pLorkhan->ForcedDespawn(); } void JustReachedHome() { if (m_pInstance) - m_pInstance->SetData(TYPE_THEKAL, NOT_STARTED); + m_pInstance->SetData(TYPE_THEKAL, FAIL); } - void UpdateAI(const uint32 diff) + // Only call in context where m_pInstance is valid + bool CanPreventAddsResurrect() + { + // If any add is alive, return false + if (m_pInstance->GetData(TYPE_ZATH) != SPECIAL || m_pInstance->GetData(TYPE_LORKHAN) != SPECIAL) + return false; + + // Else Prevent them Resurrecting + if (Creature* pLorkhan = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LORKHAN))) + { + if (boss_thekalBaseAI* pFakerAI = dynamic_cast(pLorkhan->AI())) + pFakerAI->PreventRevive(); + } + Creature* pZath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ZATH)); + { + if (boss_thekalBaseAI* pFakerAI = dynamic_cast(pZath->AI())) + pFakerAI->PreventRevive(); + } + + return true; + } + + void OnFakeingDeath() + { + m_uiResurrectTimer = 10000; + + if (m_pInstance) + { + m_pInstance->SetData(TYPE_THEKAL, SPECIAL); + + // If both Adds are already dead, don't wait 10 seconds + if (CanPreventAddsResurrect()) + m_uiResurrectTimer = 1000; + } + } + + void OnRevive() + { + if (!m_pInstance) + return; + + // Both Adds are 'dead' enter tiger phase + if (CanPreventAddsResurrect()) + { + DoCastSpellIfCan(m_creature, SPELL_TIGER_FORM, CAST_TRIGGERED); + m_uiPhase = PHASE_TIGER; + } + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Check_Timer for the death of LorKhan and Zath. - if (!WasDead && Check_Timer < diff) + switch (m_uiPhase) { - if (m_pInstance) - { - if (m_pInstance->GetData(TYPE_LORKHAN) == SPECIAL) + case PHASE_FAKE_DEATH: + if (m_uiResurrectTimer < uiDiff) { - //Resurrect LorKhan - if (Creature *pLorKhan = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_LORKHAN))) - { - pLorKhan->SetStandState(UNIT_STAND_STATE_STAND); - pLorKhan->setFaction(14); - pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pLorKhan->SetHealth(int(pLorKhan->GetMaxHealth()*1.0)); + // resurrect him in any case + DoCastSpellIfCan(m_creature, SPELL_RESURRECT); - m_pInstance->SetData(TYPE_LORKHAN, DONE); + m_uiPhase = PHASE_WAITING; + if (m_pInstance) + { + CanPreventAddsResurrect(); + m_pInstance->SetData(TYPE_THEKAL, IN_PROGRESS); } } + else + m_uiResurrectTimer -= uiDiff; - if (m_pInstance->GetData(TYPE_ZATH) == SPECIAL) + // No break needed here + case PHASE_WAITING: + return; + + case PHASE_NORMAL: + if (m_uiMortalCleaveTimer < uiDiff) { - //Resurrect Zath - if (Creature *pZath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ZATH))) - { - pZath->SetStandState(UNIT_STAND_STATE_STAND); - pZath->setFaction(14); - pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pZath->SetHealth(int(pZath->GetMaxHealth()*1.0)); + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MORTAL_CLEAVE) == CAST_OK) + m_uiMortalCleaveTimer = urand(15000, 20000); + } + else + m_uiMortalCleaveTimer -= uiDiff; - m_pInstance->SetData(TYPE_ZATH, DONE); + if (m_uiSilenceTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_SILENCE) == CAST_OK) + m_uiSilenceTimer = urand(20000, 25000); } } - } - Check_Timer = 5000; - }else Check_Timer -= diff; - - if (!PhaseTwo && MortalCleave_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_MORTALCLEAVE); - MortalCleave_Timer = urand(15000, 20000); - }else MortalCleave_Timer -= diff; - - if (!PhaseTwo && Silence_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SILENCE); - Silence_Timer = urand(20000, 25000); - }else Silence_Timer -= diff; - - if (!PhaseTwo && !WasDead && m_creature->GetHealthPercent() < 5.0f) - { - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetStandState(UNIT_STAND_STATE_SLEEP); - m_creature->AttackStop(); + else + m_uiSilenceTimer -= uiDiff; - if (m_pInstance) - m_pInstance->SetData(TYPE_THEKAL, SPECIAL); + break; + case PHASE_TIGER: + if (m_uiChargeTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_CHARGE) == CAST_OK) + { + DoResetThreat(); + AttackStart(pTarget); + m_uiChargeTimer = urand(15000, 22000); + } + } + } + else + m_uiChargeTimer -= uiDiff; - WasDead = true; - } + if (m_uiFrenzyTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) + m_uiFrenzyTimer = 30000; + } + else + m_uiFrenzyTimer -= uiDiff; - //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds. - if (!PhaseTwo && WasDead) - { - if (Resurrect_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_TIGER_FORM); - m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.00f); - m_creature->SetStandState(UNIT_STAND_STATE_STAND); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetHealth(int(m_creature->GetMaxHealth()*1.0)); - const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); - m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40))); - m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40))); - m_creature->UpdateDamagePhysical(BASE_ATTACK); - DoResetThreat(); - PhaseTwo = true; - }else Resurrect_Timer -= diff; - } + if (m_uiForcePunchTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_FORCE_PUNCH) == CAST_OK) + m_uiForcePunchTimer = urand(16000, 21000); + } + else + m_uiForcePunchTimer -= uiDiff; - if (m_creature->GetHealthPercent() == 100.0f && WasDead) - { - WasDead = false; - } + if (m_uiSummonTigersTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_TIGERS) == CAST_OK) + m_uiSummonTigersTimer = urand(10000, 14000); + } + else + m_uiSummonTigersTimer -= uiDiff; - if (PhaseTwo) - { - if (Charge_Timer < diff) - { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + if (!m_bEnraged && m_creature->GetHealthPercent() < 11.0f) { - DoCastSpellIfCan(target,SPELL_CHARGE); - DoResetThreat(); - AttackStart(target); + if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) + m_bEnraged = true; } - Charge_Timer = urand(15000, 22000); - }else Charge_Timer -= diff; - - if (Frenzy_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_FRENZY); - Frenzy_Timer = 30000; - }else Frenzy_Timer -= diff; - - if (ForcePunch_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SILENCE); - ForcePunch_Timer = urand(16000, 21000); - }else ForcePunch_Timer -= diff; - - if (SummonTigers_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SUMMONTIGERS); - SummonTigers_Timer = urand(10000, 14000); - }else SummonTigers_Timer -= diff; - - if (m_creature->GetHealthPercent() < 11.0f && !Enraged) - { - DoCastSpellIfCan(m_creature, SPELL_ENRAGE); - Enraged = true; - } + + break; } DoMeleeAttackIfReady(); } }; -//Zealot Lor'Khan -struct MANGOS_DLL_DECL mob_zealot_lorkhanAI : public ScriptedAI +/*###### +## mob_zealot_lorkhan +######*/ + +struct MANGOS_DLL_DECL mob_zealot_lorkhanAI : public boss_thekalBaseAI { - mob_zealot_lorkhanAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_zealot_lorkhanAI(Creature* pCreature) : boss_thekalBaseAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } - uint32 Shield_Timer; - uint32 BloodLust_Timer; - uint32 GreaterHeal_Timer; - uint32 Disarm_Timer; - uint32 Check_Timer; - - bool FakeDeath; - ScriptedInstance* m_pInstance; + uint32 m_uiShieldTimer; + uint32 m_uiBloodLustTimer; + uint32 m_uiGreaterHealTimer; + uint32 m_uiDisarmTimer; + uint32 m_uiResurrectTimer; + void Reset() { - Shield_Timer = 1000; - BloodLust_Timer = 16000; - GreaterHeal_Timer = 32000; - Disarm_Timer = 6000; - Check_Timer = 10000; - - FakeDeath = false; + m_uiShieldTimer = 1000; + m_uiBloodLustTimer = 16000; + m_uiGreaterHealTimer = 32000; + m_uiDisarmTimer = 6000; + m_uiPhase = PHASE_NORMAL; if (m_pInstance) m_pInstance->SetData(TYPE_LORKHAN, NOT_STARTED); - m_creature->SetStandState(UNIT_STAND_STATE_STAND); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Revive(true); } - void UpdateAI (const uint32 diff) + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_LORKHAN, IN_PROGRESS); + } + + void OnFakeingDeath() + { + m_uiResurrectTimer = 10000; + + if (m_pInstance) + m_pInstance->SetData(TYPE_LORKHAN, SPECIAL); + } + + void UpdateAI (const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Shield_Timer - if (Shield_Timer < diff) - { - DoCastSpellIfCan(m_creature,SPELL_SHIELD); - Shield_Timer = 61000; - }else Shield_Timer -= diff; - - //BloodLust_Timer - if (BloodLust_Timer < diff) + switch (m_uiPhase) { - DoCastSpellIfCan(m_creature,SPELL_BLOODLUST); - BloodLust_Timer = urand(20000, 28000); - }else BloodLust_Timer -= diff; + case PHASE_FAKE_DEATH: + if (m_uiResurrectTimer < uiDiff) + { + if (!m_pInstance) + return; - //Casting Greaterheal to Thekal or Zath if they are in meele range. - if (GreaterHeal_Timer < diff) - { - if (m_pInstance) - { - Creature* pThekal = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_THEKAL)); - Creature* pZath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ZATH)); + if (m_pInstance->GetData(TYPE_THEKAL) != SPECIAL || m_pInstance->GetData(TYPE_ZATH) != SPECIAL) + { + DoCastSpellIfCan(m_creature, SPELL_RESURRECT); + m_pInstance->SetData(TYPE_LORKHAN, IN_PROGRESS); + } - switch(urand(0, 1)) - { - case 0: - if (pThekal && m_creature->IsWithinDistInMap(pThekal, ATTACK_DISTANCE)) - DoCastSpellIfCan(pThekal, SPELL_GREATERHEAL); - break; - case 1: - if (pZath && m_creature->IsWithinDistInMap(pZath, ATTACK_DISTANCE)) - DoCastSpellIfCan(pZath, SPELL_GREATERHEAL); - break; + m_uiPhase = PHASE_WAITING; } - } + else + m_uiResurrectTimer -= uiDiff; - GreaterHeal_Timer = urand(15000, 20000); - }else GreaterHeal_Timer -= diff; + // no break needed here + case PHASE_WAITING: + return; - //Disarm_Timer - if (Disarm_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_DISARM); - Disarm_Timer = urand(15000, 25000); - }else Disarm_Timer -= diff; + case PHASE_NORMAL: + // Shield_Timer + if (m_uiShieldTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_SHIELD) == CAST_OK) + m_uiShieldTimer = 61000; + } + else + m_uiShieldTimer -= uiDiff; - //Check_Timer for the death of LorKhan and Zath. - if (!FakeDeath && Check_Timer < diff) - { - if (m_pInstance) - { - if (m_pInstance->GetData(TYPE_THEKAL) == SPECIAL) + // BloodLust_Timer + if (m_uiBloodLustTimer < uiDiff) { - //Resurrect Thekal - if (Creature* pThekal = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_THEKAL))) - { - pThekal->SetStandState(UNIT_STAND_STATE_STAND); - pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pThekal->setFaction(14); - pThekal->SetHealth(int(pThekal->GetMaxHealth()*1.0)); - } + // ToDo: research if this should be cast on Thekal or Zath + if (DoCastSpellIfCan(m_creature, SPELL_BLOODLUST) == CAST_OK) + m_uiBloodLustTimer = urand(20000, 28000); } + else + m_uiBloodLustTimer -= uiDiff; - if (m_pInstance->GetData(TYPE_ZATH) == SPECIAL) + // Casting Greaterheal to Thekal or Zath if they are in meele range. + // TODO - why this range check? + if (m_uiGreaterHealTimer < uiDiff) { - //Resurrect Zath - if (Creature* pZath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ZATH))) + if (m_pInstance) { - pZath->SetStandState(UNIT_STAND_STATE_STAND); - pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pZath->setFaction(14); - pZath->SetHealth(int(pZath->GetMaxHealth()*1.0)); + Creature* pThekal = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_THEKAL)); + Creature* pZath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ZATH)); + + switch(urand(0, 1)) + { + case 0: + if (pThekal && m_creature->IsWithinDistInMap(pThekal, 3*ATTACK_DISTANCE)) + DoCastSpellIfCan(pThekal, SPELL_GREATER_HEAL); + break; + case 1: + if (pZath && m_creature->IsWithinDistInMap(pZath, 3*ATTACK_DISTANCE)) + DoCastSpellIfCan(pZath, SPELL_GREATER_HEAL); + break; + } } - } - } - - Check_Timer = 5000; - }else Check_Timer -= diff; - if (m_creature->GetHealthPercent() < 5.0f) - { - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetStandState(UNIT_STAND_STATE_SLEEP); - m_creature->setFaction(35); - m_creature->AttackStop(); + m_uiGreaterHealTimer = urand(15000, 20000); + } + else + m_uiGreaterHealTimer -= uiDiff; - if (m_pInstance) - m_pInstance->SetData(TYPE_LORKHAN, SPECIAL); + // Disarm_Timer + if (m_uiDisarmTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DISARM) == CAST_OK) + m_uiDisarmTimer = urand(15000, 25000); + } + else + m_uiDisarmTimer -= uiDiff; - FakeDeath = true; + break; } DoMeleeAttackIfReady(); } }; -//Zealot Zath -struct MANGOS_DLL_DECL mob_zealot_zathAI : public ScriptedAI +/*###### +## npc_zealot_zath +######*/ + +struct MANGOS_DLL_DECL mob_zealot_zathAI : public boss_thekalBaseAI { - mob_zealot_zathAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_zealot_zathAI(Creature* pCreature) : boss_thekalBaseAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } - uint32 SweepingStrikes_Timer; - uint32 SinisterStrike_Timer; - uint32 Gouge_Timer; - uint32 Kick_Timer; - uint32 Blind_Timer; - uint32 Check_Timer; - - bool FakeDeath; - ScriptedInstance* m_pInstance; + uint32 m_uiSweepingStrikesTimer; + uint32 m_uiSinisterStrikeTimer; + uint32 m_uiGougeTimer; + uint32 m_uiKickTimer; + uint32 m_uiBlindTimer; + uint32 m_uiResurrectTimer; + void Reset() { - SweepingStrikes_Timer = 13000; - SinisterStrike_Timer = 8000; - Gouge_Timer = 25000; - Kick_Timer = 18000; - Blind_Timer = 5000; - Check_Timer = 10000; - - FakeDeath = false; + m_uiSweepingStrikesTimer = 13000; + m_uiSinisterStrikeTimer = 8000; + m_uiGougeTimer = 25000; + m_uiKickTimer = 18000; + m_uiBlindTimer = 5000; + m_uiPhase = PHASE_NORMAL; if (m_pInstance) m_pInstance->SetData(TYPE_ZATH, NOT_STARTED); - m_creature->SetStandState(UNIT_STAND_STATE_STAND); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Revive(true); } - void UpdateAI (const uint32 diff) + void Aggro(Unit* pWho) { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; + if (m_pInstance) + m_pInstance->SetData(TYPE_ZATH, IN_PROGRESS); + } - //SweepingStrikes_Timer - if (SweepingStrikes_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SWEEPINGSTRIKES); - SweepingStrikes_Timer = urand(22000, 26000); - }else SweepingStrikes_Timer -= diff; + void OnFakeingDeath() + { + m_uiResurrectTimer = 10000; - //SinisterStrike_Timer - if (SinisterStrike_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_SINISTERSTRIKE); - SinisterStrike_Timer = urand(8000, 16000); - }else SinisterStrike_Timer -= diff; + if (m_pInstance) + m_pInstance->SetData(TYPE_ZATH, SPECIAL); + } - //Gouge_Timer - if (Gouge_Timer < diff) + void UpdateAI (const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch (m_uiPhase) { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_GOUGE); + case PHASE_FAKE_DEATH: + if (m_uiResurrectTimer < uiDiff) + { + if (!m_pInstance) + return; - if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100); + if (m_pInstance->GetData(TYPE_THEKAL) != SPECIAL || m_pInstance->GetData(TYPE_LORKHAN) != SPECIAL) + { + DoCastSpellIfCan(m_creature, SPELL_RESURRECT); + m_pInstance->SetData(TYPE_ZATH, IN_PROGRESS); + } - Gouge_Timer = urand(17000, 27000); - }else Gouge_Timer -= diff; + m_uiPhase = PHASE_WAITING; + } + else + m_uiResurrectTimer -= uiDiff; - //Kick_Timer - if (Kick_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_KICK); - Kick_Timer = urand(15000, 25000); - }else Kick_Timer -= diff; + // no break needed here + case PHASE_WAITING: + return; - //Blind_Timer - if (Blind_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_BLIND); - Blind_Timer = urand(10000, 20000); - }else Blind_Timer -= diff; + case PHASE_NORMAL: + // SweepingStrikes_Timer + if (m_uiSweepingStrikesTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_SWEEPING_STRIKES) == CAST_OK) + m_uiSweepingStrikesTimer = urand(22000, 26000); + } + else + m_uiSweepingStrikesTimer -= uiDiff; - //Check_Timer for the death of LorKhan and Zath. - if (!FakeDeath && Check_Timer < diff) - { - if (m_pInstance) - { - if (m_pInstance->GetData(TYPE_LORKHAN) == SPECIAL) + // SinisterStrike_Timer + if (m_uiSinisterStrikeTimer < uiDiff) { - //Resurrect LorKhan - if (Creature* pLorKhan = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_LORKHAN))) - { - pLorKhan->SetStandState(UNIT_STAND_STATE_STAND); - pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pLorKhan->setFaction(14); - pLorKhan->SetHealth(int(pLorKhan->GetMaxHealth()*1.0)); - } + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SINISTER_STRIKE) == CAST_OK) + m_uiSinisterStrikeTimer = urand(8000, 16000); } + else + m_uiSinisterStrikeTimer -= uiDiff; - if (m_pInstance->GetData(TYPE_THEKAL) == SPECIAL) + // Gouge_Timer + if (m_uiGougeTimer < uiDiff) { - //Resurrect Thekal - if (Creature* pThekal = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_THEKAL))) + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_GOUGE) == CAST_OK) { - pThekal->SetStandState(UNIT_STAND_STATE_STAND); - pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - pThekal->setFaction(14); - pThekal->SetHealth(int(pThekal->GetMaxHealth()*1.0)); + if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) + m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100); + + m_uiGougeTimer = urand(17000, 27000); } } - } + else + m_uiGougeTimer -= uiDiff; - Check_Timer = 5000; - }else Check_Timer -= diff; - - if (m_creature->GetHealthPercent() <= 5.0f) - { - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetStandState(UNIT_STAND_STATE_SLEEP); - m_creature->setFaction(35); - m_creature->AttackStop(); + // Kick_Timer + if (m_uiKickTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_KICK) == CAST_OK) + m_uiKickTimer = urand(15000, 25000); + } + else + m_uiKickTimer -= uiDiff; - if (m_pInstance) - m_pInstance->SetData(TYPE_ZATH, SPECIAL); + // Blind_Timer + if (m_uiBlindTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLIND) == CAST_OK) + m_uiBlindTimer = urand(10000, 20000); + } + else + m_uiBlindTimer -= uiDiff; - FakeDeath = true; + break; } DoMeleeAttackIfReady(); } }; +bool EffectDummyCreature_thekal_resurrection(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +{ + //always check spellid and effectindex + if (uiSpellId == SPELL_RESURRECT && uiEffIndex == EFFECT_INDEX_0) + { + if (boss_thekalBaseAI* pFakerAI = dynamic_cast(pCreatureTarget->AI())) + pFakerAI->Revive(); + + //always return true when we are handling this spell and effect + return true; + } + + return false; +} + CreatureAI* GetAI_boss_thekal(Creature* pCreature) { return new boss_thekalAI(pCreature); @@ -526,20 +660,23 @@ CreatureAI* GetAI_mob_zealot_zath(Creature* pCreature) void AddSC_boss_thekal() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_thekal"; - newscript->GetAI = &GetAI_boss_thekal; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_zealot_lorkhan"; - newscript->GetAI = &GetAI_mob_zealot_lorkhan; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_zealot_zath"; - newscript->GetAI = &GetAI_mob_zealot_zath; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_thekal"; + pNewScript->GetAI = &GetAI_boss_thekal; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_thekal_resurrection; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_zealot_lorkhan"; + pNewScript->GetAI = &GetAI_mob_zealot_lorkhan; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_thekal_resurrection; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_zealot_zath"; + pNewScript->GetAI = &GetAI_mob_zealot_zath; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_thekal_resurrection; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp b/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp index 875a77f34..9495e1a6d 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -69,7 +69,7 @@ struct MANGOS_DLL_DECL boss_venoxisAI : public ScriptedAI bool m_bPhaseTwo; bool m_bInBerserk; - + float m_fDefaultSize; void Reset() @@ -180,7 +180,7 @@ struct MANGOS_DLL_DECL boss_venoxisAI : public ScriptedAI for(uint8 i = 0; i < 10; ++i) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,i)) - if (m_creature->IsWithinDistInMap(pTarget, ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(pTarget)) ++m_uiTargetsInRangeCount; } diff --git a/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp b/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp index 38b74e6aa..5a5ea2aca 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp b/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp index c0818ae3f..a2b4b66e3 100644 --- a/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp +++ b/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,221 +24,189 @@ EndScriptData */ #include "precompiled.h" #include "zulgurub.h" -struct MANGOS_DLL_DECL instance_zulgurub : public ScriptedInstance +instance_zulgurub::instance_zulgurub(Map* pMap) : ScriptedInstance(pMap), + m_uiLorKhanGUID(0), + m_uiZathGUID(0), + m_uiThekalGUID(0), + m_uiJindoGUID(0), + m_uiHakkarGUID(0), + m_bHasIntroYelled(false), + m_bHasAltarYelled(false) { - instance_zulgurub(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - std::string strInstData; - // If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too. - uint32 m_auiEncounter[MAX_ENCOUNTER]; + Initialize(); +} - // Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for heal function too. - uint64 m_uiLorKhanGUID; - uint64 m_uiZathGUID; - uint64 m_uiThekalGUID; - uint64 m_uiJindoGUID; - uint64 m_uiHakkarGUID; +void instance_zulgurub::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - void Initialize() +void instance_zulgurub::DoYellAtTriggerIfCan(uint32 uiTriggerId) +{ + if (uiTriggerId == AREATRIGGER_ENTER && !m_bHasIntroYelled) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiLorKhanGUID = 0; - m_uiZathGUID = 0; - m_uiThekalGUID = 0; - m_uiJindoGUID = 0; - m_uiHakkarGUID = 0; + if (Creature* pHakkar = instance->GetCreature(m_uiHakkarGUID)) + { + DoScriptText(SAY_HAKKAR_PROTECT, pHakkar); + m_bHasIntroYelled = true; + } } - - // each time High Priest dies lower Hakkar's HP - void LowerHakkarHitPoints() + else if (uiTriggerId == AREATRIGGER_ALTAR && !m_bHasAltarYelled) { if (Creature* pHakkar = instance->GetCreature(m_uiHakkarGUID)) { - if (pHakkar->isAlive()) - { - pHakkar->SetMaxHealth(pHakkar->GetMaxHealth() - 60000); - pHakkar->SetHealth(pHakkar->GetHealth() - 60000); - } + DoScriptText(SAY_MINION_DESTROY, pHakkar); + m_bHasAltarYelled = true; } } +} - bool IsEncounterInProgress() const +void instance_zulgurub::OnCreatureCreate(Creature* pCreature) +{ + switch(pCreature->GetEntry()) { - //not active in Zul'Gurub - return false; + case NPC_LORKHAN: + m_uiLorKhanGUID = pCreature->GetGUID(); + break; + case NPC_ZATH: + m_uiZathGUID = pCreature->GetGUID(); + break; + case NPC_THEKAL: + m_uiThekalGUID = pCreature->GetGUID(); + break; + case NPC_JINDO: + m_uiJindoGUID = pCreature->GetGUID(); + break; + case NPC_HAKKAR: + m_uiHakkarGUID = pCreature->GetGUID(); + break; } +} - void OnCreatureCreate(Creature* pCreature) +void instance_zulgurub::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - switch(pCreature->GetEntry()) - { - case NPC_LORKHAN: - m_uiLorKhanGUID = pCreature->GetGUID(); - break; - case NPC_ZATH: - m_uiZathGUID = pCreature->GetGUID(); - break; - case NPC_THEKAL: - m_uiThekalGUID = pCreature->GetGUID(); - break; - case NPC_JINDO: - m_uiJindoGUID = pCreature->GetGUID(); - break; - case NPC_HAKKAR: - m_uiHakkarGUID = pCreature->GetGUID(); - for(uint8 i = 0; i < 5; ++i) - { - if (m_auiEncounter[i] == DONE) - LowerHakkarHitPoints(); - } - break; - } + case TYPE_JEKLIK: + case TYPE_VENOXIS: + case TYPE_MARLI: + case TYPE_THEKAL: + case TYPE_ARLOKK: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoLowerHakkarHitPoints(); + break; + case TYPE_OHGAN: + case TYPE_LORKHAN: + case TYPE_ZATH: + m_auiEncounter[uiType] = uiData; + break; } - void SetData(uint32 uiType, uint32 uiData) + if (uiData == DONE) { - switch(uiType) - { - case TYPE_ARLOKK: - m_auiEncounter[0] = uiData; - if (uiData == DONE) - LowerHakkarHitPoints(); - break; - case TYPE_JEKLIK: - m_auiEncounter[1] = uiData; - if (uiData == DONE) - LowerHakkarHitPoints(); - break; - case TYPE_VENOXIS: - m_auiEncounter[2] = uiData; - if (uiData == DONE) - LowerHakkarHitPoints(); - break; - case TYPE_MARLI: - m_auiEncounter[3] = uiData; - if (uiData == DONE) - LowerHakkarHitPoints(); - break; - case TYPE_THEKAL: - m_auiEncounter[4] = uiData; - if (uiData == DONE) - LowerHakkarHitPoints(); - break; - case TYPE_LORKHAN: - m_auiEncounter[5] = uiData; - break; - case TYPE_ZATH: - m_auiEncounter[6] = uiData; - break; - case TYPE_OHGAN: - m_auiEncounter[7] = uiData; - break; - case TYPE_HAKKAR: - m_auiEncounter[8] = 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_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8]; + OUT_SAVE_INST_DATA; - strInstData = saveStream.str(); + 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]; - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } - } + m_strInstData = saveStream.str(); - const char* Save() - { - return strInstData.c_str(); + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - void Load(const char* chrIn) +// Each time High Priest dies lower Hakkar's HP +void instance_zulgurub::DoLowerHakkarHitPoints() +{ + if (Creature* pHakkar = instance->GetCreature(m_uiHakkarGUID)) { - if (!chrIn) + if (pHakkar->isAlive() && pHakkar->GetMaxHealth() > HP_LOSS_PER_PRIEST) { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(chrIn); + pHakkar->SetMaxHealth(pHakkar->GetMaxHealth() - HP_LOSS_PER_PRIEST); + pHakkar->SetHealth(pHakkar->GetHealth() - HP_LOSS_PER_PRIEST); + } + } +} - 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]; +void instance_zulgurub::Load(const char* chrIn) +{ + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } + OUT_LOAD_INST_DATA(chrIn); - OUT_LOAD_INST_DATA_COMPLETE; - } + 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]; - uint32 GetData(uint32 uiType) + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) { - switch(uiType) - { - case TYPE_ARLOKK: - return m_auiEncounter[0]; - case TYPE_JEKLIK: - return m_auiEncounter[1]; - case TYPE_VENOXIS: - return m_auiEncounter[2]; - case TYPE_MARLI: - return m_auiEncounter[3]; - case TYPE_THEKAL: - return m_auiEncounter[4]; - case TYPE_LORKHAN: - return m_auiEncounter[5]; - case TYPE_ZATH: - return m_auiEncounter[6]; - case TYPE_OHGAN: - return m_auiEncounter[7]; - case TYPE_HAKKAR: - return m_auiEncounter[8]; - } - return 0; + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; } - uint64 GetData64(uint32 uiData) + OUT_LOAD_INST_DATA_COMPLETE; +} + +uint32 instance_zulgurub::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + + return 0; +} + +uint64 instance_zulgurub::GetData64(uint32 uiData) +{ + switch(uiData) { - switch(uiData) - { - case DATA_LORKHAN: - return m_uiLorKhanGUID; - case DATA_ZATH: - return m_uiZathGUID; - case DATA_THEKAL: - return m_uiThekalGUID; - case DATA_JINDO: - return m_uiJindoGUID; - case DATA_HAKKAR: - return m_uiHakkarGUID; - } - return 0; + case NPC_LORKHAN: return m_uiLorKhanGUID; + case NPC_ZATH: return m_uiZathGUID; + case NPC_THEKAL: return m_uiThekalGUID; + case NPC_JINDO: return m_uiJindoGUID; + case NPC_HAKKAR: return m_uiHakkarGUID; + default: + return 0; } -}; +} InstanceData* GetInstanceData_instance_zulgurub(Map* pMap) { return new instance_zulgurub(pMap); } +bool AreaTrigger_at_zulgurub(Player* pPlayer, AreaTriggerEntry const* pAt) +{ + if (pAt->id == AREATRIGGER_ENTER || pAt->id == AREATRIGGER_ALTAR) + { + if (pPlayer->isGameMaster() || pPlayer->isDead()) + return false; + + if (instance_zulgurub* pInstance = (instance_zulgurub*)pPlayer->GetInstanceData()) + pInstance->DoYellAtTriggerIfCan(pAt->id); + } + + return false; +} + void AddSC_instance_zulgurub() { - Script* newscript; - newscript = new Script; - newscript->Name = "instance_zulgurub"; - newscript->GetInstanceData = &GetInstanceData_instance_zulgurub; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_zulgurub"; + pNewScript->GetInstanceData = &GetInstanceData_instance_zulgurub; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "at_zulgurub"; + pNewScript->pAreaTrigger = &AreaTrigger_at_zulgurub; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/zulgurub/zulgurub.h b/scripts/eastern_kingdoms/zulgurub/zulgurub.h index bab1e24b3..b798017a7 100644 --- a/scripts/eastern_kingdoms/zulgurub/zulgurub.h +++ b/scripts/eastern_kingdoms/zulgurub/zulgurub.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,7 +7,17 @@ enum { - MAX_ENCOUNTER = 9, + MAX_ENCOUNTER = 8, + MAX_PRIESTS = 5, + + TYPE_JEKLIK = 0, + TYPE_VENOXIS = 1, + TYPE_MARLI = 2, + TYPE_THEKAL = 3, + TYPE_ARLOKK = 4, + TYPE_OHGAN = 5, // Do not change, used by Acid + TYPE_LORKHAN = 6, + TYPE_ZATH = 7, NPC_LORKHAN = 11347, NPC_ZATH = 11348, @@ -15,21 +25,49 @@ enum NPC_JINDO = 11380, NPC_HAKKAR = 14834, - TYPE_ARLOKK = 1, - TYPE_JEKLIK = 2, - TYPE_VENOXIS = 3, - TYPE_MARLI = 4, - TYPE_OHGAN = 5, - TYPE_THEKAL = 6, - TYPE_ZATH = 7, - TYPE_LORKHAN = 8, - TYPE_HAKKAR = 9, - - DATA_JINDO = 10, - DATA_LORKHAN = 11, - DATA_THEKAL = 12, - DATA_ZATH = 13, - DATA_HAKKAR = 14 + SAY_MINION_DESTROY = -1309022, + SAY_HAKKAR_PROTECT = -1309023, + + HP_LOSS_PER_PRIEST = 60000, + + AREATRIGGER_ENTER = 3958, + AREATRIGGER_ALTAR = 3960, +}; + +class MANGOS_DLL_DECL instance_zulgurub : public ScriptedInstance +{ + public: + instance_zulgurub(Map* pMap); + ~instance_zulgurub() {} + + void Initialize(); + // IsEncounterInProgress() const { return false; } // not active in Zul'Gurub + + void OnCreatureCreate(Creature* pCreature); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + void DoYellAtTriggerIfCan(uint32 uiTriggerId); + + protected: + void DoLowerHakkarHitPoints(); + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiLorKhanGUID; + uint64 m_uiZathGUID; + uint64 m_uiThekalGUID; + uint64 m_uiJindoGUID; + uint64 m_uiHakkarGUID; + + bool m_bHasIntroYelled; + bool m_bHasAltarYelled; }; #endif diff --git a/scripts/examples/example_creature.cpp b/scripts/examples/example_creature.cpp index 76ea943a1..0ed28dc78 100644 --- a/scripts/examples/example_creature.cpp +++ b/scripts/examples/example_creature.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -37,9 +37,8 @@ EndScriptData */ enum { - //List of text id's. The text is stored in database, also in a localized version - //(if translation not exist for the textId, default english text will be used) - //Not required to define in this way, but simplify if changes are needed. + // List of text id's. The text is stored in database, also in a localized version + // (if translation not exist for the textId, default english text will be used) SAY_AGGRO = -1999900, SAY_RANDOM_0 = -1999901, SAY_RANDOM_1 = -1999902, @@ -51,7 +50,7 @@ enum SAY_DANCE = -1999908, SAY_SALUTE = -1999909, - //List of spells. Not required to define them in this way, but will make it easier to maintain in case spellId change + // List of used spells SPELL_BUFF = 25661, SPELL_ONE = 12555, SPELL_ONE_ALT = 24099, @@ -60,52 +59,57 @@ enum SPELL_ENRAGE = 23537, SPELL_BESERK = 32309, + // Some other information we need to store + TEXT_ID_GREET = 907, FACTION_WORGEN = 24 }; -//List of gossip item texts. Items will appear in the gossip window. +// List of gossip item texts. Items will appear in the gossip window. +// Actually such gossip can already be handled in normal World-Database +// If (and only if) a gossip must be handled within SD2, then it should be moved to SD2-database! #define GOSSIP_ITEM "I'm looking for a fight" struct MANGOS_DLL_DECL example_creatureAI : public ScriptedAI { - //*** HANDLED FUNCTION *** - //This is the constructor, called only once when the creature is first created - example_creatureAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - //*** CUSTOM VARIABLES **** - //These variables are for use only by this individual script. - //Nothing else will ever call them but us. - - uint32 m_uiSay_Timer; //Timer for random chat - uint32 m_uiRebuff_Timer; //Timer for rebuffing - uint32 m_uiSpell_1_Timer; //Timer for spell 1 when in combat - uint32 m_uiSpell_2_Timer; //Timer for spell 1 when in combat - uint32 m_uiSpell_3_Timer; //Timer for spell 1 when in combat - uint32 m_uiBeserk_Timer; //Timer until we go into Beserk (enraged) mode - uint32 m_uiPhase; //The current battle phase we are in - uint32 m_uiPhase_Timer; //Timer until phase transition - - //*** HANDLED FUNCTION *** - //This is called whenever the core decides we need to evade + // *** HANDLED FUNCTION *** + // This is the constructor, called only once when the creature is first created + example_creatureAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + + // *** CUSTOM VARIABLES **** + // These variables are for use only by this individual script. + // Nothing else will ever call them but us. + + uint32 m_uiSayTimer; // Timer for random chat + uint32 m_uiRebuffTimer; // Timer for rebuffing + uint32 m_uiSpellOneTimer; // Timer for spell 1 when in combat + uint32 m_uiSpellTwoTimer; // Timer for spell 1 when in combat + uint32 m_uiSpellThreeTimer; // Timer for spell 1 when in combat + uint32 m_uiBeserkTimer; // Timer until we go into Beserk (enraged) mode + uint32 m_uiPhase; // The current battle phase we are in + uint32 m_uiPhaseTimer; // Timer until phase transition + + // *** HANDLED FUNCTION *** + // This is called whenever the core decides we need to evade void Reset() { - m_uiPhase = 1; //Start in phase 1 - m_uiPhase_Timer = 60000; //60 seconds - m_uiSpell_1_Timer = 5000; //5 seconds - m_uiSpell_2_Timer = 37000; //37 seconds - m_uiSpell_3_Timer = 19000; //19 seconds - m_uiBeserk_Timer = 120000; //2 minutes + m_uiPhase = 1; // Start in phase 1 + m_uiPhaseTimer = 60000; // 60 seconds + m_uiSpellOneTimer = 5000; // 5 seconds + m_uiSpellTwoTimer = 37000; // 37 seconds + m_uiSpellThreeTimer = 19000; // 19 seconds + m_uiBeserkTimer = 120000; // 2 minutes } - //*** HANDLED FUNCTION *** - //Attack Start is called whenever someone hits us. + // *** HANDLED FUNCTION *** + // Aggro is called when we enter combat, against an enemy, and haven't been in combat before void Aggro(Unit* pWho) { - //Say some stuff + // Say some stuff DoScriptText(SAY_AGGRO, m_creature, pWho); } - //Our Recive emote function + // *** HANDLED FUNCTION *** + // Our Recive emote function void ReceiveEmote(Player* pPlayer, uint32 uiTextEmote) { m_creature->HandleEmote(uiTextEmote); @@ -121,17 +125,17 @@ struct MANGOS_DLL_DECL example_creatureAI : public ScriptedAI } } - //*** HANDLED FUNCTION *** - //Update AI is called Every single map update (roughly once every 100ms if a player is within the grid) + // *** HANDLED FUNCTION *** + // Update AI is called Every single map update (roughly once every 100ms if a player is within the grid) void UpdateAI(const uint32 uiDiff) { - //Out of combat timers + // Out of combat timers if (!m_creature->getVictim()) { - //Random Say timer - if (m_uiSay_Timer < uiDiff) + // Random Say timer + if (m_uiSayTimer < uiDiff) { - //Random switch between 5 outcomes + // Random switch between 5 outcomes switch(urand(0, 4)) { case 0: DoScriptText(SAY_RANDOM_0, m_creature); break; @@ -141,106 +145,130 @@ struct MANGOS_DLL_DECL example_creatureAI : public ScriptedAI case 4: DoScriptText(SAY_RANDOM_4, m_creature); break; } - m_uiSay_Timer = 45000; //Say something agian in 45 seconds + m_uiSayTimer = 45*IN_MILLISECONDS; // Say something agian in 45 seconds } else - m_uiSay_Timer -= uiDiff; + m_uiSayTimer -= uiDiff; - //Rebuff timer - if (m_uiRebuff_Timer < uiDiff) + // Rebuff timer + if (m_uiRebuffTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_BUFF); - m_uiRebuff_Timer = 900000; //Rebuff agian in 15 minutes + // Rebuff agian in 15 minutes + m_uiRebuffTimer = 15*MINUTE*IN_MILLISECONDS; } else - m_uiRebuff_Timer -= uiDiff; + m_uiRebuffTimer -= uiDiff; } - //Return since we have no target + // Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - //Spell 1 timer - if (m_uiSpell_1_Timer < uiDiff) + // Abilities of all phases + // Spell One timer + if (m_uiSpellOneTimer < uiDiff) { - //Cast spell one on our current target. + // Cast spell one on our current target. if (rand()%50 > 10) DoCastSpellIfCan(m_creature->getVictim(), SPELL_ONE_ALT); else if (m_creature->IsWithinDist(m_creature->getVictim(), 25.0f)) DoCastSpellIfCan(m_creature->getVictim(), SPELL_ONE); - m_uiSpell_1_Timer = 5000; + m_uiSpellOneTimer = 5000; } else - m_uiSpell_1_Timer -= uiDiff; + m_uiSpellOneTimer -= uiDiff; - //Spell 2 timer - if (m_uiSpell_2_Timer < uiDiff) + // Spell Two timer + if (m_uiSpellTwoTimer < uiDiff) { - //Cast spell one on our current target. - DoCastSpellIfCan(m_creature->getVictim(), SPELL_TWO); - m_uiSpell_2_Timer = 37000; + // Cast spell two on self (AoE spell with only self-target) if we can + if (DoCastSpellIfCan(m_creature, SPELL_TWO) == CAST_OK) + m_uiSpellTwoTimer = 37*IN_MILLISECONDS; // Only Update Timer, if we could start casting } else - m_uiSpell_2_Timer -= uiDiff; + m_uiSpellTwoTimer -= uiDiff; - //Beserk timer - if (m_uiPhase > 1) + // End of abliities of all phases + + // Phase 1 abilities + if (m_uiPhase == 1) { - //Spell 3 timer - if (m_uiSpell_3_Timer < uiDiff) + // Phase timer + if (m_uiPhaseTimer < uiDiff) { - //Cast spell one on our current target. - DoCastSpellIfCan(m_creature->getVictim(), SPELL_THREE); - - m_uiSpell_3_Timer = 19000; + // Only switch phase and display phase-switich text, if out cast was started sucessfull + if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) + { + // Go to next phase + ++m_uiPhase; + DoScriptText(SAY_PHASE, m_creature); + } } else - m_uiSpell_3_Timer -= uiDiff; - - if (m_uiBeserk_Timer < uiDiff) + m_uiPhaseTimer -= uiDiff; + } + // Phase 2 abilities + else if (m_uiPhase > 1) + { + // Spell Three timer + if (m_uiSpellThreeTimer < uiDiff) { - //Say our line then cast uber death spell - DoScriptText(SAY_BESERK, m_creature, m_creature->getVictim()); - DoCastSpellIfCan(m_creature->getVictim(), SPELL_BESERK); - - //Cast our beserk spell agian in 12 seconds if we didn't kill everyone - m_uiBeserk_Timer = 12000; + // Cast spell three on self (AoE spell with only self-target) + if (DoCastSpellIfCan(m_creature, SPELL_THREE) == CAST_OK) + m_uiSpellThreeTimer = 19000; } else - m_uiBeserk_Timer -= uiDiff; - } - else if (m_uiPhase == 1) //Phase timer - { - if (m_uiPhase_Timer < uiDiff) + m_uiSpellThreeTimer -= uiDiff; + + // Beserk timer + if (m_uiBeserkTimer < uiDiff) { - //Go to next phase - ++m_uiPhase; - DoScriptText(SAY_PHASE, m_creature); - DoCastSpellIfCan(m_creature, SPELL_ENRAGE); + // Cast uber death spell if possible + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_BESERK) == CAST_OK) + { + // Say our line if we cast + DoScriptText(SAY_BESERK, m_creature, m_creature->getVictim()); + + // Cast our beserk spell agian in 12 seconds (if we didn't kill everyone) + m_uiBeserkTimer = 12000; + } } else - m_uiPhase_Timer -= uiDiff; + m_uiBeserkTimer -= uiDiff; } + // Normal behaviour: if possible mobs do attack with melee DoMeleeAttackIfReady(); } }; -//This is the GetAI method used by all scripts that involve AI -//It is called every time a new creature using this script is created +// This is the GetAI method used by all scripts that involve AI +// It is called every time a new creature using this script is created CreatureAI* GetAI_example_creature(Creature* pCreature) { return new example_creatureAI(pCreature); } -//This function is called when the player clicks an option on the gossip menu +// This function is called when the player opens the gossip menu +// In this case as there is nothing special about this gossip dialogue, it should be moved to world-DB +bool GossipHello_example_creature(Player* pPlayer, Creature* pCreature) +{ + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + pPlayer->SEND_GOSSIP_MENU(TEXT_ID_GREET, pCreature->GetGUID()); + + return true; +} + +// This function is called when the player clicks an option on the gossip menu +// In this case here the faction change could be handled by world-DB gossip, hence it should be handled there! bool GossipSelect_example_creature(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { if (uiAction == GOSSIP_ACTION_INFO_DEF+1) { pPlayer->CLOSE_GOSSIP_MENU(); - //Set our faction to hostile twoards all + // Set our faction to hostile towards all pCreature->setFaction(FACTION_WORGEN); pCreature->AI()->AttackStart(pPlayer); } @@ -248,25 +276,16 @@ bool GossipSelect_example_creature(Player* pPlayer, Creature* pCreature, uint32 return true; } -//This function is called when the player opens the gossip menu -bool GossipHello_example_creature(Player* pPlayer, Creature* pCreature) -{ - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); - - return true; -} - -//This is the actual function called only once durring InitScripts() -//It must define all handled functions that are to be run in this script +// This is the actual function called only once durring InitScripts() +// It must define all handled functions that are to be run in this script void AddSC_example_creature() { - Script* newscript; - - newscript = new Script; - newscript->Name = "example_creature"; - newscript->GetAI = &GetAI_example_creature; - newscript->pGossipHello = &GossipHello_example_creature; - newscript->pGossipSelect = &GossipSelect_example_creature; - newscript->RegisterSelf(false); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "example_creature"; + pNewScript->GetAI = &GetAI_example_creature; + pNewScript->pGossipHello = &GossipHello_example_creature; + pNewScript->pGossipSelect = &GossipSelect_example_creature; + pNewScript->RegisterSelf(false); } diff --git a/scripts/examples/example_escort.cpp b/scripts/examples/example_escort.cpp index 58b23cb4d..066dd94d4 100644 --- a/scripts/examples/example_escort.cpp +++ b/scripts/examples/example_escort.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -53,11 +53,18 @@ enum struct MANGOS_DLL_DECL example_escortAI : public npc_escortAI { // CreatureAI functions - example_escortAI(Creature* pCreature) : npc_escortAI(pCreature) {Reset();} + example_escortAI(Creature* pCreature) : npc_escortAI(pCreature) { Reset(); } uint32 m_uiDeathCoilTimer; uint32 m_uiChatTimer; + // Is called after each combat, so usally only reset combat-stuff here + void Reset() + { + m_uiDeathCoilTimer = 4000; + m_uiChatTimer = 4000; + } + void JustSummoned(Creature* pSummoned) { pSummoned->AI()->AttackStart(m_creature); @@ -98,12 +105,7 @@ struct MANGOS_DLL_DECL example_escortAI : public npc_escortAI DoScriptText(SAY_AGGRO2, m_creature); } - void Reset() - { - m_uiDeathCoilTimer = 4000; - m_uiChatTimer = 4000; - } - + // Only overwrite if there is something special void JustDied(Unit* pKiller) { if (HasEscortState(STATE_ESCORT_ESCORTING)) @@ -122,15 +124,15 @@ struct MANGOS_DLL_DECL example_escortAI : public npc_escortAI } else DoScriptText(SAY_DEATH_3, m_creature); + + // Fail quest for group - if you don't implement JustDied in your script, this will automatically work + npc_escortAI::JustDied(pKiller); } - void UpdateAI(const uint32 uiDiff) + void UpdateEscortAI(const uint32 uiDiff) { - //Must update npc_escortAI - npc_escortAI::UpdateAI(uiDiff); - - //Combat check - if (m_creature->getVictim()) + // Combat check + if (m_creature->SelectHostileTarget() && m_creature->getVictim()) { if (m_uiDeathCoilTimer < uiDiff) { @@ -140,6 +142,8 @@ struct MANGOS_DLL_DECL example_escortAI : public npc_escortAI } else m_uiDeathCoilTimer -= uiDiff; + + DoMeleeAttackIfReady(); } else { @@ -176,7 +180,7 @@ CreatureAI* GetAI_example_escort(Creature* pCreature) bool GossipHello_example_escort(Player* pPlayer, Creature* pCreature) { pPlayer->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID()); - pPlayer->PrepareGossipMenu(pCreature, 0); + pPlayer->PrepareGossipMenu(pCreature, pPlayer->GetDefaultGossipMenuForSource(pCreature)); pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); @@ -220,11 +224,12 @@ bool GossipSelect_example_escort(Player* pPlayer, Creature* pCreature, uint32 ui void AddSC_example_escort() { - Script *newscript; - newscript = new Script; - newscript->Name = "example_escort"; - newscript->GetAI = &GetAI_example_escort; - newscript->pGossipHello = &GossipHello_example_escort; - newscript->pGossipSelect = &GossipSelect_example_escort; - newscript->RegisterSelf(false); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "example_escort"; + pNewScript->GetAI = &GetAI_example_escort; + pNewScript->pGossipHello = &GossipHello_example_escort; + pNewScript->pGossipSelect = &GossipSelect_example_escort; + pNewScript->RegisterSelf(false); } diff --git a/scripts/examples/example_gossip_codebox.cpp b/scripts/examples/example_gossip_codebox.cpp index 1c2cd7654..517e7eee0 100644 --- a/scripts/examples/example_gossip_codebox.cpp +++ b/scripts/examples/example_gossip_codebox.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -34,10 +34,11 @@ enum SAY_CORRECT = -1999924 }; +// Should actually be handled in SD2-database! #define GOSSIP_ITEM_1 "A quiz: what's your name?" #define GOSSIP_ITEM_2 "I'm not interested" -//This function is called when the player opens the gossip menubool +// This function is called when the player opens the gossip menubool bool GossipHello_example_gossip_codebox(Player* pPlayer, Creature* pCreature) { pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1, "", 0, true); @@ -48,7 +49,7 @@ bool GossipHello_example_gossip_codebox(Player* pPlayer, Creature* pCreature) return true; } -//This function is called when the player clicks an option on the gossip menubool +// This function is called when the player clicks an option on the gossip menubool bool GossipSelect_example_gossip_codebox(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { if (uiAction == GOSSIP_ACTION_INFO_DEF+2) @@ -67,7 +68,7 @@ bool GossipSelectWithCode_example_gossip_codebox(Player* pPlayer, Creature* pCre switch (uiAction) { case GOSSIP_ACTION_INFO_DEF+1: - if (std::strcmp(sCode, pPlayer->GetName())!=0) + if (std::strcmp(sCode, pPlayer->GetName()) != 0) { DoScriptText(SAY_WRONG, pCreature); pCreature->CastSpell(pPlayer, SPELL_POLYMORPH, true); @@ -88,12 +89,12 @@ bool GossipSelectWithCode_example_gossip_codebox(Player* pPlayer, Creature* pCre void AddSC_example_gossip_codebox() { - Script* newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "example_gossip_codebox"; - newscript->pGossipHello = &GossipHello_example_gossip_codebox; - newscript->pGossipSelect = &GossipSelect_example_gossip_codebox; - newscript->pGossipSelectWithCode = &GossipSelectWithCode_example_gossip_codebox; - newscript->RegisterSelf(false); + pNewScript = new Script; + pNewScript->Name = "example_gossip_codebox"; + pNewScript->pGossipHello = &GossipHello_example_gossip_codebox; + pNewScript->pGossipSelect = &GossipSelect_example_gossip_codebox; + pNewScript->pGossipSelectWithCode = &GossipSelectWithCode_example_gossip_codebox; + pNewScript->RegisterSelf(false); } diff --git a/scripts/examples/example_misc.cpp b/scripts/examples/example_misc.cpp index df2113163..097dd0255 100644 --- a/scripts/examples/example_misc.cpp +++ b/scripts/examples/example_misc.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -28,7 +28,7 @@ enum SAY_HI = -1999925 }; -bool AT_example_areatrigger(Player* pPlayer, AreaTriggerEntry const* pAt) +bool AreaTrigger_at_example(Player* pPlayer, AreaTriggerEntry const* pAt) { DoScriptText(SAY_HI, pPlayer); return true; @@ -41,7 +41,7 @@ bool ItemUse_example_item(Player* pPlayer, Item* pItem, SpellCastTargets const& return true; } -bool GOHello_example_go_teleporter(Player* pPlayer, GameObject* pGo) +bool GOUse_example_go_teleporter(Player* pPlayer, GameObject* pGo) { pPlayer->TeleportTo(0, 1807.07f, 336.105f, 70.3975f, 0.0f); return false; @@ -49,20 +49,20 @@ bool GOHello_example_go_teleporter(Player* pPlayer, GameObject* pGo) void AddSC_example_misc() { - Script* newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "example_areatrigger"; - newscript->pAreaTrigger = &AT_example_areatrigger; - newscript->RegisterSelf(false); + pNewScript = new Script; + pNewScript->Name = "at_example"; + pNewScript->pAreaTrigger = &AreaTrigger_at_example; + pNewScript->RegisterSelf(false); - newscript = new Script; - newscript->Name = "example_item"; - newscript->pItemUse = &ItemUse_example_item; - newscript->RegisterSelf(false); + pNewScript = new Script; + pNewScript->Name = "example_item"; + pNewScript->pItemUse = &ItemUse_example_item; + pNewScript->RegisterSelf(false); - newscript = new Script; - newscript->Name = "example_go_teleporter"; - newscript->pGOHello = &GOHello_example_go_teleporter; - newscript->RegisterSelf(false); + pNewScript = new Script; + pNewScript->Name = "example_go_teleporter"; + pNewScript->pGOUse = &GOUse_example_go_teleporter; + pNewScript->RegisterSelf(false); } diff --git a/scripts/kalimdor/ashenvale.cpp b/scripts/kalimdor/ashenvale.cpp index 925b92cb8..5b6897916 100644 --- a/scripts/kalimdor/ashenvale.cpp +++ b/scripts/kalimdor/ashenvale.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -223,7 +223,7 @@ CreatureAI* GetAI_npc_muglash(Creature* pCreature) return new npc_muglashAI(pCreature); } -bool GOHello_go_naga_brazier(Player* pPlayer, GameObject* pGo) +bool GOUse_go_naga_brazier(Player* pPlayer, GameObject* pGo) { if (Creature* pCreature = GetClosestCreatureWithEntry(pGo, NPC_MUGLASH, INTERACTION_DISTANCE*2)) { @@ -425,23 +425,23 @@ void AddSC_ashenvale() newscript = new Script; newscript->Name = "npc_muglash"; newscript->GetAI = &GetAI_npc_muglash; - newscript->pQuestAccept = &QuestAccept_npc_muglash; + newscript->pQuestAcceptNPC = &QuestAccept_npc_muglash; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "go_naga_brazier"; - newscript->pGOHello = &GOHello_go_naga_brazier; + newscript->pGOUse = &GOUse_go_naga_brazier; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_ruul_snowhoof"; newscript->GetAI = &GetAI_npc_ruul_snowhoofAI; - newscript->pQuestAccept = &QuestAccept_npc_ruul_snowhoof; + newscript->pQuestAcceptNPC = &QuestAccept_npc_ruul_snowhoof; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_torek"; newscript->GetAI = &GetAI_npc_torek; - newscript->pQuestAccept = &QuestAccept_npc_torek; + newscript->pQuestAcceptNPC = &QuestAccept_npc_torek; newscript->RegisterSelf(); } diff --git a/scripts/kalimdor/azshara.cpp b/scripts/kalimdor/azshara.cpp index 496b20e5f..942ee0239 100644 --- a/scripts/kalimdor/azshara.cpp +++ b/scripts/kalimdor/azshara.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -230,7 +230,7 @@ CreatureAI* GetAI_npc_depth_charge(Creature* pCreature) ## go_southfury_moonstone ######*/ -bool GOHello_go_southfury_moonstone(Player* pPlayer, GameObject* pGo) +bool GOUse_go_southfury_moonstone(Player* pPlayer, GameObject* pGo) { //implicitTarget=48 not implemented as of writing this code, and manual summon may be just ok for our purpose //pPlayer->CastSpell(pPlayer,SPELL_SUMMON_RIZZLE,false); @@ -376,7 +376,7 @@ void AddSC_azshara() newscript = new Script; newscript->Name = "go_southfury_moonstone"; - newscript->pGOHello = &GOHello_go_southfury_moonstone; + newscript->pGOUse = &GOUse_go_southfury_moonstone; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/kalimdor/azuremyst_isle.cpp b/scripts/kalimdor/azuremyst_isle.cpp index 5779d2e08..94879c4f5 100644 --- a/scripts/kalimdor/azuremyst_isle.cpp +++ b/scripts/kalimdor/azuremyst_isle.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -453,7 +453,7 @@ void AddSC_azuremyst_isle() newscript = new Script; newscript->Name = "npc_magwin"; newscript->GetAI = &GetAI_npc_magwinAI; - newscript->pQuestAccept = &QuestAccept_npc_magwin; + newscript->pQuestAcceptNPC = &QuestAccept_npc_magwin; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/kalimdor/blackfathom_deeps/blackfathom_deeps.h b/scripts/kalimdor/blackfathom_deeps/blackfathom_deeps.h index 3de750926..98855a35d 100644 --- a/scripts/kalimdor/blackfathom_deeps/blackfathom_deeps.h +++ b/scripts/kalimdor/blackfathom_deeps/blackfathom_deeps.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,23 +7,117 @@ enum { - MAX_ENCOUNTER = 6, + MAX_ENCOUNTER = 2, + MAX_FIRES = 4, + MAX_COUNT_POS = 3, TYPE_KELRIS = 1, TYPE_SHRINE = 2, NPC_KELRIS = 4832, - NPC_SERVANT = 4978, + + // Shrine event + NPC_AKUMAI_SERVANT = 4978, + NPC_AKUMAI_SNAPJAW = 4825, + NPC_BARBED_CRUSTACEAN = 4823, + NPC_MURKSHALLOW_SOFTSHELL = 4977, GO_PORTAL_DOOR = 21117, GO_SHRINE_1 = 21118, GO_SHRINE_2 = 21119, GO_SHRINE_3 = 21120, GO_SHRINE_4 = 21121, +}; + + /* This is the spawn pattern for the event mobs + * D + * 0 3 + * 1 S 4 + * 2 5 + * E + + * This event spawns 4 sets of mobs + * The order in whitch the fires are lit doesn't matter + + * First: 3 Snapjaws: Positions 0, 1, 5 + * Second: 2 Servants: Positions 1, 4 + * Third: 4 Crabs: Positions 0, 2, 3, 4 + * Fourth: 10 Murkshallows: Positions 2*0, 1, 2*2; 3, 2*4, 2*5 + + * On wipe the mobs don't despawn; they stay there until player returns + */ + +struct Locations +{ + float m_fX, m_fY, m_fZ, m_fO; +}; + +static const Locations aSpawnLocations[6] = // Should be near the correct positions +{ + {-768.949f, -174.413f, -25.87f, 3.09f}, // Left side + {-768.888f, -164.238f, -25.87f, 3.09f}, + {-768.951f, -153.911f, -25.88f, 3.09f}, + {-867.782f, -174.352f, -25.87f, 6.27f}, // Right side + {-867.875f, -164.089f, -25.87f, 6.27f}, + {-867.859f, -153.927f, -25.88f, 6.27f} +}; + +struct PosCount +{ + uint8 m_uiCount, m_uiSummonPosition; +}; + +struct SummonInformation +{ + uint8 m_uiWaveIndex; + uint32 m_uiNpcEntry; + PosCount m_aCountAndPos[MAX_COUNT_POS]; +}; + +// ASSERT m_uiSummonPosition < 6 (see aSpawnLocations) +static const SummonInformation aWaveSummonInformation[] = +{ + {0, NPC_AKUMAI_SNAPJAW, {{1, 0}, {1, 1}, {1, 5}}}, + {1, NPC_AKUMAI_SERVANT, {{1, 1}, {1, 4}, {0, 0}}}, + {2, NPC_BARBED_CRUSTACEAN, {{1, 0}, {1, 2}, {0, 0}}}, + {2, NPC_BARBED_CRUSTACEAN, {{1, 3}, {1, 4}, {0, 0}}}, + {3, NPC_MURKSHALLOW_SOFTSHELL, {{2, 0}, {1, 1}, {2, 2}}}, + {3, NPC_MURKSHALLOW_SOFTSHELL, {{1, 3}, {2, 4}, {2, 5}}} +}; + +class MANGOS_DLL_DECL instance_blackfathom_deeps : public ScriptedInstance +{ + public: + instance_blackfathom_deeps(Map* pMap); + ~instance_blackfathom_deeps() {} + + void Initialize(); + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + void OnCreatureDeath(Creature* pCreature); + + void Update(uint32 uiDiff); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + protected: + void DoSpawnMobs(uint8 uiWaveIndex); + bool IsWaveEventFinished(); + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiKelrisGUID; + uint64 m_uiPortalGUID; + uint32 m_uiSpawnMobsTimer[MAX_FIRES]; + uint8 m_uiWaveCounter; - DATA_TWILIGHT_LORD_KELRIS = 10, - DATA_SHRINE_OF_GELIHAST = 11, - DATA_ALTAR_OF_THE_DEEPS = 12 + std::list m_lWaveMobsGuids[MAX_FIRES]; }; #endif diff --git a/scripts/kalimdor/blackfathom_deeps/instance_blackfathom_deeps.cpp b/scripts/kalimdor/blackfathom_deeps/instance_blackfathom_deeps.cpp index 8ca13025d..5978b5345 100644 --- a/scripts/kalimdor/blackfathom_deeps/instance_blackfathom_deeps.cpp +++ b/scripts/kalimdor/blackfathom_deeps/instance_blackfathom_deeps.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -29,202 +29,235 @@ EndScriptData */ Must kill twilight lord for shrine event to be possible */ -struct MANGOS_DLL_DECL instance_blackfathom_deeps : public ScriptedInstance +instance_blackfathom_deeps::instance_blackfathom_deeps(Map* pMap) : ScriptedInstance(pMap), + m_uiKelrisGUID(0), + m_uiPortalGUID(0), + m_uiWaveCounter(0) { - instance_blackfathom_deeps(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + Initialize(); +} - uint64 m_uiKelrisGUID; - uint64 m_uiShrineOfGelihastGUID; - uint64 m_uiAltarOfTheDeepsGUID; - uint64 m_uiPortalGUID; - uint32 m_uiSpawnServantTimer; +void instance_blackfathom_deeps::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + memset(&m_uiSpawnMobsTimer, 0, sizeof(m_uiSpawnMobsTimer)); +} - uint32 m_auiEncounter[MAX_ENCOUNTER]; +void instance_blackfathom_deeps::OnCreatureCreate(Creature* pCreature) +{ + if (pCreature->GetEntry() == NPC_KELRIS) + m_uiKelrisGUID = pCreature->GetGUID(); +} - void Initialize() +void instance_blackfathom_deeps::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiKelrisGUID = 0; - m_uiShrineOfGelihastGUID = 0; - m_uiAltarOfTheDeepsGUID = 0; - m_uiPortalGUID = 0; - m_uiSpawnServantTimer = 0; + case GO_PORTAL_DOOR: + if (m_auiEncounter[1] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + + m_uiPortalGUID = pGo->GetGUID(); + break; + case GO_SHRINE_1: + case GO_SHRINE_2: + case GO_SHRINE_3: + case GO_SHRINE_4: + if (m_auiEncounter[1] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; } +} - void OnCreatureCreate(Creature* pCreature) - { - if (pCreature->GetEntry() == NPC_KELRIS) - m_uiKelrisGUID = pCreature->GetGUID(); - } +void instance_blackfathom_deeps::DoSpawnMobs(uint8 uiWaveIndex) +{ + Creature* pKelris = instance->GetCreature(m_uiKelrisGUID); + if (!pKelris) + return; - void OnObjectCreate(GameObject* pGo) - { - switch(pGo->GetEntry()) - { - case GO_PORTAL_DOOR: - if (m_auiEncounter[1] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - - m_uiPortalGUID = pGo->GetGUID(); - break; - case GO_SHRINE_1: - if (m_auiEncounter[2] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_SHRINE_2: - if (m_auiEncounter[3] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_SHRINE_3: - if (m_auiEncounter[4] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_SHRINE_4: - if (m_auiEncounter[5] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - - case 103015: m_uiShrineOfGelihastGUID = pGo->GetGUID(); break; - case 103016: m_uiAltarOfTheDeepsGUID = pGo->GetGUID(); break; - - } - } + float fX_resp, fY_resp, fZ_resp; - bool CanOpenEndDoor() + pKelris->GetRespawnCoord(fX_resp, fY_resp, fZ_resp); + + for (uint8 i = 0; i < sizeof(aWaveSummonInformation) / sizeof(SummonInformation); ++i) { - if (m_auiEncounter[0] != DONE) - return false; + if (aWaveSummonInformation[i].m_uiWaveIndex != uiWaveIndex) + continue; - if (m_auiEncounter[2] == DONE && m_auiEncounter[3] == DONE && m_auiEncounter[4] == DONE && m_auiEncounter[5] == DONE) - return true; + // Summon mobs at positions + for (uint8 j = 0; j < MAX_COUNT_POS; ++j) + { + for (uint8 k = 0; k < aWaveSummonInformation[i].m_aCountAndPos[j].m_uiCount; ++k) + { + uint8 uiPos = aWaveSummonInformation[i].m_aCountAndPos[j].m_uiSummonPosition; + float fPosX = aSpawnLocations[uiPos].m_fX; + float fPosY = aSpawnLocations[uiPos].m_fY; + float fPosZ = aSpawnLocations[uiPos].m_fZ; + float fPosO = aSpawnLocations[uiPos].m_fO; - return false; + // Adapt fPosY slightly in case of higher summon-counts + if (aWaveSummonInformation[i].m_aCountAndPos[j].m_uiCount > 1) + fPosY = fPosY - INTERACTION_DISTANCE / 2 + k * INTERACTION_DISTANCE / aWaveSummonInformation[i].m_aCountAndPos[j].m_uiCount; + + if (Creature* pSummoned = pKelris->SummonCreature(aWaveSummonInformation[i].m_uiNpcEntry, fPosX, fPosY, fPosZ, fPosO, TEMPSUMMON_DEAD_DESPAWN, 0)) + { + pSummoned->GetMotionMaster()->MovePoint(0, fX_resp, fY_resp, fZ_resp); + m_lWaveMobsGuids[uiWaveIndex].push_back(pSummoned->GetGUIDLow()); + } + } + } } +} - void SpawnServants() +void instance_blackfathom_deeps::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - if (Creature* pKelris = instance->GetCreature(m_uiKelrisGUID)) - { - float fX_resp, fY_resp, fZ_resp; - pKelris->GetRespawnCoord(fX_resp, fY_resp, fZ_resp); - - for(uint8 i = 0; i < 5 ; ++i) + case TYPE_KELRIS: // EventAI must set instance data (1,3) at his death + if (m_auiEncounter[0] != DONE && uiData == DONE) + m_auiEncounter[0] = uiData; + break; + case TYPE_SHRINE: + m_auiEncounter[1] = uiData; + if (uiData == IN_PROGRESS) { - // this part gets a random position at circumference point in a circle - // fRadius is how far from center to calculate. - // here we use kelris's close point coords as base and then move the summoned to the location of his respawn coords - float fRadius = 30.0f; - float fAngle = 2.0 * M_PI * rand_norm(); + m_uiSpawnMobsTimer[m_uiWaveCounter] = 3000; + ++m_uiWaveCounter; + } + else if (uiData == DONE) + DoUseDoorOrButton(m_uiPortalGUID); + break; + } - float fX, fY, fZ; + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; - fRadius *= sqrt(rand_norm()); + std::ostringstream saveStream; - pKelris->GetClosePoint(fX, fY, fZ, 0.0f, fRadius, fAngle); + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1]; - if (Creature* pServant = pKelris->SummonCreature(NPC_SERVANT, fX, fY, fZ, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000)) - pServant->GetMotionMaster()->MovePoint(0, fX_resp, fY_resp, fZ_resp); - } + m_strInstData = saveStream.str(); + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } +} - } +uint32 instance_blackfathom_deeps::GetData(uint32 uiType) +{ + switch(uiType) + { + case TYPE_KELRIS: return m_auiEncounter[0]; + case TYPE_SHRINE: return m_auiEncounter[1]; + default: + return 0; } +} - void SetData(uint32 uiType, uint32 uiData) +void instance_blackfathom_deeps::Load(const char* chrIn) +{ + if (!chrIn) { - switch(uiType) - { - case TYPE_KELRIS: // eventAI must set instance data (1,3) at his death - if (m_auiEncounter[0] != DONE && uiData == DONE) - m_auiEncounter[0] = uiData; - break; - case TYPE_SHRINE: - { - switch(uiData) - { - case GO_SHRINE_1: - m_auiEncounter[2] = DONE; - break; - case GO_SHRINE_2: - m_auiEncounter[3] = DONE; - break; - case GO_SHRINE_3: - m_auiEncounter[4] = DONE; - break; - case GO_SHRINE_4: - m_auiEncounter[5] = DONE; - break; - } + OUT_LOAD_INST_DATA_FAIL; + return; + } - m_uiSpawnServantTimer = 7500; + OUT_LOAD_INST_DATA(chrIn); - if (CanOpenEndDoor()) - { - m_auiEncounter[1] = DONE; - DoUseDoorOrButton(m_uiPortalGUID); - } + std::istringstream loadStream(chrIn); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1]; - break; - } - } + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; } - uint32 GetData(uint32 uiType) - { - switch(uiType) - { - case TYPE_KELRIS: - return m_auiEncounter[0]; - case TYPE_SHRINE: - return m_auiEncounter[1]; - } + OUT_LOAD_INST_DATA_COMPLETE; +} - return 0; - } +void instance_blackfathom_deeps::OnCreatureDeath(Creature* pCreature) +{ + // Only use this function if shrine event is in progress + if (m_auiEncounter[1] != IN_PROGRESS) + return; - uint64 GetData64(uint32 uiData) + switch (pCreature->GetEntry()) { - switch(uiData) - { - case DATA_TWILIGHT_LORD_KELRIS: - return m_uiKelrisGUID; - case DATA_SHRINE_OF_GELIHAST: - return m_uiShrineOfGelihastGUID; - } + case NPC_AKUMAI_SERVANT: + m_lWaveMobsGuids[1].remove(pCreature->GetGUIDLow()); + break; + case NPC_AKUMAI_SNAPJAW: + m_lWaveMobsGuids[0].remove(pCreature->GetGUIDLow()); + break; + case NPC_BARBED_CRUSTACEAN: + m_lWaveMobsGuids[2].remove(pCreature->GetGUIDLow()); + break; + case NPC_MURKSHALLOW_SOFTSHELL: + m_lWaveMobsGuids[3].remove(pCreature->GetGUIDLow()); + break; + } + + if (IsWaveEventFinished()) + SetData(TYPE_SHRINE, DONE); +} - return 0; +// Check if all the summoned event mobs are dead +bool instance_blackfathom_deeps::IsWaveEventFinished() +{ + // If not all fires are lighted return + if (m_uiWaveCounter < MAX_FIRES) + return false; + + // Check if all mobs are dead + for (uint8 i = 0; i < MAX_FIRES; ++i) + { + if (!m_lWaveMobsGuids[i].empty()) + return false; } - void Update(uint32 uiDiff) + return true; +} + +void instance_blackfathom_deeps::Update(uint32 uiDiff) +{ + // Only use this function if shrine event is in progress + if (m_auiEncounter[1] != IN_PROGRESS) + return; + + for (uint8 i = 0; i < MAX_FIRES; ++i) { - if (m_uiSpawnServantTimer) + if (m_uiSpawnMobsTimer[i]) { - if (m_uiSpawnServantTimer <= uiDiff) + if (m_uiSpawnMobsTimer[i] <= uiDiff) { - SpawnServants(); - m_uiSpawnServantTimer = 0; + DoSpawnMobs(i); + m_uiSpawnMobsTimer[i] = 0; } else - m_uiSpawnServantTimer -= uiDiff; + m_uiSpawnMobsTimer[i] -= uiDiff; } } -}; +} InstanceData* GetInstanceData_instance_blackfathom_deeps(Map* pMap) { return new instance_blackfathom_deeps(pMap); } -bool GOHello_go_fire_of_akumai(Player* pPlayer, GameObject* pGo) +bool GOUse_go_fire_of_akumai(Player* pPlayer, GameObject* pGo) { - ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); + instance_blackfathom_deeps* pInstance = (instance_blackfathom_deeps*)pGo->GetInstanceData(); if (!pInstance) return true; + if (pInstance->GetData(TYPE_SHRINE) == DONE) + return true; + if (pInstance->GetData(TYPE_KELRIS) == DONE) { - pInstance->SetData(TYPE_SHRINE, pGo->GetEntry()); + pInstance->SetData(TYPE_SHRINE, IN_PROGRESS); return false; } @@ -233,15 +266,15 @@ bool GOHello_go_fire_of_akumai(Player* pPlayer, GameObject* pGo) void AddSC_instance_blackfathom_deeps() { - Script *newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "instance_blackfathom_deeps"; - newscript->GetInstanceData = &GetInstanceData_instance_blackfathom_deeps; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "instance_blackfathom_deeps"; + pNewScript->GetInstanceData = &GetInstanceData_instance_blackfathom_deeps; + pNewScript->RegisterSelf(); - newscript = new Script; - newscript->Name = "go_fire_of_akumai"; - newscript->pGOHello = &GOHello_go_fire_of_akumai; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "go_fire_of_akumai"; + pNewScript->pGOUse = &GOUse_go_fire_of_akumai; + pNewScript->RegisterSelf(); } diff --git a/scripts/kalimdor/bloodmyst_isle.cpp b/scripts/kalimdor/bloodmyst_isle.cpp index 7a4531a25..891528a70 100644 --- a/scripts/kalimdor/bloodmyst_isle.cpp +++ b/scripts/kalimdor/bloodmyst_isle.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -52,7 +52,7 @@ struct MANGOS_DLL_DECL mob_webbed_creatureAI : public ScriptedAI case 0: spawnCreatureID = 17681; if (Killer->GetTypeId() == TYPEID_PLAYER) - ((Player*)Killer)->KilledMonsterCredit(spawnCreatureID, m_creature->GetGUID()); + ((Player*)Killer)->KilledMonsterCredit(spawnCreatureID, m_creature->GetObjectGuid()); break; case 1: case 2: @@ -61,7 +61,7 @@ struct MANGOS_DLL_DECL mob_webbed_creatureAI : public ScriptedAI } if (spawnCreatureID) - m_creature->SummonCreature(spawnCreatureID, 0.0f, 0.0f, 0.0f, m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + m_creature->SummonCreature(spawnCreatureID, 0.0f, 0.0f, 0.0f, m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); } }; CreatureAI* GetAI_mob_webbed_creature(Creature* pCreature) diff --git a/scripts/kalimdor/boss_azuregos.cpp b/scripts/kalimdor/boss_azuregos.cpp index d00086db3..d27dcff43 100644 --- a/scripts/kalimdor/boss_azuregos.cpp +++ b/scripts/kalimdor/boss_azuregos.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -70,10 +70,11 @@ struct MANGOS_DLL_DECL boss_azuregosAI : public ScriptedAI { DoScriptText(SAY_TELEPORT, m_creature); - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) DoTeleportPlayer(pUnit, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()+3, pUnit->GetOrientation()); diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite_corruptor.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite_corruptor.cpp new file mode 100644 index 000000000..c380e8af8 --- /dev/null +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite_corruptor.cpp @@ -0,0 +1,132 @@ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ + +#include "precompiled.h" +#include "culling_of_stratholme.h" + +enum +{ + SPELL_COURSE = 60588, + SPELL_STRIKE = 60590 +}; + +struct MANGOS_DLL_DECL boss_infinite_corruptorAI : public ScriptedAI +{ + boss_infinite_corruptorAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiStrikeTimer; + uint32 m_uiCourseTimer; + + void Reset() + { + m_uiCourseTimer = 7000; + m_uiStrikeTimer = 5000; + } + + void Aggro(Unit* who) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_BONUS, SPECIAL); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_BONUS, DONE); + } + + void KilledUnit(Unit* pVictim) + { + //switch(rand()%3) + // { + // case 0: DoScriptText(SAY_EPOCH_SLAY01, m_creature); break; + // case 1: DoScriptText(SAY_EPOCH_SLAY02, m_creature); break; + // case 2: DoScriptText(SAY_EPOCH_SLAY03, m_creature); break; + // } + } + + void EnterEvadeMode() + { + if(!m_pInstance) return; + + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + if(m_pInstance) + m_pInstance->SetData(TYPE_BONUS, IN_PROGRESS); + + if(m_creature->isAlive()) + m_creature->GetMotionMaster()->MoveTargetedHome(); + + m_creature->SetLootRecipient(NULL); + + Reset(); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + + if (m_uiCourseTimer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_COURSE); + + m_uiCourseTimer = 17000; + }else m_uiCourseTimer -= diff; + + if (m_uiStrikeTimer < diff) + { + DoCast(m_creature->getVictim(), SPELL_STRIKE); + + m_uiStrikeTimer = 5000; + }else m_uiStrikeTimer -= diff; + } +}; + +CreatureAI* GetAI_boss_infinite_corruptor(Creature* pCreature) +{ + return new boss_infinite_corruptorAI(pCreature); +} + +void AddSC_boss_infinite_corruptor() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_infinite_corruptor"; + newscript->GetAI = &GetAI_boss_infinite_corruptor; + newscript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_lord_epoch.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_lord_epoch.cpp new file mode 100644 index 000000000..503eb95a6 --- /dev/null +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_lord_epoch.cpp @@ -0,0 +1,148 @@ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ + +#include "precompiled.h" +#include "culling_of_stratholme.h" + +enum +{ + SPELL_COURSE = 52772, + SPELL_TIME_STOP = 58848, + SPELL_TIME_WARP = 52766, + SPELL_SPIKE_N = 52771, + SPELL_SPIKE_H = 58830, + + SAY_EPOCH_DEATH = -1594119, + SAY_EPOCH_SLAY01 = -1594120, + SAY_EPOCH_SLAY02 = -1594121, + SAY_EPOCH_SLAY03 = -1594122, + SAY_EPOCH_WARP01 = -1594123, + SAY_EPOCH_WARP02 = -1594124, + SAY_EPOCH_WARP03 = -1594125 +}; + +struct MANGOS_DLL_DECL boss_lord_epochAI : public ScriptedAI +{ + boss_lord_epochAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 Spike_Timer; + uint32 Warp_Timer; + uint32 Stop_Timer; + uint32 Course_Timer; + uint64 m_uiArthasGUID; + + void Reset() + { + Course_Timer = 9300; + Stop_Timer = 21300; + Warp_Timer = 25300; + Spike_Timer = 5300; + } + + void JustDied(Unit *killer) + { + DoScriptText(SAY_EPOCH_DEATH, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + switch(rand()%3) + { + case 0: DoScriptText(SAY_EPOCH_SLAY01, m_creature); break; + case 1: DoScriptText(SAY_EPOCH_SLAY02, m_creature); break; + case 2: DoScriptText(SAY_EPOCH_SLAY03, m_creature); break; + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + + if (Course_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_COURSE); + + Course_Timer = 9300; + }else Course_Timer -= diff; + + if (Spike_Timer < diff) + { + + DoCast(m_creature->getVictim(),m_bIsHeroic ? SPELL_SPIKE_H : SPELL_SPIKE_N); + + Spike_Timer = 5300; + }else Spike_Timer -= diff; + + if (Stop_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_TIME_STOP); + + Stop_Timer = 21300; + }else Stop_Timer -= diff; + + if (Warp_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_TIME_WARP); + switch(rand()%3) + { + case 0: DoScriptText(SAY_EPOCH_WARP01, m_creature); break; + case 1: DoScriptText(SAY_EPOCH_WARP02, m_creature); break; + case 2: DoScriptText(SAY_EPOCH_WARP03, m_creature); break; + } + + Warp_Timer = 25300; + }else Warp_Timer -= diff; + + } +}; + +CreatureAI* GetAI_boss_lord_epoch(Creature* pCreature) +{ + return new boss_lord_epochAI(pCreature); +} + +void AddSC_boss_lord_epoch() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_lord_epoch"; + newscript->GetAI = &GetAI_boss_lord_epoch; + newscript->RegisterSelf(); +} diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_malganis.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_malganis.cpp new file mode 100644 index 000000000..bc38fc5e6 --- /dev/null +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_malganis.cpp @@ -0,0 +1,243 @@ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ + +#include "precompiled.h" +#include "culling_of_stratholme.h" + +enum +{ + SAY_MALGANIS_AGGRO = -1594170, + SAY_MALGANIS_SLAY01 = -1594172, + SAY_MALGANIS_SLAY02 = -1594173, + SAY_MALGANIS_SLAY03 = -1594174, + SAY_MALGANIS_SLAY04 = -1594175, + SAY_MALGANIS_SLAY05 = -1594176, + SAY_MALGANIS_SLAY06 = -1594177, + SAY_MALGANIS_SLAY07 = -1594166, + SAY_MALGANIS_SLEEP01 = -1594185, + SAY_MALGANIS_SLEEP02 = -1594186, + SAY_MALGANIS_Sleep = -1594178, + SAY_MALGANIS_15HP = -1594179, + + SPELL_SWAMP_N = 52720, + SPELL_SWAMP_H = 58852, + SPELL_MIND_BLAST_N = 52722, + SPELL_MIND_BLAST_H = 58850, + SPELL_SLEEP_N = 52721, + SPELL_SLEEP_H = 58849, + SPELL_VAMPIRE = 52723 +}; + +struct MANGOS_DLL_DECL boss_malganisAI : public ScriptedAI +{ + boss_malganisAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + Unit* pTarget; + bool Sleep; + bool Vampire; + uint32 Phase; + Creature* Malganis; + Creature* Arthas; + + uint32 Swamp_Timer; + uint32 MindBlast_Timer; + uint32 Sleep_Timer; + uint32 Vampire_Timer; + + void Reset() + { + Sleep = false; + Vampire = false; + Swamp_Timer = 6300; + MindBlast_Timer = 11300; + Sleep_Timer = 17300; + Vampire_Timer = 30000; + } + + void AttackStart(Unit* who) + { + if(m_pInstance->GetData(TYPE_PHASE) > 9) return; + + if(m_pInstance->GetData(TYPE_MALGANIS) != IN_PROGRESS) return; + + if(!who || who == m_creature) + return; + + ScriptedAI::AttackStart(who); + } + + void KillCreditMalganis() + { + Map *map = m_creature->GetMap(); + Map::PlayerList const& players = map->GetPlayers(); + if (!players.isEmpty() && map->IsDungeon()) + { + for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if(Player* pPlayer = itr->getSource()) + pPlayer->KilledMonsterCredit(31006, m_creature->GetGUID()); + } + } + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + + if(m_pInstance->GetData(TYPE_PHASE) > 9) + { + KillCreditMalganis(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (Creature* pArthas = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ARTHAS))) + m_creature->SetInCombatWith(pArthas); + } + else + m_creature->RemoveFromWorld(); + + m_creature->SetLootRecipient(NULL); + } + + void Aggro(Unit* who) + { + if(m_pInstance->GetData(TYPE_PHASE) > 9) return; + + DoScriptText(SAY_MALGANIS_AGGRO, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + switch(rand()%7) + { + case 0: DoScriptText(SAY_MALGANIS_SLAY01, m_creature); break; + case 1: DoScriptText(SAY_MALGANIS_SLAY02, m_creature); break; + case 2: DoScriptText(SAY_MALGANIS_SLAY03, m_creature); break; + case 3: DoScriptText(SAY_MALGANIS_SLAY04, m_creature); break; + case 4: DoScriptText(SAY_MALGANIS_SLAY05, m_creature); break; + case 5: DoScriptText(SAY_MALGANIS_SLAY06, m_creature); break; + case 6: DoScriptText(SAY_MALGANIS_SLAY07, m_creature); break; + } + } + + void UpdateAI(const uint32 diff) + { + if(m_pInstance->GetData(TYPE_PHASE) > 9) return; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + + if (Swamp_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsHeroic ? SPELL_SWAMP_H : SPELL_SWAMP_N); + + Swamp_Timer = 7300; + }else Swamp_Timer -= diff; + + if (MindBlast_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsHeroic ? SPELL_MIND_BLAST_H : SPELL_MIND_BLAST_N); + + MindBlast_Timer = 11300; + }else MindBlast_Timer -= diff; + + if(m_creature->GetHealthPercent() < 40.0f) + { + if(Sleep == false) + { + Sleep = true; + DoScriptText(SAY_MALGANIS_Sleep, m_creature); + } + + if (Sleep_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsHeroic ? SPELL_SLEEP_H : SPELL_SLEEP_N); + switch(rand()%2) + { + case 0: DoScriptText(SAY_MALGANIS_SLEEP01, m_creature); break; + case 1: DoScriptText(SAY_MALGANIS_SLEEP02, m_creature); break; + } + + Sleep_Timer = 17300; + }else Sleep_Timer -= diff; + } + + if(m_creature->GetHealthPercent() < 25.0f) + { + if(Vampire == false) + { + Vampire = true; + DoScriptText(SAY_MALGANIS_15HP, m_creature); + DoCast(m_creature, SPELL_VAMPIRE); + } + + if (Vampire_Timer < diff) + { + DoCast(m_creature, SPELL_VAMPIRE); + + Vampire_Timer = 30000; + }else Vampire_Timer -= diff; + + } + + if(m_creature->GetHealthPercent() < 5.0f) + { + m_pInstance->SetData(TYPE_PHASE, 10); + m_pInstance->SetData(TYPE_MALGANIS, DONE); + EnterEvadeMode(); + } + + } +}; + +CreatureAI* GetAI_boss_malganis(Creature* pCreature) +{ + return new boss_malganisAI(pCreature); +} + +void AddSC_boss_malganis() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_malganis"; + newscript->GetAI = &GetAI_boss_malganis; + newscript->RegisterSelf(); + +} \ No newline at end of file diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp new file mode 100644 index 000000000..9d61b06cc --- /dev/null +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp @@ -0,0 +1,137 @@ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ + +#include "precompiled.h" +#include "culling_of_stratholme.h" + +enum +{ + SPELL_CHAIN_N = 52696, + SPELL_CHAIN_H = 58823, + SPELL_EXPLODED_N = 52666, + SPELL_EXPLODED_H = 58824, + SPELL_FRENZY = 58841, + + SAY_MEATHOOK_AGGRO = -1594111, + SAY_MEATHOOK_DEATH = -1594112, + SAY_MEATHOOK_SLAY01 = -1594113, + SAY_MEATHOOK_SLAY02 = -1594114, + SAY_MEATHOOK_SLAY03 = -1594115 +}; + +struct MANGOS_DLL_DECL boss_meathookAI : public ScriptedAI +{ + boss_meathookAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 Chain_Timer; + uint32 Exploded_Timer; + uint32 Frenzy_Timer; + + void Reset() + { + Chain_Timer = 6300; + Exploded_Timer = 5000; + Frenzy_Timer = 22300; + } + + void Aggro(Unit* who) + { + DoScriptText(SAY_MEATHOOK_AGGRO, m_creature); + } + + void JustDied(Unit *killer) + { + DoScriptText(SAY_MEATHOOK_DEATH, m_creature); + if(m_pInstance) + m_pInstance->SetData(TYPE_PHASE, 3); + } + + void KilledUnit(Unit* pVictim) + { + switch(rand()%3) + { + case 0: DoScriptText(SAY_MEATHOOK_SLAY01, m_creature); break; + case 1: DoScriptText(SAY_MEATHOOK_SLAY02, m_creature); break; + case 2: DoScriptText(SAY_MEATHOOK_SLAY03, m_creature); break; + } + } + + void UpdateAI(const uint32 diff) + { + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + + if (Chain_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsHeroic ? SPELL_CHAIN_H : SPELL_CHAIN_N); + + Chain_Timer = 6300; + }else Chain_Timer -= diff; + + if (Exploded_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsHeroic ? SPELL_EXPLODED_H : SPELL_EXPLODED_N); + + Exploded_Timer = 5000; + }else Exploded_Timer -= diff; + + if (Frenzy_Timer < diff) + { + m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature,SPELL_FRENZY); + + Frenzy_Timer = 23300; + }else Frenzy_Timer -= diff; + + } +}; + +CreatureAI* GetAI_boss_meathook(Creature* pCreature) +{ + return new boss_meathookAI(pCreature); +} + +void AddSC_boss_meathook() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_meathook"; + newscript->GetAI = &GetAI_boss_meathook; + newscript->RegisterSelf(); +} diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp new file mode 100644 index 000000000..f93c612f1 --- /dev/null +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp @@ -0,0 +1,267 @@ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ + +#include "precompiled.h" +#include "culling_of_stratholme.h" + +enum +{ + SAY_SALRAMM_AGGRO = -1594130, + SAY_SALRAMM_DEATH = -1594131, + SAY_SALRAMM_SLAY01 = -1594132, + SAY_SALRAMM_SLAY02 = -1594133, + SAY_SALRAMM_SLAY03 = -1594134, + SAY_SALRAMM_STEAL01 = -1594135, + SAY_SALRAMM_STEAL02 = -1594136, + SAY_SALRAMM_STEAL03 = -1594137, + SAY_SUMMON01 = -1594138, + SAY_SUMMON02 = -1594139, + SAY_BOOM01 = -1594140, + SAY_BOOM02 = -1594141, + + SPELL_SB_N = 57725, + SPELL_SB_H = 58827, + SPELL_FLESH = 58845, + SPELL_STEAL = 52708, + SPELL_GNOUL_BLOW = 58825, + SPELL_SUMMON_GNOUL = 52451, + + NPC_GNOUL = 27733 +}; + +struct MANGOS_DLL_DECL boss_salrammAI : public ScriptedAI +{ + boss_salrammAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 ShadowBoltTimer; + uint32 FleshTimer; + uint32 StealTimer; + uint32 SummonTimer; + + void Reset() + { + ShadowBoltTimer = 5000; + FleshTimer = (urand(7000, 9000)); + StealTimer = (urand(9000, 17000)); + SummonTimer = (urand(12000, 17000)); + if(m_pInstance) + m_pInstance->SetData64(NPC_SALRAMM, m_creature->GetGUID()); + } + + void Aggro(Unit* who) + { + DoScriptText(SAY_SALRAMM_AGGRO, m_creature); + } + + void JustDied(Unit *killer) + { + DoScriptText(SAY_SALRAMM_DEATH, m_creature); + if(m_pInstance) + m_pInstance->SetData(TYPE_ENCOUNTER, DONE); + } + + void KilledUnit(Unit* pVictim) + { + switch(rand()%3) + { + case 0: DoScriptText(SAY_SALRAMM_SLAY01, m_creature); break; + case 1: DoScriptText(SAY_SALRAMM_SLAY02, m_creature); break; + case 2: DoScriptText(SAY_SALRAMM_SLAY03, m_creature); break; + } + } + + void SpellHitTarget(Unit *target, const SpellEntry *spell) + { + if(spell->Id == SPELL_GNOUL_BLOW) + if(target->GetTypeId() != TYPEID_PLAYER && target->GetEntry() == NPC_GNOUL) + target->SetDisplayId(11686); + } + + void UpdateAI(const uint32 diff) + { + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (ShadowBoltTimer < diff) + { + DoCast(m_creature->getVictim(), m_bIsHeroic ? SPELL_SB_H : SPELL_SB_N); + + ShadowBoltTimer = (urand(5000, 6000)); + }else ShadowBoltTimer -= diff; + + if (FleshTimer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target,SPELL_FLESH); + + FleshTimer = 7300; + }else FleshTimer -= diff; + + if (StealTimer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target,SPELL_STEAL); + + switch(rand()%3) + { + case 0: DoScriptText(SAY_SALRAMM_STEAL01, m_creature); break; + case 1: DoScriptText(SAY_SALRAMM_STEAL02, m_creature); break; + case 2: DoScriptText(SAY_SALRAMM_STEAL03, m_creature); break; + } + + StealTimer = (urand(8000, 11000)); + }else StealTimer -= diff; + + if (SummonTimer < diff) + { + switch(rand()%2) + { + case 0: DoScriptText(SAY_SUMMON01, m_creature); break; + case 1: DoScriptText(SAY_SUMMON02, m_creature); break; + } + + m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature,SPELL_SUMMON_GNOUL); + + SummonTimer = (urand(12000, 17000)); + }else SummonTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +/*### +## npc_salramm_gnoul +###*/ + +struct MANGOS_DLL_DECL npc_salramm_gnoulAI : public ScriptedAI +{ + npc_salramm_gnoulAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 m_uiBlowTimer; + + void Reset() + { + m_uiBlowTimer = (urand(3000, 15000)); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) + { + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiBlowTimer < uiDiff) + { + if(Creature* pSalramm = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SALRAMM))) + { + if(pSalramm->isDead()) return; + + switch(rand()%2) + { + case 0: DoScriptText(SAY_BOOM01, pSalramm); break; + case 1: DoScriptText(SAY_BOOM02, pSalramm); break; + } + pSalramm->InterruptNonMeleeSpells(false); + pSalramm->CastSpell(m_creature, SPELL_GNOUL_BLOW, false); + } + } + else m_uiBlowTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + return; + } +}; + +CreatureAI* GetAI_boss_salramm(Creature* pCreature) +{ + return new boss_salrammAI(pCreature); +} + +CreatureAI* GetAI_npc_salramm_gnoul(Creature* pCreature) +{ + return new npc_salramm_gnoulAI(pCreature); +} + +void AddSC_boss_salramm() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_salramm"; + newscript->GetAI = &GetAI_boss_salramm; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_salramm_gnoul"; + newscript->GetAI = &GetAI_npc_salramm_gnoul; + newscript->RegisterSelf(); +} diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp index fd3228f45..b06c25c90 100644 --- a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -14,222 +14,1765 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* ScriptData -SDName: culling_of_stratholme -SD%Complete: 5% -SDComment: Placeholder +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 SDCategory: Culling of Stratholme EndScriptData */ #include "precompiled.h" #include "culling_of_stratholme.h" +#include "escort_ai.h" +#include "WorldPacket.h" +#include "Weather.h" -/* ************* -** npc_chromie (gossip, quest-accept) -************* */ +/*### +## npc_arthas +###*/ enum { - QUEST_DISPELLING_ILLUSIONS = 13149, - QUEST_A_ROYAL_ESCORT = 13151, + SAY_INTRO01 = -1594071, //Arthas + SAY_INTRO02 = -1594072, //Uther + SAY_INTRO03 = -1594073, //Arthas + SAY_INTRO04 = -1594074, //Arthas + SAY_INTRO05 = -1594075, //Uther + SAY_INTRO06 = -1594076, //Arthas + SAY_INTRO07 = -1594077, //Uther + SAY_INTRO08 = -1594078, //Arthas + SAY_INTRO09 = -1594079, //Arthas + SAY_INTRO10 = -1594080, //Uther + SAY_INTRO11 = -1594081, //Arthas + SAY_INTRO12 = -1594082, //Uther + SAY_INTRO13 = -1594083, //Jaina + SAY_INTRO14 = -1594084, //Arthas + SAY_INTRO15 = -1594085, //Uther + SAY_INTRO16 = -1594086, //Arthas + SAY_INTRO17 = -1594087, //Jaina + SAY_INTRO18 = -1594088, //Arthas + + SAY_ENTER01 = -1594089, //Arthas + SAY_ENTER02 = -1594090, //Cityman + SAY_ENTER03 = -1594091, //Arthas + SAY_ENTER04 = -1594092, //Crazyman + SAY_ENTER05 = -1594093, //Crazyman2 + SAY_ENTER06 = -1594094, //Arthas + SAY_ENTER07 = -1594095, //Malganis + SAY_ENTER08 = -1594096, //Malganis + SAY_ENTER09 = -1594097, //Arthas + SAY_ENTER10 = -1594098, //Arthas + + SAY_SALRAMM_SPAWN = -1594129, + SAY_MEATHOOK_SPAWN = -1594110, - ITEM_ARCANE_DISRUPTOR = 37888, + SAY_PHASE501 = -1594142, //Arthas + SAY_PHASE502 = -1594143, //Arthas + SAY_PHASE503 = -1594144, //Human + SAY_PHASE504 = -1594145, //Arthas + SAY_PHASE505 = -1594146, //Arthas + SAY_PHASE506 = -1594147, //Human + SAY_PHASE507 = -1594148, //Arthas + SAY_PHASE508 = -1594149, //Arthas + SAY_PHASE509 = -1594150, //Arthas + SAY_PHASE510 = -1594151, //Arthas + SAY_PHASE511 = -1594152, //Arthas + SAY_PHASE512 = -1594153, //Arthas + SAY_PHASE513 = -1594154, //Arthas - GOSSIP_ITEM_ENTRANCE_1 = -3595000, - GOSSIP_ITEM_ENTRANCE_2 = -3595001, - GOSSIP_ITEM_ENTRANCE_3 = -3595002, + SAY_EPOCH_INTRO = -1594155, + SAY_ARTHAS_INTRO = -1594156, + SAY_EPOCH_AGGRO = -1594157, - TEXT_ID_ENTRANCE_1 = 12992, - TEXT_ID_ENTRANCE_2 = 12993, - TEXT_ID_ENTRANCE_3 = 12994, - TEXT_ID_ENTRANCE_4 = 12995, + SAY_PHASE514 = -1594158, //Arthas Shkaf 01 + SAY_PHASE515 = -1594159, //Arthas Shkaf 02 + SAY_PHASE601 = -1594160, //Arthas Fire + SAY_PHASE602 = -1594161, //Arthas Picnic + SAY_PHASE603 = -1594162, //Arthas Picnic End + SAY_PHASE605 = -1594164, //Arthas mall start + SAY_PHASE606 = -1594188, - GOSSIP_ITEM_INN_1 = -3595003, - GOSSIP_ITEM_INN_2 = -3595004, - GOSSIP_ITEM_INN_3 = -3595005, + SAY_MALGANIS_ESCAPE02 = -1594180, + SAY_MALGANIS_ESCAPE01 = -1594187, + SAY_MALGANIS_OUTRO = -1594182, + SAY_ARTHAS_OUTRO01 = -1594181, + SAY_ARTHAS_OUTRO02 = -1594183, + SAY_ARTHAS_OUTRO03 = -1594184, - TEXT_ID_INN_1 = 12939, - TEXT_ID_INN_2 = 12949, - TEXT_ID_INN_3 = 12950, - TEXT_ID_INN_4 = 12952, + /*SPELL*/ + SPELL_EXORCISM_N = 52445, + SPELL_EXORCISM_H = 58822, + SPELL_HOLY_LIGHT = 52444, + SPELL_ARTHAS_AURA = 52442, + + /*NPC*/ + NPC_CITYMAN = 28167, + NPC_CRAZYMAN = 28169, + NPC_MALGANIS_INTRO = 26533, + + /*OTHER*/ + POINT_LAST_POINT = 0xFFFFFF, + FACTION = 2076 }; -bool GossipHello_npc_chromie(Player *pPlayer, Creature *pCreature) +const float SummonScourge[2][4] = { - if (pCreature->isQuestGiver()) - pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + {2340.058f, 1253.570f, 132.733f, 5.09f}, //right wing + {2272.773f, 1331.824f, 124.171f, 3.12f}, //left wing +}; + +struct MANGOS_DLL_DECL npc_arthasAI : public npc_escortAI +{ + npc_arthasAI(Creature* pCreature) : npc_escortAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + m_creature->SetSpeedRate(MOVE_RUN, 1); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint64 m_uiUtherGUID; + uint64 m_uiJainaGUID; + uint64 m_uiPeople01GUID; + uint64 m_uiPeople02GUID; + uint64 m_uiMalganisGUID; + uint64 m_uiMarine01GUID; + uint64 m_uiMarine02GUID; + uint64 m_uiMarine03GUID; + uint64 m_uiMarine04GUID; + uint64 m_uiPriest01GUID; + uint64 m_uiPriest02GUID; + uint64 m_uiHuman01GUID; + uint64 m_uiHuman02GUID; + uint64 m_uiHuman03GUID; + + uint32 culling_faction; + uint32 m_uiStep; + uint32 m_uiStepTimer; + uint32 m_uiMoveTimer; + uint32 m_uiHealTimer; + uint32 m_uiExorcismTimer; + uint32 m_uiSummonTimer; + uint32 m_uiWaveCount; + + Creature* Malganis; + Creature* pEpoch; + bool StartEvent; + bool MoveSoldier; + + float LastX; + float LastY; + float LastZ; + + void Reset() + { + if(!m_pInstance) return; + + m_creature->SetSpeedRate(MOVE_RUN, 1); + + if(m_pInstance->GetData(TYPE_INTRO) == NOT_STARTED) + { + m_creature->setFaction(35); + RemoveGossip(); + } + + if(m_pInstance->GetData(TYPE_PHASE) == 11) + { + m_creature->SetVisibility(VISIBILITY_OFF); + } + } + + void RemoveGossip() + { + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + + void MoveSoldiers() + { + if(Unit* Marine01 = m_creature->GetMap()->GetUnit( m_uiMarine01GUID)) + { + Marine01->GetMotionMaster()->MovePoint(0, 2083.483f,1282.313f,141.198f); + Marine01->setFaction(culling_faction); + } + if(Unit* Marine02 = m_creature->GetMap()->GetUnit( m_uiMarine02GUID)) + { + Marine02->GetMotionMaster()->MovePoint(0, 2083.681f,1292.809f,141.141f); + Marine02->setFaction(culling_faction); + } + if(Unit* Marine03 = m_creature->GetMap()->GetUnit( m_uiMarine03GUID)) + { + Marine03->GetMotionMaster()->MovePoint(0, 2082.158f,1290.406f,141.261f); + Marine03->setFaction(culling_faction); + } + if(Unit* Marine04 = m_creature->GetMap()->GetUnit( m_uiMarine04GUID)) + { + Marine04->GetMotionMaster()->MovePoint(0, 2081.899f,1285.122f,141.302f); + Marine04->setFaction(culling_faction); + } + if(Unit* Priest01 = m_creature->GetMap()->GetUnit( m_uiPriest01GUID)) + { + Priest01->GetMotionMaster()->MovePoint(0, 2081.072f,1292.233f,141.329f); + Priest01->setFaction(culling_faction); + } + if(Unit* Priest02 = m_creature->GetMap()->GetUnit( m_uiPriest02GUID)) + { + Priest02->GetMotionMaster()->MovePoint(0, 2080.632f,1283.004f,141.358f); + Priest02->setFaction(culling_faction); + } + } + + void EnableEscort() + { + SetEscortPaused(false); + } + + void SummonPeople() + { + if(Creature* Cityman = m_creature->SummonCreature(NPC_CITYMAN,2091.977f,1275.021f,140.757f,0.558f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + m_uiPeople01GUID = Cityman->GetGUID(); + if(Creature* Crazyman = m_creature->SummonCreature(NPC_CRAZYMAN,2093.514f,1275.842f,140.408f,3.801f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + m_uiPeople02GUID = Crazyman->GetGUID(); + } + + void StartAI() + { + SummonPeople(); + m_uiStep = 0; + m_uiStepTimer = 100; + StartEvent = true; + } + + void Aggro(Unit* who) + { + DoCast(m_creature, SPELL_ARTHAS_AURA); + } + + void EnterEvadeMode() + { + if(!m_pInstance) return; + + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + m_uiExorcismTimer = 7400; + m_uiHealTimer = 100; + + m_creature->SetLootRecipient(NULL); - if (instance_culling_of_stratholme* m_pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData()) + if(m_pInstance->GetData(TYPE_PHASE) > 4) + { + npc_escortAI::EnterEvadeMode(); + } + + if(m_pInstance->GetData(TYPE_PHASE) > 2 && m_pInstance->GetData(TYPE_PHASE) < 5) + { + m_creature->GetMotionMaster()->MovePoint(POINT_LAST_POINT, LastX, LastY, LastZ); + } + } + + void AttackStart(Unit* pWho) + { + if(!pWho || pWho == m_creature) + return; + + if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 4) return; + + npc_escortAI::AttackStart(pWho); + } + + void MoveInLineOfSight(Unit* pWho) { - switch (pCreature->GetEntry()) + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) { - case NPC_CHROMIE_INN: - if (m_pInstance->GetData(TYPE_GRAIN_EVENT) != DONE) + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) { - if (pPlayer->GetQuestRewardStatus(QUEST_DISPELLING_ILLUSIONS) && !pPlayer->HasItemCount(ITEM_ARCANE_DISRUPTOR, 1)) - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INN_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); } - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_1, pCreature->GetGUID()); - break; - case NPC_CHROMIE_ENTRANCE: - if (m_pInstance->GetData(TYPE_GRAIN_EVENT) == DONE && m_pInstance->GetData(TYPE_ARTHAS_INTRO_EVENT) == NOT_STARTED && pPlayer->GetQuestRewardStatus(QUEST_A_ROYAL_ESCORT)) - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ENTRANCE_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_1, pCreature->GetGUID()); - break; + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } + } } } - return true; -} -bool GossipSelect_npc_chromie(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 uiAction) -{ - switch (pCreature->GetEntry()) + void WaypointReached(uint32 uiPointId) { - case NPC_CHROMIE_INN: - switch (uiAction) - { - case GOSSIP_ACTION_INFO_DEF+1: - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INN_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_2, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INN_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_3, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_4, pCreature->GetGUID()); - if (!pPlayer->HasItemCount(ITEM_ARCANE_DISRUPTOR, 1)) - { - if (Item* pItem = pPlayer->StoreNewItemInInventorySlot(ITEM_ARCANE_DISRUPTOR, 1)) + switch(uiPointId) + { + case 2: + DoScriptText(SAY_INTRO18, m_creature); + SetRun(true); + break; + case 8: + GetSoldier(); + SetEscortPaused(true); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + m_pInstance->SetData(TYPE_INTRO, DONE); + SetRun(false); + break; + case 9: + DoScriptText(SAY_ENTER01, m_creature); + MoveSoldier = true; + m_uiMoveTimer = 12000; + break; + case 10: + SetEscortPaused(true); + m_pInstance->SetData(TYPE_PHASE, 2); + ResetStep(2000); + if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID)) + { + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Cityman->GetGUID()); + Cityman->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + Cityman->GetMotionMaster()->MovePoint(0, 2088.625f,1279.191f,140.743f); + } + break; + case 14: + if(Creature* Human01 = m_creature->SummonCreature(NPC_CITY,2397.308f,1207.565f,134.038f,5.593f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + m_uiHuman01GUID = Human01->GetGUID(); + if(Creature* Human02 = m_creature->SummonCreature(NPC_CITY,2400.770f,1207.362f,134.038f,3.454f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + m_uiHuman02GUID = Human02->GetGUID(); + if(Creature* Human03 = m_creature->SummonCreature(NPC_CITY,2400.547f,1204.892f,134.038f,2.479f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + m_uiHuman03GUID = Human03->GetGUID(); + break; + case 20: + SetEscortPaused(true); + m_creature->setFaction(35); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetRun(false); + break; + case 21: + DoScriptText(SAY_PHASE502, m_creature); + break; + case 22: + SetEscortPaused(true); + m_pInstance->SetData(TYPE_PHASE, 6); + ResetStep(1000); + break; + case 25: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H); + m_creature->SummonCreature(NPC_TIME_RIFT,2428.901f, 1192.164f, 148.076f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + DoScriptText(SAY_PHASE508, m_creature); + break; + case 26: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); + DoScriptText(SAY_PHASE509, m_creature); + break; + case 29: + m_creature->SummonCreature(NPC_TIME_RIFT,2413.773f, 1137.820f, 148.076f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_TIME_RIFT,2404.990f, 1175.121f, 148.076f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + DoScriptText(SAY_PHASE510, m_creature); + break; + case 30: + DoScriptText(SAY_PHASE513, m_creature); + break; + case 31: + ResetStep(1000); + m_pInstance->SetData(TYPE_PHASE, 7); + break; + case 32: + SetEscortPaused(true); + m_pInstance->SetData(TYPE_PHASE, 8); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetRun(false); + break; + case 36: + DoScriptText(SAY_PHASE514, m_creature); + break; + case 37: + if(GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_SHKAF_GATE))) + pGate->SetGoState(GO_STATE_ACTIVE); + SetRun(true); + DoScriptText(SAY_PHASE515, m_creature); + break; + case 45: + DoScriptText(SAY_PHASE601, m_creature); + break; + case 48: + DoScriptText(SAY_PHASE602, m_creature); + break; + case 51: + SetEscortPaused(true); + m_pInstance->SetData(TYPE_PHASE, 9); + DoScriptText(SAY_PHASE606, m_creature); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + break; + case 53: + SetEscortPaused(true); + m_creature->StopMoving(); + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->setFaction(FACTION); + DoScriptText(SAY_PHASE605, m_creature); + if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS))) + { + m_pInstance->SetData(TYPE_MALGANIS, IN_PROGRESS); + Malganis->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->AI()->AttackStart(Malganis); + Malganis->AI()->AttackStart(m_creature); + } + break; + } + } + + void JumpNextStep(uint32 Timer) + { + m_uiStepTimer = Timer; + m_uiStep++; + } + + void GetSoldier() //huck + { + //Marine Close Left + if(Creature* pEscort01 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f)) + { + m_uiMarine01GUID = pEscort01->GetGUID(); + pEscort01->UpdateEntry(NPC_CITYMAN); + if(Creature* pEscort02 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f)) + { + m_uiMarine02GUID = pEscort02->GetGUID(); + pEscort02->UpdateEntry(NPC_CITYMAN); + // Right marine 2 + if(Creature* pEscort03 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f)) + { + m_uiMarine03GUID = pEscort03->GetGUID(); + pEscort03->UpdateEntry(NPC_CITYMAN); + if(Creature* pEscort04 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f)) + { + m_uiMarine04GUID = pEscort04->GetGUID(); + pEscort01->UpdateEntry(NPC_MARINE); + pEscort02->UpdateEntry(NPC_MARINE); + pEscort03->UpdateEntry(NPC_MARINE); + } + } + } + } + + if(Creature* pEscort05 = GetClosestCreatureWithEntry(m_creature, NPC_PRIEST, 50.0f)) + { + m_uiPriest01GUID = pEscort05->GetGUID(); + pEscort05->UpdateEntry(NPC_CITYMAN); + if(Creature* pEscort06 = GetClosestCreatureWithEntry(m_creature, NPC_PRIEST, 50.0f)) + { + m_uiPriest02GUID = pEscort06->GetGUID(); + pEscort05->UpdateEntry(NPC_PRIEST); + } + } + } + + void ResetStep(uint32 Timer) + { + m_uiStep = 0; + m_uiStepTimer = Timer; + } + + void IntroEvent() + { + switch(m_uiStep) + { + case 0: + DoScriptText(SAY_INTRO01, m_creature); + JumpNextStep(2000); + break; + case 1: + m_uiUtherGUID = m_pInstance->GetData64(NPC_UTHER); + m_uiJainaGUID = m_pInstance->GetData64(NPC_JAINA); + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + DoScriptText(SAY_INTRO02, pUther); + JumpNextStep(8000); + break; + case 2: + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + DoScriptText(SAY_INTRO03, m_creature); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + m_creature->GetMotionMaster()->MovePoint(0, 1908.334f, 1315.354f, 149.551f); + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + pUther->GetMotionMaster()->MovePoint(0, 1903.600f, 1296.678f, 143.383f); + JumpNextStep(2000); + break; + case 3: + if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID)) + pJaina->GetMotionMaster()->MovePoint(0, 1899.641f, 1298.684f, 143.831f); + JumpNextStep(7000); + break; + case 4: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 1911.087f, 1314.263f, 150.026f); + JumpNextStep(1000); + break; + case 5: + DoScriptText(SAY_INTRO04, m_creature); + JumpNextStep(10000); + break; + case 6: + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + DoScriptText(SAY_INTRO05, pUther); + JumpNextStep(1000); + break; + case 7: + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pUther->GetGUID()); + DoScriptText(SAY_INTRO06, m_creature); + JumpNextStep(4000); + break; + case 8: + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + DoScriptText(SAY_INTRO07, pUther); + JumpNextStep(6000); + break; + case 9: + DoScriptText(SAY_INTRO08, m_creature); + JumpNextStep(4000); + break; + case 10: + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + DoScriptText(SAY_INTRO09, pUther); + JumpNextStep(8000); + break; + case 11: + DoScriptText(SAY_INTRO10, m_creature); + JumpNextStep(4000); + break; + case 12: + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + DoScriptText(SAY_INTRO11, pUther); + JumpNextStep(4000); + break; + case 13: + DoScriptText(SAY_INTRO12, m_creature); + JumpNextStep(11000); + break; + case 14: + if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID)) + DoScriptText(SAY_INTRO13, pJaina); + JumpNextStep(3000); + break; + case 15: + DoScriptText(SAY_INTRO14, m_creature); + JumpNextStep(9000); + break; + case 16: + if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID)) + DoScriptText(SAY_INTRO15, pUther); + JumpNextStep(5000); + break; + case 17: + if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID)) + { + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pJaina->GetGUID()); + pJaina->GetMotionMaster()->MovePoint(0, 1794.357f,1272.183f,140.558f); + } + JumpNextStep(1000); + break; + case 18: + DoScriptText(SAY_INTRO16, m_creature); + JumpNextStep(1000); + break; + case 19: + if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID)) + DoScriptText(SAY_INTRO17, pJaina); + JumpNextStep(3000); + break; + case 20: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + ((npc_arthasAI*)m_creature->AI())->Start(false); + JumpNextStep(3000); + break; + } + } + + void EnterEvent() + { + switch(m_uiStep) + { + case 0: + if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID)) + DoScriptText(SAY_ENTER02, Cityman); + JumpNextStep(4000); + break; + case 1: + m_creature->GetMotionMaster()->MovePoint(0, 2087.689f,1280.344f,140.73f); + DoScriptText(SAY_ENTER03, m_creature); + JumpNextStep(3000); + break; + case 2: + if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID)) + DoScriptText(SAY_ENTER04, Cityman); + m_creature->HandleEmoteCommand(37); + JumpNextStep(1000); + break; + case 3: + if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID)) + m_creature->DealDamage(Cityman, Cityman->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + if(Unit* Crazyman = m_creature->GetMap()->GetUnit( m_uiPeople02GUID)) + { + DoScriptText(SAY_ENTER05, Crazyman); + Crazyman->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Crazyman->GetGUID()); + m_creature->GetMotionMaster()->MovePoint(0, 2092.154f,1276.645f,140.52f); + } + JumpNextStep(3000); + break; + case 4: + m_creature->HandleEmoteCommand(37); + JumpNextStep(1000); + break; + case 5: + if(Unit* Crazyman = m_creature->GetMap()->GetUnit( m_uiPeople02GUID)) + Crazyman->DealDamage(Crazyman, Crazyman->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + JumpNextStep(1000); + break; + case 6: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + m_creature->GetMotionMaster()->MovePoint(0, 2091.179f,1278.065f,140.476f); + DoScriptText(SAY_ENTER06, m_creature); + JumpNextStep(3000); + break; + case 7: + if(Creature* StalkerM = m_creature->SummonCreature(20562,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,60000)) + StalkerM->CastSpell(StalkerM,63793,false); + JumpNextStep(1000); + break; + case 8: + m_pInstance->SetData(TYPE_ENCOUNTER, IN_PROGRESS); + if(Creature* TempMalganis = m_creature->SummonCreature(NPC_MALGANIS_INTRO,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,29000)) + { + m_uiMalganisGUID = TempMalganis->GetGUID(); + DoScriptText(SAY_ENTER07, TempMalganis); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, TempMalganis->GetGUID()); + TempMalganis->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + TempMalganis->setFaction(35); + } + JumpNextStep(11000); + break; + case 9: + if(Unit* TempMalganis = m_creature->GetMap()->GetUnit( m_uiMalganisGUID)) + DoScriptText(SAY_ENTER08, TempMalganis); + JumpNextStep(17000); + break; + case 10: + DoScriptText(SAY_ENTER09, m_creature); + JumpNextStep(7000); + break; + case 11: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + DoScriptText(SAY_ENTER10, m_creature); + JumpNextStep(12000); + break; + case 12: + m_creature->GetMotionMaster()->MovePoint(0, 2084.584f,1278.331f,141.479f); + JumpNextStep(4000); + break; + case 13: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 2087.414f,1279.293f,140.933f); + JumpNextStep(2000); + break; + case 14: + LastX = m_creature->GetPositionX(); + LastY = m_creature->GetPositionY(); + LastZ = m_creature->GetPositionZ(); + if(m_bIsHeroic) + m_pInstance->SetData(TYPE_BONUS, IN_PROGRESS); + m_uiWaveCount = 0; + SetRun(true); + m_pInstance->SetData(TYPE_WING, RIGHT); + m_creature->setFaction(FACTION); + m_uiSummonTimer = 100; + m_pInstance->SetData(TYPE_PHASE, 3); + break; + } + } + + void SummonWing() + { + m_uiWaveCount++; + m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_WAVE_COUNT, m_uiWaveCount); + + switch(m_uiWaveCount) + { + case 1: + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 2: + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_FIEND,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 3: + m_pInstance->SetData(TYPE_WING, LEFT); + m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_FIEND,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 4: + m_pInstance->SetData(TYPE_WING, RIGHT); + m_creature->SummonCreature(NPC_ACOLYTE,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_ACOLYTE,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_FIEND,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 5: + m_pInstance->SetData(TYPE_PHASE, 4); + if(Creature* pMeathook = m_creature->SummonCreature(NPC_MEATHOOK,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000)) + { + DoScriptText(SAY_MEATHOOK_SPAWN, pMeathook); + pMeathook->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pMeathook->GetMotionMaster()->MovePoint(0, 2196.036f, 1328.818f, 129.997f); + } + break; + case 6: + m_pInstance->SetData(TYPE_WING, LEFT); + m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_FIEND,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_FIEND,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 7: + m_pInstance->SetData(TYPE_WING, RIGHT); + m_creature->SummonCreature(NPC_CONSTRUCT,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 8: + m_pInstance->SetData(TYPE_WING, LEFT); + m_creature->SummonCreature(NPC_CONSTRUCT,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 9: + m_pInstance->SetData(TYPE_WING, RIGHT); + m_creature->SummonCreature(NPC_CONSTRUCT,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_FIEND,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000); + break; + case 10: + m_pInstance->SetData(TYPE_PHASE, 4); + if(Creature* pSalramm = m_creature->SummonCreature(NPC_SALRAMM,2196.036f, 1328.818f, 129.997f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000)) + { + DoScriptText(SAY_SALRAMM_SPAWN, pSalramm); + pSalramm->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pSalramm->GetMotionMaster()->MovePoint(0, 2196.036f, 1328.818f, 129.997f); + } + break; + } + } + + void HouseEvent() + { + switch(m_uiStep) + { + case 0: + if(Creature* Human = m_pInstance->instance->GetCreature(m_uiHuman01GUID)) + { + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Human->GetGUID()); + Human->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + DoScriptText(SAY_PHASE503, Human); + } + JumpNextStep(4000); + break; + case 1: + DoScriptText(SAY_PHASE504, m_creature); + m_creature->GetMotionMaster()->MovePoint(0, 2396.035f, 1206.942f, 134.038f); + JumpNextStep(3000); + break; + case 2: + m_creature->HandleEmoteCommand(37); + JumpNextStep(2000); + break; + case 3: + DoScriptText(SAY_PHASE505, m_creature); + JumpNextStep(2000); + break; + case 4: + if(Creature* Human = m_pInstance->instance->GetCreature(m_uiHuman01GUID)) + DoScriptText(SAY_PHASE506, Human); + JumpNextStep(6000); + break; + case 5: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + if(Creature* Human = m_pInstance->instance->GetCreature(m_uiHuman01GUID)) + { + Human->SetUInt64Value(UNIT_FIELD_TARGET, 0); + Human->UpdateEntry(NPC_INFINITE_ADVERSARY); + } + if(Creature* Human2 = m_pInstance->instance->GetCreature(m_uiHuman02GUID)) + Human2->UpdateEntry(NPC_INFINITE_HUNTER); + if(Creature* Human3 = m_pInstance->instance->GetCreature(m_uiHuman03GUID)) + Human3->UpdateEntry(NPC_INFINITE_AGENT); + JumpNextStep(1000); + break; + case 6: + SetRun(true); + m_creature->GetMotionMaster()->MovePoint(0, 2384.320f, 1202.779f, 134.040f); + DoScriptText(SAY_PHASE507, m_creature); + JumpNextStep(5000); + break; + case 7: + SetEscortPaused(false); + m_creature->setFaction(FACTION); + m_pInstance->SetData(TYPE_PHASE, 5); + JumpNextStep(1000); + break; + } + } + + void EpochEvent() + { + switch(m_uiStep) + { + case 0: + m_creature->SummonCreature(NPC_TIME_RIFT_2,2445.629f,1111.500f,148.076f,3.229f,TEMPSUMMON_TIMED_DESPAWN,9000); + JumpNextStep(2000); + break; + case 1: + pEpoch = m_creature->SummonCreature(NPC_EPOCH,2445.629f,1111.500f,148.076f,3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000); + if(pEpoch) + { + pEpoch->setFaction(35); + DoScriptText(SAY_EPOCH_INTRO, pEpoch); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pEpoch->GetGUID()); + } + JumpNextStep(20000); + break; + case 2: + DoScriptText(SAY_ARTHAS_INTRO, m_creature); + JumpNextStep(6000); + break; + case 3: + if(pEpoch) + { + DoScriptText(SAY_EPOCH_AGGRO, pEpoch); + m_creature->AI()->AttackStart(pEpoch); + pEpoch->AI()->AttackStart(m_creature); + pEpoch->setFaction(14); + } + m_pInstance->SetData(TYPE_PHASE, 5); + SetRun(false); + JumpNextStep(6000); + break; + } + } + + void MalganisEvent() + { + Map::PlayerList const &PlayerList = m_pInstance->instance->GetPlayers(); + bool bNeedSpawn = false; + + switch(m_uiStep) + { + case 0: + m_creature->setFaction(35); + m_creature->GetMotionMaster()->MovePoint(0, 2302.326f, 1491.386f, 128.362f); + if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS))) + { + DoScriptText(SAY_MALGANIS_ESCAPE01, Malganis); + Malganis->InterruptNonMeleeSpells(false); + Malganis->GetMotionMaster()->MovePoint(0, 2296.665f,1502.362f,128.362f); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Malganis->GetGUID()); + Malganis->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + } + JumpNextStep(10000); + break; + case 1: + if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS))) + DoScriptText(SAY_MALGANIS_ESCAPE02, Malganis); + JumpNextStep(10000); + break; + case 2: + DoScriptText(SAY_ARTHAS_OUTRO01, m_creature); + JumpNextStep(5000); + break; + case 3: + if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS))) + DoScriptText(SAY_MALGANIS_OUTRO, Malganis); + JumpNextStep(20000); + break; + case 4: + if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS))) + { + Malganis->SetVisibility(VISIBILITY_OFF); + m_creature->GetMotionMaster()->MovePoint(0, Malganis->GetPositionX(), Malganis->GetPositionY(), Malganis->GetPositionZ()); + } + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + JumpNextStep(3000); + break; + case 5: + DoScriptText(SAY_ARTHAS_OUTRO02, m_creature); + JumpNextStep(6000); + break; + case 6: + m_creature->GetMotionMaster()->MovePoint(0, 2298.298f,1500.362f,128.362f); + DoScriptText(SAY_ARTHAS_OUTRO03, m_creature); + JumpNextStep(11000); + break; + case 7: + m_creature->GetMotionMaster()->MovePoint(0, 2243.311f, 1476.025f, 132.352f); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (i->getSource()->GetQuestStatus(QUEST_A_ROYAL_ESCORT) == QUEST_STATUS_INCOMPLETE || + i->getSource()->GetQuestStatus(QUEST_A_ROYAL_ESCORT) == QUEST_STATUS_COMPLETE) { - pPlayer->SendNewItem(pItem, 1, true, false); - if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData()) - { - if (pInstance->GetData(TYPE_GRAIN_EVENT) == NOT_STARTED) - pInstance->SetData(TYPE_GRAIN_EVENT, SPECIAL); - } + bNeedSpawn = true; + break; } - } - break; + + if (bNeedSpawn) + m_creature->SummonCreature(30997, 2311.61f, 1497.85f, 128.01f, 4.14f, TEMPSUMMON_TIMED_DESPAWN, 1800000); + JumpNextStep(11000); + break; + case 8: + m_pInstance->SetData(TYPE_PHASE, 12); + m_creature->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if(!m_pInstance) return; + + if(StartEvent == true) + { + if(m_pInstance->GetData(TYPE_INTRO) != DONE) + { + if(m_uiStepTimer < uiDiff) + { + IntroEvent(); } - break; - case NPC_CHROMIE_ENTRANCE: - switch (uiAction) + else m_uiStepTimer -= uiDiff; + } + + if(m_pInstance->GetData(TYPE_PHASE) == 2) + { + if(m_uiStepTimer < uiDiff) { - case GOSSIP_ACTION_INFO_DEF+1: - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ENTRANCE_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_2, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ENTRANCE_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_3, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_4, pCreature->GetGUID()); - if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData()) - { - if (pInstance->GetData(TYPE_ARTHAS_INTRO_EVENT) == NOT_STARTED) - pInstance->DoSpawnArthasIfNeeded(); - } - break; + EnterEvent(); } - break; - } - return true; -} + else m_uiStepTimer -= uiDiff; + } -bool QuestAccept_npc_chromie(Player* pPlayer, Creature* pCreature, const Quest* pQuest) -{ - switch (pQuest->GetQuestId()) - { - case QUEST_DISPELLING_ILLUSIONS: - if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData()) + if(MoveSoldier == true) + { + if(m_uiMoveTimer < uiDiff) + { + MoveSoldiers(); + MoveSoldier = false; + } + else m_uiMoveTimer -= uiDiff; + } + + if(m_pInstance->GetData(TYPE_PHASE) == 3) + { + if(m_uiSummonTimer < uiDiff) + { + SummonWing(); + m_uiSummonTimer = 70000; + } + else m_uiSummonTimer -= uiDiff; + } + + if(m_pInstance->GetData(TYPE_PHASE) == 4 && m_pInstance->GetData(TYPE_ENCOUNTER) == DONE) + { + m_pInstance->SetData(TYPE_PHASE, 5); + SetRun(true); + EnableEscort(); + DoScriptText(SAY_PHASE501, m_creature); + } + + if(m_pInstance->GetData(TYPE_PHASE) == 6) + { + if(m_uiStepTimer < uiDiff) + { + HouseEvent(); + } + else m_uiStepTimer -= uiDiff; + } + + if(m_pInstance->GetData(TYPE_PHASE) == 7) + { + if(m_uiStepTimer < uiDiff) { - if (pInstance->GetData(TYPE_GRAIN_EVENT) == NOT_STARTED) - pInstance->SetData(TYPE_GRAIN_EVENT, SPECIAL); + EpochEvent(); } - break; - case QUEST_A_ROYAL_ESCORT: - if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData()) + else m_uiStepTimer -= uiDiff; + } + + } //close event! + + if(m_pInstance->GetData(TYPE_PHASE) == 10) + { + SetEscortPaused(true); + ResetStep(1000); + m_creature->AttackStop(); + m_pInstance->SetData(TYPE_PHASE, 11); + } + + if(m_pInstance->GetData(TYPE_PHASE) == 11) + { + if(m_uiStepTimer < uiDiff) { - if (pInstance->GetData(TYPE_ARTHAS_INTRO_EVENT) == NOT_STARTED) - pInstance->DoSpawnArthasIfNeeded(); + MalganisEvent(); } - break; + else m_uiStepTimer -= uiDiff; + } + + //} //close event! + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_pInstance->GetData(TYPE_PHASE) > 9) return; + + if (m_uiExorcismTimer < uiDiff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsHeroic ? SPELL_EXORCISM_H : SPELL_EXORCISM_N); + + m_uiExorcismTimer = 7300; + }else m_uiExorcismTimer -= uiDiff; + + if (m_uiHealTimer < uiDiff) + { + if(m_creature->GetHealthPercent() < 40.0f) + { + DoCast(m_creature, SPELL_HOLY_LIGHT); + m_uiHealTimer = 20000; + } + } else m_uiHealTimer -= uiDiff; + + return; } +}; + +/*### +## npc_uther +###*/ + +struct MANGOS_DLL_DECL npc_utherAI : public npc_escortAI +{ + npc_utherAI(Creature* pCreature) : npc_escortAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint64 m_uiArthasGUID; + uint32 m_uiStep; + uint32 m_uiStepTimer; + bool StartEvent; + + uint64 m_uiKnightGUID01; + uint64 m_uiKnightGUID02; + uint64 m_uiKnightGUID03; + + void Reset() + { + m_creature->SetVisibility(VISIBILITY_OFF); + m_uiStep = 0; + m_uiStepTimer = 100; + } + + void StartAI() + { + //m_pInstance->SetWeather(WEATHER_STATE_MEDIUM_RAIN, 0.9999f); + StartEvent = true; + m_creature->SetVisibility(VISIBILITY_ON); + ((npc_utherAI*)m_creature->AI())->Start(true); + + if(Creature* Knight01 = m_creature->SummonCreature(NPC_KNIGHT,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,110000)) + { + m_uiKnightGUID01 = Knight01->GetGUID(); + Knight01->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + Knight01->GetMotionMaster()->MoveFollow(m_creature,PET_FOLLOW_DIST,M_PI_F/2); + } + + if(Creature* Knight02 = m_creature->SummonCreature(NPC_KNIGHT,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,110000)) + { + m_uiKnightGUID02 = Knight02->GetGUID(); + Knight02->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + Knight02->GetMotionMaster()->MoveFollow(m_creature,PET_FOLLOW_DIST,M_PI_F/4); + } + + if(Creature* Knight03 = m_creature->SummonCreature(NPC_KNIGHT,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,110000)) + { + m_uiKnightGUID03 = Knight03->GetGUID(); + Knight03->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + Knight03->GetMotionMaster()->MoveFollow(m_creature,PET_FOLLOW_DIST,M_PI_F/3); + } + } + + void WaypointReached(uint32 uiPointId) + { + switch(uiPointId) + { + case 3: + m_uiArthasGUID = m_pInstance->GetData64(NPC_ARTHAS); + if(Creature* pArthas = m_pInstance->instance->GetCreature(m_uiArthasGUID)) + { + pArthas->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pArthas->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + pArthas->GetMotionMaster()->MovePoint(0, 1902.974f, 1291.635f, 143.337f); + } + break; + case 4: + SetRun(false); + if(Creature *pArthas = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ARTHAS))) + ((npc_arthasAI*)pArthas->AI())->StartAI(); + break; + case 6: + m_creature->SetVisibility(VISIBILITY_OFF); + uint64 m_uiJainaGUID = m_pInstance->GetData64(NPC_JAINA); + if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID)) + pJaina->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if(!m_pInstance) return; + + return; + } +}; + +/*### +## npc_chromi_middle +###*/ + +#define GOSSIP_ITEM_CHROMI1 "What do you think they're up to?" +#define GOSSIP_ITEM_CHROMI2 "What want me to do what?" +#define GOSSIP_ITEM_CHROMI3 "Very well, Chromie." + +enum +{ + QUEST_ROYAL_ESCORT = 13151, + GOSSIP_TEXTID_CHROMI1 = 12953, + GOSSIP_TEXTID_CHROMI2 = 12949, + GOSSIP_TEXTID_CHROMI3 = 12950, + GOSSIP_TEXTID_CHROMI4 = 12952 +}; + +bool GossipHello_npc_chromi_middle(Player* pPlayer, Creature* pCreature) +{ + if (pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + + //if (pPlayer->GetQuestStatus(QUEST_ROYAL_ESCORT) == QUEST_STATUS_INCOMPLETE) return true; + + ScriptedInstance* pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + if(pInstance && pInstance->GetData(TYPE_INTRO) == NOT_STARTED) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI1, pCreature->GetGUID()); + return true; } -/* ************* -** npc_crates_bunny (spell aura effect dummy) -************* */ +bool GossipSelect_npc_chromi_middle(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + if(ScriptedInstance* m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData())) + if(m_pInstance->GetData(TYPE_INTRO) != NOT_STARTED) return true; + + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI2, pCreature->GetGUID()); + } + + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI3, pCreature->GetGUID()); + } + + if (uiAction == GOSSIP_ACTION_INFO_DEF+3) + { + if(ScriptedInstance* m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData())) + { + m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 0); + m_pInstance->SetData(TYPE_INTRO, IN_PROGRESS); + if (Creature *pUther = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_UTHER))) + ((npc_utherAI*)pUther->AI())->StartAI(); + } + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI4, pCreature->GetGUID()); + } + + return true; +} + +struct MANGOS_DLL_DECL npc_chromi_middleAI : public ScriptedAI +{ + npc_chromi_middleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + m_bUtherHere = false; + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool m_bUtherHere; + + void Reset() + { + m_bUtherHere = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_bUtherHere && m_pInstance && pWho && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(pWho) <= 15 && ((Player*)pWho)->GetQuestStatus(QUEST_A_ROYAL_ESCORT) == QUEST_STATUS_INCOMPLETE) + { + m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 0); + m_pInstance->SetData(TYPE_INTRO, IN_PROGRESS); + if (Creature *pUther = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_UTHER))) + ((npc_utherAI*)pUther->AI())->StartAI(); + m_bUtherHere = true; + } + } +}; + +/*### +## npc_arthas_dialog +###*/ + +enum +{ + GOSSIP_MENU_ARTHAS_1 = 100001, + GOSSIP_MENU_ARTHAS_2 = 100002, + GOSSIP_MENU_ARTHAS_3 = 100003, + GOSSIP_MENU_ARTHAS_4 = 100004, + GOSSIP_MENU_ARTHAS_5 = 100005 +}; + +#define GOSSIP_ITEM_ARTHAS_0 "I'm ready to start Culling of Stratholme." +#define GOSSIP_ITEM_ARTHAS_1 "Yes, my Prince. We're ready." +#define GOSSIP_ITEM_ARTHAS_2 "We're only doing what is best for Loarderon your Highness." +#define GOSSIP_ITEM_ARTHAS_3 "I'm ready." +#define GOSSIP_ITEM_ARTHAS_4 "For Lordaeron!" +#define GOSSIP_ITEM_ARTHAS_5 "I'm ready to battle the dreadlord, sire." + +bool GossipHello_npc_arthas(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance* pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + + if(pInstance && pInstance->GetData(TYPE_PHASE) == 0) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_1, pCreature->GetGUID()); + } + + if(pInstance && pInstance->GetData(TYPE_PHASE) == 5) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_2, pCreature->GetGUID()); + } + + if(pInstance && pInstance->GetData(TYPE_PHASE) == 8) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_3, pCreature->GetGUID()); + } + + if(pInstance && pInstance->GetData(TYPE_PHASE) == 9) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_4, pCreature->GetGUID()); + } + + return true; +} + +bool GossipSelect_npc_arthas(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance* m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + + if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 0) + { + m_pInstance->SetData(TYPE_PHASE, 1); + ((npc_arthasAI*)pCreature->AI())->EnableEscort(); + ((npc_arthasAI*)pCreature->AI())->RemoveGossip(); + ((npc_arthasAI*)pCreature->AI())->culling_faction = pPlayer->getFaction(); + } + + if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 5) + { + ((npc_arthasAI*)pCreature->AI())->EnableEscort(); + ((npc_arthasAI*)pCreature->AI())->RemoveGossip(); + } + + if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 8) + { + ((npc_arthasAI*)pCreature->AI())->EnableEscort(); + ((npc_arthasAI*)pCreature->AI())->RemoveGossip(); + } + + if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 9) + { + ((npc_arthasAI*)pCreature->AI())->EnableEscort(); + ((npc_arthasAI*)pCreature->AI())->RemoveGossip(); + if(Creature* pMalganis = pCreature->SummonCreature(NPC_MALGANIS,2296.665f,1502.362f,128.362f,4.961f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) + { + m_pInstance->SetData64(NPC_MALGANIS, pMalganis->GetGUID()); + pMalganis->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + return true; +} + +/*### +## npc_arthas_priest +###*/ enum { - SPELL_ARCANE_DISRUPTION = 49590 + SPELL_SMITE = 61923, + SPELL_HEAL = 62442 }; -bool EffectAuraDummy_spell_aura_dummy_npc_crates_dummy(const Aura* pAura, bool bApply) +struct MANGOS_DLL_DECL npc_arthas_priestAI : public ScriptedAI { - if (pAura->GetId() == SPELL_ARCANE_DISRUPTION && pAura->GetEffIndex() == EFFECT_INDEX_0 && bApply) + npc_arthas_priestAI(Creature *c) : ScriptedAI(c) + { + SetCombatMovement(false); + Reset(); + } + + uint32 m_uiSmiteTimer; + uint32 m_uiHealTimer; + + void Reset() + { + m_uiSmiteTimer = 100; + m_uiHealTimer = 1000; + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + } + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + + m_creature->SetLootRecipient(NULL); + + Reset(); + } + + void MoveInLineOfSight(Unit* pWho) { - if (Creature* pTarget = (Creature*)pAura->GetTarget()) + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) { - std::list lCrateBunnyList; - if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pTarget->GetInstanceData()) + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) { - pInstance->GetCratesBunnyOrderedList(lCrateBunnyList); - uint8 i = 0; - for (std::list::const_iterator itr = lCrateBunnyList.begin(); itr != lCrateBunnyList.end(); ++itr) + if (!m_creature->getVictim()) { - i++; - if (*itr == pTarget) - break; + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); } - - switch (i) + else if (m_creature->GetMap()->IsDungeon()) { - case 1: - // Start NPC_ROGER_OWENS Event - break; - case 2: - // Start NPC_SERGEANT_MORIGAN Event - break; - case 3: - // Start NPC_JENA_ANDERSON Event - break; - case 4: - // Start NPC_MALCOM_MOORE Event - break; - case 5: - // Start NPC_BARTLEBY_BATTSON Event - break; + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); } + } + } + } + + void UpdateAI(const uint32 uiDiff) + { - if (pInstance->GetData(TYPE_GRAIN_EVENT) != DONE) - pInstance->SetData(TYPE_GRAIN_EVENT, IN_PROGRESS); - // pTarget->ForcedDespawn(); // direct despawn has influence on visual effects, - // but despawning makes it impossible to multi-use the spell at the same place - // perhaps some add. GO-Visual + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiSmiteTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_SMITE); + m_uiSmiteTimer = 3000; + } + else m_uiSmiteTimer -= uiDiff; + + if(m_uiHealTimer < uiDiff) + { + if(m_creature->GetHealthPercent() <= 40.0f) + { + m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature, SPELL_HEAL); + m_uiHealTimer = 3000; + } + } + else m_uiHealTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + return; + } +}; + +/*### +## npc_arthas_marine +###*/ + +struct MANGOS_DLL_DECL npc_arthas_marineAI : public ScriptedAI +{ + npc_arthas_marineAI(Creature *c) : ScriptedAI(c) + { + Reset(); + } + + float LastX; + float LastY; + float LastZ; + + uint32 m_uiHealTimer; + + void Reset() + { + m_uiHealTimer = 3000; + } + + void Aggro(Unit* who) + { + LastX = m_creature->GetPositionX(); + LastY = m_creature->GetPositionY(); + LastZ = m_creature->GetPositionZ(); + } + + void 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); + } + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + + m_creature->SetLootRecipient(NULL); + m_creature->GetMotionMaster()->MovePoint(POINT_LAST_POINT, LastX, LastY, LastZ); + + Reset(); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) + { + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } } } } - return true; + + void UpdateAI(const uint32 uiDiff) + { + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiHealTimer < uiDiff) + { + if(m_creature->GetHealthPercent() <= 40.0f) + { + if(Creature* pHeal = GetClosestCreatureWithEntry(m_creature, NPC_PRIEST, 50.0f)) + { + if(pHeal->GetHealthPercent() > 40.0f) + { + pHeal->InterruptNonMeleeSpells(false); + pHeal->CastSpell(m_creature, SPELL_HEAL, false); + m_uiHealTimer = 3000; + } + } + } + } + else m_uiHealTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + return; + } +}; + +/*### +## npc_dark_conversion +###*/ + +/*enum +{ + SAY_PEOPLE01 = -1594099, + SAY_PEOPLE02 = -1594100, + SAY_PEOPLE03 = -1594101, + SAY_PEOPLE04 = -1594102, + SAY_PEOPLE05 = -1594103, +};*/ + +struct MANGOS_DLL_DECL npc_dark_conversionAI : public ScriptedAI +{ + npc_dark_conversionAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + + if (m_pInstance && m_pInstance->GetData(TYPE_ENCOUNTER) == IN_PROGRESS) + m_creature->UpdateEntry(NPC_ZOMBIE); + + Reset(); + } + +ScriptedInstance* m_pInstance; + +bool Special; +bool Conversion; +uint32 m_uiStep; +uint32 m_uiStepTimer; + + void Reset() + { + m_creature->setFaction(35); + Conversion = false; + Special = false; + m_uiStep = 1; + m_uiStepTimer = 5000; + + if (m_pInstance && m_pInstance->GetData(TYPE_ENCOUNTER) == IN_PROGRESS) + m_creature->UpdateEntry(NPC_ZOMBIE); + } + + void MalganisScared(Creature* target, float horizontalSpeed, float verticalSpeed) + { + float angle = target->GetAngle(m_creature); + float vsin = sin(angle); + float vcos = cos(angle); + + float ox, oy, oz; + m_creature->GetPosition(ox, oy, oz); + + float g = 19.23f;// seems that physic constant g(earth's gravity) in world of warcraft is about 2 times larger than real + float dh = verticalSpeed*verticalSpeed / (2*g); // maximum parabola height + float time = sqrtf(dh/(0.124976 * verticalSpeed)); //full move time in seconds // should be time = 2*Vert_speed/g, but.. + + float dis = time * horizontalSpeed; + float fx = ox + dis * vcos; + float fy = oy + dis * vsin; + float fz = oz; + + m_creature->UpdateGroundPositionZ(fx, fy, fz); + + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MovePoint(0, fx, fy, fz); + } + + void DarkConversion(bool Move) + { + m_creature->UpdateEntry(NPC_ZOMBIE); + if(Move == true) + { + uint64 m_uiArthasGUID = m_pInstance->GetData64(NPC_ARTHAS); + if(Creature* pArthas = m_pInstance->instance->GetCreature(m_uiArthasGUID)) + m_creature->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ()); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if(!m_pInstance) return; + + if(m_pInstance->GetData(TYPE_ENCOUNTER) == IN_PROGRESS) + { + if(Creature* pMalganis = GetClosestCreatureWithEntry(m_creature, NPC_MALGANIS_INTRO, 20.0f)) + { + if(Special == false) + { + float Dist = m_creature->GetDistance2d(pMalganis->GetPositionX(), pMalganis->GetPositionY()); + Dist = Dist + 2.0f; + MalganisScared(pMalganis, Dist, 1.0f); + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); + m_uiStepTimer = 5000; + Special = true; + } + } + + if(m_uiStepTimer < uiDiff && Conversion != true) + { + Conversion = true; + if(Special != false) + DarkConversion(true); + else + DarkConversion(false); + } + else m_uiStepTimer -= uiDiff; + + } + + DoMeleeAttackIfReady(); + + return; + } +}; + +CreatureAI* GetAI_npc_chromi_middle(Creature* pCreature) +{ + return new npc_chromi_middleAI(pCreature); +} + +CreatureAI* GetAI_npc_uther(Creature* pCreature) +{ + return new npc_utherAI(pCreature); +} + +CreatureAI* GetAI_npc_arthas(Creature* pCreature) +{ + return new npc_arthasAI(pCreature); +} + +CreatureAI* GetAI_npc_arthas_priest(Creature* pCreature) +{ + return new npc_arthas_priestAI(pCreature); +} + +CreatureAI* GetAI_npc_arthas_marine(Creature* pCreature) +{ + return new npc_arthas_marineAI(pCreature); +} + +CreatureAI* GetAI_npc_dark_conversion(Creature* pCreature) +{ + return new npc_dark_conversionAI(pCreature); } void AddSC_culling_of_stratholme() { - Script* pNewScript; + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_chromi_middle"; + newscript->pGossipHello = &GossipHello_npc_chromi_middle; + newscript->pGossipSelect = &GossipSelect_npc_chromi_middle; + newscript->GetAI = &GetAI_npc_chromi_middle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_uther"; + newscript->GetAI = &GetAI_npc_uther; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_arthas"; + newscript->GetAI = &GetAI_npc_arthas; + newscript->pGossipHello = &GossipHello_npc_arthas; + newscript->pGossipSelect = &GossipSelect_npc_arthas; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_arthas_priest"; + newscript->GetAI = &GetAI_npc_arthas_priest; + newscript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "npc_chromie"; - pNewScript->pGossipHello = &GossipHello_npc_chromie; - pNewScript->pGossipSelect = &GossipSelect_npc_chromie; - pNewScript->pQuestAccept = &QuestAccept_npc_chromie; - pNewScript->RegisterSelf(); + newscript = new Script; + newscript->Name = "npc_arthas_marine"; + newscript->GetAI = &GetAI_npc_arthas_marine; + newscript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "spell_dummy_npc_crates_bunny"; - pNewScript->pEffectAuraDummy = &EffectAuraDummy_spell_aura_dummy_npc_crates_dummy; - pNewScript->RegisterSelf(); + newscript = new Script; + newscript->Name = "npc_dark_conversion"; + newscript->GetAI = &GetAI_npc_dark_conversion; + newscript->RegisterSelf(); } diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h index 766a92f98..c7cb14d2c 100644 --- a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h @@ -1,194 +1,110 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 - * This program is free software licensed under GPL version 2 - * Please see the included DOCS/LICENSE.TXT for more information */ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ #ifndef DEF_CULLING_OF_STRATHOLME_H -#define DEF_CULLING_OF_STRATHOLME_H +#define DEF_CULLING_OF_STRATHOLME_H -enum +enum Data { - MAX_ENCOUNTER = 9, - - TYPE_GRAIN_EVENT = 0, // crates with plagued grain identified - TYPE_ARTHAS_INTRO_EVENT = 1, // Arhas Speech and Walk to Gates and short intro with MalGanis - TYPE_MEATHOOK_EVENT = 2, // Waves 1-5 - TYPE_SALRAMM_EVENT = 3, // Waves 6-10 - TYPE_EPOCH_EVENT = 4, // Townhall Event, Boss Killed - TYPE_ARTHAS_ESCORT_EVENT = 5, // Townhall to Malganis - TYPE_MALGANIS_EVENT = 6, // Malganis - TYPE_INFINITE_CORRUPTER_TIME = 7, // Time for 25min Timer - TYPE_INFINITE_CORRUPTER = 8, - - // Main Encounter NPCs - NPC_CHROMIE_INN = 26527, - NPC_CHROMIE_ENTRANCE = 27915, - NPC_CHROMIE_END = 30997, - NPC_HOURGLASS = 28656, - NPC_ARTHAS = 26499, - NPC_MEATHOOK = 26529, - NPC_SALRAMM_THE_FLESHCRAFTER = 26530, - NPC_CHRONO_LORD_EPOCH = 26532, - NPC_MALGANIS = 26533, - NPC_INFINITE_CORRUPTER = 32273, - NPC_LORDAERON_CRIER = 27913, - NPC_ZOMBIE = 27737, - - // Inn Event related NPC - NPC_MICHAEL_BELFAST = 30571, - NPC_HEARTHSINGER_FORRESTEN = 30551, - NPC_FRAS_SIABI = 30552, - NPC_FOOTMAN_JAMES = 30553, - NPC_MAL_CORRICKS = 31017, - NPC_GRYAN_STOUTMANTLE = 30561, - - // Grain Event NPCs - NPC_ROGER_OWENS = 27903, - NPC_SERGEANT_MORIGAN = 27877, - NPC_JENA_ANDERSON = 27885, - NPC_MALCOM_MOORE = 27891, // Not (yet?) spawned - NPC_BARTLEBY_BATTSON = 27907, - NPC_CRATES_BUNNY = 30996, - - // Intro Event NPCs - NPC_LORDAERON_FOOTMAN = 27745, - NPC_STRATHOLME_CITIZEN = 28167, - NPC_STRATHOLME_RESIDENT = 28169, - - // Mobs in Stratholme (to despawn) -- only here for sake of completeness handling remains open (mangos feature) - NPC_MAGISTRATE_BARTHILAS = 30994, - NPC_STEPHANIE_SINDREE = 31019, - NPC_LEEKA_TURNER = 31027, - NPC_SOPHIE_AAREN = 31021, - NPC_ROBERT_PIERCE = 31025, - NPC_GEORGE_GOODMAN = 31022, - - // Others NPCs in Stratholme - NPC_EMERY_NEILL = 30570, - NPC_EDWARD_ORRICK = 31018, - NPC_OLIVIA_ZENITH = 31020, - - // Townhall Event NPCs - NPC_AGIATED_STRATHOLME_CITIZEN = 31126, - NPC_AGIATED_STRATHOLME_RESIDENT = 31127, - NPC_PATRICIA_O_REILLY = 31028, - - // Gameobjects - GO_DOOR_BOOKCASE = 188686, - GO_DARK_RUNED_CHEST = 190663, - GO_DARK_RUNED_CHEST_H = 193597, - - // World States - WORLD_STATE_CRATES = 3479, - WORLD_STATE_CRATES_COUNT = 3480, - WORLD_STATE_WAVE = 3504, - WORLD_STATE_TIME = 3932, - WORLD_STATE_TIME_COUNTER = 3931, - - // Areatrigger - AREATRIGGER_INN = 5291, - /* - 5085 before bridge - could be Uther SpawnPos - 5148 ini entrance - 5181 ini exit - 5249 fras siabis store - 5250 leeking shields...(store) - 5251 bar in stratholme - 5252 Aaren flowers - 5253 Angelicas boutique - 5256 townhall - 5291 Inn */ -}; - -enum eInstancePosition -{ - POS_ARTHAS_INTRO = 1, - POS_ARTHAS_WAVES = 2, - POS_ARTHAS_TOWNHALL = 3, - POS_ARTHAS_ESCORTING = 4, - POS_ARTHAS_MALGANIS = 5, - POS_INSTANCE_FINISHED = 6 -}; - -class MANGOS_DLL_DECL instance_culling_of_stratholme : public ScriptedInstance -{ - public: - instance_culling_of_stratholme(Map* pMap); - ~instance_culling_of_stratholme() {} - - void Initialize(); - - void OnCreatureCreate(Creature* pCreature); - void OnObjectCreate(GameObject* pGo); - - void SetData(uint32 uiType, uint32 uiData); - uint32 GetData(uint32 uiType); - uint64 GetData64(uint32 uiData); - - const char* Save() { return strInstData.c_str(); } - void Load(const char* chrIn); - - void Update(uint32 uiDiff); - - void GetStratAgiatedCitizenList(std::list &lList){ lList = m_lAgiatedCitizenGUIDList; }; - void GetStratAgiatedResidentList(std::list &lList){ lList = m_lAgiatedResidentGUIDList; }; - - void GetCratesBunnyOrderedList(std::list &lList); - Creature* GetStratIntroFootman(); - void GetResidentOrderedList(std::list &lList); - void DoSpawnArthasIfNeeded(); - void DoSpawnChromieIfNeeded(); - uint8 GetInstancePosition(); - void ArthasJustDied(); - - protected: - void OnPlayerEnter(Player* pPlayer); - Player* GetPlayerInMap(); - void UpdateQuestCredit(); - void DoChromieHurrySpeech(); - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - uint8 m_uiGrainCrateCount; - uint32 m_uiRemoveCrateStateTimer; - uint32 m_uiArthasRespawnTimer; - - uint64 m_uiChromieInnGUID; - uint64 m_uiChromieEntranceGUID; - uint64 m_uiChromieEndGUID; - uint64 m_uiHourglassGUID; - uint64 m_uiArthasGUID; - uint64 m_uiMeathookGUID; - uint64 m_uiSalrammGUID; - uint64 m_uiEpochGUID; - uint64 m_uiMalganisGUID; - uint64 m_uiCorrupterGUID; - uint64 m_uiLordaeronCrierGUID; - - uint64 m_uiBelfastGUID; - uint64 m_uiForrestenGUID; - uint64 m_uiSiabiGUID; - uint64 m_uiJamesGUID; - uint64 m_uiCorricksGUID; - uint64 m_uiStoutmantleGUID; - - uint64 m_uiOwensGUID; - uint64 m_uiMoriganGUID; - uint64 m_uiAndersonGUID; - uint64 m_uiMooreGUID; - uint64 m_uiBattsonGUID; - - uint64 m_uiOReillyGUID; - - std::list m_luiCratesBunnyGUIDs; - std::list m_luiFootmanGUIDs; - std::list m_luiResidentGUIDs; - - std::list m_lAgiatedCitizenGUIDList; - std::list m_lAgiatedResidentGUIDList; - - uint64 m_uiDoorBookcaseGUID; - uint64 m_uiDarkRunedChestGUID; + TYPE_QUEST = 1, + TYPE_INTRO = 2, + TYPE_CRATES_COUNT = 3, + TYPE_PHASE = 4, + TYPE_ENCOUNTER = 5, + TYPE_WAVE_COUNT = 6, + TYPE_WING = 7, + TYPE_BONUS = 8, + TYPE_MALGANIS = 9, + + DATA_TEMPSUMMON = 10, + + QUEST_DISPELLING_ILLUSIONS = 13149, + QUEST_A_ROYAL_ESCORT = 13151, + ITEM_ARCANE_DISRUPTOR = 37888, + + NPC_CHROMI01 = 26527, + NPC_CHROMI02 = 27915, + NPC_ARTHAS = 26499, + NPC_JAINA = 26497, + NPC_UTHER = 26528, + NPC_KNIGHT = 28612, + NPC_MIKE = 30571, + NPC_MAL_CORICS = 31017, + NPC_GRIAN_STONE = 30561, + NPC_JAMES = 30553, + NPC_FRAS_FRASIABI = 30552, + NPC_FORRESTER = 30551, + NPC_ROGER = 27903, + NPC_CRATE = 30996, + NPC_MORIGAN = 27877, + NPC_PERELLI = 27876, + NPC_JENA = 27885, + NPC_MARTHA = 27884, + NPC_MALCOLM = 27891, + NPC_DOG = 27892, + NPC_BARTLEBY = 27907, + NPC_MARINE = 27745, + NPC_PRIEST = 27747, + + NPC_INFINITE_ADVERSARY = 27742, + NPC_INFINITE_HUNTER = 27743, + NPC_INFINITE_AGENT = 27744, + NPC_TIME_RIFT = 28409, + NPC_TIME_RIFT_2 = 28439, + NPC_ZOMBIE = 27737, + NPC_GHOUL = 28249, + NPC_NECROMANCER = 28200, + NPC_STALKER = 28199, + NPC_FIEND = 27734, + NPC_GOLEM = 28201, + NPC_EGHOUL = 27729, + NPC_CONSTRUCT = 27736, + NPC_ACOLYTE = 27731, + NPC_MEATHOOK = 26529, + NPC_SALRAMM = 26530, + NPC_EPOCH = 26532, + NPC_MALGANIS = 26533, + NPC_CITY = 28167, + NPC_INFINITE_CORRUPTOR = 32273, + + GO_CRATE_LIGHT = 190117, + GO_SHKAF_GATE = 188686, + GO_MALGANIS_GATE1 = 187711, + GO_MALGANIS_GATE2 = 187723, + GO_MALGANIS_CHEST = 190663, + GO_MALGANIS_CHEST_H = 193597, + GO_EXIT = 191788, + + + WORLD_STATE_COS_TIME_ON = 3932, + WORLD_STATE_COS_TIME_COUNT = 3931, + WORLD_STATE_COS_WAVE_COUNT = 3504, + WORLD_STATE_COS_CRATE_ON = 3479, + WORLD_STATE_COS_CRATE_COUNT = 3480, + + RIGHT = 1, + LEFT = 2 }; #endif diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholmeai.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholmeai.cpp new file mode 100644 index 000000000..9c56ecd92 --- /dev/null +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholmeai.cpp @@ -0,0 +1,1293 @@ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ + +#include "precompiled.h" +#include "culling_of_stratholme.h" +#include "escort_ai.h" +#include "WorldPacket.h" + +/*### +## npc_chromi_start +###*/ + +#define GOSSIP_ITEM_CHROMI1 "Why have I been sent back to this particular place and time?" +#define GOSSIP_ITEM_CHROMI2 "What was this decision?" +#define GOSSIP_ITEM_CHROMI3 "So how does the infinite Dragonflight plan to Interfere?" + +enum +{ + GOSSIP_TEXTID_CHROMI1 = 12939, + GOSSIP_TEXTID_CHROMI2 = 12949, + GOSSIP_TEXTID_CHROMI3 = 12950, + GOSSIP_TEXTID_CHROMI4 = 12952 +}; + +bool GossipHello_npc_chromi_start(Player* pPlayer, Creature* pCreature) +{ + if(pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + + ScriptedInstance* pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + if (pPlayer && pPlayer->GetQuestStatus(QUEST_DISPELLING_ILLUSIONS) == QUEST_STATUS_COMPLETE && pInstance && pInstance->GetData(TYPE_QUEST) == NOT_STARTED) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI1, pCreature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_chromi_start(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI2, pCreature->GetGUID()); + } + + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI3, pCreature->GetGUID()); + } + + if (uiAction == GOSSIP_ACTION_INFO_DEF+3) + { + // START COUNTER HERE + if (ScriptedInstance* pInstance = (ScriptedInstance*)pCreature->GetInstanceData()) + { + pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 1); + pInstance->SetData(TYPE_QUEST, IN_PROGRESS); + } + + if (pPlayer) + if (Item* pItem = pPlayer->StoreNewItemInInventorySlot(ITEM_ARCANE_DISRUPTOR, 1)) + pPlayer->SendNewItem(pItem, 1, true, false); + + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI4, pCreature->GetGUID()); + } + + return true; +} + +struct MANGOS_DLL_DECL npc_chromi_startAI : public ScriptedAI +{ + npc_chromi_startAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + m_bCounterHere = false; + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool m_bCounterHere; + + void Reset() + { + m_bCounterHere = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_bCounterHere && m_pInstance && pWho && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(pWho) <= 15 && ((Player*)pWho)->GetQuestStatus(QUEST_DISPELLING_ILLUSIONS) == QUEST_STATUS_INCOMPLETE) + { + m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 1); + m_pInstance->SetData(TYPE_QUEST, IN_PROGRESS); + m_bCounterHere = true; + } + } +}; + +/*### +## npc_mike +###*/ + +enum +{ + SAY_MIKE01 = -1557270, + SAY_FORRESTER02 = -1557271, + SAY_JAMES03 = -1557272, + SAY_SIABI04 = -1557273, + SAY_MIKE05 = -1557274, + SAY_CORICKS06 = -1557275, + SAY_GRIAN07 = -1557276, + SAY_CORICKS08 = -1557277, + SAY_JAMES09 = -1557278, + SAY_FORRESTER10 = -1557279, + + EMOTE_SHOT = 5, + EMOTE_TALK = 1, + EMOTE_POINT = 25, + EMOTE_NO = 274, + EMOTE_LAUGH = 11 +}; + +struct MANGOS_DLL_DECL npc_mikeAI : public ScriptedAI +{ + npc_mikeAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiStep; + uint32 m_uiStepTimer; + uint32 m_uiPhase; + + uint64 m_uiForesterGUID; + uint64 m_uiJamesGUID; + uint64 m_uiSiabiGUID; + uint64 m_uiCorricksGUID; + uint64 m_uiGryanGUID; + + void Reset() + { + if(m_uiPhase != 2) + { + m_uiStep = 0; + m_uiStepTimer = 100; + m_uiPhase = 0; + } + } + + void MoveInLineOfSight(Unit* who) + { + if (!who) + return; + + if(!m_pInstance) return; + + if (who->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(who) <= 15 && who->GetPositionZ() > 99.50f && m_uiPhase == 0) + { + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, who->GetGUID()); + m_uiPhase = 1; + } + } + + void TavernEvent() + { + switch(m_uiStep) + { + case 0: + DoScriptText(SAY_MIKE01, m_creature); + m_uiStepTimer = 4000; + break; + case 1: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + m_uiStepTimer = 5000; + break; + case 2: + m_uiForesterGUID = m_pInstance->GetData64(NPC_FORRESTER); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiForesterGUID)) + DoScriptText(SAY_FORRESTER02, pTemp); + m_uiStepTimer = 6000; + break; + case 3: + m_uiJamesGUID = m_pInstance->GetData64(NPC_JAMES); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiJamesGUID)) + DoScriptText(SAY_JAMES03, pTemp); + m_uiStepTimer = 5000; + break; + case 4: + m_uiSiabiGUID = m_pInstance->GetData64(NPC_FRAS_FRASIABI); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiSiabiGUID)) + DoScriptText(SAY_SIABI04, pTemp); + m_uiStepTimer = 2000; + break; + case 5: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiSiabiGUID)) + pTemp->HandleEmoteCommand(EMOTE_SHOT); + m_uiStepTimer = 5000; + break; + case 6: + m_creature->GetMotionMaster()->MovePoint(0, 1554.849f, 588.465f, 99.775f); + m_uiStepTimer = 3000; + break; + case 7: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiSiabiGUID)) + pTemp->HandleEmoteCommand(EMOTE_LAUGH); + m_uiStepTimer = 3000; + break; + case 8: + DoScriptText(SAY_MIKE05, m_creature); + m_uiStepTimer = 2000; + break; + case 9: + m_creature->HandleEmoteCommand(EMOTE_SHOT); + m_uiStepTimer = 1000; + break; + case 10: + m_uiCorricksGUID = m_pInstance->GetData64(NPC_MAL_CORICS); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiCorricksGUID)) + DoScriptText(SAY_CORICKS06, pTemp); + m_uiStepTimer = 4000; + break; + case 11: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiCorricksGUID)) + pTemp->HandleEmoteCommand(EMOTE_TALK); + m_uiGryanGUID = m_pInstance->GetData64(NPC_GRIAN_STONE); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiGryanGUID)) + DoScriptText(SAY_GRIAN07, pTemp); + m_uiStepTimer = 11000; + break; + case 12: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiCorricksGUID)) + DoScriptText(SAY_CORICKS08, pTemp); + m_creature->GetMotionMaster()->MovePoint(0, 1549.609f, 575.544f, 100.052f); + m_uiStepTimer = 2000; + break; + case 13: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiJamesGUID)) + DoScriptText(SAY_JAMES09, pTemp); + m_uiStepTimer = 2000; + break; + case 14: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiJamesGUID)) + pTemp->HandleEmoteCommand(EMOTE_TALK); + m_uiStepTimer = 5000; + break; + case 15: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiForesterGUID)) + DoScriptText(SAY_FORRESTER10, pTemp); + m_uiPhase = 2; + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == 1) + { + if(m_uiStepTimer < uiDiff) + { + TavernEvent(); + m_uiStep++; + } + else m_uiStepTimer -= uiDiff; + } + + return; + } +}; + +/*### +## npc_roger +###*/ + +enum +{ + SAY_ROGER01 = -1557280, + SAY_ROGER02 = -1557281, + SAY_ROGER03 = -1557282, + SAY_ROGER04 = -1557283, +}; + +struct MANGOS_DLL_DECL npc_rogerAI : public ScriptedAI +{ + npc_rogerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiStep; + uint32 m_uiStepTimer; + uint32 m_uiPhase; + + void Reset() + { + if(m_uiPhase != 2) + { + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + m_uiStep = 0; + m_uiStepTimer = 100; + m_uiPhase = 0; + } + } + + void StartRoger() + { + m_uiPhase = 1; + } + + void FirstCrateEvent() + { + switch(m_uiStep) + { + case 0: + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_uiStepTimer = 7000; + break; + case 1: + MoveToPoint(m_creature, 1590.055f, 615.727f, 99.795f, 7000); + m_uiStepTimer = 6900; + break; + case 2: + MoveToPoint(m_creature, 1584.039f, 622.049f, 99.907f, 4000); + m_uiStepTimer = 3900; + break; + case 3: + MoveToPoint(m_creature, 1578.787f, 623.924f, 99.855f, 2000); + m_uiStepTimer = 2500; + break; + case 4: + DoScriptText(SAY_ROGER01, m_creature); + m_uiStepTimer = 6000; + break; + case 5: + MoveToPoint(m_creature, 1579.393f, 624.018f, 99.886f, 900); + m_uiStepTimer = 2000; + break; + case 6: + DoScriptText(SAY_ROGER02, m_creature); + m_uiStepTimer = 6000; + break; + case 7: + MoveToPoint(m_creature, 1579.387f, 623.198f, 99.837f, 300); + m_uiStepTimer = 1000; + break; + case 8: + DoScriptText(SAY_ROGER03, m_creature); + m_uiStepTimer = 4000; + break; + case 9: + MoveToPoint(m_creature, 1575.576f, 619.935f, 99.422f, 1500); + m_uiStepTimer = 2000; + break; + case 10: + MoveToPoint(m_creature, 1575.833f, 620.471f, 99.466f, 300); + m_uiStepTimer = 1000; + break; + case 11: + DoScriptText(SAY_ROGER04, m_creature); + m_uiStepTimer = 6000; + break; + case 12: + MoveToPoint(m_creature, 1580.215f, 624.368f, 99.924f, 2000); + m_uiStepTimer = 1900; + break; + case 13: + MoveToPoint(m_creature, 1587.471f, 618.181f, 99.850f, 4000); + m_uiStepTimer = 3900; + break; + case 14: + MoveToPoint(m_creature, 1592.646f, 590.888f, 99.151f, 11000); + m_uiStepTimer = 13000; + break; + case 15: + m_uiPhase = 2; + m_creature->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer) + { + unit->GetMotionMaster()->MovementExpired(false); + unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation()); + unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == 1) + { + if(m_uiStepTimer < uiDiff) + { + FirstCrateEvent(); + m_uiStep++; + } + else m_uiStepTimer -= uiDiff; + } + + return; + } +}; + +/*### +## npc_morigan +###*/ + +enum +{ + SAY_MORIGAN01 = -1557284, + SAY_PERELLI02 = -1557285, + SAY_MORIGAN03 = -1557286, + SAY_PERELLI04 = -1557287, + SAY_MORIGAN05 = -1557288, + SAY_PERELLI06 = -1557289, + SAY_MORIGAN07 = -1557290, +}; + +struct MANGOS_DLL_DECL npc_moriganAI : public ScriptedAI +{ + npc_moriganAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint64 m_uiPerelliGUID; + uint32 m_uiStep; + uint32 m_uiStepTimer; + uint32 m_uiPhase; + + void Reset() + { + if(m_uiPhase != 2) + { + m_uiStep = 0; + m_uiStepTimer = 100; + m_uiPhase = 0; + } + } + + void StartMorigan() + { + m_uiPhase = 1; + } + + void SecondCrateEvent() + { + switch(m_uiStep) + { + case 0: + DoScriptText(SAY_MORIGAN01, m_creature); + m_uiStepTimer = 6000; + break; + case 1: + m_uiPerelliGUID = m_pInstance->GetData64(NPC_PERELLI); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID)) + DoScriptText(SAY_PERELLI02, pTemp); + m_uiStepTimer = 2000; + break; + case 2: + m_creature->GetMotionMaster()->MovePoint(0, 1564.138f, 668.343f, 102.058f); + m_uiStepTimer = 2000; + break; + case 3: + m_creature->GetMotionMaster()->MovePoint(0, 1567.956f, 667.776f, 102.094f); + m_uiStepTimer = 1500; + break; + case 4: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 1569.615f, 668.859f, 102.180f); + m_uiStepTimer = 2000; + break; + case 5: + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + m_uiStepTimer = 1000; + break; + case 6: + DoScriptText(SAY_MORIGAN03, m_creature); + m_uiStepTimer = 3000; + break; + case 7: + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID)) + { + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID()); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + } + m_uiStepTimer = 3000; + break; + case 8: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID)) + DoScriptText(SAY_PERELLI04, pTemp); + m_uiStepTimer = 3000; + break; + case 9: + DoScriptText(SAY_MORIGAN05, m_creature); + m_uiStepTimer = 9000; + break; + case 10: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID)) + DoScriptText(SAY_PERELLI06, pTemp); + m_uiStepTimer = 6000; + break; + case 11: + DoScriptText(SAY_MORIGAN07, m_creature); + m_uiStepTimer = 4000; + break; + case 12: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID)) + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, 0); + MoveToPoint(m_creature, 1576.119f, 657.675f, 102.09f, 5000); + m_uiStepTimer = 4900; + break; + case 13: + MoveToPoint(m_creature, 1586.040f, 646.113f, 100.910f, 6000); + m_uiStepTimer = 5900; + break; + case 14: + MoveToPoint(m_creature, 1609.189f, 697.134f, 106.902f, 23000); + m_uiStepTimer = 24900; + break; + case 15: + m_uiPhase = 2; + m_creature->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer) + { + unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation()); + unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == 1) + { + if(m_uiStepTimer < uiDiff) + { + SecondCrateEvent(); + m_uiStep++; + } + else m_uiStepTimer -= uiDiff; + } + + return; + } +}; + +/*### +## npc_jena +###*/ + +enum +{ + SAY_JENA01 = -1557291, + SAY_MARTHA02 = -1557292, + SAY_JENA03 = -1557293, + SAY_JENA04 = -1557294, + SAY_MARTHA05 = -1557295, + +}; + +struct MANGOS_DLL_DECL npc_jenaAI : public ScriptedAI +{ + npc_jenaAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint64 m_uiMarthaGUID; + uint32 m_uiStep; + uint32 m_uiStepTimer; + uint32 m_uiPhase; + + void Reset() + { + if(m_uiPhase != 2) + { + m_uiStep = 0; + m_uiStepTimer = 100; + m_uiPhase = 0; + } + } + + void StartJena() + { + m_uiPhase = 1; + } + + void ThirdCrateEvent() + { + switch(m_uiStep) + { + case 0: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 1605.546f, 744.869f, 114.731f); + m_uiStepTimer = 1900; + break; + case 1: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 1614.967f, 743.673f, 114.063f); + m_uiStepTimer = 4900; + break; + case 2: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 1623.848f, 729.251f, 112.410f); + m_uiStepTimer = 6900; + break; + case 3: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 1633.460f, 726.261f, 113.518f); + m_uiStepTimer = 4000; + break; + case 4: + m_uiMarthaGUID = m_pInstance->GetData64(NPC_MARTHA); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID()); + DoScriptText(SAY_JENA01, m_creature); + m_uiStepTimer = 3000; + break; + case 5: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + { + pTemp->RemoveAurasDueToSpell(58925); + pTemp->GetMotionMaster()->MovePoint(0, 1635.918f, 724.357f, 113.561f); + } + m_uiStepTimer = 1000; + break; + case 6: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + { + pTemp->GetMotionMaster()->MovementExpired(false); + pTemp->GetMotionMaster()->MovePoint(0, 1636.721f, 725.88f, 113.561f); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + } + m_uiStepTimer = 1000; + break; + case 7: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + DoScriptText(SAY_MARTHA02, pTemp); + m_uiStepTimer = 4000; + break; + case 8: + DoScriptText(SAY_JENA03, m_creature); + m_uiStepTimer = 3000; + break; + case 9: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + m_creature->GetMotionMaster()->MovePoint(0, 1629.278f, 727.894f, 112.636f); + m_uiStepTimer = 1500; + break; + case 10: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + { + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, 0); + pTemp->GetMap()->CreatureRelocation(pTemp, 1640.089f, 725.766f, 113.561f, 4.77f); + pTemp->SendMonsterMove(1640.089f, 725.766f, 113.561f, SPLINETYPE_NORMAL , pTemp->GetSplineFlags(), 1500); + } + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, 1629.452f, 729.416f, 112.712f); + m_uiStepTimer = 1000; + break; + case 11: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + pTemp->GetMotionMaster()->MovePoint(0, 1640.103f, 725.522f, 113.561f); + m_uiStepTimer = 500; + break; + case 12: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + pTemp->CastSpell(pTemp, 58925, false); + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + m_uiStepTimer = 1500; + break; + case 13: + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_uiStepTimer = 1000; + break; + case 14: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID()); + DoScriptText(SAY_JENA04, m_creature); + m_uiStepTimer = 3000; + break; + case 15: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID)) + { + pTemp->RemoveAurasDueToSpell(58925); + DoScriptText(SAY_MARTHA05, pTemp); + MoveToPoint(pTemp, 1638.196f, 726.171f, 113.561f, 1000); + } + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + MoveToPoint(m_creature, 1615.590f, 719.509f, 110.311f, 2000); + m_uiStepTimer = 2000; + break; + case 16: + MoveToPoint(m_creature, 1596.436f, 670.809f, 103.747f, 7000); + m_uiStepTimer = 6900; + break; + case 17: + MoveToPoint(m_creature, 1571.549f, 609.837f, 99.767f, 9000); + m_uiStepTimer = 11000; + break; + case 18: + m_uiPhase = 2; + m_creature->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer) + { + unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation()); + unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == 1) + { + if(m_uiStepTimer < uiDiff) + { + ThirdCrateEvent(); + m_uiStep++; + } + else m_uiStepTimer -= uiDiff; + } + + return; + } +}; + +/*### +## npc_malcolm +###*/ + +enum +{ + SOUND_ID_DOG_GROWL = 1108, + SOUND_ID_DOG_HOWL = 1018, + EMOTE_DOG_HOWL = 393, + + SAY_MALCOLM01 = -1557296, + SAY_MALCOLM02 = -1557297, + SAY_MALCOLM03 = -1557298, + SAY_MALCOLM04 = -1557299, +}; + +struct MANGOS_DLL_DECL npc_malcolmAI : public ScriptedAI +{ + npc_malcolmAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint64 m_uiDogGUID; + uint32 m_uiStep; + uint32 m_uiStepTimer; + uint32 m_uiPhase; + + void Reset() + { + if(m_uiPhase != 2) + { + m_uiStep = 0; + m_uiStepTimer = 100; + m_uiPhase = 0; + } + } + + void StartMalcolm() + { + m_uiPhase = 1; + } + + void FourCrateEvent() + { + switch(m_uiStep) + { + case 0: + MoveToPoint(m_creature, 1614.066f, 796.722f, 121.739f, 5500); + m_uiDogGUID = m_pInstance->GetData64(NPC_DOG); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + MoveToPoint(pTemp, 1611.459f, 793.274f, 121.928f, 5500); + m_uiStepTimer = 5400; + break; + case 1: + DoScriptText(SAY_MALCOLM01, m_creature); + MoveToPoint(m_creature, 1622.820f, 798.816f, 120.570f, 3500); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + MoveToPoint(pTemp, 1621.467f, 794.323f, 120.323f, 3500); + m_uiStepTimer = 3400; + break; + case 2: + MoveToPoint(m_creature, 1626.574f, 806.781f, 120.270f, 3500); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + MoveToPoint(pTemp, 1629.232f, 803.629f, 120.011f, 3500); + m_uiStepTimer = 3400; + break; + case 3: + MoveToPoint(m_creature, 1622.782f, 808.533f, 121.249f, 1500); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + MoveToPoint(pTemp, 1629.265f, 805.245f, 120.070f, 300); + m_uiStepTimer = 300; + break; + case 4: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + pTemp->PlayDirectSound(SOUND_ID_DOG_GROWL); + m_uiStepTimer = 500; + break; + case 5: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID()); + DoScriptText(SAY_MALCOLM02, m_creature); + m_uiStepTimer = 2000; + break; + case 6: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + MoveToPoint(pTemp, 1629.163f, 809.738f, 120.369f, 1500); + m_uiStepTimer = 2000; + break; + case 7: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + { + pTemp->HandleEmoteCommand(EMOTE_DOG_HOWL); + pTemp->PlayDirectSound(SOUND_ID_DOG_HOWL); + } + m_uiStepTimer = 4000; + break; + case 8: + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + MoveToPoint(m_creature, 1629.922f, 807.799f, 120.122f, 3000); + m_uiStepTimer = 2900; + break; + case 9: + MoveToPoint(m_creature, 1632.169f, 809.851f, 120.047f, 1000); + m_uiStepTimer = 900; + break; + case 10: + MoveToPoint(m_creature, 1630.651f, 811.149f, 120.307f, 800); + m_uiStepTimer = 800; + break; + case 11: + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + DoScriptText(SAY_MALCOLM03, m_creature); + m_uiStepTimer = 4000; + break; + case 12: + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID()); + DoScriptText(SAY_MALCOLM04, m_creature); + m_uiStepTimer = 7000; + break; + case 13: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + MoveToPoint(pTemp, 1630.692f, 808.011f, 120.083f, 400); + m_uiStepTimer = 600; + break; + case 14: + if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID)) + pTemp->SetStandState(UNIT_STAND_STATE_SIT); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + MoveToPoint(m_creature, 1641.452f, 812.600f, 119.948f, 4000); + m_uiStepTimer = 3900; + break; + case 15: + MoveToPoint(m_creature, 1657.975f, 857.352f, 119.097f, 18000); + m_uiStepTimer = 17900; + break; + case 16: + MoveToPoint(m_creature, 1679.852f, 912.245f, 120.533f, 23000); + m_uiStepTimer = 22900; + break; + case 17: + MoveToPoint(m_creature, 1699.915f, 967.110f, 121.643f, 23000); + m_uiStepTimer = 22900; + break; + case 18: + MoveToPoint(m_creature, 1678.393f, 1026.890f, 125.431f, 25000); + m_uiStepTimer = 24900; + break; + case 19: + MoveToPoint(m_creature, 1678.943f, 1093.130f, 126.899f, 26000); + m_uiStepTimer = 25900; + break; + case 20: + MoveToPoint(m_creature, 1700.042f, 1103.880f, 130.872f, 9000); + m_uiStepTimer = 10900; + break; + case 21: + m_uiPhase = 2; + m_creature->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer) + { + unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation()); + unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == 1) + { + if(m_uiStepTimer < uiDiff) + { + FourCrateEvent(); + m_uiStep++; + } + else m_uiStepTimer -= uiDiff; + } + + return; + } +}; + +/*### +## npc_bartleby +###*/ + +enum +{ + SAY_BARTLEBY01 = -1557300, + SAY_BARTLEBY02 = -1557301, + SAY_BARTLEBY03 = -1557302, + SAY_BARTLEBY04 = -1557303, + SAY_BARTLEBY05 = -1557304, +}; + +struct MANGOS_DLL_DECL npc_bartleby_csAI : public ScriptedAI +{ + npc_bartleby_csAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiStep; + uint32 m_uiStepTimer; + uint32 m_uiPhase; + + void Reset() + { + if(m_uiPhase != 4) + { + m_uiStep = 0; + m_uiStepTimer = 100; + m_uiPhase = 0; + } + } + + void MoveInLineOfSight(Unit* who) + { + if (!who) + return; + + if(!m_pInstance) return; + + if (who->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(who) <= 20 && m_uiPhase == 0) + { + m_uiPhase = 1; + } + } + + void StartBartleby() + { + m_uiPhase = 3; + } + + void FifthCrateEvent() + { + switch(m_uiStep) + { + case 0: + DoScriptText(SAY_BARTLEBY03, m_creature); + MoveToPoint(m_creature, 1672.539f, 872.277f, 120.113f, 1000); + m_uiStepTimer = 1000; + break; + case 1: + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + m_uiStepTimer = 3000; + break; + case 2: + DoScriptText(SAY_BARTLEBY04, m_creature); + m_uiStepTimer = 7000; + break; + case 3: + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_uiStepTimer = 1000; + break; + case 4: + DoScriptText(SAY_BARTLEBY05, m_creature); + MoveToPoint(m_creature, 1663.054f, 869.959f, 119.734f, 3000); + m_uiStepTimer = 2900; + break; + case 5: + MoveToPoint(m_creature, 1640.732f, 812.422f, 119.933f, 24000); + m_uiStepTimer = 23900; + break; + case 6: + MoveToPoint(m_creature, 1623.704f, 755.741f, 115.710f, 23000); + m_uiStepTimer = 22900; + break; + case 7: + MoveToPoint(m_creature, 1607.108f, 699.637f, 106.971f, 23000); + m_uiStepTimer = 22900; + break; + case 8: + MoveToPoint(m_creature, 1587.750f, 646.929f, 100.990f, 21000); + m_uiStepTimer = 20900; + break; + case 9: + MoveToPoint(m_creature, 1571.103f, 660.949f, 102.084f, 8000); + m_uiStepTimer = 10900; + break; + case 10: + m_uiPhase = 4; + m_creature->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void SpeechEvent() + { + switch(m_uiStep) + { + case 0: + DoScriptText(SAY_BARTLEBY01, m_creature); + m_uiStepTimer = 5000; + break; + case 1: + DoScriptText(SAY_BARTLEBY02, m_creature); + if(m_uiPhase == 1) + m_uiPhase = 2; + break; + } + } + + void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer) + { + unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation()); + unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == 3) + { + if(m_uiStepTimer < uiDiff) + { + FifthCrateEvent(); + m_uiStep++; + } + else m_uiStepTimer -= uiDiff; + } + + if(m_uiPhase == 1) + { + if(m_uiStepTimer < uiDiff) + { + SpeechEvent(); + m_uiStep++; + } + else m_uiStepTimer -= uiDiff; + } + + return; + } +}; + +/*### +## npc_crates +###*/ + +enum +{ + SPELL_LIGHT = 49590 +}; + +struct MANGOS_DLL_DECL npc_stratholme_cratesAI : public ScriptedAI +{ + npc_stratholme_cratesAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool Active; + + void Reset() + { + Active = false; + } + + void UpdateAI(const uint32 uiDiff) + { + if(!m_pInstance) return; + + if(m_creature->HasAura(SPELL_LIGHT) && Active != true) + { + if(Creature* pRoger = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ROGER))) + { + if(m_creature->GetDistance2d(pRoger->GetPositionX(), pRoger->GetPositionY()) < 50.0f) + { + ((npc_rogerAI*)pRoger->AI())->StartRoger(); + } + } + + if(Creature* pMorigan = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MORIGAN))) + { + if(m_creature->GetDistance2d(pMorigan->GetPositionX(), pMorigan->GetPositionY()) < 50.0f) + { + ((npc_moriganAI*)pMorigan->AI())->StartMorigan(); + } + } + + if(Creature* pJena = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_JENA))) + { + if(m_creature->GetDistance2d(pJena->GetPositionX(), pJena->GetPositionY()) < 50.0f) + { + ((npc_jenaAI*)pJena->AI())->StartJena(); + } + } + + if(Creature* pMalcolm = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALCOLM))) + { + if(m_creature->GetDistance2d(pMalcolm->GetPositionX(), pMalcolm->GetPositionY()) < 50.0f) + { + ((npc_malcolmAI*)pMalcolm->AI())->StartMalcolm(); + } + } + + if(Creature* pBartleby = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_BARTLEBY))) + { + if(m_creature->GetDistance2d(pBartleby->GetPositionX(), pBartleby->GetPositionY()) < 50.0f) + { + ((npc_bartleby_csAI*)pBartleby->AI())->StartBartleby(); + } + } + + m_pInstance->SetData(TYPE_CRATES_COUNT, 1); + if(GameObject* pLight = GetClosestGameObjectWithEntry(m_creature, GO_CRATE_LIGHT, 5.0f)) + pLight->SetPhaseMask(0, true); + //m_creature->SetPhaseMask(0, true); + Active = true; + } + + return; + } +}; + +CreatureAI* GetAI_npc_chromi_start(Creature* pCreature) +{ + return new npc_chromi_startAI(pCreature); +} + +CreatureAI* GetAI_npc_mike(Creature* pCreature) +{ + return new npc_mikeAI(pCreature); +} + +CreatureAI* GetAI_npc_roger(Creature* pCreature) +{ + return new npc_rogerAI(pCreature); +} + +CreatureAI* GetAI_npc_morigan(Creature* pCreature) +{ + return new npc_moriganAI(pCreature); +} + +CreatureAI* GetAI_npc_jena(Creature* pCreature) +{ + return new npc_jenaAI(pCreature); +} + +CreatureAI* GetAI_npc_malcolm(Creature* pCreature) +{ + return new npc_malcolmAI(pCreature); +} + +CreatureAI* GetAI_npc_bartleby_cs(Creature* pCreature) +{ + return new npc_bartleby_csAI(pCreature); +} + +CreatureAI* GetAI_npc_stratholme_crates(Creature* pCreature) +{ + return new npc_stratholme_cratesAI(pCreature); +} + +void AddSC_culling_of_stratholmeAI() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_chromi_start"; + newscript->pGossipHello = &GossipHello_npc_chromi_start; + newscript->pGossipSelect = &GossipSelect_npc_chromi_start; + newscript->GetAI = &GetAI_npc_chromi_start; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_mike"; + newscript->GetAI = &GetAI_npc_mike; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_roger"; + newscript->GetAI = &GetAI_npc_roger; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_morigan"; + newscript->GetAI = &GetAI_npc_morigan; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_jena"; + newscript->GetAI = &GetAI_npc_jena; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_malcolm"; + newscript->GetAI = &GetAI_npc_malcolm; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_bartleby_cs"; + newscript->GetAI = &GetAI_npc_bartleby_cs; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_stratholme_crates"; + newscript->GetAI = &GetAI_npc_stratholme_crates; + newscript->RegisterSelf(); +} diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp index b3bcc11d9..9d7928b23 100644 --- a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -14,560 +14,376 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* ScriptData -SDName: Instance_culling_of_stratholme -SD%Complete: 80% -SDComment: +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 SDCategory: Culling of Stratholme EndScriptData */ #include "precompiled.h" #include "culling_of_stratholme.h" -enum -{ - MAX_ARTHAS_SPAWN_POS = 5, - SAY_CHROMIE_HURRY = -1000000 // TODO -}; - -struct sSpawnLocation -{ - float m_fX, m_fY, m_fZ, m_fO; -}; - -static sSpawnLocation m_aArthasSpawnLocs[] = // need tuning -{ - {1969.73f, 1287.12f, 145.48f, 3.14f}, - {2049.43f, 1287.43f, 142.75f, 0.06f}, - {2365.54f, 1194.85f, 131.98f, 0.47f}, - {2534.46f, 1125.99f, 130.75f, 0.27f}, - {2363.77f, 1406.31f, 128.64f, 3.23f} -}; - -static sSpawnLocation m_aChromieSpawnLocs[] = // need tuning, escpecially EndPositions! +struct MANGOS_DLL_DECL instance_culling_of_stratholme : public ScriptedInstance { - {1814.46f, 1283.97f, 142.30f, 4.32f}, // near bridge - {2311.0f, 1502.4f, 127.9f, 0.0f}, // End - {1811.52f, 1285.92f, 142.37f, 4.47f}, // Hourglass, near bridge - {2186.42f, 1323.77f, 129.91f, 0.0f}, // Hourglass, End -}; - -instance_culling_of_stratholme::instance_culling_of_stratholme(Map* pMap) : ScriptedInstance(pMap), - m_uiGrainCrateCount(0), - m_uiRemoveCrateStateTimer(0), - m_uiArthasRespawnTimer(0), - - m_uiChromieInnGUID(0), - m_uiChromieEntranceGUID(0), - m_uiChromieEndGUID(0), - m_uiHourglassGUID(0), - m_uiArthasGUID(0), - m_uiMeathookGUID(0), - m_uiSalrammGUID(0), - m_uiEpochGUID(0), - m_uiCorrupterGUID(0), - m_uiLordaeronCrierGUID(0), - - m_uiBelfastGUID(0), - m_uiForrestenGUID(0), - m_uiSiabiGUID(0), - m_uiJamesGUID(0), - m_uiCorricksGUID(0), - m_uiStoutmantleGUID(0), - - m_uiOwensGUID(0), - m_uiMoriganGUID(0), - m_uiAndersonGUID(0), - m_uiMooreGUID(0), - m_uiBattsonGUID(0), - - m_uiOReillyGUID(0), - - m_uiDoorBookcaseGUID(0), - m_uiDarkRunedChestGUID(0) -{ - Initialize(); -} - -void instance_culling_of_stratholme::Initialize() -{ - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); -} - -void instance_culling_of_stratholme::OnCreatureCreate(Creature* pCreature) -{ - switch(pCreature->GetEntry()) - { - case NPC_CHROMIE_INN: m_uiChromieInnGUID = pCreature->GetGUID(); break; - case NPC_CHROMIE_ENTRANCE: m_uiChromieEntranceGUID = pCreature->GetGUID(); break; - case NPC_CHROMIE_END: m_uiChromieEndGUID = pCreature->GetGUID(); break; - case NPC_HOURGLASS: m_uiHourglassGUID = pCreature->GetGUID(); break; - case NPC_ARTHAS: m_uiArthasGUID = pCreature->GetGUID(); break; - case NPC_MEATHOOK: m_uiMeathookGUID = pCreature->GetGUID(); break; - case NPC_SALRAMM_THE_FLESHCRAFTER: m_uiSalrammGUID = pCreature->GetGUID(); break; - case NPC_CHRONO_LORD_EPOCH: m_uiEpochGUID = pCreature->GetGUID(); break; - case NPC_MALGANIS: m_uiMalganisGUID = pCreature->GetGUID(); break; - case NPC_MICHAEL_BELFAST: m_uiBelfastGUID = pCreature->GetGUID(); break; - case NPC_HEARTHSINGER_FORRESTEN: m_uiForrestenGUID = pCreature->GetGUID(); break; - case NPC_FRAS_SIABI: m_uiSiabiGUID = pCreature->GetGUID(); break; - case NPC_FOOTMAN_JAMES: m_uiJamesGUID = pCreature->GetGUID(); break; - case NPC_MAL_CORRICKS: m_uiCorricksGUID = pCreature->GetGUID(); break; - case NPC_GRYAN_STOUTMANTLE: m_uiStoutmantleGUID = pCreature->GetGUID(); break; - case NPC_ROGER_OWENS: m_uiOwensGUID = pCreature->GetGUID(); break; - case NPC_SERGEANT_MORIGAN: m_uiMoriganGUID = pCreature->GetGUID(); break; - case NPC_JENA_ANDERSON: m_uiAndersonGUID = pCreature->GetGUID(); break; - case NPC_MALCOM_MOORE: m_uiMooreGUID = pCreature->GetGUID(); break; - case NPC_BARTLEBY_BATTSON: m_uiBattsonGUID = pCreature->GetGUID(); break; - case NPC_PATRICIA_O_REILLY: m_uiOReillyGUID = pCreature->GetGUID(); break; - case NPC_LORDAERON_CRIER: m_uiLordaeronCrierGUID = pCreature->GetGUID(); break; - case NPC_INFINITE_CORRUPTER: m_uiCorrupterGUID = pCreature->GetGUID(); break; - - case NPC_CRATES_BUNNY: m_luiCratesBunnyGUIDs.push_back(pCreature->GetGUID()); break; - case NPC_LORDAERON_FOOTMAN: m_luiFootmanGUIDs.push_back(pCreature->GetGUID()); break; - - case NPC_STRATHOLME_CITIZEN: - case NPC_STRATHOLME_RESIDENT: - if (m_auiEncounter[TYPE_ARTHAS_INTRO_EVENT] == DONE) - pCreature->UpdateEntry(NPC_ZOMBIE); - else - m_luiResidentGUIDs.push_back(pCreature->GetGUID()); - break; - case NPC_AGIATED_STRATHOLME_CITIZEN: m_lAgiatedCitizenGUIDList.push_back(pCreature->GetGUID()); break; - case NPC_AGIATED_STRATHOLME_RESIDENT: m_lAgiatedResidentGUIDList.push_back(pCreature->GetGUID()); break; - } -} - -void instance_culling_of_stratholme::OnObjectCreate(GameObject* pGo) -{ - switch(pGo->GetEntry()) + instance_culling_of_stratholme(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint8 m_uiCratesCount; + uint32 m_auiEncounter[7]; + uint32 m_uiHeroicTimer; + uint32 m_uiLastTimer; + + uint64 m_uiChromi01GUID; + uint64 m_uiChromi02GUID; + uint64 m_uiMikeGUID; + uint64 m_uiMalCoricsGUID; + uint64 m_uiGrianStoneGUID; + uint64 m_uiJamesGUID; + uint64 m_uiFrasCiabiGUID; + uint64 m_uiForrestenGUID; + uint64 m_uiRogerGUID; + uint64 m_uiMoriganGUID; + uint64 m_uiPerelliGUID; + uint64 m_uiJenaGUID; + uint64 m_uiMarthaGUID; + uint64 m_uiMalcolmGUID; + uint64 m_uiDogGUID; + uint64 m_uiBartlebyGUID; + uint64 m_uiArthasGUID; + uint64 m_uiUtherGUID; + uint64 m_uiJainaGUID; + uint64 m_uiSalrammGUID; + uint64 m_uiMalganisGUID; + uint64 m_uiCorruptorGUID; + + uint64 m_uiShkafGateGUID; + uint64 m_uiMalGate1GUID; + uint64 m_uiMalGate2GUID; + uint64 m_uiMalChestGUID; + uint64 m_uiExitGUID; + + void Initialize() { - case GO_DOOR_BOOKCASE: - m_uiDoorBookcaseGUID = pGo->GetGUID(); - if (m_auiEncounter[TYPE_EPOCH_EVENT] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_DARK_RUNED_CHEST: - case GO_DARK_RUNED_CHEST_H: - m_uiDarkRunedChestGUID = pGo->GetGUID(); - break; + m_uiHeroicTimer = 1500000; + m_uiLastTimer = 1500000; + m_auiEncounter[0] = NOT_STARTED; + m_auiEncounter[1] = NOT_STARTED; + m_auiEncounter[2] = 0; + m_auiEncounter[3] = NOT_STARTED; + m_auiEncounter[4] = 0; + m_auiEncounter[5] = NOT_STARTED; + m_auiEncounter[6] = NOT_STARTED; + + DoUpdateWorldState(WORLD_STATE_COS_CRATE_COUNT, 0); + DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 0); + DoUpdateWorldState(WORLD_STATE_COS_WAVE_COUNT, 0); + DoUpdateWorldState(WORLD_STATE_COS_TIME_COUNT, 0); + DoUpdateWorldState(WORLD_STATE_COS_TIME_ON, 0); + + m_uiCratesCount = 0; + m_uiMikeGUID = 0; + m_uiChromi01GUID = 0; + m_uiChromi02GUID = 0; + m_uiMalCoricsGUID = 0; + m_uiGrianStoneGUID = 0; + m_uiJamesGUID = 0; + m_uiFrasCiabiGUID = 0; + m_uiForrestenGUID = 0; + m_uiRogerGUID = 0; + m_uiMoriganGUID = 0; + m_uiPerelliGUID = 0; + m_uiJenaGUID = 0; + m_uiMarthaGUID = 0; + m_uiMalcolmGUID = 0; + m_uiDogGUID = 0; + m_uiBartlebyGUID = 0; + m_uiArthasGUID = 0; + m_uiUtherGUID = 0; + m_uiJainaGUID = 0; + m_uiShkafGateGUID = 0; + m_uiSalrammGUID = 0; + m_uiCorruptorGUID = 0; + m_uiMalganisGUID = 0; + m_uiMalGate1GUID = 0; + m_uiMalGate2GUID = 0; + m_uiMalChestGUID = 0; + m_uiExitGUID = 0; } -} -Player* instance_culling_of_stratholme::GetPlayerInMap() -{ - Map::PlayerList const& players = instance->GetPlayers(); - - if (!players.isEmpty()) + void OnCreatureCreate(Creature* pCreature) { - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + switch(pCreature->GetEntry()) { - if (Player* plr = itr->getSource()) - return plr; + case NPC_CHROMI01: + pCreature->SetActiveObjectState(true); + m_uiChromi01GUID = pCreature->GetGUID(); + break; + case NPC_CHROMI02: + pCreature->SetActiveObjectState(true); + m_uiChromi02GUID = pCreature->GetGUID(); + if (m_auiEncounter[0] == DONE) + pCreature->SetVisibility(VISIBILITY_ON); + else + pCreature->SetVisibility(VISIBILITY_OFF); + break; + case NPC_MIKE: + m_uiMikeGUID = pCreature->GetGUID(); + break; + case NPC_MAL_CORICS: + pCreature->SetActiveObjectState(true); + m_uiMalCoricsGUID = pCreature->GetGUID(); + break; + case NPC_GRIAN_STONE: + pCreature->SetActiveObjectState(true); + pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR); + m_uiGrianStoneGUID = pCreature->GetGUID(); + break; + case NPC_JAMES: + pCreature->SetActiveObjectState(true); + pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR); + m_uiJamesGUID = pCreature->GetGUID(); + break; + case NPC_FRAS_FRASIABI: + pCreature->SetActiveObjectState(true); + pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR); + m_uiFrasCiabiGUID = pCreature->GetGUID(); + break; + case NPC_FORRESTER: + pCreature->SetActiveObjectState(true); + pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR); + m_uiForrestenGUID = pCreature->GetGUID(); + break; + case NPC_ROGER: + m_uiRogerGUID = pCreature->GetGUID(); + break; + case NPC_MORIGAN: + m_uiMoriganGUID = pCreature->GetGUID(); + break; + case NPC_PERELLI: + pCreature->SetActiveObjectState(true); + m_uiPerelliGUID = pCreature->GetGUID(); + break; + case NPC_JENA: + m_uiJenaGUID = pCreature->GetGUID(); + break; + case NPC_MARTHA: + pCreature->CastSpell(pCreature, 58925, false); + pCreature->SetActiveObjectState(true); + m_uiMarthaGUID = pCreature->GetGUID(); + break; + case NPC_MALCOLM: + m_uiMalcolmGUID = pCreature->GetGUID(); + break; + case NPC_DOG: + pCreature->SetActiveObjectState(true); + m_uiDogGUID = pCreature->GetGUID(); + break; + case NPC_BARTLEBY: + m_uiBartlebyGUID = pCreature->GetGUID(); + break; + case NPC_UTHER: + m_uiUtherGUID = pCreature->GetGUID(); + break; + case NPC_ARTHAS: + m_uiArthasGUID = pCreature->GetGUID(); + break; + case NPC_JAINA: + pCreature->SetActiveObjectState(true); + m_uiJainaGUID = pCreature->GetGUID(); + break; + case NPC_INFINITE_CORRUPTOR: + pCreature->SetPhaseMask(0, true); + m_uiCorruptorGUID = pCreature->GetGUID(); + break; } } - return NULL; -} -void instance_culling_of_stratholme::UpdateQuestCredit() -{ - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.isEmpty()) + void OnObjectCreate(GameObject* pGo) { - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* pPlayer = itr->getSource()) - pPlayer->KilledMonsterCredit(NPC_CRATES_BUNNY); - } - } -} + if (pGo->GetEntry() == GO_SHKAF_GATE) + m_uiShkafGateGUID = pGo->GetGUID(); -void instance_culling_of_stratholme::DoChromieHurrySpeech() -{ - if (Creature* pChromie = instance->GetCreature(m_uiChromieEntranceGUID)) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.isEmpty()) - { - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* pPlayer = itr->getSource()) - DoScriptText(SAY_CHROMIE_HURRY, pChromie, pPlayer); - } - } - } -} + if (pGo->GetEntry() == GO_MALGANIS_GATE1) + m_uiMalGate1GUID = pGo->GetGUID(); -void instance_culling_of_stratholme::SetData(uint32 uiType, uint32 uiData) -{ - switch(uiType) - { - case TYPE_GRAIN_EVENT: - m_auiEncounter[TYPE_GRAIN_EVENT] = uiData; - if (uiData == SPECIAL) - DoUpdateWorldState(WORLD_STATE_CRATES, 1); - else if (uiData == IN_PROGRESS) - { - if (m_uiGrainCrateCount >= 5) - return; + if (pGo->GetEntry() == GO_MALGANIS_GATE2) + m_uiMalGate2GUID = pGo->GetGUID(); - ++m_uiGrainCrateCount; - DoUpdateWorldState(WORLD_STATE_CRATES_COUNT, m_uiGrainCrateCount); + if (pGo->GetEntry() == GO_MALGANIS_CHEST || pGo->GetEntry() == GO_MALGANIS_CHEST_H) + m_uiMalChestGUID = pGo->GetGUID(); - if (m_uiGrainCrateCount == 5) - { - UpdateQuestCredit(); - m_uiRemoveCrateStateTimer = 20000; - SetData(TYPE_GRAIN_EVENT, DONE); - } - } - break; - case TYPE_ARTHAS_INTRO_EVENT: - m_auiEncounter[TYPE_ARTHAS_INTRO_EVENT] = uiData; - break; - case TYPE_ARTHAS_ESCORT_EVENT: - m_auiEncounter[TYPE_ARTHAS_ESCORT_EVENT] = uiData; - break; - case TYPE_MEATHOOK_EVENT: - m_auiEncounter[TYPE_MEATHOOK_EVENT] = uiData; - if (uiData == DONE) - SetData(TYPE_SALRAMM_EVENT, IN_PROGRESS); - break; - case TYPE_SALRAMM_EVENT: - m_auiEncounter[TYPE_SALRAMM_EVENT] = uiData; - if (uiData == DONE) - DoUpdateWorldState(WORLD_STATE_WAVE, 0); // Remove WaveCounter - break; - case TYPE_EPOCH_EVENT: - m_auiEncounter[TYPE_EPOCH_EVENT] = uiData; - break; - case TYPE_MALGANIS_EVENT: - m_auiEncounter[TYPE_MALGANIS_EVENT] = uiData; - if (uiData == DONE) - { - DoRespawnGameObject(m_uiDarkRunedChestGUID, 30*MINUTE); - DoSpawnChromieIfNeeded(); - } - break; - case TYPE_INFINITE_CORRUPTER_TIME: - m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] = uiData; - if (!uiData) - { - DoUpdateWorldState(WORLD_STATE_TIME, 0); // Remove Timer - DoUpdateWorldState(WORLD_STATE_TIME_COUNTER, 0); - } - else - DoUpdateWorldState(WORLD_STATE_TIME_COUNTER, uiData/(MINUTE*IN_MILLISECONDS)); - break; - case TYPE_INFINITE_CORRUPTER: - m_auiEncounter[TYPE_INFINITE_CORRUPTER] = uiData; - switch(uiData) - { - case IN_PROGRESS: - if (!m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]) - SetData(TYPE_INFINITE_CORRUPTER_TIME, MINUTE*25*IN_MILLISECONDS); - DoUpdateWorldState(WORLD_STATE_TIME, 1);// Show Timer - break; - case DONE: - SetData(TYPE_INFINITE_CORRUPTER_TIME, 0); - break; - case SPECIAL: - DoChromieHurrySpeech(); - break; - case FAIL: - SetData(TYPE_INFINITE_CORRUPTER_TIME, 0); - if (Creature* pCorrupter = instance->GetCreature(m_uiCorrupterGUID)) - if (pCorrupter->isAlive()) - pCorrupter->ForcedDespawn(); - break; - } - break; + if (pGo->GetEntry() == GO_EXIT) + m_uiExitGUID = pGo->GetGUID(); } - if (uiData == DONE || (uiType == TYPE_INFINITE_CORRUPTER && uiData == FAIL)) + void ChromiWhispers() { - 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]; + Map::PlayerList const &PlayerList = instance->GetPlayers(); - strInstData = saveStream.str(); + if (PlayerList.isEmpty()) + return; - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } -} - -void instance_culling_of_stratholme::Load(const char* chrIn) -{ - if (!chrIn) - { - OUT_LOAD_INST_DATA_FAIL; - return; + if (Creature* pChromi = instance->GetCreature(m_uiChromi01GUID)) + { + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + pChromi->MonsterWhisper("Good work with crates! Come to me in front of Stratholme for your next assignment!", i->getSource(), false); + i->getSource()->KilledMonsterCredit(30996, pChromi->GetGUID()); + i->getSource()->DestroyItemCount(ITEM_ARCANE_DISRUPTOR, 1, true); + } + pChromi->SetVisibility(VISIBILITY_OFF); + } + if (Creature* pChromi2 = instance->GetCreature(m_uiChromi02GUID)) + pChromi2->SetVisibility(VISIBILITY_ON); } - 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]; - - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + void SetData(uint32 uiType, uint32 uiData) { - if (i != TYPE_INFINITE_CORRUPTER_TIME) + switch(uiType) { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; + case TYPE_QUEST: + m_auiEncounter[0] = uiData; + break; + case TYPE_CRATES_COUNT: + m_uiCratesCount = m_uiCratesCount + uiData; + if(m_uiCratesCount == 5) + { + m_auiEncounter[0] = DONE; + ChromiWhispers(); + } + DoUpdateWorldState(WORLD_STATE_COS_CRATE_COUNT, m_uiCratesCount); + break; + case TYPE_INTRO: + m_auiEncounter[1] = uiData; + break; + case TYPE_PHASE: + m_auiEncounter[2] = uiData; + break; + case TYPE_ENCOUNTER: + m_auiEncounter[3] = uiData; + break; + case TYPE_WING: + m_auiEncounter[4] = uiData; + break; + case TYPE_BONUS: + m_auiEncounter[5] = uiData; + if(uiData == IN_PROGRESS) + { + if(Creature* Corruptor = instance->GetCreature(m_uiCorruptorGUID)) + Corruptor->SetPhaseMask(1, true); + DoUpdateWorldState(WORLD_STATE_COS_TIME_ON, 1); + DoUpdateWorldState(WORLD_STATE_COS_TIME_COUNT, 25); + } + break; + case TYPE_MALGANIS: + m_auiEncounter[6] = uiData; + if (uiData == DONE) + { + DoRespawnGameObject(m_uiMalChestGUID, 30*MINUTE); + if (GameObject* pGo = instance->GetGameObject(m_uiMalChestGUID)) + pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + if (Creature* pChromi2 = instance->GetCreature(m_uiChromi02GUID)) + pChromi2->SetVisibility(VISIBILITY_OFF); + if (GameObject* pGo = instance->GetGameObject(m_uiExitGUID)) + pGo->SetGoState(GO_STATE_ACTIVE); + } + break; } } - // If already started counting down time, the event is "in progress" - if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]) - m_auiEncounter[TYPE_INFINITE_CORRUPTER] = IN_PROGRESS; - - OUT_LOAD_INST_DATA_COMPLETE; -} - -void instance_culling_of_stratholme::OnPlayerEnter(Player* pPlayer) -{ - if (instance->GetPlayersCountExceptGMs() == 0) - { - DoSpawnArthasIfNeeded(); - DoSpawnChromieIfNeeded(); - - // Show World States if needed, TODO verify if needed and if this is the right way - if (m_auiEncounter[TYPE_GRAIN_EVENT] == IN_PROGRESS || m_auiEncounter[TYPE_GRAIN_EVENT] == SPECIAL) - DoUpdateWorldState(WORLD_STATE_CRATES, 1); // Show Crates Counter - else - DoUpdateWorldState(WORLD_STATE_CRATES, 0); // Remove Crates Counter - - if (m_auiEncounter[TYPE_MEATHOOK_EVENT] == IN_PROGRESS) - DoUpdateWorldState(WORLD_STATE_WAVE, 1); // Add WaveCounter - else if (m_auiEncounter[TYPE_SALRAMM_EVENT] == IN_PROGRESS) - DoUpdateWorldState(WORLD_STATE_WAVE, 6); // Add WaveCounter - else - DoUpdateWorldState(WORLD_STATE_WAVE, 0); // Remove WaveCounter - - if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]) - DoUpdateWorldState(WORLD_STATE_TIME, 1); // Show Timer - else - DoUpdateWorldState(WORLD_STATE_TIME, 0); // Remove Timer - } -} - -uint32 instance_culling_of_stratholme::GetData(uint32 uiType) -{ - switch(uiType) - { - case TYPE_GRAIN_EVENT: return m_auiEncounter[0]; - case TYPE_ARTHAS_INTRO_EVENT: return m_auiEncounter[1]; - case TYPE_MEATHOOK_EVENT: return m_auiEncounter[2]; - case TYPE_SALRAMM_EVENT: return m_auiEncounter[3]; - case TYPE_EPOCH_EVENT: return m_auiEncounter[4]; - case TYPE_ARTHAS_ESCORT_EVENT: return m_auiEncounter[5]; - case TYPE_MALGANIS_EVENT: return m_auiEncounter[6]; - case TYPE_INFINITE_CORRUPTER_TIME: return m_auiEncounter[7]; - case TYPE_INFINITE_CORRUPTER: return m_auiEncounter[8]; - default: return 0; - } -} - -uint64 instance_culling_of_stratholme::GetData64(uint32 uiData) -{ - switch(uiData) - { - case NPC_CHROMIE_INN: return m_uiChromieInnGUID; - case NPC_CHROMIE_ENTRANCE: return m_uiChromieEntranceGUID; - case NPC_CHROMIE_END: return m_uiChromieEndGUID; - case NPC_HOURGLASS: return m_uiHourglassGUID; - case NPC_ARTHAS: return m_uiArthasGUID; - case NPC_MEATHOOK: return m_uiMeathookGUID; - case NPC_SALRAMM_THE_FLESHCRAFTER: return m_uiSalrammGUID; - case NPC_CHRONO_LORD_EPOCH: return m_uiEpochGUID; - case NPC_MALGANIS: return m_uiMalganisGUID; - case NPC_INFINITE_CORRUPTER: return m_uiCorrupterGUID; - case NPC_MICHAEL_BELFAST: return m_uiBelfastGUID; - case NPC_HEARTHSINGER_FORRESTEN: return m_uiForrestenGUID; - case NPC_FRAS_SIABI: return m_uiSiabiGUID; - case NPC_FOOTMAN_JAMES: return m_uiJamesGUID; - case NPC_MAL_CORRICKS: return m_uiCorricksGUID; - case NPC_GRYAN_STOUTMANTLE: return m_uiStoutmantleGUID; - case NPC_ROGER_OWENS: return m_uiOwensGUID; - case NPC_SERGEANT_MORIGAN: return m_uiMoriganGUID; - case NPC_JENA_ANDERSON: return m_uiAndersonGUID; - case NPC_MALCOM_MOORE: return m_uiMooreGUID; - case NPC_BARTLEBY_BATTSON: return m_uiBattsonGUID; - case NPC_PATRICIA_O_REILLY: return m_uiOReillyGUID; - case GO_DOOR_BOOKCASE: return m_uiDoorBookcaseGUID; - default: return 0; - } -} - -uint8 instance_culling_of_stratholme::GetInstancePosition() -{ - if (m_auiEncounter[TYPE_MALGANIS_EVENT] == DONE) - return POS_INSTANCE_FINISHED; - else if (m_auiEncounter[TYPE_ARTHAS_ESCORT_EVENT] == DONE) - return POS_ARTHAS_MALGANIS; - else if (m_auiEncounter[TYPE_EPOCH_EVENT] == DONE) - return POS_ARTHAS_ESCORTING; - else if (m_auiEncounter[TYPE_SALRAMM_EVENT] == DONE) - return POS_ARTHAS_TOWNHALL; - else if (m_auiEncounter[TYPE_MEATHOOK_EVENT] == DONE) - return POS_ARTHAS_WAVES; - else if (m_auiEncounter[TYPE_ARTHAS_INTRO_EVENT] == DONE) - return POS_ARTHAS_WAVES; - else if (m_auiEncounter[TYPE_GRAIN_EVENT] == DONE) - return POS_ARTHAS_INTRO; - else - return 0; -} - -static bool sortFromEastToWest(Creature* pFirst, Creature* pSecond) -{ - return pFirst && pSecond && pFirst->GetPositionY() < pSecond->GetPositionY(); -} - -static bool sortFromSouthToNorth(Creature* pFirst, Creature* pSecond) -{ - return pFirst && pSecond && pFirst->GetPositionX() < pSecond->GetPositionX(); -} - -void instance_culling_of_stratholme::GetCratesBunnyOrderedList(std::list &lList) -{ - std::list lCratesBunnyList; - for (std::list::const_iterator itr = m_luiCratesBunnyGUIDs.begin(); itr != m_luiCratesBunnyGUIDs.end(); itr++) - { - if (Creature* pBunny = instance->GetCreature(*itr)) - lCratesBunnyList.push_back(pBunny); - } - if (lCratesBunnyList.empty()) - return; - - lCratesBunnyList.sort(sortFromEastToWest); - lList = lCratesBunnyList; -} - -Creature* instance_culling_of_stratholme::GetStratIntroFootman() -{ - std::list lFootmanList; - for (std::list::const_iterator itr = m_luiFootmanGUIDs.begin(); itr != m_luiFootmanGUIDs.end(); itr++) - { - if (Creature* pFootman = instance->GetCreature(*itr)) - lFootmanList.push_back(pFootman); - } - - if (lFootmanList.empty()) - return NULL; - else + void SetData64(uint32 uiData, uint64 uiGuid) { - lFootmanList.sort(sortFromSouthToNorth); - return *lFootmanList.begin(); - } -} - -void instance_culling_of_stratholme::GetResidentOrderedList(std::list &lList) -{ - std::list lResidentList; - for (std::list::const_iterator itr = m_luiResidentGUIDs.begin(); itr != m_luiResidentGUIDs.end(); itr++) - { - if (Creature* pResident = instance->GetCreature(*itr)) - lResidentList.push_back(pResident); - } - if (lResidentList.empty()) - return; - - lResidentList.sort(sortFromSouthToNorth); - lList = lResidentList; -} - -void instance_culling_of_stratholme::ArthasJustDied() -{ - m_uiArthasRespawnTimer = 10000; // TODO, could be instant -} - -void instance_culling_of_stratholme::DoSpawnArthasIfNeeded() -{ - Creature* pArthas = instance->GetCreature(m_uiArthasGUID); - if (pArthas && pArthas->isAlive()) - return; - - uint8 uiPosition = GetInstancePosition(); - if (uiPosition && uiPosition <= MAX_ARTHAS_SPAWN_POS) - { - if (Player* pPlayer = GetPlayerInMap()) - pPlayer->SummonCreature(NPC_ARTHAS, m_aArthasSpawnLocs[uiPosition-1].m_fX, m_aArthasSpawnLocs[uiPosition-1].m_fY, m_aArthasSpawnLocs[uiPosition-1].m_fZ, m_aArthasSpawnLocs[uiPosition-1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - } -} - -// Atm here only new Chromies are spawned - despawning depends on Mangos featuring such a thing -// The hourglass also is not yet spawned/ relocated. -void instance_culling_of_stratholme::DoSpawnChromieIfNeeded() -{ - Player* pPlayer = GetPlayerInMap(); - if (!pPlayer) - return; - - if (GetInstancePosition() == POS_INSTANCE_FINISHED) - { - Creature* pChromie = instance->GetCreature(m_uiChromieEndGUID); - if (!pChromie) - pPlayer->SummonCreature(NPC_CHROMIE_END, m_aChromieSpawnLocs[1].m_fX, m_aChromieSpawnLocs[1].m_fY, m_aChromieSpawnLocs[1].m_fZ, m_aChromieSpawnLocs[1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - } - else if (GetInstancePosition() >= POS_ARTHAS_INTRO) - { - Creature* pChromie = instance->GetCreature(m_uiChromieEntranceGUID); - if (!pChromie) - pPlayer->SummonCreature(NPC_CHROMIE_ENTRANCE, m_aChromieSpawnLocs[0].m_fX, m_aChromieSpawnLocs[0].m_fY, m_aChromieSpawnLocs[0].m_fZ, m_aChromieSpawnLocs[0].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + switch(uiData) + { + case NPC_SALRAMM: + m_uiSalrammGUID = uiGuid; + break; + case NPC_MALGANIS: + m_uiMalganisGUID = uiGuid; + break; + } } -} -void instance_culling_of_stratholme::Update(uint32 uiDiff) -{ - // 25min Run - decrease time, update worldstate every ~20s - // as the time is always saved by m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME], there is no need for an extra timer - if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]) + uint32 GetData(uint32 uiType) { - if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] <= uiDiff) - SetData(TYPE_INFINITE_CORRUPTER, FAIL); - else + switch(uiType) { - m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] -= uiDiff; - if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]/IN_MILLISECONDS % 20 == 0) - SetData(TYPE_INFINITE_CORRUPTER_TIME, m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]); + case TYPE_QUEST: + return m_auiEncounter[0]; + case TYPE_INTRO: + return m_auiEncounter[1]; + case TYPE_PHASE: + return m_auiEncounter[2]; + case TYPE_ENCOUNTER: + return m_auiEncounter[3]; + case TYPE_WING: + return m_auiEncounter[4]; + case TYPE_BONUS: + return m_auiEncounter[5]; + case TYPE_MALGANIS: + return m_auiEncounter[6]; } - - // This part is needed for a small "hurry up guys" note, TODO, verify 20min - if (m_auiEncounter[TYPE_INFINITE_CORRUPTER] == IN_PROGRESS && m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] <= 24*MINUTE*IN_MILLISECONDS) - SetData(TYPE_INFINITE_CORRUPTER, SPECIAL); + return 0; } - // Small Timer, to remove Grain-Crate WorldState and Spawn Second Chromie - if (m_uiRemoveCrateStateTimer) + uint64 GetData64(uint32 uiData) { - if (m_uiRemoveCrateStateTimer <= uiDiff) + switch(uiData) { - DoUpdateWorldState(WORLD_STATE_CRATES, 0); - DoSpawnChromieIfNeeded(); - m_uiRemoveCrateStateTimer = 0; + case NPC_FORRESTER: return m_uiForrestenGUID; + case NPC_JAMES: return m_uiJamesGUID; + case NPC_FRAS_FRASIABI: return m_uiFrasCiabiGUID; + case NPC_MAL_CORICS: return m_uiMalCoricsGUID; + case NPC_GRIAN_STONE: return m_uiGrianStoneGUID; + case NPC_ROGER: return m_uiRogerGUID; + case NPC_MORIGAN: return m_uiMoriganGUID; + case NPC_PERELLI: return m_uiPerelliGUID; + case NPC_JENA: return m_uiJenaGUID; + case NPC_MARTHA: return m_uiMarthaGUID; + case NPC_MALCOLM: return m_uiMalcolmGUID; + case NPC_DOG: return m_uiDogGUID; + case NPC_BARTLEBY: return m_uiBartlebyGUID; + case NPC_UTHER: return m_uiUtherGUID; + case NPC_ARTHAS: return m_uiArthasGUID; + case NPC_JAINA: return m_uiJainaGUID; + case NPC_SALRAMM: return m_uiSalrammGUID; + case NPC_MALGANIS: return m_uiMalganisGUID; + case GO_SHKAF_GATE: return m_uiShkafGateGUID; + case GO_MALGANIS_GATE1: return m_uiMalGate1GUID; + case GO_MALGANIS_GATE2: return m_uiMalGate2GUID; + case GO_MALGANIS_CHEST: return m_uiMalChestGUID; + case GO_EXIT: return m_uiExitGUID; } - else - m_uiRemoveCrateStateTimer -= uiDiff; + + return 0; } - // Respawn Arthas after some time - if (m_uiArthasRespawnTimer) + void Update(uint32 uiDiff) { - if (m_uiArthasRespawnTimer <= uiDiff) - { - DoSpawnArthasIfNeeded(); - m_uiArthasRespawnTimer = 0; - } - else - m_uiArthasRespawnTimer -= uiDiff; + if(m_auiEncounter[5] == IN_PROGRESS) + { + if(m_uiHeroicTimer < uiDiff) + { + m_auiEncounter[5] = FAIL; + DoUpdateWorldState(WORLD_STATE_COS_TIME_ON, 0); + if(Creature* Corruptor = instance->GetCreature(m_uiCorruptorGUID)) + Corruptor->SetPhaseMask(0, true); + + }else m_uiHeroicTimer -= uiDiff; + + if(m_uiHeroicTimer < m_uiLastTimer - 60000) + { + m_uiLastTimer = m_uiHeroicTimer; + uint32 tMinutes = m_uiHeroicTimer / 60000; + DoUpdateWorldState(WORLD_STATE_COS_TIME_COUNT, tMinutes); + } + } + + return; } -} +}; InstanceData* GetInstanceData_instance_culling_of_stratholme(Map* pMap) { @@ -576,10 +392,9 @@ InstanceData* GetInstanceData_instance_culling_of_stratholme(Map* pMap) void AddSC_instance_culling_of_stratholme() { - Script* pNewScript; - - pNewScript = new Script; - pNewScript->Name = "instance_culling_of_stratholme"; - pNewScript->GetInstanceData = &GetInstanceData_instance_culling_of_stratholme; - pNewScript->RegisterSelf(); + Script *newscript; + newscript = new Script; + newscript->Name = "instance_culling_of_stratholme"; + newscript->GetInstanceData = &GetInstanceData_instance_culling_of_stratholme; + newscript->RegisterSelf(); } diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/trash_culling_of_stratholme.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/trash_culling_of_stratholme.cpp new file mode 100644 index 000000000..f10422799 --- /dev/null +++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/trash_culling_of_stratholme.cpp @@ -0,0 +1,1094 @@ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: instance_culling_of_stratholme +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Culling of Stratholme +EndScriptData */ + +#include "precompiled.h" +#include "culling_of_stratholme.h" + +/*### +## npc_cs_gnoul +###*/ + +enum +{ + SPELL_FLESH = 52352 +}; + +struct MANGOS_DLL_DECL npc_cs_gnoulAI : public ScriptedAI +{ + npc_cs_gnoulAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 m_uiFleshTimer; + + uint32 WaypointId; + uint32 MoveTimer; + + void Reset() + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + MoveTimer = (urand(100, 5000)); + m_uiFleshTimer = (urand(3000, 10000)); + WaypointId = 1; + } + + void MoveToPoint(float X, float Y, float Z) + { + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z); + } + + void 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); + } + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + m_uiFleshTimer = (urand(3000, 10000)); + + m_creature->SetLootRecipient(NULL); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) + { + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } + } + } + } + + void JumpNextStep(uint32 Time) + { + MoveTimer = Time; + WaypointId++; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon()) + { + if(MoveTimer < uiDiff) + { + if(m_pInstance->GetData(TYPE_WING) == RIGHT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2356.659f, 1185.501f, 130.636f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2301.735f, 1179.265f, 136.944f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2234.787f, 1180.638f, 136.344f); + JumpNextStep(9000); + break; + case 4: + MoveToPoint(2178.313f, 1244.350f, 136.107f); + JumpNextStep(12000); + break; + case 5: + MoveToPoint(2163.553f, 1277.814f, 133.444f); + JumpNextStep(5000); + break; + case 6: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(5000); + break; + } + } + + if(m_pInstance->GetData(TYPE_WING) == LEFT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2188.318f, 1331.410f, 130.003f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2165.351f, 1279.156f, 133.388f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(9000); + break; + } + } + + } else MoveTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiFleshTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_FLESH); + m_uiFleshTimer = (urand(3000, 10000)); + } + else m_uiFleshTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + return; + } +}; + +/*### +## npc_cs_necromancer +###*/ + +enum +{ + SPELL_SHADOW_BOLT = 15472, + SPELL_COURSE = 20812, + SPELL_DRAIN_MANA = 58770 +}; + +struct MANGOS_DLL_DECL npc_cs_necromancerAI : public ScriptedAI +{ + npc_cs_necromancerAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 m_uiShadowBoltTimer; + uint32 m_uiCourseTimer; + + uint32 WaypointId; + uint32 MoveTimer; + + void Reset() + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + MoveTimer = (urand(100, 5000)); + m_uiCourseTimer = (urand(7000, 17000)); + m_uiShadowBoltTimer = (urand(3000, 10000)); + WaypointId = 1; + } + + void Aggro(Unit* pWho) + { + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->StopMoving(); + } + + void MoveToPoint(float X, float Y, float Z) + { + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + } + m_creature->GetMotionMaster()->MovementExpired(false); + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + m_uiShadowBoltTimer = (urand(3000, 10000)); + m_uiCourseTimer = (urand(7000, 17000)); + + m_creature->SetLootRecipient(NULL); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) + { + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } + } + } + } + + void JumpNextStep(uint32 Time) + { + MoveTimer = Time; + WaypointId++; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon()) + { + if(MoveTimer < uiDiff) + { + if(m_pInstance->GetData(TYPE_WING) == RIGHT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2356.659f, 1185.501f, 130.636f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2301.735f, 1179.265f, 136.944f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2234.787f, 1180.638f, 136.344f); + JumpNextStep(9000); + break; + case 4: + MoveToPoint(2178.313f, 1244.350f, 136.107f); + JumpNextStep(12000); + break; + case 5: + MoveToPoint(2163.553f, 1277.814f, 133.444f); + JumpNextStep(5000); + break; + case 6: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(5000); + break; + } + } + + if(m_pInstance->GetData(TYPE_WING) == LEFT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2188.318f, 1331.410f, 130.003f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2165.351f, 1279.156f, 133.388f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(9000); + break; + } + } + + } else MoveTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiShadowBoltTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT); + m_uiShadowBoltTimer = (urand(3000, 5000)); + } + else m_uiShadowBoltTimer -= uiDiff; + + if(m_uiCourseTimer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(false); + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_COURSE); + m_uiCourseTimer = (urand(7000, 17000)); + } + else m_uiCourseTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + return; + } +}; + +/*### +## npc_cs_field +###*/ + +enum +{ + SPELL_BLOW = 52491, + SPELL_SCARAB = 52496 +}; + +struct MANGOS_DLL_DECL npc_cs_fieldAI : public ScriptedAI +{ + npc_cs_fieldAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 m_uiScarabTimer; + uint32 m_uiBlowTimer; + + uint32 WaypointId; + uint32 MoveTimer; + + void Reset() + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + MoveTimer = (urand(100, 5000)); + m_uiBlowTimer = (urand(7000, 17000)); + m_uiScarabTimer = (urand(3000, 10000)); + WaypointId = 1; + } + + void MoveToPoint(float X, float Y, float Z) + { + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z); + } + + void 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); + } + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + m_uiScarabTimer = (urand(3000, 10000)); + m_uiBlowTimer = (urand(7000, 17000)); + + m_creature->SetLootRecipient(NULL); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) + { + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } + } + } + } + + void JumpNextStep(uint32 Time) + { + MoveTimer = Time; + WaypointId++; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon()) + { + if(MoveTimer < uiDiff) + { + if(m_pInstance->GetData(TYPE_WING) == RIGHT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2356.659f, 1185.501f, 130.636f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2301.735f, 1179.265f, 136.944f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2234.787f, 1180.638f, 136.344f); + JumpNextStep(9000); + break; + case 4: + MoveToPoint(2178.313f, 1244.350f, 136.107f); + JumpNextStep(12000); + break; + case 5: + MoveToPoint(2163.553f, 1277.814f, 133.444f); + JumpNextStep(5000); + break; + case 6: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(5000); + break; + } + } + + if(m_pInstance->GetData(TYPE_WING) == LEFT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2188.318f, 1331.410f, 130.003f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2165.351f, 1279.156f, 133.388f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(9000); + break; + } + } + + } else MoveTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiScarabTimer < uiDiff) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_SCARAB); + m_uiScarabTimer = (urand(3000, 5000)); + } + else m_uiScarabTimer -= uiDiff; + + if(m_uiBlowTimer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(false); + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_BLOW); + m_uiBlowTimer = (urand(7000, 17000)); + } + else m_uiBlowTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + return; + } +}; + +/*### +## npc_cs_alocyte +###*/ + +enum +{ + SPELL_SHADOW = 17234, + SPELL_COLD = 15244, + SPELL_FIRE = 14145, + SPELL_COURSEA = 39621 +}; + +struct MANGOS_DLL_DECL npc_cs_acolyteAI : public ScriptedAI +{ + npc_cs_acolyteAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 m_uiColdTimer; + uint32 m_uiFireTimer; + uint32 m_uiCourseTimer; + uint32 m_uiShadowTimer; + + uint32 WaypointId; + uint32 MoveTimer; + + void Reset() + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + MoveTimer = (urand(100, 5000)); + m_uiColdTimer = (urand(7000, 17000)); + m_uiFireTimer = (urand(3000, 10000)); + m_uiCourseTimer = (urand(5000, 12000)); + m_uiShadowTimer = (urand(1000, 3000)); + WaypointId = 1; + } + + void MoveToPoint(float X, float Y, float Z) + { + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z); + } + + void Aggro(Unit* pWho) + { + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->StopMoving(); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + } + m_creature->GetMotionMaster()->MovementExpired(false); + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + m_uiColdTimer = (urand(7000, 17000)); + m_uiFireTimer = (urand(3000, 10000)); + m_uiCourseTimer = (urand(5000, 12000)); + m_uiShadowTimer = (urand(1000, 3000)); + + m_creature->SetLootRecipient(NULL); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) + { + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } + } + } + } + + void JumpNextStep(uint32 Time) + { + MoveTimer = Time; + WaypointId++; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon()) + { + if(MoveTimer < uiDiff) + { + if(m_pInstance->GetData(TYPE_WING) == RIGHT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2356.659f, 1185.501f, 130.636f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2301.735f, 1179.265f, 136.944f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2234.787f, 1180.638f, 136.344f); + JumpNextStep(9000); + break; + case 4: + MoveToPoint(2178.313f, 1244.350f, 136.107f); + JumpNextStep(12000); + break; + case 5: + MoveToPoint(2163.553f, 1277.814f, 133.444f); + JumpNextStep(5000); + break; + case 6: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(5000); + break; + } + } + + if(m_pInstance->GetData(TYPE_WING) == LEFT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2188.318f, 1331.410f, 130.003f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2165.351f, 1279.156f, 133.388f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(9000); + break; + } + } + + } else MoveTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiShadowTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_SHADOW); + m_uiShadowTimer = (urand(3000, 8000)); + } + else m_uiShadowTimer -= uiDiff; + + if(m_uiCourseTimer < uiDiff) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_COURSEA); + m_uiCourseTimer = (urand(7000, 13000)); + } + else m_uiCourseTimer -= uiDiff; + + if(m_uiColdTimer < uiDiff) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_COLD); + m_uiColdTimer = (urand(13000, 17000)); + } + else m_uiColdTimer -= uiDiff; + + if(m_uiFireTimer < uiDiff) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, SPELL_FIRE); + m_uiFireTimer = (urand(6000, 11000)); + } + else m_uiFireTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + return; + } +}; + +/*### +## npc_cs_butcher +###*/ + +enum +{ + SPELL_CLOUD = 52525 +}; + +struct MANGOS_DLL_DECL npc_cs_butcherAI : public ScriptedAI +{ + npc_cs_butcherAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 WaypointId; + uint32 MoveTimer; + + void Reset() + { + DoCast(m_creature, SPELL_CLOUD); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + MoveTimer = (urand(100, 5000)); + WaypointId = 1; + } + + void MoveToPoint(float X, float Y, float Z) + { + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z); + } + + void 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); + } + } + + void EnterEvadeMode() + { + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + + m_creature->SetLootRecipient(NULL); + DoCast(m_creature, SPELL_CLOUD); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE) + return; + + float attackRadius = m_creature->GetAttackDistance(pWho); + if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho)) + { + if (!m_creature->getVictim()) + { + AttackStart(pWho); + pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + else if (m_creature->GetMap()->IsDungeon()) + { + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 0.0f); + } + } + } + } + + void JumpNextStep(uint32 Time) + { + MoveTimer = Time; + WaypointId++; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon()) + { + if(MoveTimer < uiDiff) + { + if(m_pInstance->GetData(TYPE_WING) == RIGHT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2356.659f, 1185.501f, 130.636f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2301.735f, 1179.265f, 136.944f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2234.787f, 1180.638f, 136.344f); + JumpNextStep(9000); + break; + case 4: + MoveToPoint(2178.313f, 1244.350f, 136.107f); + JumpNextStep(12000); + break; + case 5: + MoveToPoint(2163.553f, 1277.814f, 133.444f); + JumpNextStep(5000); + break; + case 6: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(5000); + break; + } + } + + if(m_pInstance->GetData(TYPE_WING) == LEFT) + { + switch(WaypointId) + { + case 1: + MoveToPoint(2188.318f, 1331.410f, 130.003f); + JumpNextStep(10000); + break; + case 2: + MoveToPoint(2165.351f, 1279.156f, 133.388f); + JumpNextStep(8000); + break; + case 3: + MoveToPoint(2083.952f, 1287.716f, 141.146f); + JumpNextStep(9000); + break; + } + } + + } else MoveTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + + return; + } +}; + +struct MANGOS_DLL_DECL npc_time_riftCSAI : public ScriptedAI +{ + npc_time_riftCSAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsHeroic; + + uint32 Step; + uint32 m_uiStepTimer; + Creature* Drakonian01; + Creature* Drakonian02; + Creature* Drakonian03; + + void Reset() + { + m_uiStepTimer = 1000; + Step = 1; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiStepTimer < uiDiff) + { + switch(Step) + { + case 1: + if (Creature* pArthas = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ARTHAS))) + { + Drakonian01 = m_creature->SummonCreature(NPC_INFINITE_ADVERSARY,(m_creature->GetPositionX()-2)+rand()%4, (m_creature->GetPositionY()-2)+rand()%4, m_creature->GetPositionZ(),3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000); + Drakonian01->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ()); + Drakonian02 = m_creature->SummonCreature(NPC_INFINITE_HUNTER,(m_creature->GetPositionX()-2)+rand()%4, (m_creature->GetPositionY()-2)+rand()%4, m_creature->GetPositionZ(),3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000); + Drakonian02->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ()); + Drakonian03 = m_creature->SummonCreature(NPC_INFINITE_AGENT,(m_creature->GetPositionX()-2)+rand()%4, (m_creature->GetPositionY()-2)+rand()%4, m_creature->GetPositionZ(),3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000); + Drakonian03->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ()); + } + m_uiStepTimer = 3000; + Step++; + break; + case 2: + m_creature->RemoveFromWorld(); + Step++; + break; + } + } else m_uiStepTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_cs_gnoul(Creature* pCreature) +{ + return new npc_cs_gnoulAI(pCreature); +} + +CreatureAI* GetAI_npc_cs_necromancer(Creature* pCreature) +{ + return new npc_cs_necromancerAI(pCreature); +} + +CreatureAI* GetAI_npc_cs_field(Creature* pCreature) +{ + return new npc_cs_fieldAI(pCreature); +} + +CreatureAI* GetAI_npc_cs_acolyte(Creature* pCreature) +{ + return new npc_cs_acolyteAI(pCreature); +} + +CreatureAI* GetAI_npc_cs_butcher(Creature* pCreature) +{ + return new npc_cs_butcherAI(pCreature); +} + +CreatureAI* GetAI_npc_time_riftCS(Creature* pCreature) +{ + return new npc_time_riftCSAI(pCreature); +} + +void AddSC_trash_culling_of_stratholme() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_cs_gnoul"; + newscript->GetAI = &GetAI_npc_cs_gnoul; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_cs_necromancer"; + newscript->GetAI = &GetAI_npc_cs_necromancer; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_cs_field"; + newscript->GetAI = &GetAI_npc_cs_field; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_cs_acolyte"; + newscript->GetAI = &GetAI_npc_cs_acolyte; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_cs_butcher"; + newscript->GetAI = &GetAI_npc_cs_butcher; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_time_riftCS"; + newscript->GetAI = &GetAI_npc_time_riftCS; + newscript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp b/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp index 3a5f3603c..5d52c7d71 100644 --- a/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp +++ b/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp b/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp index 656742a57..c0d8fe65b 100644 --- a/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp +++ b/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp b/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp index d3c40f45f..c7efabad9 100644 --- a/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp +++ b/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp b/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp index c4b16cf4c..06116bf7c 100644 --- a/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp +++ b/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -298,7 +298,7 @@ struct MANGOS_DLL_DECL npc_time_riftAI : public ScriptedAI m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 10.0f, x, y, z); // uncomment the following if something doesn't work correctly, otherwise just delete // m_creature->UpdateAllowedPositionZ(x, y, z); - + if (Unit *Summon = m_creature->SummonCreature(creature_entry, x, y, z, m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) { if (Creature *temp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_MEDIVH))) diff --git a/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h b/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h index 34c9f66dd..c8da2e2ef 100644 --- a/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h +++ b/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp b/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp index 4484784f4..0c56a2a0f 100644 --- a/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp +++ b/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp b/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp index 00667807f..795db533d 100644 --- a/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp +++ b/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -238,8 +238,6 @@ struct MANGOS_DLL_DECL boss_archimondeAI : public ScriptedAI m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL); DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); - if (m_pInstance) m_pInstance->SetData(TYPE_ARCHIMONDE, IN_PROGRESS); } diff --git a/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp b/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp index a7255ad63..b1d36fcf0 100644 --- a/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp +++ b/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h b/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h index 851936027..2e4cff739 100644 --- a/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h +++ b/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp b/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp index bfde3223e..ff19d8d08 100644 --- a/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp +++ b/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h b/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h index d188213d9..83963c1dc 100644 --- a/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h +++ b/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp b/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp index fadb76312..9d172a341 100644 --- a/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp +++ b/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp b/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp index b3a6aad97..010148815 100644 --- a/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp +++ b/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp b/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp index 6b7c4c3b1..0d56ee9af 100644 --- a/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp +++ b/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp b/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp index 2f86b4ab8..7e1d94dbd 100644 --- a/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp +++ b/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -29,7 +29,7 @@ EndScriptData */ ## go_barrel_old_hillsbrad ######*/ -bool GOHello_go_barrel_old_hillsbrad(Player* pPlayer, GameObject* pGo) +bool GOUse_go_barrel_old_hillsbrad(Player* pPlayer, GameObject* pGo) { if (ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData()) { @@ -178,7 +178,7 @@ void AddSC_boss_lieutenant_drake() newscript = new Script; newscript->Name = "go_barrel_old_hillsbrad"; - newscript->pGOHello = &GOHello_go_barrel_old_hillsbrad; + newscript->pGOUse = &GOUse_go_barrel_old_hillsbrad; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp b/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp index 0b5fc83c4..6258c96bf 100644 --- a/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp +++ b/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -40,23 +40,6 @@ void instance_old_hillsbrad::Initialize() memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); } -Player* instance_old_hillsbrad::GetPlayerInMap() -{ - Map::PlayerList const& players = instance->GetPlayers(); - - if (!players.isEmpty()) - { - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* plr = itr->getSource()) - return plr; - } - } - - debug_log("SD2: Instance Old Hillsbrad: GetPlayerInMap, but PlayerList is empty!"); - return NULL; -} - void instance_old_hillsbrad::OnCreatureCreate(Creature* pCreature) { switch(pCreature->GetEntry()) diff --git a/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp b/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp index 72fb2b276..d65e583ae 100644 --- a/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp +++ b/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -437,7 +437,7 @@ struct MANGOS_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI { if (Player* pPlayer = GetPlayerForEscort()) { - if (npc_tarethaAI* pTarethaAI = dynamic_cast(pTaretha->AI())) + if (npc_escortAI* pTarethaAI = dynamic_cast(pTaretha->AI())) pTarethaAI->Start(true, pPlayer->GetGUID()); } } @@ -450,7 +450,7 @@ struct MANGOS_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI for(Map::PlayerList::const_iterator itr = lPlayerList.begin(); itr != lPlayerList.end(); ++itr) { if (Player* pPlayer = itr->getSource()) - pPlayer->KilledMonsterCredit(NPC_THRALL_QUEST_TRIGGER, m_creature->GetGUID()); + pPlayer->KilledMonsterCredit(NPC_THRALL_QUEST_TRIGGER, m_creature->GetObjectGuid()); } } diff --git a/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h b/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h index 61b82968b..4ca9e1a2c 100644 --- a/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h +++ b/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -38,8 +38,6 @@ class MANGOS_DLL_DECL instance_old_hillsbrad : public ScriptedInstance void Initialize(); - Player* GetPlayerInMap(); - void OnCreatureCreate(Creature* pCreature); void OnCreatureDeath(Creature* pCreature); diff --git a/scripts/kalimdor/darkshore.cpp b/scripts/kalimdor/darkshore.cpp index 2fca1e0af..e213fa8d7 100644 --- a/scripts/kalimdor/darkshore.cpp +++ b/scripts/kalimdor/darkshore.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -387,13 +387,13 @@ void AddSC_darkshore() pNewScript = new Script; pNewScript->Name = "npc_kerlonian"; pNewScript->GetAI = &GetAI_npc_kerlonian; - pNewScript->pQuestAccept = &QuestAccept_npc_kerlonian; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_kerlonian; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_prospector_remtravel"; pNewScript->GetAI = &GetAI_npc_prospector_remtravel; - pNewScript->pQuestAccept = &QuestAccept_npc_prospector_remtravel; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_prospector_remtravel; pNewScript->RegisterSelf(); pNewScript = new Script; diff --git a/scripts/kalimdor/desolace.cpp b/scripts/kalimdor/desolace.cpp index e3ea63b4d..e463a2d0d 100644 --- a/scripts/kalimdor/desolace.cpp +++ b/scripts/kalimdor/desolace.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,15 +17,21 @@ /* ScriptData SDName: Desolace SD%Complete: 100 -SDComment: Quest support: 5561 +SDComment: Quest support: 5561, 1440 SDCategory: Desolace EndScriptData */ /* ContentData npc_aged_dying_ancient_kodo +npc_dalinda_malem EndContentData */ #include "precompiled.h" +#include "escort_ai.h" + +/*###### +## npc_aged_dying_ancient_kodo +######*/ enum { @@ -161,14 +167,69 @@ bool GossipHello_npc_aged_dying_ancient_kodo(Player* pPlayer, Creature* pCreatur return true; } +/*###### +## npc_dalinda_malem +######*/ + +enum +{ + QUEST_RETURN_TO_VAHLARRIEL = 1440, +}; + +struct MANGOS_DLL_DECL npc_dalinda_malemAI : public npc_escortAI +{ + npc_dalinda_malemAI(Creature* m_creature) : npc_escortAI(m_creature) { Reset(); } + + void Reset() {} + + void JustStartedEscort() + { + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + } + + void WaypointReached(uint32 uiPointId) + { + if (uiPointId == 18) + { + if (Player* pPlayer = GetPlayerForEscort()) + pPlayer->GroupEventHappens(QUEST_RETURN_TO_VAHLARRIEL, m_creature); + } + } +}; + +CreatureAI* GetAI_npc_dalinda_malem(Creature* pCreature) +{ + return new npc_dalinda_malemAI(pCreature); +} + +bool QuestAccept_npc_dalinda_malem(Player* pPlayer, Creature* pCreature, const Quest* pQuest) +{ + if (pQuest->GetQuestId() == QUEST_RETURN_TO_VAHLARRIEL) + { + if (npc_dalinda_malemAI* pEscortAI = dynamic_cast(pCreature->AI())) + { + // TODO This faction change needs confirmation, also possible that we need to drop her PASSIVE flag + pCreature->setFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE); + pEscortAI->Start(false, pPlayer->GetGUID(), pQuest); + } + } + return true; +} + void AddSC_desolace() { - Script *newscript; - - newscript = new Script; - newscript->Name = "npc_aged_dying_ancient_kodo"; - newscript->GetAI = &GetAI_npc_aged_dying_ancient_kodo; - newscript->pEffectDummyCreature = &EffectDummyCreature_npc_aged_dying_ancient_kodo; - newscript->pGossipHello = &GossipHello_npc_aged_dying_ancient_kodo; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "npc_aged_dying_ancient_kodo"; + pNewScript->GetAI = &GetAI_npc_aged_dying_ancient_kodo; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_npc_aged_dying_ancient_kodo; + pNewScript->pGossipHello = &GossipHello_npc_aged_dying_ancient_kodo; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_dalinda_malem"; + pNewScript->GetAI = &GetAI_npc_dalinda_malem; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_dalinda_malem; + pNewScript->RegisterSelf(); } diff --git a/scripts/kalimdor/dire_maul/dire_maul.cpp b/scripts/kalimdor/dire_maul/dire_maul.cpp new file mode 100644 index 000000000..da85cd70a --- /dev/null +++ b/scripts/kalimdor/dire_maul/dire_maul.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: dire_maul +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Dire Maul +EndScriptData */ + +#include "precompiled.h" + +void AddSC_dire_maul() +{ +} diff --git a/scripts/kalimdor/dire_maul/dire_maul.h b/scripts/kalimdor/dire_maul/dire_maul.h new file mode 100644 index 000000000..58ff9f62e --- /dev/null +++ b/scripts/kalimdor/dire_maul/dire_maul.h @@ -0,0 +1,132 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_DM_H +#define DEF_DM_H + +enum +{ + MAX_ENCOUNTER = 9, + MAX_GENERATORS = 5, + + // East + TYPE_ALZZIN = 0, // Do not change - Handled with Acid + + // West + TYPE_IMMOLTHAR = 1, + TYPE_PRINCE = 2, + TYPE_PYLON_1 = 3, + TYPE_PYLON_2 = TYPE_PYLON_1 + 1, + TYPE_PYLON_3 = TYPE_PYLON_1 + 2, + TYPE_PYLON_4 = TYPE_PYLON_1 + 3, + TYPE_PYLON_5 = TYPE_PYLON_1 + 4, + + // North + TYPE_KING_GORDOK = 8, + + // East + GO_CRUMBLE_WALL = 177220, + GO_CORRUPT_VINE = 179502, + GO_FELVINE_SHARD = 179559, + GO_CONSERVATORY_DOOR = 176907, + + NPC_OLD_IRONBARK = 11491, + NPC_IRONBARK_REDEEMED = 14241, + + // West + NPC_PRINCE_TORTHELDRIN = 11486, + NPC_IMMOLTHAR = 11496, + NPC_ARCANE_ABERRATION = 11480, + NPC_MANA_REMNANT = 11483, + NPC_HIGHBORNE_SUMMONER = 11466, + + GO_PRINCES_CHEST = 179545, + GO_PRINCES_CHEST_AURA = 179563, + GO_CRYSTAL_GENERATOR_1 = 177259, + GO_CRYSTAL_GENERATOR_2 = 177257, + GO_CRYSTAL_GENERATOR_3 = 177258, + GO_CRYSTAL_GENERATOR_4 = 179504, + GO_CRYSTAL_GENERATOR_5 = 179505, + GO_FORCEFIELD = 179503, + GO_WARPWOOD_DOOR = 177221, + + // North + NPC_GUARD_MOLDAR = 14326, + NPC_STOMPER_KREEG = 14322, + NPC_GUARD_FENGUS = 14321, + NPC_GUARD_SLIPKIK = 14323, + NPC_CAPTAIN_KROMCRUSH = 14325, + NPC_CHORUSH = 14324, + NPC_KING_GORDOK = 11501, + NPC_MIZZLE_THE_CRAFTY = 14353, + + GO_KNOTS_CACHE = 179501, + GO_KNOTS_BALL_AND_CHAIN = 179511, + GO_GORDOK_TRIBUTE = 179564, + + SAY_FREE_IMMOLTHAR = -1429000, + SAY_KILL_IMMOLTHAR = -1429001, + + FACTION_HOSTILE = 14, + SPELL_KING_OF_GORDOK = 22799, +}; + +class MANGOS_DLL_DECL instance_dire_maul : public ScriptedInstance +{ + public: + instance_dire_maul(Map* pMap); + ~instance_dire_maul() {} + + void Initialize(); + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + void OnCreatureEnterCombat(Creature* pCreature); + void OnCreatureDeath(Creature* pCreature); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + protected: + bool CheckAllGeneratorsDestroyed(); + void ProcessForceFieldOpening(); + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + // East + bool m_bWallDestroyed; + + uint64 m_uiCrumbleWallGUID; + uint64 m_uiCorruptVineGUID; + uint64 m_uiConservatoryDoorGUID; + uint64 m_uiOldIronbarkGUID; + + std::list m_lFelvineShardGUIDs; + + // West + uint64 m_auiCrystalGeneratorGUID[MAX_GENERATORS]; + + uint64 m_uiPrinceTortheldrinGUID; + uint64 m_uiImmolTharGUID; + uint64 m_uiForcefieldGUID; + uint64 m_uiPrincesChestAuraGUID; + uint64 m_uiTendrisWarpwoodDoorGUID; + + std::list m_luiHighborneSummonerGUIDs; + std::list m_lGeneratorGuardGUIDs; + std::set m_sSortedGeneratorGuards[MAX_GENERATORS]; + + // North + uint64 m_uiGordokGUID; + uint64 m_uiChoRushGUID; + uint64 m_uiMizzleGUID; +}; + +#endif diff --git a/scripts/kalimdor/dire_maul/instance_dire_maul.cpp b/scripts/kalimdor/dire_maul/instance_dire_maul.cpp new file mode 100644 index 000000000..2428861e7 --- /dev/null +++ b/scripts/kalimdor/dire_maul/instance_dire_maul.cpp @@ -0,0 +1,423 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: instance_dire_maul +SD%Complete: 30 +SDComment: Basic Support - Most events and quest-related stuff missing +SDCategory: Dire Maul +EndScriptData */ + +#include "precompiled.h" +#include "dire_maul.h" + +instance_dire_maul::instance_dire_maul(Map* pMap) : ScriptedInstance(pMap), + // East + m_bWallDestroyed(false), + m_uiCrumbleWallGUID(0), + m_uiCorruptVineGUID(0), + m_uiConservatoryDoorGUID(0), + m_uiOldIronbarkGUID(0), + + // West + m_uiPrinceTortheldrinGUID(0), + m_uiImmolTharGUID(0), + m_uiForcefieldGUID(0), + m_uiPrincesChestAuraGUID(0), + m_uiTendrisWarpwoodDoorGUID(0), + + // North + m_uiGordokGUID(0), + m_uiChoRushGUID(0), + m_uiMizzleGUID(0) +{ + Initialize(); +} + +void instance_dire_maul::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + memset(&m_auiCrystalGeneratorGUID, 0, sizeof(m_auiCrystalGeneratorGUID)); + + m_lFelvineShardGUIDs.clear(); + m_luiHighborneSummonerGUIDs.clear(); + m_lGeneratorGuardGUIDs.clear(); +} + +void instance_dire_maul::OnCreatureCreate(Creature* pCreature) +{ + switch(pCreature->GetEntry()) + { + // West + case NPC_PRINCE_TORTHELDRIN: + m_uiPrinceTortheldrinGUID = pCreature->GetGUID(); + if (m_auiEncounter[TYPE_IMMOLTHAR] == DONE) + pCreature->setFaction(FACTION_HOSTILE); + break; + case NPC_ARCANE_ABERRATION: + case NPC_MANA_REMNANT: + m_lGeneratorGuardGUIDs.push_back(pCreature->GetGUID()); + break; + case NPC_IMMOLTHAR: + m_uiImmolTharGUID = pCreature->GetGUID(); + break; + case NPC_HIGHBORNE_SUMMONER: + m_luiHighborneSummonerGUIDs.push_back(pCreature->GetGUID()); + break; + + // North + case NPC_CHORUSH: + m_uiChoRushGUID = pCreature->GetGUID(); + break; + case NPC_KING_GORDOK: + m_uiGordokGUID = pCreature->GetGUID(); + break; + case NPC_MIZZLE_THE_CRAFTY: + m_uiMizzleGUID = pCreature->GetGUID(); + break; + } +} + +void instance_dire_maul::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) + { + // East + case GO_CRUMBLE_WALL: + m_uiCrumbleWallGUID = pGo->GetGUID(); + if (m_bWallDestroyed) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CORRUPT_VINE: + m_uiCorruptVineGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_ALZZIN] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_FELVINE_SHARD: + m_lFelvineShardGUIDs.push_back(pGo->GetGUID()); + break; + + // West + case GO_CRYSTAL_GENERATOR_1: + m_auiCrystalGeneratorGUID[0] = pGo->GetGUID(); + if (m_auiEncounter[TYPE_PYLON_1] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_GENERATOR_2: + m_auiCrystalGeneratorGUID[1] = pGo->GetGUID(); + if (m_auiEncounter[TYPE_PYLON_2] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_GENERATOR_3: + m_auiCrystalGeneratorGUID[2] = pGo->GetGUID(); + if (m_auiEncounter[TYPE_PYLON_3] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_GENERATOR_4: + m_auiCrystalGeneratorGUID[3] = pGo->GetGUID(); + if (m_auiEncounter[TYPE_PYLON_4] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_GENERATOR_5: + m_auiCrystalGeneratorGUID[4] = pGo->GetGUID(); + if (m_auiEncounter[TYPE_PYLON_5] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_FORCEFIELD: + m_uiForcefieldGUID = pGo->GetGUID(); + if (CheckAllGeneratorsDestroyed()) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_PRINCES_CHEST_AURA: + m_uiPrincesChestAuraGUID = pGo->GetGUID(); + break; + } +} + +void instance_dire_maul::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) + { + // East + case TYPE_ALZZIN: // This Encounter is expected to be handled within Acid (reason handling at 50% hp) + if (uiData == DONE) + { + if (!m_bWallDestroyed) + { + DoUseDoorOrButton(m_uiCrumbleWallGUID); + m_bWallDestroyed = true; + } + + DoUseDoorOrButton(m_uiCorruptVineGUID); + + if (!m_lFelvineShardGUIDs.empty()) + { + for(std::list::iterator i = m_lFelvineShardGUIDs.begin(); i != m_lFelvineShardGUIDs.end(); ++i) + DoRespawnGameObject(*i); + } + } + else if (uiData == SPECIAL && !m_bWallDestroyed) + { + DoUseDoorOrButton(m_uiCrumbleWallGUID); + m_bWallDestroyed = true; + } + m_auiEncounter[uiType] = uiData; + break; + + // West + case TYPE_IMMOLTHAR: + if (uiData == DONE) + { + if (Creature* pPrince = instance->GetCreature(m_uiPrinceTortheldrinGUID)) + { + DoScriptText(SAY_FREE_IMMOLTHAR, pPrince); + pPrince->setFaction(FACTION_HOSTILE); + // Despawn Chest-Aura + if (GameObject* pChestAura = instance->GetGameObject(m_uiPrincesChestAuraGUID)) + pChestAura->Use(pPrince); + } + } + m_auiEncounter[uiType] = uiData; + break; + case TYPE_PRINCE: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_PYLON_1: + case TYPE_PYLON_2: + case TYPE_PYLON_3: + case TYPE_PYLON_4: + case TYPE_PYLON_5: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + DoUseDoorOrButton(m_auiCrystalGeneratorGUID[uiType - TYPE_PYLON_1]); + if (CheckAllGeneratorsDestroyed()) + ProcessForceFieldOpening(); + } + break; + + // North + case TYPE_KING_GORDOK: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + // Apply Aura to players in the map + Map::PlayerList const& players = instance->GetPlayers(); + for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + pPlayer->CastSpell(pPlayer, SPELL_KING_OF_GORDOK, true); + } + } + 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_auiEncounter[8]; + + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } +} + +uint32 instance_dire_maul::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + + return 0; +} + +uint64 instance_dire_maul::GetData64(uint32 uiData) +{ + switch(uiData) + { + case NPC_CHORUSH: return m_uiChoRushGUID; + case NPC_KING_GORDOK: return m_uiGordokGUID; + default: + return 0; + } +} + +void instance_dire_maul::OnCreatureEnterCombat(Creature* pCreature) +{ + switch (pCreature->GetEntry()) + { + // West + // - Handling of guards of generators + case NPC_ARCANE_ABERRATION: + case NPC_MANA_REMNANT: + if (!m_lGeneratorGuardGUIDs.empty()) + { + for (uint8 i = 0; i < MAX_GENERATORS; i++) + { + GameObject* pGenerator = instance->GetGameObject(m_auiCrystalGeneratorGUID[i]); + // Skip non-existing or finished generators + if (!pGenerator || GetData(TYPE_PYLON_1 + i) == DONE) + continue; + + // Sort all remaining (alive) NPCs to unfinished generators + for (std::list::iterator itr = m_lGeneratorGuardGUIDs.begin(); itr != m_lGeneratorGuardGUIDs.end();) + { + Creature* pGuard = instance->GetCreature(*itr); + if (!pGuard || pGuard->isDead()) // Remove invalid guids and dead guards + { + m_lGeneratorGuardGUIDs.erase(itr++); + continue; + } + + if (pGuard->IsWithinDistInMap(pGenerator, 20.0f)) + { + m_sSortedGeneratorGuards[i].insert(pGuard->GetGUIDLow()); + m_lGeneratorGuardGUIDs.erase(itr++); + } + else + ++itr; + } + } + } + break; + // - Set InstData for ImmolThar + case NPC_IMMOLTHAR: + SetData(TYPE_IMMOLTHAR, IN_PROGRESS); + break; + } +} + +void instance_dire_maul::OnCreatureDeath(Creature* pCreature) +{ + switch (pCreature->GetEntry()) + { + // West + // - Handling of guards of generators + case NPC_ARCANE_ABERRATION: + case NPC_MANA_REMNANT: + for (uint8 i = 0; i < MAX_GENERATORS; i++) + { + // Skip already activated generators + if (GetData(TYPE_PYLON_1 + i) == DONE) + continue; + + // Only process generator where the npc is sorted in + if (m_sSortedGeneratorGuards[i].find(pCreature->GetGUIDLow()) != m_sSortedGeneratorGuards[i].end()) + { + m_sSortedGeneratorGuards[i].erase(pCreature->GetGUIDLow()); + if (m_sSortedGeneratorGuards[i].empty()) + SetData(TYPE_PYLON_1 + i, DONE); + + break; + } + } + break; + // - Set InstData for ImmolThar + case NPC_IMMOLTHAR: + SetData(TYPE_IMMOLTHAR, DONE); + break; + + // North + // - Handling of Ogre Boss (Assume boss can be handled in Acid) + case NPC_KING_GORDOK: + SetData(TYPE_KING_GORDOK, DONE); + break; + } +} + +void instance_dire_maul::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]; + + if (m_auiEncounter[TYPE_ALZZIN] >= DONE) + m_bWallDestroyed = true; + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; +} + +bool instance_dire_maul::CheckAllGeneratorsDestroyed() +{ + if (m_auiEncounter[TYPE_PYLON_1] != DONE || m_auiEncounter[TYPE_PYLON_2] != DONE || m_auiEncounter[TYPE_PYLON_3] != DONE || m_auiEncounter[TYPE_PYLON_4] != DONE || m_auiEncounter[TYPE_PYLON_5] != DONE) + return false; + + return true; +} + +void instance_dire_maul::ProcessForceFieldOpening() +{ + // 'Open' the force field + DoUseDoorOrButton(m_uiForcefieldGUID); + + // Let the summoners attack Immol'Thar + Creature* pImmolThar = instance->GetCreature(m_uiImmolTharGUID); + if (!pImmolThar || pImmolThar->isDead()) + return; + + bool bHasYelled = false; + for (std::list::const_iterator itr = m_luiHighborneSummonerGUIDs.begin(); itr != m_luiHighborneSummonerGUIDs.end(); ++itr) + { + Creature* pSummoner = instance->GetCreature(*itr); + + if (!bHasYelled && pSummoner) + { + DoScriptText(SAY_KILL_IMMOLTHAR, pSummoner); + bHasYelled = true; + } + + if (!pSummoner || pSummoner->isDead()) + continue; + + pSummoner->AI()->AttackStart(pImmolThar); + } + m_luiHighborneSummonerGUIDs.clear(); +} + +InstanceData* GetInstanceData_instance_dire_maul(Map* pMap) +{ + return new instance_dire_maul(pMap); +} + +void AddSC_instance_dire_maul() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_dire_maul"; + pNewScript->GetInstanceData = &GetInstanceData_instance_dire_maul; + pNewScript->RegisterSelf(); +} diff --git a/scripts/kalimdor/dustwallow_marsh.cpp b/scripts/kalimdor/dustwallow_marsh.cpp index bbf3f20b2..c44f6c609 100644 --- a/scripts/kalimdor/dustwallow_marsh.cpp +++ b/scripts/kalimdor/dustwallow_marsh.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -71,7 +71,7 @@ struct MANGOS_DLL_DECL mobs_risen_husk_spiritAI : public ScriptedAI void JustSummoned(Creature* pSummoned) { if (m_pCreditPlayer) - m_pCreditPlayer->KilledMonsterCredit(pSummoned->GetEntry(), pSummoned->GetGUID()); + m_pCreditPlayer->KilledMonsterCredit(pSummoned->GetEntry(), pSummoned->GetObjectGuid()); } void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) @@ -168,7 +168,7 @@ struct MANGOS_DLL_DECL npc_restless_apparitionAI : public ScriptedAI case 6: DoScriptText(SAY_RAND_7, m_creature); break; case 7: DoScriptText(SAY_RAND_8, m_creature); break; } - + m_uiTalk_Timer = 0; } else @@ -863,7 +863,7 @@ void AddSC_dustwallow_marsh() pNewScript = new Script; pNewScript->Name = "npc_morokk"; pNewScript->GetAI = &GetAI_npc_morokk; - pNewScript->pQuestAccept = &QuestAccept_npc_morokk; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_morokk; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -875,13 +875,13 @@ void AddSC_dustwallow_marsh() pNewScript = new Script; pNewScript->Name = "npc_ogron"; pNewScript->GetAI = &GetAI_npc_ogron; - pNewScript->pQuestAccept = &QuestAccept_npc_ogron; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_ogron; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_private_hendel"; pNewScript->GetAI = &GetAI_npc_private_hendel; - pNewScript->pQuestAccept = &QuestAccept_npc_private_hendel; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_private_hendel; pNewScript->RegisterSelf(); pNewScript = new Script; diff --git a/scripts/kalimdor/felwood.cpp b/scripts/kalimdor/felwood.cpp index 4e8164e3b..15dc62687 100644 --- a/scripts/kalimdor/felwood.cpp +++ b/scripts/kalimdor/felwood.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -205,7 +205,7 @@ bool GossipHello_npcs_riverbreeze_and_silversky(Player* pPlayer, Creature* pCrea pPlayer->SEND_GOSSIP_MENU(2842, pCreature->GetGUID()); break; } - + return true; } @@ -322,7 +322,7 @@ CreatureAI* GetAI_npc_niby_the_almighty(Creature* pCreature) return new npc_niby_the_almightyAI(pCreature); } -bool ChooseReward_npc_niby_the_almighty(Player* pPlayer, Creature* pCreature, const Quest* pQuest, uint32 slot) +bool QuestRewarded_npc_niby_the_almighty(Player* pPlayer, Creature* pCreature, Quest const* pQuest) { if (pQuest->GetQuestId() == QUEST_KROSHIUS) { @@ -477,7 +477,7 @@ void AddSC_felwood() pNewScript = new Script; pNewScript->Name = "npc_kitten"; pNewScript->GetAI = &GetAI_npc_kitten; - pNewScript->pEffectDummyCreature = &EffectDummyCreature_npc_kitten; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_npc_kitten; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -495,7 +495,7 @@ void AddSC_felwood() pNewScript = new Script; pNewScript->Name = "npc_niby_the_almighty"; pNewScript->GetAI = &GetAI_npc_niby_the_almighty; - pNewScript->pChooseReward = &ChooseReward_npc_niby_the_almighty; + pNewScript->pQuestRewardedNPC = &QuestRewarded_npc_niby_the_almighty; pNewScript->RegisterSelf(); pNewScript = new Script; diff --git a/scripts/kalimdor/feralas.cpp b/scripts/kalimdor/feralas.cpp index 79463a8b0..57daaf415 100644 --- a/scripts/kalimdor/feralas.cpp +++ b/scripts/kalimdor/feralas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -190,7 +190,7 @@ void AddSC_feralas() newscript = new Script; newscript->Name = "npc_oox22fe"; newscript->GetAI = &GetAI_npc_oox22fe; - newscript->pQuestAccept = &QuestAccept_npc_oox22fe; + newscript->pQuestAcceptNPC = &QuestAccept_npc_oox22fe; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp b/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp index b1495f9c4..87bdb0076 100644 --- a/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp +++ b/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/maraudon/boss_landslide.cpp b/scripts/kalimdor/maraudon/boss_landslide.cpp index 69c211fd5..104807d48 100644 --- a/scripts/kalimdor/maraudon/boss_landslide.cpp +++ b/scripts/kalimdor/maraudon/boss_landslide.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/maraudon/boss_noxxion.cpp b/scripts/kalimdor/maraudon/boss_noxxion.cpp index 7d9773d35..01b167ff2 100644 --- a/scripts/kalimdor/maraudon/boss_noxxion.cpp +++ b/scripts/kalimdor/maraudon/boss_noxxion.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/maraudon/boss_princess_theradras.cpp b/scripts/kalimdor/maraudon/boss_princess_theradras.cpp index 5d9574704..cfd3f3072 100644 --- a/scripts/kalimdor/maraudon/boss_princess_theradras.cpp +++ b/scripts/kalimdor/maraudon/boss_princess_theradras.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/moonglade.cpp b/scripts/kalimdor/moonglade.cpp index 621131518..4bdb39961 100644 --- a/scripts/kalimdor/moonglade.cpp +++ b/scripts/kalimdor/moonglade.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -72,6 +72,7 @@ bool GossipHello_npc_bunthen_plainswind(Player* pPlayer, Creature* pCreature) bool GossipSelect_npc_bunthen_plainswind(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { + pPlayer->PlayerTalkClass->ClearMenus(); switch(uiAction) { case GOSSIP_ACTION_INFO_DEF + 1: @@ -253,6 +254,7 @@ bool GossipHello_npc_great_bear_spirit(Player* pPlayer, Creature* pCreature) bool GossipSelect_npc_great_bear_spirit(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { + pPlayer->PlayerTalkClass->ClearMenus(); switch(uiAction) { case GOSSIP_ACTION_INFO_DEF: @@ -310,6 +312,7 @@ bool GossipHello_npc_silva_filnaveth(Player* pPlayer, Creature* pCreature) bool GossipSelect_npc_silva_filnaveth(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { + pPlayer->PlayerTalkClass->ClearMenus(); switch(uiAction) { case GOSSIP_ACTION_INFO_DEF + 1: @@ -346,7 +349,7 @@ void AddSC_moonglade() newscript = new Script; newscript->Name = "npc_clintar_dw_spirit"; newscript->GetAI = &GetAI_npc_clintar_dw_spirit; - newscript->pEffectDummyCreature = &EffectDummyCreature_npc_clintar_dw_spirit; + newscript->pEffectDummyNPC = &EffectDummyCreature_npc_clintar_dw_spirit; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/kalimdor/mulgore.cpp b/scripts/kalimdor/mulgore.cpp index 47fba87a3..98dcb7648 100644 --- a/scripts/kalimdor/mulgore.cpp +++ b/scripts/kalimdor/mulgore.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -82,7 +82,7 @@ struct MANGOS_DLL_DECL npc_kyle_the_frenziedAI : public ScriptedAI m_bEvent = true; DoScriptText(EMOTE_SEE_LUNCH, m_creature); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CREATURE_SPECIAL); + m_creature->HandleEmote(EMOTE_ONESHOT_CREATURE_SPECIAL); } } @@ -112,16 +112,32 @@ struct MANGOS_DLL_DECL npc_kyle_the_frenziedAI : public ScriptedAI case 1: if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) { - if (GameObject* pGo = pPlayer->GetGameObject(SPELL_LUNCH)) + GameObject* pGo = pPlayer->GetGameObject(SPELL_LUNCH); + + // Workaround for broken function GetGameObject + if (!pGo) + { + const SpellEntry* pSpell = GetSpellStore()->LookupEntry(SPELL_LUNCH); + + uint32 uiGameobjectEntry = pSpell->EffectMiscValue[EFFECT_INDEX_1]; + + pGo = GetClosestGameObjectWithEntry(pPlayer, uiGameobjectEntry, 2*INTERACTION_DISTANCE); + } + + if (pGo) { m_bIsMovingToLunch = true; - m_creature->GetMotionMaster()->MovePoint(POINT_ID, pGo->GetPositionX(), pGo->GetPositionY(), pGo->GetPositionZ()); + + float fX, fY, fZ; + pGo->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); + + m_creature->GetMotionMaster()->MovePoint(POINT_ID, fX, fY, fZ); } } break; case 2: DoScriptText(EMOTE_EAT_LUNCH, m_creature); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USESTANDING); + m_creature->HandleEmote(EMOTE_STATE_USESTANDING); break; case 3: if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) @@ -132,10 +148,10 @@ struct MANGOS_DLL_DECL npc_kyle_the_frenziedAI : public ScriptedAI case 4: m_uiEventTimer = 30000; DoScriptText(EMOTE_DANCE, m_creature); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCESPECIAL); + m_creature->HandleEmote(EMOTE_STATE_DANCESPECIAL); break; case 5: - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + m_creature->HandleEmote(EMOTE_STATE_NONE); Reset(); m_creature->GetMotionMaster()->Clear(); break; diff --git a/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp b/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp index 913eafa6e..fadb93dee 100644 --- a/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp +++ b/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: Boss_Onyxia SD%Complete: 70 -SDComment: Phase 3 need additional code. The spawning Whelps need GO-Support. Erruption needs GO-Support +SDComment: Phase 3 need additional code. The spawning Whelps need GO-Support. Use of spells 22191 and 21131 unknown SDCategory: Onyxia's Lair EndScriptData */ @@ -57,6 +57,9 @@ enum SPELL_BREATH_SW_TO_NE = 18596, // 12x in "array" SPELL_BREATH_NE_TO_SW = 18617, // 12x in "array" + SPELL_VISUAL_BREATH_A = 4880, // Only and all of the above Breath spells (and their triggered spells) have these visuals + SPELL_VISUAL_BREATH_B = 4919, + //SPELL_BREATH = 21131, // 8x in "array", different initial cast than the other arrays SPELL_BELLOWINGROAR = 18431, @@ -66,7 +69,6 @@ enum SPELL_SUMMON_LAIR_GUARD = 68968, MAX_WHELPS_PER_PACK = 40, - NPC_WHELP = 11262, PHASE_START = 1, PHASE_BREATH = 2, @@ -167,7 +169,9 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); + + if (m_pInstance) + m_pInstance->SetData(TYPE_ONYXIA, IN_PROGRESS); } void JustReachedHome() @@ -175,6 +179,15 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI // in case evade in phase 2, see comments for hack where phase 2 is set m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); m_creature->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0); + + if (m_pInstance) + m_pInstance->SetData(TYPE_ONYXIA, FAIL); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_ONYXIA, DONE); } void JustSummoned(Creature* pSummoned) @@ -182,7 +195,7 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI pSummoned->GetMotionMaster()->MovePoint(0, afSpawnLocations[3][0], afSpawnLocations[3][1], afSpawnLocations[3][2]); pSummoned->SetInCombatWithZone(); - if (pSummoned->GetEntry() == NPC_WHELP) + if (pSummoned->GetEntry() == NPC_ONYXIA_WHELP) ++m_uiSummonCount; } @@ -305,6 +318,9 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI if (m_pPointData) m_creature->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); + // TODO - this might not be the correct place to set this setting + if (m_pInstance) + m_pInstance->SetData(TYPE_ONYXIA, DATA_LIFTOFF); return; } @@ -377,8 +393,8 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI { if (m_uiWhelpTimer < uiDiff) { - m_creature->SummonCreature(NPC_WHELP, afSpawnLocations[0][0], afSpawnLocations[0][1], afSpawnLocations[0][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); - m_creature->SummonCreature(NPC_WHELP, afSpawnLocations[1][0], afSpawnLocations[1][1], afSpawnLocations[1][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); + m_creature->SummonCreature(NPC_ONYXIA_WHELP, afSpawnLocations[0][0], afSpawnLocations[0][1], afSpawnLocations[0][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); + m_creature->SummonCreature(NPC_ONYXIA_WHELP, afSpawnLocations[1][0], afSpawnLocations[1][1], afSpawnLocations[1][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); m_uiWhelpTimer = 500; } else @@ -414,6 +430,17 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI } } } + + void SpellHitTarget(Unit* pTarget, const SpellEntry* pSpell) + { + // Check if players are hit by Onyxia's Deep Breath + if (pTarget->GetTypeId() != TYPEID_PLAYER || !m_pInstance) + return; + + // All and only the Onyxia Deep Breath Spells have these visuals + if (pSpell->SpellVisual[0] == SPELL_VISUAL_BREATH_A || pSpell->SpellVisual[0] == SPELL_VISUAL_BREATH_B) + m_pInstance->SetData(TYPE_ONYXIA, DATA_PLAYER_TOASTED); + } }; CreatureAI* GetAI_boss_onyxia(Creature* pCreature) @@ -424,6 +451,7 @@ CreatureAI* GetAI_boss_onyxia(Creature* pCreature) void AddSC_boss_onyxia() { Script* pNewScript; + pNewScript = new Script; pNewScript->Name = "boss_onyxia"; pNewScript->GetAI = &GetAI_boss_onyxia; diff --git a/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp b/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp index bcb0fde0e..bdf548c3e 100644 --- a/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp +++ b/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -25,13 +25,21 @@ EndScriptData */ #include "onyxias_lair.h" instance_onyxias_lair::instance_onyxias_lair(Map* pMap) : ScriptedInstance(pMap), - m_uiOnyxTriggerGUID(0) + m_uiOnyxTriggerGUID(0), + m_uiAchievWhelpsCount(0) { Initialize(); } void instance_onyxias_lair::Initialize() { + m_uiEncounter = NOT_STARTED; + m_tPhaseTwoStart = time(NULL); +} + +bool instance_onyxias_lair::IsEncounterInProgress() const +{ + return m_uiEncounter == IN_PROGRESS || m_uiEncounter >= DATA_LIFTOFF; } void instance_onyxias_lair::OnCreatureCreate(Creature* pCreature) @@ -41,6 +49,39 @@ void instance_onyxias_lair::OnCreatureCreate(Creature* pCreature) case NPC_ONYXIA_TRIGGER: m_uiOnyxTriggerGUID = pCreature->GetGUID(); break; + case NPC_ONYXIA_WHELP: + if (m_uiEncounter >= DATA_LIFTOFF && time_t(m_tPhaseTwoStart + TIME_LIMIT_MANY_WHELPS) >= time(NULL)) + ++m_uiAchievWhelpsCount; + break; + } +} + +void instance_onyxias_lair::SetData(uint32 uiType, uint32 uiData) +{ + if (uiType != TYPE_ONYXIA) + return; + + m_uiEncounter = uiData; + if (uiData == IN_PROGRESS) + m_uiAchievWhelpsCount = 0; + if (uiData == DATA_LIFTOFF) + m_tPhaseTwoStart = time(NULL); + + // Currently no reason to save anything +} + +bool instance_onyxias_lair::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/) +{ + switch (uiCriteriaId) + { + case ACHIEV_CRIT_MANY_WHELPS_N: + case ACHIEV_CRIT_MANY_WHELPS_H: + return m_uiAchievWhelpsCount >= ACHIEV_CRIT_REQ_MANY_WHELPS; + case ACHIEV_CRIT_NO_BREATH_N: + case ACHIEV_CRIT_NO_BREATH_H: + return m_uiEncounter != DATA_PLAYER_TOASTED; + default: + return false; } } diff --git a/scripts/kalimdor/onyxias_lair/onyxias_lair.h b/scripts/kalimdor/onyxias_lair/onyxias_lair.h index 2751ba33a..f43083820 100644 --- a/scripts/kalimdor/onyxias_lair/onyxias_lair.h +++ b/scripts/kalimdor/onyxias_lair/onyxias_lair.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,7 +7,23 @@ enum { - NPC_ONYXIA_TRIGGER = 12758 + TYPE_ONYXIA = 0, + + // Special data fields for Onyxia + DATA_LIFTOFF = 4, + DATA_PLAYER_TOASTED = 5, + + NPC_ONYXIA_WHELP = 11262, + NPC_ONYXIA_TRIGGER = 12758, + + // Achievement Related + TIME_LIMIT_MANY_WHELPS = 10, // 10s timeframe to kill 50 whelps after liftoff + ACHIEV_CRIT_REQ_MANY_WHELPS = 50, + + ACHIEV_CRIT_MANY_WHELPS_N = 12565, // Achievements 4403, 4406 + ACHIEV_CRIT_MANY_WHELPS_H = 12568, + ACHIEV_CRIT_NO_BREATH_N = 12566, // Acheivements 4404, 4407 + ACHIEV_CRIT_NO_BREATH_H = 12569, }; class MANGOS_DLL_DECL instance_onyxias_lair : public ScriptedInstance @@ -18,11 +34,22 @@ class MANGOS_DLL_DECL instance_onyxias_lair : public ScriptedInstance void Initialize(); + bool IsEncounterInProgress() const; + void OnCreatureCreate(Creature* pCreature); + void SetData(uint32 uiType, uint32 uiData); + + bool CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/); + uint64 GetOnyxiaTriggerGUID() { return m_uiOnyxTriggerGUID; } protected: + uint32 m_uiEncounter; + uint32 m_uiAchievWhelpsCount; + + time_t m_tPhaseTwoStart; + uint64 m_uiOnyxTriggerGUID; }; diff --git a/scripts/kalimdor/orgrimmar.cpp b/scripts/kalimdor/orgrimmar.cpp index 557c78339..434686a4a 100644 --- a/scripts/kalimdor/orgrimmar.cpp +++ b/scripts/kalimdor/orgrimmar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -262,7 +262,7 @@ void AddSC_orgrimmar() newscript = new Script; newscript->Name = "npc_shenthul"; newscript->GetAI = &GetAI_npc_shenthul; - newscript->pQuestAccept = &QuestAccept_npc_shenthul; + newscript->pQuestAcceptNPC = &QuestAccept_npc_shenthul; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp b/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp index 56b769b80..4d7bbef20 100644 --- a/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp +++ b/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp b/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp index b854a0bf6..7248e5f85 100644 --- a/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp +++ b/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp b/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp index 1cf6d3c71..f55da4c1f 100644 --- a/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp +++ b/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h b/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h index a38b4d307..f7e189618 100644 --- a/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h +++ b/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -12,7 +12,7 @@ enum TYPE_AGATHELOS = 1, GO_AGATHELOS_WARD = 21099, - + NPC_WARD_KEEPER = 4625 }; diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp index b074a7978..587c200ef 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -53,7 +53,7 @@ struct MANGOS_DLL_DECL boss_ayamissAI : public ScriptedAI m_uiStingerSprayTimer = 30000; m_uiPoisonStingerTimer = 30000; m_uiSummonSwarmerTimer = 60000; - + m_uiPhase = PHASE_AIR; } @@ -70,7 +70,7 @@ struct MANGOS_DLL_DECL boss_ayamissAI : public ScriptedAI } else m_uiStingerSprayTimer -= uiDiff; - + if (m_uiPhase == PHASE_AIR) { // Start ground phase at 70% of HP diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp index 2eddb5e49..fc298990d 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp index e6b65c3e3..2d395471c 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp index 88963cfa3..5d2139d65 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -46,7 +46,7 @@ struct MANGOS_DLL_DECL boss_moamAI : public ScriptedAI boss_moamAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} uint8 m_uiPhase; - + uint32 m_uiTrample_Timer; uint32 m_uiManaDrain_Timer; uint32 m_uiCheckoutMana_Timer; diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp index e176b7cc1..09bb8f184 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp index 3abfe4d42..98ca3a0dd 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp index 6c2ff364e..7a42f4a9e 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp b/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp index 51f4d036d..03f25d97c 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp +++ b/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -38,7 +38,7 @@ enum SPELL_THUNDER_CLAP = 26554, SPELL_REFLECT_ARFR = 13022, SPELL_REFLECT_FSSH = 19595, - SPELL_ENRAGE = 8559, + SPELL_ENRAGE = 8599, SPELL_EXPLODE = 25698, SPELL_SUMMON_ANUB_SWARMGUARD = 17430, diff --git a/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h b/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h index 60dfa9c66..999551b61 100644 --- a/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h +++ b/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/kalimdor/silithus.cpp b/scripts/kalimdor/silithus.cpp index 4c36854c7..906fab9e1 100644 --- a/scripts/kalimdor/silithus.cpp +++ b/scripts/kalimdor/silithus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -202,7 +202,7 @@ bool GossipSelect_npcs_rutgar_and_frankal(Player* pPlayer, Creature* pCreature, case GOSSIP_ACTION_INFO_DEF + 6: pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RUTGAR7, pCreature->GetGUID()); //'kill' our trigger to update quest status - pPlayer->KilledMonsterCredit(TRIGGER_RUTGAR, pCreature->GetGUID()); + pPlayer->KilledMonsterCredit(TRIGGER_RUTGAR, pCreature->GetObjectGuid()); break; case GOSSIP_ACTION_INFO_DEF + 9: @@ -228,7 +228,7 @@ bool GossipSelect_npcs_rutgar_and_frankal(Player* pPlayer, Creature* pCreature, case GOSSIP_ACTION_INFO_DEF + 14: pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_FRANKAL6, pCreature->GetGUID()); //'kill' our trigger to update quest status - pPlayer->KilledMonsterCredit(TRIGGER_FRANKAL, pCreature->GetGUID()); + pPlayer->KilledMonsterCredit(TRIGGER_FRANKAL, pCreature->GetObjectGuid()); break; } return true; diff --git a/scripts/kalimdor/stonetalon_mountains.cpp b/scripts/kalimdor/stonetalon_mountains.cpp index 33ab44f49..6bc25a769 100644 --- a/scripts/kalimdor/stonetalon_mountains.cpp +++ b/scripts/kalimdor/stonetalon_mountains.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -155,6 +155,6 @@ void AddSC_stonetalon_mountains() newscript = new Script; newscript->Name = "npc_kaya"; newscript->GetAI = &GetAI_npc_kaya; - newscript->pQuestAccept = &QuestAccept_npc_kaya; + newscript->pQuestAcceptNPC = &QuestAccept_npc_kaya; newscript->RegisterSelf(); } diff --git a/scripts/kalimdor/tanaris.cpp b/scripts/kalimdor/tanaris.cpp index 4a8954090..2e976a70f 100644 --- a/scripts/kalimdor/tanaris.cpp +++ b/scripts/kalimdor/tanaris.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -613,14 +613,14 @@ void AddSC_tanaris() newscript = new Script; newscript->Name = "npc_oox17tn"; newscript->GetAI = &GetAI_npc_oox17tn; - newscript->pQuestAccept = &QuestAccept_npc_oox17tn; + newscript->pQuestAcceptNPC = &QuestAccept_npc_oox17tn; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_steward_of_time"; newscript->pGossipHello = &GossipHello_npc_steward_of_time; newscript->pGossipSelect = &GossipSelect_npc_steward_of_time; - newscript->pQuestAccept = &QuestAccept_npc_steward_of_time; + newscript->pQuestAcceptNPC = &QuestAccept_npc_steward_of_time; newscript->RegisterSelf(); newscript = new Script; @@ -632,6 +632,6 @@ void AddSC_tanaris() newscript = new Script; newscript->Name = "npc_tooga"; newscript->GetAI = &GetAI_npc_tooga; - newscript->pQuestAccept = &QuestAccept_npc_tooga; + newscript->pQuestAcceptNPC = &QuestAccept_npc_tooga; newscript->RegisterSelf(); } diff --git a/scripts/kalimdor/teldrassil.cpp b/scripts/kalimdor/teldrassil.cpp index 3a8efbbfa..0fbdf4684 100644 --- a/scripts/kalimdor/teldrassil.cpp +++ b/scripts/kalimdor/teldrassil.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -108,6 +108,6 @@ void AddSC_teldrassil() newscript = new Script; newscript->Name = "npc_mist"; newscript->GetAI = &GetAI_npc_mist; - newscript->pQuestAccept = &QuestAccept_npc_mist; + newscript->pQuestAcceptNPC = &QuestAccept_npc_mist; newscript->RegisterSelf(); } diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp index ed05f27ed..7457f4a1f 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -254,8 +254,8 @@ struct MANGOS_DLL_DECL boss_yaujAI : public ScriptedAI { if (m_pInstance) { - Creature *pKri = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_KRI)); - Creature *pVem = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_VEM)); + Creature* pKri = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_KRI)); + Creature* pVem = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VEM)); switch(urand(0, 2)) { diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp index 02fc0497a..6611efff1 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -186,11 +186,6 @@ struct MANGOS_DLL_DECL eye_of_cthunAI : public ScriptedAI m_pInstance->SetData(TYPE_CTHUN_PHASE, 0); } - void Aggro(Unit* pWho) - { - m_creature->SetInCombatWithZone(); - } - void SpawnEyeTentacle(float x, float y) { Creature* Spawned; @@ -503,11 +498,6 @@ struct MANGOS_DLL_DECL cthunAI : public ScriptedAI m_pInstance->SetData(TYPE_CTHUN_PHASE, 0); } - void Aggro(Unit* pWho) - { - m_creature->SetInCombatWithZone(); - } - void SpawnEyeTentacle(float x, float y) { Creature* Spawned; @@ -1030,7 +1020,7 @@ struct MANGOS_DLL_DECL claw_tentacleAI : public ScriptedAI return; //EvadeTimer - if (!m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DISTANCE)) + if (!m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) if (EvadeTimer < diff) { if (Creature* pCreature = m_creature->GetMap()->GetCreature(Portal)) @@ -1125,7 +1115,7 @@ struct MANGOS_DLL_DECL giant_claw_tentacleAI : public ScriptedAI return; //EvadeTimer - if (m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) if (EvadeTimer < diff) { if (Creature* pCreature = m_creature->GetMap()->GetCreature(Portal)) diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp index 7ff51e8ee..a0b988561 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp index 655ebfd76..345800856 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp index 39b8a0b91..e9ad59a7b 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -36,10 +36,10 @@ enum SPELL_SUMMON_SCARABS = 26060, SPELL_SUMMON_OURO_MOUND = 26058, SPELL_SUMMON_OURO = 26642, - + SPELL_DIRTMOUND_PASSIVE = 26092, SPELL_SUBMERGE_VISUAL = 26063, - + NPC_OURO_SCARAB = 15718, NPC_OURO_SPAWNER = 15957, NPC_OURO_TRIGGER = 15717 diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp index c60fccdd1..5ee2b3e40 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,254 +16,284 @@ /* ScriptData SDName: Boss_Sartura -SD%Complete: 95 -SDComment: +SD%Complete: 85 +SDComment: Targeting currently doesn't work as expected SDCategory: Temple of Ahn'Qiraj EndScriptData */ #include "precompiled.h" -#define SAY_AGGRO -1531008 -#define SAY_SLAY -1531009 -#define SAY_DEATH -1531010 +enum +{ + SAY_AGGRO = -1531008, + SAY_SLAY = -1531009, + SAY_DEATH = -1531010, -#define SPELL_WHIRLWIND 26083 -#define SPELL_ENRAGE 28747 //Not sure if right ID. -#define SPELL_ENRAGEHARD 28798 + SPELL_WHIRLWIND = 26083, + SPELL_ENRAGE = 28747, // Not sure if right ID. + SPELL_ENRAGEHARD = 28798, -//Guard Spell -#define SPELL_WHIRLWINDADD 26038 -#define SPELL_KNOCKBACK 26027 + // Guard Spell + SPELL_WHIRLWIND_ADD = 26038, + SPELL_KNOCKBACK = 26027, +}; struct MANGOS_DLL_DECL boss_sarturaAI : public ScriptedAI { - boss_sarturaAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_sarturaAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } - uint32 WhirlWind_Timer; - uint32 WhirlWindRandom_Timer; - uint32 WhirlWindEnd_Timer; - uint32 AggroReset_Timer; - uint32 AggroResetEnd_Timer; - uint32 EnrageHard_Timer; + uint32 m_uiWhirlWindTimer; + uint32 m_uiWhirlWindRandomTimer; + uint32 m_uiWhirlWindEndTimer; + uint32 m_uiAggroResetTimer; + uint32 m_uiAggroResetEndTimer; + uint32 m_uiEnrageHardTimer; - bool Enraged; - bool EnragedHard; - bool WhirlWind; - bool AggroReset; + bool m_bIsEnraged; + bool m_bIsEnragedHard; + bool m_bIsWhirlWind; + bool m_bAggroReset; void Reset() { - WhirlWind_Timer = 30000; - WhirlWindRandom_Timer = urand(3000, 7000); - WhirlWindEnd_Timer = 15000; - AggroReset_Timer = urand(45000, 55000); - AggroResetEnd_Timer = 5000; - EnrageHard_Timer = 10*60000; - - WhirlWind = false; - AggroReset = false; - Enraged = false; - EnragedHard = false; - + m_uiWhirlWindTimer = 30000; + m_uiWhirlWindRandomTimer = urand(3000, 7000); + m_uiWhirlWindEndTimer = 15000; + m_uiAggroResetTimer = urand(45000, 55000); + m_uiAggroResetEndTimer = 5000; + m_uiEnrageHardTimer = 10*60000; + + m_bIsWhirlWind = false; + m_bAggroReset = false; + m_bIsEnraged = false; + m_bIsEnragedHard = false; } - void Aggro(Unit *who) + void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); } - void KilledUnit(Unit* victim) + void KilledUnit(Unit* pVictim) { DoScriptText(SAY_SLAY, m_creature); } - void JustDied(Unit* Killer) + void JustDied(Unit* pKiller) { DoScriptText(SAY_DEATH, m_creature); } - - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (WhirlWind) + if (m_bIsWhirlWind) { - if (WhirlWindRandom_Timer < diff) + // While whirlwind, switch to random targets often + if (m_uiWhirlWindRandomTimer < uiDiff) { - //Attack random Gamers - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1); - if (target) - m_creature->AddThreat(target); - m_creature->TauntApply(target); - AttackStart(target); - - WhirlWindRandom_Timer = urand(3000, 7000); - }else WhirlWindRandom_Timer -= diff; - - if (WhirlWindEnd_Timer < diff) - { - WhirlWind = false; - WhirlWind_Timer = urand(25000, 40000); - }else WhirlWindEnd_Timer -= diff; - } + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + m_creature->AddThreat(pTarget); + m_creature->TauntApply(pTarget); + AttackStart(pTarget); + } - if (!WhirlWind) + m_uiWhirlWindRandomTimer = urand(3000, 7000); + } + else + m_uiWhirlWindRandomTimer -= uiDiff; + + // End Whirlwind Phase + if (m_uiWhirlWindEndTimer < uiDiff) + m_bIsWhirlWind = false; + else + m_uiWhirlWindEndTimer -= uiDiff; + } + else // if (!m_bIsWhirlWind) { - if (WhirlWind_Timer < diff) + // Enter Whirlwind Phase + if (m_uiWhirlWindTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_WHIRLWIND); - WhirlWind = true; - WhirlWindEnd_Timer = 15000; - }else WhirlWind_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_WHIRLWIND) == CAST_OK) + { + m_bIsWhirlWind = true; + m_uiWhirlWindEndTimer = 15000; + m_uiWhirlWindTimer = urand(25000, 40000); + } + } + else + m_uiWhirlWindTimer -= uiDiff; - if (AggroReset_Timer < diff) + // Aquire a new target sometimes + if (m_uiAggroResetTimer < uiDiff) { - //Attack random Gamers - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1); - if (target) - m_creature->AddThreat(target); - m_creature->TauntApply(target); - AttackStart(target); - - AggroReset = true; - AggroReset_Timer = urand(2000, 5000); - }else AggroReset_Timer -= diff; - - if (AggroReset) - { - if (AggroResetEnd_Timer SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { - AggroReset = false; - AggroResetEnd_Timer = 5000; - AggroReset_Timer = urand(35000, 45000); - } else AggroResetEnd_Timer -= diff; + m_creature->AddThreat(pTarget); + m_creature->TauntApply(pTarget); + AttackStart(pTarget); + } + + m_bAggroReset = true; + m_uiAggroResetTimer = urand(2000, 5000); } + else + m_uiAggroResetTimer -= uiDiff; - //If she is 20% enrage - if (!Enraged) + // Remove remaining taunts, TODO + if (m_bAggroReset) { - if (m_creature->GetHealthPercent() <= 20.0f && !m_creature->IsNonMeleeSpellCasted(false)) + if (m_uiAggroResetEndTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_ENRAGE); - Enraged = true; + m_bAggroReset = false; + m_uiAggroResetEndTimer = 5000; + m_uiAggroResetTimer = urand(35000, 45000); } + else + m_uiAggroResetEndTimer -= uiDiff; } + } + + // If she is 20% enrage + if (!m_bIsEnraged && m_creature->GetHealthPercent() <= 20.0f) + { + if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE, m_bIsWhirlWind ? CAST_TRIGGERED : 0) == CAST_OK) + m_bIsEnraged = true; + } - //After 10 minutes hard enrage - if (!EnragedHard) + // After 10 minutes hard enrage + if (!m_bIsEnragedHard) + { + if (m_uiEnrageHardTimer < uiDiff) { - if (EnrageHard_Timer < diff) - { - DoCastSpellIfCan(m_creature, SPELL_ENRAGEHARD); - EnragedHard = true; - } else EnrageHard_Timer -= diff; + if (DoCastSpellIfCan(m_creature, SPELL_ENRAGEHARD, m_bIsWhirlWind ? CAST_TRIGGERED : 0) == CAST_OK) + m_bIsEnragedHard = true; } + else + m_uiEnrageHardTimer -= uiDiff; + } + // No melee damage while in whirlwind + if (!m_bIsWhirlWind) DoMeleeAttackIfReady(); - } } }; struct MANGOS_DLL_DECL mob_sartura_royal_guardAI : public ScriptedAI { - mob_sartura_royal_guardAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + mob_sartura_royal_guardAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } - uint32 WhirlWind_Timer; - uint32 WhirlWindRandom_Timer; - uint32 WhirlWindEnd_Timer; - uint32 AggroReset_Timer; - uint32 AggroResetEnd_Timer; - uint32 KnockBack_Timer; + uint32 m_uiWhirlWindTimer; + uint32 m_uiWhirlWindRandomTimer; + uint32 m_uiWhirlWindEndTimer; + uint32 m_uiAggroResetTimer; + uint32 m_uiAggroResetEndTimer; + uint32 m_uiKnockBackTimer; - bool WhirlWind; - bool AggroReset; + bool m_IsWhirlWind; + bool m_bAggroReset; void Reset() { - WhirlWind_Timer = 30000; - WhirlWindRandom_Timer = urand(3000, 7000); - WhirlWindEnd_Timer = 15000; - AggroReset_Timer = urand(45000, 55000); - AggroResetEnd_Timer = 5000; - KnockBack_Timer = 10000; - - WhirlWind = false; - AggroReset = false; - + m_uiWhirlWindTimer = 30000; + m_uiWhirlWindRandomTimer = urand(3000, 7000); + m_uiWhirlWindEndTimer = 15000; + m_uiAggroResetTimer = urand(45000, 55000); + m_uiAggroResetEndTimer = 5000; + m_uiKnockBackTimer = 10000; + + m_IsWhirlWind = false; + m_bAggroReset = false; } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (!WhirlWind && WhirlWind_Timer < diff) + if (m_IsWhirlWind) { - DoCastSpellIfCan(m_creature, SPELL_WHIRLWINDADD); - WhirlWind = true; - WhirlWind_Timer = urand(25000, 40000); - WhirlWindEnd_Timer = 15000; - }else WhirlWind_Timer -= diff; + // While whirlwind, switch to random targets often + if (m_uiWhirlWindRandomTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + m_creature->AddThreat(pTarget); + m_creature->TauntApply(pTarget); + AttackStart(pTarget); + } - if (WhirlWind) + m_uiWhirlWindRandomTimer = urand(3000, 7000); + } + else + m_uiWhirlWindRandomTimer -= uiDiff; + + // End Whirlwind Phase + if (m_uiWhirlWindEndTimer < uiDiff) + m_IsWhirlWind = false; + else + m_uiWhirlWindEndTimer -= uiDiff; + } + else // if (!m_IsWhirlWind) { - if (WhirlWindRandom_Timer < diff) - { - //Attack random Gamers - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1); - if (target) - m_creature->AddThreat(target); - m_creature->TauntApply(target); - AttackStart(target); - - WhirlWindRandom_Timer = urand(3000, 7000); - }else WhirlWindRandom_Timer -= diff; - - if (WhirlWindEnd_Timer < diff) + // Enter Whirlwind Phase + if (m_uiWhirlWindTimer < uiDiff) { - WhirlWind = false; - }else WhirlWindEnd_Timer -= diff; - } + if (DoCastSpellIfCan(m_creature, SPELL_WHIRLWIND_ADD) == CAST_OK) + { + m_IsWhirlWind = true; + m_uiWhirlWindEndTimer = 8000; + m_uiWhirlWindTimer = urand(25000, 40000); + } + } + else + m_uiWhirlWindTimer -= uiDiff; - if (!WhirlWind) - { - if (AggroReset_Timer < diff) + // Aquire a new target sometimes + if (m_uiAggroResetTimer < uiDiff) { - //Attack random Gamers - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1); - if (target) - m_creature->AddThreat(target); - m_creature->TauntApply(target); - AttackStart(target); - - AggroReset = true; - AggroReset_Timer = urand(2000, 5000); - }else AggroReset_Timer -= diff; - - if (KnockBack_Timer < diff) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + m_creature->AddThreat(pTarget); + m_creature->TauntApply(pTarget); + AttackStart(pTarget); + } + + m_bAggroReset = true; + m_uiAggroResetTimer = urand(2000, 5000); + } + else + m_uiAggroResetTimer -= uiDiff; + + // Remove remaining taunts, TODO + if (m_bAggroReset) { - DoCastSpellIfCan(m_creature, SPELL_WHIRLWINDADD); - KnockBack_Timer = urand(10000, 20000); - }else KnockBack_Timer -= diff; - } + if (m_uiAggroResetEndTimer Name = "boss_sartura"; - newscript->GetAI = &GetAI_boss_sartura; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_sartura_royal_guard"; - newscript->GetAI = &GetAI_mob_sartura_royal_guard; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_sartura"; + pNewScript->GetAI = &GetAI_boss_sartura; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_sartura_royal_guard"; + pNewScript->GetAI = &GetAI_mob_sartura_royal_guard; + pNewScript->RegisterSelf(); } diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp index 53762245f..aad80e5d2 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -107,19 +107,34 @@ struct MANGOS_DLL_DECL boss_skeramAI : public ScriptedAI void JustDied(Unit* Killer) { if (!IsImage) + { DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_SKERAM, DONE); + } } void Aggro(Unit *who) { if (IsImage || Images75) return; + switch(urand(0, 2)) { case 0: DoScriptText(SAY_AGGRO1, m_creature); break; case 1: DoScriptText(SAY_AGGRO2, m_creature); break; case 2: DoScriptText(SAY_AGGRO3, m_creature); break; } + + if (m_pInstance) + m_pInstance->SetData(TYPE_SKERAM, IN_PROGRESS); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_SKERAM, FAIL); } void UpdateAI(const uint32 diff) @@ -136,7 +151,7 @@ struct MANGOS_DLL_DECL boss_skeramAI : public ScriptedAI }else ArcaneExplosion_Timer -= diff; //If we are within range melee the target - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { //Make sure our attack is ready and we arn't currently casting if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) @@ -263,11 +278,11 @@ struct MANGOS_DLL_DECL boss_skeramAI : public ScriptedAI Image1->SetMaxHealth(m_creature->GetMaxHealth() / 5); Image1->SetHealth(m_creature->GetHealth() / 5); - if (target) - Image1->AI()->AttackStart(target); - if (boss_skeramAI* pImageAI = dynamic_cast(Image1->AI())) pImageAI->IsImage = true; + + if (target) + Image1->AI()->AttackStart(target); } Image2 = m_creature->SummonCreature(15263,i2->x, i2->y, i2->z, i2->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); @@ -276,11 +291,11 @@ struct MANGOS_DLL_DECL boss_skeramAI : public ScriptedAI Image2->SetMaxHealth(m_creature->GetMaxHealth() / 5); Image2->SetHealth(m_creature->GetHealth() / 5); - if (target) - Image2->AI()->AttackStart(target); - if (boss_skeramAI* pImageAI = dynamic_cast(Image2->AI())) pImageAI->IsImage = true; + + if (target) + Image2->AI()->AttackStart(target); } diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp index 785ef75d4..ea1bcde50 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -96,7 +96,7 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI { if (m_pInstance) { - return m_creature->GetMap()->GetCreature(m_pInstance->GetData64(IAmVeklor() ? DATA_VEKNILASH : DATA_VEKLOR)); + return m_creature->GetMap()->GetCreature(m_pInstance->GetData64(IAmVeklor() ? NPC_VEKNILASH : NPC_VEKLOR)); } else { @@ -135,6 +135,9 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI if (!DontYellWhenDead) // I hope AI is not threaded DoPlaySoundToSet(m_creature, IAmVeklor() ? SOUND_VL_DEATH : SOUND_VN_DEATH); + + if (m_pInstance) + m_pInstance->SetData(TYPE_TWINS, DONE); } void KilledUnit(Unit* victim) @@ -144,8 +147,6 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); - Creature *pOtherBoss = GetOtherBoss(); if (pOtherBoss) { @@ -157,6 +158,15 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI pOtherBoss->AI()->AttackStart(pWho); } } + + if (m_pInstance) + m_pInstance->SetData(TYPE_TWINS, IN_PROGRESS); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_TWINS, DONE); } void SpellHit(Unit *caster, const SpellEntry *entry) @@ -216,7 +226,7 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI { Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); - if (m_creature->IsWithinDistInMap(pUnit, dist)) + if (m_creature->GetCombatDistance(pUnit) < dist) { if (!totallyRandom) return pUnit; @@ -269,7 +279,7 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI Creature *pOtherBoss = GetOtherBoss(); if (pOtherBoss) { - //m_creature->MonsterYell("Teleporting ...", LANG_UNIVERSAL, 0); + //m_creature->MonsterYell("Teleporting ...", LANG_UNIVERSAL); float other_x = pOtherBoss->GetPositionX(); float other_y = pOtherBoss->GetPositionY(); float other_z = pOtherBoss->GetPositionZ(); @@ -487,7 +497,7 @@ struct MANGOS_DLL_DECL boss_veknilashAI : public boss_twinemperorsAI if (UpperCut_Timer < diff) { - Unit* randomMelee = GetAnyoneCloseEnough(ATTACK_DISTANCE, true); + Unit* randomMelee = GetAnyoneCloseEnough(2*ATTACK_DISTANCE, true); if (randomMelee) DoCastSpellIfCan(randomMelee,SPELL_UPPERCUT); UpperCut_Timer = urand(15000, 30000); @@ -586,7 +596,7 @@ struct MANGOS_DLL_DECL boss_veklorAI : public boss_twinemperorsAI if (ArcaneBurst_Timer < diff) { Unit *mvic; - if ((mvic=GetAnyoneCloseEnough(ATTACK_DISTANCE, false))!=NULL) + if ((mvic=GetAnyoneCloseEnough(2*ATTACK_DISTANCE, false))!=NULL) { DoCastSpellIfCan(mvic,SPELL_ARCANEBURST); ArcaneBurst_Timer = 5000; diff --git a/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp index d2e27e609..62a1679b5 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -27,3 +27,7 @@ EndScriptData */ #define SPELL_POISONBOLT_VOLLEY 25991 #define SPELL_TOXIN_CLOUD 25989 + +void AddSC_boss_viscidus() +{ +} diff --git a/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp b/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp index 12c43e956..7a0ea5bdb 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,114 +24,161 @@ EndScriptData */ #include "precompiled.h" #include "temple_of_ahnqiraj.h" -struct MANGOS_DLL_DECL instance_temple_of_ahnqiraj : public ScriptedInstance +instance_temple_of_ahnqiraj::instance_temple_of_ahnqiraj(Map* pMap) : ScriptedInstance(pMap), + m_uiSkeramGUID(0), + m_uiVemGUID(0), + m_uiKriGUID(0), + m_uiVeklorGUID(0), + m_uiVeknilashGUID(0), + m_uiBugTrioDeathCount(0), + m_uiCthunPhase(0), + m_uiSkeramGateGUID(0), + m_uiTwinsEnterDoorGUID(0), + m_uiTwinsExitDoorGUID(0) { - instance_temple_of_ahnqiraj(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + Initialize(); +}; - uint32 m_auiEncounter[MAX_ENCOUNTER]; +void instance_temple_of_ahnqiraj::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - //Storing Skeram, Vem and Kri. - uint64 m_uiSkeramGUID; - uint64 m_uiVemGUID; - uint64 m_uiKriGUID; - uint64 m_uiVeklorGUID; - uint64 m_uiVeknilashGUID; +void instance_temple_of_ahnqiraj::OnCreatureCreate (Creature* pCreature) +{ + switch (pCreature->GetEntry()) + { + case NPC_SKERAM: m_uiSkeramGUID = pCreature->GetGUID(); break; + case NPC_VEM: m_uiVemGUID = pCreature->GetGUID(); break; + case NPC_KRI: m_uiKriGUID = pCreature->GetGUID(); break; + case NPC_VEKLOR: m_uiVeklorGUID = pCreature->GetGUID(); break; + case NPC_VEKNILASH: m_uiVeknilashGUID = pCreature->GetGUID(); break; + } +} - uint32 m_uiBugTrioDeathCount; +void instance_temple_of_ahnqiraj::OnObjectCreate(GameObject* pGo) +{ + switch (pGo->GetEntry()) + { + case GO_SKERAM_GATE: + m_uiSkeramGateGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_SKERAM] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_TWINS_ENTER_DOOR: + m_uiTwinsEnterDoorGUID = pGo->GetGUID(); + break; + case GO_TWINS_EXIT_DOOR: + m_uiTwinsExitDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_TWINS] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + } +} - uint32 m_uiCthunPhase; +bool instance_temple_of_ahnqiraj::IsEncounterInProgress() const +{ + // not active in AQ40 + return false; +} + +void instance_temple_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) + { + case TYPE_SKERAM: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiSkeramGateGUID); + break; + case TYPE_VEM: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_TWINS: + // Either of the twins can set data, so return to avoid double changing + if (m_auiEncounter[uiType] == uiData) + return; + + m_auiEncounter[uiType] = uiData; + DoUseDoorOrButton(m_uiTwinsEnterDoorGUID); + if (uiData == DONE) + DoUseDoorOrButton(m_uiTwinsExitDoorGUID); + break; + + // The following temporarily datas are not to be saved + case DATA_BUG_TRIO_DEATH: + ++m_uiBugTrioDeathCount; + return; + + case TYPE_CTHUN_PHASE: + m_uiCthunPhase = uiData; + return; + } - void Initialize() + if (uiData == DONE) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + OUT_SAVE_INST_DATA; - m_uiSkeramGUID = 0; - m_uiVemGUID = 0; - m_uiKriGUID = 0; - m_uiVeklorGUID = 0; - m_uiVeknilashGUID = 0; + std::ostringstream saveStream; + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2]; - m_uiBugTrioDeathCount = 0; + m_strInstData = saveStream.str(); - m_uiCthunPhase = 0; + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - void OnCreatureCreate (Creature* pCreature) +void instance_temple_of_ahnqiraj::Load(const char* chrIn) +{ + if (!chrIn) { - switch (pCreature->GetEntry()) - { - case 15263: m_uiSkeramGUID = pCreature->GetGUID(); break; - case 15544: m_uiVemGUID = pCreature->GetGUID(); break; - case 15511: m_uiKriGUID = pCreature->GetGUID(); break; - case 15276: m_uiVeklorGUID = pCreature->GetGUID(); break; - case 15275: m_uiVeknilashGUID = pCreature->GetGUID(); break; - } + OUT_LOAD_INST_DATA_FAIL; + return; } - bool IsEncounterInProgress() const - { - //not active in AQ40 - return false; - } + OUT_LOAD_INST_DATA(chrIn); - void SetData(uint32 uiType, uint32 uiData) + std::istringstream loadStream(chrIn); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) { - switch(uiType) - { - case TYPE_VEM: - m_auiEncounter[0] = uiData; - break; - case TYPE_VEKLOR: - m_auiEncounter[1] = uiData; - break; - case TYPE_VEKNILASH: - m_auiEncounter[2] = uiData; - break; - - case DATA_BUG_TRIO_DEATH: - ++m_uiBugTrioDeathCount; - break; - - case TYPE_CTHUN_PHASE: - m_uiCthunPhase = uiData; - break; - } + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; } - uint32 GetData(uint32 uiType) + OUT_LOAD_INST_DATA_COMPLETE; +} + +uint32 instance_temple_of_ahnqiraj::GetData(uint32 uiType) +{ + switch(uiType) { - switch(uiType) - { - case TYPE_VEM: - return m_auiEncounter[0]; - - case DATA_BUG_TRIO_DEATH: - return m_uiBugTrioDeathCount; - - case TYPE_CTHUN_PHASE: - return m_uiCthunPhase; - } - return 0; + case TYPE_VEM: + return m_auiEncounter[0]; + case DATA_BUG_TRIO_DEATH: + return m_uiBugTrioDeathCount; + case TYPE_CTHUN_PHASE: + return m_uiCthunPhase; + default: + return 0; } +} - uint64 GetData64(uint32 uiData) +uint64 instance_temple_of_ahnqiraj::GetData64(uint32 uiData) +{ + switch(uiData) { - switch(uiData) - { - case DATA_SKERAM: - return m_uiSkeramGUID; - case DATA_VEM: - return m_uiVemGUID; - case DATA_KRI: - return m_uiKriGUID; - case DATA_VEKLOR: - return m_uiVeklorGUID; - case DATA_VEKNILASH: - return m_uiVeknilashGUID; - } - return 0; + case NPC_SKERAM: return m_uiSkeramGUID; + case NPC_VEM: return m_uiVemGUID; + case NPC_KRI: return m_uiKriGUID; + case NPC_VEKLOR: return m_uiVeklorGUID; + case NPC_VEKNILASH: return m_uiVeknilashGUID; + default: + return 0; } -}; +} InstanceData* GetInstanceData_instance_temple_of_ahnqiraj(Map* pMap) { @@ -140,9 +187,10 @@ InstanceData* GetInstanceData_instance_temple_of_ahnqiraj(Map* pMap) void AddSC_instance_temple_of_ahnqiraj() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_temple_of_ahnqiraj"; - newscript->GetInstanceData = &GetInstanceData_instance_temple_of_ahnqiraj; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_temple_of_ahnqiraj"; + pNewScript->GetInstanceData = &GetInstanceData_instance_temple_of_ahnqiraj; + pNewScript->RegisterSelf(); } diff --git a/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp b/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp index d10c9bbb2..416bbe9d7 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h b/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h index c9c93e1c9..d6fe5c9a3 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h +++ b/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -9,19 +9,63 @@ enum { MAX_ENCOUNTER = 3, + TYPE_SKERAM = 0, TYPE_VEM = 1, - TYPE_VEKLOR = 2, - TYPE_VEKNILASH = 3, + TYPE_TWINS = 2, - DATA_SKERAM = 5, - DATA_KRI = 6, - DATA_VEM = 7, - DATA_VEKLOR = 8, - DATA_VEKNILASH = 9, + NPC_SKERAM = 15263, + NPC_KRI = 15511, + NPC_VEM = 15544, + NPC_VEKLOR = 15276, + NPC_VEKNILASH = 15275, + + GO_SKERAM_GATE = 180636, + GO_TWINS_ENTER_DOOR = 180634, + GO_TWINS_EXIT_DOOR = 180635, DATA_BUG_TRIO_DEATH = 10, TYPE_CTHUN_PHASE = 20 }; +class MANGOS_DLL_DECL instance_temple_of_ahnqiraj : public ScriptedInstance +{ + public: + instance_temple_of_ahnqiraj(Map* pMap); + + void Initialize(); + + bool IsEncounterInProgress() const; + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + private: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + // Storing Skeram, Vem and Kri. + uint64 m_uiSkeramGUID; + uint64 m_uiVemGUID; + uint64 m_uiKriGUID; + uint64 m_uiVeklorGUID; + uint64 m_uiVeknilashGUID; + + // Doors + uint64 m_uiSkeramGateGUID; + uint64 m_uiTwinsEnterDoorGUID; + uint64 m_uiTwinsExitDoorGUID; + + uint32 m_uiBugTrioDeathCount; + + uint32 m_uiCthunPhase; +}; + #endif diff --git a/scripts/kalimdor/the_barrens.cpp b/scripts/kalimdor/the_barrens.cpp index 2fea2accf..2f72d68d0 100644 --- a/scripts/kalimdor/the_barrens.cpp +++ b/scripts/kalimdor/the_barrens.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -467,15 +467,14 @@ CreatureAI* GetAI_npc_twiggy_flathead(Creature* pCreature) bool AreaTrigger_at_twiggy_flathead(Player* pPlayer, AreaTriggerEntry const* pAt) { - if (!pPlayer->isDead() && pPlayer->GetQuestStatus(QUEST_AFFRAY) == QUEST_STATUS_INCOMPLETE) - { - if (uint16 slot = pPlayer->FindQuestSlot(QUEST_AFFRAY)) - { - //we don't want player to start event if failed already. - if (pPlayer->GetQuestSlotState(slot) == QUEST_STATE_FAIL) - return true; - } + if (pPlayer->GetQuestStatus(QUEST_AFFRAY) == QUEST_STATUS_FAILED) + { + //we don't want player to start event if failed already. + return true; + } + else if (!pPlayer->isDead() && pPlayer->GetQuestStatus(QUEST_AFFRAY) == QUEST_STATUS_INCOMPLETE) + { Creature* pCreature = GetClosestCreatureWithEntry(pPlayer, NPC_TWIGGY, 30.0f); if (!pCreature) @@ -662,7 +661,7 @@ void AddSC_the_barrens() newscript = new Script; newscript->Name = "npc_gilthares"; newscript->GetAI = &GetAI_npc_gilthares; - newscript->pQuestAccept = &QuestAccept_npc_gilthares; + newscript->pQuestAcceptNPC = &QuestAccept_npc_gilthares; newscript->RegisterSelf(); newscript = new Script; @@ -689,6 +688,6 @@ void AddSC_the_barrens() newscript = new Script; newscript->Name = "npc_wizzlecranks_shredder"; newscript->GetAI = &GetAI_npc_wizzlecranks_shredder; - newscript->pQuestAccept = &QuestAccept_npc_wizzlecranks_shredder; + newscript->pQuestAcceptNPC = &QuestAccept_npc_wizzlecranks_shredder; newscript->RegisterSelf(); } diff --git a/scripts/kalimdor/thousand_needles.cpp b/scripts/kalimdor/thousand_needles.cpp index 648b9a3d0..079a13e97 100644 --- a/scripts/kalimdor/thousand_needles.cpp +++ b/scripts/kalimdor/thousand_needles.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -374,19 +374,19 @@ void AddSC_thousand_needles() newscript = new Script; newscript->Name = "npc_kanati"; newscript->GetAI = &GetAI_npc_kanati; - newscript->pQuestAccept = &QuestAccept_npc_kanati; + newscript->pQuestAcceptNPC = &QuestAccept_npc_kanati; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_lakota_windsong"; newscript->GetAI = &GetAI_npc_lakota_windsong; - newscript->pQuestAccept = &QuestAccept_npc_lakota_windsong; + newscript->pQuestAcceptNPC = &QuestAccept_npc_lakota_windsong; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_paoka_swiftmountain"; newscript->GetAI = &GetAI_npc_paoka_swiftmountain; - newscript->pQuestAccept = &QuestAccept_npc_paoka_swiftmountain; + newscript->pQuestAcceptNPC = &QuestAccept_npc_paoka_swiftmountain; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/kalimdor/thunder_bluff.cpp b/scripts/kalimdor/thunder_bluff.cpp index 5f5168221..c4b515f3c 100644 --- a/scripts/kalimdor/thunder_bluff.cpp +++ b/scripts/kalimdor/thunder_bluff.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/ungoro_crater.cpp b/scripts/kalimdor/ungoro_crater.cpp index 3f3c86a2d..3963e53ac 100644 --- a/scripts/kalimdor/ungoro_crater.cpp +++ b/scripts/kalimdor/ungoro_crater.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -334,12 +334,12 @@ void AddSC_ungoro_crater() pNewScript = new Script; pNewScript->Name = "npc_ame01"; pNewScript->GetAI = &GetAI_npc_ame01; - pNewScript->pQuestAccept = &QuestAccept_npc_ame01; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_ame01; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_ringo"; pNewScript->GetAI = &GetAI_npc_ringo; - pNewScript->pQuestAccept = &QuestAccept_npc_ringo; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_ringo; pNewScript->RegisterSelf(); } diff --git a/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp b/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp index 41e16de76..b6907a75a 100644 --- a/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp +++ b/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: Instance_Wailing_Caverns SD%Complete: 90 -SDComment: +SDComment: SDCategory: Wailing Caverns EndScriptData */ @@ -25,7 +25,8 @@ EndScriptData */ #include "wailing_caverns.h" instance_wailing_caverns::instance_wailing_caverns(Map* pMap) : ScriptedInstance(pMap), - m_uiNaralexGUID(0) + m_uiNaralexGUID(0), + m_uiDiscipleGUID(0) { Initialize(); } @@ -39,7 +40,8 @@ void instance_wailing_caverns::OnCreatureCreate(Creature* pCreature) { switch (pCreature->GetEntry()) { - case NPC_NARLEX: m_uiNaralexGUID = pCreature->GetGUID(); break; + case NPC_NARALEX: m_uiNaralexGUID = pCreature->GetGUID(); break; + case NPC_DISCIPLE: m_uiDiscipleGUID = pCreature->GetGUID(); break; } } @@ -62,13 +64,23 @@ void instance_wailing_caverns::SetData(uint32 uiType, uint32 uiData) case TYPE_DISCIPLE: m_auiEncounter[4] = uiData; break; - case TYPE_MUTANOUS: + case TYPE_MUTANUS: m_auiEncounter[5] = uiData; break; } - if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE && m_auiEncounter[3] == DONE && m_auiEncounter[4] == NOT_STARTED) + // Set to special in order to start the escort event; only if all four bosses are done + if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE && m_auiEncounter[3] == DONE && (m_auiEncounter[4] == NOT_STARTED || m_auiEncounter[4] == FAIL)) + { + // Yell intro text; only the first time + if (m_auiEncounter[4] == NOT_STARTED) + { + if (Creature* pDisciple = instance->GetCreature(m_uiDiscipleGUID)) + DoScriptText(SAY_INTRO, pDisciple); + } + m_auiEncounter[4] = SPECIAL; + } if (uiData == DONE) { @@ -117,7 +129,7 @@ uint32 instance_wailing_caverns::GetData(uint32 uiType) case TYPE_PYTHAS: return m_auiEncounter[2]; break; case TYPE_SERPENTIS: return m_auiEncounter[3]; break; case TYPE_DISCIPLE: return m_auiEncounter[4]; break; - case TYPE_MUTANOUS: return m_auiEncounter[5]; break; + case TYPE_MUTANUS: return m_auiEncounter[5]; break; } return 0; } @@ -126,7 +138,7 @@ uint64 instance_wailing_caverns::GetData64(uint32 uiData) { switch (uiData) { - case DATA_NARALEX: return m_uiNaralexGUID; + case NPC_NARALEX: return m_uiNaralexGUID; } return 0; } diff --git a/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp b/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp new file mode 100644 index 000000000..6c68a5803 --- /dev/null +++ b/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp @@ -0,0 +1,498 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: wailing_caverns +SD%Complete: 90 +SDComment: Missing vipers emerge effect, Naralex doesn't fly at exit(Core issue) +SDCategory: Wailing Caverns +EndScriptData */ + +#include "precompiled.h" +#include "wailing_caverns.h" +#include "escort_ai.h" + +enum +{ + SAY_PREPARE = -1043001, + SAY_FIRST_CORNER = -1043002, + SAY_CONTINUE = -1043003, + SAY_CIRCLE_BANISH = -1043004, + SAY_PURIFIED = -1043005, + SAY_NARALEX_CHAMBER = -1043006, + SAY_BEGIN_RITUAL = -1043007, + SAY_MUTANUS = -1043012, + SAY_NARALEX_AWAKE = -1043013, + SAY_AWAKE = -1043014, + SAY_NARALEX_THANKYOU = -1043015, + SAY_FAREWELL = -1043016, + SAY_AGGRO_1 = -1043017, // Random between the first 2 + SAY_AGGRO_2 = -1043018, + SAY_AGGRO_3 = -1043019, // During the awakening ritual + + EMOTE_RITUAL_BEGIN = -1043008, + EMOTE_NARALEX_AWAKE = -1043009, + EMOTE_BREAK_THROUGH = -1043010, + EMOTE_VISION = -1043011, + + GOSSIP_ITEM_BEGIN = -3043000, + TEXT_ID_DISCIPLE = 698, + + SPELL_MARK = 5232, // Buff before the fight. To be removed after 4.0.3 + SPELL_SLEEP = 1090, + SPELL_POTION = 8141, + SPELL_CLEANSING = 6270, + SPELL_AWAKENING = 6271, + SPELL_SHAPESHIFT = 8153, + + NPC_DEVIATE_RAPTOR = 3636, // 2 of them at the first stop + NPC_DEVIATE_VIPER = 5755, // 3 of them at the circle + NPC_DEVIATE_MOCCASIN = 5762, // 6 of them at Naralex chamber + NPC_NIGHTMARE_ECTOPLASM = 5763, // 10 of them at Naralex chamber + NPC_MUTANUS = 3654 +}; + +// Distance, Angle or Offset +static const float aSummonPositions[5][2] = +{ + {50.0f, -0.507f}, // First Raptors + {53.0f, -0.603f}, + { 7.0f, 1.73f}, // Vipers + {45.0f, 5.16f}, // Chamber + {47.0f, 0.5901f} // Mutanus +}; + +struct MANGOS_DLL_DECL npc_disciple_of_naralexAI : public npc_escortAI +{ + npc_disciple_of_naralexAI(Creature* pCreature) : npc_escortAI(pCreature) + { + m_pInstance = (instance_wailing_caverns*)pCreature->GetInstanceData(); + Reset(); + } + + instance_wailing_caverns* m_pInstance; + + uint32 m_uiEventTimer; + uint32 m_uiSleepTimer; + uint32 m_uiPotionTimer; + uint32 m_uiCleansingTimer; + uint8 m_uiSummonedAlive; + bool m_bIsFirstHit; + + uint32 m_uiPoint; + uint8 m_uiSubeventPhase; + + void Reset() + { + m_uiSleepTimer = 5000; + m_uiPotionTimer = 5000; + m_uiCleansingTimer = 0; + m_bIsFirstHit = false; // Used to trigger the combat yell; reset at every evade + + // Don't reset mob counter during the event + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + m_uiEventTimer = 0; + + m_uiPoint = 0; + m_uiSubeventPhase = 0; + + m_uiSummonedAlive = 0; + } + } + + void JustRespawned() + { + npc_escortAI::JustRespawned(); + + // Reset event if can + if (m_pInstance && m_pInstance->GetData(TYPE_DISCIPLE) != DONE) + m_pInstance->SetData(TYPE_DISCIPLE, FAIL); + } + + void AttackedBy(Unit* pAttacker) + { + if (!m_bIsFirstHit) + { + if (pAttacker->GetEntry() == NPC_MUTANUS) + DoScriptText(SAY_MUTANUS, m_creature, pAttacker); + // Check if already in ritual + else if (m_uiPoint >= 30) + DoScriptText(SAY_AGGRO_3, m_creature, pAttacker); + else + // Aggro 1 should be in 90% of the cases + DoScriptText(roll_chance_i(90) ? SAY_AGGRO_1 : SAY_AGGRO_2, m_creature, pAttacker); + + m_bIsFirstHit = true; + } + } + + // Overwrite the evade function, to change the combat stop function (keep casting some spells) + void EnterEvadeMode() + { + // Do not stop casting at these points + if (m_uiPoint == 15 || m_uiPoint == 32) + { + m_creature->SetLootRecipient(NULL); + m_creature->DeleteThreatList(); + m_creature->CombatStop(false); + Reset(); + + // Remove running + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + else + npc_escortAI::EnterEvadeMode(); + } + + void JustStartedEscort() + { + DoScriptText(SAY_PREPARE, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_DISCIPLE, IN_PROGRESS); + } + + void WaypointReached(uint32 uiPointId) + { + switch (uiPointId) + { + case 7: + DoScriptText(SAY_FIRST_CORNER, m_creature); + m_uiSubeventPhase = 0; + m_uiEventTimer = 2000; + m_uiPoint = uiPointId; + SetEscortPaused(true); + break; + case 15: + m_uiSubeventPhase = 0; + m_uiEventTimer = 2000; + m_uiPoint = uiPointId; + SetEscortPaused(true); + break; + case 26: + DoScriptText(SAY_NARALEX_CHAMBER, m_creature); + break; + case 32: + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + m_creature->SetFacingToObject(pNaralex); + + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + m_uiEventTimer = 2000; + m_uiSubeventPhase = 0; + m_uiPoint = uiPointId; + SetEscortPaused(true); + break; + } + } + + void JustSummoned(Creature* pSummoned) + { + // Attack the disciple + pSummoned->AI()->AttackStart(m_creature); + + ++m_uiSummonedAlive; + } + + void SummonedCreatureJustDied(Creature* pSummoned) + { + if (m_uiSummonedAlive == 0) + return; // Actually if this happens, something went wrong before + + --m_uiSummonedAlive; + + // Continue Event if all are dead and we are in a stopped subevent + if (m_uiSummonedAlive == 0 && m_uiEventTimer == 0) + m_uiEventTimer = 1000; + } + + // Summon mobs at calculated points + void DoSpawnMob(uint32 uiEntry, float fDistance, float fAngle) + { + float fX, fY, fZ; + m_creature->GetNearPoint(m_creature, fX, fY, fZ, 0, fDistance, fAngle); + + m_creature->SummonCreature(uiEntry, fX, fY, fZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); + } + + void UpdateEscortAI(const uint32 uiDiff) + { + if (m_uiEventTimer) + { + if (m_uiEventTimer <= uiDiff) + { + switch (m_uiPoint) + { + // Corner stop -> raptors + case 7: + switch (m_uiSubeventPhase) + { + case 0: + // Summon raptors at first stop + DoSpawnMob(NPC_DEVIATE_RAPTOR, aSummonPositions[0][0], aSummonPositions[0][1]); + DoSpawnMob(NPC_DEVIATE_RAPTOR, aSummonPositions[1][0], aSummonPositions[1][1]); + m_uiEventTimer = 0; + ++m_uiSubeventPhase; + break; + case 1: + // After the summoned mobs are killed continue + DoScriptText(SAY_CONTINUE, m_creature); + SetEscortPaused(false); + m_uiEventTimer = 0; + break; + } + break; + // Circle stop -> vipers + case 15: + switch (m_uiSubeventPhase) + { + case 0: + DoScriptText(SAY_CIRCLE_BANISH, m_creature); + m_uiEventTimer = 2000; + ++m_uiSubeventPhase; + break; + case 1: + DoCastSpellIfCan(m_creature, SPELL_CLEANSING); + m_uiEventTimer = 20000; + ++m_uiSubeventPhase; + break; + case 2: + // Summon vipers at the first circle + for (uint8 i = 0; i < 3; ++i) + DoSpawnMob(NPC_DEVIATE_VIPER, aSummonPositions[2][0], aSummonPositions[2][1] + 2*M_PI_F/3 * i); + m_uiEventTimer = 0; + ++m_uiSubeventPhase; + break; + case 3: + // Wait for casting to be complete - TODO, this might have to be done better + ++m_uiSubeventPhase; + m_uiEventTimer = 10000; + break; + case 4: + DoScriptText(SAY_PURIFIED, m_creature); + m_uiEventTimer = 0; + ++m_uiPoint; // Increment this in order to avoid the special case evade + SetEscortPaused(false); + break; + } + break; + // Chamber stop -> ritual and final boss + case 32: + switch (m_uiSubeventPhase) + { + case 0: + DoScriptText(SAY_BEGIN_RITUAL, m_creature); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_uiEventTimer = 2000; + ++m_uiSubeventPhase; + break; + case 1: + DoCastSpellIfCan(m_creature, SPELL_AWAKENING); + DoScriptText(EMOTE_RITUAL_BEGIN, m_creature); + m_uiEventTimer = 4000; + ++m_uiSubeventPhase; + break; + case 2: + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + DoScriptText(EMOTE_NARALEX_AWAKE, pNaralex); + m_uiEventTimer = 5000; + ++m_uiSubeventPhase; + break; + case 3: + // First set of mobs + for (uint8 i = 0; i < 3; ++i) + DoSpawnMob(NPC_DEVIATE_MOCCASIN, aSummonPositions[3][0], aSummonPositions[3][1] + M_PI_F /3 * i); + m_uiEventTimer = 20000; + ++m_uiSubeventPhase; + break; + case 4: + // Second set of mobs + for (uint8 i = 0; i < 7; ++i) + DoSpawnMob(NPC_NIGHTMARE_ECTOPLASM, aSummonPositions[3][0], aSummonPositions[3][1] + M_PI_F /7 * i); + m_uiEventTimer = 0; + ++m_uiSubeventPhase; + break; + case 5: + // Advance only when all mobs are dead + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + DoScriptText(EMOTE_BREAK_THROUGH, pNaralex); + ++m_uiSubeventPhase; + m_uiEventTimer = 10000; + break; + case 6: + // Mutanus + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + DoScriptText(EMOTE_VISION, pNaralex); + DoSpawnMob(NPC_MUTANUS, aSummonPositions[4][0], aSummonPositions[4][1]); + m_uiEventTimer = 0; + ++m_uiSubeventPhase; + break; + case 7: + // Awaken Naralex after mutanus is defeated + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + { + pNaralex->SetStandState(UNIT_STAND_STATE_SIT); + DoScriptText(SAY_NARALEX_AWAKE, pNaralex); + } + m_creature->InterruptNonMeleeSpells(false, SPELL_AWAKENING); + m_creature->RemoveAurasDueToSpell(SPELL_AWAKENING); + m_pInstance->SetData(TYPE_DISCIPLE, DONE); + ++m_uiSubeventPhase; + m_uiEventTimer = 2000; + break; + case 8: + DoScriptText(SAY_AWAKE, m_creature); + m_uiEventTimer = 5000; + ++m_uiSubeventPhase; + break; + case 9: + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + { + DoScriptText(SAY_NARALEX_THANKYOU, pNaralex); + pNaralex->SetStandState(UNIT_STAND_STATE_STAND); + } + m_uiEventTimer = 10000; + ++m_uiSubeventPhase; + break; + case 10: + // Shapeshift into a bird + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + { + DoScriptText(SAY_FAREWELL, pNaralex); + pNaralex->CastSpell(pNaralex, SPELL_SHAPESHIFT, false); + } + DoCastSpellIfCan(m_creature, SPELL_SHAPESHIFT); + m_uiEventTimer = 10000; + ++m_uiSubeventPhase; + break; + case 11: + SetEscortPaused(false); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + SetRun(); + // Send them flying somewhere outside of the room + if (Creature* pNaralex = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_NARALEX))) + { + // ToDo: Make Naralex fly + // sort of a hack, compare to boss_onyxia + pNaralex->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + + // Set to flying + pNaralex->AddSplineFlag(SPLINEFLAG_FLYING); + pNaralex->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + + // Set following + pNaralex->GetMotionMaster()->MoveFollow(m_creature, 5.0f, 0); + // Despawn after some time + pNaralex->ForcedDespawn(30000); + } + m_uiEventTimer = 0; + break; + } + break; + } + } + else + m_uiEventTimer -= uiDiff; + } + + if (m_uiPotionTimer < uiDiff) + { + // if health lower than 80%, cast heal + if (m_creature->GetHealthPercent() < 80.0f) + { + if (DoCastSpellIfCan(m_creature, SPELL_POTION) == CAST_OK) + m_uiPotionTimer = 45000; + } + else + m_uiPotionTimer = 5000; + } + else + m_uiPotionTimer -= uiDiff; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSleepTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + if (DoCastSpellIfCan(pTarget, SPELL_SLEEP) == CAST_OK) + m_uiSleepTimer = 30000; + } + } + else + m_uiSleepTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +bool GossipHello_npc_disciple_of_naralex(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + + if (pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + + // Buff the players + pCreature->CastSpell(pPlayer, SPELL_MARK, false); + + if (m_pInstance && m_pInstance->GetData(TYPE_DISCIPLE) == SPECIAL) + { + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + pPlayer->SEND_GOSSIP_MENU(TEXT_ID_DISCIPLE, pCreature->GetGUID()); + } + else + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_disciple_of_naralex(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + + if (!m_pInstance) + return false; + + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + if (npc_disciple_of_naralexAI* pEscortAI = dynamic_cast(pCreature->AI())) + { + pEscortAI->Start(false, pPlayer->GetGUID()); // Note: after 4.0.3 set him run = true + pCreature->setFaction(FACTION_ESCORT_N_ACTIVE); + } + pPlayer->CLOSE_GOSSIP_MENU(); + } + return true; +} + +CreatureAI* GetAI_npc_disciple_of_naralex(Creature* pCreature) +{ + return new npc_disciple_of_naralexAI(pCreature); +} + +void AddSC_wailing_caverns() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "npc_disciple_of_naralex"; + pNewScript->GetAI = &GetAI_npc_disciple_of_naralex; + pNewScript->pGossipHello = &GossipHello_npc_disciple_of_naralex; + pNewScript->pGossipSelect = &GossipSelect_npc_disciple_of_naralex; + pNewScript->RegisterSelf(); +} diff --git a/scripts/kalimdor/wailing_caverns/wailing_caverns.h b/scripts/kalimdor/wailing_caverns/wailing_caverns.h index 04093f7d8..99d317990 100644 --- a/scripts/kalimdor/wailing_caverns/wailing_caverns.h +++ b/scripts/kalimdor/wailing_caverns/wailing_caverns.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,18 +7,18 @@ enum { - MAX_ENCOUNTER = 6, - - TYPE_ANACONDRA = 0, - TYPE_COBRAHN = 1, - TYPE_PYTHAS = 2, - TYPE_SERPENTIS = 3, - TYPE_DISCIPLE = 4, - TYPE_MUTANOUS = 5, - - DATA_NARALEX = 6, - - NPC_NARLEX = 3679 + MAX_ENCOUNTER = 6, + + TYPE_ANACONDRA = 0, + TYPE_COBRAHN = 1, + TYPE_PYTHAS = 2, + TYPE_SERPENTIS = 3, + TYPE_DISCIPLE = 4, + TYPE_MUTANUS = 5, + + NPC_NARALEX = 3679, + NPC_DISCIPLE = 3678, + SAY_INTRO = -1043000, // Say when the first 4 encounter are DONE }; class MANGOS_DLL_DECL instance_wailing_caverns : public ScriptedInstance @@ -43,5 +43,6 @@ class MANGOS_DLL_DECL instance_wailing_caverns : public ScriptedInstance std::string strInstData; uint64 m_uiNaralexGUID; + uint64 m_uiDiscipleGUID; }; #endif diff --git a/scripts/kalimdor/winterspring.cpp b/scripts/kalimdor/winterspring.cpp index 56cf8c4b1..a83ef3220 100644 --- a/scripts/kalimdor/winterspring.cpp +++ b/scripts/kalimdor/winterspring.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/zulfarrak/boss_zumrah.cpp b/scripts/kalimdor/zulfarrak/boss_zumrah.cpp index bef247fd4..1fecb127d 100644 --- a/scripts/kalimdor/zulfarrak/boss_zumrah.cpp +++ b/scripts/kalimdor/zulfarrak/boss_zumrah.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,3 +22,7 @@ SDCategory: Zul'Farrak EndScriptData */ #include "precompiled.h" + +void AddSC_boss_zumrah() +{ +} diff --git a/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp b/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp index 11902defa..d699b93ad 100644 --- a/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp +++ b/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/zulfarrak/zulfarrak.cpp b/scripts/kalimdor/zulfarrak/zulfarrak.cpp index fea9cb1d3..f573d5c1c 100644 --- a/scripts/kalimdor/zulfarrak/zulfarrak.cpp +++ b/scripts/kalimdor/zulfarrak/zulfarrak.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/kalimdor/zulfarrak/zulfarrak.h b/scripts/kalimdor/zulfarrak/zulfarrak.h index 653a326f1..486344f8e 100644 --- a/scripts/kalimdor/zulfarrak/zulfarrak.h +++ b/scripts/kalimdor/zulfarrak/zulfarrak.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/northrend/azjol-nerub/ahnkahet/ahnkahet.h b/scripts/northrend/azjol-nerub/ahnkahet/ahnkahet.h index 23f326c9c..50da6a9a8 100644 --- a/scripts/northrend/azjol-nerub/ahnkahet/ahnkahet.h +++ b/scripts/northrend/azjol-nerub/ahnkahet/ahnkahet.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -27,7 +27,8 @@ enum GO_VORTEX = 193564, NPC_ELDER_NADOX = 29309, - NPC_JEDOGA_SHADOWSEEKER = 29310 + NPC_TALDARAM = 29308, + NPC_JEDOGA_SHADOWSEEKER = 29310, }; #endif diff --git a/scripts/northrend/azjol-nerub/ahnkahet/boss_amanitar.cpp b/scripts/northrend/azjol-nerub/ahnkahet/boss_amanitar.cpp new file mode 100644 index 000000000..ceaf907bc --- /dev/null +++ b/scripts/northrend/azjol-nerub/ahnkahet/boss_amanitar.cpp @@ -0,0 +1,270 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Boss_Amanitar +SD%Complete: 80% +SDComment: Timers +SDAuthor: Tassadar +SDCategory: Ahn'kahet +EndScriptData */ + +#include "precompiled.h" +#include "ahnkahet.h" + +enum +{ + //Amanitar spells + SPELL_BASH = 57094, + SPELL_VENOM_BOLT = 57088, + SPELL_ENTANGLING_ROOTS = 57095, + SPELL_MINI = 57055, // this one and SPELL_POTENT_FUNGUS MUST stack! + + //Mushroom spells + SPELL_POISON_CLOUD = 57061, + SPELL_POISONOUS_MUSHROOM_VISUAL = 56741, + SPELL_POTENT_FUNGUS = 56648, // this one and SPELL_MINI MUST stack! + SPELL_PUTRID_MUSHROOM = 31690, // They should look like mushroom + + //Script thinks that all mushrooms which are spawned are only healthy, so change entry only for poisinous + NPC_HEALTHY_MUSHROOM = 30391, + NPC_POISONOUS_MUSHROOM = 30435, +}; +/*###### +## boss_amanitar +######*/ + +struct MANGOS_DLL_DECL boss_amanitarAI : public ScriptedAI +{ + boss_amanitarAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiBashTimer; + uint32 m_uiVenomBoltTimer; + uint32 m_uiRootsTimer; + uint32 m_uiMiniTimer; + + + void Reset() + { + m_uiBashTimer = 8000; + m_uiVenomBoltTimer = 12000; + m_uiRootsTimer = 19000; + m_uiMiniTimer = 30000; + m_creature->SetRespawnDelay(DAY); + + if (m_pInstance) + m_pInstance->SetData(TYPE_AMANITAR, NOT_STARTED); + } + + void Aggro(Unit* pWho) + { + ShowMushrooms(); + + if(m_bIsRegularMode == true) + m_creature->ForcedDespawn(); + + m_pInstance->SetData(TYPE_AMANITAR, IN_PROGRESS); + } + void EnterEvadeMode() + { + ShowMushrooms(false); + if (m_pInstance) + m_pInstance->SetData(TYPE_AMANITAR, FAIL); + + m_creature->GetMotionMaster()->MoveTargetedHome(); + } + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_AMANITAR, DONE); + } + void ShowMushrooms(bool show = true) + { + std::list lMushroomsHealthy; + GetCreatureListWithEntryInGrid(lMushroomsHealthy, m_creature, NPC_HEALTHY_MUSHROOM, 150.0f); + for(std::list::iterator itr1 = lMushroomsHealthy.begin(); itr1 != lMushroomsHealthy.end(); ++itr1) + { + if(show) + (*itr1)->SetVisibility(VISIBILITY_ON); + else + (*itr1)->SetVisibility(VISIBILITY_OFF); + } + std::list lMushroomsPoison; + GetCreatureListWithEntryInGrid(lMushroomsPoison, m_creature, NPC_POISONOUS_MUSHROOM, 150.0f); + for(std::list::iterator itr2 = lMushroomsPoison.begin(); itr2 != lMushroomsPoison.end(); ++itr2) + { + if(show) + (*itr2)->SetVisibility(VISIBILITY_ON); + else + (*itr2)->SetVisibility(VISIBILITY_OFF); + } + } + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + //Bash + if(m_uiBashTimer <= uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_BASH); + m_uiBashTimer = 8000 + rand()%5000; + }else m_uiBashTimer -= uiDiff; + + //Venom bolt volley + if(m_uiVenomBoltTimer <= uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), SPELL_VENOM_BOLT); + m_uiVenomBoltTimer = 15000 + rand()%5000; + }else m_uiVenomBoltTimer -= uiDiff; + + //Entangling Roots + if(m_uiRootsTimer <= uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), SPELL_ENTANGLING_ROOTS); + m_uiRootsTimer = 18000 + rand()%5000; + }else m_uiRootsTimer -= uiDiff; + + //Mini + if(m_uiMiniTimer <= uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), SPELL_MINI); + m_uiMiniTimer = 30000; + }else m_uiMiniTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_amanitar(Creature* pCreature) +{ + return new boss_amanitarAI(pCreature); +} +/*###### +## npc_amanitar_mushroom +######*/ + +struct MANGOS_DLL_DECL npc_amanitar_mushroomAI : public ScriptedAI +{ + npc_amanitar_mushroomAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint8 m_uiMushroomType; //0 = healthy, 1 = poisinous + bool m_bIsDead; + uint32 m_uiRespawnTimer; + + void Reset() + { + m_bIsDead = false; + m_uiRespawnTimer = 30000; + + DoCast(m_creature,SPELL_PUTRID_MUSHROOM,true); + m_creature->SetVisibility(VISIBILITY_OFF); + + ResetMushroom(); + } + void ResetMushroom() + { + m_uiMushroomType = urand(0, 1); + if(m_uiMushroomType == 1) + { + m_creature->UpdateEntry(NPC_POISONOUS_MUSHROOM); + m_creature->CastSpell(m_creature, SPELL_POISONOUS_MUSHROOM_VISUAL, true); + }else{ + m_creature->RemoveAurasDueToSpell(SPELL_POISONOUS_MUSHROOM_VISUAL); + m_creature->UpdateEntry(NPC_HEALTHY_MUSHROOM); + } + DoCast(m_creature,SPELL_PUTRID_MUSHROOM,true); + if(m_bIsDead) + m_creature->SetVisibility(VISIBILITY_OFF); + } + void AttackStart(Unit *pWho) + { + return; + } + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (m_bIsDead) + { + uiDamage = 0; + return; + } + + if (uiDamage > m_creature->GetHealth()) + { + m_bIsDead = true; + uiDamage = 0; + if(m_uiMushroomType == 0) + m_creature->CastSpell(m_creature, SPELL_POTENT_FUNGUS, true); + else + m_creature->CastSpell(m_creature, SPELL_POISON_CLOUD, true); + + m_creature->SetHealth(1); + m_creature->SetVisibility(VISIBILITY_OFF); + } + } + void JustDied(Unit* pKiller) + { + m_creature->Respawn(); + } + void UpdateAI(const uint32 uiDiff) + { + if(m_bIsDead) + { + if(m_uiRespawnTimer <= uiDiff) + { + m_bIsDead = false; + ResetMushroom(); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetVisibility(VISIBILITY_ON); + m_uiRespawnTimer = 30000; + }else m_uiRespawnTimer -= uiDiff; + } + } +}; + +CreatureAI* GetAI_npc_amanitar_mushroom(Creature* pCreature) +{ + return new npc_amanitar_mushroomAI(pCreature); +} +void AddSC_boss_amanitar() +{ + Script* newscript; + + newscript = new Script; + newscript->Name = "boss_amanitar"; + newscript->GetAI = &GetAI_boss_amanitar; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_amanitar_mushroom"; + newscript->GetAI = &GetAI_npc_amanitar_mushroom; + newscript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/northrend/azjol-nerub/ahnkahet/boss_jedoga.cpp b/scripts/northrend/azjol-nerub/ahnkahet/boss_jedoga.cpp index 1692b06df..560b1f608 100644 --- a/scripts/northrend/azjol-nerub/ahnkahet/boss_jedoga.cpp +++ b/scripts/northrend/azjol-nerub/ahnkahet/boss_jedoga.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,50 +16,214 @@ /* ScriptData SDName: Boss_Jedoga -SD%Complete: 40 -SDComment: +SD%Complete: 90% +SDAuthor: Tassadar +SDComment: Correct Timers SDCategory: Ahn'kahet EndScriptData */ #include "precompiled.h" #include "ahnkahet.h" +struct Locations +{ + float x, y, z, o; + uint32 id; +}; enum { - SAY_AGGRO = -1619017, - SAY_CALL_SACRIFICE1 = -1619018, - SAY_CALL_SACRIFICE2 = -1619019, - SAY_SACRIFICE1 = -1619020, - SAY_SACRIFICE2 = -1619021, - SAY_SLAY_1 = -1619022, - SAY_SLAY_2 = -1619023, - SAY_SLAY_3 = -1619024, - SAY_DEATH = -1619025, - - // preaching 1-5 when it is used? - SAY_PREACHING1 = -1619026, - SAY_PREACHING2 = -1619027, - SAY_PREACHING3 = -1619028, - SAY_PREACHING4 = -1619029, - SAY_PREACHING5 = -1619030, - - SAY_VOLUNTEER_CHOOSEN = -1619031, // I have been choosen! - SAY_VOLUNTEER_SACRIFICED = -1619032, // I give myself to the master! - - SPELL_CYCLONE_STRIKE = 56855, - SPELL_CYCLONE_STRIKE_H = 60030, - SPELL_LIGHTNING_BOLT = 56891, - SPELL_LIGHTNING_BOLT_H = 60032, - SPELL_THUNDERSHOCK = 56926, - SPELL_THUNDERSHOCK_H = 60029, - SPELL_GIFT_OF_THE_HERALD = 56219, - - SPELL_SACRIFICE_VISUAL = 56133, - SPELL_SACRIFICE_BEAM = 56150, - - NPC_JEDOGA_CONTROLLER = 30181, - NPC_TWILIGHT_INITIATE = 30114, - NPC_TWILIGHT_VOLUNTEER = 30385 + SPELL_SPHERE_VISUAL = 56075, + SPELL_GIFT_OF_THE_HERALD = 56219, + SPELL_CYCLONE_STRIKE = 60030, + SPELL_CYCLONE_STRIKE_H = 56855, + SPELL_LIGHTNING_BOLT = 56891, + SPELL_LIGHTNING_BOLT_H = 60032, + SPELL_THUNDERSHOCK = 56926, + SPELL_THUNDERSHOCK_H = 60029, + + SAY_AGGRO = -1619017, + SAY_CALL_SACRIFICE_1 = -1619018, + SAY_CALL_SACRIFICE_2 = -1619019, + SAY_SACRIFICE_1 = -1619020, + SAY_SACRIFICE_2 = -1619021, + SAY_SLAY_1 = -1619022, + SAY_SLAY_2 = -1619023, + SAY_SLAY_3 = -1619024, + SAY_DEATH = -1619025, + SAY_PREACHING_1 = -1619026, + SAY_PREACHING_2 = -1619027, + SAY_PREACHING_3 = -1619028, + SAY_PREACHING_4 = -1619029, + SAY_PREACHING_5 = -1619030, + + SAY_VOLUNTEER_1 = -1619031, //said by the volunteer image + SAY_VOLUNTEER_2 = -1619032, + + NPC_TWILIGHT_INITIATE = 30114, + NPC_TWILIGHT_VOLUNTEER = 30385, + NPC_JEDOGA = 29310, + + GO_CIRCLE = 194394, // Propably wrong id + + //Jedoga Shadowseeker's phases + PHASE_NOSTART = 0, + PHASE_PREACHING = 1, + PHASE_DESCEND = 2, + SUBPHASE_FLY_DESCEND = 21, + PHASE_FIGHT = 3, + PHASE_SACRIFACE = 4, + SUBPHASE_FLY_UP = 41, + SUBPHASE_CALL_VOLUNTEER = 42, + SUBPHASE_WAIT_FOR_VOLUNTEER = 43, + SUBPHASE_SACRIFACE = 44, + + //Twilight Volunteer's sacriface phases + SACRIFACE_CHOOSEN = 1, + SACRIFACE_DIE = 2, + + VOLUNTEER_COUNT = 29, +}; +#define CENTER_X 367.800f +#define CENTER_Y -704.403f +#define GROUND_Z -16.17f + +#define JEDOGA_X 357.353f +#define JEDOGA_Y -692.807f +#define JEDOGA_Z -11.720f +#define JEDOGA_O 5.565f + +static Locations VolunteerLoc[]= +{ + //29 Volunteers + {365.68f, -735.95f, -16.17f, 1.607f}, // Right, first line + {367.12f, -736.13f, -16.17f, 1.607f}, + {369.03f, -736.06f, -16.17f, 1.607f}, + {371.66f, -735.97f, -16.17f, 1.607f}, + {373.47f, -735.63f, -16.17f, 1.607f}, + + {365.45f, -739.03f, -16.00f, 1.607f}, // Right, second line + {367.56f, -738.62f, -16.00f, 1.607f}, + {369.62f, -738.22f, -16.17f, 1.607f}, + {371.66f, -737.82f, -16.06f, 1.607f}, + {373.75f, -737.41f, -16.00f, 1.607f}, + + {400.99f, -705.41f, -16.00f, 2.491f}, // Center, from right + {398.07f, -710.02f, -16.00f, 2.491f}, + {395.34f, -713.76f, -16.00f, 2.491f}, + {393.42f, -716.39f, -16.00f, 2.491f}, + {391.48f, -718.94f, -16.00f, 2.491f}, + {388.80f, -722.46f, -16.00f, 2.491f}, + {386.19f, -725.89f, -16.00f, 2.491f}, + {383.61f, -729.29f, -16.00f, 2.491f}, + {380.37f, -733.55f, -16.00f, 2.491f}, + + {402.72f, -700.79f, -16.00f, 3.046f}, // Left, first line + {402.63f, -698.86f, -16.18f, 3.149f}, + {402.62f, -697.10f, -16.17f, 3.149f}, + {402.61f, -695.50f, -16.17f, 3.059f}, + {402.20f, -693.39f, -16.17f, 3.159f}, + + {405.31f, -701.29f, -16.00f, 2.924f}, // Left, second line + {405.46f, -699.25f, -16.00f, 3.198f}, + {405.40f, -697.19f, -16.00f, 3.150f}, + {405.35f, -695.30f, -16.00f, 3.150f}, + {405.29f, -693.26f, -16.00f, 3.150f} +}; + +/*###### +## npc_twilight_volunteer +######*/ +struct MANGOS_DLL_DECL npc_twilight_volunteerAI : public ScriptedAI +{ + npc_twilight_volunteerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint8 m_uiPhase; + bool m_bIsVulunteerNear; + uint32 m_uiCheckTimer; + bool m_bIsDead; + void Reset() + { + m_uiPhase = 0; + m_bIsVulunteerNear = false; + m_uiCheckTimer = 1000; + m_bIsDead = false; + m_creature->SetRespawnDelay(DAY); + } + + void AttackStart(Unit* pWho) + { + return; + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (m_bIsDead) + { + uiDamage = 0; + return; + } + + if (uiDamage > m_creature->GetHealth()) + { + m_creature->ForcedDespawn(10000); + m_bIsDead = true; + uiDamage = 0; + + m_creature->SetHealth(1); + m_creature->SetVisibility(VISIBILITY_OFF); + } + } + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if(uiType != POINT_MOTION_TYPE) + return; + + switch(uiPointId) + { + case 0: + m_bIsVulunteerNear = true; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->ForcedDespawn(10000); + m_creature->SetVisibility(VISIBILITY_OFF); + break; + } + } + void Sacriface(uint8 phase) + { + if(m_bIsDead) + return; + + m_uiPhase = phase; + switch(m_uiPhase) + { + case SACRIFACE_CHOOSEN: + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_VOLUNTEER_1, m_creature); break; + case 1: DoScriptText(SAY_VOLUNTEER_2, m_creature); break; + } + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, GROUND_Z); + break; + case SACRIFACE_DIE: + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + break; + } + } + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_bIsDead) return; + + if (m_pInstance->GetData(TYPE_JEDOGA) != IN_PROGRESS) m_creature->ForcedDespawn(); + + } }; /*###### @@ -77,40 +241,53 @@ struct MANGOS_DLL_DECL boss_jedogaAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + bool m_bIsVulunteerNear; + bool m_bVolunteerDied; + bool m_isRealEvade; + uint8 m_uiPhase; + uint8 m_uiSubPhase; + uint8 m_uiPreachingText; + Creature *pVolunteer; + uint8 m_uiLastSacrifaceHP; - uint32 m_uiThundershockTimer; + uint32 m_uiPreachingTimer; + uint32 m_uiCheckTimer; + uint32 m_uiSacrifaceTimer; uint32 m_uiCycloneStrikeTimer; uint32 m_uiLightningBoltTimer; - uint8 m_uiSacrificeCount; - bool m_bSacrifice; + uint32 m_uiThundershockTimer; + void Reset() { - m_uiThundershockTimer = 40000; - m_uiCycloneStrikeTimer = 15000; - m_uiLightningBoltTimer = 7000; - m_bSacrifice = false; - } + m_uiPhase = PHASE_PREACHING; + m_uiSubPhase = 0; + m_uiPreachingText = 0; + m_bIsVulunteerNear = false; + m_bVolunteerDied = false; + m_uiLastSacrifaceHP = 0; + m_isRealEvade = true; - Creature* SelectRandomCreatureOfEntryInRange(uint32 uiEntry, float fRange) - { - std::list lCreatureList; - GetCreatureListWithEntryInGrid(lCreatureList, m_creature, uiEntry, fRange); + m_uiCheckTimer = 1000; + m_uiSacrifaceTimer = 2000; + m_uiPreachingTimer = 0; + m_uiCycloneStrikeTimer = 17000; + m_uiLightningBoltTimer = 3000; + m_uiThundershockTimer = 30000; - if (lCreatureList.empty()) - return NULL; - - std::list::iterator iter = lCreatureList.begin(); - advance(iter, urand(0, lCreatureList.size()-1)); - - return *iter; + DoCast(m_creature, SPELL_SPHERE_VISUAL); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (m_pInstance) + m_pInstance->SetData(TYPE_JEDOGA, NOT_STARTED); } - void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); + AttackStart(pWho); + if (m_pInstance) + m_pInstance->SetData(TYPE_JEDOGA, IN_PROGRESS); } - void KilledUnit(Unit* pVictim) { switch(urand(0, 2)) @@ -120,66 +297,308 @@ struct MANGOS_DLL_DECL boss_jedogaAI : public ScriptedAI case 2: DoScriptText(SAY_SLAY_3, m_creature); break; } } + void EnterEvadeMode() + { + if (m_uiPhase == PHASE_PREACHING && !m_isRealEvade) return; + + m_uiPhase = PHASE_PREACHING; + SetCombatMovement(false); + m_creature->GetMotionMaster()->MovementExpired(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_SPHERE_VISUAL); + m_creature->GetMap()->CreatureRelocation(m_creature, JEDOGA_X, JEDOGA_Y, JEDOGA_Z, JEDOGA_O); + m_creature->SendMonsterMove(JEDOGA_X, JEDOGA_Y, JEDOGA_Z, SPLINETYPE_NORMAL, SPLINEFLAG_NONE, 0); + if (m_pInstance) + m_pInstance->SetData(TYPE_JEDOGA, NOT_STARTED); + + if (m_isRealEvade) + { + RespawnInitiates(); + m_isRealEvade = false; + } + } + + void RespawnInitiates() + { + std::list lInitiates; //respawn Twilight initiates + GetCreatureListWithEntryInGrid(lInitiates, m_creature, NPC_TWILIGHT_INITIATE, DEFAULT_VISIBILITY_INSTANCE); + + if (!lInitiates.empty()) + { + for(std::list::iterator iter = lInitiates.begin(); iter != lInitiates.end(); ++iter) + { + if ((*iter) && !(*iter)->isAlive()) + (*iter)->Respawn(); + } + } + } void JustDied(Unit* pKiller) { DoScriptText(SAY_DEATH, m_creature); + if (m_pInstance) + m_pInstance->SetData(TYPE_JEDOGA, DONE); } - void UpdateAI(const uint32 uiDiff) + Creature* SelectRandomVolunteer(float fRange) { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; + std::list lVolunteerList; + GetCreatureListWithEntryInGrid(lVolunteerList, m_creature, NPC_TWILIGHT_VOLUNTEER, fRange); - if (m_creature->GetHealthPercent() < 50.0f && !m_bSacrifice) - { - // start sacrifice here - m_bSacrifice = true; + //This should not appear! + if (lVolunteerList.empty()){ + EnterEvadeMode(); + debug_log("SD2: AhnKahet: No volunteer to sacriface!"); + return NULL; } - if (m_uiThundershockTimer < uiDiff) - { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_THUNDERSHOCK : SPELL_THUNDERSHOCK_H); - m_uiThundershockTimer = 40000; - } - else - m_uiThundershockTimer -= uiDiff; + std::list::iterator iter = lVolunteerList.begin(); + advance(iter, urand(0, lVolunteerList.size()-1)); - if (m_uiLightningBoltTimer < uiDiff) + return *iter; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == PHASE_NOSTART) + return; + else if(m_uiPhase == PHASE_PREACHING) { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_LIGHTNING_BOLT : SPELL_LIGHTNING_BOLT_H); + if(m_uiCheckTimer <= uiDiff) + { + if(Creature *pTemp = GetClosestCreatureWithEntry(m_creature, NPC_TWILIGHT_INITIATE, 150.0f)) + m_uiCheckTimer = 2000; + else + { + m_uiPhase = PHASE_DESCEND; + m_uiSubPhase = SUBPHASE_FLY_DESCEND; + return; + } + }else m_uiCheckTimer -= uiDiff; + + if(m_uiPreachingTimer > uiDiff) + { + m_uiPreachingTimer -= uiDiff; + return; + } - m_uiLightningBoltTimer = 7000; + if (m_pInstance) + if(m_pInstance->GetData(TYPE_TALDARAM) != DONE) + return; + + switch(m_uiPreachingText) + { + case 0: + DoScriptText(SAY_PREACHING_1, m_creature); + m_uiPreachingText++; + m_uiPreachingTimer = 9500; + break; + case 1: + DoScriptText(SAY_PREACHING_2, m_creature); + m_uiPreachingText++; + m_uiPreachingTimer = 6500; + break; + case 2: + DoScriptText(SAY_PREACHING_3, m_creature); + m_uiPreachingText++; + m_uiPreachingTimer = 8500; + break; + case 3: + DoScriptText(SAY_PREACHING_4, m_creature); + m_uiPreachingText++; + m_uiPreachingTimer = 7500; + break; + case 4: + DoScriptText(SAY_PREACHING_5, m_creature); + m_uiPreachingText = 0; + m_uiPreachingTimer = 12000; + break; + } + return; } - else - m_uiLightningBoltTimer -= uiDiff; + else if(m_uiPhase == PHASE_DESCEND) + { + if(m_uiSubPhase == SUBPHASE_FLY_DESCEND) + { + if(GetClosestCreatureWithEntry(m_creature, NPC_TWILIGHT_VOLUNTEER, 150.0f)) + return; + + SetCombatMovement(true); + m_creature->GetMap()->CreatureRelocation(m_creature, CENTER_X, CENTER_Y, GROUND_Z, JEDOGA_O); + m_creature->SendMonsterMove(CENTER_X, CENTER_Y, GROUND_Z, SPLINETYPE_NORMAL, SPLINEFLAG_NONE, 0); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL); + m_creature->SetInCombatWithZone(); + //Spawn Volunteers + for(int i = 0; i <= 28; ++i) + { + if(Creature *pTemp = m_creature->SummonCreature(NPC_TWILIGHT_VOLUNTEER, VolunteerLoc[i].x, VolunteerLoc[i].y, VolunteerLoc[i].z, VolunteerLoc[i].o, TEMPSUMMON_CORPSE_DESPAWN, 0)) + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (m_uiCycloneStrikeTimer < uiDiff) + } + m_uiSubPhase = 0; + m_uiPhase = PHASE_FIGHT; + return; + } + } + else if(m_uiPhase == PHASE_FIGHT) { - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CYCLONE_STRIKE : SPELL_CYCLONE_STRIKE_H); - m_uiCycloneStrikeTimer = 15000; + //Evade if no target in this phase + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + //Spells + //Cyclone Strike + if(m_uiCycloneStrikeTimer <= uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_CYCLONE_STRIKE : SPELL_CYCLONE_STRIKE_H); + m_uiCycloneStrikeTimer = 10000 + rand()%10000; + }else m_uiCycloneStrikeTimer -= uiDiff; + + //Lightning Bolt + if(m_uiLightningBoltTimer <= uiDiff) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_LIGHTNING_BOLT : SPELL_LIGHTNING_BOLT_H); + m_uiLightningBoltTimer = 3000 + rand()%2000; + }else m_uiLightningBoltTimer -= uiDiff; + + //Thundershock + if(m_uiThundershockTimer <= uiDiff) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_THUNDERSHOCK : SPELL_THUNDERSHOCK_H); + m_uiThundershockTimer = 20000 + rand()%10000; + }else m_uiThundershockTimer -= uiDiff; + + //Health check + if(m_uiCheckTimer <= uiDiff) + { + uint8 health = m_creature->GetHealth()*100 / m_creature->GetMaxHealth(); + if(m_uiLastSacrifaceHP == 0 && health <= 75) + { + m_uiLastSacrifaceHP = 75; + m_uiPhase = PHASE_SACRIFACE; + m_uiSubPhase = SUBPHASE_FLY_UP; + return; + } + else if(m_uiLastSacrifaceHP == 75 && health <= 50) + { + m_uiLastSacrifaceHP = 50; + m_uiPhase = PHASE_SACRIFACE; + m_uiSubPhase = SUBPHASE_FLY_UP; + return; + } + else if(m_uiLastSacrifaceHP == 50 && health <= 25) + { + m_uiLastSacrifaceHP = 25; + m_uiPhase = PHASE_SACRIFACE; + m_uiSubPhase = SUBPHASE_FLY_UP; + return; + } + m_uiCheckTimer = 1000; + }else m_uiCheckTimer -= uiDiff; + + DoMeleeAttackIfReady(); } - else - m_uiCycloneStrikeTimer -= uiDiff; + else if(m_uiPhase == PHASE_SACRIFACE) + { + if(m_uiSubPhase == SUBPHASE_FLY_UP) + { + SetCombatMovement(false); + m_creature->GetMotionMaster()->MovementExpired(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_SPHERE_VISUAL); + m_creature->GetMap()->CreatureRelocation(m_creature, JEDOGA_X, JEDOGA_Y, JEDOGA_Z, JEDOGA_O); + m_creature->SendMonsterMove(JEDOGA_X, JEDOGA_Y, JEDOGA_Z, SPLINETYPE_NORMAL, SPLINEFLAG_NONE, 0); + m_uiSubPhase = SUBPHASE_CALL_VOLUNTEER; + GameObject* pCircle = GetClosestGameObjectWithEntry(m_creature,GO_CIRCLE,50.0f); + if (pCircle && !pCircle->isSpawned()) + pCircle->SetRespawnTime(10000); + } + else if(m_uiSubPhase == SUBPHASE_CALL_VOLUNTEER) + { + pVolunteer = SelectRandomVolunteer(150.0f); + if(pVolunteer) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_CALL_SACRIFICE_1, m_creature); break; + case 1: DoScriptText(SAY_CALL_SACRIFICE_2, m_creature); break; + } + ((npc_twilight_volunteerAI*)pVolunteer->AI())->Sacriface(SACRIFACE_CHOOSEN); + m_uiSubPhase = SUBPHASE_WAIT_FOR_VOLUNTEER; + } + } + else if(m_uiSubPhase == SUBPHASE_WAIT_FOR_VOLUNTEER) + { + if(m_uiCheckTimer <= uiDiff) + { + if(pVolunteer && pVolunteer->isAlive()){ + if(pVolunteer->GetVisibility() == VISIBILITY_OFF) + { + if(((npc_twilight_volunteerAI*)pVolunteer->AI())->m_bIsVulunteerNear) + m_bVolunteerDied = false; + else + m_bVolunteerDied = true; + m_uiSubPhase = SUBPHASE_SACRIFACE; + } + }else{ + m_bIsVulunteerNear = true; + m_bVolunteerDied = true; + m_uiSubPhase = SUBPHASE_SACRIFACE; + } + m_uiCheckTimer = 1000; + }else m_uiCheckTimer -= uiDiff; + } + else if(m_uiSubPhase == SUBPHASE_SACRIFACE) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_SACRIFICE_1, m_creature); break; + case 1: DoScriptText(SAY_SACRIFICE_2, m_creature); break; + } + if(!m_bVolunteerDied) + DoCast(m_creature, SPELL_GIFT_OF_THE_HERALD); - DoMeleeAttackIfReady(); + m_creature->GetMap()->CreatureRelocation(m_creature, CENTER_X, CENTER_Y, GROUND_Z, JEDOGA_O); + m_creature->SendMonsterMove(CENTER_X, CENTER_Y, GROUND_Z, SPLINETYPE_NORMAL, SPLINEFLAG_NONE, 0); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL); + SetCombatMovement(true); + m_uiPhase = PHASE_FIGHT; + if(m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + } } }; - CreatureAI* GetAI_boss_jedoga(Creature* pCreature) { return new boss_jedogaAI(pCreature); } +CreatureAI* GetAI_npc_twilight_volunteer(Creature* pCreature) +{ + return new npc_twilight_volunteerAI(pCreature); +} + void AddSC_boss_jedoga() { - Script* newscript; + Script *newscript; newscript = new Script; newscript->Name = "boss_jedoga"; newscript->GetAI = &GetAI_boss_jedoga; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_twilight_volunteer"; + newscript->GetAI = &GetAI_npc_twilight_volunteer; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/azjol-nerub/ahnkahet/boss_nadox.cpp b/scripts/northrend/azjol-nerub/ahnkahet/boss_nadox.cpp index 017b08989..5f25753ef 100644 --- a/scripts/northrend/azjol-nerub/ahnkahet/boss_nadox.cpp +++ b/scripts/northrend/azjol-nerub/ahnkahet/boss_nadox.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -109,7 +109,7 @@ struct MANGOS_DLL_DECL boss_nadoxAI : public ScriptedAI bool m_bIsRegularMode; bool m_bBerserk; - bool m_bGuardianSummoned; + uint8 m_uiGuardianCount; uint32 m_uiBroodPlagueTimer; uint32 m_uiBroodRageTimer; uint32 m_uiSummonTimer; @@ -117,10 +117,11 @@ struct MANGOS_DLL_DECL boss_nadoxAI : public ScriptedAI void Reset() { m_bBerserk = false; - m_bGuardianSummoned = false; + m_uiGuardianCount = 3; m_uiSummonTimer = 5000; m_uiBroodPlagueTimer = 15000; m_uiBroodRageTimer = 20000; + m_creature->SetRespawnDelay(DAY); } Creature* SelectRandomCreatureOfEntryInRange(uint32 uiEntry, float fRange) @@ -162,21 +163,32 @@ struct MANGOS_DLL_DECL boss_nadoxAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (!m_bGuardianSummoned && m_creature->GetHealthPercent() < 50.0f) + if (m_creature->GetHealth()*4 < m_creature->GetMaxHealth()*m_uiGuardianCount) { - // guardian is summoned at 50% of boss HP - if (Creature* pGuardianEgg = SelectRandomCreatureOfEntryInRange(NPC_AHNKAHAR_GUARDIAN_EGG, 75.0f)) - pGuardianEgg->CastSpell(pGuardianEgg, SPELL_SUMMON_SWARM_GUARDIAN, false); + // guardian is summoned at 75%, 50% and 25% of boss HP + if (Creature* pGuardianEgg = SelectRandomCreatureOfEntryInRange(NPC_AHNKAHAR_GUARDIAN_EGG, 75.0)) + { + // pGuardianEgg->CastSpell(pGuardianEgg, SPELL_SUMMON_SWARM_GUARDIAN, false); + if(Creature *pGuardian = pGuardianEgg->SummonCreature(NPC_AHNKAHAR_GUARDIAN, pGuardianEgg->GetPositionX(), pGuardianEgg->GetPositionY(), pGuardianEgg->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 3*MINUTE*IN_MILLISECONDS)) + pGuardian->AI()->AttackStart(m_creature->getVictim()); + } - m_bGuardianSummoned = true; + --m_uiGuardianCount; } if (m_uiSummonTimer < uiDiff) { - DoScriptText(urand(0, 1) ? SAY_SUMMON_EGG_1 : SAY_SUMMON_EGG_2, m_creature); + DoScriptText(rand()%2?SAY_SUMMON_EGG_1:SAY_SUMMON_EGG_2, m_creature); if (Creature* pSwarmerEgg = SelectRandomCreatureOfEntryInRange(NPC_AHNKAHAR_SWARM_EGG, 75.0)) - pSwarmerEgg->CastSpell(pSwarmerEgg, SPELL_SUMMON_SWARMERS, false); + { + // pSwarmerEgg->CastSpell(pSwarmerEgg, SPELL_SUMMON_SWARMERS, false); + if(Creature *pSwarmer = pSwarmerEgg->SummonCreature(NPC_AHNKAHAR_SWARMER, pSwarmerEgg->GetPositionX(), pSwarmerEgg->GetPositionY(), pSwarmerEgg->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 3*MINUTE*IN_MILLISECONDS)) + pSwarmer->AI()->AttackStart(m_creature->getVictim()); + + if(Creature *pSwarmer = pSwarmerEgg->SummonCreature(NPC_AHNKAHAR_SWARMER, pSwarmerEgg->GetPositionX(), pSwarmerEgg->GetPositionY(), pSwarmerEgg->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 3*MINUTE*IN_MILLISECONDS)) + pSwarmer->AI()->AttackStart(m_creature->getVictim()); + } m_uiSummonTimer = 10000; } @@ -193,12 +205,12 @@ struct MANGOS_DLL_DECL boss_nadoxAI : public ScriptedAI else m_uiBroodPlagueTimer -= uiDiff; - if (!m_bIsRegularMode) + if(!m_bIsRegularMode) { if (m_uiBroodRageTimer < uiDiff) { if (Creature* pRageTarget = SelectRandomCreatureOfEntryInRange(NPC_AHNKAHAR_SWARMER, 50.0)) - DoCastSpellIfCan(pRageTarget, SPELL_BROOD_RAGE); + DoCast(pRageTarget, SPELL_BROOD_RAGE); m_uiBroodRageTimer = 20000; } @@ -206,10 +218,10 @@ struct MANGOS_DLL_DECL boss_nadoxAI : public ScriptedAI m_uiBroodRageTimer -= uiDiff; } - if (!m_bBerserk && m_creature->GetPositionZ() < 24.0) + if (!m_bBerserk && (m_creature->GetPositionZ() < 24.0)) { m_bBerserk = true; - DoCastSpellIfCan(m_creature, SPELL_BERSERK); + DoCast(m_creature, SPELL_BERSERK); } DoMeleeAttackIfReady(); @@ -223,7 +235,7 @@ CreatureAI* GetAI_boss_nadox(Creature* pCreature) void AddSC_boss_nadox() { - Script* newscript; + Script *newscript; newscript = new Script; newscript->Name = "boss_nadox"; diff --git a/scripts/northrend/azjol-nerub/ahnkahet/boss_taldaram.cpp b/scripts/northrend/azjol-nerub/ahnkahet/boss_taldaram.cpp index 2b2c6b58b..a073d0fba 100644 --- a/scripts/northrend/azjol-nerub/ahnkahet/boss_taldaram.cpp +++ b/scripts/northrend/azjol-nerub/ahnkahet/boss_taldaram.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,9 @@ /* ScriptData SDName: Boss_Taldaram -SD%Complete: 20% -SDComment: +SD%Complete: 80% +SDAuthor: Tassadar +SDComment: Timers, maybe wrong orb behavior SDCategory: Ahn'kahet EndScriptData */ @@ -26,6 +27,21 @@ EndScriptData */ enum { + SPELL_BEAM_VISUAL = 60342, // Used when taldram levitates before encounter + SPELL_CONJURE_FLAME_ORB = 55931, // Dummy spell, dont do anything except cast + SPELL_BLOODTHIRST = 55968, + SPELL_VANISH = 55964, // Does not work...? + SPELL_EMBRACE_OF_THE_VAMPYR = 55959, + SPELL_EMBRACE_OF_THE_VAMPYR_H = 59513, + + SPELL_FLAME_ORB_SPAWN_EFFECT = 55891, // Orb Grow up + SPELL_FLAME_ORB_VISUAL = 55928, // Flame orb effect + SPELL_FLAME_ORB_DEATH = 55947, // Despawn effect + SPELL_FLAME_ORB = 57750, // Flame orb damage + SPELL_FLAME_ORB_H = 58937, + + NPC_FLAME_ORB = 30702, + SAY_AGGRO = -1619008, SAY_VANISH_1 = -1619009, SAY_VANISH_2 = -1619010, @@ -34,7 +50,21 @@ enum SAY_SLAY_1 = -1619013, SAY_SLAY_2 = -1619014, SAY_SLAY_3 = -1619015, - SAY_DEATH = -1619016 + SAY_DEATH = -1619016, + + FLAME_ORB_Z = 17, + + FLAME_ORB_UP_X = 383, + FLAME_ORB_UP_Y = -984, + + FLAME_ORB_DOWN_X = 632, + FLAME_ORB_DOWN_Y = -684, + + FLAME_ORB_RIGHT_X = 350, + FLAME_ORB_RIGHT_Y = -705, + + FLAME_ORB_LEFT_X = 613, + FLAME_ORB_LEFT_Y = -966, }; /*###### @@ -52,14 +82,37 @@ struct MANGOS_DLL_DECL boss_taldaramAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + uint8 m_uiVanishPhase; + uint32 m_uiDamageTaken; + Unit* m_uEmbraceTarget; + + uint32 m_uiBloodthirst_Timer; + uint32 m_uiSummonOrb_Timer; + uint32 m_uiVanish_Timer; + uint32 m_uiVanishPhase_Timer; + uint32 m_uiEmbrace_Timer; void Reset() { + m_creature->SetRespawnDelay(DAY); + m_uiBloodthirst_Timer = 4000; + m_uiSummonOrb_Timer = 13000; + m_uiVanish_Timer = 17000; + m_uiVanishPhase_Timer = 0; + m_uiEmbrace_Timer = 0; + m_uiVanishPhase = 0; + m_uiDamageTaken = 0; + if (m_pInstance) + m_pInstance->SetData(TYPE_TALDARAM, NOT_STARTED); } void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); + m_creature->RemoveAurasDueToSpell(SPELL_BEAM_VISUAL); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + if (m_pInstance) + m_pInstance->SetData(TYPE_TALDARAM, IN_PROGRESS); } void KilledUnit(Unit* pVictim) @@ -80,11 +133,108 @@ struct MANGOS_DLL_DECL boss_taldaramAI : public ScriptedAI m_pInstance->SetData(TYPE_TALDARAM, DONE); } + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if(m_creature->IsNonMeleeSpellCasted(false)) + { + m_uiDamageTaken += uiDamage; + uint32 m_uiMinDamage = m_bIsRegularMode ? 20000 : 40000; + if(m_uiDamageTaken >= m_uiMinDamage) + { + m_uiVanishPhase = 0; + m_creature->InterruptNonMeleeSpells(false); + } + } + } void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + if (!m_pInstance) return; + + if(m_uiVanishPhase != 0) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if(m_uiVanishPhase_Timer <= uiDiff) + { + m_creature->InterruptNonMeleeSpells(false); + m_uiVanishPhase = 0; + }else m_uiVanishPhase_Timer -= uiDiff; + + if(m_uiVanishPhase != 1) + return; + + // Embrace of the Vampyr + if(m_uiEmbrace_Timer <= uiDiff) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_FEED_1, m_creature); break; + case 1: DoScriptText(SAY_FEED_2, m_creature); break; + } + m_creature->SetVisibility(VISIBILITY_ON); + if(m_uEmbraceTarget && m_uEmbraceTarget->isAlive()) + DoCast(m_uEmbraceTarget, m_bIsRegularMode ? SPELL_EMBRACE_OF_THE_VAMPYR : SPELL_EMBRACE_OF_THE_VAMPYR_H); + m_uiDamageTaken = 0; + m_uiVanishPhase = 2; + }else m_uiEmbrace_Timer -= uiDiff; + return; + } + + // Bloodthirst + if(m_uiBloodthirst_Timer <= uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_BLOODTHIRST); + m_uiBloodthirst_Timer = 8000 + rand()%6000; + }else m_uiBloodthirst_Timer -= uiDiff; + + // Summon Flame Orb + if(m_uiSummonOrb_Timer <= uiDiff) + { + for(int i = 0; i <= 3; ++i) + { + m_creature->SummonCreature(NPC_FLAME_ORB, m_creature->GetPositionX(), m_creature->GetPositionY(), FLAME_ORB_Z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + if(m_bIsRegularMode) + break; + } + DoCast(m_creature, SPELL_CONJURE_FLAME_ORB); + m_uiSummonOrb_Timer = 16000 + rand()%10000; + m_uiVanish_Timer = 16000; + }else m_uiSummonOrb_Timer -= uiDiff; + + // Vanish + if(m_uiVanish_Timer <= uiDiff) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_VANISH_1, m_creature); break; + case 1: DoScriptText(SAY_VANISH_2, m_creature); break; + } + + //DoCast(m_creature, SPELL_VANISH); We dont want to drop aggro + m_uiVanishPhase = 1; + bool stop = false; + while(!stop) + { + m_uEmbraceTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); + if(m_uEmbraceTarget && m_uEmbraceTarget->isAlive() && m_uEmbraceTarget->GetTypeId() == TYPEID_PLAYER) + stop = true; + else + continue; + + m_creature->GetMotionMaster()->MoveChase(m_uEmbraceTarget); + break; + } + + m_creature->SetVisibility(VISIBILITY_OFF); + m_uiVanish_Timer = 10000 + rand()%10000; + m_uiEmbrace_Timer = 3500; + m_uiVanishPhase_Timer = 22500; + return; + }else m_uiVanish_Timer -= uiDiff; + DoMeleeAttackIfReady(); } }; @@ -93,12 +243,94 @@ CreatureAI* GetAI_boss_taldaram(Creature* pCreature) { return new boss_taldaramAI(pCreature); } +/*###### +## mob_flame_orb +######*/ + +struct MANGOS_DLL_DECL mob_flame_orbAI : public ScriptedAI +{ + mob_flame_orbAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + bool m_bIsFlying; + int8 direction; + + uint32 m_uiDespawn_Timer; + uint32 m_uiCast_Timer; + + void Reset() + { + m_uiDespawn_Timer = 13000; + m_uiCast_Timer = 3000; + direction = -1; + m_bIsFlying = false; + DoCast(m_creature, SPELL_FLAME_ORB_VISUAL); + DoCast(m_creature, SPELL_FLAME_ORB_SPAWN_EFFECT); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + void AttackStart(Unit* pWho) + { + return; + } + void UpdateAI(const uint32 uiDiff) + { + // Despawn Timer + if(m_uiDespawn_Timer <= uiDiff) + { + DoCast(m_creature, SPELL_FLAME_ORB_DEATH); + m_creature->ForcedDespawn(); + }else m_uiDespawn_Timer -= uiDiff; + + // Fly timer + if(m_uiCast_Timer <= uiDiff) + { + if(m_bIsFlying) + return; + + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_ORB : SPELL_FLAME_ORB_H); + direction = rand()%4; + switch(direction) + { + case 0: // Up + m_creature->GetMotionMaster()->MovePoint(0, FLAME_ORB_UP_X, FLAME_ORB_UP_Y, FLAME_ORB_Z); + break; + case 1: // Down + m_creature->GetMotionMaster()->MovePoint(0, FLAME_ORB_DOWN_X, FLAME_ORB_DOWN_Y, FLAME_ORB_Z); + break; + case 2: // Right + m_creature->GetMotionMaster()->MovePoint(0, FLAME_ORB_RIGHT_X, FLAME_ORB_RIGHT_Y, FLAME_ORB_Z); + break; + case 3: // Left + m_creature->GetMotionMaster()->MovePoint(0, FLAME_ORB_LEFT_X, FLAME_ORB_LEFT_Y, FLAME_ORB_Z); + break; + default: + m_creature->GetMotionMaster()->MovePoint(0, FLAME_ORB_UP_X, FLAME_ORB_UP_Y, FLAME_ORB_Z); + break; + + } + m_bIsFlying = true; + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + }else m_uiCast_Timer -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_flame_orb(Creature* pCreature) +{ + return new mob_flame_orbAI(pCreature); +} /*###### ## go_nerubian_device ######*/ -bool GOHello_go_nerubian_device(Player* pPlayer, GameObject* pGo) +bool GOUse_go_nerubian_device(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -121,6 +353,11 @@ void AddSC_boss_taldaram() newscript = new Script; newscript->Name = "go_nerubian_device"; - newscript->pGOHello = &GOHello_go_nerubian_device; + newscript->pGOUse = &GOUse_go_nerubian_device; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_flame_orb"; + newscript->GetAI = &GetAI_mob_flame_orb; newscript->RegisterSelf(); } diff --git a/scripts/northrend/azjol-nerub/ahnkahet/boss_volazj.cpp b/scripts/northrend/azjol-nerub/ahnkahet/boss_volazj.cpp index 9d934720c..075a1bd68 100644 --- a/scripts/northrend/azjol-nerub/ahnkahet/boss_volazj.cpp +++ b/scripts/northrend/azjol-nerub/ahnkahet/boss_volazj.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,25 +16,102 @@ /* ScriptData SDName: Boss_Volazj -SD%Complete: 20% -SDComment: +SD%Complete: 60% +SDComment: Insanity does not work blizzlike - custom event made, shiver need core support, timers +SDAuthor: Tassadar SDCategory: Ahn'kahet EndScriptData */ #include "precompiled.h" +#include "ahnkahet.h" -//TODO: fill in texts in database. Also need to add text for whisper. enum { + SPELL_MIND_FLAY = 57941, + SPELL_MIND_FLAY_H = 59974, + SPELL_SHADOW_BOLT = 57942, + SPELL_SHADOW_BOLT_H = 59975, + + //Shiver - horrible ability + SPELL_SHIVER = 57949, //Jump Aura + SPELL_SHIVER_H = 59978, + SPELL_SHIVER_DMG = 57952, //Damage + SPELL_SHIVER_DMG_H = 59979, + SPELL_SHIVER_DUMMY = 57951, //What is this? + + //This is little complicated: + //When volajz cast this, on every player is cast different invisibility spell, + //so they dont see together, but they see four Twisted Visages - images of other + //four party members, which cast spell like their class. + SPELL_INSANITY = 57496, //This is what volajz casts, it should trigger Twisted Visage spawn spells + SPELL_INSANITY_PHASE = 57507, //For use in code + SPELL_INSANITY_PHASE_1 = 57508, //invis spells + SPELL_INSANITY_PHASE_2 = 57509, + SPELL_INSANITY_PHASE_3 = 57510, + SPELL_INSANITY_PHASE_4 = 57511, + SPELL_INSANITY_PHASE_5 = 57512, + SPELL_INSANITY_CHANNEL = 57561, //Just for visual, Volazj cast this when players are in insanity + + SPELL_TWISTED_VISAGE_MIRROR = 57507, //Not implented in mangos, but I have patch :) + + /* + http://www.wowhead.com/?spell=57507 Twisted visage visual + http://www.wowhead.com/?spells=0&filter=na=twisted+visage so many spells?! + */ + + //Ancient void spells + SPELL_PRISON = 43312, + SPELL_BLUE_FLAMES = 42586, + SPELL_RED_FLAMES = 42346, + SPELL_BLUE_BEAM = 32840, + SPELL_SHAKE = 44681, + SPELL_PSYCHIC_SCREAM = 34322, + + NPC_TWISTED_VISAGE = 30621, + NPC_ANCIENT_VOID = 30622, //Custom + + MODEL_VOID_LIGHT = 19702, + MODEL_VOID_DARK = 1132, + SAY_AGGRO = -1619033, SAY_INSANITY = -1619034, SAY_SLAY_1 = -1619035, SAY_SLAY_2 = -1619036, SAY_SLAY_3 = -1619037, SAY_DEATH_1 = -1619038, - SAY_DEATH_2 = -1619039 + SAY_DEATH_2 = -1619039, + SAY_ANCIENT_VOID = -1619040, + + SAY_VOID_CORRUPT = -1619041, + SAY_VOID_AGGRO = -1619042, + + PHASE_NOSTART = 0, + PHASE_FIGHT = 1, + PHASE_INSANITY_1 = 2, // Wait five seconds until cast is complete, set unattackable + PHASE_INSANITY_2 = 3, + PHASE_INSANITY_3 = 4, +}; +struct Locations +{ + float x, y, z; + uint32 id; }; +static Locations SpawnLoc[]= +{ + //Around room + {571.48f, -494.01f, 26.35f}, + {562.58f, -526.48f, 28.97f}, + {524.80f, -552.07f, 26.66f}, + {494.62f, -533.39f, 28.99f}, + {470.88f, -498.74f, 26.35f}, + {483.96f, -468.54f, 28.97f}, + {519.23f, -441.54f, 26.35f}, + {548.45f, -456.50f, 29.00f}, + + //Center of the room + {521.67f, -496.17f, 27.01f} +}; /*###### ## boss_volazj ######*/ @@ -50,14 +127,57 @@ struct MANGOS_DLL_DECL boss_volazjAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + uint8 m_uiPhase; + uint64 m_uiLastShiverTargetGUID; + uint8 m_uiShiverJumpTimer; + uint8 m_uiLastSacrifaceHP; + + uint32 m_uiMindFlayTimer; + uint32 m_uiShadowBoltTimer; + uint32 m_uiShiverTimer; + uint32 m_uiCheckTimer; + + //Insanity + uint32 m_uiInsanityCastTimer; void Reset() { + m_uiPhase = PHASE_NOSTART; + m_uiLastSacrifaceHP = 0; + + m_uiMindFlayTimer = 10000; + m_uiShadowBoltTimer = 5000; + m_uiShiverTimer = 18000; + m_uiCheckTimer = 1000; + m_uiShiverJumpTimer = 0; + m_uiLastShiverTargetGUID = 0; + + m_creature->SetRespawnDelay(DAY); + + //Insanity + m_uiInsanityCastTimer = 5000; + + if (m_pInstance && m_pInstance->GetData(TYPE_VOLAZJ) != DONE) + m_pInstance->SetData(TYPE_VOLAZJ, NOT_STARTED); } void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); + if (m_pInstance) + m_pInstance->SetData(TYPE_VOLAZJ, IN_PROGRESS); + m_uiPhase = PHASE_FIGHT; + + Map* pMap = m_creature->GetMap(); + } + + void EnterEvadeMode() + { + if(m_uiPhase != PHASE_FIGHT) + return; + + m_creature->GetMotionMaster()->MoveTargetedHome(); + m_pInstance->SetData(TYPE_VOLAZJ, FAIL); } void KilledUnit(Unit* pVictim) @@ -73,22 +193,301 @@ struct MANGOS_DLL_DECL boss_volazjAI : public ScriptedAI void JustDied(Unit* pKiller) { DoScriptText(urand(0, 1) ? SAY_DEATH_1 : SAY_DEATH_2, m_creature); + if (m_pInstance) + m_pInstance->SetData(TYPE_VOLAZJ, DONE); } void UpdateAI(const uint32 uiDiff) { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + if(m_uiPhase == PHASE_FIGHT) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + //Spells + //Mind Flay + if(m_uiMindFlayTimer <= uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_MIND_FLAY : SPELL_MIND_FLAY_H); + m_uiMindFlayTimer = 10000 + rand()%10000; + }else m_uiMindFlayTimer -= uiDiff; + + //Shadowbolt voley + if(m_uiShadowBoltTimer <= uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHADOW_BOLT : SPELL_SHADOW_BOLT_H); + m_uiShadowBoltTimer = 8000 + rand()%5000; + }else m_uiShadowBoltTimer -= uiDiff; + + //Shiver + if(m_uiShiverTimer <= uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_SHIVER : SPELL_SHIVER_H); + m_uiShiverTimer = 30000; + }else m_uiShiverTimer -= uiDiff; + + //Health check + if(m_uiCheckTimer <= uiDiff) + { + uint8 health = m_creature->GetHealth()*100 / m_creature->GetMaxHealth(); + if(m_uiLastSacrifaceHP == 0 && health <= 50) + { + m_creature->InterruptNonMeleeSpells(true); + SetCombatMovement(false); + m_uiLastSacrifaceHP = 50; + DoCast(m_creature, SPELL_INSANITY); + m_uiPhase = PHASE_INSANITY_1; + return; + } + m_uiCheckTimer = 1000; + }else m_uiCheckTimer -= uiDiff; + + DoMeleeAttackIfReady(); + }else if(m_uiPhase == PHASE_INSANITY_1) + { + //Wait until cast is complete + if(m_uiInsanityCastTimer <= uiDiff) + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, SPELL_INSANITY_CHANNEL); + DoInsanity(); + m_uiInsanityCastTimer = 5000; + m_uiCheckTimer = 5000; + m_uiPhase = PHASE_INSANITY_2; + SetCombatMovement(false); + m_creature->GetMotionMaster()->MovementExpired(false); + DoScriptText(SAY_ANCIENT_VOID, m_creature); + }else m_uiInsanityCastTimer -= uiDiff; + }else if(m_uiPhase == PHASE_INSANITY_2) + { + if(m_uiCheckTimer <= uiDiff) + { + if(Creature *pTemp = GetClosestCreatureWithEntry(m_creature, NPC_ANCIENT_VOID, 150.0f)) + { + if(!pTemp->isAlive()) + m_uiPhase = PHASE_INSANITY_3; + }else m_uiPhase = PHASE_INSANITY_3; + m_uiCheckTimer = 1000; + }else m_uiCheckTimer -= uiDiff; + }else if(m_uiPhase == PHASE_INSANITY_3) + { + m_creature->RemoveAurasDueToSpell(SPELL_INSANITY_CHANNEL); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_uiPhase = PHASE_FIGHT; + } + + } + //This do everything which is needed by Insanity spell (CUSTOM) + void DoInsanity() + { + m_creature->SummonCreature(NPC_ANCIENT_VOID, SpawnLoc[8].x, SpawnLoc[8].y, SpawnLoc[8].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + + for(int i = 0; i <= 7; ++i) + m_creature->SummonCreature(NPC_TWISTED_VISAGE, SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + + } +}; +/*###### +## mob_twisted_visage +######*/ +struct MANGOS_DLL_DECL mob_twisted_visageAI : public ScriptedAI +{ + mob_twisted_visageAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + void Reset() + { + m_creature->GetMotionMaster()->MovePoint(0, SpawnLoc[8].x, SpawnLoc[8].y, SpawnLoc[8].z); + } + void AttackStart(Unit *pWho) + { + return; + } + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if(uiType != POINT_MOTION_TYPE) + return; + + switch(uiPointId) + { + case 0: + if(Creature *pVoid = GetClosestCreatureWithEntry(m_creature, NPC_ANCIENT_VOID, 30.0f)) + { + float newsize = pVoid->GetFloatValue(OBJECT_FIELD_SCALE_X) + 0.25f; + uint32 health = pVoid->GetHealth() + 20000; + pVoid->SetHealth(health); + pVoid->SetFloatValue(OBJECT_FIELD_SCALE_X, newsize); + } + m_creature->ForcedDespawn(); + break; + } + } + void UpdateAI(const uint32 uiDiff) + { + + } +}; +/*###### +## mob_ancient_void +######*/ +struct MANGOS_DLL_DECL mob_ancient_voidAI : public ScriptedAI +{ + mob_ancient_voidAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + defaultsize = m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + uint8 m_uiPhase; + float defaultsize; + uint8 m_uiTransformPhase; + uint32 m_uiDelayTimer; + uint32 m_uiPhysicScreamTimer; + uint32 m_uiShadowBoltTimer; + uint32 m_uiOutOfCombatTimer; + float m_fVisages; + + void Reset() + { + m_fVisages = 0.0f; + m_uiDelayTimer = 1000; + m_uiOutOfCombatTimer = 20000; + m_uiPhase = 1; + m_uiTransformPhase = 1; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); + m_creature->SetDisplayId(MODEL_VOID_LIGHT); + SetCombatMovement(false); + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize); + DoCast(m_creature, SPELL_PRISON); + DoCast(m_creature, SPELL_BLUE_BEAM, true); + + m_uiPhysicScreamTimer = 0; + m_uiShadowBoltTimer = 8000; + if(m_bIsRegularMode) + m_creature->SetHealth(200000); + else + m_creature->SetHealth(300000); + } + void DoTransform(uint8 phase) + { + switch(phase) + { + case 1: + m_fVisages = (m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X) - 1.0f) / 0.25; + SetPhysicScreamTimer(); + DoCast(m_creature, SPELL_BLUE_FLAMES); + DoScriptText(SAY_VOID_CORRUPT, m_creature); + m_creature->RemoveAurasDueToSpell(SPELL_PRISON); + break; + case 2: + DoCast(m_creature, SPELL_RED_FLAMES); + m_creature->RemoveAurasDueToSpell(SPELL_BLUE_BEAM); + break; + case 3: + DoCast(m_creature, SPELL_SHAKE); + m_creature->SetDisplayId(MODEL_VOID_DARK); + break; + case 4: + m_creature->RemoveAurasDueToSpell(SPELL_RED_FLAMES); + break; + case 5: + DoScriptText(SAY_VOID_AGGRO, m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(true); + if(m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_uiPhase = 3; + break; + } + } + void SetPhysicScreamTimer() + { + if(m_fVisages < 3) + m_uiPhysicScreamTimer = 23000; + else if(m_fVisages < 5) + m_uiPhysicScreamTimer = 17000; + else if(m_fVisages < 7) + m_uiPhysicScreamTimer = 11000; + else if(m_fVisages < 9) + m_uiPhysicScreamTimer = 5000; + } + void UpdateAI(const uint32 uiDiff) + { + if(m_uiPhase == 1) + { + if(m_uiDelayTimer <= uiDiff) + { + if(!GetClosestCreatureWithEntry(m_creature, NPC_TWISTED_VISAGE, 150.0f)) + m_uiPhase = 2; + m_uiDelayTimer = 1000; + }else m_uiDelayTimer -= uiDiff; return; + } + if(m_uiPhase == 2) + { + if(m_uiDelayTimer <= uiDiff) + { + DoTransform(m_uiTransformPhase); + m_uiTransformPhase++; + m_uiDelayTimer = 2500; + }else m_uiDelayTimer -= uiDiff; + } + + if(m_uiPhase != 3) + return; + if(!m_creature->isInCombat()) + { + if(m_uiOutOfCombatTimer <= uiDiff) + m_creature->ForcedDespawn(); + else m_uiOutOfCombatTimer -= uiDiff; + + return; + } + + if(m_uiPhysicScreamTimer <= uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0),SPELL_PSYCHIC_SCREAM); + SetPhysicScreamTimer(); + }else m_uiPhysicScreamTimer -= uiDiff; + + //Shadowbolt voley + if(m_uiShadowBoltTimer <= uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHADOW_BOLT : SPELL_SHADOW_BOLT_H); + m_uiShadowBoltTimer = 8000; + }else m_uiShadowBoltTimer -= uiDiff; DoMeleeAttackIfReady(); } }; - CreatureAI* GetAI_boss_volazj(Creature* pCreature) { return new boss_volazjAI(pCreature); } +CreatureAI* GetAI_mob_twisted_visage(Creature* pCreature) +{ + return new mob_twisted_visageAI(pCreature); +} +CreatureAI* GetAI_mob_ancient_void(Creature* pCreature) +{ + return new mob_ancient_voidAI(pCreature); +} + void AddSC_boss_volazj() { Script *newscript; @@ -97,4 +496,14 @@ void AddSC_boss_volazj() newscript->Name = "boss_volazj"; newscript->GetAI = &GetAI_boss_volazj; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_twisted_visage"; + newscript->GetAI = &GetAI_mob_twisted_visage; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ancient_void"; + newscript->GetAI = &GetAI_mob_ancient_void; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/azjol-nerub/ahnkahet/instance_ahnkahet.cpp b/scripts/northrend/azjol-nerub/ahnkahet/instance_ahnkahet.cpp index 5dee80b57..87db005d1 100644 --- a/scripts/northrend/azjol-nerub/ahnkahet/instance_ahnkahet.cpp +++ b/scripts/northrend/azjol-nerub/ahnkahet/instance_ahnkahet.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -33,6 +33,7 @@ struct MANGOS_DLL_DECL instance_ahnkahet : public ScriptedInstance uint64 m_uiElderNadoxGUID; uint64 m_uiJedogaShadowseekerGUID; + uint64 m_uiTaldaramGUID; uint64 m_uiTaldaramDoorGUID; uint64 m_uiTaldaramVortexGUID; uint8 m_uiDevicesActivated; @@ -43,6 +44,7 @@ struct MANGOS_DLL_DECL instance_ahnkahet : public ScriptedInstance m_uiElderNadoxGUID = 0; m_uiJedogaShadowseekerGUID = 0; + m_uiTaldaramGUID = 0; m_uiTaldaramDoorGUID = 0; m_uiTaldaramVortexGUID = 0; m_uiDevicesActivated = 0; @@ -54,6 +56,7 @@ struct MANGOS_DLL_DECL instance_ahnkahet : public ScriptedInstance { case NPC_ELDER_NADOX: m_uiElderNadoxGUID = pCreature->GetGUID(); break; case NPC_JEDOGA_SHADOWSEEKER: m_uiJedogaShadowseekerGUID = pCreature->GetGUID(); break; + case NPC_TALDARAM: m_uiTaldaramGUID = pCreature->GetGUID(); break; } } @@ -81,7 +84,7 @@ struct MANGOS_DLL_DECL instance_ahnkahet : public ScriptedInstance break; } } - + void SetData(uint32 uiType, uint32 uiData) { debug_log("SD2: Instance Ahn'Kahet: SetData received for type %u with data %u",uiType,uiData); @@ -169,10 +172,16 @@ struct MANGOS_DLL_DECL instance_ahnkahet : public ScriptedInstance { switch(uiType) { - case TYPE_TALDARAM: + case TYPE_NADOX: return m_auiEncounter[0]; - case TYPE_JEDOGA: + case TYPE_TALDARAM: return m_auiEncounter[1]; + case TYPE_JEDOGA: + return m_auiEncounter[2]; + case TYPE_VOLAZJ: + return m_auiEncounter[3]; + case TYPE_AMANITAR: + return m_auiEncounter[4]; } return 0; } diff --git a/scripts/northrend/azjol-nerub/azjol-nerub/azjol-nerub.h b/scripts/northrend/azjol-nerub/azjol-nerub/azjol-nerub.h index 29f8258a0..a04889ffb 100644 --- a/scripts/northrend/azjol-nerub/azjol-nerub/azjol-nerub.h +++ b/scripts/northrend/azjol-nerub/azjol-nerub/azjol-nerub.h @@ -1,70 +1,46 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 - * This program is free software licensed under GPL version 2 - * Please see the included DOCS/LICENSE.TXT for more information */ +/* Copyright (C) 2006 - 2011 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 + */ + + +/* ScriptData +SDName: azjol-nerub +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Azjol-Nerub instance +EndScriptData */ #ifndef DEF_AZJOL_NERUB_H #define DEF_AZJOL_NERUB_H enum { - MAX_ENCOUNTER = 3, - MAX_WATCHERS = 3, + MAX_ENCOUNTER = 3, - TYPE_KRIKTHIR = 0, - TYPE_HADRONOX = 1, - TYPE_ANUBARAK = 2, + TYPE_KRIKTHIR = 1, + TYPE_HADRONOX = 2, + TYPE_ANUBARAK = 3, - NPC_KRIKTHIR = 28684, + GO_DOOR_KRIKTHIR = 192395, + GO_DOOR_ANUBARAK_1 = 192396, + GO_DOOR_ANUBARAK_2 = 192397, + GO_DOOR_ANUBARAK_3 = 192398, - SAY_SEND_GROUP_1 = -1601004, - SAY_SEND_GROUP_2 = -1601005, - SAY_SEND_GROUP_3 = -1601006, - - NPC_GASHRA = 28730, - NPC_NARJIL = 28729, - NPC_SILTHIK = 28731, - - GO_DOOR_KRIKTHIR = 192395, - GO_DOOR_ANUBARAK_1 = 192396, - GO_DOOR_ANUBARAK_2 = 192397, - GO_DOOR_ANUBARAK_3 = 192398 + DATA_WATCHER_GASHRA = 4, + DATA_WATCHER_SILTHIK = 5, + DATA_WATCHER_NARJIL = 6 }; -struct MANGOS_DLL_DECL instance_azjol_nerub : public ScriptedInstance -{ - public: - instance_azjol_nerub(Map* pMap); - ~instance_azjol_nerub() {}; - - void Initialize(); - void OnObjectCreate(GameObject* pGo); - void OnCreatureCreate(Creature* pCreature); - void OnCreatureEvade(Creature* pCreature); - void OnCreatureEnterCombat(Creature* pCreature); - void OnCreatureDeath(Creature* pCreature); - void SetData(uint32 uiType, uint32 uiData); - const char* Save() { return strInstData.c_str(); } - void Load(const char* chrIn); - void Update(uint32 uiDiff); - void DoSendWatcherOrKrikthir(); - - protected: - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - uint64 m_uiDoorKrikthirGUID; - uint64 m_uiDoorAnubarak1GUID; - uint64 m_uiDoorAnubarak2GUID; - uint64 m_uiDoorAnubarak3GUID; - - uint64 m_uiKrikthirGUID; - uint64 m_uiGashraGUID; - uint64 m_uiNarjilGUID; - uint64 m_uiSilthikGUID; - - uint64 m_uiPlayerGUID; - - uint64 m_auiWatcherGUIDS[3]; - uint32 m_uiWatcherTimer; -}; #endif diff --git a/scripts/northrend/azjol-nerub/azjol-nerub/boss_anubarak.cpp b/scripts/northrend/azjol-nerub/azjol-nerub/boss_anubarak.cpp index 461e7f5e2..2f675a395 100644 --- a/scripts/northrend/azjol-nerub/azjol-nerub/boss_anubarak.cpp +++ b/scripts/northrend/azjol-nerub/azjol-nerub/boss_anubarak.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -14,11 +14,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* ScriptData -SDName: Boss_Anubarak -SD%Complete: 20% -SDComment: -SDCategory: Azjol'NerubstrInstData +SDName: boss_anubarak +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Azjol-Nerub instance EndScriptData */ #include "precompiled.h" @@ -26,91 +27,324 @@ EndScriptData */ enum { - SAY_INTRO = -1601014, - SAY_AGGRO = -1601015, - SAY_KILL_1 = -1601016, - SAY_KILL_2 = -1601017, - SAY_KILL_3 = -1601018, - SAY_SUBMERGE_1 = -1601019, - SAY_SUBMERGE_2 = -1601020, - SAY_LOCUST_1 = -1601021, - SAY_LOCUST_2 = -1601022, - SAY_LOCUST_3 = -1601023, - SAY_DEATH = -1601024 + SPELL_CARRION_BEETLES = 53520, + SPELL_SUMMON_CARRION_BEETLES = 53521, + SPELL_LEECHING_SWARM = 53467, + SPELL_IMPALE = 53454, + SPELL_POUND = 53472, + SPELL_SUBMERGE = 53421, + + NPC_GUARDIAN = 29216, + NPC_VENOMANCER = 29217, + NPC_DATTER = 29213, + + SAY_INTRO = -1601010, + SAY_AGGRO = -1601000, + SAY_SLAY_1 = -1601001, + SAY_SLAY_2 = -1601002, + SAY_SLAY_3 = -1601003, + SAY_LOCUST_1 = -1601005, + SAY_LOCUST_2 = -1601006, + SAY_LOCUST_3 = -1601007, + SAY_SUBMERGE_1 = -1601008, + SAY_SUBMERGE_2 = -1601009, + SAY_DEATH = -1601004 +}; + +struct Locations +{ + float x, y, z; + uint32 id; }; -/*###### -## boss_anubarak -######*/ +static Locations SpawnPoint[2] = +{ + {550.7f, 282.8f, 224.3f}, + {551.1f, 229.4f, 224.3f} +}; struct MANGOS_DLL_DECL boss_anubarakAI : public ScriptedAI { - boss_anubarakAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_anubarakAI(Creature *pCreature) : ScriptedAI(pCreature) { - m_pInstance = (instance_azjol_nerub*)pCreature->GetInstanceData(); - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } - instance_azjol_nerub* m_pInstance; - bool m_bIsRegularMode; + ScriptedInstance *pInstance; + + bool bChanneling; + bool bGuardianSummoned; + bool bVenomancerSummoned; + bool bDatterSummoned; + uint8 uiPhase; + uint32 uiPhaseTimer; + uint32 uiEmergeTimer; + + uint32 uiCarrionBeetlesTimer; + uint32 uiLeechingSwarmTimer; + uint32 uiImpaleTimer; + uint32 uiPoundTimer; + uint32 uiSubmergeTimer; + uint32 uiUndergroundTimer; + uint32 uiVenomancerTimer; + uint32 uiDatterTimer; + + //SummonList lSummons; void Reset() { + + uiCarrionBeetlesTimer = 8000; + uiLeechingSwarmTimer = 20000; + uiImpaleTimer = 9000; + uiPoundTimer = 15000; + + uiPhase = 0; + uiPhaseTimer = 0; + bChanneling = false; + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveAurasDueToSpell(SPELL_SUBMERGE); + m_creature->SetDisplayId(27856); + + DespawnAll(); + + if (pInstance) + pInstance->SetData(TYPE_ANUBARAK, NOT_STARTED); } - void Aggro(Unit* pWho) + void AttackStart(Unit* who) { - DoScriptText(SAY_AGGRO, m_creature); + if(!who) return; + + if(uiPhase > 0) return; - if (m_pInstance) - m_pInstance->SetData(TYPE_ANUBARAK, IN_PROGRESS); + ScriptedAI::AttackStart(who); } - void KilledUnit(Unit* pVictim) + void DespawnAll() { - switch(urand(0, 2)) - { - case 0: DoScriptText(SAY_KILL_1, m_creature); break; - case 1: DoScriptText(SAY_KILL_2, m_creature); break; - case 2: DoScriptText(SAY_KILL_3, m_creature); break; - } + std::list m_pGuard; + GetCreatureListWithEntryInGrid(m_pGuard, m_creature, NPC_GUARDIAN, DEFAULT_VISIBILITY_INSTANCE); + + if (!m_pGuard.empty()) + for(std::list::iterator itr = m_pGuard.begin(); itr != m_pGuard.end(); ++itr) + { + (*itr)->ForcedDespawn(); + } + + std::list m_pVen; + GetCreatureListWithEntryInGrid(m_pVen, m_creature, NPC_VENOMANCER, DEFAULT_VISIBILITY_INSTANCE); + + if (!m_pVen.empty()) + for(std::list::iterator iter = m_pVen.begin(); iter != m_pVen.end(); ++iter) + { + (*iter)->ForcedDespawn(); + } + + std::list m_pDat; + GetCreatureListWithEntryInGrid(m_pDat, m_creature, NPC_DATTER, DEFAULT_VISIBILITY_INSTANCE); + + if (!m_pDat.empty()) + for(std::list::iterator iter = m_pDat.begin(); iter != m_pDat.end(); ++iter) + { + (*iter)->ForcedDespawn(); + } } - void JustDied(Unit* pKiller) + void EnterCombat(Unit *pWho) { - DoScriptText(SAY_DEATH, m_creature); + DoScriptText(SAY_AGGRO, m_creature); - if (m_pInstance) - m_pInstance->SetData(TYPE_ANUBARAK, DONE); + if (pInstance) + pInstance->SetData(TYPE_ANUBARAK, IN_PROGRESS); } - void JustReachedHome() + void NextPhase() { - if (m_pInstance) - m_pInstance->SetData(TYPE_ANUBARAK, NOT_STARTED); + m_creature->InterruptNonMeleeSpells(false); + ++uiPhaseTimer; + + bGuardianSummoned = false; + bVenomancerSummoned = false; + bDatterSummoned = false; + + uiUndergroundTimer = 40000; + uiVenomancerTimer = 25000; + uiDatterTimer = 32000; + + DoCast(m_creature, SPELL_SUBMERGE); + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + + uiPhase = 1; } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 diff) { + //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - DoMeleeAttackIfReady(); + if (bChanneling == true) + { + for (uint8 i = 0; i < 4; ++i) + DoCast(m_creature->getVictim(), SPELL_SUMMON_CARRION_BEETLES, true); + bChanneling = false; + } + + if (uiPhase == 1) + { + if (uiImpaleTimer <= diff) + { + if(m_creature->HasAura(SPELL_SUBMERGE)) + { + m_creature->RemoveAurasDueToSpell(SPELL_SUBMERGE); + m_creature->SetDisplayId(11686); + m_creature->StopMoving(); + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); + } + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_IMPALE); + uiImpaleTimer = 9000; + } else uiImpaleTimer -= diff; + + if (!bGuardianSummoned) + { + for (uint8 i = 0; i < 2; ++i) + { + if (Creature *Guardian = m_creature->SummonCreature(NPC_GUARDIAN,SpawnPoint[i].x,SpawnPoint[i].y,SpawnPoint[i].z,0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + { + Guardian->AddThreat(m_creature->getVictim(), 0.0f); + Guardian->SetInCombatWithZone(); + } + } + bGuardianSummoned = true; + } + + if (!bVenomancerSummoned) + { + if (uiVenomancerTimer <= diff) + { + if (uiPhaseTimer > 1) + { + for (uint8 i = 0; i < 2; ++i) + { + if (Creature *Venomancer = m_creature->SummonCreature(NPC_VENOMANCER,SpawnPoint[i].x,SpawnPoint[i].y,SpawnPoint[i].z,0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + { + Venomancer->AddThreat(m_creature->getVictim(), 0.0f); + Venomancer->SetInCombatWithZone(); + } + } + bVenomancerSummoned = true; + } + } else uiVenomancerTimer -= diff; + } + + if (!bDatterSummoned) + { + if (uiDatterTimer <= diff) + { + if (uiPhaseTimer > 2) + { + for (uint8 i = 0; i < 2; ++i) + { + if (Creature *Datter = m_creature->SummonCreature(NPC_DATTER,SpawnPoint[i].x,SpawnPoint[i].y,SpawnPoint[i].z,0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000)) + { + Datter->AddThreat(m_creature->getVictim(), 0.0f); + Datter->SetInCombatWithZone(); + } + } + bDatterSummoned = true; + } + } else uiDatterTimer -= diff; + } + + if (uiUndergroundTimer <= diff) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetDisplayId(27856); + DoCast(m_creature, 50142); + uiEmergeTimer = 2000; + uiPhase = 2; + } else uiUndergroundTimer -= diff; + } + + if (uiPhase == 2) + { + if (uiEmergeTimer <= diff) + { + uiPhase = 0; + m_creature->RemoveAurasDueToSpell(50142); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } else uiEmergeTimer -= diff; + } + + if (uiPhase == 0) + { + if (uiLeechingSwarmTimer <= diff) + { + DoCast(m_creature, SPELL_LEECHING_SWARM); + uiLeechingSwarmTimer = 19000; + } else uiLeechingSwarmTimer -= diff; + + if (uiCarrionBeetlesTimer <= diff) + { + bChanneling = true; + DoCast(m_creature->getVictim(), SPELL_CARRION_BEETLES); + uiCarrionBeetlesTimer = 25000; + } else uiCarrionBeetlesTimer -= diff; + + if (uiPoundTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_POUND); + uiPoundTimer = 16500; + } else uiPoundTimer -= diff; + + DoMeleeAttackIfReady(); + } + + if(uiPhaseTimer == 0 && m_creature->GetHealthPercent() < 75.0f) + NextPhase(); + + if(uiPhaseTimer == 1 && m_creature->GetHealthPercent() < 50.0f) + NextPhase(); + + if(uiPhaseTimer == 2 && m_creature->GetHealthPercent() < 25.0f) + NextPhase(); + } + + void JustDied(Unit *pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + if (pInstance) + pInstance->SetData(TYPE_ANUBARAK, DONE); + } + + void KilledUnit(Unit *pVictim) + { + if (pVictim == m_creature) + return; + + DoScriptText(urand(SAY_SLAY_1,SAY_SLAY_2), m_creature); } + }; -CreatureAI* GetAI_boss_anubarak(Creature* pCreature) +CreatureAI* GetAI_boss_anubarak(Creature *pCreature) { - return new boss_anubarakAI(pCreature); + return new boss_anubarakAI (pCreature); } void AddSC_boss_anubarak() { - Script* pNewScript; + Script *newscript; - pNewScript = new Script; - pNewScript->Name = "boss_anubarak"; - pNewScript->GetAI = &GetAI_boss_anubarak; - pNewScript->RegisterSelf(); + newscript = new Script; + newscript->Name = "boss_anubarak"; + newscript->GetAI = &GetAI_boss_anubarak; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/azjol-nerub/azjol-nerub/boss_hadronox.cpp b/scripts/northrend/azjol-nerub/azjol-nerub/boss_hadronox.cpp index 0189f7348..1be3b8246 100644 --- a/scripts/northrend/azjol-nerub/azjol-nerub/boss_hadronox.cpp +++ b/scripts/northrend/azjol-nerub/azjol-nerub/boss_hadronox.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -14,66 +14,198 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* ScriptData -SDName: Boss_Hadronox -SD%Complete: 20% -SDComment: -SDCategory: Azjol'Nerub +SDName: boss_hadronox +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Azjol-Nerub instance EndScriptData */ +/* +* Comment: No Waves atm and the doors spells are crazy... +* +* When your group enters the main room (the one after the bridge), you will notice a group of 3 Nerubians. +* When you engage them, 2 more groups like this one spawn behind the first one - it is important to pull the first group back, +* so you don't aggro all 3. Hadronox will be under you, fighting Nerubians. +* +* This is the timed gauntlet - waves of non-elite spiders +* will spawn from the 3 doors located a little above the main room, and will then head down to fight Hadronox. After clearing the +* main room, it is recommended to just stay in it, kill the occasional non-elites that will attack you instead of the boss, and wait for +* Hadronox to make his way to you. When Hadronox enters the main room, she will web the doors, and no more non-elites will spawn. +*/ #include "precompiled.h" #include "azjol-nerub.h" enum { - + SPELL_ACID_CLOUD = 53400, // Victim + SPELL_LEECH_POISON = 53030, // Victim + SPELL_PIERCE_ARMOR = 53418, // Victim + SPELL_WEB_GRAB = 57731, // Victim + SPELL_WEB_FRONT_DOORS = 53177, // Self + SPELL_WEB_SIDE_DOORS = 53185, // Self }; -/*###### -## boss_hadronox -######*/ - struct MANGOS_DLL_DECL boss_hadronoxAI : public ScriptedAI { boss_hadronoxAI(Creature* pCreature) : ScriptedAI(pCreature) { - m_pInstance = (instance_azjol_nerub*)pCreature->GetInstanceData(); - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); + bFirstTime = true; } - instance_azjol_nerub* m_pInstance; - bool m_bIsRegularMode; + ScriptedInstance* pInstance; + + uint32 uiAcidTimer; + uint32 uiLeechTimer; + uint32 uiPierceTimer; + uint32 uiGrabTimer; + uint32 uiDoorsTimer; + uint32 uiCheckDistanceTimer; + + bool bFirstTime; + + float fMaxDistance; void Reset() { + m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 9.0f); + m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 9.0f); + + uiAcidTimer = urand(10000,14000); + uiLeechTimer = urand(3000,9000); + uiPierceTimer = urand(1000,3000); + uiGrabTimer = urand(15000,19000); + uiDoorsTimer = urand(20000,30000); + uiCheckDistanceTimer = 2000; + + fMaxDistance = 50.0f; + + if (pInstance && (pInstance->GetData(TYPE_HADRONOX) != DONE && !bFirstTime)) + pInstance->SetData(TYPE_HADRONOX, FAIL); + + bFirstTime = false; + } + + //when Hadronox kills any enemy (that includes a party member) she will regain 10% of her HP if the target had Leech Poison on + void KilledUnit(Unit* Victim) + { + // not sure if this aura check is correct, I think it is though + if (!Victim || !Victim->HasAura(SPELL_LEECH_POISON) || !m_creature->isAlive()) + return; + + uint32 health = m_creature->GetMaxHealth()/10; + + if ((m_creature->GetHealth()+health) >= m_creature->GetMaxHealth()) + m_creature->SetHealth(m_creature->GetMaxHealth()); + else + m_creature->SetHealth(m_creature->GetHealth()+health); + } + + void JustDied(Unit* Killer) + { + if (pInstance) + pInstance->SetData(TYPE_HADRONOX, DONE); } - void KilledUnit(Unit* pVictim) + void EnterCombat(Unit* who) { - m_creature->SetHealth(m_creature->GetHealth() + (m_creature->GetMaxHealth() * 0.1)); + if (pInstance) + pInstance->SetData(TYPE_HADRONOX, IN_PROGRESS); + m_creature->SetInCombatWithZone(); } - void UpdateAI(const uint32 uiDiff) + void CheckDistance(float dist, const uint32 uiDiff) { + if (!m_creature->isInCombat()) + return; + + float x=0.0f, y=0.0f, z=0.0f; + m_creature->GetRespawnCoord(x,y,z); + + if (uiCheckDistanceTimer <= uiDiff) + uiCheckDistanceTimer = 5000; + else + { + uiCheckDistanceTimer -= uiDiff; + return; + } + if (m_creature->IsInEvadeMode() || !m_creature->getVictim()) + return; + if (m_creature->GetDistance(x,y,z) > dist) + EnterEvadeMode(); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + // Without he comes up through the air to players on the bridge after krikthir if players crossing this bridge! + CheckDistance(fMaxDistance, diff); + + if (m_creature->HasAura(SPELL_WEB_FRONT_DOORS) || m_creature->HasAura(SPELL_WEB_SIDE_DOORS)) + { + if (IsCombatMovement()) + SetCombatMovement(false); + } + else if (!IsCombatMovement()) + SetCombatMovement(true); + + if (uiPierceTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_PIERCE_ARMOR); + uiPierceTimer = 8000; + } else uiPierceTimer -= diff; + + if (uiAcidTimer <= diff) + { + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_ACID_CLOUD); + + uiAcidTimer = urand(20000,30000); + } else uiAcidTimer -= diff; + + if (uiLeechTimer <= diff) + { + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_LEECH_POISON); + + uiLeechTimer = urand(11000,14000); + } else uiLeechTimer -= diff; + + if (uiGrabTimer <= diff) + { + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) // Draws all players (and attacking Mobs) to itself. + DoCast(pTarget, SPELL_WEB_GRAB); + + uiGrabTimer = urand(15000,30000); + } else uiGrabTimer -= diff; + + if (uiDoorsTimer <= diff) + { + //DoCast(me, urand(SPELL_WEB_FRONT_DOORS, SPELL_WEB_SIDE_DOORS)); + uiDoorsTimer = urand(30000,60000); + } else uiDoorsTimer -= diff; + DoMeleeAttackIfReady(); } }; CreatureAI* GetAI_boss_hadronox(Creature* pCreature) { - return new boss_hadronoxAI(pCreature); + return new boss_hadronoxAI (pCreature); } void AddSC_boss_hadronox() { - Script* pNewScript; + Script *newscript; - pNewScript = new Script; - pNewScript->Name = "boss_hadronox"; - pNewScript->GetAI = &GetAI_boss_hadronox; - pNewScript->RegisterSelf(); + newscript = new Script; + newscript->Name = "boss_hadronox"; + newscript->GetAI = &GetAI_boss_hadronox; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/azjol-nerub/azjol-nerub/boss_krikthir.cpp b/scripts/northrend/azjol-nerub/azjol-nerub/boss_krikthir.cpp index e122b4069..753330df3 100644 --- a/scripts/northrend/azjol-nerub/azjol-nerub/boss_krikthir.cpp +++ b/scripts/northrend/azjol-nerub/azjol-nerub/boss_krikthir.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -14,172 +14,558 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* ScriptData -SDName: Boss_Krikthir -SD%Complete: 90% -SDComment: Implement Achievement -SDCategory: Azjol'Nerub +SDName: boss_krikthir +SD%Complete: ?% +SDComment: by MaxXx2021 +SDCategory: Azjol-Nerub instance EndScriptData */ #include "precompiled.h" #include "azjol-nerub.h" -enum -{ - SAY_AGGRO = -1601000, - SAY_KILL_1 = -1601001, - SAY_KILL_2 = -1601002, - SAY_KILL_3 = -1601003, - SAY_PREFIGHT_1 = -1601007, - SAY_PREFIGHT_2 = -1601008, - SAY_PREFIGHT_3 = -1601009, - SAY_SWARM_1 = -1601010, - SAY_SWARM_2 = -1601011, - SAY_DEATH = -1601012, - EMOTE_BOSS_GENERIC_FRENZY = -1000005, - - SPELL_SWARM = 52440, - SPELL_CURSE_OF_FATIGUE = 52592, - SPELL_CURSE_OF_FATIGUE_H = 59368, - SPELL_MINDFLAY = 52586, - SPELL_MINDFLAY_H = 59367, - SPELL_FRENZY = 28747, - - NPC_SKITTERING_SWARMER = 28735, - NPC_SKITTERING_INFECTOR = 28736 +enum Spells +{ + SPELL_MIND_FLAY = 52586, + H_SPELL_MIND_FLAY = 59367, + SPELL_CURSE_OF_FATIGUE = 52592, + H_SPELL_CURSE_OF_FATIGUE = 59368, + SPELL_FRENZY = 28747, //maybe 53361 + SPELL_SUMMON_SKITTERING_SWARMER = 52438, //AOE Effect 140, maybe 52439 + SPELL_SUMMON_SKITTERING_SWARMER_1 = 52439, //Summon 3x 28735 + H_SPELL_ACID_SPLASH = 59363, + SPELL_ACID_SPLASH = 52446, + SPELL_CHARGE = 16979,//maybe is another spell + SPELL_BACKSTAB = 52540, + SPELL_SHADOW_BOLT = 52534, + H_SPELL_SHADOW_BOLT = 59357, + SPELL_SHADOW_NOVA = 52535, + H_SPELL_SHADOW_NOVA = 59358, + SPELL_STRIKE = 52532, + SPELL_CLEAVE = 49806, + SPELL_ENRAGE = 52470, + SPELL_INFECTED_BITE = 52469, + H_SPELL_INFECTED_BITE = 59364, + SPELL_WEB_WRAP = 52086,//the spell is not working properly + SPELL_BLINDING_WEBS = 52524, + H_SPELL_BLINDING_WEBS = 59365, + SPELL_POSION_SPRAY = 52493, + H_SPELL_POSION_SPRAY = 59366, + + MOB_SKITTERING_SWARMER = 28735, + MOB_SKITTERING_SWARMER_CONTROLLER = 32593, + MOB_SKITTERING_INFECTIOR = 28736, + + SAY_AGGRO = -1601011, + SAY_SLAY_1 = -1601012, + SAY_SLAY_2 = -1601013, + SAY_DEATH = -1601014, + //Not in db + SAY_SEND_GROUP_1 = -1601020, + SAY_SEND_GROUP_2 = -1601021, + SAY_SEND_GROUP_3 = -1601022, + SAY_SWARM_1 = -1601015, + SAY_SWARM_2 = -1601016, + SAY_PREFIGHT_1 = -1601017, + SAY_PREFIGHT_2 = -1601018, + SAY_PREFIGHT_3 = -1601019, + + ACHIEV_WATH_HIM_DIE = 1296 }; -/*###### -## boss_krikthir -######*/ +struct Locations +{ + float x, y, z, o; + uint32 id; +}; +static Locations SpawnPoint[8] = +{ + {566.164f, 682.087f, 769.079f, 2.21f}, + {529.042f, 706.941f, 777.298f, 1.08f}, + {489.975f, 671.239f, 772.131f, 0.26f}, + {488.556f, 692.950f, 771.764f, 4.88f}, + {553.340f, 640.387f, 777.419f, 1.20f}, + {517.486f, 706.398f, 777.335f, 5.35f}, + {504.010f, 637.693f, 777.479f, 0.50f}, + {552.625f, 706.408f, 777.177f, 3.43f} +}; struct MANGOS_DLL_DECL boss_krikthirAI : public ScriptedAI { - boss_krikthirAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_krikthirAI(Creature *pCreature) : ScriptedAI(pCreature) { - m_pInstance = (instance_azjol_nerub*)pCreature->GetInstanceData(); - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } - instance_azjol_nerub* m_pInstance; - bool m_bIsRegularMode; - - bool m_bFrenzy; - bool m_bIntroSpeech; + ScriptedInstance* pInstance; - uint32 m_uiSwarmTimer; - uint32 m_uiCurseTimer; - uint32 m_uiMindFlayTimer; + uint32 uiMindFlayTimer; + uint32 uiCurseFatigueTimer; + uint32 uiSummonTimer; void Reset() { - m_uiSwarmTimer = 15000; - m_uiCurseTimer = 20000; - m_uiMindFlayTimer = 8000; + uiMindFlayTimer = 15000; + uiCurseFatigueTimer = 12000; - m_bIntroSpeech = false; - m_bFrenzy = false; + if (pInstance) + pInstance->SetData(TYPE_KRIKTHIR, NOT_STARTED); } - void Aggro(Unit* pWho) + void EnterCombat(Unit* who) { DoScriptText(SAY_AGGRO, m_creature); + Summon(); + uiSummonTimer = 15000; + + if (pInstance) + pInstance->SetData(TYPE_KRIKTHIR, IN_PROGRESS); } - void KilledUnit(Unit* pVictim) + void Summon() + { + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[0].x,SpawnPoint[0].y,SpawnPoint[0].z,SpawnPoint[0].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[0].x,SpawnPoint[0].y,SpawnPoint[0].z,SpawnPoint[0].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[1].x,SpawnPoint[1].y,SpawnPoint[1].z,SpawnPoint[1].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[1].x,SpawnPoint[1].y,SpawnPoint[1].z,SpawnPoint[1].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[2].x,SpawnPoint[2].y,SpawnPoint[2].z,SpawnPoint[2].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[2].x,SpawnPoint[2].y,SpawnPoint[2].z,SpawnPoint[2].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[3].x,SpawnPoint[3].y,SpawnPoint[3].z,SpawnPoint[3].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[3].x,SpawnPoint[3].y,SpawnPoint[3].z,SpawnPoint[3].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_INFECTIOR,SpawnPoint[4].x,SpawnPoint[4].y,SpawnPoint[4].z,SpawnPoint[4].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[4].x,SpawnPoint[4].y,SpawnPoint[4].z,SpawnPoint[4].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_INFECTIOR,SpawnPoint[5].x,SpawnPoint[5].y,SpawnPoint[5].z,SpawnPoint[5].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[5].x,SpawnPoint[5].y,SpawnPoint[5].z,SpawnPoint[5].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_INFECTIOR,SpawnPoint[6].x,SpawnPoint[6].y,SpawnPoint[6].z,SpawnPoint[6].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[6].x,SpawnPoint[6].y,SpawnPoint[6].z,SpawnPoint[6].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[7].x,SpawnPoint[7].y,SpawnPoint[7].z,SpawnPoint[7].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + m_creature->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[7].x,SpawnPoint[7].y,SpawnPoint[7].z,SpawnPoint[7].o,TEMPSUMMON_CORPSE_TIMED_DESPAWN,25000); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (uiSummonTimer <= diff) + { + Summon(); + uiSummonTimer = 15000; + } else uiSummonTimer -= diff; + + if (uiMindFlayTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_MIND_FLAY); + uiMindFlayTimer = 15000; + } else uiMindFlayTimer -= diff; + + if (uiCurseFatigueTimer <= diff) + { + //WowWiki say "Curse of Fatigue-Kirk'thir will cast Curse of Fatigue on 2-3 targets periodically." + if(Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_CURSE_OF_FATIGUE); + if(Unit *pTarget_1 = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget_1, SPELL_CURSE_OF_FATIGUE); + + uiCurseFatigueTimer = 10000; + } else uiCurseFatigueTimer -= diff; + + if (!m_creature->HasAura(SPELL_FRENZY) && m_creature->GetHealthPercent() < 10.0f) + DoCast(m_creature, SPELL_FRENZY); + + DoMeleeAttackIfReady(); + } + void JustDied(Unit* killer) { - switch(urand(0, 2)) + DoScriptText(SAY_DEATH, m_creature); + + if (pInstance) { - case 0: DoScriptText(SAY_KILL_1, m_creature); break; - case 1: DoScriptText(SAY_KILL_2, m_creature); break; - case 2: DoScriptText(SAY_KILL_3, m_creature); break; + pInstance->SetData(TYPE_KRIKTHIR, DONE); + //Achievement: Watch him die + //Creature *pAdd1, *pAdd2, *pAdd3; + //if ((pAdd1 = pInstance->instance->GetCreature(pInstance->GetData64(DATA_WATCHER_GASHRA))) && pAdd1->isAlive() && + //(pAdd2 = pInstance->instance->GetCreature(pInstance->GetData64(DATA_WATCHER_SILTHIK))) && pAdd2->isAlive() && + //(pAdd3 = pInstance->instance->GetCreature(pInstance->GetData64(DATA_WATCHER_NARJIL))) && pAdd3->isAlive() && + //m_bIsRegularMode) + //pInstance->DoCompleteAchievement(ACHIEV_WATH_HIM_DIE); } } + void KilledUnit(Unit *victim) + { + if (victim == m_creature) + return; - void MoveInLineOfSight (Unit* pWho) + DoScriptText(urand(SAY_SLAY_1,SAY_SLAY_2), m_creature); + } + + void JustSummoned(Creature* summoned) { - if (!m_bIntroSpeech && m_creature->IsWithinDistInMap(pWho, DEFAULT_VISIBILITY_INSTANCE)) + summoned->GetMotionMaster()->MovePoint(0,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ()); + } +}; + +struct MANGOS_DLL_DECL npc_skittering_infectorAI : public ScriptedAI +{ + npc_skittering_infectorAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + void Reset() + { + } + + void JustDied(Unit* killer) + { + DoCast(m_creature->getVictim(), SPELL_ACID_SPLASH); + } + + void UpdateAI(const uint32 uiDiff) + { + DoMeleeAttackIfReady(); + return; + } +}; + +CreatureAI* GetAI_npc_skittering_infector(Creature* pCreature) +{ + return new npc_skittering_infectorAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_anub_ar_skirmisherAI : public ScriptedAI +{ + npc_anub_ar_skirmisherAI(Creature *c) : ScriptedAI(c) + { + Reset(); + } + + uint32 uiChargeTimer; + uint32 uiBackstabTimer; + + void Reset() + { + uiChargeTimer = 11000; + uiBackstabTimer = 7000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (uiChargeTimer <= diff) { - switch(urand(0, 2)) + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - case 0: DoScriptText(SAY_PREFIGHT_1, m_creature); break; - case 1: DoScriptText(SAY_PREFIGHT_2, m_creature); break; - case 2: DoScriptText(SAY_PREFIGHT_3, m_creature); break; + DoResetThreat(); + m_creature->AddThreat(pTarget,1.0f); + DoCast(pTarget, SPELL_CHARGE, true); } - m_bIntroSpeech = true; - } + uiChargeTimer = 15000; + } else uiChargeTimer -= diff; + + if (uiBackstabTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_BACKSTAB); + uiBackstabTimer = 12000; + } else uiBackstabTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; - void JustDied(Unit* pKiller) +struct MANGOS_DLL_DECL npc_anub_ar_shadowcasterAI : public ScriptedAI +{ + npc_anub_ar_shadowcasterAI(Creature *pCreature) : ScriptedAI(pCreature) { - DoScriptText(SAY_DEATH, m_creature); + Reset(); + } + + uint32 uiShadowBoltTimer; + uint32 uiShadowNovaTimer; - if (m_pInstance) - m_pInstance->SetData(TYPE_KRIKTHIR, DONE); + void Reset() + { + uiShadowBoltTimer = 6000; + uiShadowNovaTimer = 15000; } - void JustSummoned(Creature* pSummoned) + void UpdateAI(const uint32 diff) { - uint32 uiEntry = pSummoned->GetEntry(); - if (uiEntry == NPC_SKITTERING_SWARMER || uiEntry == NPC_SKITTERING_INFECTOR) - pSummoned->AI()->AttackStart(m_creature->getVictim()); + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (uiShadowBoltTimer <= diff) + { + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_SHADOW_BOLT); + uiShadowBoltTimer = 15000; + } else uiShadowBoltTimer -= diff; + + if (uiShadowNovaTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_SHADOW_NOVA); + uiShadowNovaTimer = 17000; + } else uiShadowNovaTimer -= diff; + + DoMeleeAttackIfReady(); } +}; - void UpdateAI(const uint32 uiDiff) +struct MANGOS_DLL_DECL npc_anub_ar_warriorAI : public ScriptedAI +{ + npc_anub_ar_warriorAI(Creature *c) : ScriptedAI(c){ Reset(); } + + uint32 uiCleaveTimer; + uint32 uiStrikeTimer; + + void Reset() + { + uiCleaveTimer = 11000; + uiStrikeTimer = 6000; + } + + void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (!m_bFrenzy && m_creature->GetHealthPercent() <= 10.0f) + if (uiStrikeTimer <= diff) { - DoCastSpellIfCan(m_creature, SPELL_FRENZY); - DoScriptText(EMOTE_BOSS_GENERIC_FRENZY, m_creature); - m_bFrenzy = true; - } + DoCast(m_creature->getVictim(), SPELL_STRIKE, true); + uiStrikeTimer = 15000; + } else uiStrikeTimer -= diff; - if (m_uiCurseTimer < uiDiff) + if (uiCleaveTimer <= diff) { - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CURSE_OF_FATIGUE : SPELL_CURSE_OF_FATIGUE_H); - m_uiCurseTimer = 20000; + DoCast(m_creature->getVictim(), SPELL_CLEAVE, true); + uiCleaveTimer = 17000; + } else uiCleaveTimer -= diff; - } - else - m_uiCurseTimer -= uiDiff; + DoMeleeAttackIfReady(); + + } + +}; + +struct MANGOS_DLL_DECL npc_watcher_gashraAI : public ScriptedAI +{ + npc_watcher_gashraAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 uiWebWrapTimer; + uint32 uiInfectedBiteTimer; - if (m_uiMindFlayTimer < uiDiff) + void Reset() + { + uiWebWrapTimer = 11000; + uiInfectedBiteTimer = 4000; + } + + void EnterCombat(Unit* who) + { + DoCast(m_creature, SPELL_ENRAGE, true); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (uiWebWrapTimer <= diff) { - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_MINDFLAY : SPELL_MINDFLAY_H); - m_uiMindFlayTimer = 8000; - } - else - m_uiMindFlayTimer -= uiDiff; + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_WEB_WRAP); + uiWebWrapTimer = 17000; + } else uiWebWrapTimer -= diff; - if (m_uiSwarmTimer < uiDiff) + if (uiInfectedBiteTimer <= diff) { - DoScriptText(urand(0, 1) ? SAY_SWARM_1 : SAY_SWARM_2, m_creature); - DoCastSpellIfCan(m_creature, SPELL_SWARM); - m_uiSwarmTimer = 15000; + DoCast(m_creature->getVictim(), SPELL_INFECTED_BITE); + uiInfectedBiteTimer = 15000; + } else uiInfectedBiteTimer -= diff; - } - else - m_uiSwarmTimer -= uiDiff; + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL npc_watcher_narjilAI : public ScriptedAI +{ + npc_watcher_narjilAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 uiWebWrapTimer; + uint32 uiInfectedBiteTimer; + uint32 uiBindingWebsTimer; + + void Reset() + { + uiWebWrapTimer = 11000; + uiInfectedBiteTimer = 4000; + uiBindingWebsTimer = 17000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (uiWebWrapTimer <= diff) + { + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_WEB_WRAP); + uiWebWrapTimer = 15000; + } else uiWebWrapTimer -= diff; + + if (uiInfectedBiteTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_INFECTED_BITE); + uiInfectedBiteTimer = 11000; + } else uiInfectedBiteTimer -= diff; + + if (uiBindingWebsTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_BLINDING_WEBS); + uiBindingWebsTimer = 17000; + } else uiBindingWebsTimer -= diff; DoMeleeAttackIfReady(); } }; +struct MANGOS_DLL_DECL npc_watcher_silthikAI : public ScriptedAI +{ + npc_watcher_silthikAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 uiWebWrapTimer; + uint32 uiInfectedBiteTimer; + uint32 uiPoisonSprayTimer; + + void Reset() + { + uiWebWrapTimer = 11000; + uiInfectedBiteTimer = 4000; + uiPoisonSprayTimer = 15000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (uiWebWrapTimer <= diff) + { + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_WEB_WRAP); + + uiWebWrapTimer = 15000; + } else uiWebWrapTimer -= diff; + + if (uiInfectedBiteTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_INFECTED_BITE); + uiInfectedBiteTimer = 15000; + } else uiInfectedBiteTimer -= diff; + + if (uiPoisonSprayTimer <= diff) + { + DoCast(m_creature->getVictim(), SPELL_POSION_SPRAY); + uiPoisonSprayTimer = 17000; + } else uiPoisonSprayTimer -= diff; + + DoMeleeAttackIfReady(); + + } +}; + CreatureAI* GetAI_boss_krikthir(Creature* pCreature) { return new boss_krikthirAI(pCreature); } +CreatureAI* GetAI_npc_anub_ar_skirmisher(Creature* pCreature) +{ + return new npc_anub_ar_skirmisherAI(pCreature); +} + +CreatureAI* GetAI_npc_anub_ar_shadowcaster(Creature* pCreature) +{ + return new npc_anub_ar_shadowcasterAI(pCreature); +} + +CreatureAI* GetAI_npc_anub_ar_warrior(Creature* pCreature) +{ + return new npc_anub_ar_warriorAI(pCreature); +} + +CreatureAI* GetAI_npc_watcher_gashra(Creature* pCreature) +{ + return new npc_watcher_gashraAI(pCreature); +} + +CreatureAI* GetAI_npc_watcher_narjil(Creature* pCreature) +{ + return new npc_watcher_narjilAI(pCreature); +} + +CreatureAI* GetAI_npc_watcher_silthik(Creature* pCreature) +{ + return new npc_watcher_silthikAI(pCreature); +} + void AddSC_boss_krikthir() { - Script* pNewScript; + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_krikthir"; + newscript->GetAI = &GetAI_boss_krikthir; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_skittering_infector"; + newscript->GetAI = &GetAI_npc_skittering_infector; + newscript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "boss_krikthir"; - pNewScript->GetAI = &GetAI_boss_krikthir; - pNewScript->RegisterSelf(); + newscript = new Script; + newscript->Name = "npc_anub_ar_skirmisher"; + newscript->GetAI = &GetAI_npc_anub_ar_skirmisher; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_anub_ar_shadowcaster"; + newscript->GetAI = &GetAI_npc_anub_ar_shadowcaster; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_watcher_gashra"; + newscript->GetAI = &GetAI_npc_watcher_gashra; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_anub_ar_warrior"; + newscript->GetAI = &GetAI_npc_anub_ar_warrior; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_watcher_silthik"; + newscript->GetAI = &GetAI_npc_watcher_silthik; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_watcher_narjil"; + newscript->GetAI = &GetAI_npc_watcher_narjil; + newscript->RegisterSelf(); } + diff --git a/scripts/northrend/azjol-nerub/azjol-nerub/instance_azjol-nerub.cpp b/scripts/northrend/azjol-nerub/azjol-nerub/instance_azjol-nerub.cpp index 4920327e0..9bc0fff1d 100644 --- a/scripts/northrend/azjol-nerub/azjol-nerub/instance_azjol-nerub.cpp +++ b/scripts/northrend/azjol-nerub/azjol-nerub/instance_azjol-nerub.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,207 +24,162 @@ EndScriptData */ #include "precompiled.h" #include "azjol-nerub.h" -instance_azjol_nerub::instance_azjol_nerub(Map* pMap) : ScriptedInstance(pMap), - m_uiDoorKrikthirGUID(0), - m_uiDoorAnubarak1GUID(0), - m_uiDoorAnubarak2GUID(0), - m_uiDoorAnubarak3GUID(0), - - m_uiKrikthirGUID(0), - m_uiGashraGUID(0), - m_uiNarjilGUID(0), - m_uiSilthikGUID(0), - - m_uiPlayerGUID(0), - - m_uiWatcherTimer(0) +struct MANGOS_DLL_DECL instance_azjol_nerub : public ScriptedInstance { - Initialize(); -} + instance_azjol_nerub(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; -void instance_azjol_nerub::Initialize() -{ - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - memset(&m_auiWatcherGUIDS, 0, sizeof(m_auiWatcherGUIDS)); -} + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string strInstData; -void instance_azjol_nerub::OnObjectCreate(GameObject* pGo) -{ - switch(pGo->GetEntry()) - { - case GO_DOOR_KRIKTHIR: - m_uiDoorKrikthirGUID = pGo->GetGUID(); - if (m_auiEncounter[0] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_DOOR_ANUBARAK_1: - m_uiDoorAnubarak1GUID = pGo->GetGUID(); - if (m_auiEncounter[2] == DONE || m_auiEncounter[2] == NOT_STARTED) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_DOOR_ANUBARAK_2: - m_uiDoorAnubarak2GUID = pGo->GetGUID(); - if (m_auiEncounter[2] == DONE || m_auiEncounter[2] == NOT_STARTED) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_DOOR_ANUBARAK_3: - m_uiDoorAnubarak3GUID = pGo->GetGUID(); - if (m_auiEncounter[2] == DONE || m_auiEncounter[2] == NOT_STARTED) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - } -} + uint64 m_uiDoor_KrikthirGUID; + uint64 m_uiDoor_Anubarak_1GUID; + uint64 m_uiDoor_Anubarak_2GUID; + uint64 m_uiDoor_Anubarak_3GUID; -void instance_azjol_nerub::OnCreatureCreate(Creature* pCreature) -{ - switch(pCreature->GetEntry()) - { - case NPC_KRIKTHIR: m_uiKrikthirGUID = pCreature->GetGUID(); break; - case NPC_GASHRA: m_auiWatcherGUIDS[0] = pCreature->GetGUID(); break; - case NPC_NARJIL: m_auiWatcherGUIDS[1] = pCreature->GetGUID(); break; - case NPC_SILTHIK: m_auiWatcherGUIDS[2] = pCreature->GetGUID(); break; - } -} + uint64 uiWatcherGashra; + uint64 uiWatcherSilthik; + uint64 uiWatcherNarjil; -void instance_azjol_nerub::OnCreatureDeath(Creature* pCreature) -{ - uint32 uiEntry = pCreature->GetEntry(); - if (uiEntry == NPC_GASHRA || uiEntry == NPC_NARJIL || uiEntry == NPC_SILTHIK) + void Initialize() { - if (m_auiEncounter[0] == NOT_STARTED) - m_uiWatcherTimer = 5000; - } -} + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); -void instance_azjol_nerub::OnCreatureEnterCombat(Creature* pCreature) -{ - uint32 uiEntry = pCreature->GetEntry(); + m_uiDoor_KrikthirGUID = 0; + m_uiDoor_Anubarak_1GUID = 0; + m_uiDoor_Anubarak_2GUID = 0; + m_uiDoor_Anubarak_3GUID = 0; - if (uiEntry == NPC_GASHRA || uiEntry == NPC_NARJIL || uiEntry == NPC_SILTHIK) - { - // Creature enter combat is not equal to having a victim yet. - if (!m_uiPlayerGUID && pCreature->getVictim()) - m_uiPlayerGUID = pCreature->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()->GetGUID(); + uiWatcherGashra = 0; + uiWatcherSilthik = 0; + uiWatcherNarjil = 0; } -} - -void instance_azjol_nerub::OnCreatureEvade(Creature* pCreature) -{ - uint32 uiEntry = pCreature->GetEntry(); - if (uiEntry == NPC_GASHRA || uiEntry == NPC_NARJIL || uiEntry == NPC_SILTHIK) - m_uiPlayerGUID = 0; -} -void instance_azjol_nerub::Update(uint32 uiDiff) -{ - if (m_uiWatcherTimer) + void OnObjectCreate(GameObject* pGo) { - if (m_uiWatcherTimer <= uiDiff) + switch(pGo->GetEntry()) { - DoSendWatcherOrKrikthir(); - m_uiWatcherTimer = 0; + case GO_DOOR_KRIKTHIR: + m_uiDoor_KrikthirGUID = pGo->GetGUID(); + if (m_auiEncounter[0] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOOR_ANUBARAK_1: + m_uiDoor_Anubarak_1GUID = pGo->GetGUID(); + if (m_auiEncounter[2] == DONE || m_auiEncounter[2] == NOT_STARTED) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOOR_ANUBARAK_2: + m_uiDoor_Anubarak_2GUID = pGo->GetGUID(); + if (m_auiEncounter[2] == DONE || m_auiEncounter[2] == NOT_STARTED) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOOR_ANUBARAK_3: + m_uiDoor_Anubarak_3GUID = pGo->GetGUID(); + if (m_auiEncounter[2] == DONE || m_auiEncounter[2] == NOT_STARTED) + pGo->SetGoState(GO_STATE_ACTIVE); + break; } - else - m_uiWatcherTimer -= uiDiff; } -} -void instance_azjol_nerub::DoSendWatcherOrKrikthir() -{ - Creature* pAttacker = NULL; - Creature* pKrikthir = instance->GetCreature(m_uiKrikthirGUID); - - if (!pKrikthir) - return; - - for (uint8 i = 0; i < MAX_WATCHERS; ++i) + void OnCreatureCreate(Creature* pCreature) { - if (Creature* pTemp = instance->GetCreature(m_auiWatcherGUIDS[i])) + switch(pCreature->GetEntry()) { - if (pTemp->isAlive()) - { - if (pAttacker && urand(0, 1)) - continue; - else - pAttacker = pTemp; - } + case 28730: uiWatcherGashra = pCreature->GetGUID(); break; + case 28731: uiWatcherSilthik = pCreature->GetGUID(); break; + case 28729: uiWatcherNarjil = pCreature->GetGUID(); break; } } - if (pAttacker) + uint64 GetData64(uint32 identifier) { - switch(urand(0, 2)) + switch(identifier) { - case 0: DoScriptText(SAY_SEND_GROUP_1, pKrikthir); break; - case 1: DoScriptText(SAY_SEND_GROUP_2, pKrikthir); break; - case 2: DoScriptText(SAY_SEND_GROUP_3, pKrikthir); break; + case DATA_WATCHER_GASHRA: return uiWatcherGashra; + case DATA_WATCHER_SILTHIK: return uiWatcherSilthik; + case DATA_WATCHER_NARJIL: return uiWatcherNarjil; } - } - else - pAttacker = pKrikthir; - if (Unit* pTarget = instance->GetUnit(m_uiPlayerGUID)) - { - if (pTarget->isAlive()) - pAttacker->AI()->AttackStart(pTarget); + return 0; } -} -void instance_azjol_nerub::SetData(uint32 uiType, uint32 uiData) -{ - switch(uiType) + void SetData(uint32 uiType, uint32 uiData) { - case TYPE_KRIKTHIR: - m_auiEncounter[0] = uiData; - if (uiData == DONE) - DoUseDoorOrButton(m_uiDoorKrikthirGUID); - break; - case TYPE_HADRONOX: - m_auiEncounter[1] = uiData; - break; - case TYPE_ANUBARAK: - m_auiEncounter[2] = uiData; - DoUseDoorOrButton(m_uiDoorAnubarak1GUID); - DoUseDoorOrButton(m_uiDoorAnubarak2GUID); - DoUseDoorOrButton(m_uiDoorAnubarak3GUID); - break; - } + switch(uiType) + { + case TYPE_KRIKTHIR: + m_auiEncounter[0] = uiData; + if (uiData == DONE) + if (GameObject* pGo = instance->GetGameObject(m_uiDoor_KrikthirGUID)) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case TYPE_HADRONOX: + m_auiEncounter[1] = uiData; + break; + case TYPE_ANUBARAK: + m_auiEncounter[2] = uiData; + if (uiData == DONE || uiData == NOT_STARTED) + { + if (GameObject* pGo = instance->GetGameObject(m_uiDoor_Anubarak_1GUID)) + pGo->SetGoState(GO_STATE_ACTIVE); + if (GameObject* pGo = instance->GetGameObject(m_uiDoor_Anubarak_2GUID)) + pGo->SetGoState(GO_STATE_ACTIVE); + if (GameObject* pGo = instance->GetGameObject(m_uiDoor_Anubarak_3GUID)) + pGo->SetGoState(GO_STATE_ACTIVE); + } + if (uiData == IN_PROGRESS) + { + if (GameObject* pGo = instance->GetGameObject(m_uiDoor_Anubarak_1GUID)) + pGo->SetGoState(GO_STATE_READY); + if (GameObject* pGo = instance->GetGameObject(m_uiDoor_Anubarak_2GUID)) + pGo->SetGoState(GO_STATE_READY); + if (GameObject* pGo = instance->GetGameObject(m_uiDoor_Anubarak_3GUID)) + pGo->SetGoState(GO_STATE_READY); + } + break; + } - if (uiData == DONE) - { - OUT_SAVE_INST_DATA; + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2]; + std::ostringstream saveStream; + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2]; - strInstData = saveStream.str(); + strInstData = saveStream.str(); - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } } -} -void instance_azjol_nerub::Load(const char* chrIn) -{ - if (!chrIn) + const char* Save() { - OUT_LOAD_INST_DATA_FAIL; - return; + return strInstData.c_str(); } - OUT_LOAD_INST_DATA(chrIn); + void Load(const char* in) + { + if (!in) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - std::istringstream loadStream(chrIn); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; + OUT_LOAD_INST_DATA(in); - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } + std::istringstream loadStream(in); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; - OUT_LOAD_INST_DATA_COMPLETE; -} + 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_azjol_nerub(Map* pMap) { @@ -233,9 +188,9 @@ InstanceData* GetInstanceData_instance_azjol_nerub(Map* pMap) void AddSC_instance_azjol_nerub() { - Script* pNewScript; - pNewScript = new Script; - pNewScript->Name = "instance_azjol-nerub"; - pNewScript->GetInstanceData = &GetInstanceData_instance_azjol_nerub; - pNewScript->RegisterSelf(); + Script *newscript; + newscript = new Script; + newscript->Name = "instance_azjol-nerub"; + newscript->GetInstanceData = &GetInstanceData_instance_azjol_nerub; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/borean_tundra.cpp b/scripts/northrend/borean_tundra.cpp index d6eb0c01a..6f5132541 100644 --- a/scripts/northrend/borean_tundra.cpp +++ b/scripts/northrend/borean_tundra.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: Borean_Tundra SD%Complete: 100 -SDComment: Quest support: 11708, 11692, 11961, 11865. Taxi vendors. 11570 +SDComment: Quest support: 11570, 11590, 11692, 11676, 11708, 11919, 11940, 11961. Taxi vendors. SDCategory: Borean Tundra EndScriptData */ @@ -27,13 +27,19 @@ npc_iruk npc_kara_thricestar npc_nesingwary_trapper go_caribou_trap +npc_sinkhole_kill_credit npc_surristrasz npc_tiare npc_lurgglbr +npc_nexus_drake +go_scourge_cage +npc_beryl_sorcerer EndContentData */ #include "precompiled.h" #include "escort_ai.h" +#include "ObjectMgr.h" +#include "follower_ai.h" /*###### ## npc_fizzcrank_fullthrottle @@ -286,11 +292,133 @@ CreatureAI* GetAI_npc_nesingwary_trapper(Creature* pCreature) return new npc_nesingwary_trapperAI(pCreature); } +/*##### +# npc_oil_stained_wolf +#####*/ + +enum +{ + SPELL_THROW_WOLF_BAIT = 53326, + SPELL_PLACE_WOLF_BAIT = 46072, // doesn't appear to be used for anything + SPELL_HAS_EATEN = 46073, + SPELL_SUMMON_DROPPINGS = 46075, + + FACTION_MONSTER = 634, + + POINT_DEST = 1 +}; + +struct MANGOS_DLL_DECL npc_oil_stained_wolfAI : public ScriptedAI +{ + npc_oil_stained_wolfAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + + bool m_bCanCrapInPublic; + uint32 m_uiPooTimer; + + void Reset() + { + m_bCanCrapInPublic = false; + m_uiPooTimer = 0; + } + + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if (uiType != POINT_MOTION_TYPE) + return; + + if (uiPointId == POINT_DEST) + { + DoCastSpellIfCan(m_creature, SPELL_HAS_EATEN); + m_uiPooTimer = 4000; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + { + if (m_uiPooTimer) + { + if (m_uiPooTimer <= uiDiff) + { + if (m_bCanCrapInPublic) + { + DoCastSpellIfCan(m_creature, SPELL_SUMMON_DROPPINGS); + m_creature->GetMotionMaster()->Clear(); + Reset(); + } + else + { + m_creature->HandleEmote(EMOTE_ONESHOT_BATTLEROAR); + m_bCanCrapInPublic = true; + m_uiPooTimer = 3000; + } + } + else + m_uiPooTimer -= uiDiff; + } + + return; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_oil_stained_wolf(Creature* pCreature) +{ + return new npc_oil_stained_wolfAI(pCreature); +} + +bool EffectDummyCreature_npc_oil_stained_wolf(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +{ + if (uiSpellId == SPELL_THROW_WOLF_BAIT) + { + if (uiEffIndex == EFFECT_INDEX_0 && pCreatureTarget->getFaction() != FACTION_MONSTER && !pCreatureTarget->HasAura(SPELL_HAS_EATEN)) + { + pCreatureTarget->SetFactionTemporary(FACTION_MONSTER); + pCreatureTarget->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + + pCreatureTarget->GetMotionMaster()->MoveIdle(); + + float fX, fY, fZ; + pCaster->GetContactPoint(pCreatureTarget, fX, fY, fZ, CONTACT_DISTANCE); + pCreatureTarget->GetMotionMaster()->MovePoint(POINT_DEST, fX, fY, fZ); + return true; + } + } + + return false; +} + +bool EffectAuraDummy_npc_oil_stained_wolf(const Aura* pAura, bool bApply) +{ + if (pAura->GetId() == SPELL_HAS_EATEN) + { + if (pAura->GetEffIndex() != EFFECT_INDEX_0) + return false; + + if (bApply) + { + pAura->GetTarget()->HandleEmote(EMOTE_ONESHOT_CUSTOMSPELL01); + } + else + { + Creature* pCreature = (Creature*)pAura->GetTarget(); + pCreature->setFaction(pCreature->GetCreatureInfo()->faction_A); + } + + return true; + } + + return false; +} + /*###### ## go_caribou_trap ######*/ -bool GOHello_go_caribou_trap(Player* pPlayer, GameObject* pGo) +bool GOUse_go_caribou_trap(Player* pPlayer, GameObject* pGo) { float fX, fY, fZ; pGo->GetClosePoint(fX, fY, fZ, pGo->GetObjectBoundingRadius(), 2*INTERACTION_DISTANCE, frand(0, M_PI_F*2)); @@ -314,6 +442,100 @@ bool GOHello_go_caribou_trap(Player* pPlayer, GameObject* pGo) return true; } +/*##### +# npc_sinkhole_kill_credit +#####*/ + +enum +{ + SPELL_SUMMON_EXPLOSIVES_CART_FIRE = 46799, + SPELL_SUMMON_SCOURGE_BURROWER = 46800, + SPELL_COSMETIC_HUGE_EXPLOSION = 46225, + SPELL_CANNON_FIRE = 42445, +}; + +struct MANGOS_DLL_DECL npc_sinkhole_kill_creditAI : public ScriptedAI +{ + npc_sinkhole_kill_creditAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + + ObjectGuid m_uiCartGUID; + ObjectGuid m_uiWormGUID; + uint32 m_uiCartTimer; + uint32 m_uiCartPhase; + + void Reset() + { + m_uiCartGUID.Clear(); + m_uiWormGUID.Clear(); + m_uiCartTimer = 2000; + m_uiCartPhase = 0; + } + + void JustSummoned(Creature* pSummoned) + { + m_uiWormGUID = pSummoned->GetObjectGuid(); + } + + void JustSummoned(GameObject* pGo) + { + // Go is not really needed, but ok to use as a check point so only one "event" can be processed at a time + if (!m_uiCartGUID.IsEmpty()) + return; + + // Expecting summoned from mangos dummy effect 46797 + m_uiCartGUID = pGo->GetObjectGuid(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_uiCartGUID.IsEmpty()) + { + if (m_uiCartTimer <= uiDiff) + { + switch(m_uiCartPhase) + { + case 0: + DoCastSpellIfCan(m_creature, SPELL_SUMMON_EXPLOSIVES_CART_FIRE); + m_uiCartTimer = 4000; + break; + case 1: + // Unclear if these should be in a dummy effect or not. + // The order of spells are correct though. + DoCastSpellIfCan(m_creature, SPELL_COSMETIC_HUGE_EXPLOSION, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_CANNON_FIRE, CAST_TRIGGERED); + break; + case 2: + DoCastSpellIfCan(m_creature, SPELL_SUMMON_SCOURGE_BURROWER); + m_uiCartTimer = 2000; + break; + case 3: + if (Creature* pWorm = m_creature->GetMap()->GetCreature(m_uiWormGUID)) + { + pWorm->SetDeathState(JUST_DIED); + pWorm->SetHealth(0); + } + m_uiCartTimer = 10000; + break; + case 4: + if (Creature* pWorm = m_creature->GetMap()->GetCreature(m_uiWormGUID)) + pWorm->RemoveCorpse(); + + Reset(); + return; + } + + ++m_uiCartPhase; + } + else + m_uiCartTimer -= uiDiff; + } + } +}; + +CreatureAI* GetAI_npc_sinkhole_kill_credit(Creature* pCreature) +{ + return new npc_sinkhole_kill_creditAI(pCreature); +} /*###### ## npc_surristrasz @@ -527,53 +749,274 @@ CreatureAI* GetAI_npc_lurgglbr(Creature* pCreature) return new npc_lurgglbrAI(pCreature); } +/*###### +## npc_nexus_drake_hatchling +######*/ + +enum +{ + SPELL_DRAKE_HARPOON = 46607, + SPELL_RED_DRAGONBLOOD = 46620, + SPELL_DRAKE_HATCHLING_SUBDUED = 46691, + SPELL_SUBDUED = 46675, + + NPC_RAELORASZ = 26117, + DRAKE_HUNT_KILL_CREDIT = 26175, + + QUEST_DRAKE_HUNT = 11919, + QUEST_DRAKE_HUNT_D = 11940 + +}; + +struct MANGOS_DLL_DECL npc_nexus_drakeAI : public FollowerAI +{ + npc_nexus_drakeAI(Creature* pCreature) : FollowerAI(pCreature) { Reset(); } + + uint64 uiHarpoonerGUID; + bool bWithRedDragonBlood; + bool bIsFollowing; + + void Reset() + { + bWithRedDragonBlood = false; + bIsFollowing = false; + } + + void EnterCombat(Unit* pWho) + { + AttackStart(pWho); + } + + void SpellHit(Unit* pCaster, SpellEntry const* pSpell) + { + if (pSpell->Id == SPELL_DRAKE_HARPOON && pCaster->GetTypeId() == TYPEID_PLAYER) + { + uiHarpoonerGUID = pCaster->GetGUID(); + DoCast(m_creature, SPELL_RED_DRAGONBLOOD, true); + } + m_creature->Attack(pCaster,true); + bWithRedDragonBlood = true; + } + + void MoveInLineOfSight(Unit *pWho) + { + FollowerAI::MoveInLineOfSight(pWho); + + + if (pWho->GetEntry() == NPC_RAELORASZ && m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE)) + { + if (Player *pHarpooner = m_creature->GetMap()->GetPlayer(uiHarpoonerGUID)) + { + + pHarpooner->KilledMonsterCredit(DRAKE_HUNT_KILL_CREDIT,m_creature->GetGUID()); + pHarpooner->RemoveAurasByCasterSpell(SPELL_DRAKE_HATCHLING_SUBDUED,uiHarpoonerGUID); + SetFollowComplete(); + uiHarpoonerGUID = 0; + m_creature->ForcedDespawn(1000); + } + + } + } + + void UpdateAI(const uint32 uidiff) + { + if (bWithRedDragonBlood && uiHarpoonerGUID && !m_creature->HasAura(SPELL_RED_DRAGONBLOOD)) + { + if (Player *pHarpooner = m_creature->GetMap()->GetPlayer(uiHarpoonerGUID)) + { + EnterEvadeMode(); + StartFollow(pHarpooner, 35, NULL); + + DoCast(m_creature, SPELL_SUBDUED, true); + pHarpooner->CastSpell(pHarpooner, SPELL_DRAKE_HATCHLING_SUBDUED, true); + + m_creature->AttackStop(); + bIsFollowing = true; + bWithRedDragonBlood = false; + } + } + if(bIsFollowing && !m_creature->HasAura(SPELL_SUBDUED)) + { + m_creature->ForcedDespawn(1000); + } + + if (!m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_nexus_drake(Creature* pCreature) +{ + return new npc_nexus_drakeAI(pCreature); +} + +/*##### +## go_scourge_cage +#####*/ + +enum +{ + QUEST_MERCIFUL_FREEDOM = 11676, + NPC_SCOURGE_PRISONER = 25610, +}; + +bool GOHello_go_scourge_cage(Player* pPlayer, GameObject* pGo) +{ + if (pPlayer->GetQuestStatus(QUEST_MERCIFUL_FREEDOM) == QUEST_STATUS_INCOMPLETE) + { + Creature *pCreature = GetClosestCreatureWithEntry(pGo, NPC_SCOURGE_PRISONER, INTERACTION_DISTANCE); + if(pCreature) + { + pPlayer->KilledMonsterCredit(NPC_SCOURGE_PRISONER, pCreature->GetGUID()); + pCreature->CastSpell(pCreature, 43014, false); + } + } + return false; +}; + +/*###### +## npc_beryl_sorcerer +######*/ + +enum eBerylSorcerer +{ + NPC_CAPTURED_BERLY_SORCERER = 25474, + NPC_LIBRARIAN_DONATHAN = 25262, + + SPELL_ARCANE_CHAINS = 45611, + SPELL_COSMETIC_CHAINS = 54324, + SPELL_COSMETIC_ENSLAVE_CHAINS_SELF = 45631 +}; + +struct MANGOS_DLL_DECL npc_beryl_sorcererAI : public FollowerAI +{ + npc_beryl_sorcererAI(Creature* pCreature) : FollowerAI(pCreature) { + m_uiNormalFaction = pCreature->getFaction(); + Reset(); + } + + bool bEnslaved; + uint64 uiChainerGUID; + uint32 m_uiNormalFaction; + + void Reset() + { + m_creature->setFaction(m_uiNormalFaction); + bEnslaved = false; + } + void EnterCombat(Unit* pWho) + { + AttackStart(pWho); + } + + void SpellHit(Unit* pCaster, SpellEntry const* pSpell) + { + if (pSpell->Id == SPELL_ARCANE_CHAINS && pCaster->GetTypeId() == TYPEID_PLAYER && !bEnslaved) + { + EnterEvadeMode(); //We make sure that the npc is not attacking the player! + m_creature->setFaction(35); + uiChainerGUID = pCaster->GetGUID(); + if(Player *pChainer = m_creature->GetMap()->GetPlayer(uiChainerGUID)) + { + StartFollow(pChainer, 35, NULL); + m_creature->UpdateEntry(NPC_CAPTURED_BERLY_SORCERER); + DoCast(m_creature, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF, true); + + bEnslaved = true; + } + } + } + + void MoveInLineOfSight(Unit* pWho) + { + FollowerAI::MoveInLineOfSight(pWho); + + if (pWho->GetEntry() == NPC_LIBRARIAN_DONATHAN && m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE)) + { + if(Player *pChainer = m_creature->GetMap()->GetPlayer(uiChainerGUID)) + { + pChainer->KilledMonsterCredit(NPC_CAPTURED_BERLY_SORCERER,m_creature->GetGUID()); + SetFollowComplete(); + m_creature->ForcedDespawn(1000); + } + } + } + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } + +}; + +CreatureAI* GetAI_npc_beryl_sorcerer(Creature* pCreature) +{ + return new npc_beryl_sorcererAI(pCreature); +} + void AddSC_borean_tundra() { - Script *newscript; - - newscript = new Script; - newscript->Name = "npc_fizzcrank_fullthrottle"; - newscript->pGossipHello = &GossipHello_npc_fizzcrank_fullthrottle; - newscript->pGossipSelect = &GossipSelect_npc_fizzcrank_fullthrottle; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_iruk"; - newscript->pGossipHello = &GossipHello_npc_iruk; - newscript->pGossipSelect = &GossipSelect_npc_iruk; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_kara_thricestar"; - newscript->pGossipHello = &GossipHello_npc_kara_thricestar; - newscript->pGossipSelect = &GossipSelect_npc_kara_thricestar; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_nesingwary_trapper"; - newscript->GetAI = &GetAI_npc_nesingwary_trapper; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "go_caribou_trap"; - newscript->pGOHello = &GOHello_go_caribou_trap; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_surristrasz"; - newscript->pGossipHello = &GossipHello_npc_surristrasz; - newscript->pGossipSelect = &GossipSelect_npc_surristrasz; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_tiare"; - newscript->pGossipHello = &GossipHello_npc_tiare; - newscript->pGossipSelect = &GossipSelect_npc_tiare; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_lurgglbr"; - newscript->GetAI = &GetAI_npc_lurgglbr; - newscript->pQuestAccept = &QuestAccept_npc_lurgglbr; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "npc_fizzcrank_fullthrottle"; + pNewScript->pGossipHello = &GossipHello_npc_fizzcrank_fullthrottle; + pNewScript->pGossipSelect = &GossipSelect_npc_fizzcrank_fullthrottle; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_iruk"; + pNewScript->pGossipHello = &GossipHello_npc_iruk; + pNewScript->pGossipSelect = &GossipSelect_npc_iruk; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_kara_thricestar"; + pNewScript->pGossipHello = &GossipHello_npc_kara_thricestar; + pNewScript->pGossipSelect = &GossipSelect_npc_kara_thricestar; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_nesingwary_trapper"; + pNewScript->GetAI = &GetAI_npc_nesingwary_trapper; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_oil_stained_wolf"; + pNewScript->GetAI = &GetAI_npc_oil_stained_wolf; + pNewScript->pEffectDummyNPC = &EffectDummyCreature_npc_oil_stained_wolf; + pNewScript->pEffectAuraDummy = &EffectAuraDummy_npc_oil_stained_wolf; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "go_caribou_trap"; + pNewScript->pGOUse = &GOUse_go_caribou_trap; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_sinkhole_kill_credit"; + pNewScript->GetAI = &GetAI_npc_sinkhole_kill_credit; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_surristrasz"; + pNewScript->pGossipHello = &GossipHello_npc_surristrasz; + pNewScript->pGossipSelect = &GossipSelect_npc_surristrasz; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_tiare"; + pNewScript->pGossipHello = &GossipHello_npc_tiare; + pNewScript->pGossipSelect = &GossipSelect_npc_tiare; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_lurgglbr"; + pNewScript->GetAI = &GetAI_npc_lurgglbr; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_lurgglbr; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp new file mode 100644 index 000000000..9325fac26 --- /dev/null +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp @@ -0,0 +1,434 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_argent_challenge +SD%Complete: 50% +SDComment: missing yells. radiance is "wrong". modified by /dev/rsa +SDCategory: Trial Of the Champion +EndScriptData */ + +#include "precompiled.h" +#include "trial_of_the_champion.h" + +enum +{ + SPELL_BERSERK = 47008, + //yells + + //eadric + SPELL_VENGEANCE = 66889, + SPELL_RADIANCE = 66862, + SPELL_RADIANCE_H = 67681, + SPELL_HAMMER_OF_JUSTICE = 66940, + SPELL_HAMMER = 67680, + //paletress + SPELL_SMITE = 66536, + SPELL_SMITE_H = 67674, + SPELL_HOLY_FIRE = 66538, + SPELL_HOLY_FIRE_H = 67676, + SPELL_RENEW = 66537, + SPELL_RENEW_H = 67675, + SPELL_HOLY_NOVA = 66546, + SPELL_SHIELD = 66515, + SPELL_CONFESS = 66547, + //memory + SPELL_FEAR = 66552, + SPELL_FEAR_H = 67677, + SPELL_SHADOWS = 66619, + SPELL_SHADOWS_H = 67678, + SPELL_OLD_WOUNDS = 66620, + SPELL_OLD_WOUNDS_H = 67679, +}; + +// Eadric The Pure +struct MANGOS_DLL_DECL boss_eadricAI : public ScriptedAI +{ + boss_eadricAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Vengeance_Timer; + uint32 Radiance_Timer; + uint32 Hammer_Timer; + uint32 Hammer_Dmg_Timer; + uint32 m_uiBerserk_Timer; + uint64 HammerTarget; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + Vengeance_Timer = 1000; + Radiance_Timer = m_bIsRegularMode ? 15000 : 8000; + Hammer_Timer = m_bIsRegularMode ? 40000 : 10000; + Hammer_Dmg_Timer = m_bIsRegularMode ? 45000 : 20000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + HammerTarget = 0; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + if (m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) != DONE) + m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, DONE); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Vengeance_Timer < diff) + { + DoCast(m_creature, SPELL_VENGEANCE); + Vengeance_Timer = m_bIsRegularMode ? 12000 : 8000; + }else Vengeance_Timer -= diff; + + if (Radiance_Timer < diff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_RADIANCE : SPELL_RADIANCE_H); + Radiance_Timer = m_bIsRegularMode ? 20000 : 12000; + }else Radiance_Timer -= diff; + + if (Hammer_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + { + DoCast(target, SPELL_HAMMER_OF_JUSTICE); + HammerTarget = target->GetGUID(); + } + Hammer_Timer = m_bIsRegularMode ? 40000 : 15000; + }else Hammer_Timer -= diff; + + if (Hammer_Dmg_Timer < diff) + { + if (Unit* pHammerTarget = m_creature->GetMap()->GetUnit(HammerTarget)) + DoCast(pHammerTarget, SPELL_HAMMER); + Hammer_Dmg_Timer = m_bIsRegularMode ? 50000 : 15000; + } + else Hammer_Dmg_Timer -= diff; + + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_eadric(Creature* pCreature) +{ + return new boss_eadricAI(pCreature); +} + +// Argent Confessor Paletress +struct MANGOS_DLL_DECL boss_paletressAI : public ScriptedAI +{ + boss_paletressAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Smite_Timer; + uint32 Holy_Fire_Timer; + uint32 Renew_Timer; + uint32 Shield_Delay; + uint32 Shield_Check; + uint32 m_uiBerserk_Timer; + bool summoned; + bool shielded; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->RemoveAurasDueToSpell(SPELL_SHIELD); + Smite_Timer = 5000; + Holy_Fire_Timer = m_bIsRegularMode ? 10000 : 8000; + Renew_Timer = m_bIsRegularMode ? 7000 : 5000; + Shield_Delay = 0; + Shield_Check = 1000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + summoned = false; + shielded = false; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + void JustSummoned(Creature* _summoned) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + _summoned->AddThreat(target); + summoned = true; + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + if (m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) != DONE) + m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, DONE); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Smite_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H); + Smite_Timer = 2000; + }else Smite_Timer -= diff; + + if (Holy_Fire_Timer < diff) + { + m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H); + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H); + Holy_Fire_Timer = m_bIsRegularMode ? 10000 : 7000; + }else Holy_Fire_Timer -= diff; + + if (Renew_Timer < diff) + { + m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H); + m_creature->CastStop(m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H); + switch(urand(0, 1)) + { + case 0: + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MEMORY)))) + if (pTemp->isAlive()) + DoCast(pTemp, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H); + else + DoCast(m_creature, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H); + break; + case 1: + DoCast(m_creature, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H); + break; + } + Renew_Timer = 25000; + }else Renew_Timer -= diff; + + if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 35 ) && !summoned ) + { + m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H); + m_creature->CastStop(m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H); + DoCast(m_creature, SPELL_HOLY_NOVA); + switch(urand(0, 24)) + { + case 0: m_creature->SummonCreature(MEMORY_ALGALON, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 1: m_creature->SummonCreature(MEMORY_CHROMAGGUS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 2: m_creature->SummonCreature(MEMORY_CYANIGOSA, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 3: m_creature->SummonCreature(MEMORY_DELRISSA, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 4: m_creature->SummonCreature(MEMORY_ECK, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 5: m_creature->SummonCreature(MEMORY_ENTROPIUS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 6: m_creature->SummonCreature(MEMORY_GRUUL, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 7: m_creature->SummonCreature(MEMORY_HAKKAR, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 8: m_creature->SummonCreature(MEMORY_HEIGAN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 9: m_creature->SummonCreature(MEMORY_HEROD, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 10: m_creature->SummonCreature(MEMORY_HOGGER, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 11: m_creature->SummonCreature(MEMORY_IGNIS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 12: m_creature->SummonCreature(MEMORY_ILLIDAN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 13: m_creature->SummonCreature(MEMORY_INGVAR, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 14: m_creature->SummonCreature(MEMORY_KALITHRESH, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 15: m_creature->SummonCreature(MEMORY_LUCIFRON, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 16: m_creature->SummonCreature(MEMORY_MALCHEZAAR, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 17: m_creature->SummonCreature(MEMORY_MUTANUS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 18: m_creature->SummonCreature(MEMORY_ONYXIA, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 19: m_creature->SummonCreature(MEMORY_THUNDERAAN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 20: m_creature->SummonCreature(MEMORY_VANCLEEF, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 21: m_creature->SummonCreature(MEMORY_VASHJ, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 22: m_creature->SummonCreature(MEMORY_VEKNILASH, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 23: m_creature->SummonCreature(MEMORY_VEZAX, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 24: m_creature->SummonCreature(MEMORY_ARCHIMONDE, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + + } + Shield_Delay = 1000; + }; + if (Shield_Delay < diff && !shielded && summoned) + { + m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H); + m_creature->CastStop(m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H); + DoCast(m_creature, SPELL_SHIELD); + shielded = true; + Shield_Check = m_bIsRegularMode ? 3000 : 5000; + }else Shield_Delay -= diff; + + if (Shield_Check < diff && shielded) + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MEMORY)))) + if (!pTemp->isAlive()) + { + m_creature->RemoveAurasDueToSpell(SPELL_SHIELD); + shielded = false; + } else Shield_Check = 1000; + }else Shield_Check -= diff; + + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_paletress(Creature* pCreature) +{ + return new boss_paletressAI(pCreature); +} + +// Summoned Memory +struct MANGOS_DLL_DECL mob_toc5_memoryAI : public ScriptedAI +{ + mob_toc5_memoryAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Old_Wounds_Timer; + uint32 Shadows_Timer; + uint32 Fear_Timer; + + void Reset() + { + Old_Wounds_Timer = 5000; + Shadows_Timer = 8000; + Fear_Timer = 13000; + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Old_Wounds_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsRegularMode ? SPELL_OLD_WOUNDS : SPELL_OLD_WOUNDS_H); + Old_Wounds_Timer = 10000; + }else Old_Wounds_Timer -= diff; + + if (Fear_Timer < diff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_FEAR : SPELL_FEAR_H); + Fear_Timer = 40000; + }else Fear_Timer -= diff; + + if (Shadows_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) + DoCast(target, m_bIsRegularMode ? SPELL_SHADOWS : SPELL_SHADOWS_H); + Shadows_Timer = 10000; + }else Shadows_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_toc5_memory(Creature* pCreature) +{ + return new mob_toc5_memoryAI(pCreature); +} + +void AddSC_boss_argent_challenge() +{ + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "boss_eadric"; + NewScript->GetAI = &GetAI_boss_eadric; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "boss_paletress"; + NewScript->GetAI = &GetAI_boss_paletress; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_toc5_memory"; + NewScript->GetAI = &GetAI_mob_toc5_memory; + NewScript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp new file mode 100644 index 000000000..ce20f85ae --- /dev/null +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp @@ -0,0 +1,311 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_black_knight +SD%Complete: 70% +SDComment: missing yells. not sure about timers. modified by /dev/rsa +SDCategory: Trial Of the Champion +EndScriptData */ + +#include "precompiled.h" +#include "trial_of_the_champion.h" + +enum +{ + SPELL_BERSERK = 47008, + //yells + + //undead + SPELL_PLAGUE_STRIKE = 67724, + SPELL_PLAGUE_STRIKE_H = 67884, + SPELL_ICY_TOUCH = 67718, + SPELL_ICY_TOUCH_H = 67881, + SPELL_OBLITERATE = 67725, + SPELL_OBLITERATE_H = 67883, + SPELL_CHOKE = 68306, + //skeleton + SPELL_ARMY = 42650, //replacing original one, since that one spawns millions of ghouls!! + //ghost + SPELL_DEATH = 67808, + SPELL_DEATH_H = 67875, + SPELL_MARK = 67823, + + //risen ghoul + SPELL_CLAW = 67879, + SPELL_EXPLODE = 67729, + SPELL_EXPLODE_H = 67886, + SPELL_LEAP = 67749, + SPELL_LEAP_H = 67880, + + //sword ID + EQUIP_SWORD = 40343 +}; + +// Risen Ghoul +struct MANGOS_DLL_DECL mob_toc5_risen_ghoulAI : public ScriptedAI +{ + mob_toc5_risen_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Attack; + + void Reset() + { + Attack = 2500; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Attack < diff) + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_BLACK_KNIGHT)))) + if (pTemp->isAlive()) + if ((pTemp->GetHealth()*100 / pTemp->GetMaxHealth()) < 25) + DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLODE : SPELL_EXPLODE_H); + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 4)) + { + DoCast(m_creature->getVictim(), SPELL_CLAW); + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) + m_creature->AI()->AttackStart(target); + Attack = 2500; + }else + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 30)) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_LEAP : SPELL_LEAP_H); + Attack = 2500; + } + }else Attack -= diff; + + if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25) + DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLODE : SPELL_EXPLODE_H); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_toc5_risen_ghoul(Creature* pCreature) +{ + return new mob_toc5_risen_ghoulAI(pCreature); +} + +// The Black Knight +struct MANGOS_DLL_DECL boss_black_knightAI : public ScriptedAI +{ + boss_black_knightAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Plague_Strike_Timer; + uint32 Icy_Touch_Timer; + uint32 Obliterate_Timer; + uint32 Choke_Timer; + uint32 Death_Timer; + uint32 Mark_Timer; + uint32 Phase_Delay; + uint32 Summon_Ghoul; + uint32 m_uiBerserk_Timer; + bool phase1; + bool phase2; + bool phase3; + bool ghoul; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->SetDisplayId(29837); + SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + Plague_Strike_Timer = m_bIsRegularMode ? 5000 : 4000; + Icy_Touch_Timer = m_bIsRegularMode ? 10000 : 7000; + Obliterate_Timer = m_bIsRegularMode ? 16000 : 10000; + Choke_Timer = 15000; + Summon_Ghoul = 4000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + phase1 = true; + phase2 = false; + phase3 = false; + ghoul = false; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + if (m_pInstance->GetData(TYPE_BLACK_KNIGHT) != DONE) + m_pInstance->SetData(TYPE_BLACK_KNIGHT, IN_PROGRESS); + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if ((uiDamage > m_creature->GetHealth() || + m_creature->GetHealth()/m_creature->GetHealth() <= 0.1 ) && !phase3){ + uiDamage = 0; + if (phase2) + StartPhase3(); + if (phase1) + StartPhase2(); + } + } + + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + if (phase3 && !phase1 && !phase2) + { + m_pInstance->SetData(TYPE_BLACK_KNIGHT, DONE); + } +/* if (phase2 && !phase1 && !phase3) + if (!m_creature->isAlive()) + { + m_creature->Respawn(); + StartPhase3(); + } + if (phase1 && !phase2 && !phase3) + if (!m_creature->isAlive()) + { + m_creature->Respawn(); + StartPhase2(); + }*/ + } + + void StartPhase2() + { + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetDisplayId(27550); + phase1 = false; + phase2 = true; + phase3 = false; + DoCast(m_creature, SPELL_ARMY); + Plague_Strike_Timer = m_bIsRegularMode ? 14000 : 8000; + Icy_Touch_Timer = m_bIsRegularMode ? 12000 : 7000; + Obliterate_Timer = m_bIsRegularMode ? 18000 : 10000; + } + + void StartPhase3() + { + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetDisplayId(14560); + SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + phase1 = false; + phase2 = false; + phase3 = true; + Death_Timer = m_bIsRegularMode ? 5000 : 3000; + Mark_Timer = m_bIsRegularMode ? 9000 : 7000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Plague_Strike_Timer < diff && !phase3) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_PLAGUE_STRIKE : SPELL_PLAGUE_STRIKE_H); + Plague_Strike_Timer = m_bIsRegularMode ? 10500 : 7000; + }else Plague_Strike_Timer -= diff; + + if (Icy_Touch_Timer < diff && !phase3) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ICY_TOUCH : SPELL_ICY_TOUCH_H); + Icy_Touch_Timer = m_bIsRegularMode ? 10000 : 8000; + }else Icy_Touch_Timer -= diff; + + if (Obliterate_Timer < diff && !phase3) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_OBLITERATE : SPELL_OBLITERATE_H); + Obliterate_Timer = m_bIsRegularMode ? 11000 : 8000; + }else Obliterate_Timer -= diff; + + if (Choke_Timer < diff && phase1) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) + DoCast(m_creature->getVictim(), SPELL_CHOKE); + Choke_Timer = m_bIsRegularMode ? 15000 : 10000; + }else Choke_Timer -= diff; + + if (Summon_Ghoul < diff && phase1 && !ghoul) + { + if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == m_pInstance->GetData(DATA_JAEREN)) + m_creature->SummonCreature(NPC_RISEN_JAEREN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + else + m_creature->SummonCreature(NPC_RISEN_ARELAS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + ghoul = true; + }else Summon_Ghoul -= diff; + + if (Mark_Timer < diff && phase3) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) + DoCast(target, SPELL_MARK); + Mark_Timer = m_bIsRegularMode ? 15000 : 10000; + }else Mark_Timer -= diff; + + if (Death_Timer < diff && phase3) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_DEATH : SPELL_DEATH_H); + Death_Timer = 3500; + }else Death_Timer -= diff; + + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_black_knight(Creature* pCreature) +{ + return new boss_black_knightAI(pCreature); +} + +void AddSC_boss_black_knight() +{ + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "mob_toc5_risen_ghoul"; + NewScript->GetAI = &GetAI_mob_toc5_risen_ghoul; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "boss_black_knight"; + NewScript->GetAI = &GetAI_boss_black_knight; + NewScript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp index bbc5a803b..2e3036355 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,11 +15,734 @@ */ /* ScriptData -SDName: grand_champions -SD%Complete: 0 -SDComment: -SDCategory: Crusader Coliseum, Trial of the Champion +SDName: boss_grand_champions +SD%Complete: 70% +SDComment: missing yells. hunter AI sucks. no pvp diminuishing returns(is it DB related?). modified by /dev/rsa +SDCategory: Trial Of the Champion EndScriptData */ #include "precompiled.h" #include "trial_of_the_champion.h" + +enum +{ + //common + SPELL_BERSERK = 47008, + //yells + //warrior + SPELL_MORTAL_STRIKE = 68783, + SPELL_MORTAL_STRIKE_H = 68784, + SPELL_BLADESTORM = 63784, + SPELL_INTERCEPT = 67540, + SPELL_ROLLING_THROW = 47115, //need core support for spell 67546, using 47115 instead + //mage + SPELL_FIREBALL = 66042, + SPELL_FIREBALL_H = 68310, + SPELL_BLAST_WAVE = 66044, + SPELL_BLAST_WAVE_H = 68312, + SPELL_HASTE = 66045, + SPELL_POLYMORPH = 66043, + SPELL_POLYMORPH_H = 68311, + //shaman + SPELL_CHAIN_LIGHTNING = 67529, + SPELL_CHAIN_LIGHTNING_H = 68319, + SPELL_EARTH_SHIELD = 67530, + SPELL_HEALING_WAVE = 67528, + SPELL_HEALING_WAVE_H = 68318, + SPELL_HEX_OF_MENDING = 67534, + //hunter + SPELL_DISENGAGE = 68340, + SPELL_LIGHTNING_ARROWS = 66083, + SPELL_MULTI_SHOT = 66081, + SPELL_SHOOT = 66079, + //rogue + SPELL_EVISCERATE = 67709, + SPELL_EVISCERATE_H = 68317, + SPELL_FAN_OF_KNIVES = 67706, + SPELL_POISON_BOTTLE = 67701 +}; + +// Warrior +struct MANGOS_DLL_DECL mob_toc5_warriorAI : public ScriptedAI +{ + mob_toc5_warriorAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Mortal_Strike_Timer; + uint32 Bladestorm_Timer; + uint32 Rolling_Throw_Timer; + uint32 Intercept_Cooldown; + uint32 intercept_check; + uint32 m_uiBerserk_Timer; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + Mortal_Strike_Timer = m_bIsRegularMode ? 9000 : 6000; + Bladestorm_Timer = m_bIsRegularMode ? 30000 : 20000; + Rolling_Throw_Timer = m_bIsRegularMode ? 45000 : 30000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + Intercept_Cooldown = 0; + intercept_check = 1000; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + + } + + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + else + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); +// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS); + } + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1); + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) { + m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Mortal_Strike_Timer < diff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_MORTAL_STRIKE : SPELL_MORTAL_STRIKE_H); + Mortal_Strike_Timer = m_bIsRegularMode ? 6000 : 4000; + }else Mortal_Strike_Timer -= diff; + + if (Rolling_Throw_Timer < diff) + { + DoCast(m_creature->getVictim(), SPELL_ROLLING_THROW); + Rolling_Throw_Timer = m_bIsRegularMode ? 30000 : 15000; + }else Rolling_Throw_Timer -= diff; + + if (Bladestorm_Timer < diff) + { + DoCast(m_creature, SPELL_BLADESTORM); + Bladestorm_Timer = m_bIsRegularMode ? 60000 : 20000; + }else Bladestorm_Timer -= diff; + + if (intercept_check < diff) + { + if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 25) && Intercept_Cooldown < diff) + { + DoCast(m_creature->getVictim(), SPELL_INTERCEPT); + Intercept_Cooldown = m_bIsRegularMode ? 15000 : 10000; + } + intercept_check = 1000; + } + else + { + intercept_check -= diff; + Intercept_Cooldown -= diff; + } + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_toc5_warrior(Creature* pCreature) +{ + return new mob_toc5_warriorAI(pCreature); +} + +// Mage +struct MANGOS_DLL_DECL mob_toc5_mageAI : public ScriptedAI +{ + mob_toc5_mageAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Fireball_Timer; + uint32 Blast_Wave_Timer; + uint32 Haste_Timer; + uint32 Polymorph_Timer; + uint32 m_uiBerserk_Timer; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + Fireball_Timer = 0; + Blast_Wave_Timer = m_bIsRegularMode ? 20000 : 12000; + Haste_Timer = m_bIsRegularMode ? 12000 : 9000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + Polymorph_Timer = m_bIsRegularMode ? 12000 : 10000; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + else + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); +// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS); + } + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1); + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) { + m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Fireball_Timer < diff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FIREBALL : SPELL_FIREBALL_H); + Fireball_Timer = m_bIsRegularMode ? 5000 : 3000; + }else Fireball_Timer -= diff; + + if (Blast_Wave_Timer < diff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_BLAST_WAVE : SPELL_BLAST_WAVE_H); + Blast_Wave_Timer = m_bIsRegularMode ? 20000 : 12000; + }else Blast_Wave_Timer -= diff; + + if (Haste_Timer < diff) + { + DoCast(m_creature, SPELL_HASTE); + Haste_Timer = m_bIsRegularMode ? 10000 : 8000; + }else Haste_Timer -= diff; + + if (Polymorph_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(target, m_bIsRegularMode ? SPELL_POLYMORPH : SPELL_POLYMORPH_H); + Polymorph_Timer = m_bIsRegularMode ? 20000 : 15000; + }else Polymorph_Timer -= diff; + + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_toc5_mage(Creature* pCreature) +{ + return new mob_toc5_mageAI(pCreature); +} + +// Shaman +struct MANGOS_DLL_DECL mob_toc5_shamanAI : public ScriptedAI +{ + mob_toc5_shamanAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Chain_Lightning_Timer; + uint32 Earth_Shield_Timer; + uint32 Healing_Wave_Timer; + uint32 Hex_Timer; + + float mob1_health; + float mob2_health; + float mob3_health; + uint32 m_uiBerserk_Timer; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + Chain_Lightning_Timer = m_bIsRegularMode ? 2000 : 1000; + Earth_Shield_Timer = m_bIsRegularMode ? 10000 : 5000; + Healing_Wave_Timer = m_bIsRegularMode ? 20000 : 12000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + Hex_Timer = m_bIsRegularMode ? 15000 : 10000; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + else + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); +// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS); + } + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1); + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) { + m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Chain_Lightning_Timer < diff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H); + Chain_Lightning_Timer = m_bIsRegularMode ? 12000 : 8000; + }else Chain_Lightning_Timer -= diff; + + if (Hex_Timer < diff) + { + DoCast(m_creature->getVictim(), SPELL_HEX_OF_MENDING); + Hex_Timer = m_bIsRegularMode ? 30000 : 20000; + }else Hex_Timer -= diff; + + if (Healing_Wave_Timer < diff) + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + if (pTemp->isAlive()) + mob1_health = pTemp->GetHealth()*100 / pTemp->GetMaxHealth(); + else + mob1_health = 100; + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + if (pTemp->isAlive()) + mob2_health = pTemp->GetHealth()*100 / pTemp->GetMaxHealth(); + else + mob2_health = 100; + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + if (pTemp->isAlive()) + mob3_health = pTemp->GetHealth()*100 / pTemp->GetMaxHealth(); + else + mob3_health = 100; + if (mob1_health < mob2_health && mob1_health < mob3_health && mob1_health < 70) + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + DoCast(pTemp, m_bIsRegularMode ? SPELL_HEALING_WAVE : SPELL_HEALING_WAVE_H); + if (mob1_health > mob2_health && mob2_health < mob3_health && mob2_health < 70) + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + DoCast(pTemp, m_bIsRegularMode ? SPELL_HEALING_WAVE : SPELL_HEALING_WAVE_H); + if (mob3_health < mob2_health && mob1_health > mob3_health && mob3_health < 70) + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + DoCast(pTemp, m_bIsRegularMode ? SPELL_HEALING_WAVE : SPELL_HEALING_WAVE_H); + Healing_Wave_Timer = m_bIsRegularMode ? 8000 : 6000; + }else Healing_Wave_Timer -= diff; + + if (Earth_Shield_Timer < diff) + { + switch(urand(0, 2)) + { + case 0: + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + if (pTemp->isAlive()) + DoCast(pTemp, SPELL_EARTH_SHIELD); + else + DoCast(m_creature, SPELL_EARTH_SHIELD); + break; + case 1: + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + if (pTemp->isAlive()) + DoCast(pTemp, SPELL_EARTH_SHIELD); + else + DoCast(m_creature, SPELL_EARTH_SHIELD); + break; + case 2: + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + if (pTemp->isAlive()) + DoCast(pTemp, SPELL_EARTH_SHIELD); + else + DoCast(m_creature, SPELL_EARTH_SHIELD); + break; + } + Earth_Shield_Timer = m_bIsRegularMode ? 35000 : 25000; + }else Earth_Shield_Timer -= diff; + + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_toc5_shaman(Creature* pCreature) +{ + return new mob_toc5_shamanAI(pCreature); +} + +// Hunter +struct MANGOS_DLL_DECL mob_toc5_hunterAI : public ScriptedAI +{ + mob_toc5_hunterAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Shoot_Timer; + uint32 Lightning_Arrows_Timer; + uint32 Multi_Shot_Timer; + uint32 Disengage_Cooldown; + uint32 enemy_check; + uint32 disengage_check; + uint32 m_uiBerserk_Timer; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + Shoot_Timer = 0; + Lightning_Arrows_Timer = m_bIsRegularMode ? 18000 : 10000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + Multi_Shot_Timer = m_bIsRegularMode ? 15000 : 8000; + Disengage_Cooldown = 0; + enemy_check = 1000; + disengage_check; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + else + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); +// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS); + } + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1); + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) { + m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (enemy_check < diff) + { + if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 30)) + { + m_creature->SetSpeedRate(MOVE_RUN, 0.0001); + } + else + { + m_creature->SetSpeedRate(MOVE_RUN, 1.2); + } + enemy_check = 100; + }else enemy_check -= diff; + + if (Disengage_Cooldown>0) + Disengage_Cooldown -= diff; + + if (Shoot_Timer < diff) + { + DoCast(m_creature->getVictim(), SPELL_SHOOT); + Shoot_Timer = m_bIsRegularMode ? 5000 : 3000; + }else Shoot_Timer -= diff; + + if (Multi_Shot_Timer < diff) + { + m_creature->CastStop(SPELL_SHOOT); + DoCast(m_creature->getVictim(), SPELL_MULTI_SHOT); + Multi_Shot_Timer = m_bIsRegularMode ? 10000 : 5000; + }else Multi_Shot_Timer -= diff; + + if (Lightning_Arrows_Timer < diff) + { + m_creature->CastStop(SPELL_SHOOT); + DoCast(m_creature, SPELL_LIGHTNING_ARROWS); + Lightning_Arrows_Timer = m_bIsRegularMode ? 15000 : 8000; + }else Lightning_Arrows_Timer -= diff; + + if (disengage_check < diff) + { + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 5) && Disengage_Cooldown == 0) + { + DoCast(m_creature, SPELL_DISENGAGE); + Disengage_Cooldown = m_bIsRegularMode ? 15000 : 10000; + } + disengage_check = 1000; + }else disengage_check -= diff; + + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_toc5_hunter(Creature* pCreature) +{ + return new mob_toc5_hunterAI(pCreature); +} + +// Rogue +struct MANGOS_DLL_DECL mob_toc5_rogueAI : public ScriptedAI +{ + mob_toc5_rogueAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Eviscerate_Timer; + uint32 FoK_Timer; + uint32 Poison_Timer; + uint32 m_uiBerserk_Timer; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + Eviscerate_Timer = m_bIsRegularMode ? 20000 : 10000; + FoK_Timer = m_bIsRegularMode ? 15000 : 10000; + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + Poison_Timer = m_bIsRegularMode ? 12000 : 5000; + m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ()); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + else + { + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); +// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS); + } + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1); + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) { + m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3)))) + pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Eviscerate_Timer < diff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_EVISCERATE : SPELL_EVISCERATE_H); + Eviscerate_Timer = m_bIsRegularMode ? 15000 : 10000; + }else Eviscerate_Timer -= diff; + + if (FoK_Timer < diff) + { + DoCast(m_creature->getVictim(), SPELL_FAN_OF_KNIVES); + FoK_Timer = m_bIsRegularMode ? 12000 : 7000; + }else FoK_Timer -= diff; + + if (Poison_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(m_creature, SPELL_POISON_BOTTLE); + Poison_Timer = m_bIsRegularMode ? 10000 : 5000; + }else Poison_Timer -= diff; + + if (m_uiBerserk_Timer < diff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000; + } + else m_uiBerserk_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_toc5_rogue(Creature* pCreature) +{ + return new mob_toc5_rogueAI(pCreature); +} + +void AddSC_boss_grand_champions() +{ + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "mob_toc5_warrior"; + NewScript->GetAI = &GetAI_mob_toc5_warrior; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_toc5_mage"; + NewScript->GetAI = &GetAI_mob_toc5_mage; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_toc5_shaman"; + NewScript->GetAI = &GetAI_mob_toc5_shaman; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_toc5_hunter"; + NewScript->GetAI = &GetAI_mob_toc5_hunter; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_toc5_rogue"; + NewScript->GetAI = &GetAI_mob_toc5_rogue; + NewScript->RegisterSelf(); +} diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp index 37aeea6f6..75072b435 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,17 +15,541 @@ */ /* ScriptData -SDName: instance_trial_of_the_champion -SD%Complete: 0 -SDComment: -SDCategory: Crusader Coliseum, Trial of the Champion +SDName: Instance_Trial_Of_the_Champion +SD%Complete: 70 +SDComment: modified by /dev/rsa +SDCategory: Trial Of the Champion EndScriptData */ #include "precompiled.h" #include "trial_of_the_champion.h" +#include "World.h" -/* Trial of the Champion encounters: -0 - Grand Champions -1 - Argent Champion -2 - Black Knight -*/ +struct MANGOS_DLL_DECL instance_trial_of_the_champion : public ScriptedInstance +{ + instance_trial_of_the_champion(Map* pMap) : ScriptedInstance(pMap) { Initialize(); } + + uint32 m_auiEncounter[MAX_ENCOUNTER+1]; + + std::string m_strInstData; + + uint64 m_uiJacobGUID; + uint64 m_uiAmbroseGUID; + uint64 m_uiColososGUID; + uint64 m_uiJaelyneGUID; + uint64 m_uiLanaGUID; + uint64 m_uiMokraGUID; + uint64 m_uiEresseaGUID; + uint64 m_uiRunokGUID; + uint64 m_uiZultoreGUID; + uint64 m_uiVisceriGUID; + uint64 m_uiChampionsLootGUID; + uint64 m_uiEadricGUID; + uint64 m_uiEadricLootGUID; + uint64 m_uiPaletressGUID; + uint64 m_uiPaletressLootGUID; + uint64 m_uiBlackKnightGUID; + uint64 m_uiJaerenGUID; + uint64 m_uiArelasGUID; + uint64 m_uiAnnouncerGUID; + uint32 m_uiChampionId1; + uint32 m_uiChampionId2; + uint32 m_uiChampionId3; + uint32 m_uiChampionsCount; + uint64 m_uiChampion1; + uint64 m_uiChampion2; + uint64 m_uiChampion3; + uint64 m_uiBlackKnightMinionGUID; + uint64 m_uiArgentChallenger; + uint64 m_uiArgentChallengerID; + uint64 m_uiMemoryGUID; + + void Initialize() + { + m_uiJacobGUID = 0; + m_uiAmbroseGUID = 0; + m_uiColososGUID = 0; + m_uiJaelyneGUID = 0; + m_uiLanaGUID = 0; + m_uiMokraGUID = 0; + m_uiEresseaGUID = 0; + m_uiRunokGUID = 0; + m_uiZultoreGUID = 0; + m_uiVisceriGUID = 0; + m_uiChampionsLootGUID = 0; + m_uiEadricGUID = 0; + m_uiEadricLootGUID = 0; + m_uiPaletressGUID = 0; + m_uiPaletressLootGUID = 0; + m_uiBlackKnightGUID = 0; + m_uiJaerenGUID = 0; + m_uiArelasGUID = 0; + m_uiAnnouncerGUID = 0; + m_uiBlackKnightMinionGUID = 0; + m_uiChampionId1 = 0; + m_uiChampionId2 = 0; + m_uiChampionId3 = 0; + m_uiChampion1 = 0; + m_uiChampion2 = 0; + m_uiChampion3 = 0; + m_uiChampionsCount = 3; + m_uiArgentChallenger = 0; + m_uiMemoryGUID = 0; + m_uiArgentChallengerID = 0; + + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + m_auiEncounter[i] = NOT_STARTED; + } + + void OnPlayerEnter(Player *pPlayer) + { + + enum PhaseControl + { + HORDE_CONTROL_PHASE_SHIFT_1 = 55773, + HORDE_CONTROL_PHASE_SHIFT_2 = 60028, + ALLIANCE_CONTROL_PHASE_SHIFT_1 = 55774, + ALLIANCE_CONTROL_PHASE_SHIFT_2 = 60027, + }; + if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP)) return; + + switch (pPlayer->GetTeam()) + { + case ALLIANCE: + if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(HORDE_CONTROL_PHASE_SHIFT_1)) + pPlayer->RemoveAurasDueToSpell(HORDE_CONTROL_PHASE_SHIFT_1); + pPlayer->CastSpell(pPlayer, HORDE_CONTROL_PHASE_SHIFT_2, false); + break; + case HORDE: + if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(ALLIANCE_CONTROL_PHASE_SHIFT_1)) + pPlayer->RemoveAurasDueToSpell(ALLIANCE_CONTROL_PHASE_SHIFT_1); + pPlayer->CastSpell(pPlayer, ALLIANCE_CONTROL_PHASE_SHIFT_2, false); + break; + }; + }; + + void OnCreatureCreate(Creature* pCreature) + { + switch(pCreature->GetEntry()) + { + // Champions of the Alliance + case NPC_JACOB: + m_uiJacobGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_AMBROSE: + m_uiAmbroseGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_COLOSOS: + m_uiColososGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_JAELYNE: + m_uiJaelyneGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_LANA: + m_uiLanaGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + + // Champions of the Horde + case NPC_MOKRA: + m_uiMokraGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_ERESSEA: + m_uiEresseaGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_RUNOK: + m_uiRunokGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_ZULTORE: + m_uiZultoreGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + case NPC_VISCERI: + m_uiVisceriGUID = pCreature->GetGUID(); + if (m_uiChampion1 == 0) + m_uiChampion1 = pCreature->GetGUID(); + else + if (m_uiChampion2 == 0) + m_uiChampion2 = pCreature->GetGUID(); + else + if (m_uiChampion3 == 0) + m_uiChampion3 = pCreature->GetGUID(); + break; + + // Argent Challenge + case NPC_EADRIC: + m_uiEadricGUID = pCreature->GetGUID(); + m_uiArgentChallenger = pCreature->GetGUID(); + break; + case NPC_PALETRESS: + m_uiPaletressGUID = pCreature->GetGUID(); + m_uiArgentChallenger = pCreature->GetGUID(); + break; + + // Black Knight + case NPC_BLACK_KNIGHT: + m_uiBlackKnightGUID = pCreature->GetGUID(); + break; + case NPC_RISEN_JAEREN: + m_uiBlackKnightMinionGUID = pCreature->GetGUID(); + break; + case NPC_RISEN_ARELAS: + m_uiBlackKnightMinionGUID = pCreature->GetGUID(); + break; + + // Coliseum Announcers + case NPC_JAEREN: + m_uiJaerenGUID = pCreature->GetGUID(); + break; + case NPC_ARELAS: + m_uiArelasGUID = pCreature->GetGUID(); + break; + + // memories + case MEMORY_ALGALON: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_ARCHIMONDE: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_CHROMAGGUS: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_CYANIGOSA: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_DELRISSA: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_ECK: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_ENTROPIUS: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_GRUUL: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_HAKKAR: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_HEIGAN: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_HEROD: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_HOGGER: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_IGNIS: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_ILLIDAN: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_INGVAR: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_KALITHRESH: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_LUCIFRON: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_MALCHEZAAR: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_MUTANUS: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_ONYXIA: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_THUNDERAAN: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_VANCLEEF: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_VASHJ: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_VEKNILASH: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + case MEMORY_VEZAX: + m_uiMemoryGUID = pCreature->GetGUID(); + break; + } + } + + void OnObjectCreate(GameObject *pGo) + { + switch(pGo->GetEntry()) + { + case GO_CHAMPIONS_LOOT: + m_uiChampionsLootGUID = pGo->GetGUID(); + break; + case GO_EADRIC_LOOT: + m_uiEadricLootGUID = pGo->GetGUID(); + break; + case GO_PALETRESS_LOOT: + m_uiPaletressLootGUID = pGo->GetGUID(); + break; + case GO_CHAMPIONS_LOOT_H: + m_uiChampionsLootGUID = pGo->GetGUID(); + break; + case GO_EADRIC_LOOT_H: + m_uiEadricLootGUID = pGo->GetGUID(); + break; + case GO_PALETRESS_LOOT_H: + m_uiPaletressLootGUID = pGo->GetGUID(); + break; + } + } + + void SetData(uint32 uiType, uint32 uiData) + { + switch(uiType) + { + case DATA_TOC5_ANNOUNCER: + m_uiAnnouncerGUID = uiData; + break; + case DATA_CHAMPIONID_1: + m_uiChampionId1 = uiData; + break; + case DATA_CHAMPIONID_2: + m_uiChampionId2 = uiData; + break; + case DATA_CHAMPIONID_3: + m_uiChampionId3 = uiData; + break; + case DATA_CHAMPIONS_COUNT: + m_uiChampionsCount = uiData; + break; + case DATA_ARGENT_CHALLENGER: + m_uiArgentChallengerID = uiData; + break; + case DATA_BLACK_KNIGHT_MINION: + m_uiBlackKnightMinionGUID = uiData; + break; + case TYPE_GRAND_CHAMPIONS: + m_auiEncounter[0] = uiData; + if (uiData == DONE) + { + if (GameObject* pChest = instance->GetGameObject(m_uiChampionsLootGUID)) + if (pChest && !pChest->isSpawned()) + pChest->SetRespawnTime(DAY); + } + if (uiData == FAIL) + { + m_auiEncounter[0] = NOT_STARTED; + } + break; + case TYPE_ARGENT_CHALLENGE: + m_auiEncounter[1] = uiData; + if (uiData == DONE) + { + if (m_uiArgentChallenger == m_uiEadricGUID) + if (GameObject* pChest = instance->GetGameObject(m_uiEadricLootGUID)) + if (pChest && !pChest->isSpawned()) + pChest->SetRespawnTime(DAY); + if (m_uiArgentChallenger == m_uiPaletressGUID) + if (GameObject* pChest = instance->GetGameObject(m_uiPaletressLootGUID)) + if (pChest && !pChest->isSpawned()) + pChest->SetRespawnTime(DAY); + } + if (uiData == FAIL) + { + m_auiEncounter[1] = NOT_STARTED; + } + break; + case TYPE_BLACK_KNIGHT: + m_auiEncounter[2] = uiData; + if (uiData == FAIL) + { + m_auiEncounter[2] = NOT_STARTED; + } + break; + } + + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + saveStream << m_auiEncounter[i] << " "; + + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + uint64 GetData64(uint32 uiData) + { + switch(uiData) + { + case DATA_CHAMPION_1: + return m_uiChampion1; + case DATA_CHAMPION_2: + return m_uiChampion2; + case DATA_CHAMPION_3: + return m_uiChampion3; + case DATA_MEMORY: + return m_uiMemoryGUID; + case DATA_ARGENT_CHALLENGER: + return m_uiArgentChallenger; + case DATA_BLACK_KNIGHT: + return m_uiBlackKnightGUID; + } + + return 0; + } + + uint32 GetData(uint32 uiType) + { + switch(uiType) + { + case DATA_CHAMPIONID_1: + return m_uiChampionId1; + case DATA_CHAMPIONID_2: + return m_uiChampionId2; + case DATA_CHAMPIONID_3: + return m_uiChampionId3; + case DATA_CHAMPIONS_COUNT: + return m_uiChampionsCount; + case DATA_ARGENT_CHALLENGER: + return m_uiArgentChallengerID; + case DATA_BLACK_KNIGHT_MINION: + return m_uiBlackKnightMinionGUID; + case DATA_TOC5_ANNOUNCER: + return m_uiAnnouncerGUID; + case DATA_JAEREN: + return m_uiJaerenGUID; + case DATA_ARELAS: + return m_uiArelasGUID; + case TYPE_GRAND_CHAMPIONS: return m_auiEncounter[0]; + case TYPE_ARGENT_CHALLENGE: return m_auiEncounter[1]; + case TYPE_BLACK_KNIGHT: return m_auiEncounter[2]; + } + + return 0; + } + + const char* Save() + { + return m_strInstData.c_str(); + } + + void Load(const char* strIn) + { + if (!strIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(strIn); + + std::istringstream loadStream(strIn); + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + loadStream >> m_auiEncounter[i]; + + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; + } +}; + +InstanceData* GetInstanceData_instance_trial_of_the_champion(Map* pMap) +{ + return new instance_trial_of_the_champion(pMap); +} + +void AddSC_instance_trial_of_the_champion() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_trial_of_the_champion"; + newscript->GetInstanceData = &GetInstanceData_instance_trial_of_the_champion; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp index 3ebfa687a..9ad547fc7 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,11 +15,235 @@ */ /* ScriptData -SDName: trial_of_the_champion -SD%Complete: 0 -SDComment: -SDCategory: Crusader Coliseum, Trial of the Champion +SDName: Trial Of the Champion +SD%Complete: 80% +SDComment: event script. modified by /dev/rsa +SDCategory: trial_of_the_champion EndScriptData */ +/* ContentData +npc_toc5_announcer +EndContentData */ + #include "precompiled.h" #include "trial_of_the_champion.h" + +#define GOSSIP_START_EVENT "Im ready for the next challenge." + +/*###### +## npc_toc5_announcer +######*/ +struct _Messages +{ + char const* name; + uint32 id; + bool state; + uint32 encounter; +}; + +static _Messages _GossipMessage[]= +{ +{"Вы готовы драться с чемпионами противоположной фракции?",GOSSIP_ACTION_INFO_DEF+1,false,TYPE_GRAND_CHAMPIONS}, // +{"Вы готовы драться с чемпионом Серебряного Рассвета?",GOSSIP_ACTION_INFO_DEF+2,false,TYPE_ARGENT_CHALLENGE}, // +{"Вы готовы драться с Черным рыцарем?",GOSSIP_ACTION_INFO_DEF+3,false,TYPE_BLACK_KNIGHT}, // +{"Не надо сюда тыкать. На сегодня арена закрыта.",GOSSIP_ACTION_INFO_DEF+4,true,TYPE_BLACK_KNIGHT}, // +}; + +struct MANGOS_DLL_DECL npc_toc5_announcerAI : public ScriptedAI +{ + npc_toc5_announcerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + } + + void UpdateAI(const uint32 diff) + { + if (!m_pInstance) return; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + } +}; + +CreatureAI* GetAI_npc_toc5_announcer(Creature* pCreature) +{ + return new npc_toc5_announcerAI(pCreature); +} + +bool GossipHello_npc_toc5_announcer(Player* pPlayer, Creature* pCreature) +{ + + ScriptedInstance* m_pInstance; + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + + if (!m_pInstance) return false; + + if(!pPlayer->getAttackers().empty()) return true; + + for(uint8 i = 0; i < MAX_ENCOUNTER+1; i++) { + if (!_GossipMessage[i].state && (m_pInstance->GetData(_GossipMessage[i].encounter) == NOT_STARTED || m_pInstance->GetData(_GossipMessage[i].encounter) == IN_PROGRESS)) + {pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _GossipMessage[i].name, GOSSIP_SENDER_MAIN,_GossipMessage[i].id); + break; + } + if (_GossipMessage[i].state && m_pInstance->GetData(_GossipMessage[i].encounter) == DONE) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _GossipMessage[i].name, GOSSIP_SENDER_MAIN,_GossipMessage[i].id); + }; + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_toc5_announcer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance* m_pInstance; + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + +pPlayer->CLOSE_GOSSIP_MENU(); + +switch(uiAction) { + case GOSSIP_ACTION_INFO_DEF+1: { + if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == 0) { + m_pInstance->SetData(DATA_TOC5_ANNOUNCER, pCreature->GetGUID()); + + if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == m_pInstance->GetData(DATA_ARELAS)) + { + m_pInstance->SetData(DATA_BLACK_KNIGHT_MINION, 35564); + switch(urand(0, 4)) + { + case 0: m_pInstance->SetData(DATA_CHAMPIONID_1, 35572); break; + case 1: m_pInstance->SetData(DATA_CHAMPIONID_1, 35569); break; + case 2: m_pInstance->SetData(DATA_CHAMPIONID_1, 35571); break; + case 3: m_pInstance->SetData(DATA_CHAMPIONID_1, 35570); break; + case 4: m_pInstance->SetData(DATA_CHAMPIONID_1, 35617); break; + }; + do{ + switch(urand(0, 4)) + { + case 0: m_pInstance->SetData(DATA_CHAMPIONID_2, 35572); break; + case 1: m_pInstance->SetData(DATA_CHAMPIONID_2, 35569); break; + case 2: m_pInstance->SetData(DATA_CHAMPIONID_2, 35571); break; + case 3: m_pInstance->SetData(DATA_CHAMPIONID_2, 35570); break; + case 4: m_pInstance->SetData(DATA_CHAMPIONID_2, 35617); break; + } + } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_2)); + do{ + switch(urand(0, 4)) + { + case 0: m_pInstance->SetData(DATA_CHAMPIONID_3, 35572); break; + case 1: m_pInstance->SetData(DATA_CHAMPIONID_3, 35569); break; + case 2: m_pInstance->SetData(DATA_CHAMPIONID_3, 35571); break; + case 3: m_pInstance->SetData(DATA_CHAMPIONID_3, 35570); break; + case 4: m_pInstance->SetData(DATA_CHAMPIONID_3, 35617); break; + } + } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_3) || m_pInstance->GetData(DATA_CHAMPIONID_2) == m_pInstance->GetData(DATA_CHAMPIONID_3)); + }; + + if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == m_pInstance->GetData(DATA_JAEREN)) + { + m_pInstance->SetData(DATA_BLACK_KNIGHT_MINION, 123); + + switch(urand(0, 4)) + { + case 0: m_pInstance->SetData(DATA_CHAMPIONID_1, 34705); break; + case 1: m_pInstance->SetData(DATA_CHAMPIONID_1, 34702); break; + case 2: m_pInstance->SetData(DATA_CHAMPIONID_1, 34701); break; + case 3: m_pInstance->SetData(DATA_CHAMPIONID_1, 34657); break; + case 4: m_pInstance->SetData(DATA_CHAMPIONID_1, 34703); break; + } + do{ + switch(urand(0, 4)) + { + case 0: m_pInstance->SetData(DATA_CHAMPIONID_2, 34705); break; + case 1: m_pInstance->SetData(DATA_CHAMPIONID_2, 34702); break; + case 2: m_pInstance->SetData(DATA_CHAMPIONID_2, 34701); break; + case 3: m_pInstance->SetData(DATA_CHAMPIONID_2, 34657); break; + case 4: m_pInstance->SetData(DATA_CHAMPIONID_2, 34703); break; + } + } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_2)); + do{ + switch(urand(0, 4)) + { + case 0: m_pInstance->SetData(DATA_CHAMPIONID_3, 34705); break; + case 1: m_pInstance->SetData(DATA_CHAMPIONID_3, 34702); break; + case 2: m_pInstance->SetData(DATA_CHAMPIONID_3, 34701); break; + case 3: m_pInstance->SetData(DATA_CHAMPIONID_3, 34657); break; + case 4: m_pInstance->SetData(DATA_CHAMPIONID_3, 34703); break; + } + } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_3) || m_pInstance->GetData(DATA_CHAMPIONID_2) == m_pInstance->GetData(DATA_CHAMPIONID_3)); + + }; + + switch(urand(0, 1)) + { + case 0: m_pInstance->SetData(DATA_ARGENT_CHALLENGER, 35119); break; + case 1: m_pInstance->SetData(DATA_ARGENT_CHALLENGER, 34928); break; + }; + }; + + if (m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == NOT_STARTED || m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == IN_PROGRESS) + { + m_pInstance->SetData(DATA_CHAMPIONS_COUNT, 3); + if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_CHAMPION_1))) + pTemp->Respawn(); + else + pCreature->SummonCreature(m_pInstance->GetData(DATA_CHAMPIONID_1), 738.665771f, 661.031433f, 412.394623f, 4.698702f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_CHAMPION_2))) + pTemp->Respawn(); + else + pCreature->SummonCreature(m_pInstance->GetData(DATA_CHAMPIONID_2), 746.864441f, 660.918762f, 411.695465f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_CHAMPION_3))) + pTemp->Respawn(); + else + pCreature->SummonCreature(m_pInstance->GetData(DATA_CHAMPIONID_3), 754.360779f, 660.816162f, 412.395996f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS); + }; + }; + + case GOSSIP_ACTION_INFO_DEF+2: { + if ((m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) == NOT_STARTED || m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) == IN_PROGRESS) && m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE) + { + if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ARGENT_CHALLENGER))) + pTemp->Respawn(); + else + pCreature->SummonCreature(m_pInstance->GetData(DATA_ARGENT_CHALLENGER), 746.864441f, 660.918762f, 411.695465f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, IN_PROGRESS); + }; + + }; + + case GOSSIP_ACTION_INFO_DEF+3: { + if ((m_pInstance->GetData(TYPE_BLACK_KNIGHT) == NOT_STARTED || m_pInstance->GetData(TYPE_BLACK_KNIGHT) == IN_PROGRESS) && m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) == DONE) + { + pCreature->SummonCreature(NPC_BLACK_KNIGHT, 746.864441f, 660.918762f, 411.695465f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + pCreature->DealDamage(pCreature, pCreature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_pInstance->SetData(TYPE_BLACK_KNIGHT, IN_PROGRESS); + }; + }; + + case GOSSIP_ACTION_INFO_DEF+4: { + if (m_pInstance->GetData(TYPE_BLACK_KNIGHT) == DONE) { + pCreature->DealDamage(pCreature, pCreature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + }; + }; +}; + + return true; +} + +void AddSC_trial_of_the_champion() +{ + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "npc_toc5_announcer"; + NewScript->GetAI = &GetAI_npc_toc5_announcer; + NewScript->pGossipHello = &GossipHello_npc_toc5_announcer; + NewScript->pGossipSelect = &GossipSelect_npc_toc5_announcer; + NewScript->RegisterSelf(); +} diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h index d7778d506..a263069ab 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h @@ -1,17 +1,86 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ -#ifndef DEF_TRIAL_OF_THE_CHAMPION_H -#define DEF_TRIAL_OF_THE_CHAMPION_H +#ifndef DEF_TOC_H +#define DEF_TOC_H enum { - MAX_ENCOUNTER = 3, + MAX_ENCOUNTER = 3, + + TYPE_GRAND_CHAMPIONS = 0, + TYPE_ARGENT_CHALLENGE = 1, + TYPE_BLACK_KNIGHT = 2, + + DATA_CHAMPION_1 = 3, + DATA_CHAMPION_2 = 4, + DATA_CHAMPION_3 = 5, + DATA_BLACK_KNIGHT = 6, + DATA_BLACK_KNIGHT_MINION = 7, + DATA_TOC5_ANNOUNCER = 8, + DATA_JAEREN = 9, + DATA_ARELAS = 10, + DATA_CHAMPIONID_1 = 11, + DATA_CHAMPIONID_2 = 12, + DATA_CHAMPIONID_3 = 13, + DATA_MEMORY = 14, + DATA_ARGENT_CHALLENGER = 15, + DATA_CHAMPIONS_COUNT = 16, + + NPC_JACOB = 34705, + NPC_AMBROSE = 34702, + NPC_COLOSOS = 34701, + NPC_JAELYNE = 34657, + NPC_LANA = 34703, + NPC_MOKRA = 35572, + NPC_ERESSEA = 35569, + NPC_RUNOK = 35571, + NPC_ZULTORE = 35570, + NPC_VISCERI = 35617, + NPC_EADRIC = 35119, + NPC_PALETRESS = 34928, + NPC_BLACK_KNIGHT = 35451, + NPC_RISEN_JAEREN = 35545, + NPC_RISEN_ARELAS = 35564, + NPC_JAEREN = 35004, + + NPC_ARELAS = 35005, + MEMORY_ALGALON = 35052, + MEMORY_ARCHIMONDE = 35041, + MEMORY_CHROMAGGUS = 35033, + MEMORY_CYANIGOSA = 35046, + MEMORY_DELRISSA = 35043, + MEMORY_ECK = 35047, + MEMORY_ENTROPIUS = 35044, + MEMORY_GRUUL = 35039, + MEMORY_HAKKAR = 35034, + MEMORY_HEIGAN = 35049, + MEMORY_HEROD = 35030, + MEMORY_HOGGER = 34942, + MEMORY_IGNIS = 35050, + MEMORY_ILLIDAN = 35042, + MEMORY_INGVAR = 35045, + MEMORY_KALITHRESH = 35037, + MEMORY_LUCIFRON = 35031, + MEMORY_MALCHEZAAR = 35038, + MEMORY_MUTANUS = 35029, + MEMORY_ONYXIA = 35048, + MEMORY_THUNDERAAN = 35032, + MEMORY_VANCLEEF = 35028, + MEMORY_VASHJ = 35040, + MEMORY_VEKNILASH = 35036, + MEMORY_VEZAX = 35051, + + GO_CHAMPIONS_LOOT = 195709, + GO_CHAMPIONS_LOOT_H = 195710, + GO_EADRIC_LOOT = 195374, + GO_EADRIC_LOOT_H = 195375, + GO_PALETRESS_LOOT = 195323, + GO_PALETRESS_LOOT_H = 195324, + + DESPAWN_TIME = 300000 - TYPE_GRAND_CHAMPIONS = 0, - TYPE_ARGENT_CHAMPION = 1, - TYPE_BLACK_KNIGHT = 2, }; #endif diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp index 25a3f1f7e..9495629e9 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,52 +16,110 @@ /* ScriptData SDName: boss_anubarak_trial -SD%Complete: 0 -SDComment: +SD%Complete: 70% +SDComment: by /dev/rsa SDCategory: EndScriptData */ +// Anubarak - underground phase partially not worked, timers need correct +// Burrower - underground phase not implemented, buff not worked. +// Leecheng Swarm spell not worked - awaiting core support +// Anubarak spike aura worked only after 9750 + #include "precompiled.h" #include "trial_of_the_crusader.h" -enum +enum Summons { - SAY_AGGRO = -1649064, - SAY_SLAY_1 = -1649065, - SAY_SLAY_2 = -1649066, - SAY_DEATH = -1649067, - SAY_BERSERK = -1649068, - SAY_SUBMERGE = -1649069, - SAY_LEECHING_SWARM = -1649070, + NPC_FROST_SPHERE = 34606, + NPC_BURROWER = 34607, + NPC_SCARAB = 34605, + NPC_SPIKE = 34660, }; -struct MANGOS_DLL_DECL boss_anubarak_trialAI : public ScriptedAI +enum BossSpells { - boss_anubarak_trialAI(Creature* pCreature) : ScriptedAI(pCreature) +SPELL_COLD = 66013, +SPELL_MARK = 67574, +SPELL_LEECHING_SWARM = 66118, +SPELL_LEECHING_HEAL = 66125, +SPELL_LEECHING_DAMAGE = 66240, +SPELL_IMPALE = 65920, +SPELL_SPIKE_CALL = 66169, +SPELL_POUND = 66012, +SPELL_SHOUT = 67730, +SPELL_SUBMERGE_0 = 53421, +SPELL_SUBMERGE_1 = 67322, +SPELL_SUMMON_BEATLES = 66339, +SPELL_DETERMINATION = 66092, +SPELL_ACID_MANDIBLE = 67861, +SPELL_SPIDER_FRENZY = 66129, +SPELL_EXPOSE_WEAKNESS = 67847, +SUMMON_SCARAB = NPC_SCARAB, +SUMMON_BORROWER = NPC_BURROWER, +SUMMON_FROSTSPHERE = NPC_FROST_SPHERE, +SPELL_BERSERK = 26662, +SPELL_PERMAFROST = 66193, +}; + +struct MANGOS_DLL_DECL boss_anubarak_trialAI : public BSWScriptedAI +{ + boss_anubarak_trialAI(Creature* pCreature) : BSWScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } ScriptedInstance* m_pInstance; + uint8 stage; + bool intro; + Unit* pTarget; + + void Reset() { + if(!m_pInstance) return; + stage = 0; + intro = true; + m_creature->SetRespawnDelay(DAY); + pTarget = NULL; + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } - void Reset() {} + + void KilledUnit(Unit* pVictim) + { + DoScriptText(-1713563,m_creature); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!intro) return; + DoScriptText(-1713554,m_creature); + intro = false; + m_creature->SetInCombatWithZone(); + } void JustReachedHome() { if (m_pInstance) - m_pInstance->SetData(TYPE_ANUBARAK, NOT_STARTED); + m_pInstance->SetData(TYPE_ANUBARAK, FAIL); +// m_creature->ForcedDespawn(); } void JustDied(Unit* pKiller) { - if (m_pInstance) + if (!m_pInstance) return; + DoScriptText(-1713564,m_creature); m_pInstance->SetData(TYPE_ANUBARAK, DONE); } void Aggro(Unit* pWho) { + if (!intro) DoScriptText(-1713555,m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetInCombatWithZone(); + m_pInstance->SetData(TYPE_ANUBARAK, IN_PROGRESS); } void UpdateAI(const uint32 uiDiff) @@ -69,6 +127,66 @@ struct MANGOS_DLL_DECL boss_anubarak_trialAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + switch(stage) + { + case 0: { + timedCast(SPELL_POUND, uiDiff); + timedCast(SPELL_COLD, uiDiff); + if (timedQuery(SUMMON_BORROWER, uiDiff)) { + doCast(SUMMON_BORROWER); + DoScriptText(-1713556,m_creature); + }; + if (timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 1; + + break;} + case 1: { + doCast(SPELL_SUBMERGE_0); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + stage = 2; + DoScriptText(-1713557,m_creature); + break;} + case 2: { + if (timedQuery(SPELL_SPIKE_CALL, uiDiff)) { + pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); +// doCast(SPELL_SPIKE_CALL); +// This summon not supported in database. Temporary override. + Unit* spike = doSummon(NPC_SPIKE,TEMPSUMMON_TIMED_DESPAWN,60000); + if (spike) { spike->AddThreat(pTarget, 1000.0f); + DoScriptText(-1713558,m_creature,pTarget); + doCast(SPELL_MARK,pTarget); + spike->GetMotionMaster()->MoveChase(pTarget); + } + }; + if (timedQuery(SPELL_SUMMON_BEATLES, uiDiff)) { + doCast(SPELL_SUMMON_BEATLES); + doCast(SUMMON_SCARAB); + DoScriptText(-1713560,m_creature); + }; + if (timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 3; + break;} + case 3: { + stage = 0; + DoScriptText(-1713559,m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + doRemove(SPELL_SUBMERGE_0,m_creature); + break;} + case 4: { + doCast(SPELL_LEECHING_SWARM); + DoScriptText(-1713561,m_creature); + stage = 5; + break;} + case 5: { + timedCast(SPELL_POUND, uiDiff); + timedCast(SPELL_COLD, uiDiff); + break;} + + } + timedCast(SUMMON_FROSTSPHERE, uiDiff); + + timedCast(SPELL_BERSERK, uiDiff); + + if (m_creature->GetHealthPercent() < 30.0f && stage == 0) stage = 4; + DoMeleeAttackIfReady(); } }; @@ -78,6 +196,216 @@ CreatureAI* GetAI_boss_anubarak_trial(Creature* pCreature) return new boss_anubarak_trialAI(pCreature); } +struct MANGOS_DLL_DECL mob_swarm_scarabAI : public BSWScriptedAI +{ + mob_swarm_scarabAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(DAY); + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) return; + } + + void JustDied(Unit* Killer) + { + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_DETERMINATION, uiDiff); + + timedCast(SPELL_ACID_MANDIBLE, uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_swarm_scarab(Creature* pCreature) +{ + return new mob_swarm_scarabAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_nerubian_borrowerAI : public BSWScriptedAI +{ + mob_nerubian_borrowerAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool submerged; + Unit* currentTarget; + + void Reset() + { + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(DAY); + submerged = false; + currentTarget = NULL; + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) return; + } + + void JustDied(Unit* Killer) + { + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_EXPOSE_WEAKNESS, uiDiff); + + if (timedQuery(SPELL_SPIDER_FRENZY, uiDiff)) + if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, NPC_BURROWER, 50.0f)) + { + currentTarget = pTemp; + doCast(SPELL_SPIDER_FRENZY); + }; + + if (m_creature->GetHealthPercent() < 20.0f && timedQuery(SPELL_SUBMERGE_1, uiDiff) && !submerged) + { + doCast(SPELL_SUBMERGE_1); + submerged = true; + DoScriptText(-1713557,m_creature); + }; + + if (m_creature->GetHealthPercent() > 50.0f && submerged) + { + doRemove(SPELL_SUBMERGE_1,m_creature); + submerged = false; + DoScriptText(-1713559,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_nerubian_borrower(Creature* pCreature) +{ + return new mob_nerubian_borrowerAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_frost_sphereAI : public BSWScriptedAI +{ + mob_frost_sphereAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->SetSpeedRate(MOVE_RUN, 0.1f); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MoveRandom(); + } + + void EnterCombat(Unit* attacker) + { + doCast(SPELL_PERMAFROST); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS) + m_creature->ForcedDespawn(); + } +}; + +CreatureAI* GetAI_mob_frost_sphere(Creature* pCreature) +{ + return new mob_frost_sphereAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_anubarak_spikeAI : public BSWScriptedAI +{ + mob_anubarak_spikeAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + Unit* defaultTarget; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->SetSpeedRate(MOVE_RUN, 0.5f); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + defaultTarget = NULL; + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + doCast(SPELL_IMPALE); + defaultTarget = who; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS) + m_creature->ForcedDespawn(); + if (defaultTarget) + if (!defaultTarget->isAlive() || !hasAura(SPELL_MARK,defaultTarget)) + m_creature->ForcedDespawn(); + +/* if (timedQuery(SPELL_IMPALE,uiDiff)) { + if (m_creature->IsWithinDist(m_creature->getVictim(), 4.0f) + && !hasAura(SPELL_PERMAFROST,m_creature->getVictim())) + { + doCast(SPELL_IMPALE); + } else doRemove(SPELL_IMPALE); + }*/ + } +}; + +CreatureAI* GetAI_mob_anubarak_spike(Creature* pCreature) +{ + return new mob_anubarak_spikeAI(pCreature); +}; + void AddSC_boss_anubarak_trial() { Script* newscript; @@ -86,4 +414,25 @@ void AddSC_boss_anubarak_trial() newscript->Name = "boss_anubarak_trial"; newscript->GetAI = &GetAI_boss_anubarak_trial; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_swarm_scarab"; + newscript->GetAI = &GetAI_mob_swarm_scarab; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_nerubian_borrower"; + newscript->GetAI = &GetAI_mob_nerubian_borrower; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_anubarak_spike"; + newscript->GetAI = &GetAI_mob_anubarak_spike; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_frost_sphere"; + newscript->GetAI = &GetAI_mob_frost_sphere; + newscript->RegisterSelf(); + } \ No newline at end of file diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp index 379d45ad5..98738a8dc 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -11,28 +11,1095 @@ * * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* ScriptData SDName: faction_champions -SD%Complete: 0 -SDComment: +SD%Complete: 60% +SDComment: Scripts by Selector, modified by /dev/rsa SDCategory: Crusader Coliseum EndScriptData */ #include "precompiled.h" #include "trial_of_the_crusader.h" -enum +#define AI_MELEE 0 +#define AI_RANGED 1 +#define AI_HEALER 2 + +#define SPELL_ANTI_AOE 68595 +#define SPELL_PVP_TRINKET 65547 + +struct MANGOS_DLL_DECL boss_faction_championsAI : public BSWScriptedAI +{ + boss_faction_championsAI(Creature* pCreature, uint32 aitype) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + mAIType = aitype; + Init(); + } + + ScriptedInstance* m_pInstance; + + uint32 mAIType; + uint32 ThreatTimer; + uint32 CCTimer; + + void Init() + { + CCTimer = rand()%10000; + ThreatTimer = 5000; + resetTimers(); + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(DAY); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_CRUSADERS, FAIL); + m_creature->ForcedDespawn(); + } + + float CalculateThreat(float distance, float armor, uint32 health) + { + float dist_mod = (mAIType == AI_MELEE) ? 15.0f/(15.0f + distance) : 1.0f; + float armor_mod = (mAIType == AI_MELEE) ? armor / 16635.0f : 0.0f; + float eh = (health+1) * (1.0f + armor_mod); + return dist_mod * 30000.0f / eh; + } + + void UpdateThreat() + { + ThreatList const& tList = m_creature->getThreatManager().getThreatList(); + ThreatList::const_iterator itr; + bool empty = true; + for(itr = tList.begin(); itr!=tList.end(); ++itr) + { + Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + if (pUnit && m_creature->getThreatManager().getThreat(pUnit)) + { + if(pUnit->GetTypeId()==TYPEID_PLAYER) + { + float threat = CalculateThreat(m_creature->GetDistance2d(pUnit), (float)pUnit->GetArmor(), pUnit->GetHealth()); + m_creature->getThreatManager().modifyThreatPercent(pUnit, -100); + m_creature->AddThreat(pUnit, 1000000.0f * threat); + empty = false; + } + } + } + } + + void UpdatePower() + { + if(m_creature->getPowerType() == POWER_MANA) + m_creature->ModifyPower(POWER_MANA, m_creature->GetMaxPower(POWER_MANA) / 3); + //else if(m_creature->getPowerType() == POWER_ENERGY) + // m_creature->ModifyPower(POWER_ENERGY, 100); + } + + void RemoveCC() + { + m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_STUN); + m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_FEAR); + m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); + m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_PACIFY); + m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_CONFUSE); + //DoCast(m_creature, SPELL_PVP_TRINKET); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) m_pInstance->SetData(TYPE_CRUSADERS_COUNT, 0); + } + + void Aggro(Unit *who) + { + if(!m_pInstance) return; + m_pInstance->SetData(TYPE_CRUSADERS, IN_PROGRESS); + DoCast(m_creature, SPELL_ANTI_AOE, true); + if(who->GetTypeId() != TYPEID_PLAYER) + if (Unit* player = doSelectRandomPlayerAtRange(80.0f)) + m_creature->AddThreat(player, 100.0f); + } + + void Reset() + { + if(m_pInstance) m_pInstance->SetData(TYPE_CRUSADERS, NOT_STARTED); + } + + Creature* SelectRandomFriendlyMissingBuff(uint32 spell) + { + std::list lst = DoFindFriendlyMissingBuff(40.0f, spell); + std::list::const_iterator itr = lst.begin(); + if(lst.empty()) + return NULL; + advance(itr, rand()%lst.size()); + return (*itr); + } + + Unit* SelectEnemyCaster(bool casting) + { + ThreatList const& tList = m_creature->getThreatManager().getThreatList(); + ThreatList::const_iterator iter; + for(iter = tList.begin(); iter!=tList.end(); ++iter) + { + Unit *target; + if(target = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid())) + if(target->getPowerType() == POWER_MANA) + return target; + } + return NULL; + } + + uint32 EnemiesInRange(float distance) + { + ThreatList const& tList = m_creature->getThreatManager().getThreatList(); + ThreatList::const_iterator iter; + uint32 count = 0; + for(iter = tList.begin(); iter!=tList.end(); ++iter) + { + Unit *target; + if(target = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid())) + if(m_creature->GetDistance2d(target) < distance) + ++count; + } + return count; + } + + void 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(mAIType==AI_MELEE) + DoStartMovement(pWho); + else + DoStartMovement(pWho, 20.0f); + + SetCombatMovement(true); + + } + } + + void UpdateAI(const uint32 diff) + { + if(ThreatTimer < diff) + { + UpdatePower(); + UpdateThreat(); + ThreatTimer = 4000; + } + else ThreatTimer -= diff; + + if(CCTimer < diff) + { + RemoveCC(); + CCTimer = 8000+rand()%2000; + } + else CCTimer -= diff; + + if(mAIType == AI_MELEE) DoMeleeAttackIfReady(); + } +}; + +/******************************************************************** + HEALERS +********************************************************************/ + +#define SPELL_LIFEBLOOM 66093 +#define SPELL_NOURISH 66066 +#define SPELL_REGROWTH 66067 +#define SPELL_REJUVENATION 66065 +#define SPELL_TRANQUILITY 66086 +#define SPELL_BARKSKIN 65860 //1 min cd +#define SPELL_THORNS 66068 +#define SPELL_NATURE_GRASP 66071 //1 min cd, self buff + +struct MANGOS_DLL_DECL mob_toc_druidAI : public boss_faction_championsAI +{ + mob_toc_druidAI(Creature* pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();} + + void Init() + { + SetEquipmentSlots(false, 51799, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_NATURE_GRASP, diff); + + timedCast(SPELL_TRANQUILITY, diff); + + if(timedQuery(SPELL_BARKSKIN, diff)) + if(m_creature->GetHealthPercent() < 50.0f) + doCast(SPELL_BARKSKIN); + + if(timedQuery(SPELL_LIFEBLOOM, diff)) + switch(urand(0,4)) + { + case 0: + doCast(SPELL_LIFEBLOOM); + break; + case 1: + doCast(SPELL_NOURISH); + break; + case 2: + doCast(SPELL_REGROWTH); + break; + case 3: + doCast(SPELL_REJUVENATION); + break; + case 4: + if(Creature* target = SelectRandomFriendlyMissingBuff(SPELL_THORNS)) + doCast(SPELL_THORNS, target); + break; + } + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_HEALING_WAVE 66055 +#define SPELL_RIPTIDE 66053 +#define SPELL_SPIRIT_CLEANSE 66056 //friendly only +#define SPELL_HEROISM 65983 +#define SPELL_BLOODLUST 65980 +#define SPELL_HEX 66054 +#define SPELL_EARTH_SHIELD 66063 +#define SPELL_EARTH_SHOCK 65973 + +struct MANGOS_DLL_DECL mob_toc_shamanAI : public boss_faction_championsAI +{ + mob_toc_shamanAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();} + + void Init() + { + SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_HEROISM, diff); + + timedCast(SPELL_HEX, diff); + + if(timedQuery(SPELL_HEALING_WAVE, diff)) + { + switch(urand(0,5)) + { + case 0: case 1: + doCast(SPELL_HEALING_WAVE); + break; + case 2: + doCast(SPELL_RIPTIDE); + break; + case 3: + doCast(SPELL_EARTH_SHOCK); + break; + case 4: + doCast(SPELL_SPIRIT_CLEANSE); + break; + case 5: + if(Unit *target = SelectRandomFriendlyMissingBuff(SPELL_EARTH_SHIELD)) + doCast(target, SPELL_EARTH_SHIELD); + break; + } + } + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_HAND_OF_FREEDOM 68757 //25 sec cd +#define SPELL_BUBBLE 66010 //5 min cd +#define SPELL_CLEANSE 66116 +#define SPELL_FLASH_OF_LIGHT 66113 +#define SPELL_HOLY_LIGHT 66112 +#define SPELL_HOLY_SHOCK 66114 +#define SPELL_HAND_OF_PROTECTION 66009 +#define SPELL_HAMMER_OF_JUSTICE 66613 + +struct MANGOS_DLL_DECL mob_toc_paladinAI : public boss_faction_championsAI +{ + mob_toc_paladinAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();} + + void Init() + { + SetEquipmentSlots(false, 50771, 47079, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + //cast bubble at 20% hp + if(m_creature->GetHealthPercent() < 20.0f) + timedCast(SPELL_BUBBLE, diff); + + if(Unit *target = DoSelectLowestHpFriendly(40.0f)) + if(target->GetHealthPercent() < 15.0f) + timedCast(SPELL_HAND_OF_PROTECTION, diff); + + timedCast(SPELL_HOLY_SHOCK, diff); + + if(Unit *target = SelectRandomFriendlyMissingBuff(SPELL_HAND_OF_FREEDOM)) + timedCast(SPELL_HAND_OF_FREEDOM, diff, target); + + timedCast(SPELL_HAMMER_OF_JUSTICE, diff); + + if(timedQuery(SPELL_FLASH_OF_LIGHT, diff)) + { + switch(urand(0,4)) + { + case 0: case 1: + doCast(SPELL_FLASH_OF_LIGHT); + break; + case 2: case 3: + doCast(SPELL_HOLY_LIGHT); + break; + case 4: + doCast(SPELL_CLEANSE); + break; + } + } + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_RENEW 66177 +#define SPELL_SHIELD 66099 +#define SPELL_FLASH_HEAL 66104 +#define SPELL_DISPEL 65546 +#define SPELL_PSYCHIC_SCREAM 65543 +#define SPELL_MANA_BURN 66100 + +struct MANGOS_DLL_DECL mob_toc_priestAI : public boss_faction_championsAI +{ + mob_toc_priestAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();} + + void Init() + { + SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + if(EnemiesInRange(10.0f) > 2) + timedCast(SPELL_PSYCHIC_SCREAM, diff); + + if(timedQuery(SPELL_RENEW, diff)) + { + switch(urand(0,5)) + { + case 0: + doCast(SPELL_RENEW); + break; + case 1: + doCast(SPELL_SHIELD); + break; + case 2: case 3: + doCast(SPELL_FLASH_HEAL); + break; + case 4: + if(Unit *target = urand(0,1) ? m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0) : DoSelectLowestHpFriendly(40.0f)) + doCast(target, SPELL_DISPEL); + break; + case 5: + doCast(SPELL_MANA_BURN); + break; + } + } + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +/******************************************************************** + RANGED +********************************************************************/ + +#define SPELL_SILENCE 65542 +#define SPELL_VAMPIRIC_TOUCH 65490 +#define SPELL_SW_PAIN 65541 +#define SPELL_MIND_FLAY 65488 +#define SPELL_MIND_BLAST 65492 +#define SPELL_HORROR 65545 +#define SPELL_DISPERSION 65544 +#define SPELL_SHADOWFORM 16592 + +struct MANGOS_DLL_DECL mob_toc_shadow_priestAI : public boss_faction_championsAI +{ + mob_toc_shadow_priestAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();} + + void Init() + { + SetEquipmentSlots(false, 50040, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void Aggro(Unit *who) + { + boss_faction_championsAI::Aggro(who); + doCast(SPELL_SHADOWFORM); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + if(EnemiesInRange(10.0f) > 2) + timedCast(SPELL_PSYCHIC_SCREAM, diff); + + if(m_creature->GetHealthPercent() < 20.0f) + timedCast(SPELL_DISPERSION, diff); + + if(Unit *target = SelectEnemyCaster(false)) + timedCast(SPELL_SILENCE, diff, target); + + timedCast(SPELL_MIND_BLAST, diff); + + if(timedQuery(SPELL_MIND_FLAY, diff)) + { + switch(urand(0,4)) + { + case 0: case 1: + doCast(SPELL_MIND_FLAY); + break; + case 2: + doCast(SPELL_VAMPIRIC_TOUCH); + break; + case 3: + doCast(SPELL_SW_PAIN); + break; + case 4: + doCast(SPELL_DISPEL); + break; + } + } + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_HELLFIRE 65816 +#define SPELL_CORRUPTION 65810 +#define SPELL_Curse_of_Agony 65814 +#define SPELL_Curse_of_Exhaustion 65815 +#define SPELL_Fear 65809 //8s +#define SPELL_Searing_Pain 65819 +#define SPELL_Shadow_Bolt 65821 +#define SPELL_Unstable_Affliction 65812 +#define H_SPELL_Unstable_Affliction 68155 //15s + +struct MANGOS_DLL_DECL mob_toc_warlockAI : public boss_faction_championsAI +{ + mob_toc_warlockAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();} + + void Init() + { + SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_Fear, diff); + + if(EnemiesInRange(10.0f) > 2) + timedCast(SPELL_HELLFIRE, diff); + + timedCast(SPELL_Unstable_Affliction, diff); + + if(timedQuery(SPELL_Shadow_Bolt, diff)) + { + switch(urand(0,5)) + { + case 0: + doCast(SPELL_Searing_Pain); + break; + case 1: case 2: + doCast(SPELL_Shadow_Bolt); + break; + case 3: + doCast(SPELL_CORRUPTION); + break; + case 4: + doCast(SPELL_Curse_of_Agony); + break; + case 5: + doCast(SPELL_Curse_of_Exhaustion); + break; + } + } + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_Arcane_Barrage 65799 //3s +#define SPELL_Arcane_Blast 65791 +#define SPELL_Arcane_Explosion 65800 +#define SPELL_Blink 65793 //15s +#define SPELL_Counterspell 65790 //24s +#define SPELL_Frost_Nova 65792 //25s +#define SPELL_Frostbolt 65807 +#define SPELL_Ice_Block 65802 //5min +#define SPELL_Polymorph 65801 //15s + +struct MANGOS_DLL_DECL mob_toc_mageAI : public boss_faction_championsAI { - SAY_GARROSH_PVP_A_SLAY_1 = -1649048, - SAY_GARROSH_PVP_A_SLAY_2 = -1649049, - SAY_GARROSH_PVP_A_SLAY_3 = -1649050, - SAY_GARROSH_PVP_A_SLAY_4 = -1649051, + mob_toc_mageAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();} - SAY_VARIAN_PVP_H_SLAY_1 = -1649052, - SAY_VARIAN_PVP_H_SLAY_2 = -1649053, - SAY_VARIAN_PVP_H_SLAY_3 = -1649054, - SAY_VARIAN_PVP_H_SLAY_4 = -1649055, + void Init() + { + SetEquipmentSlots(false, 47524, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + if(Unit *target = SelectEnemyCaster(false)) + timedCast(SPELL_Counterspell, diff, target); + + if(m_creature->GetHealthPercent() < 50.0f + && EnemiesInRange(10.0f)>3 ) + { + timedCast(SPELL_Frost_Nova, diff); + timedCast(SPELL_Blink, diff); + } + + if(m_creature->GetHealthPercent() < 20.0f) + timedCast(SPELL_Ice_Block, diff); + + timedCast(SPELL_Polymorph, diff); + + if(timedQuery(SPELL_Arcane_Barrage, diff)) + { + switch(urand(0,2)) + { + case 0: + doCast(SPELL_Arcane_Barrage); + break; + case 1: + doCast(SPELL_Arcane_Blast); + break; + case 2: + doCast(SPELL_Frostbolt); + break; + } + } + boss_faction_championsAI::UpdateAI(diff); + } }; + + +#define SPELL_AIMED_SHOT 65883 +#define SPELL_Deterrence 65871 //90s +#define SPELL_Disengage 65869 //30s +#define SPELL_EXPLOSIVE_SHOT 65866 +#define SPELL_Frost_Trap 65880 //30s +#define SPELL_SHOOT 65868 //1.7s +#define SPELL_Steady_Shot 65867 //3s +#define SPELL_WING_CLIP 66207 //6s +#define SPELL_Wyvern_Sting 65877 //60s + +struct MANGOS_DLL_DECL mob_toc_hunterAI : public boss_faction_championsAI +{ + mob_toc_hunterAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();} + + void Init() + { + SetEquipmentSlots(false, 47156, EQUIP_NO_CHANGE, 48711); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + if(EnemiesInRange(10.0f) > 3) + timedCast(SPELL_Disengage, diff); + + if(m_creature->GetHealthPercent() < 20.0f) + timedCast(SPELL_Deterrence, diff); + + timedCast(SPELL_Wyvern_Sting, diff); + + timedCast(SPELL_Frost_Trap, diff ); + + if(m_creature->GetDistance2d(m_creature->getVictim()) < 5.0f) + timedCast(SPELL_WING_CLIP, diff); + + if(timedQuery(SPELL_SHOOT, diff)) + { + switch(urand(0,3)) + { + case 0: case 1: + doCast(SPELL_SHOOT); + break; + case 2: + doCast(SPELL_EXPLOSIVE_SHOT); + break; + case 3: + doCast(SPELL_AIMED_SHOT); + break; + } + } + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_Cyclone 65859 //6s +#define SPELL_Entangling_Roots 65857 //10s +#define SPELL_Faerie_Fire 65863 +#define SPELL_Force_of_Nature 65861 //180s +#define SPELL_Insect_Swarm 65855 +#define SPELL_Moonfire 65856 //5s +#define SPELL_Starfire 65854 +#define SPELL_Wrath 65862 + +struct MANGOS_DLL_DECL mob_toc_boomkinAI : public boss_faction_championsAI +{ + mob_toc_boomkinAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();} + + void Init() + { + SetEquipmentSlots(false, 50966, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + if(m_creature->GetHealthPercent() < 50.0f) + timedCast(SPELL_BARKSKIN, diff); + + timedCast(SPELL_Cyclone, diff); + + timedCast(SPELL_Entangling_Roots, diff); + + timedCast(SPELL_Faerie_Fire, diff); + + if(timedQuery(SPELL_Moonfire, diff)) + { + switch(urand(0,6)) + { + case 0: case 1: + doCast(SPELL_Moonfire); + break; + case 2: + doCast(SPELL_Insect_Swarm); + break; + case 3: + doCast(SPELL_Starfire); + break; + case 4: case 5: case 6: + doCast(SPELL_Wrath); + break; + } + } + boss_faction_championsAI::UpdateAI(diff); + } +}; + +/******************************************************************** + MELEE +********************************************************************/ + +#define SPELL_BLADESTORM 65947 +#define SPELL_INTIMIDATING_SHOUT 65930 +#define SPELL_MORTAL_STRIKE 65926 +#define SPELL_CHARGE 68764 +#define SPELL_DISARM 65935 +#define SPELL_OVERPOWER 65924 +#define SPELL_SUNDER_ARMOR 65936 +#define SPELL_SHATTERING_THROW 65940 +#define SPELL_RETALIATION 65932 + +struct MANGOS_DLL_DECL mob_toc_warriorAI : public boss_faction_championsAI +{ + mob_toc_warriorAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();} + + void Init() + { + SetEquipmentSlots(false, 47427, 46964, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_BLADESTORM, diff); + + timedCast(SPELL_INTIMIDATING_SHOUT, diff); + + timedCast(SPELL_MORTAL_STRIKE, diff); + + timedCast(SPELL_SUNDER_ARMOR, diff); + + timedCast(SPELL_CHARGE, diff); + + timedCast(SPELL_RETALIATION, diff); + + timedCast(SPELL_OVERPOWER, diff); + + timedCast(SPELL_SHATTERING_THROW, diff); + + timedCast(SPELL_DISARM, diff); + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_Chains_of_Ice 66020 //8sec +#define SPELL_Death_Coil 66019 //5sec +#define SPELL_Death_Grip 66017 //35sec +#define SPELL_Frost_Strike 66047 //6sec +#define SPELL_Icebound_Fortitude 66023 //1min +#define SPELL_Icy_Touch 66021 //8sec +#define SPELL_Strangulate 66018 //2min + +struct MANGOS_DLL_DECL mob_toc_dkAI : public boss_faction_championsAI +{ + mob_toc_dkAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();} + + void Init() + { + SetEquipmentSlots(false, 47518, 51021, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + if(m_creature->GetHealthPercent() < 50.0f) + timedCast(SPELL_Icebound_Fortitude, diff); + + timedCast(SPELL_Chains_of_Ice, diff); + + timedCast(SPELL_Death_Coil, diff); + + if(Unit *target = SelectEnemyCaster(false)) + timedCast(SPELL_Strangulate, diff, target); + + timedCast(SPELL_Frost_Strike, diff); + + timedCast(SPELL_Icy_Touch, diff); + + if(m_creature->IsInRange(m_creature->getVictim(), 10.0f, 30.0f, false)) + timedCast(SPELL_Death_Grip, diff); + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_FAN_OF_KNIVES 65955 //2sec +#define SPELL_BLIND 65960 //2min +#define SPELL_CLOAK 65961 //90sec +#define SPELL_Blade_Flurry 65956 //2min +#define SPELL_SHADOWSTEP 66178 //30sec +#define SPELL_HEMORRHAGE 65954 +#define SPELL_EVISCERATE 65957 + +struct MANGOS_DLL_DECL mob_toc_rogueAI : public boss_faction_championsAI +{ + mob_toc_rogueAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();} + + void Init() + { + SetEquipmentSlots(false, 47422, 49982, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + if(EnemiesInRange(15.0f) > 2) + timedCast(SPELL_FAN_OF_KNIVES, diff); + + timedCast(SPELL_HEMORRHAGE, diff); + + timedCast(SPELL_EVISCERATE, diff); + + if(m_creature->IsInRange(m_creature->getVictim(), 10.0f, 40.0f)) + timedCast(SPELL_SHADOWSTEP, diff); + + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) + if(m_creature->IsInRange(target, 0.0f, 15.0f, false)) + timedCast(SPELL_BLIND, diff, target); + + if(m_creature->GetHealthPercent() < 50.0f) + timedCast(SPELL_CLOAK, diff); + + timedCast(SPELL_Blade_Flurry, diff); + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_EARTH_SHOCK 65973 +#define SPELL_LAVA_LASH 65974 +#define SPELL_STORMSTRIKE 65970 + +struct MANGOS_DLL_DECL mob_toc_enh_shamanAI : public boss_faction_championsAI +{ + mob_toc_enh_shamanAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();} + + void Init() + { + SetEquipmentSlots(false, 51803, 48013, EQUIP_NO_CHANGE); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_HEROISM, diff); + + timedCast(SPELL_EARTH_SHOCK, diff); + + timedCast(SPELL_STORMSTRIKE, diff); + + timedCast(SPELL_LAVA_LASH, diff); + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_Avenging_Wrath 66011 //3min cd +#define SPELL_Crusader_Strike 66003 //6sec cd +#define SPELL_Divine_Shield 66010 //5min cd +#define SPELL_Divine_Storm 66006 //10sec cd +#define SPELL_Hammer_of_Justice 66007 //40sec cd +#define SPELL_Hand_of_Protection 66009 //5min cd +#define SPELL_Judgement_of_Command 66005 //8sec cd +#define SPELL_REPENTANCE 66008 //60sec cd +#define SPELL_Seal_of_Command 66004 //no cd + +struct MANGOS_DLL_DECL mob_toc_retro_paladinAI : public boss_faction_championsAI +{ + mob_toc_retro_paladinAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();} + + void Init() + { + SetEquipmentSlots(false, 47519, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + } + + void Aggro(Unit *who) + { + boss_faction_championsAI::Aggro(who); + doCast(SPELL_Seal_of_Command); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_REPENTANCE, diff); + + timedCast(SPELL_Crusader_Strike, diff); + + timedCast(SPELL_Avenging_Wrath, diff); + + if(m_creature->GetHealthPercent() < 20.0f) + timedCast(SPELL_Divine_Shield, diff); + + timedCast(SPELL_Divine_Storm, diff); + + timedCast(SPELL_Judgement_of_Command, diff); + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_WPET0 67518 +#define SPELL_WPET1 67519 + +struct MANGOS_DLL_DECL mob_toc_pet_warlockAI : public boss_faction_championsAI +{ + mob_toc_pet_warlockAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();} + + void Aggro(Unit *who) + { + boss_faction_championsAI::Aggro(who); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_WPET0, diff); + + timedCast(SPELL_WPET1, diff); + + boss_faction_championsAI::UpdateAI(diff); + } +}; + +#define SPELL_HPET0 67793 +struct MANGOS_DLL_DECL mob_toc_pet_hunterAI : public boss_faction_championsAI +{ + mob_toc_pet_hunterAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();} + + void Aggro(Unit *who) + { + boss_faction_championsAI::Aggro(who); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + + timedCast(SPELL_HPET0, diff); + + boss_faction_championsAI::UpdateAI(diff); + } +}; + + +/*========================================================*/ +CreatureAI* GetAI_mob_toc_druid(Creature *pCreature) { + return new mob_toc_druidAI (pCreature); +} +CreatureAI* GetAI_mob_toc_shaman(Creature *pCreature) { + return new mob_toc_shamanAI (pCreature); +} +CreatureAI* GetAI_mob_toc_paladin(Creature *pCreature) { + return new mob_toc_paladinAI (pCreature); +} +CreatureAI* GetAI_mob_toc_priest(Creature *pCreature) { + return new mob_toc_priestAI (pCreature); +} +CreatureAI* GetAI_mob_toc_shadow_priest(Creature *pCreature) { + return new mob_toc_shadow_priestAI (pCreature); +} +CreatureAI* GetAI_mob_toc_warlock(Creature *pCreature) { + return new mob_toc_warlockAI (pCreature); +} +CreatureAI* GetAI_mob_toc_mage(Creature *pCreature) { + return new mob_toc_mageAI (pCreature); +} +CreatureAI* GetAI_mob_toc_hunter(Creature *pCreature) { + return new mob_toc_hunterAI (pCreature); +} +CreatureAI* GetAI_mob_toc_boomkin(Creature *pCreature) { + return new mob_toc_boomkinAI (pCreature); +} +CreatureAI* GetAI_mob_toc_warrior(Creature *pCreature) { + return new mob_toc_warriorAI (pCreature); +} +CreatureAI* GetAI_mob_toc_dk(Creature *pCreature) { + return new mob_toc_dkAI (pCreature); +} +CreatureAI* GetAI_mob_toc_rogue(Creature *pCreature) { + return new mob_toc_rogueAI (pCreature); +} +CreatureAI* GetAI_mob_toc_enh_shaman(Creature *pCreature) { + return new mob_toc_enh_shamanAI (pCreature); +} +CreatureAI* GetAI_mob_toc_retro_paladin(Creature *pCreature) { + return new mob_toc_retro_paladinAI (pCreature); +} +CreatureAI* GetAI_mob_toc_pet_warlock(Creature *pCreature) { + return new mob_toc_pet_warlockAI (pCreature); +} +CreatureAI* GetAI_mob_toc_pet_hunter(Creature *pCreature) { + return new mob_toc_pet_hunterAI (pCreature); +} + +void AddSC_boss_faction_champions() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "mob_toc_druid"; + newscript->GetAI = &GetAI_mob_toc_druid; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_shaman"; + newscript->GetAI = &GetAI_mob_toc_shaman; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_paladin"; + newscript->GetAI = &GetAI_mob_toc_paladin; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_priest"; + newscript->GetAI = &GetAI_mob_toc_priest; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_shadow_priest"; + newscript->GetAI = &GetAI_mob_toc_shadow_priest; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_mage"; + newscript->GetAI = &GetAI_mob_toc_mage; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_warlock"; + newscript->GetAI = &GetAI_mob_toc_warlock; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_hunter"; + newscript->GetAI = &GetAI_mob_toc_hunter; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_boomkin"; + newscript->GetAI = &GetAI_mob_toc_boomkin; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_warrior"; + newscript->GetAI = &GetAI_mob_toc_warrior; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_dk"; + newscript->GetAI = &GetAI_mob_toc_dk; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_rogue"; + newscript->GetAI = &GetAI_mob_toc_rogue; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_enh_shaman"; + newscript->GetAI = &GetAI_mob_toc_enh_shaman; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_retro_paladin"; + newscript->GetAI = &GetAI_mob_toc_retro_paladin; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_pet_warlock"; + newscript->GetAI = &GetAI_mob_toc_pet_warlock; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toc_pet_hunter"; + newscript->GetAI = &GetAI_mob_toc_pet_hunter; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp index fc50b8c26..3e0d26216 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -13,60 +13,112 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +// Jaraxxus - Magic aura (from start?) not fully offlike implemented. +// Legion flame visual effect not imlemented /* ScriptData SDName: trial_of_the_crusader -SD%Complete: 0 -SDComment: +SD%Complete: 80% +SDComment: by /dev/rsa SDCategory: Crusader Coliseum EndScriptData */ #include "precompiled.h" #include "trial_of_the_crusader.h" +enum Equipment +{ + EQUIP_MAIN = 47266, + EQUIP_OFFHAND = 46996, + EQUIP_RANGED = 47267, + EQUIP_DONE = EQUIP_NO_CHANGE, +}; -/*###### -## boss_jaraxxus -######*/ +enum Summons +{ + NPC_LEGION_FLAME = 34784, + NPC_INFERNAL_VOLCANO = 34813, + NPC_FEL_INFERNAL = 34815, + NPC_NETHER_PORTAL = 34825, + NPC_MISTRESS = 34826, +}; -enum +enum BossSpells { - SAY_AGGRO = -1649040, - SAY_SLAY_1 = -1649041, - SAY_SLAY_2 = -1649042, - SAY_DEATH = -1649043, - SAY_BERSERK = -1649044, - SAY_INCINERATE = -1649045, - SAY_MISTRESS = -1649046, - SAY_INFERNO = -1649047, +SPELL_NETHER_POWER = 67108, +SPELL_INFERNAL = 66258, +SPELL_INFERNAL_ERUPTION = 66255, +SPELL_FEL_FIREBALL = 66532, +SPELL_FEL_LIGHTING = 66528, +SPELL_INCINERATE_FLESH = 66237, +SPELL_BURNING_INFERNO = 66242, +SPELL_NETHER_PORTAL = 66264, +SPELL_LEGION_FLAME_0 = 66199, +SPELL_LEGION_FLAME_1 = 66197, +SPELL_SHIVAN_SLASH = 67098, +SPELL_SPINNING_STRIKE = 66316, +SPELL_FEL_INFERNO = 67047, +SPELL_FEL_STREAK = 66494, +SPELL_BERSERK = 26662, }; -struct MANGOS_DLL_DECL boss_jaraxxusAI : public ScriptedAI +/*###### +## boss_jaraxxus +######*/ + +struct MANGOS_DLL_DECL boss_jaraxxusAI : public BSWScriptedAI { - boss_jaraxxusAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_jaraxxusAI(Creature* pCreature) : BSWScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } ScriptedInstance* m_pInstance; + uint8 stage; + uint8 substage; + uint8 m_portalsCount; + uint8 m_volcanoCount; - void Reset() {} + void Reset() { + if(!m_pInstance) return; + m_pInstance->SetData(TYPE_JARAXXUS, NOT_STARTED); +// SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED); + m_portalsCount = 1; + if (currentDifficulty == RAID_DIFFICULTY_10MAN_HEROIC || currentDifficulty == RAID_DIFFICULTY_25MAN_HEROIC) + { + m_portalsCount = 2; + m_volcanoCount = 4; + } else { + m_portalsCount = 1; + m_volcanoCount = 4; + } + DoScriptText(-1713517,m_creature); + m_creature->SetRespawnDelay(DAY); + } void JustReachedHome() { - if (m_pInstance) - m_pInstance->SetData(TYPE_JARAXXUS, NOT_STARTED); + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_JARAXXUS, FAIL); + m_creature->ForcedDespawn(); } void JustDied(Unit* pKiller) { - if (m_pInstance) + if (!m_pInstance) return; + DoScriptText(-1713525,m_creature); m_pInstance->SetData(TYPE_JARAXXUS, DONE); + m_pInstance->SetData(TYPE_EVENT,2000); + m_pInstance->SetData(TYPE_STAGE,0); } void Aggro(Unit* pWho) { + if (!m_pInstance) return; m_creature->SetInCombatWithZone(); + m_pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS); + DoScriptText(-1713514,m_creature); + doCast(SPELL_NETHER_POWER); } void UpdateAI(const uint32 uiDiff) @@ -74,6 +126,37 @@ struct MANGOS_DLL_DECL boss_jaraxxusAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + timedCast(SPELL_FEL_FIREBALL, uiDiff); + + timedCast(SPELL_FEL_LIGHTING, uiDiff); + + if (timedQuery(SPELL_INCINERATE_FLESH, uiDiff)) { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) + { + DoScriptText(-1713522,m_creature,pTarget); + doCast(SPELL_INCINERATE_FLESH,pTarget); + } + } + + if (timedQuery(SPELL_LEGION_FLAME_1, uiDiff)) { + DoScriptText(-1713518,m_creature); + doCast(SPELL_LEGION_FLAME_1); + }; + + if (timedQuery(SPELL_INFERNAL_ERUPTION, uiDiff) + && m_volcanoCount > 0) { + DoScriptText(-1713520,m_creature); + if (doCast(NPC_INFERNAL_VOLCANO) == CAST_OK) --m_volcanoCount; + }; + + if (timedQuery(SPELL_NETHER_PORTAL, uiDiff) + && m_portalsCount > 0 + && m_creature->GetHealthPercent() <= 90.0f) + { + DoScriptText(-1713519,m_creature); + if (doCast(NPC_NETHER_PORTAL) == CAST_OK) --m_portalsCount; + }; + DoMeleeAttackIfReady(); } }; @@ -83,6 +166,320 @@ CreatureAI* GetAI_boss_jaraxxus(Creature* pCreature) return new boss_jaraxxusAI(pCreature); } +struct MANGOS_DLL_DECL mob_legion_flameAI : public BSWScriptedAI +{ + mob_legion_flameAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_uiRangeCheck_Timer; + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(DAY); + + if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ) { + m_creature->GetMotionMaster()->MoveChase(pTarget); + m_creature->SetSpeedRate(MOVE_RUN, 0.5); + } + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) return; + } + + void JustDied(Unit* Killer) + { + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiRangeCheck_Timer < uiDiff) + { + if (m_pInstance) + { + if (m_creature->IsWithinDist(m_creature->getVictim(), 4.0f, false)) + { + DoCast(m_creature,SPELL_LEGION_FLAME_0); + } + } + m_uiRangeCheck_Timer = 1000; + if (m_creature->getVictim()) { + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->SetSpeedRate(MOVE_RUN, 0.5); + } + } + else m_uiRangeCheck_Timer -= uiDiff; + + } +}; + +CreatureAI* GetAI_mob_legion_flame(Creature* pCreature) +{ + return new mob_legion_flameAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_infernal_volcanoAI : public BSWScriptedAI +{ + mob_infernal_volcanoAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint8 m_Count; + uint32 m_Timer; + + void Reset() + { + m_Timer = 15000; + m_creature->SetRespawnDelay(DAY); + if (currentDifficulty != RAID_DIFFICULTY_10MAN_HEROIC && currentDifficulty != RAID_DIFFICULTY_25MAN_HEROIC) + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_Count = 3; + } else + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_Count = 6; + } + } + + void AttackStart(Unit *who) + { + return; + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) return; + } + + void JustDied(Unit* Killer) + { + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + } + + void UpdateAI(const uint32 diff) + { + if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (timedQuery(SPELL_INFERNAL_ERUPTION,diff) && m_Count > 0) { + doCast(SPELL_INFERNAL_ERUPTION); + DoScriptText(-1713524,m_creature); + --m_Count; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + } +}; + +CreatureAI* GetAI_mob_infernal_volcano(Creature* pCreature) +{ + return new mob_infernal_volcanoAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_fel_infernalAI : public BSWScriptedAI +{ + mob_fel_infernalAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(DAY); + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) return; + } + + void JustDied(Unit* Killer) + { + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_FEL_INFERNO, uiDiff); + + timedCast(SPELL_FEL_STREAK, uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_fel_infernal(Creature* pCreature) +{ + return new mob_fel_infernalAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_nether_portalAI : public BSWScriptedAI +{ + mob_nether_portalAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_Timer; + uint8 m_Count; + + void Reset() + { + m_Timer = 10000; + m_creature->SetRespawnDelay(DAY); + if (currentDifficulty != RAID_DIFFICULTY_10MAN_HEROIC && currentDifficulty != RAID_DIFFICULTY_25MAN_HEROIC) + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_Count = 1; + } else + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_Count = 2; + } + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) return; + } + + void AttackStart(Unit *who) + { + return; + } + + void JustDied(Unit* Killer) + { + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + } + + void UpdateAI(const uint32 diff) + { + if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_Timer < diff && m_Count > 0) { + DoCast(m_creature,SPELL_NETHER_PORTAL,false); + DoScriptText(-1713521,m_creature); + --m_Count; + m_Timer = 60000; + } else m_Timer -= diff; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + } +}; + +CreatureAI* GetAI_mob_nether_portal(Creature* pCreature) +{ + return new mob_nether_portalAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_mistress_of_painAI : public BSWScriptedAI +{ + mob_mistress_of_painAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(DAY); + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) return; + } + + void JustDied(Unit* Killer) + { + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + DoScriptText(-1713523,m_creature, who); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) return; + if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_SHIVAN_SLASH, uiDiff); + + timedCast(SPELL_SPINNING_STRIKE, uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_mistress_of_pain(Creature* pCreature) +{ + return new mob_mistress_of_painAI(pCreature); +} + void AddSC_boss_jaraxxus() { Script* newscript; @@ -91,4 +488,29 @@ void AddSC_boss_jaraxxus() newscript->Name = "boss_jaraxxus"; newscript->GetAI = &GetAI_boss_jaraxxus; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_legion_flame"; + newscript->GetAI = &GetAI_mob_legion_flame; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_infernal_volcano"; + newscript->GetAI = &GetAI_mob_infernal_volcano; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_fel_infernal"; + newscript->GetAI = &GetAI_mob_fel_infernal; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_nether_portal"; + newscript->GetAI = &GetAI_mob_nether_portal; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_mistress_of_pain"; + newscript->GetAI = &GetAI_mob_mistress_of_pain; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp index 561aaa48a..8d8456654 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -13,42 +13,113 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +// Gormok - Firebomb not implemented, timers need correct +// Snakes - Underground phase not worked, timers need correct +// Icehowl - Trample&Crash event not implemented, timers need correct /* ScriptData -SDName: -SD%Complete: 0 -SDComment: +SDName: northrend_beasts +SD%Complete: 90% +SDComment: by /dev/rsa SDCategory: EndScriptData */ +// not implemented: +// snobolds link +// snakes underground cast (not support in core) + #include "precompiled.h" #include "trial_of_the_crusader.h" -/*###### -## boss_gormok -######*/ +enum Equipment +{ + EQUIP_MAIN = 50760, + EQUIP_OFFHAND = 48040, + EQUIP_RANGED = 47267, + EQUIP_DONE = EQUIP_NO_CHANGE, +}; + +enum Summons +{ + NPC_SNOBOLD_VASSAL = 34800, + NPC_SLIME_POOL = 35176, + NPC_FIRE_BOMB = 34854, +}; + +enum BossSpells +{ +SPELL_IMPALE = 66331, +SPELL_STAGGERING_STOMP = 67648, +SPELL_RISING_ANGER = 66636, +SUMMON_SNOBOLD = NPC_SNOBOLD_VASSAL, +SPELL_ACID_SPIT = 66880, +SPELL_PARALYTIC_SPRAY = 66901, +SPELL_ACID_SPEW = 66819, +SPELL_PARALYTIC_BITE = 66824, +SPELL_SWEEP_0 = 66794, +SPELL_SLIME_POOL = 66883, +SPELL_FIRE_SPIT = 66796, +SPELL_MOLTEN_SPEW = 66821, +SPELL_BURNING_BITE = 66879, +SPELL_BURNING_SPRAY = 66902, +SPELL_SWEEP_1 = 67646, +SPELL_FEROCIOUS_BUTT = 66770, +SPELL_MASSIVE_CRASH = 66683, +SPELL_WHIRL = 67345, +SPELL_ARCTIC_BREATH = 66689, +SPELL_TRAMPLE = 66734, +SPELL_ADRENALINE = 68667, +SPELL_SNOBOLLED = 66406, +SPELL_BATTER = 66408, +SPELL_FIRE_BOMB = 66313, +SPELL_FIRE_BOMB_1 = 66317, +SPELL_FIRE_BOMB_DOT = 66318, +SPELL_HEAD_CRACK = 66407, +SPELL_SUBMERGE_0 = 53421, +SPELL_ENRAGE = 68335, +SPELL_FROTHING_RAGE = 66759, +SPELL_STAGGERED_DAZE = 66758, +SPELL_SLIME_POOL_1 = 66881, +SPELL_SLIME_POOL_2 = 66882, +SPELL_SLIME_POOL_VISUAL = 63084, +}; -struct MANGOS_DLL_DECL boss_gormokAI : public ScriptedAI +struct MANGOS_DLL_DECL boss_gormokAI : public BSWScriptedAI { - boss_gormokAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_gormokAI(Creature* pCreature) : BSWScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } ScriptedInstance* m_pInstance; + uint8 SnoboldsCount; - void Reset() {} + void Reset() { + + if(!m_pInstance) return; + SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED); + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetInCombatWithZone(); + SnoboldsCount = 4; + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_DONE); + } void JustReachedHome() { - if (m_pInstance) - m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED); + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL); + m_creature->ForcedDespawn(); } void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_IN_PROGRESS); } void UpdateAI(const uint32 uiDiff) @@ -56,6 +127,16 @@ struct MANGOS_DLL_DECL boss_gormokAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + timedCast(SPELL_IMPALE, uiDiff); + + timedCast(SPELL_STAGGERING_STOMP, uiDiff); + + if (timedQuery(SUMMON_SNOBOLD, uiDiff) && SnoboldsCount > 0 ) { + doCast(SUMMON_SNOBOLD); + DoScriptText(-1713601,m_creature); + --SnoboldsCount; + }; + DoMeleeAttackIfReady(); } }; @@ -65,38 +146,175 @@ CreatureAI* GetAI_boss_gormok(Creature* pCreature) return new boss_gormokAI(pCreature); } -/*###### -## boss_acidmaw -######*/ +struct MANGOS_DLL_DECL mob_snobold_vassalAI : public BSWScriptedAI +{ + mob_snobold_vassalAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + Unit* pBoss; + Unit* defaultTarget; + + void Reset() + { + pBoss = NULL; + defaultTarget = NULL; + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(DAY); + pBoss = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_GORMOK)); + if (pBoss) doCast(SPELL_RISING_ANGER,pBoss); + } + + void Aggro(Unit *who) + { + if (!m_pInstance) return; + defaultTarget = who; + doCast(SPELL_SNOBOLLED, defaultTarget); + } + + void JustReachedHome() + { + if (!m_pInstance) return; + m_creature->ForcedDespawn(); + } + + void JustDied(Unit* pKiller) + { + if (defaultTarget && defaultTarget->isAlive()) doRemove(SPELL_SNOBOLLED, defaultTarget); +// if (pBoss && pBoss->isAlive()) doRemove(SPELL_RISING_ANGER,pBoss); +// This string - not offlike, in off this buff not removed! especially for small servers. + } + + void UpdateAI(const uint32 uiDiff) + { + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_BATTER, uiDiff); + + if (timedCast(SPELL_FIRE_BOMB, uiDiff, m_creature->getVictim()) == CAST_OK) { + doCast(SPELL_FIRE_BOMB_1, m_creature->getVictim()); + doCast(SPELL_FIRE_BOMB_DOT, m_creature->getVictim()); + } + + timedCast(SPELL_HEAD_CRACK, uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_snobold_vassal(Creature* pCreature) +{ + return new mob_snobold_vassalAI(pCreature); +} -struct MANGOS_DLL_DECL boss_acidmawAI : public ScriptedAI +struct MANGOS_DLL_DECL boss_acidmawAI : public BSWScriptedAI { - boss_acidmawAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_acidmawAI(Creature* pCreature) : BSWScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } ScriptedInstance* m_pInstance; + uint8 stage; + bool enraged; - void Reset() {} + void Reset() + { + stage = 1; + enraged = false; + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(7*DAY); + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ACIDMAW_SUBMERGED); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) return; + if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DREADSCALE))) + if (!pSister->isAlive()) + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_DONE); + else m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_SPECIAL); + } void JustReachedHome() { - if (m_pInstance) - m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED); + if (!m_pInstance) return; + if (m_pInstance->GetData(TYPE_BEASTS) == IN_PROGRESS + && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != FAIL) + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL); + m_creature->ForcedDespawn(); } void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); } void UpdateAI(const uint32 uiDiff) { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + + if ((!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + && (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != ACIDMAW_SUBMERGED)) return; + switch (stage) + { + case 0: { + timedCast(SPELL_ACID_SPEW, uiDiff); + + timedCast(SPELL_PARALYTIC_BITE, uiDiff); + + timedCast(SPELL_ACID_SPIT, uiDiff); + + timedCast(SPELL_PARALYTIC_SPRAY, uiDiff); + + timedCast(SPELL_SWEEP_0, uiDiff); + + if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == ACIDMAW_SUBMERGED) + stage = 1; + + break;} + case 1: { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->InterruptNonMeleeSpells(true); + doCast(SPELL_SUBMERGE_0); + stage = 2; + DoScriptText(-1713557,m_creature); + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ACIDMAW_SUBMERGED); + break;} + case 2: { + if (timedQuery(SPELL_SLIME_POOL, uiDiff)) + doCast(NPC_SLIME_POOL); + + if ((timedQuery(SPELL_SUBMERGE_0, uiDiff) && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == ACIDMAW_SUBMERGED) + || m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == DREADSCALE_SUBMERGED) + stage = 3; + break;} + case 3: { + DoScriptText(-1713559,m_creature); + doRemove(SPELL_SUBMERGE_0); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + stage = 0; + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, DREADSCALE_SUBMERGED); + break;} + } + + if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL && !enraged) + { + DoScriptText(-1713559,m_creature); + doRemove(SPELL_SUBMERGE_0); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + doCast(SPELL_ENRAGE); + enraged = true; + stage = 0; + DoScriptText(-1713504,m_creature); + }; + DoMeleeAttackIfReady(); } }; @@ -106,38 +324,108 @@ CreatureAI* GetAI_boss_acidmaw(Creature* pCreature) return new boss_acidmawAI(pCreature); } -/*###### -## boss_dreadscale -######*/ - -struct MANGOS_DLL_DECL boss_dreadscaleAI : public ScriptedAI +struct MANGOS_DLL_DECL boss_dreadscaleAI : public BSWScriptedAI { - boss_dreadscaleAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_dreadscaleAI(Creature* pCreature) : BSWScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } ScriptedInstance* m_pInstance; + uint8 stage; + bool enraged; + + void Reset() + { + stage = 0; + enraged = false; + m_creature->SetInCombatWithZone(); + m_creature->SetRespawnDelay(7*DAY); + } - void Reset() {} + void JustDied(Unit* pKiller) + { + if (!m_pInstance) return; + if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ACIDMAW))) + if (!pSister->isAlive()) + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_DONE); + else m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_SPECIAL); + } void JustReachedHome() { - if (m_pInstance) - m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED); + if (!m_pInstance) return; + if (m_pInstance->GetData(TYPE_BEASTS) == IN_PROGRESS + && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != FAIL) + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL); + m_creature->ForcedDespawn(); } void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); } void UpdateAI(const uint32 uiDiff) { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + if ((!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + && (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != DREADSCALE_SUBMERGED)) return; + switch (stage) + { + case 0: { + timedCast(SPELL_BURNING_BITE, uiDiff); + + timedCast(SPELL_MOLTEN_SPEW, uiDiff); + + timedCast(SPELL_FIRE_SPIT, uiDiff); + + timedCast(SPELL_BURNING_SPRAY, uiDiff); + + timedCast(SPELL_SWEEP_0, uiDiff); + + if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == DREADSCALE_SUBMERGED) + stage = 1; + + break;} + case 1: { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->InterruptNonMeleeSpells(true); + doCast(SPELL_SUBMERGE_0); + stage = 2; + DoScriptText(-1713557,m_creature); + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, DREADSCALE_SUBMERGED); + break;} + case 2: { + + if (timedQuery(SPELL_SLIME_POOL, uiDiff)) + doCast(NPC_SLIME_POOL); + + if ((timedQuery(SPELL_SUBMERGE_0, uiDiff) && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == DREADSCALE_SUBMERGED) + || m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == ACIDMAW_SUBMERGED) + stage = 3; + break;} + case 3: { + DoScriptText(-1713559,m_creature); + doRemove(SPELL_SUBMERGE_0); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + stage = 0; + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ACIDMAW_SUBMERGED); + break;} + } + + if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL && !enraged) + { + DoScriptText(-1713559,m_creature); + doRemove(SPELL_SUBMERGE_0); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + doCast(SPELL_ENRAGE); + enraged = true; + stage = 0; + DoScriptText(-1713504,m_creature); + }; + DoMeleeAttackIfReady(); } }; @@ -147,36 +435,113 @@ CreatureAI* GetAI_boss_dreadscale(Creature* pCreature) return new boss_dreadscaleAI(pCreature); } -/*###### -## boss_icehowl -######*/ - -enum +struct MANGOS_DLL_DECL mob_slime_poolAI : public BSWScriptedAI { - EMOTE_MASSIVE_CRASH = -1649039, + mob_slime_poolAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance *m_pInstance; + float m_Size; + bool cloudcasted; + + void Reset() + { + if(!m_pInstance) return; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWithZone(); + m_creature->SetSpeedRate(MOVE_RUN, 0.05f); + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveRandom(); + doCast(SPELL_SLIME_POOL_2); + m_Size = m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X); + cloudcasted = false; + } + + void AttackStart(Unit *who) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!cloudcasted) { + doCast(SPELL_SLIME_POOL_VISUAL); + cloudcasted = true; + } + + if (timedQuery(SPELL_SLIME_POOL_2,uiDiff)) { + m_Size = m_Size*1.035; + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_Size); + } + // Override especially for clean core + if (m_Size >= 6.0f) m_creature->ForcedDespawn(); + } + }; -struct MANGOS_DLL_DECL boss_icehowlAI : public ScriptedAI +CreatureAI* GetAI_mob_slime_pool(Creature* pCreature) { - boss_icehowlAI(Creature* pCreature) : ScriptedAI(pCreature) + return new mob_slime_poolAI(pCreature); +} + +struct MANGOS_DLL_DECL boss_icehowlAI : public BSWScriptedAI +{ + boss_icehowlAI(Creature* pCreature) : BSWScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } ScriptedInstance* m_pInstance; + bool MovementStarted; + bool TrampleCasted; + uint8 stage; + float fPosX, fPosY, fPosZ; + Unit* pTarget; + + void Reset() { + if(!m_pInstance) return; + m_creature->SetRespawnDelay(7*DAY); + MovementStarted = false; + stage = 0; + } - void Reset() {} + void JustDied(Unit* pKiller) + { + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_DONE); + } + + void MovementInform(uint32 type, uint32 id) + { + if(!m_pInstance) return; + if(type != POINT_MOTION_TYPE) return; + if(id != 1 && MovementStarted) + { + m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ); + } + else { + m_creature->GetMotionMaster()->MovementExpired(); + MovementStarted = false; + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + } void JustReachedHome() { - if (m_pInstance) - m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED); + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL); + m_creature->ForcedDespawn(); } void Aggro(Unit* pWho) { m_creature->SetInCombatWithZone(); + m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_IN_PROGRESS); } void UpdateAI(const uint32 uiDiff) @@ -184,7 +549,95 @@ struct MANGOS_DLL_DECL boss_icehowlAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - DoMeleeAttackIfReady(); + switch (stage) + { + case 0: { + timedCast(SPELL_FEROCIOUS_BUTT, uiDiff); + + timedCast(SPELL_ARCTIC_BREATH, uiDiff); + + timedCast(SPELL_WHIRL, uiDiff); + + if (timedQuery(SPELL_MASSIVE_CRASH, uiDiff)) stage = 1; + + timedCast(SPELL_FROTHING_RAGE, uiDiff); + + DoMeleeAttackIfReady(); + + break; + } + case 1: { + if (doCast(SPELL_MASSIVE_CRASH) == CAST_OK) + stage = 2; + break; + } + case 2: { + if (pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) { + TrampleCasted = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + stage = 3; + resetTimer(SPELL_TRAMPLE); + DoScriptText(-1713506,m_creature,pTarget); + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveIdle(); + } + break; + } + case 3: { + if (timedQuery(SPELL_TRAMPLE,uiDiff)) { + if (pTarget && pTarget->isAlive() && (pTarget->IsWithinDistInMap(m_creature, 200.0f))) { + pTarget->GetPosition(fPosX, fPosY, fPosZ); + TrampleCasted = false; + MovementStarted = true; + m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ); + DoScriptText(-1713508,m_creature); + doCast(SPELL_ADRENALINE); + stage = 4; + } + else { + TrampleCasted = true; + stage = 5; + } + } + break; + } + case 4: { + if (MovementStarted) + { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + Unit* pPlayer = itr->getSource(); + if (!pPlayer) continue; + if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(m_creature, 5.0f)) { + doCast(SPELL_TRAMPLE, pPlayer); + TrampleCasted = true; + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + } + + } else stage = 5; + if (TrampleCasted) stage = 5; + break; + } + case 5: { + if (!TrampleCasted) { + doCast(SPELL_STAGGERED_DAZE); + DoScriptText(-1713507,m_creature); + } + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + SetCombatMovement(true); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + stage = 0; + break; + } + } + } }; @@ -217,4 +670,14 @@ void AddSC_northrend_beasts() newscript->GetAI = &GetAI_boss_icehowl; newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "mob_snobold_vassal"; + newscript->GetAI = &GetAI_mob_snobold_vassal; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_slime_pool"; + newscript->GetAI = &GetAI_mob_slime_pool; + newscript->RegisterSelf(); + } diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp index 7647d9d76..7e7befa98 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,48 +16,211 @@ /* ScriptData SDName: trial_of_the_crusader -SD%Complete: 0 -SDComment: +SD%Complete: 80% +SDComment: by /dev/rsa SDCategory: Crusader Coliseum EndScriptData */ +// Twin pact - heal part not worked now by undefined reason. Need override? +// timers need correct + #include "precompiled.h" #include "trial_of_the_crusader.h" -enum +enum Equipment { - SAY_AGGRO = -1649056, - SAY_BERSERK = -1649057, - SAY_COLORSWITCH = -1649058, - SAY_DEATH = -1649059, - SAY_SLAY_1 = -1649060, - SAY_SLAY_2 = -1649061, - SAY_TO_BLACK = -1649062, - SAY_TO_WHITE = -1649063, + EQUIP_MAIN_1 = 49303, + EQUIP_OFFHAND_1 = 47146, + EQUIP_RANGED_1 = 47267, + EQUIP_MAIN_2 = 45990, + EQUIP_OFFHAND_2 = 47470, + EQUIP_RANGED_2 = 47267, + EQUIP_DONE = EQUIP_NO_CHANGE, +}; + +enum Summons +{ + NPC_DARK_ESSENCE = 34567, + NPC_LIGHT_ESSENCE = 34568, + + NPC_UNLEASHED_DARK = 34628, + NPC_UNLEASHED_LIGHT = 34630, }; -/*###### -## boss_fjola -######*/ +enum BossSpells +{ + SPELL_TWIN_SPIKE_L = 66075, + SPELL_LIGHT_SURGE = 65766, + SPELL_SHIELD_LIGHT = 65858, + SPELL_TWIN_PACT_L = 65875, + SPELL_LIGHT_VORTEX = 66046, + SPELL_LIGHT_TOUCH = 67297, + SPELL_TWIN_SPIKE_H = 66069, + SPELL_DARK_SURGE = 65768, + SPELL_SHIELD_DARK = 65874, + SPELL_TWIN_PACT_H = 65876, + SPELL_DARK_VORTEX = 66058, + SPELL_DARK_TOUCH = 67282, + SPELL_TWIN_POWER = 65916, + SPELL_LIGHT_ESSENCE = 65686, + SPELL_DARK_ESSENCE = 65684, + SPELL_BERSERK = 64238, + SPELL_REMOVE_TOUCH = 68084, + SPELL_NONE = 0, +// + SPELL_UNLEASHED_DARK = 65808, + SPELL_UNLEASHED_LIGHT = 65795, +}; -struct MANGOS_DLL_DECL boss_fjolaAI : public ScriptedAI +struct MANGOS_DLL_DECL boss_fjolaAI : public BSWScriptedAI { - boss_fjolaAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_fjolaAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } ScriptedInstance* m_pInstance; + uint8 stage; - void Reset() {} + void Reset() { + if(!m_pInstance) return; + SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_OFFHAND_1, EQUIP_RANGED_1); + m_creature->SetRespawnDelay(7*DAY); + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + stage = 0; + } + + void JustReachedHome() + { + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_VALKIRIES, FAIL); + m_pInstance->SetData(DATA_HEALTH_FJOLA, m_creature->GetMaxHealth()); + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + m_creature->ForcedDespawn(); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) return; + DoScriptText(-1713547,m_creature); + if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DARKBANE))) + if (!pSister->isAlive()) + m_pInstance->SetData(TYPE_VALKIRIES, DONE); + else m_pInstance->SetData(TYPE_VALKIRIES, SPECIAL); + m_pInstance->SetData(DATA_HEALTH_FJOLA, 0); + } + + void KilledUnit(Unit* pVictim) + { + if (!m_pInstance) return; + DoScriptText(-1713544,m_creature,pVictim); + } void Aggro(Unit* pWho) { + if (!m_pInstance) return; m_creature->SetInCombatWithZone(); + m_pInstance->SetData(TYPE_VALKIRIES, IN_PROGRESS); + if (m_creature->isAlive()) m_creature->SummonCreature(NPC_LIGHT_ESSENCE, SpawnLoc[24].x, SpawnLoc[24].y, SpawnLoc[24].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + if (m_creature->isAlive()) m_creature->SummonCreature(NPC_LIGHT_ESSENCE, SpawnLoc[25].x, SpawnLoc[25].y, SpawnLoc[25].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + DoScriptText(-1713541,m_creature); + m_pInstance->SetData(DATA_HEALTH_FJOLA, m_creature->GetMaxHealth()); + doCast(SPELL_LIGHT_SURGE); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_pInstance) return; + if (!m_creature || !m_creature->isAlive()) + return; + + if(pDoneBy->GetGUID() == m_creature->GetGUID()) return; + + if(pDoneBy->GetTypeId() == TYPEID_PLAYER) + { + if(pDoneBy->HasAura(SPELL_LIGHT_ESSENCE)) + uiDamage /= 2; + else if(pDoneBy->HasAura(SPELL_DARK_ESSENCE)) + uiDamage += uiDamage/2; + } + + m_pInstance->SetData(DATA_HEALTH_FJOLA, m_creature->GetHealth() >= uiDamage ? m_creature->GetHealth() - uiDamage : 0); } void UpdateAI(const uint32 uiDiff) { + if (!m_pInstance) return; if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + if (m_creature->GetHealth() > m_pInstance->GetData(DATA_HEALTH_EYDIS) && + m_pInstance->GetData(DATA_HEALTH_EYDIS) != 0) + m_creature->SetHealth(m_pInstance->GetData(DATA_HEALTH_EYDIS)); + + switch (stage) + { + case 0: + timedCast(SPELL_TWIN_SPIKE_L, uiDiff); + + if (timedQuery(SPELL_LIGHT_TOUCH, uiDiff)) + { + if (Unit* pTarget = doSelectRandomPlayer(SPELL_LIGHT_ESSENCE, false, 50.0f)) + doCast(SPELL_LIGHT_TOUCH, pTarget); + doCast(NPC_UNLEASHED_LIGHT); + }; + if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_NONE ) + { + if (timedQuery(SPELL_LIGHT_VORTEX, uiDiff)) + { + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_LIGHT_VORTEX); + DoScriptText(-1713538,m_creature); + stage = 1; + break; + }; + if (timedQuery(SPELL_TWIN_PACT_L, uiDiff) + && m_creature->GetHealthPercent() <= 50.0f) + { + m_creature->InterruptNonMeleeSpells(true); + doCast(SPELL_SHIELD_LIGHT); + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_TWIN_PACT_L); + DoScriptText(-1713539,m_creature); + stage = 3; + }; + }; + if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_TWIN_PACT_H) + if (!m_creature->HasAura(SPELL_TWIN_POWER)) + doCast(SPELL_TWIN_POWER); + break; + case 1: + doCast(SPELL_LIGHT_VORTEX); + stage = 2; + break; + case 2: + if (!m_creature->HasAura(SPELL_LIGHT_VORTEX) + && timedQuery(SPELL_SHIELD_LIGHT, uiDiff)) + { + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + stage = 0; + }; + break; + case 3: + doCast(SPELL_TWIN_PACT_L); + stage = 4; + break; + case 4: + if (!m_creature->HasAura(SPELL_SHIELD_LIGHT) + && timedQuery(SPELL_SHIELD_LIGHT, uiDiff)) + { + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + stage = 0; + }; + default: + break; + } + + timedCast(SPELL_BERSERK, uiDiff); + DoMeleeAttackIfReady(); } }; @@ -67,19 +230,80 @@ CreatureAI* GetAI_boss_fjola(Creature* pCreature) return new boss_fjolaAI(pCreature); } -/*###### -## boss_eydis -######*/ - -struct MANGOS_DLL_DECL boss_eydisAI : public ScriptedAI +struct MANGOS_DLL_DECL boss_eydisAI : public BSWScriptedAI { - boss_eydisAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + boss_eydisAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint8 stage; + + void Reset() + { + if(!m_pInstance) return; + SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_OFFHAND_2, EQUIP_RANGED_2); + m_creature->SetRespawnDelay(7*DAY); + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + stage = 0; + } - void Reset() {} + void JustReachedHome() + { + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_VALKIRIES, FAIL); + m_pInstance->SetData(DATA_HEALTH_EYDIS, m_creature->GetMaxHealth()); + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + m_creature->ForcedDespawn(); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) return; + DoScriptText(-1713547,m_creature); + if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LIGHTBANE))) + if (!pSister->isAlive()) + m_pInstance->SetData(TYPE_VALKIRIES, DONE); + else m_pInstance->SetData(TYPE_VALKIRIES, SPECIAL); + m_pInstance->SetData(DATA_HEALTH_EYDIS, 0); + } + + void KilledUnit(Unit* pVictim) + { + DoScriptText(-1713543,m_creature,pVictim); + } void Aggro(Unit* pWho) { + if (!m_pInstance) return; m_creature->SetInCombatWithZone(); + m_pInstance->SetData(TYPE_VALKIRIES, IN_PROGRESS); + DoScriptText(-1713741,m_creature); + if (m_creature->isAlive()) m_creature->SummonCreature(NPC_DARK_ESSENCE, SpawnLoc[22].x, SpawnLoc[22].y, SpawnLoc[22].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + if (m_creature->isAlive()) m_creature->SummonCreature(NPC_DARK_ESSENCE, SpawnLoc[23].x, SpawnLoc[23].y, SpawnLoc[23].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + m_pInstance->SetData(DATA_HEALTH_EYDIS, m_creature->GetMaxHealth()); + doCast(SPELL_DARK_SURGE); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_pInstance) return; + if (!m_creature || !m_creature->isAlive()) + return; + + if(pDoneBy->GetGUID() == m_creature->GetGUID()) return; + + if(pDoneBy->GetTypeId() == TYPEID_PLAYER) + { + if(pDoneBy->HasAura(SPELL_DARK_ESSENCE)) + uiDamage /= 2; + else if(pDoneBy->HasAura(SPELL_LIGHT_ESSENCE)) + uiDamage += uiDamage/2; + } + + m_pInstance->SetData(DATA_HEALTH_EYDIS, m_creature->GetHealth() >= uiDamage ? m_creature->GetHealth() - uiDamage : 0); } void UpdateAI(const uint32 uiDiff) @@ -87,6 +311,74 @@ struct MANGOS_DLL_DECL boss_eydisAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + if (m_creature->GetHealth() > m_pInstance->GetData(DATA_HEALTH_FJOLA) && + m_pInstance->GetData(DATA_HEALTH_FJOLA) != 0) + m_creature->SetHealth(m_pInstance->GetData(DATA_HEALTH_FJOLA)); + + switch (stage) + { + case 0: + timedCast(SPELL_TWIN_SPIKE_H, uiDiff); + + if (timedQuery(SPELL_DARK_TOUCH, uiDiff)) + { + if (Unit* pTarget = doSelectRandomPlayer(SPELL_DARK_ESSENCE, false, 50.0f)) + doCast(SPELL_DARK_TOUCH, pTarget); + doCast(NPC_UNLEASHED_DARK); + }; + if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_NONE ) + { + if (timedQuery(SPELL_DARK_VORTEX, uiDiff)) + { + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_DARK_VORTEX); + DoScriptText(-1713540,m_creature); + stage = 1; + break; + }; + if (timedQuery(SPELL_TWIN_PACT_H, uiDiff) + && m_creature->GetHealthPercent() <= 50.0f) + { + m_creature->InterruptNonMeleeSpells(true); + doCast(SPELL_SHIELD_DARK); + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_TWIN_PACT_H); + DoScriptText(-1713539,m_creature); + stage = 3; + break; + }; + }; + if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_TWIN_PACT_L) + if (!m_creature->HasAura(SPELL_TWIN_POWER)) + doCast(SPELL_TWIN_POWER); + break; + case 1: + doCast(SPELL_DARK_VORTEX); + stage = 2; + break; + case 2: + if (!m_creature->HasAura(SPELL_DARK_VORTEX) + && timedQuery(SPELL_SHIELD_DARK, uiDiff)) + { + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + stage = 0; + }; + break; + case 3: + doCast(SPELL_TWIN_PACT_H); + stage = 4; + break; + case 4: + if (!m_creature->HasAura(SPELL_SHIELD_DARK) + && timedQuery(SPELL_SHIELD_DARK, uiDiff)) + { + m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE); + stage = 0; + }; + default: + break; + } + + timedCast(SPELL_BERSERK, uiDiff); + DoMeleeAttackIfReady(); } }; @@ -96,6 +388,250 @@ CreatureAI* GetAI_boss_eydis(Creature* pCreature) return new boss_eydisAI(pCreature); } +struct MANGOS_DLL_DECL mob_light_essenceAI : public ScriptedAI +{ + mob_light_essenceAI(Creature* pCreature) : ScriptedAI(pCreature) { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + ScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MoveRandom(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) m_creature->ForcedDespawn(); + if (m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS) { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + Unit* pPlayer = itr->getSource(); + if (!pPlayer) continue; + if (pPlayer->isAlive()) + pPlayer->RemoveAurasDueToSpell(SPELL_LIGHT_ESSENCE); + } + + m_creature->ForcedDespawn(); + } + return; + } +}; + +CreatureAI* GetAI_mob_light_essence(Creature* pCreature) +{ + return new mob_light_essenceAI(pCreature); +}; + +bool GossipHello_mob_light_essence(Player *player, Creature* pCreature) +{ + ScriptedInstance *pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + if(!pInstance) return true; + player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID()); + player->RemoveAurasDueToSpell(SPELL_DARK_ESSENCE); +// player->CastSpell(player,SPELL_REMOVE_TOUCH,false); // Not worked now + player->CastSpell(player,SPELL_LIGHT_ESSENCE,false); + player->RemoveAurasDueToSpell(SPELL_LIGHT_TOUCH); // Override for REMOVE_TOUCH + player->CLOSE_GOSSIP_MENU(); + return true; +}; + +struct MANGOS_DLL_DECL mob_dark_essenceAI : public ScriptedAI +{ + mob_dark_essenceAI(Creature* pCreature) : ScriptedAI(pCreature) { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + ScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MoveRandom(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) m_creature->ForcedDespawn(); + if (m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS) { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + Unit* pPlayer = itr->getSource(); + if (!pPlayer) continue; + if (pPlayer->isAlive()) + pPlayer->RemoveAurasDueToSpell(SPELL_DARK_ESSENCE); + } + m_creature->ForcedDespawn(); + } + return; + } +}; + +CreatureAI* GetAI_mob_dark_essence(Creature* pCreature) +{ + return new mob_dark_essenceAI(pCreature); +}; + +bool GossipHello_mob_dark_essence(Player *player, Creature* pCreature) +{ + ScriptedInstance *pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + if(!pInstance) return true; + player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID()); + player->RemoveAurasDueToSpell(SPELL_LIGHT_ESSENCE); +// player->CastSpell(player,SPELL_REMOVE_TOUCH,false); // Not worked now + player->CastSpell(player,SPELL_DARK_ESSENCE,false); + player->RemoveAurasDueToSpell(SPELL_DARK_TOUCH); // Override for REMOVE_TOUCH + player->CLOSE_GOSSIP_MENU(); + return true; +} + +struct MANGOS_DLL_DECL mob_unleashed_darkAI : public ScriptedAI +{ + mob_unleashed_darkAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_uiRangeCheck_Timer; + Creature* pboss1; + Creature* pboss2; + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveRandom(); + m_uiRangeCheck_Timer = 1000; + pboss1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DARKBANE)); + pboss2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LIGHTBANE)); + } + + void AttackStart(Unit *pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_uiRangeCheck_Timer < uiDiff) + { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + Unit* pPlayer = itr->getSource(); + if (!pPlayer) continue; + if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(m_creature, 2.0f)) + { + m_creature->CastSpell(m_creature, SPELL_UNLEASHED_DARK, true); + m_creature->ForcedDespawn(); + } + + } + if (pboss1 && pboss1->isAlive() && pboss1->IsWithinDistInMap(m_creature, 2.0f)) + { + m_creature->CastSpell(m_creature, SPELL_UNLEASHED_DARK, true); + m_creature->ForcedDespawn(); + } + if (pboss2 && pboss2->isAlive() && pboss2->IsWithinDistInMap(m_creature, 2.0f)) + { + m_creature->CastSpell(m_creature, SPELL_UNLEASHED_DARK, true); + m_creature->ForcedDespawn(); + } + m_uiRangeCheck_Timer = 1000; + } + else m_uiRangeCheck_Timer -= uiDiff; + } + +}; + +CreatureAI* GetAI_mob_unleashed_dark(Creature *pCreature) +{ + return new mob_unleashed_darkAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_unleashed_lightAI : public ScriptedAI +{ + mob_unleashed_lightAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_uiRangeCheck_Timer; + Creature* pboss1; + Creature* pboss2; + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveRandom(); + m_uiRangeCheck_Timer = 1000; + pboss1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DARKBANE)); + pboss2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LIGHTBANE)); + } + + void AttackStart(Unit *pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_uiRangeCheck_Timer < uiDiff) + { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + Unit* pPlayer = itr->getSource(); + if (!pPlayer) continue; + if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(m_creature, 2.0f)) + { + m_creature->CastSpell(m_creature, SPELL_UNLEASHED_LIGHT, true); + m_creature->ForcedDespawn(); + } + } + if (pboss1 && pboss1->isAlive() && pboss1->IsWithinDistInMap(m_creature, 2.0f)) + { + m_creature->CastSpell(m_creature, SPELL_UNLEASHED_LIGHT, true); + m_creature->ForcedDespawn(); + } + if (pboss2 && pboss2->isAlive() && pboss2->IsWithinDistInMap(m_creature, 2.0f)) + { + m_creature->CastSpell(m_creature, SPELL_UNLEASHED_LIGHT, true); + m_creature->ForcedDespawn(); + } + m_uiRangeCheck_Timer = 1000; + } + else m_uiRangeCheck_Timer -= uiDiff; + } + +}; + +CreatureAI* GetAI_mob_unleashed_light(Creature *pCreature) +{ + return new mob_unleashed_lightAI(pCreature); +} + void AddSC_twin_valkyr() { Script* newscript; @@ -107,6 +643,29 @@ void AddSC_twin_valkyr() newscript = new Script; newscript->Name = "boss_eydis"; - newscript->GetAI = &GetAI_boss_fjola; + newscript->GetAI = &GetAI_boss_eydis; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_unleashed_light"; + newscript->GetAI = &GetAI_mob_unleashed_light; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_unleashed_dark"; + newscript->GetAI = &GetAI_mob_unleashed_dark; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_light_essence"; + newscript->GetAI = &GetAI_mob_light_essence; + newscript->pGossipHello = &GossipHello_mob_light_essence; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_essence"; + newscript->GetAI = &GetAI_mob_dark_essence; + newscript->pGossipHello = &GossipHello_mob_dark_essence; + newscript->RegisterSelf(); + } diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp index 21c424fe3..ea3183665 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,170 +16,591 @@ /* ScriptData SDName: instance_trial_of_the_crusader -SD%Complete: 100 -SDComment: -SDCategory: Crusader Coliseum +SD%Complete: 80% +SDComment: by /dev/rsa +SDCategory: Trial of the Crusader EndScriptData */ #include "precompiled.h" #include "trial_of_the_crusader.h" -/* Trial Of The Crusader encounters: -0 - Northrend Beasts -1 - Jaraxxus -2 - Faction Champions -3 - Twin Valkyr -4 - Anubarak -*/ - struct MANGOS_DLL_DECL instance_trial_of_the_crusader : public ScriptedInstance { - instance_trial_of_the_crusader(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + instance_trial_of_the_crusader(Map* pMap) : ScriptedInstance(pMap) { + Difficulty = pMap->GetDifficulty(); + Initialize(); + } + + uint32 m_auiEncounter[MAX_ENCOUNTERS+1]; + uint32 m_auiEventTimer; + uint32 m_auiEventNPCId; + uint32 m_auiNorthrendBeasts; + uint8 Difficulty; + std::string m_strInstData; + bool needsave; + + uint32 m_uiDataDamageFjola; + uint32 m_uiDataDamageEydis; + uint32 m_uiValkyrsCasting; + + uint32 m_auiCrusadersCount; + + uint64 m_uiBarrentGUID; + uint64 m_uiTirionGUID; + uint64 m_uiFizzlebangGUID; + uint64 m_uiGarroshGUID; + uint64 m_uiRinnGUID; + uint64 m_uiLich0GUID; + uint64 m_uiLich1GUID; + + uint64 m_uiGormokGUID; + uint64 m_uiAcidmawGUID; + uint64 m_uiDreadscaleGUID; + uint64 m_uiIcehowlGUID; + uint64 m_uiJaraxxusGUID; + uint64 m_uiDarkbaneGUID; + uint64 m_uiLightbaneGUID; + uint64 m_uiAnubarakGUID; + + uint64 m_uiCrusader11Guid; + uint64 m_uiCrusader12Guid; + uint64 m_uiCrusader13Guid; + uint64 m_uiCrusader14Guid; + uint64 m_uiCrusader15Guid; + uint64 m_uiCrusader16Guid; + uint64 m_uiCrusader17Guid; + uint64 m_uiCrusader18Guid; + uint64 m_uiCrusader19Guid; + uint64 m_uiCrusader1aGuid; + uint64 m_uiCrusader1bGuid; + uint64 m_uiCrusader1cGuid; + uint64 m_uiCrusader1dGuid; + uint64 m_uiCrusader1eGuid; + + uint64 m_uiCrusader21Guid; + uint64 m_uiCrusader22Guid; + uint64 m_uiCrusader23Guid; + uint64 m_uiCrusader24Guid; + uint64 m_uiCrusader25Guid; + uint64 m_uiCrusader26Guid; + uint64 m_uiCrusader27Guid; + uint64 m_uiCrusader28Guid; + uint64 m_uiCrusader29Guid; + uint64 m_uiCrusader2aGuid; + uint64 m_uiCrusader2bGuid; + uint64 m_uiCrusader2cGuid; + uint64 m_uiCrusader2dGuid; + uint64 m_uiCrusader2eGuid; + + uint64 m_uiCrusader01Guid; + uint64 m_uiCrusader02Guid; - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; + uint64 m_uiCrusadersCacheGUID; + uint64 m_uiFloorGUID; + + uint64 m_uiTC10h25GUID; + uint64 m_uiTC10h45GUID; + uint64 m_uiTC10h50GUID; + uint64 m_uiTC10h99GUID; + + uint64 m_uiTC25h25GUID; + uint64 m_uiTC25h45GUID; + uint64 m_uiTC25h50GUID; + uint64 m_uiTC25h99GUID; + + uint64 m_uiTributeChest1GUID; + uint64 m_uiTributeChest2GUID; + uint64 m_uiTributeChest3GUID; + uint64 m_uiTributeChest4GUID; + + uint64 m_uiMainGateDoorGUID; + + uint64 m_uiWestPortcullisGUID; + uint64 m_uiNorthPortcullisGUID; + uint64 m_uiSouthPortcullisGUID; - uint32 m_uiGormokGUID; - uint32 m_uiAcidmawGUID; - uint32 m_uiDreadscaleGUID; - uint32 m_uiIcehowlGUID; - uint32 m_uiJaraxxusGUID; - uint32 m_uiFjolaGUID; - uint32 m_uiEydisGUID; - uint32 m_uiAnubarakGUID; void Initialize() { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + m_auiEncounter[i] = NOT_STARTED; + + m_auiEncounter[0] = 0; + m_auiEncounter[7] = 50; + m_auiEncounter[8] = 0; + + m_uiTributeChest1GUID = 0; + m_uiTributeChest2GUID = 0; + m_uiTributeChest3GUID = 0; + m_uiTributeChest4GUID = 0; + m_uiDataDamageFjola = 0; + m_uiDataDamageEydis = 0; + m_uiLich0GUID = 0; + m_uiLich1GUID = 0; + + m_auiNorthrendBeasts = NOT_STARTED; + + m_auiEventTimer = 1000; - m_uiGormokGUID = 0; - m_uiAcidmawGUID = 0; - m_uiDreadscaleGUID = 0; - m_uiIcehowlGUID = 0; - m_uiJaraxxusGUID = 0; - m_uiFjolaGUID = 0; - m_uiEydisGUID = 0; - m_uiAnubarakGUID = 0; + m_auiCrusadersCount = 6; + needsave = false; } bool IsEncounterInProgress() const { - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + for(uint8 i = 1; i < MAX_ENCOUNTERS-2 ; ++i) if (m_auiEncounter[i] == IN_PROGRESS) return true; return false; } - void OnCreatureCreate(Creature* pCreature) + void OnPlayerEnter(Player *m_player) { + if (Difficulty == RAID_DIFFICULTY_10MAN_HEROIC || Difficulty == RAID_DIFFICULTY_25MAN_HEROIC) + { + m_player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,1); + m_player->SendUpdateWorldState(UPDATE_STATE_UI_COUNT, GetData(TYPE_COUNTER)); + } + } + + bool IsRaidWiped() + { + Map::PlayerList const &players = instance->GetPlayers(); + + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + { + if(Player* pPlayer = i->getSource()) + { + if(pPlayer->isAlive()) + return false; + } + } + return true; + } + + void OpenDoor(uint64 guid) + { + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + } + + void CloseDoor(uint64 guid) + { + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_READY); + } + + void OnCreatureCreate(Creature* pCreature) + { switch(pCreature->GetEntry()) { - case 34796: m_uiGormokGUID = pCreature->GetGUID(); break; - case 35144: m_uiAcidmawGUID = pCreature->GetGUID(); break; - case 34799: m_uiDreadscaleGUID = pCreature->GetGUID(); break; - case 34797: m_uiIcehowlGUID = pCreature->GetGUID(); break; - case 34780: m_uiJaraxxusGUID = pCreature->GetGUID(); break; - case 34497: m_uiFjolaGUID = pCreature->GetGUID(); break; - case 34496: m_uiEydisGUID = pCreature->GetGUID(); break; - case 34564: m_uiAnubarakGUID = pCreature->GetGUID(); break; + case NPC_BARRENT: m_uiBarrentGUID = pCreature->GetGUID(); break; + case NPC_TIRION: m_uiTirionGUID = pCreature->GetGUID(); break; + case NPC_FIZZLEBANG: m_uiFizzlebangGUID = pCreature->GetGUID(); break; + case NPC_GARROSH: m_uiGarroshGUID = pCreature->GetGUID(); break; + case NPC_RINN: m_uiRinnGUID = pCreature->GetGUID(); break; + case NPC_LICH_KING_0: m_uiLich0GUID = pCreature->GetGUID(); break; + case NPC_LICH_KING_1: m_uiLich1GUID = pCreature->GetGUID(); break; + + case NPC_GORMOK: m_uiGormokGUID = pCreature->GetGUID(); break; + case NPC_ACIDMAW: m_uiAcidmawGUID = pCreature->GetGUID(); break; + case NPC_DREADSCALE: m_uiDreadscaleGUID = pCreature->GetGUID(); break; + case NPC_ICEHOWL: m_uiIcehowlGUID = pCreature->GetGUID(); break; + case NPC_JARAXXUS: m_uiJaraxxusGUID = pCreature->GetGUID(); break; + case NPC_DARKBANE: m_uiDarkbaneGUID = pCreature->GetGUID(); break; + case NPC_LIGHTBANE: m_uiLightbaneGUID = pCreature->GetGUID(); break; + case NPC_ANUBARAK: m_uiAnubarakGUID = pCreature->GetGUID(); break; + + case NPC_CRUSADER_1_1: m_uiCrusader11Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_2: m_uiCrusader12Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_3: m_uiCrusader13Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_4: m_uiCrusader14Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_5: m_uiCrusader15Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_6: m_uiCrusader16Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_7: m_uiCrusader17Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_8: m_uiCrusader18Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_9: m_uiCrusader19Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_10: m_uiCrusader1aGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_11: m_uiCrusader1bGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_12: m_uiCrusader1cGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_13: m_uiCrusader1dGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_1_14: m_uiCrusader1eGuid = pCreature->GetGUID(); break; + + case NPC_CRUSADER_2_1: m_uiCrusader21Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_2: m_uiCrusader22Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_3: m_uiCrusader23Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_4: m_uiCrusader24Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_5: m_uiCrusader25Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_6: m_uiCrusader26Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_7: m_uiCrusader27Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_8: m_uiCrusader28Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_9: m_uiCrusader29Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_10: m_uiCrusader2aGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_11: m_uiCrusader2bGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_12: m_uiCrusader2cGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_13: m_uiCrusader2dGuid = pCreature->GetGUID(); break; + case NPC_CRUSADER_2_14: m_uiCrusader2eGuid = pCreature->GetGUID(); break; + + case NPC_CRUSADER_0_1: m_uiCrusader01Guid = pCreature->GetGUID(); break; + case NPC_CRUSADER_0_2: m_uiCrusader02Guid = pCreature->GetGUID(); break; } } - void SetData(uint32 uiType, uint32 uiData) + void OnObjectCreate(GameObject *pGo) { - debug_log("SD2: Instance Trial Of The Crusader: SetData received for type %u with data %u",uiType,uiData); + switch(pGo->GetEntry()) + { + case GO_CRUSADERS_CACHE_10: + if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL) + m_uiCrusadersCacheGUID = pGo->GetGUID(); + break; + case GO_CRUSADERS_CACHE_25: + if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) + m_uiCrusadersCacheGUID = pGo->GetGUID(); + break; + case GO_CRUSADERS_CACHE_10_H: + if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC) + m_uiCrusadersCacheGUID = pGo->GetGUID(); + break; + case GO_CRUSADERS_CACHE_25_H: + if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC) + m_uiCrusadersCacheGUID = pGo->GetGUID(); + break; + case GO_ARGENT_COLISEUM_FLOOR: + m_uiFloorGUID = pGo->GetGUID(); + break; + case GO_MAIN_GATE_DOOR: m_uiMainGateDoorGUID = pGo->GetGUID(); break; + case GO_SOUTH_PORTCULLIS: m_uiSouthPortcullisGUID = pGo->GetGUID(); break; + case GO_WEST_PORTCULLIS: m_uiWestPortcullisGUID = pGo->GetGUID(); break; + case GO_NORTH_PORTCULLIS: m_uiNorthPortcullisGUID = pGo->GetGUID(); break; + + case GO_TRIBUTE_CHEST_10H_25: m_uiTC10h25GUID = pGo->GetGUID(); break; + case GO_TRIBUTE_CHEST_10H_45: m_uiTC10h45GUID = pGo->GetGUID(); break; + case GO_TRIBUTE_CHEST_10H_50: m_uiTC10h50GUID = pGo->GetGUID(); break; + case GO_TRIBUTE_CHEST_10H_99: m_uiTC10h99GUID = pGo->GetGUID(); break; + + case GO_TRIBUTE_CHEST_25H_25: m_uiTC25h25GUID = pGo->GetGUID(); break; + case GO_TRIBUTE_CHEST_25H_45: m_uiTC25h45GUID = pGo->GetGUID(); break; + case GO_TRIBUTE_CHEST_25H_50: m_uiTC25h50GUID = pGo->GetGUID(); break; + case GO_TRIBUTE_CHEST_25H_99: m_uiTC25h99GUID = pGo->GetGUID(); break; + } + } + + void SetData(uint32 uiType, uint32 uiData) + { switch(uiType) { - case TYPE_NORTHREND_BEASTS: - m_auiEncounter[0] = uiData; - break; - case TYPE_JARAXXUS: - m_auiEncounter[1] = uiData; - break; - case TYPE_FACTION_CHAMPIONS: - m_auiEncounter[2] = uiData; - break; - case TYPE_TWIN_VALKYR: - m_auiEncounter[3] = uiData; - break; - case TYPE_ANUBARAK: - m_auiEncounter[4] = uiData; - break; - default: - error_log("SD2: Instance Trial of The Crusader: ERROR SetData = %u for type %u does not exist/not implemented.",uiType,uiData); - break; + case TYPE_STAGE: m_auiEncounter[0] = uiData; break; + case TYPE_BEASTS: m_auiEncounter[1] = uiData; break; + case TYPE_JARAXXUS: m_auiEncounter[2] = uiData; break; + case TYPE_CRUSADERS: if (uiData == FAIL && (m_auiEncounter[3] == FAIL || m_auiEncounter[3] == NOT_STARTED)) + m_auiEncounter[3] = NOT_STARTED; + else m_auiEncounter[3] = uiData; + if (uiData == DONE) { + if (GameObject* pChest = instance->GetGameObject(m_uiCrusadersCacheGUID)) + if (pChest && !pChest->isSpawned()) + pChest->SetRespawnTime(7*DAY); + }; + break; + case TYPE_CRUSADERS_COUNT: if (uiData == 0) --m_auiCrusadersCount; + else m_auiCrusadersCount = uiData; + break; + case TYPE_VALKIRIES: if (m_auiEncounter[4] == SPECIAL && uiData == SPECIAL) uiData = DONE; + m_auiEncounter[4] = uiData; break; + case TYPE_LICH_KING: m_auiEncounter[5] = uiData; break; + case TYPE_ANUBARAK: m_auiEncounter[6] = uiData; + if (uiData == DONE) { + if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC){ + if ( m_auiEncounter[7] >= 25) m_uiTributeChest1GUID = m_uiTC10h25GUID; + if ( m_auiEncounter[7] >= 45) m_uiTributeChest2GUID = m_uiTC10h45GUID; + if ( m_auiEncounter[7] >= 49) m_uiTributeChest3GUID = m_uiTC10h50GUID; + m_uiTributeChest4GUID = m_uiTC10h99GUID; + } + if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC){ + if ( m_auiEncounter[7] >= 25) m_uiTributeChest1GUID = m_uiTC25h25GUID; + if ( m_auiEncounter[7] >= 45) m_uiTributeChest2GUID = m_uiTC25h45GUID; + if ( m_auiEncounter[7] >= 49) m_uiTributeChest3GUID = m_uiTC25h50GUID; + m_uiTributeChest4GUID = m_uiTC25h99GUID; + } + // Attention! It is (may be) not off-like, but spawning all Tribute Chests is real + // reward for clearing TOC instance + if (m_uiTributeChest1GUID) + if (GameObject* pChest1 = instance->GetGameObject(m_uiTributeChest1GUID)) + if (pChest1 && !pChest1->isSpawned()) pChest1->SetRespawnTime(7*DAY); + if (m_uiTributeChest2GUID) + if (GameObject* pChest2 = instance->GetGameObject(m_uiTributeChest2GUID)) + if (pChest2 && !pChest2->isSpawned()) pChest2->SetRespawnTime(7*DAY); + if (m_uiTributeChest3GUID) + if (GameObject* pChest3 = instance->GetGameObject(m_uiTributeChest3GUID)) + if (pChest3 && !pChest3->isSpawned()) pChest3->SetRespawnTime(7*DAY); + if (m_uiTributeChest4GUID) + if (GameObject* pChest4 = instance->GetGameObject(m_uiTributeChest4GUID)) + if (pChest4 && !pChest4->isSpawned()) pChest4->SetRespawnTime(7*DAY); + }; + break; + case TYPE_COUNTER: m_auiEncounter[7] = uiData; uiData = DONE; break; + case TYPE_EVENT: m_auiEncounter[8] = uiData; uiData = NOT_STARTED; break; + case TYPE_EVENT_TIMER: m_auiEventTimer = uiData; uiData = NOT_STARTED; break; + case TYPE_NORTHREND_BEASTS: m_auiNorthrendBeasts = uiData; break; + case DATA_HEALTH_FJOLA: m_uiDataDamageFjola = uiData; uiData = NOT_STARTED; break; + case DATA_HEALTH_EYDIS: m_uiDataDamageEydis = uiData; uiData = NOT_STARTED; break; + case DATA_CASTING_VALKYRS: m_uiValkyrsCasting = uiData; uiData = NOT_STARTED; break; + } + + if (IsEncounterInProgress()) { + CloseDoor(GetData64(GO_WEST_PORTCULLIS)); + CloseDoor(GetData64(GO_NORTH_PORTCULLIS)); +// CloseDoor(GetData64(GO_SOUTH_PORTCULLIS)); + } + else { + OpenDoor(GetData64(GO_WEST_PORTCULLIS)); + OpenDoor(GetData64(GO_NORTH_PORTCULLIS)); +// OpenDoor(GetData64(GO_SOUTH_PORTCULLIS)); + }; + + if (uiData == FAIL && uiType != TYPE_STAGE + && uiType != TYPE_EVENT + && uiType != TYPE_COUNTER + && uiType != TYPE_EVENT_TIMER) + { if (IsRaidWiped()) { --m_auiEncounter[7]; + needsave = true; + } + uiData = NOT_STARTED; } - if (uiData == DONE) + if ((uiData == DONE && uiType != TYPE_STAGE + && uiType != TYPE_EVENT + && uiType != TYPE_EVENT_TIMER) + || needsave == true) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " - << m_auiEncounter[3] << " " << m_auiEncounter[4]; - strInstData = saveStream.str(); + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + saveStream << m_auiEncounter[i] << " "; + + m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; + needsave = false; } } - uint32 GetData(uint32 uiType) + uint64 GetData64(uint32 uiData) { - switch(uiType) + switch(uiData) { - case TYPE_NORTHREND_BEASTS: return m_auiEncounter[0]; - case TYPE_JARAXXUS: return m_auiEncounter[1]; - case TYPE_FACTION_CHAMPIONS: return m_auiEncounter[2]; - case TYPE_TWIN_VALKYR: return m_auiEncounter[3]; - case TYPE_ANUBARAK: return m_auiEncounter[4]; + case NPC_BARRENT: return m_uiBarrentGUID; + case NPC_TIRION: return m_uiTirionGUID; + case NPC_FIZZLEBANG: return m_uiFizzlebangGUID; + case NPC_GARROSH: return m_uiGarroshGUID; + case NPC_RINN: return m_uiRinnGUID; + case NPC_LICH_KING_0: return m_uiLich0GUID; + case NPC_LICH_KING_1: return m_uiLich1GUID; + + case NPC_GORMOK: return m_uiGormokGUID; + case NPC_ACIDMAW: return m_uiAcidmawGUID; + case NPC_DREADSCALE: return m_uiDreadscaleGUID; + case NPC_ICEHOWL: return m_uiIcehowlGUID; + case NPC_JARAXXUS: return m_uiJaraxxusGUID; + case NPC_DARKBANE: return m_uiDarkbaneGUID; + case NPC_LIGHTBANE: return m_uiLightbaneGUID; + case NPC_ANUBARAK: return m_uiAnubarakGUID; + + case NPC_CRUSADER_1_1: return m_uiCrusader11Guid; + case NPC_CRUSADER_1_2: return m_uiCrusader12Guid; + case NPC_CRUSADER_1_3: return m_uiCrusader13Guid; + case NPC_CRUSADER_1_4: return m_uiCrusader14Guid; + case NPC_CRUSADER_1_5: return m_uiCrusader15Guid; + case NPC_CRUSADER_1_6: return m_uiCrusader16Guid; + case NPC_CRUSADER_1_7: return m_uiCrusader17Guid; + case NPC_CRUSADER_1_8: return m_uiCrusader18Guid; + case NPC_CRUSADER_1_9: return m_uiCrusader19Guid; + case NPC_CRUSADER_1_10: return m_uiCrusader1aGuid; + case NPC_CRUSADER_1_11: return m_uiCrusader1bGuid; + case NPC_CRUSADER_1_12: return m_uiCrusader1cGuid; + case NPC_CRUSADER_1_13: return m_uiCrusader1dGuid; + case NPC_CRUSADER_1_14: return m_uiCrusader1eGuid; + + case NPC_CRUSADER_2_1: return m_uiCrusader21Guid; + case NPC_CRUSADER_2_2: return m_uiCrusader22Guid; + case NPC_CRUSADER_2_3: return m_uiCrusader23Guid; + case NPC_CRUSADER_2_4: return m_uiCrusader24Guid; + case NPC_CRUSADER_2_5: return m_uiCrusader25Guid; + case NPC_CRUSADER_2_6: return m_uiCrusader26Guid; + case NPC_CRUSADER_2_7: return m_uiCrusader27Guid; + case NPC_CRUSADER_2_8: return m_uiCrusader28Guid; + case NPC_CRUSADER_2_9: return m_uiCrusader29Guid; + case NPC_CRUSADER_2_10: return m_uiCrusader2aGuid; + case NPC_CRUSADER_2_11: return m_uiCrusader2bGuid; + case NPC_CRUSADER_2_12: return m_uiCrusader2cGuid; + case NPC_CRUSADER_2_13: return m_uiCrusader2dGuid; + case NPC_CRUSADER_2_14: return m_uiCrusader2eGuid; + + case NPC_CRUSADER_0_1: return m_uiCrusader01Guid; + case NPC_CRUSADER_0_2: return m_uiCrusader02Guid; + + case GO_ARGENT_COLISEUM_FLOOR: return m_uiFloorGUID; + case GO_MAIN_GATE_DOOR: return m_uiMainGateDoorGUID; + + case GO_SOUTH_PORTCULLIS: return m_uiSouthPortcullisGUID; + case GO_WEST_PORTCULLIS: return m_uiWestPortcullisGUID; + case GO_NORTH_PORTCULLIS: return m_uiNorthPortcullisGUID; + } return 0; } - uint64 GetData64(uint32 uiData) + uint32 GetData(uint32 uiType) { - switch(uiData) + switch(uiType) { - case DATA_GORMOK: return m_uiGormokGUID; - case DATA_ACIDMAW: return m_uiAcidmawGUID; - case DATA_DREADSCALE: return m_uiDreadscaleGUID; - case DATA_ICEHOWL: return m_uiIcehowlGUID; - case DATA_JARAXXUS: return m_uiJaraxxusGUID; - case DATA_FJOLA: return m_uiFjolaGUID; - case DATA_EYDIS: return m_uiEydisGUID; - case DATA_ANUBARAK: return m_uiAnubarakGUID; + case TYPE_STAGE: return m_auiEncounter[0]; + case TYPE_BEASTS: return m_auiEncounter[1]; + case TYPE_JARAXXUS: return m_auiEncounter[2]; + case TYPE_CRUSADERS: return m_auiEncounter[3]; + case TYPE_VALKIRIES: return m_auiEncounter[4]; + case TYPE_LICH_KING: return m_auiEncounter[5]; + case TYPE_ANUBARAK: return m_auiEncounter[6]; + case TYPE_COUNTER: return m_auiEncounter[7]; + case TYPE_EVENT: return m_auiEncounter[8]; + case TYPE_DIFFICULTY: return Difficulty; + case TYPE_NORTHREND_BEASTS: return m_auiNorthrendBeasts; + case TYPE_EVENT_TIMER: return m_auiEventTimer; + case TYPE_CRUSADERS_COUNT: return m_auiCrusadersCount; + case TYPE_EVENT_NPC: switch (m_auiEncounter[8]) + { + case 110: + case 140: + case 150: + case 200: + case 205: + case 210: + case 300: + case 305: + case 310: + case 400: + case 666: + case 1010: + case 1180: + case 2000: + case 2030: + case 3000: + case 3001: + case 3060: + case 3061: + case 3090: + case 3091: + case 3100: + case 3110: + case 4000: + case 4010: + case 4015: + case 4040: + case 4050: + case 5000: + case 5005: + case 5020: + case 6000: + case 6005: + case 6010: + m_auiEventNPCId = NPC_TIRION; + break; + + case 5010: + case 5030: + case 5040: + case 5050: + case 5060: + case 5070: + case 5080: + m_auiEventNPCId = NPC_LICH_KING_1; + break; + + case 130: + case 132: + case 2020: + case 3080: + case 3051: + case 3071: + case 4020: + m_auiEventNPCId = NPC_RINN; + break; + + case 120: + case 122: + case 2010: + case 3050: + case 3070: + case 3081: + case 4030: + m_auiEventNPCId = NPC_GARROSH; + break; + + case 1110: + case 1120: + case 1130: + case 1132: + case 1134: + case 1135: + case 1140: + case 1142: + case 1144: + case 1145: + case 1150: + case 1160: + m_auiEventNPCId = NPC_FIZZLEBANG; + break; + + default: + m_auiEventNPCId = NPC_TIRION; + break; + + }; + return m_auiEventNPCId; + + case DATA_HEALTH_FJOLA: return m_uiDataDamageFjola; + case DATA_HEALTH_EYDIS: return m_uiDataDamageEydis; + case DATA_CASTING_VALKYRS: return m_uiValkyrsCasting; } return 0; } const char* Save() { - return strInstData.c_str(); + return m_strInstData.c_str(); } - void Load(const char* chrIn) + void Load(const char* strIn) { - if (!chrIn) + if (!strIn) { OUT_LOAD_INST_DATA_FAIL; return; } - OUT_LOAD_INST_DATA(chrIn); + OUT_LOAD_INST_DATA(strIn); - std::istringstream loadStream(chrIn); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] - >> m_auiEncounter[4]; + std::istringstream loadStream(strIn); - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + { + loadStream >> m_auiEncounter[i]; + + if (m_auiEncounter[i] == IN_PROGRESS) m_auiEncounter[i] = NOT_STARTED; + } + m_auiEncounter[TYPE_EVENT] = 0; + m_auiEncounter[TYPE_STAGE] = 0; OUT_LOAD_INST_DATA_COMPLETE; + } }; @@ -190,8 +611,7 @@ InstanceData* GetInstanceData_instance_trial_of_the_crusader(Map* pMap) void AddSC_instance_trial_of_the_crusader() { - Script* newscript; - + Script *newscript; newscript = new Script; newscript->Name = "instance_trial_of_the_crusader"; newscript->GetInstanceData = &GetInstanceData_instance_trial_of_the_crusader; diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp index 45496c338..f542c534a 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,123 +15,1383 @@ */ /* ScriptData -SDName: trial_of_the_crusader -SD%Complete: 0 -SDComment: -SDCategory: Crusader Coliseum +SDName: Trial Of the crusader +SD%Complete: 60% +SDComment: event script by /dev/rsa +SDCategory: trial_of_the_crusader EndScriptData */ #include "precompiled.h" #include "trial_of_the_crusader.h" +struct _Messages +{ + AnnounserMessages msgnum; + uint32 id; + bool state; + uint32 encounter; +}; + +static _Messages _GossipMessage[]= +{ +{MSG_BEASTS,GOSSIP_ACTION_INFO_DEF+1,false,TYPE_BEASTS}, // +{MSG_JARAXXUS,GOSSIP_ACTION_INFO_DEF+2,false,TYPE_JARAXXUS}, // +{MSG_CRUSADERS,GOSSIP_ACTION_INFO_DEF+3,false,TYPE_CRUSADERS}, // +{MSG_VALKIRIES,GOSSIP_ACTION_INFO_DEF+4,false,TYPE_VALKIRIES}, // +{MSG_LICH_KING,GOSSIP_ACTION_INFO_DEF+5,false,TYPE_ANUBARAK}, // +{MSG_ANUBARAK,GOSSIP_ACTION_INFO_DEF+6,true,TYPE_ANUBARAK}, // +}; + enum { - SAY_TIRION_RAID_INTRO_LONG = -1649000, - SAY_RAID_TRIALS_INTRO = -1649001, - - // Northrend Beasts - SAY_TIRION_BEAST_1 = -1649002, - SAY_VARIAN_BEAST_1 = -1649003, - SAY_GARROSH_BEAST_1 = -1649004, - SAY_TIRION_BEAST_2 = -1649005, - SAY_TIRION_BEAST_3 = -1649006, - SAY_TIRION_BEAST_SLAY = -1649007, - SAY_TIRION_BEAST_WIPE = -1649008, - - // Jaraxxus Encounter - SAY_TIRION_JARAXXUS_INTRO_1 = -1649009, - SAY_WILFRED_JARAXXUS_INTRO_1 = -1649010, - SAY_WILFRED_JARAXXUS_INTRO_2 = -1649011, - SAY_WILFRED_JARAXXUS_INTRO_3 = -1649012, - SAY_JARAXXUS_JARAXXAS_INTRO_1 = -1649013, - SAY_WILFRED_DEATH = -1649014, - SAY_TIRION_JARAXXUS_INTRO_2 = -1649015, - SAY_TIRION_JARAXXUS_EXIT_1 = -1649016, - SAY_GARROSH_JARAXXUS_EXIT_1 = -1649017, - SAY_VARIAN_JARAXXUS_SLAY = -1649018, - SAY_TIRION_JARAXXUS_EXIT_2 = -1649019, - - // Faction-Champions - SAY_TIRION_PVP_INTRO_1 = -1649020, - SAY_GARROSH_PVP_A_INTRO_1 = -1649021, - SAY_VARIAN_PVP_H_INTRO_1 = -1649022, - SAY_TIRION_PVP_INTRO_2 = -1649023, - SAY_VARIAN_PVP_A_INTRO_2 = -1649024, - SAY_GARROSH_PVP_H_INTRO_2 = -1649025, - SAY_VARIAN_PVP_A_WIN = -1649026, - SAY_GARROSH_PVP_H_WIN = -1649027, - SAY_TIRION_PVP_WIN = -1649028, - - // Twin Valkyrs - SAY_TIRION_TWINS_INTRO = -1649029, - SAY_RAID_INTRO_SHORT = -1649030, - SAY_VARIAN_TWINS_A_WIN = -1649031, - SAY_GARROSH_TWINS_H_WIN = -1649032, - SAY_TIRION_TWINS_WIN = -1649033, - - // Anub'Arak Encounter - SAY_LKING_ANUB_INTRO_1 = -1649034, - SAY_TIRION_ABUN_INTRO_1 = -1649035, - SAY_LKING_ANUB_INTRO_2 = -1649036, - SAY_LKING_ANUB_INTRO_3 = -1649037, - SAY_ANUB_ANUB_INTRO_1 = -1649038, - - NPC_GORMOK = 34796, - NPC_JARAXXUS = 34780, - - GOSSIP_ITEM_START_EVENT1 = -3649000 + NUM_MESSAGES = 6, + SPELL_WILFRED_PORTAL = 68424, + SPELL_JARAXXUS_CHAINS = 67924, }; -/*###### -## npc_barrett_ramsey -######*/ -struct MANGOS_DLL_DECL npc_barrett_ramseyAI : public ScriptedAI +struct MANGOS_DLL_DECL npc_toc_announcerAI : public ScriptedAI { - npc_barrett_ramseyAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + npc_toc_announcerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } - ScriptedInstance* m_pInstance; + ScriptedInstance* pInstance; + uint32 DelayTimer; + uint32 substage; - void Reset() {} + void Reset() + { + if (!pInstance) return; + pInstance->SetData(TYPE_STAGE,0); + DelayTimer = 0; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if(Creature *pAlly = GetClosestCreatureWithEntry(m_creature, NPC_THRALL, 300.0f)) + pAlly->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if(Creature *pAlly = GetClosestCreatureWithEntry(m_creature, NPC_PROUDMOORE, 300.0f)) + pAlly->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetRespawnDelay(DAY); + } - void StartEvent(Player* pPlayer) + void AttackStart(Unit *who) { - // code starting the event here + //ignore all attackstart commands + return; + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance) return; + + if(DelayTimer < diff) { + switch (pInstance->GetData(TYPE_STAGE)) { + case 0: break; + case 1: { + if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == GORMOK_DONE) { + pInstance->SetData(TYPE_STAGE,2); + pInstance->SetData(TYPE_EVENT,200); + pInstance->SetData(TYPE_NORTHREND_BEASTS,SNAKES_IN_PROGRESS); + pInstance->SetData(TYPE_BEASTS,IN_PROGRESS); + }; + if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == FAIL) { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_EVENT,666); + pInstance->SetData(TYPE_BEASTS,NOT_STARTED); + }; + break; + }; + case 2: { + if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_DONE) { + pInstance->SetData(TYPE_STAGE,3); + pInstance->SetData(TYPE_EVENT,300); + pInstance->SetData(TYPE_NORTHREND_BEASTS,ICEHOWL_IN_PROGRESS); + pInstance->SetData(TYPE_BEASTS,IN_PROGRESS); + }; + if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == FAIL) { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_EVENT,666); + pInstance->SetData(TYPE_BEASTS,NOT_STARTED); + }; + break; + } + case 3: { + if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == ICEHOWL_DONE) { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_BEASTS,DONE); + pInstance->SetData(TYPE_EVENT,400); + pInstance->SetData(TYPE_NORTHREND_BEASTS,DONE); + } + if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == FAIL) { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_EVENT,666); + pInstance->SetData(TYPE_BEASTS,NOT_STARTED); + }; + break; + }; + + case 4: { + break; + }; + + case 5: { + break; + }; + + case 6: { + if (pInstance->GetData(TYPE_CRUSADERS_COUNT) == 0 + && pInstance->GetData(TYPE_CRUSADERS) == IN_PROGRESS) + { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_CRUSADERS,DONE); + pInstance->SetData(TYPE_EVENT,3100); + } + break; + }; + + case 7: { + if (pInstance->GetData(TYPE_VALKIRIES) == DONE) { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_EVENT,4020); + } + if (pInstance->GetData(TYPE_VALKIRIES) == FAIL) { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_EVENT,0); + } + break; + }; + case 8: { + break; + }; + case 9: { + if (pInstance->GetData(TYPE_ANUBARAK) == DONE) { + pInstance->SetData(TYPE_STAGE,10); + pInstance->SetData(TYPE_EVENT,6000); + } + if (pInstance->GetData(TYPE_ANUBARAK) == FAIL) { + pInstance->SetData(TYPE_STAGE,0); + pInstance->SetData(TYPE_EVENT,0); + } + break; + }; + case 10: { +// m_creature->ForcedDespawn(); + break; + }; + + } + } else DelayTimer -= diff; } }; -bool GossipHello_npc_barrett_ramsey(Player* pPlayer, Creature* pCreature) +CreatureAI* GetAI_npc_toc_announcer(Creature* pCreature) { - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START_EVENT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + return new npc_toc_announcerAI(pCreature); +} + +bool GossipHello_npc_toc_announcer(Player* pPlayer, Creature* pCreature) +{ + + ScriptedInstance* pInstance; + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + char const* _message; + uint8 i; + + if (!pInstance) return false; + + if( !pPlayer->getAttackers().empty() || + pInstance->IsEncounterInProgress() || + pInstance->GetData(TYPE_EVENT)) + return true; + + switch (LocaleConstant currentlocale = pPlayer->GetSession()->GetSessionDbcLocale()) + { + case LOCALE_enUS: + case LOCALE_koKR: + case LOCALE_frFR: + case LOCALE_deDE: + case LOCALE_zhCN: + case LOCALE_zhTW: + case LOCALE_esES: + case LOCALE_esMX: + _message = "We are ready!"; + break; + case LOCALE_ruRU: + _message = "Всегда готовы!"; + break; + default: + _message = "We are ready!"; + break; + }; + + for(i = 0; i < NUM_MESSAGES; i++) { + if (!_GossipMessage[i].state && (pInstance->GetData(_GossipMessage[i].encounter) != DONE )) { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _message, GOSSIP_SENDER_MAIN,_GossipMessage[i].id); + break; + } + if (_GossipMessage[i].state && pInstance->GetData(_GossipMessage[i].encounter) == DONE) { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _message, GOSSIP_SENDER_MAIN,_GossipMessage[i].id); + break; + } + }; + + pPlayer->SEND_GOSSIP_MENU(_GossipMessage[i].msgnum, pCreature->GetGUID()); + return true; } -bool GossipSelect_npc_barrett_ramsey(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +bool GossipSelect_npc_toc_announcer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { - if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + ScriptedInstance* pInstance; + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + if (!pInstance) return false; + +pPlayer->CLOSE_GOSSIP_MENU(); + +switch(uiAction) { + case GOSSIP_ACTION_INFO_DEF+1: { + if (pInstance->GetData(TYPE_BEASTS) != DONE) { + pInstance->SetData(TYPE_EVENT,110); + pInstance->SetData(TYPE_NORTHREND_BEASTS,NOT_STARTED); + pInstance->SetData(TYPE_BEASTS,IN_PROGRESS); + }; + break; + }; + + case GOSSIP_ACTION_INFO_DEF+2: { + if (pInstance->GetData(TYPE_JARAXXUS) != DONE) + pInstance->SetData(TYPE_EVENT,1010); + break; + }; + + case GOSSIP_ACTION_INFO_DEF+3: { + if (pInstance->GetData(TYPE_CRUSADERS) != DONE) { + if (pPlayer->GetTeam() == ALLIANCE) pInstance->SetData(TYPE_EVENT,3000); + else pInstance->SetData(TYPE_EVENT,3001); + }; + break; + }; + + case GOSSIP_ACTION_INFO_DEF+4: { + if (pInstance->GetData(TYPE_VALKIRIES) != DONE) + pInstance->SetData(TYPE_EVENT,4000); + break; + }; + + case GOSSIP_ACTION_INFO_DEF+5: { + if (pInstance->GetData(TYPE_LICH_KING) != DONE) return false; + if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARGENT_COLISEUM_FLOOR))) + { + pGoFloor->SetUInt32Value(GAMEOBJECT_DISPLAYID,9060); + pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN); + pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449); + } + pCreature->CastSpell(pCreature,69016,false); + + Creature* pTemp = pCreature->GetMap()->GetCreature(pInstance->GetData64(NPC_ANUBARAK)); + if (!pTemp || !pTemp->isAlive()) + pCreature->SummonCreature(NPC_ANUBARAK, SpawnLoc[19].x, SpawnLoc[19].y, SpawnLoc[19].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (pTemp) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[20].x, SpawnLoc[20].y, SpawnLoc[20].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + pInstance->SetData(TYPE_STAGE,9); + pInstance->SetData(TYPE_ANUBARAK,IN_PROGRESS); + if (pCreature->GetVisibility() == VISIBILITY_ON) + pCreature->SetVisibility(VISIBILITY_OFF); + break; + }; + + case GOSSIP_ACTION_INFO_DEF+6: { + pInstance->SetData(TYPE_STAGE,10); + break; + }; + + }; + +return true; +} + +struct MANGOS_DLL_DECL boss_lich_king_tocAI : public ScriptedAI +{ + boss_lich_king_tocAI(Creature *pCreature) : ScriptedAI(pCreature) { - pPlayer->CLOSE_GOSSIP_MENU(); - if (npc_barrett_ramseyAI* pBarrettAI = dynamic_cast(pCreature->AI())) - pBarrettAI->StartEvent(pPlayer); + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + WayPointList.clear(); + JustRespawned(); } - return true; + ScriptedInstance* pInstance; + uint32 UpdateTimer; + uint32 event_state_lich_king; + bool Event; + bool MovementStarted; + std::list WayPointList; + std::list::iterator WayPoint; + uint32 WalkTimer; + bool IsWalking; + Creature* pPortal; + + void Reset() + { + UpdateTimer = 0; + event_state_lich_king = 0; + Event = false; + MovementStarted = false; + m_creature->SetRespawnDelay(DAY); + pPortal = m_creature->SummonCreature(NPC_TRIGGER, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + pPortal->SetRespawnDelay(DAY); + pPortal->CastSpell(pPortal, 51807, false); + pPortal->SetDisplayId(17612); + if(pInstance) pInstance->SetData(TYPE_LICH_KING,IN_PROGRESS); + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void JustRespawned() + { + Reset(); + } + + void MoveInLineOfSight(Unit *who) + { + } + + void StartMovement() + { + if(!WayPointList.empty() || MovementStarted) + return; + + AddWaypoint(0, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z); + AddWaypoint(1, SpawnLoc[17].x, SpawnLoc[17].y, SpawnLoc[17].z); + AddWaypoint(2, SpawnLoc[18].x, SpawnLoc[18].y, SpawnLoc[18].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + WayPoint = WayPointList.begin(); + MovementStarted = true; + IsWalking = true; + WalkTimer = 200; + event_state_lich_king = 1; + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + } + + void AddWaypoint(uint32 id, float x, float y, float z) + { + WayPoints wp(id, x, y, z); + WayPointList.push_back(wp); + } + + void UpdateAI(const uint32 diff) + { + + if(!pInstance) return; + if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_LICH_KING_1) return; + if (!MovementStarted) StartMovement(); + + if (IsWalking && WalkTimer) + { + if (WalkTimer <= diff) + { + if (WayPoint != WayPointList.end()) + { + m_creature->GetMotionMaster()->MovePoint(WayPoint->id, WayPoint->x, WayPoint->y,WayPoint->z); + WalkTimer = 0; + } + }else WalkTimer -= diff; + } + + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + + if (UpdateTimer <= diff) + { + switch (pInstance->GetData(TYPE_EVENT)) + { + case 5010: + DoScriptText(-1713550,m_creature); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,5020); + break; + case 5030: + DoScriptText(-1713552,m_creature); + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,5040); + break; + case 5040: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + UpdateTimer = 1000; + pInstance->SetData(TYPE_EVENT,5050); + break; + case 5050: + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,5060); + break; + case 5060: if (Event) { + DoScriptText(-1713553,m_creature); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + UpdateTimer = 2500; + pInstance->SetData(TYPE_EVENT,5070); + } + break; + case 5070: + m_creature->CastSpell(m_creature,68198,false); + UpdateTimer = 1500; + pInstance->SetData(TYPE_EVENT,5080); + break; + case 5080: + if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARGENT_COLISEUM_FLOOR))) + { + pGoFloor->SetUInt32Value(GAMEOBJECT_DISPLAYID,9060); + pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN); + pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449); + } + m_creature->CastSpell(m_creature,69016,false); + if(pInstance) pInstance->SetData(TYPE_LICH_KING,DONE); + + pInstance->SetData(TYPE_ANUBARAK,IN_PROGRESS); + m_creature->SummonCreature(NPC_ANUBARAK, SpawnLoc[19].x, SpawnLoc[19].y, SpawnLoc[19].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ANUBARAK))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[20].x, SpawnLoc[20].y, SpawnLoc[20].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + pInstance->SetData(TYPE_STAGE,9); + Event=false; + m_creature->ForcedDespawn(); + pPortal->ForcedDespawn(); + pInstance->SetData(TYPE_EVENT,0); + UpdateTimer = 20000; + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + + } + + void MovementInform(uint32 type, uint32 id) + { + if(pInstance) + { + if(id == 2) + { + Event = true; + } + } + if(type != POINT_MOTION_TYPE) return; + if(WayPoint->id != id) return; + ++WayPoint; + WalkTimer = 200; + } +}; + +CreatureAI* GetAI_boss_lich_king_toc(Creature* pCreature) +{ + return new boss_lich_king_tocAI(pCreature); +}; + +struct MANGOS_DLL_DECL npc_fizzlebang_tocAI : public ScriptedAI +{ + npc_fizzlebang_tocAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); + Reset(); + } + + InstanceData* pInstance; + uint32 UpdateTimer; + Creature* pPortal; + Creature* pTrigger; + + void JustDied(Unit* pKiller) + { + DoScriptText(-1713715, m_creature, pKiller); + pInstance->SetData(TYPE_EVENT, 1180); + if (pPortal) pPortal->ForcedDespawn(); + } + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[27].x, SpawnLoc[27].y, SpawnLoc[27].z); + pPortal = NULL; + } + + void UpdateAI(const uint32 diff) + { + if(!pInstance) return; + + if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_FIZZLEBANG) return; + + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + if(UpdateTimer <= diff) + { + switch(pInstance->GetData(TYPE_EVENT)) + { + case 1110: + pInstance->SetData(TYPE_EVENT, 1120); + UpdateTimer = 3000; + pInstance->SetData(TYPE_JARAXXUS,IN_PROGRESS); + break; + case 1120: + DoScriptText(-1713511, m_creature); + pInstance->SetData(TYPE_EVENT, 1130); + UpdateTimer = 12000; + break; + case 1130: + m_creature->GetMotionMaster()->MovementExpired(); + m_creature->HandleEmoteCommand(EMOTE_STATE_SPELL_CHANNEL_OMNI); + pPortal = m_creature->SummonCreature(NPC_WILFRED_PORTAL, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 5, TEMPSUMMON_MANUAL_DESPAWN, 5000); + if (pPortal) { + pPortal->SetRespawnDelay(DAY); + pPortal->SetDisplayId(22862); + } + DoScriptText(-1713512, m_creature); + pInstance->SetData(TYPE_EVENT, 1132); + UpdateTimer = 4000; + break; + case 1132: + m_creature->GetMotionMaster()->MovementExpired(); + if (pPortal) pPortal->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.5f); + pInstance->SetData(TYPE_EVENT, 1134); + UpdateTimer = 4000; + break; + case 1134: + if (pPortal) pPortal->SetDisplayId(15900); + pTrigger = m_creature->SummonCreature(NPC_TRIGGER, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 5.0f, TEMPSUMMON_MANUAL_DESPAWN, 5000); + if (pTrigger) { + pTrigger->SetDisplayId(17612); + pTrigger->CastSpell(pTrigger, SPELL_WILFRED_PORTAL, false); + pTrigger->SetRespawnDelay(DAY); + } + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST_OMNI); + UpdateTimer = 4000; + pInstance->SetData(TYPE_EVENT, 1135); + break; + case 1135: + if (pTrigger) pTrigger->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST_OMNI); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT, 1140); + break; + case 1140: + pInstance->SetData(TYPE_STAGE,4); + m_creature->SummonCreature(NPC_JARAXXUS, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_JARAXXUS))) { + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->CastSpell(pTemp, SPELL_JARAXXUS_CHAINS, false); + } + pInstance->SetData(TYPE_EVENT, 1142); + UpdateTimer = 5000; + break; + case 1142: + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT, 1144); + DoScriptText(-1713513, m_creature); + break; + case 1144: + if (pTrigger) pTrigger->ForcedDespawn(); + pInstance->SetData(TYPE_EVENT, 1150); + UpdateTimer = 5000; + break; + case 1150: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_JARAXXUS))) { + pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS); + pTemp->SetInCombatWithZone(); + m_creature->SetInCombatWith(pTemp); + pTemp->AddThreat(m_creature, 1000.0f); + pTemp->AI()->AttackStart(m_creature); + } + DoScriptText(-1713515, m_creature); + pInstance->SetData(TYPE_EVENT, 1160); + UpdateTimer = 3000; + break; + case 1160: + pInstance->SetData(TYPE_EVENT, 1170); + UpdateTimer = 1000; + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + } +}; + +CreatureAI* GetAI_npc_fizzlebang_toc(Creature* pCreature) +{ + return new npc_fizzlebang_tocAI(pCreature); } -CreatureAI* GetAI_npc_barrett_ramsey(Creature* pCreature) +struct MANGOS_DLL_DECL npc_tirion_tocAI : public ScriptedAI +{ + npc_tirion_tocAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + uint32 UpdateTimer; + uint32 crusader[12]; + uint8 crusaderscount; + + void Reset() + { + crusaderscount = 0; + memset(&crusader, 0, sizeof(crusader)); + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance) return; + if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_TIRION) return; + + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + + if (UpdateTimer <= diff) + { + switch (pInstance->GetData(TYPE_EVENT)) + { + case 110: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK); + DoScriptText(-1713500, m_creature); + UpdateTimer = 12000; + pInstance->SetData(TYPE_EVENT,120); +// pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_WEST_PORTCULLIS)); + break; + case 140: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK); + DoScriptText(-1713501, m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,150); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + case 150: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + if (pInstance->GetData(TYPE_BEASTS) != DONE) { + m_creature->SummonCreature(NPC_GORMOK, SpawnLoc[26].x, SpawnLoc[26].y, SpawnLoc[26].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_GORMOK))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + } + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,160); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + pInstance->SetData(TYPE_STAGE,1); + pInstance->SetData(TYPE_BEASTS,IN_PROGRESS); + break; + + case 200: + DoScriptText(-1713503, m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,205); + break; + + case 205: + UpdateTimer = 8000; + pInstance->SetData(TYPE_EVENT,210); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + + case 210: + if (pInstance->GetData(TYPE_BEASTS) != DONE){ + m_creature->SummonCreature(NPC_DREADSCALE, SpawnLoc[3].x, SpawnLoc[3].y, SpawnLoc[3].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + m_creature->SummonCreature(NPC_ACIDMAW, SpawnLoc[4].x, SpawnLoc[4].y, SpawnLoc[4].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_DREADSCALE))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ACIDMAW))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + } + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,220); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + case 300: + DoScriptText(-1713505, m_creature); + UpdateTimer = 15000; + pInstance->SetData(TYPE_EVENT,305); + break; + case 305: + UpdateTimer = 8000; + pInstance->SetData(TYPE_EVENT,310); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + case 310: + if (pInstance->GetData(TYPE_BEASTS) != DONE) { + m_creature->SummonCreature(NPC_ICEHOWL, SpawnLoc[26].x, SpawnLoc[26].y, SpawnLoc[26].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ICEHOWL))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + } + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,320); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + case 400: + DoScriptText(-1713509, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,0); +// pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_WEST_PORTCULLIS)); + break; + + case 666: + DoScriptText(-1713709, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,0); + pInstance->SetData(TYPE_NORTHREND_BEASTS,NOT_STARTED); +// pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_WEST_PORTCULLIS)); + break; + + case 1010: + DoScriptText(-1713510, m_creature); + UpdateTimer = 5000; + m_creature->SummonCreature(NPC_FIZZLEBANG, SpawnLoc[21].x, SpawnLoc[21].y, SpawnLoc[21].z, 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + pInstance->SetData(TYPE_EVENT,1110); + break; + + case 1180: + DoScriptText(-1713516, m_creature); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,0); + break; + + case 2000: + DoScriptText(-1713526, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,2010); + break; + case 2030: + DoScriptText(-1713529, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,0); + break; + case 3000: + DoScriptText(-1713530, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3050); + break; + case 3001: + DoScriptText(-1713530, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3051); + break; + case 3060: + DoScriptText(-1713532, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3070); + break; + case 3061: + DoScriptText(-1713532, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3071); + break; +//Summoning crusaders + case 3091: + pInstance->SetData(TYPE_STAGE,6); + if (pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_NORMAL + || pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_HEROIC) + { + crusaderscount = 12; + switch (urand(0,3)){ // Healers, 3 in 25-mode + case 0: crusader[0] = NPC_CRUSADER_1_1; + crusader[1] = NPC_CRUSADER_1_12; + crusader[2] = NPC_CRUSADER_1_13; + break; + case 1: crusader[0] = NPC_CRUSADER_1_1; + crusader[1] = NPC_CRUSADER_1_2; + crusader[2] = NPC_CRUSADER_1_13; + break; + case 2: crusader[0] = NPC_CRUSADER_1_1; + crusader[1] = NPC_CRUSADER_1_2; + crusader[2] = NPC_CRUSADER_1_12; + break; + case 3: crusader[0] = NPC_CRUSADER_1_2; + crusader[1] = NPC_CRUSADER_1_12; + crusader[2] = NPC_CRUSADER_1_13; + break; + } + switch (urand(0,5)){ // Random melee DD, 2 in 25-mode + case 0: crusader[3] = NPC_CRUSADER_1_3; + crusader[4] = NPC_CRUSADER_1_4; + break; + case 1: crusader[3] = NPC_CRUSADER_1_3; + crusader[4] = NPC_CRUSADER_1_5; + break; + case 2: crusader[3] = NPC_CRUSADER_1_3; + crusader[4] = NPC_CRUSADER_1_6; + break; + case 3: crusader[3] = NPC_CRUSADER_1_4; + crusader[4] = NPC_CRUSADER_1_5; + break; + case 4: crusader[3] = NPC_CRUSADER_1_4; + crusader[4] = NPC_CRUSADER_1_6; + break; + case 5: crusader[3] = NPC_CRUSADER_1_5; + crusader[4] = NPC_CRUSADER_1_6; + break; + } + + switch (urand(0,3)){ // Random magic DD, 3 in 25-mode + case 0: crusader[5] = NPC_CRUSADER_1_7; + crusader[6] = NPC_CRUSADER_1_8; + crusader[7] = NPC_CRUSADER_1_11; + break; + case 1: crusader[5] = NPC_CRUSADER_1_7; + crusader[6] = NPC_CRUSADER_1_8; + crusader[7] = NPC_CRUSADER_1_14; + break; + case 2: crusader[5] = NPC_CRUSADER_1_8; + crusader[6] = NPC_CRUSADER_1_11; + crusader[7] = NPC_CRUSADER_1_14; + break; + case 3: crusader[5] = NPC_CRUSADER_1_7; + crusader[6] = NPC_CRUSADER_1_11; + crusader[7] = NPC_CRUSADER_1_14; + break; + } + crusader[8] = NPC_CRUSADER_1_9; //Hunter+warlock + crusader[9] = NPC_CRUSADER_1_10; + crusader[10] = NPC_CRUSADER_0_1; + crusader[11] = NPC_CRUSADER_0_2; + + } else { + crusaderscount = 6; + switch (urand(0,5)){ // Healers, 2 in 10-mode + case 0: crusader[0] = NPC_CRUSADER_1_1; + crusader[1] = NPC_CRUSADER_1_12; + break; + case 1: crusader[0] = NPC_CRUSADER_1_1; + crusader[1] = NPC_CRUSADER_1_2; + break; + case 2: crusader[0] = NPC_CRUSADER_1_2; + crusader[1] = NPC_CRUSADER_1_12; + break; + case 3: crusader[0] = NPC_CRUSADER_1_1; + crusader[1] = NPC_CRUSADER_1_13; + break; + case 4: crusader[0] = NPC_CRUSADER_1_2; + crusader[1] = NPC_CRUSADER_1_13; + break; + case 5: crusader[0] = NPC_CRUSADER_1_12; + crusader[1] = NPC_CRUSADER_1_13; + break; + } + switch (urand(0,5)){ // Random melee DD, 2 in 10-mode + case 0: crusader[3] = NPC_CRUSADER_1_3; + crusader[2] = NPC_CRUSADER_1_4; + break; + case 1: crusader[3] = NPC_CRUSADER_1_3; + crusader[2] = NPC_CRUSADER_1_5; + break; + case 2: crusader[3] = NPC_CRUSADER_1_3; + crusader[2] = NPC_CRUSADER_1_6; + break; + case 3: crusader[3] = NPC_CRUSADER_1_4; + crusader[2] = NPC_CRUSADER_1_5; + break; + case 4: crusader[3] = NPC_CRUSADER_1_4; + crusader[2] = NPC_CRUSADER_1_6; + break; + case 5: crusader[3] = NPC_CRUSADER_1_5; + crusader[2] = NPC_CRUSADER_1_6; + break; + } + + switch (urand(0,5)){ // Random magic DD, 2 in 10-mode + case 0: crusader[4] = NPC_CRUSADER_1_7; + crusader[5] = NPC_CRUSADER_1_8; + break; + case 1: crusader[5] = NPC_CRUSADER_1_7; + crusader[4] = NPC_CRUSADER_1_14; + break; + case 2: crusader[5] = NPC_CRUSADER_1_7; + crusader[4] = NPC_CRUSADER_1_11; + break; + case 3: crusader[5] = NPC_CRUSADER_1_8; + crusader[4] = NPC_CRUSADER_1_11; + break; + case 4: crusader[5] = NPC_CRUSADER_1_8; + crusader[4] = NPC_CRUSADER_1_14; + break; + case 5: crusader[5] = NPC_CRUSADER_1_11; + crusader[4] = NPC_CRUSADER_1_14; + break; + } + + } + for(uint8 i = 0; i < crusaderscount; ++i) + { + m_creature->SummonCreature(crusader[i], SpawnLoc[i+2].x, SpawnLoc[i+2].y, SpawnLoc[i+2].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(crusader[i]))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + } + pInstance->SetData(TYPE_CRUSADERS_COUNT,crusaderscount); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,0); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + pInstance->SetData(TYPE_CRUSADERS,IN_PROGRESS); + break; + +//summoning crusaders + case 3090: + pInstance->SetData(TYPE_STAGE,6); + if (pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_NORMAL + || pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_HEROIC) + { + crusaderscount = 12; + switch (urand(0,3)){ // Healers, 3 in 25-mode + case 0: crusader[0] = NPC_CRUSADER_2_1; + crusader[1] = NPC_CRUSADER_2_12; + crusader[2] = NPC_CRUSADER_2_13; + break; + case 1: crusader[0] = NPC_CRUSADER_2_1; + crusader[1] = NPC_CRUSADER_2_2; + crusader[2] = NPC_CRUSADER_2_13; + break; + case 2: crusader[0] = NPC_CRUSADER_2_1; + crusader[1] = NPC_CRUSADER_2_2; + crusader[2] = NPC_CRUSADER_2_12; + break; + case 3: crusader[0] = NPC_CRUSADER_2_2; + crusader[1] = NPC_CRUSADER_2_12; + crusader[2] = NPC_CRUSADER_2_13; + break; + } + switch (urand(0,5)){ // Random melee DD, 2 in 25-mode + case 0: crusader[3] = NPC_CRUSADER_2_3; + crusader[4] = NPC_CRUSADER_2_4; + break; + case 1: crusader[3] = NPC_CRUSADER_2_3; + crusader[4] = NPC_CRUSADER_2_5; + break; + case 2: crusader[3] = NPC_CRUSADER_2_3; + crusader[4] = NPC_CRUSADER_2_6; + break; + case 3: crusader[3] = NPC_CRUSADER_2_4; + crusader[4] = NPC_CRUSADER_2_5; + break; + case 4: crusader[3] = NPC_CRUSADER_2_4; + crusader[4] = NPC_CRUSADER_2_6; + break; + case 5: crusader[3] = NPC_CRUSADER_2_5; + crusader[4] = NPC_CRUSADER_2_6; + break; + } + + switch (urand(0,3)){ // Random magic DD, 3 in 25-mode + case 0: crusader[5] = NPC_CRUSADER_2_7; + crusader[6] = NPC_CRUSADER_2_8; + crusader[7] = NPC_CRUSADER_2_11; + break; + case 1: crusader[5] = NPC_CRUSADER_2_7; + crusader[6] = NPC_CRUSADER_2_8; + crusader[7] = NPC_CRUSADER_2_14; + break; + case 2: crusader[5] = NPC_CRUSADER_2_8; + crusader[6] = NPC_CRUSADER_2_11; + crusader[7] = NPC_CRUSADER_2_14; + break; + case 3: crusader[5] = NPC_CRUSADER_2_7; + crusader[6] = NPC_CRUSADER_2_11; + crusader[7] = NPC_CRUSADER_2_14; + break; + } + crusader[8] = NPC_CRUSADER_2_9; //Hunter+warlock + crusader[9] = NPC_CRUSADER_2_10; + crusader[10] = NPC_CRUSADER_0_1; + crusader[11] = NPC_CRUSADER_0_2; + + } else { + crusaderscount = 6; + switch (urand(0,5)){ // Healers, 2 in 10-mode + case 0: crusader[0] = NPC_CRUSADER_2_1; + crusader[1] = NPC_CRUSADER_2_12; + break; + case 1: crusader[0] = NPC_CRUSADER_2_1; + crusader[1] = NPC_CRUSADER_2_2; + break; + case 2: crusader[0] = NPC_CRUSADER_2_2; + crusader[1] = NPC_CRUSADER_2_12; + break; + case 3: crusader[0] = NPC_CRUSADER_2_1; + crusader[1] = NPC_CRUSADER_2_13; + break; + case 4: crusader[0] = NPC_CRUSADER_2_2; + crusader[1] = NPC_CRUSADER_2_13; + break; + case 5: crusader[0] = NPC_CRUSADER_2_12; + crusader[1] = NPC_CRUSADER_2_13; + break; + } + switch (urand(0,5)){ // Random melee DD, 2 in 10-mode + case 0: crusader[3] = NPC_CRUSADER_2_3; + crusader[2] = NPC_CRUSADER_2_4; + break; + case 1: crusader[3] = NPC_CRUSADER_2_3; + crusader[2] = NPC_CRUSADER_2_5; + break; + case 2: crusader[3] = NPC_CRUSADER_2_3; + crusader[2] = NPC_CRUSADER_2_6; + break; + case 3: crusader[3] = NPC_CRUSADER_2_4; + crusader[2] = NPC_CRUSADER_2_5; + break; + case 4: crusader[3] = NPC_CRUSADER_2_4; + crusader[2] = NPC_CRUSADER_2_6; + break; + case 5: crusader[3] = NPC_CRUSADER_2_5; + crusader[2] = NPC_CRUSADER_2_6; + break; + } + + switch (urand(0,5)){ // Random magic DD, 2 in 10-mode + case 0: crusader[4] = NPC_CRUSADER_2_7; + crusader[5] = NPC_CRUSADER_2_8; + break; + case 1: crusader[5] = NPC_CRUSADER_2_7; + crusader[4] = NPC_CRUSADER_2_14; + break; + case 2: crusader[5] = NPC_CRUSADER_2_7; + crusader[4] = NPC_CRUSADER_2_11; + break; + case 3: crusader[5] = NPC_CRUSADER_2_8; + crusader[4] = NPC_CRUSADER_2_11; + break; + case 4: crusader[5] = NPC_CRUSADER_2_8; + crusader[4] = NPC_CRUSADER_2_14; + break; + case 5: crusader[5] = NPC_CRUSADER_2_11; + crusader[4] = NPC_CRUSADER_2_14; + break; + } + + } + for(uint8 i = 0; i < crusaderscount; ++i) + { + m_creature->SummonCreature(crusader[i], SpawnLoc[i+2].x, SpawnLoc[i+2].y, SpawnLoc[i+2].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(crusader[i]))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + } + pInstance->SetData(TYPE_CRUSADERS_COUNT,crusaderscount); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,0); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + pInstance->SetData(TYPE_CRUSADERS,IN_PROGRESS); + break; + +//Crusaders battle end + case 3100: + DoScriptText(-1713535, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,0); + break; + + case 4000: + DoScriptText(-1713536, m_creature); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,4010); + break; + case 4010: + DoScriptText(-1713537, m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,4015); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + + case 4015: + pInstance->SetData(TYPE_STAGE,7); + pInstance->SetData(TYPE_VALKIRIES,IN_PROGRESS); + m_creature->SummonCreature(NPC_LIGHTBANE, SpawnLoc[3].x, SpawnLoc[3].y, SpawnLoc[3].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LIGHTBANE))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + m_creature->SummonCreature(NPC_DARKBANE, SpawnLoc[4].x, SpawnLoc[4].y, SpawnLoc[4].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_DARKBANE))) { + pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetInCombatWithZone(); + } + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,4016); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + + case 4040: + UpdateTimer = 60000; + pInstance->SetData(TYPE_EVENT,5000); + break; + + case 5000: + DoScriptText(-1713549, m_creature); + UpdateTimer = 8000; + pInstance->SetData(TYPE_EVENT,5005); + break; + case 5005: + UpdateTimer = 8000; + pInstance->SetData(TYPE_EVENT,5010); + pInstance->SetData(TYPE_STAGE,8); + m_creature->SummonCreature(NPC_LICH_KING_1, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z, 5, TEMPSUMMON_MANUAL_DESPAWN, 0); + break; + case 5020: + DoScriptText(-1713551, m_creature); + UpdateTimer = 8000; + pInstance->SetData(TYPE_EVENT,5030); + break; + case 6000: + m_creature->NearTeleportTo(SpawnLoc[19].x, SpawnLoc[19].y, SpawnLoc[19].z, 4.0f); + UpdateTimer = 20000; + pInstance->SetData(TYPE_EVENT,6005); + break; + case 6005: + DoScriptText(-1713565, m_creature); + UpdateTimer = 20000; + pInstance->SetData(TYPE_EVENT,6010); + break; + case 6010: + if (pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_10MAN_HEROIC + || pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_HEROIC) + DoScriptText(-1713566, m_creature); + UpdateTimer = 60000; + pInstance->SetData(TYPE_EVENT,6020); + break; + case 6020: + pInstance->SetData(TYPE_STAGE,10); + m_creature->ForcedDespawn(); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,6030); + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + + } +}; + +CreatureAI* GetAI_npc_tirion_toc(Creature* pCreature) { - return new npc_barrett_ramseyAI(pCreature); + return new npc_tirion_tocAI(pCreature); } +struct MANGOS_DLL_DECL npc_garrosh_tocAI : public ScriptedAI +{ + npc_garrosh_tocAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + uint32 UpdateTimer; + + void Reset() + { + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance) return; + if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_GARROSH) return; + + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + + if (UpdateTimer <= diff) + { + switch (pInstance->GetData(TYPE_EVENT)) + { + case 120: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK); + DoScriptText(-1713702, m_creature); + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,122); + break; + case 122: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,130); + break; + case 2010: + DoScriptText(-1713527, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,2020); + break; + case 3050: + DoScriptText(-1713531, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3060); + break; + case 3070: + DoScriptText(-1713533, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3080); + break; + case 3081: + DoScriptText(-1713734, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3091); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + case 4030: + DoScriptText(-1713748, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,4040); + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + } +}; + +CreatureAI* GetAI_npc_garrosh_toc(Creature* pCreature) +{ + return new npc_garrosh_tocAI(pCreature); +}; + +struct MANGOS_DLL_DECL npc_rinn_tocAI : public ScriptedAI +{ + npc_rinn_tocAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + uint32 UpdateTimer; + + void Reset() + { + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance) return; + if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_RINN) return; + + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + + if (UpdateTimer <= diff) + { + switch (pInstance->GetData(TYPE_EVENT)) + { + case 130: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK); + DoScriptText(-1713502, m_creature); + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,132); + break; + case 132: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,140); + break; + case 2020: + DoScriptText(-1713528, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,2030); + break; + case 3051: + DoScriptText(-1713731, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3061); + break; + case 3071: + DoScriptText(-1713733, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3081); + break; + case 3080: + DoScriptText(-1713534, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,3090); + pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR)); + break; + case 4020: + DoScriptText(-1713548, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,4030); + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER,UpdateTimer); + } +}; + +CreatureAI* GetAI_npc_rinn_toc(Creature* pCreature) +{ + return new npc_rinn_tocAI(pCreature); +}; + void AddSC_trial_of_the_crusader() { - Script* pNewScript; + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "npc_toc_announcer"; + NewScript->GetAI = &GetAI_npc_toc_announcer; + NewScript->pGossipHello = &GossipHello_npc_toc_announcer; + NewScript->pGossipSelect = &GossipSelect_npc_toc_announcer; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "boss_lich_king_toc"; + NewScript->GetAI = &GetAI_boss_lich_king_toc; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "npc_fizzlebang_toc"; + NewScript->GetAI = &GetAI_npc_fizzlebang_toc; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "npc_tirion_toc"; + NewScript->GetAI = &GetAI_npc_tirion_toc; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "npc_garrosh_toc"; + NewScript->GetAI = &GetAI_npc_garrosh_toc; + NewScript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "npc_barrett_ramsey"; - pNewScript->GetAI = &GetAI_npc_barrett_ramsey; - pNewScript->pGossipHello = &GossipHello_npc_barrett_ramsey; - pNewScript->pGossipSelect = &GossipSelect_npc_barrett_ramsey; - pNewScript->RegisterSelf(); + NewScript = new Script; + NewScript->Name = "npc_rinn_toc"; + NewScript->GetAI = &GetAI_npc_rinn_toc; + NewScript->RegisterSelf(); } diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h index 20ec79ffe..18021f6a8 100644 --- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h +++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h @@ -1,29 +1,177 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ -#ifndef DEF_TRIAL_OF_THE_CRUSADER_H -#define DEF_TRIAL_OF_THE_CRUSADER_H +#ifndef DEF_CRUSADER_H +#define DEF_CRUSADER_H +#include "BSW_ai.h" enum { - MAX_ENCOUNTER = 5, - - TYPE_NORTHREND_BEASTS = 1, - TYPE_JARAXXUS = 2, - TYPE_FACTION_CHAMPIONS = 3, - TYPE_TWIN_VALKYR = 4, - TYPE_ANUBARAK = 5, - - DATA_GORMOK = 6, - DATA_ACIDMAW = 7, - DATA_DREADSCALE = 8, - DATA_ICEHOWL = 9, - DATA_JARAXXUS = 10, - DATA_FACTION_CHAMPIONS = 11, - DATA_FJOLA = 12, - DATA_EYDIS = 13, - DATA_ANUBARAK = 14, + TYPE_STAGE = 0, + TYPE_BEASTS = 1, + TYPE_JARAXXUS = 2, + TYPE_CRUSADERS = 3, + TYPE_VALKIRIES = 4, + TYPE_LICH_KING = 5, + TYPE_ANUBARAK = 6, + TYPE_COUNTER = 7, + TYPE_EVENT = 8, + MAX_ENCOUNTERS = 9, + + NPC_BARRENT = 34816, + NPC_TIRION = 34996, + NPC_FIZZLEBANG = 35458, + NPC_GARROSH = 34995, + NPC_RINN = 34990, + NPC_LICH_KING_0 = 16980, + NPC_LICH_KING_1 = 35877, + + NPC_THRALL = 34994, + NPC_PROUDMOORE = 34992, + NPC_TRIGGER = 22517, + NPC_WILFRED_PORTAL = 35651, + + NPC_ICEHOWL = 34797, + NPC_GORMOK = 34796, + NPC_DREADSCALE = 34799, + NPC_ACIDMAW = 35144, + + NPC_JARAXXUS = 34780, + + NPC_CRUSADER_1_1 = 34460, //Druid + NPC_CRUSADER_1_2 = 34463, //Shaman + NPC_CRUSADER_1_3 = 34461, //DK + NPC_CRUSADER_1_4 = 34472, //Rogue + NPC_CRUSADER_1_5 = 34475, //Warrior + NPC_CRUSADER_1_6 = 34471, //Retro pal + NPC_CRUSADER_1_7 = 34473, //Shadow priest + NPC_CRUSADER_1_8 = 34468, //Mage + NPC_CRUSADER_1_9 = 34467, //Hunter + NPC_CRUSADER_1_10 = 34474, //Warlock + NPC_CRUSADER_1_11 = 34470, //Enh shaman + NPC_CRUSADER_1_12 = 34466, //Priest + NPC_CRUSADER_1_13 = 34465, //Holy paladin + NPC_CRUSADER_1_14 = 34469, //Moonkin + + NPC_CRUSADER_2_1 = 34451, //Druid + NPC_CRUSADER_2_2 = 34455, //Shaman + NPC_CRUSADER_2_3 = 34458, //DK + NPC_CRUSADER_2_4 = 34454, //Rogue + NPC_CRUSADER_2_5 = 34453, //Warrior + NPC_CRUSADER_2_6 = 34456, //Retro pal + NPC_CRUSADER_2_7 = 34441, //Shadow Priest + NPC_CRUSADER_2_8 = 34449, //Mage + NPC_CRUSADER_2_9 = 34448, //Hunter + NPC_CRUSADER_2_10 = 34450, //Warlock + NPC_CRUSADER_2_11 = 34444, //Enh shaman + NPC_CRUSADER_2_12 = 34447, //Priest + NPC_CRUSADER_2_13 = 34445, //Holy paladin + NPC_CRUSADER_2_14 = 34459, //Moonkin + + NPC_CRUSADER_0_1 = 35465, + NPC_CRUSADER_0_2 = 35610, + + NPC_LIGHTBANE = 34497, + NPC_DARKBANE = 34496, + + NPC_ANUBARAK = 34564, + + GO_CRUSADERS_CACHE_10 = 195631, + GO_CRUSADERS_CACHE_25 = 195632, + GO_CRUSADERS_CACHE_10_H = 195633, + GO_CRUSADERS_CACHE_25_H = 195635, + + GO_TRIBUTE_CHEST_10H_25 = 195665, + GO_TRIBUTE_CHEST_10H_45 = 195666, + GO_TRIBUTE_CHEST_10H_50 = 195667, + GO_TRIBUTE_CHEST_10H_99 = 195668, + + GO_TRIBUTE_CHEST_25H_25 = 195669, + GO_TRIBUTE_CHEST_25H_45 = 195670, + GO_TRIBUTE_CHEST_25H_50 = 195671, + GO_TRIBUTE_CHEST_25H_99 = 195672, + + GO_ARGENT_COLISEUM_FLOOR = 195527, //20943 + GO_MAIN_GATE_DOOR = 195647, + + GO_WEST_PORTCULLIS = 195589, + GO_SOUTH_PORTCULLIS = 195590, + GO_NORTH_PORTCULLIS = 195591, + + TYPE_DIFFICULTY = 101, + TYPE_EVENT_TIMER = 102, + TYPE_EVENT_NPC = 103, + TYPE_NORTHREND_BEASTS = 104, + TYPE_CRUSADERS_COUNT = 105, + + DATA_HEALTH_EYDIS = 201, + DATA_HEALTH_FJOLA = 202, + DATA_CASTING_VALKYRS = 203, + + DESPAWN_TIME = 300000, + +}; + +static Locations SpawnLoc[]= +{ + {559.257996f, 90.266197f, 395.122986f}, // 0 Barrent + {563.672974f, 139.571f, 393.837006f}, // 1 Center + {563.833008f, 187.244995f, 394.5f}, // 2 Backdoor + {577.347839f, 195.338888f, 395.14f}, // 3 - Right + {550.955933f, 195.338888f, 395.14f}, // 4 - Left + {575.042358f, 195.260727f, 395.137146f}, // 5 + {552.248901f, 195.331955f, 395.132658f}, // 6 + {573.342285f, 195.515823f, 395.135956f}, // 7 + {554.239929f, 195.825577f, 395.137909f}, // 8 + {571.042358f, 195.260727f, 395.137146f}, // 9 + {556.720581f, 195.015472f, 395.132658f}, // 10 + {569.534119f, 195.214478f, 395.139526f}, // 11 + {569.231201f, 195.941071f, 395.139526f}, // 12 + {558.811610f, 195.985779f, 394.671661f}, // 13 + {567.641724f, 195.351501f, 394.659943f}, // 14 + {560.633972f, 195.391708f, 395.137543f}, // 15 + {565.816956f, 195.477921f, 395.136810f}, // 16 + {563.549f, 152.474f, 394.393f}, // 17 - Lich king start + {563.547f, 141.613f, 393.908f}, // 18 - Lich king end + {787.932556f, 133.28978f, 142.612152f}, // 19 - Anub'arak start location + {618.157898f, 132.640869f, 139.559769f}, // 20 - Anub'arak move point location + {508.104767f, 138.247345f, 395.128052f}, // 21 - Fizzlebang start location + {586.060242f, 117.514809f, 394.314026f}, // 22 - Dark essence 1 + {541.602112f, 161.879837f, 394.587952f}, // 23 - Dark essence 2 + {541.021118f, 117.262932f, 395.314819f}, // 24 - Light essence 1 + {586.200562f, 162.145523f, 394.626129f}, // 25 - Light essence 2 + {563.833008f, 195.244995f, 394.585561f}, // 26 - outdoor + {548.610596f, 139.807800f, 394.321838f}, // 27 - fizzlebang end +}; + +enum uiWorldStates +{ + UPDATE_STATE_UI_SHOW = 4390, + UPDATE_STATE_UI_COUNT = 4389, +}; + +enum NorthrendBeasts +{ + GORMOK_IN_PROGRESS = 1000, + GORMOK_DONE = 1001, + SNAKES_IN_PROGRESS = 2000, + DREADSCALE_SUBMERGED = 2001, + ACIDMAW_SUBMERGED = 2002, + SNAKES_SPECIAL = 2003, + SNAKES_DONE = 2004, + ICEHOWL_IN_PROGRESS = 3000, + ICEHOWL_DONE = 3001, +}; + +enum AnnounserMessages +{ + MSG_BEASTS = 724001, + MSG_JARAXXUS = 724002, + MSG_CRUSADERS = 724003, + MSG_VALKIRIES = 724004, + MSG_LICH_KING = 724005, + MSG_ANUBARAK = 724006, }; #endif diff --git a/scripts/northrend/dalaran.cpp b/scripts/northrend/dalaran.cpp index eaa9ff777..a209effec 100644 --- a/scripts/northrend/dalaran.cpp +++ b/scripts/northrend/dalaran.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/dragonblight.cpp b/scripts/northrend/dragonblight.cpp index 545d56d26..a315b3164 100644 --- a/scripts/northrend/dragonblight.cpp +++ b/scripts/northrend/dragonblight.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/draktharon_keep/boss_dred.cpp b/scripts/northrend/draktharon_keep/boss_dred.cpp new file mode 100644 index 000000000..033671951 --- /dev/null +++ b/scripts/northrend/draktharon_keep/boss_dred.cpp @@ -0,0 +1,196 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Boss_Tharonja +SD%Complete: 80% +SDComment: Timers +SDCategory: Drak'Tharon Keep +EndScriptData */ + +#include "precompiled.h" +#include "draktharon_keep.h" + +enum +{ + SAY_KING_DRED_TALON = -1600020, + SAY_CALL_FOR_RAPTOR = -1600021, + + SPELL_BELLOWING_ROAR = 22686, + SPELL_FEARSOME_ROAR = 48849, + H_SPELL_FEARSOME_ROAR = 59422, + SPELL_GRIEVOUS_BITE = 48920, + SPELL_MANGLING_SLASH = 48873, + SPELL_PIERCING_SLASH = 48878, + SPELL_RAPTOR_CALL = 59416, //not yet implemented + +}; + +const float PosSummon1[3] = {-528.8f, -690.58f, 30.25f}; +/*###### +## boss_dred +######*/ + +struct MANGOS_DLL_DECL boss_dredAI : public ScriptedAI +{ + boss_dredAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 FearsomeRoar_Timer; + uint32 ManglingSlash_Timer; + uint32 PiercingSlash_Timer; + uint32 GrievousBite_Timer; + uint32 BellowingRoar_Timer; + uint32 Check_Timer; + uint32 CallForRaptor_Timer; + uint32 CallForRaptorSpawn_Timer; + uint32 CallForRaptorSpawn_Check; + + void Reset() + { + FearsomeRoar_Timer = 15000; + ManglingSlash_Timer = urand(5000, 10000); + PiercingSlash_Timer = urand(10000, 15000); + GrievousBite_Timer = urand (15000, 20000); + BellowingRoar_Timer = 60000; + Check_Timer = 15000; + CallForRaptor_Timer = 25000; + CallForRaptorSpawn_Check = 0; + } + + void Aggro(Unit* pWho) + { + + } + + void KilledUnit(Unit* pVictim) + { + + } + + void JustDied(Unit* pKiller) + { + + } + + void CallForRaptorSpawnCheck() + { + CallForRaptorSpawn_Timer = 1000; + CallForRaptorSpawn_Check = 1; + } + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + //Fearsome Roar + if (FearsomeRoar_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FEARSOME_ROAR : H_SPELL_FEARSOME_ROAR, true); + FearsomeRoar_Timer = 15000; + }else FearsomeRoar_Timer -= uiDiff; + + //Piercing Slash + if (PiercingSlash_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_PIERCING_SLASH, true); + PiercingSlash_Timer = urand(20000, 25000); + }else PiercingSlash_Timer -= uiDiff; + + //Mangling Slash + if (ManglingSlash_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_MANGLING_SLASH, true); + ManglingSlash_Timer = urand(20000, 25000); + }else ManglingSlash_Timer -= uiDiff; + + //Mangling Slash + if (GrievousBite_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_GRIEVOUS_BITE, true); + GrievousBite_Timer = urand(20000, 25000); + }else GrievousBite_Timer -= uiDiff; + + //Grievous Bite remove + if (Check_Timer < uiDiff) + { + Unit* pPlayer = m_creature->getVictim(); + if (pPlayer->GetHealth() == pPlayer->GetMaxHealth()) + if (pPlayer->HasAura(SPELL_GRIEVOUS_BITE)) + pPlayer->RemoveAura(SPELL_GRIEVOUS_BITE, EFFECT_INDEX_0); + Check_Timer = 1000; + }else Check_Timer -= uiDiff; + + //Bellowing Roar + if (BellowingRoar_Timer < uiDiff) + { + DoCast(m_creature, SPELL_BELLOWING_ROAR); + BellowingRoar_Timer = 60000; + }else BellowingRoar_Timer -= uiDiff; + + //Call For Raptor - spell + if (CallForRaptor_Timer < uiDiff) + { + DoScriptText(SAY_CALL_FOR_RAPTOR, m_creature); + m_creature->CastSpell(m_creature, SAY_CALL_FOR_RAPTOR, true); + CallForRaptor_Timer = 25000; + CallForRaptorSpawnCheck(); + }else CallForRaptor_Timer -= uiDiff; + + //Call For Raptor - spawn + if (CallForRaptorSpawn_Timer < uiDiff && CallForRaptorSpawn_Check == 1) + { + switch(urand(0, 1)) + { + case 0: + { + if (Creature* pRaptor1 = m_creature->SummonCreature(NPC_DRAKKARI_GUTRIPPER, PosSummon1[0], PosSummon1[1], PosSummon1[2], 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 240000)) + pRaptor1->AI()->AttackStart(m_creature->getVictim()); + } + case 1: + { + if (Creature* pRaptor2 = m_creature->SummonCreature(NPC_DRAKKARI_SCYTHECLAW, PosSummon1[0], PosSummon1[1], PosSummon1[2], 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 240000)) + pRaptor2->AI()->AttackStart(m_creature->getVictim()); + } + } + CallForRaptorSpawn_Check = 0; + }else CallForRaptorSpawn_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_dred(Creature* pCreature) +{ + return new boss_dredAI(pCreature); +} + +void AddSC_boss_dred() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_dred"; + newscript->GetAI = &GetAI_boss_dred; + newscript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/northrend/draktharon_keep/boss_novos.cpp b/scripts/northrend/draktharon_keep/boss_novos.cpp index 3b238860f..84f08e3c5 100644 --- a/scripts/northrend/draktharon_keep/boss_novos.cpp +++ b/scripts/northrend/draktharon_keep/boss_novos.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Novos -SD%Complete: 20% -SDComment: +SD%Complete: 80% +SDComment: Timers SDCategory: Drak'Tharon Keep EndScriptData */ @@ -35,12 +35,32 @@ enum EMOTE_ASSISTANCE = -1600011, - NPC_CRYSTAL_HANDLER = 26627, - NPC_HULKING_CORPSE = 27597, - NPC_FETID_TROLL_CORPSE = 27598, - NPC_RISON_SHADOWCASTER = 27600 + POS = 3, + + SPELL_ARCANE_FIELD = 47346, + SPELL_FROSTBOLT = 49037, + H_SPELL_FROSTBOLT = 59855, + SPELL_ARCANE_BLAST = 49198, + H_SPELL_ARCANE_BLAST = 59909, + SPELL_BLIZZARD = 49034, + H_SPELL_BLIZZARD = 59854, + SPELL_WRATH_OF_MISERY = 50089, + H_SPELL_WRATH_OF_MISERY = 59856, + + SPELL_RITUAL_CRYSTAL_KEY = 51404, + SPELL_EFFECT = 52106, + SPELL_DEAD_EFFECT = 47336, + + SPELL_SHADOW_BOLT = 51363, + H_SPELL_SHADOW_BOLT = 59016, }; +const float PosSummonHandler[POS][3] = +{ + {-337.78f, -720.39f, 28.58f}, + {-379.31f, -818.36f, 59.70f}, + {-412.45f, -726.96f, 28.58f}, +}; /*###### ## boss_novos ######*/ @@ -57,14 +77,29 @@ struct MANGOS_DLL_DECL boss_novosAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + bool Phase1; + bool Phase2; + uint32 Start_Check; + uint32 Handler_Spawn; + uint32 Handler_Count; + uint32 Cast_Timer; + uint32 ArcaneBlast_Timer; + uint32 SpecialCast_Timer; + uint32 SummonMinion_Timer; + void Reset() { + Start_Check = 1; + Handler_Spawn = 5000; + Handler_Count = 0; + Phase1 = false; + Phase2 = false; } void MoveInLineOfSight(Unit* pWho) { // An Add reached the ground, if its z-pos is near the z pos of Novos - if (pWho->GetEntry() == NPC_HULKING_CORPSE || pWho->GetEntry() == NPC_FETID_TROLL_CORPSE || pWho->GetEntry() == NPC_RISON_SHADOWCASTER) + if (pWho->GetEntry() == NPC_HULKING_CORPSE || pWho->GetEntry() == NPC_FETID_TROLL_CORPSE || pWho->GetEntry() == NPC_RISEN_SHADOWCASTER) { // Add reached ground, and the failure has not yet been reported if (pWho->GetPositionZ() < m_creature->GetPositionZ() + 1.5f && m_pInstance && m_pInstance->GetData(TYPE_NOVOS) == IN_PROGRESS) @@ -79,6 +114,9 @@ struct MANGOS_DLL_DECL boss_novosAI : public ScriptedAI { DoScriptText(SAY_AGGRO, m_creature); + m_creature->SummonCreature(NPC_CRYSTAL_CHANNEL_TARGET, -379.269f, -737.728f, 39.313f, 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + m_creature->CallForHelp(50.0f); + if (m_pInstance) m_pInstance->SetData(TYPE_NOVOS, IN_PROGRESS); } @@ -102,26 +140,236 @@ struct MANGOS_DLL_DECL boss_novosAI : public ScriptedAI m_pInstance->SetData(TYPE_NOVOS, FAIL); } + void EnterPhase1() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetInCombatWithZone(); + Phase1 = true; + } + + void EnterPhase2() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL); + SummonMinion_Timer = urand (15000,20000); + SpecialCast_Timer = urand(15000, 20000); + ArcaneBlast_Timer = urand(25000, 30000); + Cast_Timer = 500; + Phase1 = false; + Phase2 = true; + } + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + if (Phase2 == true) + { + //Arcane Blast + if (ArcaneBlast_Timer < uiDiff) + { + m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); + m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_ARCANE_BLAST : H_SPELL_ARCANE_BLAST, true); + ArcaneBlast_Timer = urand(25000, 30000); + }else ArcaneBlast_Timer -= uiDiff; + + //Wrath Of Misery or Blizzard + if (SpecialCast_Timer < uiDiff) + { + m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); + switch(urand(0, 1)) + { + case 0: + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_WRATH_OF_MISERY : H_SPELL_WRATH_OF_MISERY); + case 1: + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_BLIZZARD : H_SPELL_BLIZZARD); + } + SpecialCast_Timer = urand(10000, 15000); + }else ArcaneBlast_Timer -= uiDiff; + + //Regual cast - frostbolt + if (Cast_Timer < uiDiff && ArcaneBlast_Timer > uiDiff && SpecialCast_Timer > uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_FROSTBOLT : H_SPELL_FROSTBOLT); + Cast_Timer = 1000; + }else Cast_Timer -= uiDiff; + + //Summon Minions (Heroic) + if (SummonMinion_Timer < uiDiff) + { + if(m_bIsRegularMode) + return; + + uint8 SummonLoc = rand()%POS; + if (Creature* pAdd1 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd1->AI()->AttackStart(m_creature->getVictim()); + if (Creature* pAdd2 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd2->AI()->AttackStart(m_creature->getVictim()); + if (Creature* pAdd3 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd3->AI()->AttackStart(m_creature->getVictim()); + if (Creature* pAdd4 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd4->AI()->AttackStart(m_creature->getVictim()); + if (Creature* pAdd5 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd5->AI()->AttackStart(m_creature->getVictim()); + SummonMinion_Timer = urand (15000,20000); + }else SummonMinion_Timer -= uiDiff; + + } - DoMeleeAttackIfReady(); + if (m_creature->getVictim() && Start_Check == 1) + { + EnterPhase1(); + DoCast(m_creature, SPELL_ARCANE_FIELD); + Start_Check = 0; + } + + //Phase 1 Waves spawn + if (Handler_Spawn < uiDiff && Phase1 == true) + { + Handler_Count ++; + if(Handler_Count < 5) + { + uint8 SummonLoc = rand()%POS; + m_creature->SummonCreature(NPC_CRYSTAL_HANDLER, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000); + if (Creature* pAdd1 = m_creature->SummonCreature(NPC_HULKING_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd1->AI()->AttackStart(m_creature->getVictim()); + if (Creature* pAdd2 = m_creature->SummonCreature(NPC_RISEN_SHADOWCASTER, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd2->AI()->AttackStart(m_creature->getVictim()); + if (Creature* pAdd3 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd3->AI()->AttackStart(m_creature->getVictim()); + if (Creature* pAdd4 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000)) + pAdd4->AI()->AttackStart(m_creature->getVictim()); + Handler_Spawn = 17500; + } + if(Handler_Count == 5) + { + EnterPhase2(); + if (Creature* pTrigger = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL, 85.0f)) + pTrigger->ForcedDespawn(); + } + }else Handler_Spawn -= uiDiff; } }; + + CreatureAI* GetAI_boss_novos(Creature* pCreature) { return new boss_novosAI(pCreature); } +struct MANGOS_DLL_DECL crystal_handlerAI : public ScriptedAI +{ + crystal_handlerAI(Creature* pCreature) : ScriptedAI(pCreature){Reset();} + void Reset(){} + void MoveInLineOfSight(Unit* who) + { + if (Unit* pNovos = GetClosestCreatureWithEntry(m_creature, NPC_NOVOS, 85.0f)) + m_creature->AI()->AttackStart(pNovos->getVictim()); + } + + void JustDied() + { + if (Creature* pDeadTrigger = m_creature->SummonCreature(NPC_TRIGGER_TARGET,0,0,0,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,10000)) + { + if (Unit* pTarget = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL, 85.0f)) + { + pDeadTrigger->CastSpell(pTarget, SPELL_DEAD_EFFECT, true); + } + } + if (Creature* pTrigger = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL, 85.0f)) + pTrigger->ForcedDespawn(); + } +}; + +CreatureAI* GetAI_crystal_handler(Creature* pCreature) +{ + return new crystal_handlerAI(pCreature); +} + +struct MANGOS_DLL_DECL crystal_channelAI : public ScriptedAI +{ + crystal_channelAI(Creature* pCreature) : ScriptedAI(pCreature){Reset();} + uint32 Check_Timer; + void Reset() + { + Check_Timer = 1000; + } + void AttackStart(Unit *pWho){} + void UpdateAI(const uint32 uiDiff) + { + if (Check_Timer < uiDiff) + { + Creature* pNovos = GetClosestCreatureWithEntry(m_creature, NPC_NOVOS, 85.0f); + if (Creature* pTarget = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL_TARGET , 85.0f)) + if (pNovos && ((boss_novosAI*)pNovos->AI())->Phase1 == true) + DoCast(pTarget, SPELL_EFFECT, true); + else + pTarget->ForcedDespawn(); + Check_Timer = 1000; + }else Check_Timer -= uiDiff; + } +}; + +CreatureAI* GetAI_crystal_channel(Creature* pCreature) +{ + return new crystal_channelAI(pCreature); +} + +struct MANGOS_DLL_DECL risen_shadowcasterAI : public ScriptedAI +{ + risen_shadowcasterAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 Check_Timer; + void Reset() + { + Check_Timer = 1000; + } + + void UpdateAI(const uint32 uiDiff) + { + if (Check_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BOLT : H_SPELL_SHADOW_BOLT); + Check_Timer = 1000; + }else Check_Timer -= uiDiff; + } +}; + +CreatureAI* GetAI_risen_shadowcaster(Creature* pCreature) +{ + return new risen_shadowcasterAI(pCreature); +} void AddSC_boss_novos() { - Script* pNewScript; + Script* newscript; + + newscript = new Script; + newscript->Name = "boss_novos"; + newscript->GetAI = &GetAI_boss_novos; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "crystal_handler"; + newscript->GetAI = &GetAI_crystal_handler; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "crystal_channel"; + newscript->GetAI = &GetAI_crystal_channel; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "risen_shadowcaster"; + newscript->GetAI = &GetAI_risen_shadowcaster; + newscript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "boss_novos"; - pNewScript->GetAI = &GetAI_boss_novos; - pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/draktharon_keep/boss_tharonja.cpp b/scripts/northrend/draktharon_keep/boss_tharonja.cpp index 1295ac7aa..a77c9e7fe 100644 --- a/scripts/northrend/draktharon_keep/boss_tharonja.cpp +++ b/scripts/northrend/draktharon_keep/boss_tharonja.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Tharonja -SD%Complete: 20% -SDComment: +SD%Complete: 80% +SDComment: Timers, end event with drakuru SDCategory: Drak'Tharon Keep EndScriptData */ @@ -33,9 +33,53 @@ enum SAY_FLESH_2 = -1600016, SAY_SKELETON_1 = -1600017, SAY_SKELETON_2 = -1600018, - SAY_DEATH = -1600019 + SAY_DEATH = -1600019, + + //Phase 1 (Skeleton) Spells + SPELL_CURSE_OF_LIFE = 49527, + H_SPELL_CURSE_OF_LIFE = 59972, + + SPELL_SHADOW_VOLLEY = 49528, + H_SPELL_SHADOW_VOLLEY = 59973, + SPELL_RAIN_OF_FIRE = 49518, + H_SPELL_RAIN_OF_FIRE = 59971, + + SPELL_DECAY_FLESH = 49356, //not working + + //Phase 2 (Flesh) Spells + SPELL_GIFT_OF_THARONJA = 52509, + + SPELL_LIGHTNING_BREATH = 49537, + H_SPELL_LIGHTNING_BREATH = 59936, + SPELL_EYE_BEAM = 49544, + H_SPELL_EYE_BEAM = 59965, + + SPELL_POISON_CLOUD = 49548, + H_SPELL_POSION_CLOUD = 59969, + + SPELL_RETURN_FLESH = 53463, //not working + + //achie hacks + ACHIEVEMENT_NORMAL = 482, + ACHIEVEMENT_HEROIC = 493 + +}; + +//Phasses +enum Phase +{ + PHASE_SKELETON = 0, + PHASE_INTOFLESH = 1, + PHASE_FLESH = 2, + PHASE_INTOSKELETON = 3 }; +enum PhaseChangeTimer +{ + PHASE_CHANGE_SKELETON = 12000, + PHASE_CHANGE_REAL = 6000, + PHASE_CHANGE_FLESH = 20000 +}; /*###### ## boss_tharonja ######*/ @@ -51,9 +95,19 @@ struct MANGOS_DLL_DECL boss_tharonjaAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + uint32 PhaseChangeTimer; + uint32 Phase; + uint32 CurseOfLife_Timer; + uint32 SkeletonSpells_Timer; + uint32 PoisonCloud_Timer; + uint32 FleshSpells_Timer; void Reset() { + PhaseChangeTimer = PHASE_CHANGE_SKELETON; + Phase = PHASE_SKELETON; + SkeletonSpells_Timer = urand (5000, 10000); + CurseOfLife_Timer = urand (5000, 10000); } void Aggro(Unit* pWho) @@ -88,7 +142,91 @@ struct MANGOS_DLL_DECL boss_tharonjaAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - DoMeleeAttackIfReady(); + if (Phase == PHASE_SKELETON) + { + if (CurseOfLife_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CURSE_OF_LIFE : H_SPELL_CURSE_OF_LIFE); + CurseOfLife_Timer = urand (5000, 10000); + }else CurseOfLife_Timer -= uiDiff; + + if (SkeletonSpells_Timer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_VOLLEY : H_SPELL_SHADOW_VOLLEY); + case 1: + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_RAIN_OF_FIRE : H_SPELL_RAIN_OF_FIRE); + } + SkeletonSpells_Timer = urand (5000, 10000); + }else SkeletonSpells_Timer -= uiDiff; + + if (PhaseChangeTimer < uiDiff) + { + m_creature->CastSpell(m_creature, SPELL_DECAY_FLESH, true); + PhaseChangeTimer = PHASE_CHANGE_REAL; + Phase = PHASE_INTOFLESH; + }else PhaseChangeTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + if (Phase == PHASE_INTOFLESH) + { + if (PhaseChangeTimer < uiDiff) + { + m_creature->CastSpell(m_creature, SPELL_GIFT_OF_THARONJA, true); + m_creature->SetDisplayId(27073); + PhaseChangeTimer = PHASE_CHANGE_FLESH; + Phase = PHASE_FLESH; + FleshSpells_Timer = 1500; + PoisonCloud_Timer = 10000; + }else PhaseChangeTimer -= uiDiff; + } + + if (Phase == PHASE_FLESH) + { + if (PhaseChangeTimer < uiDiff) + { + DoCast(m_creature, SPELL_RETURN_FLESH); + PhaseChangeTimer = PHASE_CHANGE_REAL; + Phase = PHASE_INTOSKELETON; + }else PhaseChangeTimer -= uiDiff; + + if (PoisonCloud_Timer < uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_POISON_CLOUD : H_SPELL_POSION_CLOUD); + PoisonCloud_Timer = 10000; + }else PoisonCloud_Timer -= uiDiff; + + if (FleshSpells_Timer < uiDiff) + { + switch(urand(0, 3)) + { + case 0: + case 1: + case 2: + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_LIGHTNING_BREATH : H_SPELL_LIGHTNING_BREATH); + case 3: + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_EYE_BEAM : SPELL_EYE_BEAM); + } + FleshSpells_Timer = 1500; + }else FleshSpells_Timer -= uiDiff; + } + + if (Phase == PHASE_INTOSKELETON) + { + if (PhaseChangeTimer < uiDiff) + { + DoCast(m_creature, SPELL_DECAY_FLESH); + m_creature->SetDisplayId(27072); + PhaseChangeTimer = PHASE_CHANGE_SKELETON; + Phase = PHASE_SKELETON; + SkeletonSpells_Timer = urand (5000, 10000); + CurseOfLife_Timer = urand (5000, 10000); + }else PhaseChangeTimer -= uiDiff; + } } }; diff --git a/scripts/northrend/draktharon_keep/boss_trollgore.cpp b/scripts/northrend/draktharon_keep/boss_trollgore.cpp index 046917dc2..45ece53b7 100644 --- a/scripts/northrend/draktharon_keep/boss_trollgore.cpp +++ b/scripts/northrend/draktharon_keep/boss_trollgore.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Trollgore -SD%Complete: 20% -SDComment: +SD%Complete: 90% +SDComment: Timers SDCategory: Drak'Tharon Keep EndScriptData */ @@ -30,9 +30,29 @@ enum SAY_CONSUME = -1600001, SAY_DEATH = -1600002, SAY_EXPLODE = -1600003, - SAY_KILL = -1600004 + SAY_KILL = -1600004, + + SPELL_CRUSH = 49639, + SPELL_INFECTED_WOUND = 49367, + SPELL_CORPSE_EXPLODE = 49555, + H_SPELL_CORPSE_EXPLODE = 59087, + SPELL_CONSUME = 49380, + H_SPELL_CONSUME = 59803, + SPELL_CONSUME_BUFF = 49381, + H_SPELL_CONSUME_BUFF = 59805, + + SPELL_CORPSE_EXPLODE_PROC = 49618, + H_SPELL_CORPSE_EXPLODE_PROC = 59809, + + NPC_DRAKKARI_INVADER = 27753, + NPC_TROLLGORE = 26630 }; +const float PosSummon1[3] = {-259.59f, -652.49f, 26.52f}; +const float PosSummon2[3] = {-261.60f, -658.71f, 26.51f}; +const float PosSummon3[3] = {-262.05f, -665.71f, 26.49f}; + + /*###### ## boss_trollgore ######*/ @@ -49,8 +69,19 @@ struct MANGOS_DLL_DECL boss_trollgoreAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + uint32 Consume_Timer; + uint32 Crush_Timer; + uint32 InfectedWound_Timer; + uint32 Wave_Timer; + uint32 CorpseExplode_Timer; + void Reset() { + CorpseExplode_Timer = 10000; + Consume_Timer = 5000; + Crush_Timer = 10000; + InfectedWound_Timer = 30000; + Wave_Timer = 2000; } void Aggro(Unit* pWho) @@ -81,11 +112,78 @@ struct MANGOS_DLL_DECL boss_trollgoreAI : public ScriptedAI m_pInstance->SetData(TYPE_TROLLGORE, FAIL); } + void SummonWaves() + { + if (Creature* pInvader1 = m_creature->SummonCreature(NPC_DRAKKARI_INVADER,PosSummon1[0],PosSummon1[1],PosSummon1[2],0, TEMPSUMMON_TIMED_DESPAWN, 15000)) + pInvader1->AI()->AttackStart(m_creature); + if (Creature* pInvader2 = m_creature->SummonCreature(NPC_DRAKKARI_INVADER,PosSummon2[0],PosSummon2[1],PosSummon2[2],0, TEMPSUMMON_TIMED_DESPAWN, 15000)) + pInvader2->AI()->AttackStart(m_creature); + if (Creature* pInvader3 = m_creature->SummonCreature(NPC_DRAKKARI_INVADER,PosSummon3[0],PosSummon3[1],PosSummon3[2],0, TEMPSUMMON_TIMED_DESPAWN, 15000)) + pInvader3->AI()->AttackStart(m_creature); + } + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + // Crush + if (Crush_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_CRUSH); + Crush_Timer = 10000; + }else Crush_Timer -= uiDiff; + + // Infected Wound + if (InfectedWound_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_CRUSH); + InfectedWound_Timer = 30000; + }else InfectedWound_Timer -= uiDiff; + + // Summon npcs + if (Wave_Timer < uiDiff) + { + SummonWaves(); + Wave_Timer = 15000; + }else Wave_Timer -= uiDiff; + + // Consume + if (Consume_Timer < uiDiff) + { + m_creature->CastSpell(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CONSUME : H_SPELL_CONSUME, true); + m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_CONSUME_BUFF : H_SPELL_CONSUME_BUFF, true); + Consume_Timer = 15000; + }else Consume_Timer -= uiDiff; + + //Corpse Explosion + if (CorpseExplode_Timer < uiDiff) + { + //DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CORPSE_EXPLODE : H_SPELL_CORPSE_EXPLODE); + + if (Creature* pCorpse = GetClosestCreatureWithEntry(m_creature, NPC_DRAKKARI_INVADER, 85.0f)) + { + if (!pCorpse->isAlive()) + { + Map *map = pCorpse->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive() && pCorpse->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) <= 5) + m_creature->DealDamage(i->getSource(), (m_bIsRegularMode ? urand(3770, 4230) : urand(9425, 10575)), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NATURE, NULL, false); + } + } + } + } + CorpseExplode_Timer = 15000; + }else CorpseExplode_Timer -= uiDiff; + DoMeleeAttackIfReady(); } }; diff --git a/scripts/northrend/draktharon_keep/draktharon_keep.h b/scripts/northrend/draktharon_keep/draktharon_keep.h index 67093b4eb..5675d37bd 100644 --- a/scripts/northrend/draktharon_keep/draktharon_keep.h +++ b/scripts/northrend/draktharon_keep/draktharon_keep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -16,6 +16,23 @@ enum NPC_KING_DRED = 27483, + TYPE_CRYSTAL_1 = 5, + TYPE_CRYSTAL_2 = 6, + TYPE_CRYSTAL_3 = 7, + TYPE_CRYSTAL_4 = 8, + TYPE_NOVOS_PHASE2_CHECK = 9, + TYPE_NOVOS_EVENT = 10, + + NPC_CRYSTAL_CHANNEL_TARGET = 26710, + NPC_CRYSTAL_CHANNEL = 26712, + NPC_TRIGGER_TARGET = 26714, + NPC_NOVOS = 26631, + + NPC_CRYSTAL_HANDLER = 26627, + NPC_HULKING_CORPSE = 27597, + NPC_FETID_TROLL_CORPSE = 27598, + NPC_RISEN_SHADOWCASTER = 27600, + // Adds of King Dred Encounter - deaths counted for achievement NPC_DRAKKARI_GUTRIPPER = 26641, NPC_DRAKKARI_SCYTHECLAW = 26628, diff --git a/scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp b/scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp index e25f823d3..7d73ea93d 100644 --- a/scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp +++ b/scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/grizzly_hills.cpp b/scripts/northrend/grizzly_hills.cpp index e5c1c67f9..40edf127d 100644 --- a/scripts/northrend/grizzly_hills.cpp +++ b/scripts/northrend/grizzly_hills.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,8 +17,91 @@ /* ScriptData SDName: Grizzly_Hills SD%Complete: -SDComment: +SDComment: Quest support: 12138, 12198 SDCategory: Grizzly Hills EndScriptData */ +/* ContentData +npc_depleted_war_golem +EndContentData */ + #include "precompiled.h" +#include "pet_ai.h" + +/*###### +## npc_depleted_war_golem +######*/ + +enum +{ + SAY_GOLEM_CHARGE = -1000626, + SAY_GOLEM_COMPLETE = -1000627, + + NPC_LIGHTNING_SENTRY = 26407, + + SPELL_CHARGE_GOLEM = 47799, + SPELL_GOLEM_CHARGE_CREDIT = 47797, +}; + +struct MANGOS_DLL_DECL npc_depleted_war_golemAI : public ScriptedPetAI +{ + npc_depleted_war_golemAI(Creature* pCreature) : ScriptedPetAI(pCreature) { Reset(); } + + void Reset() { } + + void OwnerKilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() == TYPEID_UNIT && pVictim->GetEntry() == NPC_LIGHTNING_SENTRY) + { + // Is distance expected? + if (m_creature->IsWithinDistInMap(pVictim, 10.0f)) + m_creature->CastSpell(m_creature, SPELL_CHARGE_GOLEM, true); + } + } +}; + +CreatureAI* GetAI_npc_depleted_war_golem(Creature* pCreature) +{ + return new npc_depleted_war_golemAI(pCreature); +} + +bool EffectAuraDummy_npc_depleted_war_golem(const Aura* pAura, bool bApply) +{ + if (pAura->GetId() != SPELL_CHARGE_GOLEM) + return true; + + Creature* pCreature = (Creature*)pAura->GetTarget(); + + if (!pCreature) + return true; + + if (pAura->GetEffIndex() == EFFECT_INDEX_0) + { + if (bApply) + { + DoScriptText(SAY_GOLEM_CHARGE, pCreature); + pCreature->addUnitState(UNIT_STAT_STUNNED); + } + else + { + DoScriptText(SAY_GOLEM_COMPLETE, pCreature); + pCreature->clearUnitState(UNIT_STAT_STUNNED); + + // targets master + pCreature->CastSpell(pCreature, SPELL_GOLEM_CHARGE_CREDIT, true); + } + } + + return true; +} + +void AddSC_grizzly_hills() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "npc_depleted_war_golem"; + pNewScript->GetAI = &GetAI_npc_depleted_war_golem; + pNewScript->pEffectAuraDummy = &EffectAuraDummy_npc_depleted_war_golem; + pNewScript->RegisterSelf(); +} diff --git a/scripts/northrend/gundrak/boss_colossus.cpp b/scripts/northrend/gundrak/boss_colossus.cpp index e10df4f2f..d5c8967aa 100644 --- a/scripts/northrend/gundrak/boss_colossus.cpp +++ b/scripts/northrend/gundrak/boss_colossus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/gundrak/boss_eck.cpp b/scripts/northrend/gundrak/boss_eck.cpp index e6c17ef55..24728b333 100644 --- a/scripts/northrend/gundrak/boss_eck.cpp +++ b/scripts/northrend/gundrak/boss_eck.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/gundrak/boss_galdarah.cpp b/scripts/northrend/gundrak/boss_galdarah.cpp index 436aee65f..7d027d4b2 100644 --- a/scripts/northrend/gundrak/boss_galdarah.cpp +++ b/scripts/northrend/gundrak/boss_galdarah.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/gundrak/boss_moorabi.cpp b/scripts/northrend/gundrak/boss_moorabi.cpp index 05cb78e82..0ef08cdd4 100644 --- a/scripts/northrend/gundrak/boss_moorabi.cpp +++ b/scripts/northrend/gundrak/boss_moorabi.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/gundrak/boss_sladran.cpp b/scripts/northrend/gundrak/boss_sladran.cpp index a472c65ea..d10ef4ab3 100644 --- a/scripts/northrend/gundrak/boss_sladran.cpp +++ b/scripts/northrend/gundrak/boss_sladran.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/gundrak/gundrak.h b/scripts/northrend/gundrak/gundrak.h index 7f4ac4b31..997f7bd25 100644 --- a/scripts/northrend/gundrak/gundrak.h +++ b/scripts/northrend/gundrak/gundrak.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -28,6 +28,7 @@ enum NPC_LIVIN_MOJO = 29830, NPC_GALDARAH = 29306, NPC_ECK = 29932, + NPC_INVISIBLE_STALKER = 30298, // Caster and Target for visual spells on altar use GO_ECK_DOOR = 192632, GO_ECK_UNDERWATER_DOOR = 192569, @@ -45,9 +46,20 @@ enum GO_RHINO_KEY = 192566, GO_BRIDGE = 193188, - GO_COLLISION = 192633 + GO_COLLISION = 192633, + + SPELL_BEAM_MAMMOTH = 57068, + SPELL_BEAM_SNAKE = 57071, + SPELL_BEAM_ELEMENTAL = 57072, + + TIMER_VISUAL_ALTAR = 3000, + TIMER_VISUAL_BEAM = 2500, + TIMER_VISUAL_KEY = 2000, }; +typedef std::map TypeTimerMap; +typedef std::pair TypeTimerPair; + class MANGOS_DLL_DECL instance_gundrak : public ScriptedInstance { public: @@ -66,7 +78,10 @@ class MANGOS_DLL_DECL instance_gundrak : public ScriptedInstance const char* Save() { return strInstData.c_str(); } void Load(const char* chrIn); + void Update(uint32 uiDiff); + protected: + void DoAltarVisualEffect(uint8 uiType); uint32 m_auiEncounter[MAX_ENCOUNTER]; std::string strInstData; @@ -78,14 +93,24 @@ class MANGOS_DLL_DECL instance_gundrak : public ScriptedInstance uint64 m_uiSnakeKeyGUID; uint64 m_uiMammothKeyGUID; uint64 m_uiTrollKeyGUID; + uint64 m_uiRhinoKeyGUID; uint64 m_uiAltarOfSladranGUID; uint64 m_uiAltarOfMoorabiGUID; uint64 m_uiAltarOfColossusGUID; uint64 m_uiBridgeGUID; + uint64 m_uiCollisionGUID; uint64 m_uiSladranGUID; uint64 m_uiElementalGUID; uint64 m_uiColossusGUID; + + TypeTimerMap m_mAltarInProgress; + TypeTimerMap m_mBeamInProgress; + TypeTimerMap m_mKeyInProgress; + + std::list m_luiStalkerGUIDs; + std::list m_luiStalkerCasterGUIDs; + std::list m_luiStalkerTargetGUIDs; }; #endif diff --git a/scripts/northrend/gundrak/instance_gundrak.cpp b/scripts/northrend/gundrak/instance_gundrak.cpp index 63be2a2f9..64d0ebb68 100644 --- a/scripts/northrend/gundrak/instance_gundrak.cpp +++ b/scripts/northrend/gundrak/instance_gundrak.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,15 +16,15 @@ /* ScriptData SDName: instance_gundrak -SD%Complete: 0 -SDComment: +SD%Complete: 80 +SDComment: Reload case for bridge support is missing, achievement support is missing SDCategory: Gundrak EndScriptData */ #include "precompiled.h" #include "gundrak.h" -bool GOHello_go_gundrak_altar(Player* pPlayer, GameObject* pGo) +bool GOUse_go_gundrak_altar(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -38,7 +38,7 @@ bool GOHello_go_gundrak_altar(Player* pPlayer, GameObject* pGo) case GO_ALTAR_OF_COLOSSUS: pInstance->SetData(TYPE_COLOSSUS, SPECIAL); break; } - pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + pGo->UseDoorOrButton(0, true); return true; } @@ -51,10 +51,12 @@ instance_gundrak::instance_gundrak(Map* pMap) : ScriptedInstance(pMap), m_uiSnakeKeyGUID(0), m_uiMammothKeyGUID(0), m_uiTrollKeyGUID(0), + m_uiRhinoKeyGUID(0), m_uiAltarOfSladranGUID(0), m_uiAltarOfMoorabiGUID(0), m_uiAltarOfColossusGUID(0), m_uiBridgeGUID(0), + m_uiCollisionGUID(0), m_uiSladranGUID(0), m_uiElementalGUID(0), @@ -75,9 +77,24 @@ void instance_gundrak::OnCreatureCreate(Creature* pCreature) case NPC_SLADRAN: m_uiSladranGUID = pCreature->GetGUID(); break; case NPC_ELEMENTAL: m_uiElementalGUID = pCreature->GetGUID(); break; case NPC_COLOSSUS: m_uiColossusGUID = pCreature->GetGUID(); break; + + case NPC_INVISIBLE_STALKER: m_luiStalkerGUIDs.push_back(pCreature->GetGUID()); break; } } +/* TODO: Reload case need some love! +* Problem is to get the bridge/ collision work correct in relaod case. +* To provide correct functionality(expecting testers to activate all altars in reload case), the Keys aren't loaded, too +* TODO: When fixed, also remove the SPECIAL->DONE data translation in Load(). +* +* For the Keys should be used something like this, and for bridge and collision similar +* +* if (m_auiEncounter[0] == SPECIAL && m_auiEncounter[1] == SPECIAL && m_auiEncounter[2] == SPECIAL) +* pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); +* else +* pGo->SetGoState(GO_STATE_READY); +*/ + void instance_gundrak::OnObjectCreate(GameObject* pGo) { switch(pGo->GetEntry()) @@ -123,22 +140,22 @@ void instance_gundrak::OnObjectCreate(GameObject* pGo) break; case GO_SNAKE_KEY: m_uiSnakeKeyGUID = pGo->GetGUID(); - if (m_auiEncounter[TYPE_SLADRAN] == SPECIAL) - DoUseDoorOrButton(m_uiSnakeKeyGUID); break; case GO_TROLL_KEY: m_uiTrollKeyGUID = pGo->GetGUID(); - if (m_auiEncounter[TYPE_COLOSSUS] == SPECIAL) - DoUseDoorOrButton(m_uiTrollKeyGUID); break; case GO_MAMMOTH_KEY: m_uiMammothKeyGUID = pGo->GetGUID(); - if (m_auiEncounter[TYPE_MOORABI] == SPECIAL) - DoUseDoorOrButton(m_uiMammothKeyGUID); + break; + case GO_RHINO_KEY: + m_uiRhinoKeyGUID = pGo->GetGUID(); break; case GO_BRIDGE: m_uiBridgeGUID = pGo->GetGUID(); break; + case GO_COLLISION: + m_uiCollisionGUID = pGo->GetGUID(); + break; } } void instance_gundrak::Load(const char* chrIn) @@ -158,6 +175,10 @@ void instance_gundrak::Load(const char* chrIn) { if (m_auiEncounter[i] == IN_PROGRESS) m_auiEncounter[i] = NOT_STARTED; + + // TODO: REMOVE when bridge/ collision reloading correctly working + if (m_auiEncounter[i] == SPECIAL) + m_auiEncounter[i] = DONE; } OUT_LOAD_INST_DATA_COMPLETE; @@ -165,7 +186,7 @@ void instance_gundrak::Load(const char* chrIn) void instance_gundrak::SetData(uint32 uiType, uint32 uiData) { - debug_log("SD2: Instance Gundrak: SetData received for type %u with data %u",uiType,uiData); + debug_log("SD2: Instance Gundrak: SetData received for type %u with data %u", uiType, uiData); switch(uiType) { @@ -175,7 +196,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) if (GameObject* pGo = instance->GetGameObject(m_uiAltarOfSladranGUID)) pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); if (uiData == SPECIAL) - DoUseDoorOrButton(m_uiSnakeKeyGUID); + m_mAltarInProgress.insert(TypeTimerPair(TYPE_SLADRAN, TIMER_VISUAL_ALTAR)); break; case TYPE_MOORABI: m_auiEncounter[TYPE_MOORABI] = uiData; @@ -187,7 +208,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); } if (uiData == SPECIAL) - DoUseDoorOrButton(m_uiMammothKeyGUID); + m_mAltarInProgress.insert(TypeTimerPair(TYPE_MOORABI, TIMER_VISUAL_ALTAR)); break; case TYPE_COLOSSUS: m_auiEncounter[TYPE_COLOSSUS] = uiData; @@ -195,7 +216,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) if (GameObject* pGo = instance->GetGameObject(m_uiAltarOfColossusGUID)) pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); if (uiData == SPECIAL) - DoUseDoorOrButton(m_uiTrollKeyGUID); + m_mAltarInProgress.insert(TypeTimerPair(TYPE_COLOSSUS, TIMER_VISUAL_ALTAR)); break; case TYPE_GALDARAH: m_auiEncounter[TYPE_GALDARAH] = uiData; @@ -216,7 +237,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) break; } - if (uiData == DONE) + if (uiData == DONE || uiData == SPECIAL) // Save activated altars, too { OUT_SAVE_INST_DATA; @@ -263,6 +284,164 @@ uint64 instance_gundrak::GetData64(uint32 uiType) return 0; } +static bool sortFromEastToWest(Creature* pFirst, Creature* pSecond) +{ + return pFirst && pSecond && pFirst->GetPositionY() < pSecond->GetPositionY(); +} + +void instance_gundrak::DoAltarVisualEffect(uint8 uiType) +{ + // Sort the lists if not yet done + if (!m_luiStalkerGUIDs.empty()) + { + float fHeight = 10.0f; // A bit higher than the altar is needed + if (GameObject* pCollusAltar = instance->GetGameObject(m_uiAltarOfColossusGUID)) + fHeight += pCollusAltar->GetPositionZ(); + + std::list lStalkerTargets, lStalkerCasters; + for (std::list::const_iterator itr = m_luiStalkerGUIDs.begin(); itr != m_luiStalkerGUIDs.end(); ++itr) + { + if (Creature* pStalker = instance->GetCreature(*itr)) + { + if (pStalker->GetPositionZ() > fHeight) + lStalkerTargets.push_back(pStalker); + else + lStalkerCasters.push_back(pStalker); + } + } + m_luiStalkerGUIDs.clear(); + + lStalkerTargets.sort(sortFromEastToWest); + lStalkerCasters.sort(sortFromEastToWest); + + for (std::list::const_iterator itr = lStalkerTargets.begin(); itr != lStalkerTargets.end(); ++itr) + m_luiStalkerTargetGUIDs.push_back((*itr)->GetGUID()); + for (std::list::const_iterator itr = lStalkerCasters.begin(); itr != lStalkerCasters.end(); ++itr) + m_luiStalkerCasterGUIDs.push_back((*itr)->GetGUID()); + } + + // Verify that the DB has enough trigger spawned + if (m_luiStalkerTargetGUIDs.size() < 3 || m_luiStalkerCasterGUIDs.size() < 3) + return; + + // Get the Index from the bosses + uint8 uiIndex = 0; + switch (uiType) + { + case TYPE_SLADRAN: uiIndex = 0; break; + case TYPE_COLOSSUS: uiIndex = 1; break; + case TYPE_MOORABI: uiIndex = 2; break; + default: + return; + } + + std::list::iterator targetItr = m_luiStalkerTargetGUIDs.begin(); + std::list::iterator casterItr = m_luiStalkerCasterGUIDs.begin(); + + advance(targetItr, uiIndex); + advance(casterItr, uiIndex); + + Creature* pTarget = instance->GetCreature(*targetItr); + Creature* pCaster = instance->GetCreature(*casterItr); + + if (!pTarget || !pCaster) + return; + + uint32 auiFireBeamSpells[3] = {SPELL_BEAM_SNAKE, SPELL_BEAM_ELEMENTAL, SPELL_BEAM_MAMMOTH}; + + // Cast from Caster to Target + pCaster->CastSpell(pTarget, auiFireBeamSpells[uiIndex], true); +} + +void instance_gundrak::Update(uint32 uiDiff) +{ + // Possible multible altars used at the same time, process their timers + if (!m_mAltarInProgress.empty()) + { + for (TypeTimerMap::iterator itr = m_mAltarInProgress.begin(); itr != m_mAltarInProgress.end();) + { + if (itr->second < uiDiff) + { + // Do Visual Effect + DoAltarVisualEffect(itr->first); + // Set Timer for Beam-Duration + m_mBeamInProgress.insert(TypeTimerPair(itr->first, TIMER_VISUAL_BEAM)); + // Remove this timer, as processed + m_mAltarInProgress.erase(itr++); + } + else + { + itr->second -= uiDiff; + ++itr; + } + } + } + + // Possible multible beams used at the same time, process their timers + if (!m_mBeamInProgress.empty()) + { + for (TypeTimerMap::iterator itr = m_mBeamInProgress.begin(); itr != m_mBeamInProgress.end();) + { + if (itr->second < uiDiff) + { + // Use Key + switch (itr->first) + { + case TYPE_SLADRAN: DoUseDoorOrButton(m_uiSnakeKeyGUID); break; + case TYPE_MOORABI: DoUseDoorOrButton(m_uiMammothKeyGUID); break; + case TYPE_COLOSSUS: DoUseDoorOrButton(m_uiTrollKeyGUID); break; + } + // Set Timer for Beam-Duration + m_mKeyInProgress.insert(TypeTimerPair(itr->first, TIMER_VISUAL_KEY)); + m_mBeamInProgress.erase(itr++); + } + else + { + itr->second -= uiDiff; + ++itr; + } + } + } + + // Activate Bridge if all Three Encounters are used + if (!m_mKeyInProgress.empty()) + { + for (TypeTimerMap::iterator itr = m_mKeyInProgress.begin(); itr != m_mKeyInProgress.end();) + { + if (itr->second < uiDiff) + { + // Activate Bridge (and all other Keys) if we are on the last Key, and all other keys are already set + if (m_auiEncounter[0] == SPECIAL && m_auiEncounter[1] == SPECIAL && m_auiEncounter[2] == SPECIAL + && m_mAltarInProgress.empty() && m_mBeamInProgress.empty() && m_mKeyInProgress.size() == 1) + { + DoUseDoorOrButton(m_uiCollisionGUID); + DoUseDoorOrButton(m_uiRhinoKeyGUID, 0, true); + + // The already closed keys cannot be done with DoUseDoorOrButton + if (GameObject* pTrollKey = instance->GetGameObject(m_uiTrollKeyGUID)) + pTrollKey->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + if (GameObject* pMammothKey = instance->GetGameObject(m_uiMammothKeyGUID)) + pMammothKey->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + if (GameObject* pSnakeKey = instance->GetGameObject(m_uiSnakeKeyGUID)) + pSnakeKey->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + + // GO_BRIDGE is type 35 (TRAP_DOOR) and needs to be handled directly + // Real Use of this GO is unknown, but this change of state is expected + if (GameObject* pBridge = instance->GetGameObject(m_uiBridgeGUID)) + pBridge->SetGoState(GO_STATE_READY); + } + // Remove this timer, as processed + m_mKeyInProgress.erase(itr++); + } + else + { + itr->second -= uiDiff; + ++itr; + } + } + } +} + InstanceData* GetInstanceData_instance_gundrak(Map* pMap) { return new instance_gundrak(pMap); @@ -274,7 +453,7 @@ void AddSC_instance_gundrak() pNewScript = new Script; pNewScript->Name = "go_gundrak_altar"; - pNewScript->pGOHello = &GOHello_go_gundrak_altar; + pNewScript->pGOUse = &GOUse_go_gundrak_altar; pNewScript->RegisterSelf(); pNewScript = new Script; diff --git a/scripts/northrend/howling_fjord.cpp b/scripts/northrend/howling_fjord.cpp index 3ab3e90be..24c31616c 100644 --- a/scripts/northrend/howling_fjord.cpp +++ b/scripts/northrend/howling_fjord.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,20 +17,130 @@ /* ScriptData SDName: Howling_Fjord SD%Complete: ? -SDComment: Quest support: 11221, 11483, 11300, 11464 +SDComment: Quest support: 11221, 11300, 11464, 11343 SDCategory: Howling Fjord EndScriptData */ /* ContentData +npc_ancient_male_vrykul +at_ancient_male_vrykul npc_daegarn npc_deathstalker_razael - TODO, can be moved to database npc_dark_ranger_lyana - TODO, can be moved to database -npc_mcgoyver - TODO, can be moved to database npc_silvermoon_harry EndContentData */ #include "precompiled.h" +enum +{ + SPELL_ECHO_OF_YMIRON = 42786, + SPELL_SECRET_OF_NIFFELVAR = 43458, + QUEST_ECHO_OF_YMIRON = 11343, + NPC_MALE_VRYKUL = 24314, + NPC_FEMALE_VRYKUL = 24315, + + SAY_VRYKUL_CURSED = -1000635, + EMOTE_VRYKUL_POINT = -1000636, + EMOTE_VRYKUL_SOB = -1000637, + SAY_VRYKUL_DISPOSE = -1000638, + SAY_VRYKUL_BEG = -1000639, + SAY_VRYKUL_WHAT = -1000640, + SAY_VRYKUL_HIDE = -1000641, +}; + +struct MANGOS_DLL_DECL npc_ancient_male_vrykulAI : public ScriptedAI +{ + npc_ancient_male_vrykulAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + + bool m_bEventInProgress; + uint32 m_uiPhase; + uint32 m_uiPhaseTimer; + + void Reset() + { + m_bEventInProgress = false; + m_uiPhase = 0; + m_uiPhaseTimer = 0; + } + + void StartEvent() + { + if (m_bEventInProgress) + return; + + m_bEventInProgress = true; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_bEventInProgress) + return; + + if (m_uiPhaseTimer < uiDiff) + m_uiPhaseTimer = 5000; + else + { + m_uiPhaseTimer -= uiDiff; + return; + } + + Creature* pFemale = GetClosestCreatureWithEntry(m_creature, NPC_FEMALE_VRYKUL, 10.0f); + + switch(m_uiPhase) + { + case 0: + DoScriptText(SAY_VRYKUL_CURSED, m_creature); + DoScriptText(EMOTE_VRYKUL_POINT, m_creature); + break; + case 1: + if (pFemale) + DoScriptText(EMOTE_VRYKUL_SOB, pFemale); + DoScriptText(SAY_VRYKUL_DISPOSE, m_creature); + break; + case 2: + if (pFemale) + DoScriptText(SAY_VRYKUL_BEG, pFemale); + break; + case 3: + DoScriptText(SAY_VRYKUL_WHAT, m_creature); + break; + case 4: + if (pFemale) + DoScriptText(SAY_VRYKUL_HIDE, pFemale); + break; + case 5: + DoCastSpellIfCan(m_creature, SPELL_SECRET_OF_NIFFELVAR); + break; + case 6: + Reset(); + return; + } + + ++m_uiPhase; + } +}; + +CreatureAI* GetAI_npc_ancient_male_vrykul(Creature* pCreature) +{ + return new npc_ancient_male_vrykulAI(pCreature); +} + +bool AreaTrigger_at_ancient_male_vrykul(Player* pPlayer, AreaTriggerEntry const* pAt) +{ + if (pPlayer->isAlive() && pPlayer->GetQuestStatus(QUEST_ECHO_OF_YMIRON) == QUEST_STATUS_INCOMPLETE && + pPlayer->HasAura(SPELL_ECHO_OF_YMIRON)) + { + if (Creature* pCreature = GetClosestCreatureWithEntry(pPlayer, NPC_MALE_VRYKUL, 20.0f)) + { + if (npc_ancient_male_vrykulAI* pVrykulAI = dynamic_cast(pCreature->AI())) + pVrykulAI->StartEvent(); + } + } + + return true; +} + /*###### ## npc_daegarn ######*/ @@ -93,7 +203,7 @@ struct MANGOS_DLL_DECL npc_daegarnAI : public ScriptedAI void SummonGladiator(uint32 uiEntry) { - m_creature->SummonCreature(uiEntry, afSummon[0], afSummon[1], afSummon[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30*IN_MILLISECONDS); + m_creature->SummonCreature(uiEntry, afSummon[0], afSummon[1], afSummon[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20*IN_MILLISECONDS); } void SummonedMovementInform(Creature* pSummoned, uint32 uiMotionType, uint32 uiPointId) @@ -230,63 +340,57 @@ bool GossipSelect_npc_dark_ranger_lyana(Player* pPlayer, Creature* pCreature, ui } /*###### -## npc_mcgoyver - TODO, can be moved to database +## npc_greer_orehammer ######*/ -#define GOSSIP_ITEM_MCGOYVER1 "Walt sent me to pick up some dark iron ingots." -#define GOSSIP_ITEM_MCGOYVER2 "Yarp." - enum { - QUEST_WE_CAN_REBUILD_IT = 11483, - GOSSIP_TEXTID_MCGOYVER = 12193, - ITEM_DARK_IRON_INGOTS = 34135, - SPELL_MCGOYVER_TAXI_EXPLORERSLEAGUE = 44280, - SPELL_MCGOYVER_CREATE_DARK_IRON_INGOTS = 44512 + GOSSIP_ITEM_TAXI = -3000106, + GOSSIP_ITEM_GET_BOMBS = -3000107, + GOSSIP_ITEM_FLIGHT = -3000108, + + QUEST_MISSION_PLAGUE_THIS = 11332, + ITEM_PRECISION_BOMBS = 33634, + TAXI_PATH_PLAGUE_THIS = 745, }; -bool GossipHello_npc_mcgoyver(Player* pPlayer, Creature* pCreature) +bool GossipHello_npc_greer_orehammer(Player* pPlayer, Creature* pCreature) { - switch(pPlayer->GetQuestStatus(QUEST_WE_CAN_REBUILD_IT)) + if (pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + + if (pPlayer->GetQuestStatus(QUEST_MISSION_PLAGUE_THIS) == QUEST_STATUS_INCOMPLETE) { - case QUEST_STATUS_INCOMPLETE: - if (!pPlayer->HasItemCount(ITEM_DARK_IRON_INGOTS, 1, true)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MCGOYVER1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); - } - else - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MCGOYVER2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_MCGOYVER, pCreature->GetGUID()); - } - break; - case QUEST_STATUS_COMPLETE: - if (!pPlayer->GetQuestRewardStatus(QUEST_WE_CAN_REBUILD_IT)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MCGOYVER2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_MCGOYVER, pCreature->GetGUID()); - break; - } - default: - pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + if (!pPlayer->HasItemCount(ITEM_PRECISION_BOMBS, 1, true)) + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_GET_BOMBS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); } + if (pCreature->isTaxi()) + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_TAXI, GOSSIP_ITEM_TAXI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + return true; } -bool GossipSelect_npc_mcgoyver(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +bool GossipSelect_npc_greer_orehammer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { switch(uiAction) { - case GOSSIP_ACTION_INFO_DEF+1: - pCreature->CastSpell(pPlayer, SPELL_MCGOYVER_CREATE_DARK_IRON_INGOTS, true); - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MCGOYVER2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_MCGOYVER, pCreature->GetGUID()); + case GOSSIP_ACTION_INFO_DEF + 1: + if (Item* pItem = pPlayer->StoreNewItemInInventorySlot(ITEM_PRECISION_BOMBS, 10)) + pPlayer->SendNewItem(pItem, 10, true, false); + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); break; - case GOSSIP_ACTION_INFO_DEF+2: + case GOSSIP_ACTION_INFO_DEF + 2: pPlayer->CLOSE_GOSSIP_MENU(); - pCreature->CastSpell(pPlayer, SPELL_MCGOYVER_TAXI_EXPLORERSLEAGUE, true); + pPlayer->ActivateTaxiPathTo(TAXI_PATH_PLAGUE_THIS); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + pPlayer->GetSession()->SendTaxiMenu(pCreature); break; } @@ -471,10 +575,20 @@ void AddSC_howling_fjord() { Script* pNewScript; + pNewScript = new Script; + pNewScript->Name = "npc_ancient_male_vrykul"; + pNewScript->GetAI = &GetAI_npc_ancient_male_vrykul; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "at_ancient_male_vrykul"; + pNewScript->pAreaTrigger = &AreaTrigger_at_ancient_male_vrykul; + pNewScript->RegisterSelf(); + pNewScript = new Script; pNewScript->Name = "npc_daegarn"; pNewScript->GetAI = &GetAI_npc_daegarn; - pNewScript->pQuestAccept = &QuestAccept_npc_daegarn; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_daegarn; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -490,9 +604,9 @@ void AddSC_howling_fjord() pNewScript->RegisterSelf(); pNewScript = new Script; - pNewScript->Name = "npc_mcgoyver"; - pNewScript->pGossipHello = &GossipHello_npc_mcgoyver; - pNewScript->pGossipSelect = &GossipSelect_npc_mcgoyver; + pNewScript->Name = "npc_greer_orehammer"; + pNewScript->pGossipHello = &GossipHello_npc_greer_orehammer; + pNewScript->pGossipSelect = &GossipSelect_npc_greer_orehammer; pNewScript->RegisterSelf(); pNewScript = new Script; diff --git a/scripts/northrend/icecrown.cpp b/scripts/northrend/icecrown.cpp index e85c1ae25..f406333f9 100644 --- a/scripts/northrend/icecrown.cpp +++ b/scripts/northrend/icecrown.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,95 +17,16 @@ /* ScriptData SDName: Icecrown SD%Complete: 100 -SDComment: Quest support: 12807, Vendor support: 34885 +SDComment: Vendor support: 34885 SDCategory: Icecrown EndScriptData */ /* ContentData -npc_arete npc_dame_evniki_kapsalis EndContentData */ #include "precompiled.h" -/*###### -## npc_arete -######*/ - -#define GOSSIP_ARETE_ITEM1 "Lord-Commander, I would hear your tale." -#define GOSSIP_ARETE_ITEM2 "" -#define GOSSIP_ARETE_ITEM3 "I thought that they now called themselves the Scarlet Onslaught?" -#define GOSSIP_ARETE_ITEM4 "Where did the grand admiral go?" -#define GOSSIP_ARETE_ITEM5 "That's fine. When do I start?" -#define GOSSIP_ARETE_ITEM6 "Let's finish this!" -#define GOSSIP_ARETE_ITEM7 "That's quite a tale, Lord-Commander." - -enum -{ - GOSSIP_TEXTID_ARETE1 = 13525, - GOSSIP_TEXTID_ARETE2 = 13526, - GOSSIP_TEXTID_ARETE3 = 13527, - GOSSIP_TEXTID_ARETE4 = 13528, - GOSSIP_TEXTID_ARETE5 = 13529, - GOSSIP_TEXTID_ARETE6 = 13530, - GOSSIP_TEXTID_ARETE7 = 13531, - - QUEST_THE_STORY_THUS_FAR = 12807 -}; - -bool GossipHello_npc_arete(Player* pPlayer, Creature* pCreature) -{ - if (pCreature->isQuestGiver()) - pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - - if (pPlayer->GetQuestStatus(QUEST_THE_STORY_THUS_FAR) == QUEST_STATUS_INCOMPLETE) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE1, pCreature->GetGUID()); - return true; - } - - pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); - return true; -} - -bool GossipSelect_npc_arete(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) -{ - switch(uiAction) - { - case GOSSIP_ACTION_INFO_DEF+1: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE2, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE3, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE4, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE5, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE6, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE7, pCreature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - pPlayer->CLOSE_GOSSIP_MENU(); - pPlayer->AreaExploredOrEventHappens(QUEST_THE_STORY_THUS_FAR); - break; - } - - return true; -} - /*###### ## npc_dame_evniki_kapsalis ######*/ @@ -135,12 +56,6 @@ void AddSC_icecrown() { Script* newscript; - newscript = new Script; - newscript->Name = "npc_arete"; - newscript->pGossipHello = &GossipHello_npc_arete; - newscript->pGossipSelect = &GossipSelect_npc_arete; - newscript->RegisterSelf(); - newscript = new Script; newscript->Name = "npc_dame_evniki_kapsalis"; newscript->pGossipHello = &GossipHello_npc_dame_evniki_kapsalis; diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_bronjahm.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_bronjahm.cpp index 83c387875..164d52cf2 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_bronjahm.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_bronjahm.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,70 +16,211 @@ /* ScriptData SDName: boss_bronjahm -SD%Complete: 0% -SDComment: Placeholder -SDCategory: The Forge of Souls +SD%Complete: 10% +SDComment: by /dev/rsa +SDCategory: Icecrown - forge of souls EndScriptData */ #include "precompiled.h" #include "forge_of_souls.h" -enum +enum BossSpells { - SAY_AGGRO_1 = -1632000, // without sound, really correct? - SAY_AGGRO_2 = -1632001, - SAY_SLAY_1 = -1632002, - SAY_SLAY_2 = -1632003, - SAY_DEATH = -1632004, - SAY_SOULSTORM = -1632005, - SAY_CORRUPT_SOUL = -1632006, + //common + SPELL_BERSERK = 47008, + //yells + //summons + NPC_SOUL_FRAGMENT = 36535, + //Abilities + SPELL_MAGIC_BANE = 68793, + SPELL_CORRUPT_SOUL = 68839, + SPELL_CONSUME_SOUL = 68858, + SPELL_TELEPORT = 68988, + SPELL_SOULSTORM = 68872, + SPELL_SOULSTORM_2 = 68921, + SPELL_FEAR = 68950, + SPELL_SHADOW_BOLT = 70043, + + /*Music*/ + Battle01 = 6077, + Battle02 = 6078, + Battle03 = 6079, + }; -struct MANGOS_DLL_DECL boss_bronjahmAI : public ScriptedAI +struct MANGOS_DLL_DECL boss_bronjahmAI : public BSWScriptedAI { - boss_bronjahmAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_bronjahmAI(Creature* pCreature) : BSWScriptedAI(pCreature) { - m_pInstance = (instance_forge_of_souls*)pCreature->GetInstanceData(); - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } - instance_forge_of_souls* m_pInstance; - bool m_bIsRegularMode; + ScriptedInstance *pInstance; + uint8 stage; + uint32 BattleMusicTimer; + uint32 Music; void Reset() { + if(pInstance) pInstance->SetData(TYPE_BRONJAHM, NOT_STARTED); + resetTimers(); + stage = 0; + } + + void Aggro(Unit *who) + { + Music = (urand(0, 2)); + switch(Music) + { + case 0: + m_creature->PlayDirectSound(Battle01); + BattleMusicTimer = 48000; + break; + case 1: + m_creature->PlayDirectSound(Battle02); + BattleMusicTimer = 27000; + break; + case 2: + m_creature->PlayDirectSound(Battle03); + BattleMusicTimer = 36000; + break; + } + + if(pInstance) pInstance->SetData(TYPE_BRONJAHM, IN_PROGRESS); + DoScriptText(-1632001,m_creature,who); + SetCombatMovement(true); } - void Aggro(Unit* pWho) + void JustDied(Unit *killer) { - DoScriptText(urand(0, 1) ? SAY_AGGRO_1 : SAY_AGGRO_2, m_creature); - if (m_pInstance) - m_pInstance->SetData(TYPE_BRONJAHM, IN_PROGRESS); + if(pInstance) pInstance->SetData(TYPE_BRONJAHM, DONE); + doRemove(SPELL_SOULSTORM); + DoScriptText(-1632004,m_creature,killer); } void KilledUnit(Unit* pVictim) { - if (pVictim->GetTypeId() != TYPEID_PLAYER) + switch (urand(0,1)) { + case 0: + DoScriptText(-1632002,m_creature,pVictim); + break; + case 1: + DoScriptText(-1632003,m_creature,pVictim); + break; + }; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (urand(0, 1)) - DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); + switch(stage) + { + case 0: + if (timedQuery(SPELL_CORRUPT_SOUL, diff)) + { + if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (doCast(SPELL_CORRUPT_SOUL, pTarget) == CAST_OK) + { + DoScriptText(-1632006,m_creature,pTarget); + float fPosX, fPosY, fPosZ; + pTarget->GetPosition(fPosX, fPosY, fPosZ); + doSummon(NPC_SOUL_FRAGMENT,fPosX, fPosY, fPosZ); + } + } + } + break; + case 1: + if (timedCast(SPELL_TELEPORT, diff) == CAST_OK) stage = 2; + break; + case 2: + if (timedCast(SPELL_SOULSTORM, diff) == CAST_OK) { + DoScriptText(-1632005,m_creature); + SetCombatMovement(false); + stage = 3; + } + break; + case 3: + timedCast(SPELL_FEAR, diff); + break; + } + + timedCast(SPELL_SHADOW_BOLT, diff); + + timedCast(SPELL_MAGIC_BANE, diff); + + if (m_creature->GetHealthPercent() <= 30.0f && stage == 0) stage = 1; + + DoMeleeAttackIfReady(); + + if (BattleMusicTimer < diff && m_creature->isAlive()) + { + switch(Music) + { + case 0: + m_creature->PlayDirectSound(Battle01); + BattleMusicTimer = 49000; + break; + case 1: + m_creature->PlayDirectSound(Battle02); + BattleMusicTimer = 28000; + break; + case 2: + m_creature->PlayDirectSound(Battle03); + BattleMusicTimer = 37000; + break; + } + } else BattleMusicTimer -= diff; + } +}; + +struct MANGOS_DLL_DECL mob_soul_fragmentAI : public ScriptedAI +{ + mob_soul_fragmentAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); } - void JustDied(Unit* pKiller) + ScriptedInstance *m_pInstance; + Creature* pBoss; + uint32 m_uiRangeCheck_Timer; + + void Reset() { - DoScriptText(SAY_DEATH, m_creature); + m_uiRangeCheck_Timer = 1000; + if (!m_pInstance) return; + pBoss = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRONJAHM)); + m_creature->SetSpeedRate(MOVE_RUN, 0.2f); + m_creature->GetMotionMaster()->MoveChase(pBoss); + m_creature->SetRespawnDelay(DAY); + } - if (m_pInstance) - m_pInstance->SetData(TYPE_BRONJAHM, DONE); + void AttackStart(Unit* pWho) + { + return; } - void JustReachedHome() + void UpdateAI(const uint32 uiDiff) { - if (m_pInstance) - m_pInstance->SetData(TYPE_BRONJAHM, NOT_STARTED); + if (!m_pInstance || m_pInstance->GetData(TYPE_BRONJAHM) != IN_PROGRESS ) m_creature->ForcedDespawn(); + + if (m_uiRangeCheck_Timer < uiDiff) + { + if (pBoss->IsWithinDistInMap(m_creature, 2.0f)) + { + pBoss->CastSpell(pBoss, SPELL_CONSUME_SOUL, false); + m_creature->ForcedDespawn(); + } else m_creature->GetMotionMaster()->MoveChase(pBoss); + + m_uiRangeCheck_Timer = 1000; + } + else m_uiRangeCheck_Timer -= uiDiff; } + }; CreatureAI* GetAI_boss_bronjahm(Creature* pCreature) @@ -87,12 +228,23 @@ CreatureAI* GetAI_boss_bronjahm(Creature* pCreature) return new boss_bronjahmAI(pCreature); } +CreatureAI* GetAI_mob_soul_fragment(Creature* pCreature) +{ + return new mob_soul_fragmentAI (pCreature); +} + + void AddSC_boss_bronjahm() { - Script* pNewScript; + Script *newscript; + newscript = new Script; + newscript->Name = "boss_bronjahm"; + newscript->GetAI = &GetAI_boss_bronjahm; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_soul_fragment"; + newscript->GetAI = &GetAI_mob_soul_fragment; + newscript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "boss_bronjahm"; - pNewScript->GetAI = &GetAI_boss_bronjahm; - pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp index 2f54fa51b..972787886 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_devourer_of_souls -SD%Complete: 0% -SDComment: Placeholder +SD%Complete: 100% +SDComment: MaxXx2021, modified by /dev/rsa SDCategory: The Forge of Souls EndScriptData */ @@ -26,95 +26,396 @@ EndScriptData */ enum { - // TODO, how to change the face on random?, how to know which face is shown, to use the additional entries - SAY_MALE_1_AGGRO = -1632007, - SAY_FEMALE_AGGRO = -1632008, - SAY_MALE_1_SLAY_1 = -1632009, - SAY_FEMALE_SLAY_1 = -1632010, - SAY_MALE_2_SLAY_1 = -1632011, - SAY_MALE_1_SLAY_2 = -1632012, - SAY_FEMALE_SLAY_2 = -1632013, - SAY_MALE_2_SLAY_2 = -1632014, - SAY_MALE_1_DEATH = -1632015, - SAY_FEMALE_DEATH = -1632016, - SAY_MALE_2_DEATH = -1632017, - SAY_MALE_1_SOUL_ATTACK = -1632018, - SAY_FEMALE_SOUL_ATTACK = -1632019, - SAY_MALE_2_SOUL_ATTACK = -1632020, - SAY_MALE_1_DARK_GLARE = -1632021, - SAY_FEMALE_DARK_GLARE = -1632022, - - EMOTE_MIRRORED_SOUL = -1632023, - EMOTE_UNLEASH_SOULS = -1632024, - EMOTE_WAILING_SOULS = -1632025, - - FACE_NORMAL = 0, - FACE_UNLEASHING = 1, - FACE_WAILING = 2, + /*Speach*/ + SAY_DEVOURER_AGGRO_MALE_01 = -1632010, + SAY_DEVOURER_SLAY_01_MALE_01 = -1632012, + SAY_DEVOURER_SLAY_02_MALE_01 = -1632015, + SAY_DEVOURER_DEATH_MALE_01 = -1632018, + SAY_DEVOURER_SUMMON_MALE_01 = -1632023, + SAY_DEVOURER_DARK_MALE_01 = -1632027, + SAY_DEVOURER_MIRRORED_SOUL = -1632021, + SAY_DEVOURER_UNLEASHED_SOULS = -1632022, + SAY_DEVOURER_WELL_OF_SOULS = -1632026, + + SAY_JAINA_FS09_EXTRO = -1632029, + SAY_SYLVANA_FS07_EXTRO = -1632030, + + /*Spell And Visual Effects*/ + SPELL_PHANTOM_BLAST = 68982, + SPELL_MIRRORED_SOUL = 69051, + SPELL_WELL_OF_SOULS = 68820, + SPELL_UNLEASHED_SOULS = 68939, + SPELL_WAILING_SOULS = 68912, //68873 + SPELL_WELL_OF_SOULS_VIS = 68854, + SPELL_WELL_OF_SOUL_DM = 68863, + + /*Units*/ + NPC_WELL_OF_SOUL = 36536, + NPC_UNLEASHED_SOUL = 36595, + + /*Others*/ + MODEL_FAT = 30149, + MODEL_WOMAN = 30150, + + /*Music*/ + Battle01 = 6077, + Battle02 = 6078, + Battle03 = 6079, + + MAX_POINTS = 22, }; -static const int aTexts[6][3] = +static Locations SpawnLoc[]= { - {SAY_MALE_1_AGGRO, SAY_FEMALE_AGGRO, 0}, // 0 - aggro - {SAY_MALE_1_SLAY_1, SAY_FEMALE_SLAY_1, SAY_MALE_2_SLAY_1}, // 1 - slay1 - {SAY_MALE_1_SLAY_2, SAY_FEMALE_SLAY_2, SAY_MALE_2_SLAY_2}, // 2 - slay2 - {SAY_MALE_1_DEATH, SAY_FEMALE_DEATH, SAY_MALE_2_DEATH}, // 3 - death - {SAY_MALE_1_SOUL_ATTACK, SAY_FEMALE_SOUL_ATTACK, SAY_MALE_2_SOUL_ATTACK}, // 4 - soul - {SAY_MALE_1_DARK_GLARE, SAY_FEMALE_DARK_GLARE, 0} // 5 - glare +{5618.139f, 2451.873f, 705.854f}, //0 - spawn +{5590.47f, 2427.79f, 705.935f}, +{5593.59f, 2428.34f, 705.935f}, +{5600.81f, 2429.31f, 705.935f}, +{5600.81f, 2421.12f, 705.935f}, +{5601.43f, 2426.53f, 705.935f}, +{5601.55f, 2418.36f, 705.935f}, +{5598.0f, 2429.14f, 705.935f}, +{5594.04f, 2424.87f, 705.935f}, +{5597.89f, 2421.54f, 705.935f}, +{5598.57f, 2434.62f, 705.935f}, +{5585.46f, 2417.99f, 705.935f}, +{5605.81f, 2428.42f, 705.935f}, +{5591.61f, 2412.66f, 705.935f}, +{5593.9f, 2410.64f, 705.935f}, +{5586.76f, 2416.73f, 705.935f}, +{5592.23f, 2419.14f, 705.935f}, +{5594.61f, 2416.87f, 705.935f}, +{5589.77f, 2421.03f, 705.935f}, +{5602.58f, 2435.95f, 705.935f}, +{5606.13f, 2433.16f, 705.935f}, +{5606.12f, 2436.6f, 705.935f}, //21 }; + + struct MANGOS_DLL_DECL boss_devourer_of_soulsAI : public ScriptedAI { - boss_devourer_of_soulsAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_devourer_of_soulsAI(Creature *pCreature) : ScriptedAI(pCreature) { - m_pInstance = (instance_forge_of_souls*)pCreature->GetInstanceData(); - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } - instance_forge_of_souls* m_pInstance; - uint8 m_uiFace; - bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint32 BattleMusicTimer; + uint32 PhantomBlastTimer; + uint32 SummonTimer; + uint32 WellOfSoulTimer; + uint32 MirroredTimer; + uint32 SoulBeamTimer; + uint32 Step; + uint32 StepTimer; + bool Summon; void Reset() { - m_uiFace = FACE_NORMAL; + if(!m_pInstance) return; + m_pInstance->SetData(TYPE_DEVOURER, NOT_STARTED); + DespawnAllSummons(); + Summon = false; + Step = 0; + StepTimer = 100; + PhantomBlastTimer = 5000; + WellOfSoulTimer = 12000; + SummonTimer = 20000; + MirroredTimer = 28000; + SoulBeamTimer = 33000; } - void Aggro(Unit* pWho) + void Aggro(Unit *who) { - DoScriptText(aTexts[0][m_uiFace], m_creature); - if (m_pInstance) - m_pInstance->SetData(TYPE_DECOURER_OF_SOULS, IN_PROGRESS); + if(!m_pInstance) return; + m_pInstance->SetData(TYPE_DEVOURER, IN_PROGRESS); + m_creature->PlayDirectSound(Battle01); + BattleMusicTimer = 48000; + DoScriptText(SAY_DEVOURER_AGGRO_MALE_01, m_creature); } - void KilledUnit(Unit* pVictim) + void DespawnAllSummons() { - if (pVictim->GetTypeId() != TYPEID_PLAYER) - return; + std::list m_pSouls; + GetCreatureListWithEntryInGrid(m_pSouls, m_creature, NPC_UNLEASHED_SOUL, DEFAULT_VISIBILITY_INSTANCE); + + if (!m_pSouls.empty()) + for(std::list::iterator itr = m_pSouls.begin(); itr != m_pSouls.end(); ++itr) + { + (*itr)->ForcedDespawn(); + } + + std::list m_pWells; + GetCreatureListWithEntryInGrid(m_pWells, m_creature, NPC_WELL_OF_SOUL, DEFAULT_VISIBILITY_INSTANCE); - if (urand(0, 1)) - DoScriptText(aTexts[urand(1, 2)][m_uiFace], m_creature); + if (!m_pWells.empty()) + for(std::list::iterator iter = m_pWells.begin(); iter != m_pWells.end(); ++iter) + { + (*iter)->ForcedDespawn(); + } + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + + Map *map = m_creature->GetMap(); + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_MIRRORED_SOUL)) + m_creature->DealDamage(i->getSource(), uiDamage/2,NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + void SpawnOutro(uint32 guid) + { + if (Creature *pSummon = m_creature->SummonCreature(guid, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z,0, TEMPSUMMON_TIMED_DESPAWN, 300000)) + { + uint8 i = urand(1,MAX_POINTS); + + pSummon->GetMotionMaster()->MovePoint(i, SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z); + + if (pSummon->GetEntry() == npc_jaina_extro) + DoScriptText(SAY_JAINA_FS09_EXTRO, pSummon); + else if (pSummon->GetEntry() == npc_sylvana_extro) + DoScriptText(SAY_SYLVANA_FS07_EXTRO, pSummon); + } } void JustDied(Unit* pKiller) { - DoScriptText(aTexts[3][m_uiFace], m_creature); + if(!m_pInstance) return; + m_pInstance->SetData(TYPE_DEVOURER, DONE); + DoScriptText(SAY_DEVOURER_DEATH_MALE_01, m_creature); + DespawnAllSummons(); - if (m_pInstance) + Player* player = (Player*)pKiller; + + if(player->GetTeam() == ALLIANCE) + { + m_pInstance->SetData64(DATA_LIDER,0); + SpawnOutro(npc_jaina_extro); + SpawnOutro(npc_jaina_credit); + SpawnOutro(npc_mage); + SpawnOutro(npc_mage_woman); + SpawnOutro(npc_cc_a_01); + SpawnOutro(npc_cc_a_02); + SpawnOutro(npc_cc_a_03); + + } else + { + m_pInstance->SetData64(DATA_LIDER,1); + SpawnOutro(npc_sylvana_extro); + SpawnOutro(npc_sylvana_credit); + SpawnOutro(npc_mage); + SpawnOutro(npc_mage_woman); + SpawnOutro(npc_cc_h_01); + SpawnOutro(npc_cc_h_02); + SpawnOutro(npc_cc_h_03); + }; + } + + void KilledUnit(Unit* victim) + { + switch (urand(0,1)) { - m_pInstance->SetData(TYPE_DECOURER_OF_SOULS, DONE); + case 0: DoScriptText(SAY_DEVOURER_SLAY_01_MALE_01, m_creature); break; + case 1: DoScriptText(SAY_DEVOURER_SLAY_02_MALE_01, m_creature); break; } } - void JustReachedHome() + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(Summon != true) + { + if (PhantomBlastTimer < diff) + { + if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(Target, SPELL_PHANTOM_BLAST); + PhantomBlastTimer = 8000; + } + else + PhantomBlastTimer -= diff; + + if (WellOfSoulTimer < diff) + { + if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(Target, SPELL_WELL_OF_SOULS); + DoScriptText(SAY_DEVOURER_WELL_OF_SOULS, m_creature); + WellOfSoulTimer = urand(12000,24000); + } + else + WellOfSoulTimer -= diff; + + if (SummonTimer < diff) + { + m_creature->InterruptNonMeleeSpells(false); + switch (urand(0,1)) + { + case 0: DoScriptText(SAY_DEVOURER_SUMMON_MALE_01, m_creature); break; + case 1: DoScriptText(SAY_DEVOURER_UNLEASHED_SOULS, m_creature); break; + } + DoCast(m_creature, SPELL_UNLEASHED_SOULS); + SummonTimer = 50000; + Summon = true; + } + else + SummonTimer -= diff; + + if (MirroredTimer < diff) + { + if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + DoCast(Target, SPELL_MIRRORED_SOUL); + DoScriptText(SAY_DEVOURER_MIRRORED_SOUL, m_creature); + MirroredTimer = 25000; + } + } + else + MirroredTimer -= diff; + + if (SoulBeamTimer < diff) + { + DoScriptText(SAY_DEVOURER_DARK_MALE_01, m_creature); + DoCast(m_creature->getVictim(), SPELL_WAILING_SOULS); + SoulBeamTimer = (urand(35000, 45000)); + } + else + SoulBeamTimer -= diff; + + } + + if(Summon == true) + { + if (StepTimer < diff) + { + switch(Step) + { + case 0: + StepTimer = 900; + ++Step; + break; + case 1: + m_creature->SetDisplayId(MODEL_FAT); //this is huck, because this spell (SPELL_UNLEASHED_SOULS) morphed boss into PIG :D + StepTimer = 2000; + ++Step; + break; + case 2: + Summon = false; + Step = 0; + StepTimer = 100; + break; + } + } else StepTimer -= diff; + + } + + DoMeleeAttackIfReady(); + + if (BattleMusicTimer < diff && m_creature->isAlive()) + { + m_creature->PlayDirectSound(Battle01); + BattleMusicTimer = 49000; + } + else + BattleMusicTimer -= diff; + + return; + } +}; + +struct MANGOS_DLL_DECL npc_well_of_soulAI : public ScriptedAI +{ + npc_well_of_soulAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + +ScriptedInstance* m_pInstance; + +uint32 DamageTimer; +uint32 DeathTimer; + + void Reset() + { + m_creature->SetLevel(80); + m_creature->setFaction(14); + m_creature->SetDisplayId(11686); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DeathTimer = 60000; + DoCast(m_creature, SPELL_WELL_OF_SOULS_VIS); + DamageTimer = 1000; + } + + void AttackStart(Unit* who) + { + return; + } + + void UpdateAI(const uint32 diff) + { + if(!m_pInstance) return; + + if(m_pInstance && m_pInstance->GetData(TYPE_DEVOURER) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (DeathTimer < diff) + { + m_creature->ForcedDespawn(); + } else DeathTimer -= diff; + + if (DamageTimer < diff) + { + DoCast(m_creature, SPELL_WELL_OF_SOUL_DM); + DamageTimer = 1000; + } else DamageTimer -= diff; + + return; + } +}; + +struct MANGOS_DLL_DECL npc_unleashed_soulAI : public ScriptedAI +{ + npc_unleashed_soulAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() { if (m_pInstance) { - m_pInstance->SetData(NPC_DEVOURER_OF_SOULS, NOT_STARTED); - // If we previously failed, set such that possible to try again - m_pInstance->SetData(TYPE_ACHIEV_PHANTOM_BLAST, IN_PROGRESS); + if (Creature* pDevourer = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_DEVOURER))) + if (pDevourer && pDevourer->isAlive()) + AttackStart(pDevourer->getVictim()); } + + } + + void UpdateAI(const uint32 diff) + { + if(!m_pInstance) return; + + if(m_pInstance && m_pInstance->GetData(TYPE_DEVOURER) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } }; @@ -123,12 +424,32 @@ CreatureAI* GetAI_boss_devourer_of_souls(Creature* pCreature) return new boss_devourer_of_soulsAI(pCreature); } +CreatureAI* GetAI_npc_well_of_soul(Creature* pCreature) +{ + return new npc_well_of_soulAI(pCreature); +} + +CreatureAI* GetAI_npc_unleashed_soul(Creature* pCreature) +{ + return new npc_unleashed_soulAI(pCreature); +} + void AddSC_boss_devourer_of_souls() { - Script* pNewScript; + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_devourer_of_souls"; + newscript->GetAI = &GetAI_boss_devourer_of_souls; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_well_of_soul"; + newscript->GetAI = &GetAI_npc_well_of_soul; + newscript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "boss_devourer_of_souls"; - pNewScript->GetAI = &GetAI_boss_devourer_of_souls; - pNewScript->RegisterSelf(); + newscript = new Script; + newscript->Name = "npc_unleashed_soul"; + newscript->GetAI = &GetAI_npc_unleashed_soul; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp new file mode 100644 index 000000000..bfe8d2fe8 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp @@ -0,0 +1,537 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Forge Of The Souls +SD%Complete: 90% +SDComment: event script! Need Add 6 Coliseum Champion after devourer death. +SDCategory: forge_of_the_souls +SDAuthor: MaxXx2021 aka Mioka +EndScriptData */ + +#include "precompiled.h" +#include "forge_of_souls.h" + +enum +{ + SAY_JAINA_FS01 = -1632040, + SAY_JAINA_FS02 = -1632041, + SAY_JAINA_FS03 = -1632042, + SAY_JAINA_FS04 = -1632043, + SAY_JAINA_FS05 = -1632044, + SAY_JAINA_FS06 = -1632045, + SAY_JAINA_FS07 = -1632046, + SAY_JAINA_FS08 = -1632047, + SAY_JAINA_FS09_EXTRO = -1632029, + + SAY_SYLVANA_FS01 = -1632050, + SAY_SYLVANA_FS02 = -1632051, + SAY_SYLVANA_FS03 = -1632052, + SAY_SYLVANA_FS04 = -1632053, + SAY_SYLVANA_FS05 = -1632054, + SAY_SYLVANA_FS06 = -1632055, + SAY_SYLVANA_FS07_EXTRO = -1632030, + + GOSSIP_SPEECHINTRO = 13525, +}; + +struct MANGOS_DLL_DECL npc_jaina_and_sylvana_FSintroAI : public ScriptedAI +{ + npc_jaina_and_sylvana_FSintroAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + +ScriptedInstance* m_pInstance; + +uint32 StepTimer; +uint32 Step; +bool StartEvent; + + void Reset() + { + if(m_pInstance) + if(m_pInstance->GetData(TYPE_DEVOURER) == DONE) + m_creature->SetVisibility(VISIBILITY_OFF); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + Step = 0; + StepTimer = 100; + if(m_pInstance->GetData(TYPE_INTRO) == DONE) + { + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + Step = 8; + } + } + + void UpdateAI(const uint32 diff) + { + DoMeleeAttackIfReady(); + + if(!m_pInstance) return; + + if(StartEvent != true) return; + + if(StepTimer < diff) + { + switch(Step) + { + case 0: + m_pInstance->SetData(TYPE_INTRO, DONE); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS01, m_creature); + StepTimer = 7000; + } + if(m_creature->GetEntry() == npc_sylvana) + StepTimer = 100; + ++Step; + break; + case 1: + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS02, m_creature); + StepTimer = 9000; + } + if(m_creature->GetEntry() == npc_sylvana) + { + DoScriptText(SAY_SYLVANA_FS01, m_creature); + StepTimer = 12000; + } + ++Step; + break; + case 2: + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS03, m_creature); + StepTimer = 8000; + } + if(m_creature->GetEntry() == npc_sylvana) + { + DoScriptText(SAY_SYLVANA_FS02, m_creature); + StepTimer = 11000; + } + ++Step; + break; + case 3: + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS04, m_creature); + StepTimer = 10000; + } + if(m_creature->GetEntry() == npc_sylvana) + { + DoScriptText(SAY_SYLVANA_FS03, m_creature); + StepTimer = 11000; + } + ++Step; + break; + case 4: + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS05, m_creature); + StepTimer = 8000; + } + if(m_creature->GetEntry() == npc_sylvana) + { + DoScriptText(SAY_SYLVANA_FS04, m_creature); + StepTimer = 12000; + } + ++Step; + break; + case 5: + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS06, m_creature); + StepTimer = 12000; + } + if(m_creature->GetEntry() == npc_sylvana) + { + DoScriptText(SAY_SYLVANA_FS05, m_creature); + StepTimer = 7000; + } + ++Step; + break; + case 6: + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS07, m_creature); + StepTimer = 7000; + } + if(m_creature->GetEntry() == npc_sylvana) + { + DoScriptText(SAY_SYLVANA_FS06, m_creature); + StepTimer = 4000; + } + ++Step; + break; + case 7: + if(m_creature->GetEntry() == npc_jaina) + { + DoScriptText(SAY_JAINA_FS08, m_creature); + StepTimer = 5000; + } + ++Step; + break; + } + } else StepTimer -= diff; + } +}; + +bool GossipHello_npc_jaina_and_sylvana_FSintro(Player* pPlayer, Creature* pCreature) +{ + if (pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu( pCreature->GetGUID()); + switch(pCreature->GetEntry()) + { + case 37597: + if(((npc_jaina_and_sylvana_FSintroAI*)pCreature->AI())->StartEvent != true) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "What would you have of me, My Lady?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + break; + case 37596: + if(((npc_jaina_and_sylvana_FSintroAI*)pCreature->AI())->StartEvent != true) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "What would you have of me, Banshee Queen?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + break; + } + + pPlayer->PlayerTalkClass->SendGossipMenu(907,pCreature->GetGUID()); //907 + return true; +} + +bool GossipSelect_npc_jaina_and_sylvana_FSintro(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + pPlayer->CLOSE_GOSSIP_MENU(); + ((npc_jaina_and_sylvana_FSintroAI*)pCreature->AI())->StartEvent = true; + + return true; +} + +struct MANGOS_DLL_DECL npc_jaina_and_sylvana_FSextroAI : public ScriptedAI +{ + npc_jaina_and_sylvana_FSextroAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + +ScriptedInstance* m_pInstance; + +uint32 StepTimer; +uint32 Step; +uint64 m_uiLiderGUID; +uint32 uiSummon_counter; + + void Reset() + { + if (m_pInstance) + if (m_pInstance->GetData(TYPE_DEVOURER) != DONE) + { + m_pInstance->SetData(TYPE_DEVOURER, NOT_STARTED); + Step = 0; + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } else Step = 10; + StepTimer = 100; + m_creature->SetVisibility(VISIBILITY_OFF); + } + + void UpdateAI(const uint32 diff) + { + DoMeleeAttackIfReady(); + + if (!m_pInstance) return; + + if (m_pInstance->GetData(TYPE_DEVOURER) == DONE) + { + + if(m_pInstance->GetData64(DATA_LIDER) == 1 && m_creature->GetEntry() == npc_sylvana_extro) return; + + if(m_pInstance->GetData64(DATA_LIDER) == 2 && m_creature->GetEntry() == npc_jaina_extro) return; + + if(StepTimer < diff) + { + switch(Step) + { + case 0: + m_creature->SetVisibility(VISIBILITY_ON); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MovePoint(0, 5653.337f, 2496.407f, 708.829f); + uiSummon_counter = 0; + StepTimer = 400; + ++Step; + break; + case 1: + if(m_creature->GetEntry() == npc_jaina_extro) + { + StepTimer = 100; + if (uiSummon_counter < 4) + { + if (Creature* pTemp = m_creature->SummonCreature(npc_cc_a_01,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + switch(uiSummon_counter) + { + case 0: + pTemp->GetMotionMaster()->MovePoint(0, 5659.251f, 2472.017f, 708.696f); + break; + case 1: + pTemp->GetMotionMaster()->MovePoint(0, 5627.611f, 2501.972f, 708.696f); + break; + case 2: + pTemp->GetMotionMaster()->MovePoint(0, 5680.920f, 2482.998f, 708.696f); + break; + case 3: + pTemp->GetMotionMaster()->MovePoint(0, 5641.398f, 2523.911f, 708.696f); + break; + } + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + Step++; + } + } + if(m_creature->GetEntry() == npc_sylvana_extro) + { + StepTimer = 100; + if (uiSummon_counter < 4) + { + if (Creature* pTemp = m_creature->SummonCreature(npc_cc_h_01,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + switch(uiSummon_counter) + { + case 0: + pTemp->GetMotionMaster()->MovePoint(0, 5659.251f, 2472.017f, 708.696f); + break; + case 1: + pTemp->GetMotionMaster()->MovePoint(0, 5627.611f, 2501.972f, 708.696f); + break; + case 2: + pTemp->GetMotionMaster()->MovePoint(0, 5680.920f, 2482.998f, 708.696f); + break; + case 3: + pTemp->GetMotionMaster()->MovePoint(0, 5641.398f, 2523.911f, 708.696f); + break; + } + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + Step++; + } + } + break; + case 2: + if(m_creature->GetEntry() == npc_jaina_extro) + { + StepTimer = 100; + if (uiSummon_counter < 4) + { + if (Creature* pTemp = m_creature->SummonCreature(npc_cc_a_02,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + switch(uiSummon_counter) + { + case 0: + pTemp->GetMotionMaster()->MovePoint(0, 5661.508f, 2473.066f, 708.696f); + break; + case 1: + pTemp->GetMotionMaster()->MovePoint(0, 5627.146f, 2499.098f, 708.696f); + break; + case 2: + pTemp->GetMotionMaster()->MovePoint(0, 5682.331f, 2485.985f, 708.696f); + break; + case 3: + pTemp->GetMotionMaster()->MovePoint(0, 5639.636f, 2521.228f, 708.696f); + break; + } + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + Step++; + } + } + if(m_creature->GetEntry() == npc_sylvana_extro) + { + StepTimer = 100; + if (uiSummon_counter < 4) + { + if (Creature* pTemp = m_creature->SummonCreature(npc_cc_h_02,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + switch(uiSummon_counter) + { + case 0: + pTemp->GetMotionMaster()->MovePoint(0, 5661.508f, 2473.066f, 708.696f); + break; + case 1: + pTemp->GetMotionMaster()->MovePoint(0, 5627.146f, 2499.098f, 708.696f); + break; + case 2: + pTemp->GetMotionMaster()->MovePoint(0, 5682.331f, 2485.985f, 708.696f); + break; + case 3: + pTemp->GetMotionMaster()->MovePoint(0, 5639.636f, 2521.228f, 708.696f); + break; + } + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + Step++; + } + } + break; + case 3: + if(m_creature->GetEntry() == npc_jaina_extro) + { + StepTimer = 100; + if (uiSummon_counter < 4) + { + if (Creature* pTemp = m_creature->SummonCreature(npc_cc_a_03,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + switch(uiSummon_counter) + { + case 0: + pTemp->GetMotionMaster()->MovePoint(0, 5664.265f, 2473.974f, 708.696f); + break; + case 1: + pTemp->GetMotionMaster()->MovePoint(0, 5626.768f, 2496.534f, 708.696f); + break; + case 2: + pTemp->GetMotionMaster()->MovePoint(0, 5683.696f, 2489.598f, 708.696f); + break; + case 3: + pTemp->GetMotionMaster()->MovePoint(0, 5637.580f, 2518.249f, 708.696f); + break; + } + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + StepTimer = 8000; + Step++; + } + } + if(m_creature->GetEntry() == npc_sylvana_extro) + { + StepTimer = 100; + if (uiSummon_counter < 4) + { + if (Creature* pTemp = m_creature->SummonCreature(npc_cc_h_03,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000)) + { + pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + switch(uiSummon_counter) + { + case 0: + pTemp->GetMotionMaster()->MovePoint(0, 5664.265f, 2473.974f, 708.696f); + break; + case 1: + pTemp->GetMotionMaster()->MovePoint(0, 5626.768f, 2496.534f, 708.696f); + break; + case 2: + pTemp->GetMotionMaster()->MovePoint(0, 5683.696f, 2489.598f, 708.696f); + break; + case 3: + pTemp->GetMotionMaster()->MovePoint(0, 5637.580f, 2518.249f, 708.696f); + break; + } + uiSummon_counter++; + } + } + else + { + uiSummon_counter = 0; + StepTimer = 8000; + Step++; + } + } + break; + case 4: + if(m_creature->GetEntry() == npc_jaina_extro) + { + DoScriptText(SAY_JAINA_FS09_EXTRO, m_creature); + StepTimer = 6000; + } + if(m_creature->GetEntry() == npc_sylvana_extro) + { + DoScriptText(SAY_SYLVANA_FS07_EXTRO, m_creature); + StepTimer = 3000; + } + ++Step; + break; + case 5: + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + ++Step; + break; + } + } else StepTimer -= diff; + } + return; + } +}; + +CreatureAI* GetAI_npc_jaina_and_sylvana_FSintro(Creature* pCreature) +{ + return new npc_jaina_and_sylvana_FSintroAI(pCreature); +} + +CreatureAI* GetAI_npc_jaina_and_sylvana_FSextro(Creature* pCreature) +{ + return new npc_jaina_and_sylvana_FSextroAI(pCreature); +} + +void AddSC_forge_of_souls() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_jaina_and_sylvana_FSintro"; + newscript->GetAI = &GetAI_npc_jaina_and_sylvana_FSintro; + newscript->pGossipHello = &GossipHello_npc_jaina_and_sylvana_FSintro; + newscript->pGossipSelect = &GossipSelect_npc_jaina_and_sylvana_FSintro; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_jaina_and_sylvana_FSextro"; + newscript->GetAI = &GetAI_npc_jaina_and_sylvana_FSextro; + newscript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.h b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.h index a6767f058..1a6e0055b 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.h +++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.h @@ -1,129 +1,39 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ #ifndef DEF_FORGE_OF_SOULS_H #define DEF_FORGE_OF_SOULS_H +#include "BSW_ai.h" enum { - MAX_ENCOUNTER = 2, - TYPE_BRONJAHM = 1, - TYPE_DECOURER_OF_SOULS = 2, - TYPE_ACHIEV_PHANTOM_BLAST = 3, + MAX_ENCOUNTERS = 3, + + TYPE_INTRO = 0, + TYPE_BRONJAHM = 1, + TYPE_DEVOURER = 2, + + NPC_BRONJAHM = 36497, + NPC_DEVOURER = 36502, + + DATA_LIDER = 101, + + npc_jaina = 37597, + npc_sylvana = 37596, + npc_jaina_extro = 38160, + npc_sylvana_extro = 38161, + npc_jaina_credit = 36955, + npc_sylvana_credit = 37554, + npc_mage = 37582, + npc_mage_woman = 37774, + npc_cc_a_01 = 37497, + npc_cc_a_02 = 37496, + npc_cc_a_03 = 37498, + npc_cc_h_01 = 37588, + npc_cc_h_02 = 37584, + npc_cc_h_03 = 37587, - DATA_SOULFRAGMENT_REMOVE = 4, // on Death and on Use - - NPC_BRONJAHM = 36497, - NPC_DEVOURER_OF_SOULS = 36502, - NPC_CORRUPTED_SOUL_FRAGMENT = 36535, - - // Event NPCs - NPC_SILVANA_BEGIN = 37596, - NPC_SILVANA_END = 38161, - NPC_JAINA_BEGIN = 37597, - NPC_JAINA_END = 38160, - NPC_ARCHMAGE_ELANDRA = 37774, - NPC_ARCHMAGE_KORELN = 37582, - NPC_DARK_RANGER_KALIRA = 37583, - NPC_DARK_RANGER_LORALEN = 37779, - NPC_COLISEUM_CHAMPION_A_P = 37498, // Alliance Paladin - NPC_COLISEUM_CHAMPION_A_F = 37496, // Alliance Footman - NPC_COLISEUM_CHAMPION_A_M = 37497, // Alliance Mage - NPC_COLISEUM_CHAMPION_H_F = 37584, // Horde Footman - NPC_COLISEUM_CHAMPION_H_T = 37587, // Horde Taure - NPC_COLISEUM_CHAMPION_H_M = 37588, // Horde Mage - - ACHIEV_CRIT_SOUL_POWER = 12752, - ACHIEV_CRIT_PHANTOM_BLAST = 12976, -}; - -struct sIntoEventNpcSpawnLocations -{ - uint32 uiEntryHorde, uiEntryAlliance; - float fSpawnX, fSpawnY, fSpawnZ, fSpawnO; -}; - -/* Still TODO -** We have 12 npc-entries to do moving, and often different waypoints for one entry -** Best way to handle the paths of these mobs is still open -*/ - -struct sExtroEventNpcLocations -{ - uint32 uiEntryHorde, uiEntryAlliance; - float fStartO, fEndO; // Orientation for Spawning - float fSpawnX, fSpawnY, fSpawnZ; - float fEndX, fEndY, fEndZ; -}; - -// TODO: verify Horde - Entries -const sIntoEventNpcSpawnLocations aEventBeginLocations[3] = -{ - {NPC_SILVANA_BEGIN, NPC_JAINA_BEGIN, 4901.25439f, 2206.861f, 638.8166f, 5.88175964f}, - {NPC_DARK_RANGER_KALIRA, NPC_ARCHMAGE_ELANDRA, 4899.709961f, 2205.899902f, 638.817017f, 5.864306f}, - {NPC_DARK_RANGER_LORALEN, NPC_ARCHMAGE_KORELN, 4903.160156f, 2213.090088f, 638.817017f, 0.1745329f} -}; - -const sExtroEventNpcLocations aEventEndLocations[18] = -{ - // Horde Entry Ally Entry O_Spawn O_End SpawnPos EndPos - {NPC_SILVANA_END, NPC_JAINA_END, 0.8901179f, 0.890118f, 5606.34033f, 2436.32129f, 705.9351f, 5638.404f, 2477.154f, 708.6932f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 0.9773844f, 1.780236f, 5593.632f, 2428.57983f, 705.9351f, 5695.879f, 2522.944f, 714.6915f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 1.1519173f, 1.78023f, 5594.079f, 2425.111f, 705.9351f, 5692.123f, 2522.613f, 714.6915f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 0.6108652f, 0.296706f, 5597.932f, 2421.78125f, 705.9351f, 5669.314f, 2540.029f, 714.6915f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 1.0471975f, 5.358161f, 5598.03564f, 2429.37671f, 705.9351f, 5639.267f, 2520.912f, 708.6959f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 0.8901179f, 0.112373f, 5600.836f, 2421.35938f, 705.9351f, 5668.145f, 2543.854f, 714.6915f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 0.8901179f, 5.358161f, 5600.848f, 2429.54517f, 705.9351f, 5639.961f, 2522.936f, 708.6959f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 0.8901179f, 5.347504f, 5601.46533f, 2426.77075f, 705.9351f, 5643.156f, 2525.342f, 708.6958f}, - {NPC_COLISEUM_CHAMPION_H_F, NPC_COLISEUM_CHAMPION_A_F, 1.1519173f, 0.232039f, 5601.587f, 2418.60425f, 705.9351f, 5670.483f, 2536.204f, 714.6915f}, - {NPC_DARK_RANGER_LORALEN, NPC_ARCHMAGE_KORELN, 0.7853982f, 3.717551f, 5606.35059f, 2432.88013f, 705.9351f, 5688.9f, 2538.981f, 714.6915f}, - {NPC_DARK_RANGER_KALIRA, NPC_ARCHMAGE_ELANDRA, 0.9599311f, 4.694936f, 5602.80371f, 2435.66846f, 705.9351f, 5685.069f, 2541.771f, 714.6915f}, - {NPC_COLISEUM_CHAMPION_H_T, NPC_COLISEUM_CHAMPION_A_P, 0.8552113f, 1.958489f, 5589.8125f, 2421.27075f, 705.9351f, 5669.351f, 2472.626f, 708.6959f}, - {NPC_COLISEUM_CHAMPION_H_T, NPC_COLISEUM_CHAMPION_A_P, 0.8552113f, 2.111848f, 5592.2666f, 2419.37842f, 705.9351f, 5665.927f, 2470.574f, 708.6959f}, - {NPC_COLISEUM_CHAMPION_H_T, NPC_COLISEUM_CHAMPION_A_P, 0.9075712f, 2.196496f, 5594.64746f, 2417.10767f, 705.9351f, 5662.503f, 2468.522f, 708.6958f}, - {NPC_COLISEUM_CHAMPION_H_M, NPC_COLISEUM_CHAMPION_A_M, 1.0646508f, 0.837758f, 5585.49854f, 2418.22925f, 705.9351f, 5624.832f, 2473.713f, 708.6959f}, - {NPC_COLISEUM_CHAMPION_H_M, NPC_COLISEUM_CHAMPION_A_M, 0.9424777f, 0.837758f, 5586.80029f, 2416.97388f, 705.9351f, 5627.443f, 2472.236f, 708.6959f}, - {NPC_COLISEUM_CHAMPION_H_M, NPC_COLISEUM_CHAMPION_A_M, 0.9250245f, 0.977384f, 5591.653f, 2412.89771f, 705.9351f, 5637.912f, 2465.69f, 708.6959f}, - {NPC_COLISEUM_CHAMPION_H_M, NPC_COLISEUM_CHAMPION_A_M, 0.8726646f, 0.977384f, 5593.93652f, 2410.875f, 705.9351f, 5642.629f, 2474.331f, 708.6959f} -}; - -class MANGOS_DLL_DECL instance_forge_of_souls : public ScriptedInstance -{ - public: - instance_forge_of_souls(Map* pMap); - ~instance_forge_of_souls() {} - - void Initialize(); - - void OnCreatureCreate(Creature* pCreature); - - void SetData(uint32 uiType, uint32 uiData); - uint32 GetData(uint32 uiType); - uint64 GetData64(uint32 uiData); - void SetData64(uint32 uiType, uint64 uiData); - - Player* GetPlayer(); - void OnPlayerEnter(Player* pPlayer); - void ProcessEventNpcs(Player* pPlayer, bool bChanged); - bool CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/); - - const char* Save() { return strInstData.c_str(); } - void Load(const char* chrIn); - - protected: - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - bool m_bCriteriaPhantomBlastFailed; - - uint32 m_uiTeam; // Team of first entered player, used to set if Jaina or Silvana to spawn - - uint64 m_uiBronjahmGUID; - uint64 m_uiDevourerOrSoulsGUID; - - std::list m_luiSoulFragmentAliveGUIDs; - std::list m_lEventMobGUIDs; }; #endif diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp index 2b9afa4cf..fb5f2faad 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,214 +24,159 @@ EndScriptData */ #include "precompiled.h" #include "forge_of_souls.h" -instance_forge_of_souls::instance_forge_of_souls(Map* pMap) : ScriptedInstance(pMap), - m_bCriteriaPhantomBlastFailed(false), - m_uiTeam(0), - m_uiBronjahmGUID(0), - m_uiDevourerOrSoulsGUID(0) +struct MANGOS_DLL_DECL instance_forge_of_souls : public ScriptedInstance { - Initialize(); -} + instance_forge_of_souls(Map* pMap) : ScriptedInstance(pMap) + { + Regular = pMap->IsRegularDifficulty(); + Initialize(); + } -void instance_forge_of_souls::Initialize() -{ - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); -} + bool Regular; + bool needSave; + std::string strSaveData; -void instance_forge_of_souls::OnCreatureCreate(Creature* pCreature) -{ - switch(pCreature->GetEntry()) + //Creatures GUID + uint32 m_auiEncounter[MAX_ENCOUNTERS+1]; + uint64 m_uiBronjahmGUID; + uint64 m_uiDevourerGUID; + uint64 m_uiLiderGUID; + + void OpenDoor(uint64 guid) { - case NPC_BRONJAHM: m_uiBronjahmGUID = pCreature->GetGUID(); break; - case NPC_DEVOURER_OF_SOULS: m_uiDevourerOrSoulsGUID = pCreature->GetGUID(); break; - case NPC_CORRUPTED_SOUL_FRAGMENT: m_luiSoulFragmentAliveGUIDs.push_back(pCreature->GetGUID()); break; + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_ACTIVE); } -} -void instance_forge_of_souls::OnPlayerEnter(Player* pPlayer) -{ - if (!m_uiTeam) // very first player to enter + void CloseDoor(uint64 guid) { - m_uiTeam = pPlayer->GetTeam(); - ProcessEventNpcs(pPlayer, false); + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_READY); } -} -void instance_forge_of_souls::ProcessEventNpcs(Player* pPlayer, bool bChanged) -{ - if (!pPlayer) - return; + void Initialize() + { + for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + m_auiEncounter[i] = NOT_STARTED; + m_uiBronjahmGUID =0; + m_uiDevourerGUID =0; + } - if (m_auiEncounter[0] != DONE || m_auiEncounter[1] != DONE) + void OnCreatureCreate(Creature* pCreature) { - // Spawn Begin Mobs - for (uint8 i = 0; i < sizeof(aEventBeginLocations)/sizeof(sIntoEventNpcSpawnLocations); i++) + switch(pCreature->GetEntry()) { - if (Creature* pSummon = pPlayer->SummonCreature(m_uiTeam == HORDE ? aEventBeginLocations[i].uiEntryHorde : aEventBeginLocations[i].uiEntryAlliance, - aEventBeginLocations[i].fSpawnX, aEventBeginLocations[i].fSpawnY, aEventBeginLocations[i].fSpawnZ, aEventBeginLocations[i].fSpawnO, TEMPSUMMON_DEAD_DESPAWN, 24*HOUR*IN_MILLISECONDS)) - m_lEventMobGUIDs.push_back(pSummon->GetGUID()); + case NPC_DEVOURER: + m_uiDevourerGUID = pCreature->GetGUID(); + break; + case NPC_BRONJAHM: + m_uiBronjahmGUID = pCreature->GetGUID(); + break; } } - else + + void OnObjectCreate(GameObject* pGo) { - // if bChanged, despawn Begin Mobs, spawn End Mobs at Spawn, else spawn EndMobs at End - if (bChanged) + switch(pGo->GetEntry()) { - for (std::list::const_iterator itr = m_lEventMobGUIDs.begin(); itr != m_lEventMobGUIDs.end(); itr++) - { - if (Creature* pSummoned = instance->GetCreature(*itr)) - pSummoned->ForcedDespawn(); - } - - for (uint8 i = 0; i < sizeof(aEventEndLocations)/sizeof(sExtroEventNpcLocations); i++) - { - pPlayer->SummonCreature(m_uiTeam == HORDE ? aEventEndLocations[i].uiEntryHorde : aEventEndLocations[i].uiEntryAlliance, - aEventEndLocations[i].fSpawnX, aEventEndLocations[i].fSpawnY, aEventEndLocations[i].fSpawnZ, aEventEndLocations[i].fStartO, TEMPSUMMON_DEAD_DESPAWN, 24*HOUR*IN_MILLISECONDS); - - // TODO: Let the NPCs Move along their paths - } - } - else - { // Summon at end, without event - for (uint8 i = 0; i < sizeof(aEventEndLocations)/sizeof(sExtroEventNpcLocations); i++) - { - pPlayer->SummonCreature(m_uiTeam == HORDE ? aEventEndLocations[i].uiEntryHorde : aEventEndLocations[i].uiEntryAlliance, - aEventEndLocations[i].fEndX, aEventEndLocations[i].fEndY, aEventEndLocations[i].fEndZ, aEventEndLocations[i].fEndO, TEMPSUMMON_DEAD_DESPAWN, 24*HOUR*IN_MILLISECONDS); - } } } -} - -Player* instance_forge_of_souls::GetPlayer() -{ - Map::PlayerList const& players = instance->GetPlayers(); - - if (!players.isEmpty()) + void SetData(uint32 uiType, uint32 uiData) { - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + switch(uiType) + { + case TYPE_INTRO: m_auiEncounter[0] = uiData; break; + case TYPE_BRONJAHM: m_auiEncounter[1] = uiData; break; + case TYPE_DEVOURER: m_auiEncounter[2] = uiData; break; + default: break; + } + + if (uiData == DONE) { - if (Player* plr = itr->getSource()) - return plr; + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + saveStream << m_auiEncounter[i] << " "; + + strSaveData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } } - return NULL; -} -bool instance_forge_of_souls::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/) -{ - switch (uiCriteriaId) + const char* Save() { - case ACHIEV_CRIT_SOUL_POWER: - return m_luiSoulFragmentAliveGUIDs.size() >= 4; - case ACHIEV_CRIT_PHANTOM_BLAST: - return !m_bCriteriaPhantomBlastFailed; - default: - return 0; + return strSaveData.c_str(); } -} -void instance_forge_of_souls::SetData(uint32 uiType, uint32 uiData) -{ - switch(uiType) + uint32 GetData(uint32 uiType) { - case TYPE_BRONJAHM: - m_auiEncounter[0] = uiData; - - // Despawn remaining adds and clear list - for (std::list::const_iterator itr = m_luiSoulFragmentAliveGUIDs.begin(); itr != m_luiSoulFragmentAliveGUIDs.end(); itr++) - { - if (Creature* pFragment = instance->GetCreature(*itr)) - pFragment->ForcedDespawn(); - } - m_luiSoulFragmentAliveGUIDs.clear(); - break; - case TYPE_DECOURER_OF_SOULS: - m_auiEncounter[1] = uiData; - if (uiData == DONE) - ProcessEventNpcs(GetPlayer(), true); - break; - case TYPE_ACHIEV_PHANTOM_BLAST: - m_bCriteriaPhantomBlastFailed = (uiData == FAIL); - return; + switch(uiType) + { + case TYPE_INTRO: return m_auiEncounter[0]; + case TYPE_BRONJAHM: return m_auiEncounter[1]; + case TYPE_DEVOURER: return m_auiEncounter[2]; + } + return 0; } - if (uiData == DONE) + uint64 GetData64(uint32 uiData) { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1]; - - strInstData = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; + switch(uiData) + { + case NPC_BRONJAHM: return m_uiBronjahmGUID; + case NPC_DEVOURER: return m_uiDevourerGUID; + case DATA_LIDER: return m_uiLiderGUID; + } + return 0; } -} -void instance_forge_of_souls::Load(const char* chrIn) -{ - if (!chrIn) + void SetData64(uint32 uiData, uint64 uiGuid) { - OUT_LOAD_INST_DATA_FAIL; - return; + switch(uiData) + { + case DATA_LIDER: m_uiLiderGUID = uiGuid; + } } - OUT_LOAD_INST_DATA(chrIn); + void Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - std::istringstream loadStream(chrIn); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1]; + OUT_LOAD_INST_DATA(chrIn); - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } + std::istringstream loadStream(chrIn); - OUT_LOAD_INST_DATA_COMPLETE; -} + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + { + loadStream >> m_auiEncounter[i]; -uint32 instance_forge_of_souls::GetData(uint32 uiType) -{ - switch(uiType) - { - case TYPE_BRONJAHM: - return m_auiEncounter[0]; - case TYPE_DECOURER_OF_SOULS: - return m_auiEncounter[1]; - default: - return 0; - } -} + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } -uint64 instance_forge_of_souls::GetData64(uint32 uiData) -{ - switch(uiData) - { - case NPC_BRONJAHM: - return m_uiBronjahmGUID; - case NPC_DEVOURER_OF_SOULS: - return m_uiDevourerOrSoulsGUID; - default: - return 0; + OUT_LOAD_INST_DATA_COMPLETE; } -} - -void instance_forge_of_souls::SetData64(uint32 uiType, uint64 uiData) -{ - if (uiType == DATA_SOULFRAGMENT_REMOVE) - m_luiSoulFragmentAliveGUIDs.remove(uiData); -} +}; InstanceData* GetInstanceData_instance_forge_of_souls(Map* pMap) { return new instance_forge_of_souls(pMap); } + void AddSC_instance_forge_of_souls() { Script* pNewScript; - pNewScript = new Script; pNewScript->Name = "instance_forge_of_souls"; pNewScript->GetInstanceData = &GetInstanceData_instance_forge_of_souls; diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falric.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falric.cpp new file mode 100644 index 000000000..049b3d056 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falric.cpp @@ -0,0 +1,230 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_falric +SD%Complete: 70% +SDComment: +SDAuthor: /dev/rsa, changed by MaxXx2021 aka Mioka +SDCategory: Halls of Reflection +EndScriptData */ + +#include "precompiled.h" +#include "def_halls.h" + +enum +{ + SAY_FALRIC_AGGRO = -1594507, + SAY_FALRIC_DEATH = -1594508, + SAY_FALRIC_SLAY01 = -1594509, + SAY_FALRIC_SLAY02 = -1594510, + SAY_FALRIC_SP01 = -1594511, + SAY_FALRIC_SP02 = -1594512, + + SPELL_HOPELESSNESS = 72395, + SPELL_IMPENDING_DESPAIR = 72426, + SPELL_DEFILING_HORROR = 72435, + SPELL_QUIVERING_STRIKE = 72422, + + SPELL_BERSERK = 47008 +}; + +struct MANGOS_DLL_DECL boss_falricAI : public BSWScriptedAI +{ + boss_falricAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsCall; + + uint32 m_uiSummonTimer; + uint32 m_uiLocNo; + uint64 m_uiSummonGUID[16]; + uint32 m_uiCheckSummon; + + uint8 SummonCount; + + uint64 pSummon; + + void Reset() + { + SummonCount = 0; + m_bIsCall = false; + m_uiSummonTimer = 11000; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetVisibility(VISIBILITY_OFF); + } + + void Aggro(Unit* pVictim) + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + DoScriptText(SAY_FALRIC_AGGRO, m_creature); + DoCast(m_creature, SPELL_HOPELESSNESS); + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0,1)) + { + case 0: DoScriptText(SAY_FALRIC_SLAY01, m_creature); break; + case 1: DoScriptText(SAY_FALRIC_SLAY02, m_creature); break; + } + } + + void JustDied(Unit* pKiller) + { + if(!m_pInstance) return; + m_pInstance->SetData(TYPE_MARWYN, SPECIAL); + DoScriptText(SAY_FALRIC_DEATH, m_creature); + } + + void AttackStart(Unit* who) + { + if(!m_pInstance) return; + + if(m_pInstance->GetData(TYPE_FALRIC) != IN_PROGRESS) + return; + + ScriptedAI::AttackStart(who); + } + + void Summon() + { + m_uiLocNo = 0; + + for(uint8 i = 0; i < 14; i++) + { + switch(urand(0,3)) + { + case 0: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_1; break; + case 2: pSummon = NPC_DARK_3; break; + case 3: pSummon = NPC_DARK_6; break; + } + break; + case 1: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_2; break; + case 2: pSummon = NPC_DARK_3; break; + case 3: pSummon = NPC_DARK_4; break; + } + break; + case 2: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_2; break; + case 2: pSummon = NPC_DARK_5; break; + case 3: pSummon = NPC_DARK_6; break; + } + break; + case 3: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_1; break; + case 2: pSummon = NPC_DARK_5; break; + case 3: pSummon = NPC_DARK_4; break; + } + break; + } + + m_uiCheckSummon = 0; + + if(Creature* Summon = m_creature->SummonCreature(pSummon, SpawnLoc[m_uiLocNo].x, SpawnLoc[m_uiLocNo].y, SpawnLoc[m_uiLocNo].z, SpawnLoc[m_uiLocNo].o, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000)) + { + m_uiSummonGUID[i] = Summon->GetGUID(); + Summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Summon->setFaction(974); + } + m_uiLocNo++; + } + } + + void CallFallSoldier() + { + for(uint8 i = 0; i < 4; i++) + { + if(Creature* Summon = m_pInstance->instance->GetCreature(m_uiSummonGUID[m_uiCheckSummon])) + { + Summon->setFaction(14); + Summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Summon->SetInCombatWithZone(); + } + m_uiCheckSummon++; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_EVENT) == 5) + { + m_pInstance->SetData(TYPE_EVENT, 6); + Summon(); + } + + if (m_pInstance->GetData(TYPE_FALRIC) == SPECIAL) + { + + if (m_uiSummonTimer < uiDiff) + { + ++SummonCount; + if(SummonCount > 4) + { + m_pInstance->SetData(TYPE_FALRIC, IN_PROGRESS); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWithZone(); + } + else CallFallSoldier(); + m_uiSummonTimer = 60000; + } else m_uiSummonTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_QUIVERING_STRIKE, uiDiff); + timedCast(SPELL_IMPENDING_DESPAIR, uiDiff); + timedCast(SPELL_DEFILING_HORROR, uiDiff); + + timedCast(SPELL_BERSERK, uiDiff); + + DoMeleeAttackIfReady(); + + } +}; + +CreatureAI* GetAI_boss_falric(Creature* pCreature) +{ + return new boss_falricAI(pCreature); +} + +void AddSC_boss_falric() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_falric"; + newscript->GetAI = &GetAI_boss_falric; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp index 78d6d649c..42060b5df 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,663 @@ /* ScriptData SDName: boss_lich_king -SD%Complete: 0% +SD%Complete: 100% SDComment: +SDAuthor: MaxXx2021 aka Mioka SDCategory: Halls of Reflection EndScriptData */ #include "precompiled.h" +#include "def_halls.h" +#include "escort_ai.h" + +enum +{ + SPELL_WINTER = 69780, + SPELL_FURY_OF_FROSTMOURNE = 70063, + SPELL_SOUL_REAPER = 73797, + SPELL_ICE_PRISON = 69708, + SPELL_DARK_ARROW = 70194, + SPELL_EMERGE_VISUAL = 50142, + SPELL_DESTROY_ICE_WALL_02 = 70224, + SPELL_SILENCE = 69413, + SPELL_LICH_KING_CAST = 57561, + SPELL_GNOUL_JUMP = 70150, + SPELL_ABON_STRIKE = 40505, + + // summon spells + SPELL_WITCH_DOCTOR = 69836, + SPELL_SUMMON_ABOM = 69835, + SPELL_RAISE_DEAD = 69818, + + /*SPELLS - Witch Doctor, 36941 */ + SPELL_COURSE_OF_DOOM = 70144, + SPELL_SHADOW_BOLT_VALLEY = 70145, + SPELL_SHADOW_BOLT = 70080, + + /*SPELLS - abomination, 37069 */ + SPELL_CLEAVE = 40505, + + /*SPELLS - raging ghoul, 36940 */ + SPELL_LEAP = 70150, + + SAY_LICH_KING_WALL_01 = -1594486, + SAY_LICH_KING_WALL_02 = -1594491, + SAY_LICH_KING_GNOUL = -1594482, + SAY_LICH_KING_ABON = -1594483, + SAY_LICH_KING_WINTER = -1594481, + SAY_LICH_KING_END_DUN = -1594504, + SAY_LICH_KING_WIN = -1594485, + + /*INTRO - Lich King Arrive*/ + SAY_LICH_KING_17 = -1594468, + SAY_LICH_KING_18 = -1594469, + SAY_LICH_KING_19 = -1594470, + SAY_JAINA_20 = -1594471, + SAY_SYLVANA_20 = -1594472, + SAY_LICH_KING_A_21 = -1594473, + SAY_LICH_KING_H_21 = -1594474, + SAY_FALRIC_INTRO = -1594475, + SAY_MARWYN_INTRO = -1594476, + SAY_FALRIC_INTRO2 = -1594505, + + SPELL_TAKE_FROSTMOURNE = 72729, + SPELL_FROSTMOURNE_DESPAWN = 72726, + SPELL_FROSTMOURNE_SOUNDS = 70667, + SPELL_CAST_VISUAL = 65633, //Jaina And Sylavana cast this when summon uther. + SPELL_BOSS_SPAWN_AURA = 72712, //Falric and Marwyn + SPELL_UTHER_DESPAWN = 70693, + SPELL_FROSTMOURNE_VISUAL = 73220, + + /*INTRO - Pre Escape*/ + SAY_LICH_KING_AGGRO_A = -1594477, + SAY_LICH_KING_AGGRO_H = -1594478, + SAY_JAINA_AGGRO = -1594479, + SAY_SYLVANA_AGGRO = -1594480, + +}; + +struct MANGOS_DLL_DECL boss_lich_king_hrAI : public npc_escortAI +{ + boss_lich_king_hrAI(Creature *pCreature) : npc_escortAI(pCreature) + { + m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + BSWScriptedInstance* m_pInstance; + bool StartEscort; + bool NonFight; + bool Finish; + + void Reset() + { + if(!m_pInstance) return; + NonFight = false; + StartEscort = false; + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, 36942); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if (m_pInstance->GetData(TYPE_LICH_KING) == DONE) + m_creature->SetVisibility(VISIBILITY_OFF); + } + + void JustDied(Unit* pKiller) + { + } + + void MoveInLineOfSight(Unit* who) + { + if (!who || !m_pInstance) + return; + + if (who->GetTypeId() != TYPEID_PLAYER) + return; + + Player* pPlayer = (Player *)who; + + if (pPlayer->isGameMaster()) + return; + + if (m_pInstance->GetData(TYPE_PHASE) != 3 + || m_pInstance->GetData(TYPE_LICH_KING) == DONE + || !m_creature->IsWithinDistInMap(who, 50.0f) + || m_pInstance->GetData(TYPE_FROST_GENERAL) != DONE) + return; + + m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICECROWN_DOOR_2)); + + Team team; + if (Group* pGroup = pPlayer->GetGroup()) + { + ObjectGuid LeaderGuid = pGroup->GetLeaderGuid(); + if (!LeaderGuid.IsEmpty()) + if (Player* pLeader =m_creature->GetMap()->GetPlayer(LeaderGuid)) + team = pLeader->GetTeam(); + } + else + team = ((Player*)who)->GetTeam(); + + uint32 newLeader; + + if (team == ALLIANCE) + newLeader = NPC_JAINA_OUTRO; + else + newLeader = NPC_SYLVANA_OUTRO; + + if (Creature* pNewLeader = m_creature->SummonCreature(newLeader,WallLoc[6].x,WallLoc[6].y,WallLoc[6].z,WallLoc[6].o,TEMPSUMMON_MANUAL_DESPAWN,0,true)) + { + pNewLeader->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pNewLeader->SetSpeedRate(MOVE_RUN, 1.0f, true); + pNewLeader->SetRespawnDelay(DAY); + pNewLeader->SetHealth(pNewLeader->GetMaxHealth()/10); + m_pInstance->SetData64(DATA_ESCAPE_LIDER, pNewLeader->GetGUID()); + } + m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICECROWN_DOOR_2)); + m_pInstance->SetData(TYPE_PHASE, 4); + m_pInstance->SetNextEvent(100,GetLeader(),500); + } + + void WaypointReached(uint32 i) + { + switch(i) + { + case 20: + SetEscortPaused(true); + Finish = true; + DoCast(m_creature, SPELL_LICH_KING_CAST); + m_pInstance->SetData(TYPE_LICH_KING, SPECIAL); + DoScriptText(SAY_LICH_KING_END_DUN, m_creature); + if(Creature* pLider = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ESCAPE_LIDER)))) + { + pLider->CastSpell(pLider, SPELL_SILENCE, false); + pLider->AddSplineFlag(SPLINEFLAG_FLYING); + pLider->SendMonsterMove(pLider->GetPositionX(), pLider->GetPositionY(), pLider->GetPositionZ() + 4, SPLINETYPE_NORMAL , pLider->GetSplineFlags(), 3000); + } + m_pInstance->SetData(TYPE_PHASE, 6); + m_pInstance->SetNextEvent(610,GetLeader(),5000); + m_creature->SetActiveObjectState(false); + break; + } + } + + void AttackStart(Unit* who) + { + if (!m_pInstance || !who || NonFight) + return; + + if (m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS || who->GetTypeId() == TYPEID_PLAYER) return; + + npc_escortAI::AttackStart(who); + } + + void SummonedCreatureJustDied(Creature* summoned) + { + if(!m_pInstance || !summoned) + return; + + if (summoned->GetEntry() == NPC_JAINA_OUTRO + || summoned->GetEntry() == NPC_SYLVANA_OUTRO) + { + m_creature->NearTeleportTo(5572.077f, 2283.1f, 734.976f, 3.89f); + if (boss_lich_king_hrAI* pEscortAI = dynamic_cast(m_creature->AI())) + pEscortAI->EnterEvadeMode(); + StartEscort = false; + } + else + m_pInstance->SetData(DATA_SUMMONS, 0); + } + + void JustSummoned(Creature* summoned) + { + if (!m_pInstance || !summoned) + return; + + if (summoned->GetEntry() == NPC_JAINA_OUTRO + || summoned->GetEntry() == NPC_SYLVANA_OUTRO) + { + summoned->SetCreatorGuid(ObjectGuid()); + summoned->setFaction(2076); + summoned->SetPhaseMask(65535, true); + m_creature->SetInCombatWith(summoned); + summoned->SetInCombatWith(m_creature); + } + else + { + summoned->SetPhaseMask(65535, true); + summoned->SetInCombatWithZone(); + summoned->SetActiveObjectState(true); + + m_pInstance->SetData(DATA_SUMMONS, 1); + + if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER))) + { + summoned->GetMotionMaster()->MoveChase(pLider); + summoned->AddThreat(pLider, 100.0f); + } + } + } + + uint32 GetLeader() + { + if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER))) + return pLider->GetEntry(); + else + return 0; + } + + void Event() + { + switch (m_pInstance->GetEvent(m_creature->GetEntry())) + { +// Intro phase + case 101: + if(GetLeader() == NPC_JAINA_OUTRO) + DoScriptText((GetLeader() == NPC_JAINA_OUTRO ? SAY_LICH_KING_AGGRO_A : SAY_LICH_KING_AGGRO_H), m_creature); + if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER))) + AttackStart(pLider); + m_pInstance->SetNextEvent(102,GetLeader(),3000); + break; + +// Active phase + case 200: + SetEscortPaused(true); + m_pInstance->SetData(DATA_SUMMONS, 3); + DoScriptText(SAY_LICH_KING_WALL_01, m_creature); + m_pInstance->SetNextEvent(210,m_creature->GetEntry(),2000); + break; + case 210: + m_pInstance->SetNextEvent(220,m_creature->GetEntry(),2000); + break; + case 220: + DoCast(m_creature, SPELL_RAISE_DEAD); + DoScriptText(SAY_LICH_KING_GNOUL, m_creature); + m_pInstance->SetNextEvent(230,m_creature->GetEntry(),7000); + break; + case 230: + DoScriptText(SAY_LICH_KING_WINTER, m_creature); + DoCast(m_creature, SPELL_WINTER); + m_creature->SetSpeedRate(MOVE_WALK, 1.3f, true); + m_pInstance->SetNextEvent(240,m_creature->GetEntry(),1000); + break; + case 240: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + SetEscortPaused(false); + m_pInstance->SetNextEvent(250,m_creature->GetEntry(),2000); + break; + case 250: + m_pInstance->SetNextEvent(290,GetLeader(),1000); + DoCast(m_creature, SPELL_WITCH_DOCTOR); + break; + + case 300: + SetEscortPaused(true); + DoCast(m_creature, SPELL_SUMMON_ABOM); + m_pInstance->SetData(DATA_SUMMONS, 3); + DoScriptText(SAY_LICH_KING_GNOUL, m_creature); + m_pInstance->SetNextEvent(310,m_creature->GetEntry(),500); + break; + case 310: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(320,m_creature->GetEntry(),500); + break; + case 320: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(330,m_creature->GetEntry(),5000); + break; + case 330: + DoCast(m_creature, SPELL_RAISE_DEAD); + SetEscortPaused(false); + m_pInstance->SetNextEvent(390,GetLeader(),1000); + break; + + case 400: + SetEscortPaused(true); + DoCast(m_creature, SPELL_SUMMON_ABOM); + m_pInstance->SetData(DATA_SUMMONS, 3); + DoScriptText(SAY_LICH_KING_GNOUL, m_creature); + m_pInstance->SetNextEvent(410,m_creature->GetEntry(),500); + break; + case 410: + DoScriptText(SAY_LICH_KING_ABON, m_creature); + DoCast(m_creature, SPELL_SUMMON_ABOM); + m_pInstance->SetNextEvent(420,m_creature->GetEntry(),500); + break; + case 420: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(430,m_creature->GetEntry(),500); + break; + case 430: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(440,m_creature->GetEntry(),500); + break; + case 440: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(450,m_creature->GetEntry(),500); + break; + case 450: + DoCast(m_creature, SPELL_RAISE_DEAD); + m_pInstance->SetNextEvent(490,GetLeader(),5000); + SetEscortPaused(false); + break; + + case 500: + m_pInstance->SetData(DATA_SUMMONS, 3); + DoScriptText(SAY_LICH_KING_GNOUL, m_creature); + DoCast(m_creature, SPELL_SUMMON_ABOM); + m_pInstance->SetNextEvent(510,m_creature->GetEntry(),10000); + break; + case 510: + m_creature->SetSpeedRate(MOVE_WALK, 1.3f, true); + DoCast(m_creature, SPELL_SUMMON_ABOM); + m_pInstance->SetNextEvent(520,m_creature->GetEntry(),500); + break; + case 520: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(530,m_creature->GetEntry(),500); + break; + case 530: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(540,m_creature->GetEntry(),500); + break; + case 540: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(550,m_creature->GetEntry(),500); + break; + case 550: + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(570,m_creature->GetEntry(),2000); + break; + case 570: + DoScriptText(SAY_LICH_KING_ABON, m_creature); + DoCast(m_creature, SPELL_WITCH_DOCTOR); + m_pInstance->SetNextEvent(580,m_creature->GetEntry(),5000); + break; + case 580: + DoScriptText(SAY_LICH_KING_ABON, m_creature); + DoCast(m_creature, SPELL_RAISE_DEAD); + m_pInstance->SetNextEvent(590,GetLeader(),1000); + break; + + case 900: + if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER))) + m_creature->DealDamage(pLider, pLider->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_pInstance->SetData(TYPE_LICH_KING, FAIL); + m_creature->SetActiveObjectState(false); + m_pInstance->SetData(TYPE_PHASE, 3); + m_pInstance->SetNextEvent(0,0); + break; + + default: + break; + } + } + + void UpdateEscortAI(const uint32 diff) + { + if(!m_pInstance) + return; + + if ( (m_pInstance->GetData(TYPE_PHASE) == 4 || m_pInstance->GetData(TYPE_PHASE) == 5 || m_pInstance->GetData(TYPE_PHASE) == 7) + && m_pInstance->GetEventTimer(m_creature->GetEntry(),diff)) + Event(); + + if(m_pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + return; + } + + if(m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS && !StartEscort) + { + StartEscort = true; + if(m_creature->HasAura(SPELL_ICE_PRISON)) + m_creature->RemoveAurasDueToSpell(SPELL_ICE_PRISON); + if(m_creature->HasAura(SPELL_DARK_ARROW)) + m_creature->RemoveAurasDueToSpell(SPELL_DARK_ARROW); + + m_creature->SetActiveObjectState(true); + + NonFight = true; + m_creature->AttackStop(); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_WALK, 2.7f, true); + if (boss_lich_king_hrAI* pEscortAI = dynamic_cast(m_creature->AI())) + pEscortAI->Start(); + } + if (m_pInstance->GetData(TYPE_PHASE) == 5) + if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER))) + if (pLider->isAlive() && pLider->IsWithinDistInMap(m_creature, 2.0f)) + { + m_pInstance->SetData(TYPE_PHASE,7); + SetEscortPaused(true); + m_creature->GetMotionMaster()->Clear(); + DoScriptText(SAY_LICH_KING_WIN, m_creature); + m_pInstance->SetNextEvent(900,m_creature->GetEntry(),4000); + m_creature->CastSpell(m_creature, SPELL_FURY_OF_FROSTMOURNE, false); + }; + + return; + } +}; + +CreatureAI* GetAI_boss_lich_king_hr(Creature* pCreature) +{ + return new boss_lich_king_hrAI(pCreature); +} + +struct MANGOS_DLL_DECL boss_lich_king_intro_horAI : public ScriptedAI +{ + boss_lich_king_intro_horAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + BSWScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void JustDied(Unit* pKiller) + { + } + + void AttackStart(Unit* who) + { + } + + uint32 GetLeader() + { + if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER))) + return pLider->GetEntry(); + else + return 0; + } + + void Event() + { + switch(m_pInstance->GetEvent(m_creature->GetEntry())) + { + case 24: + m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR)); + m_pInstance->SetNextEvent(25,GetLeader(),1000); + break; + case 25: + m_creature->GetMotionMaster()->MovePoint(0, 5314.881f, 2012.496f, 709.341f); + m_pInstance->SetNextEvent(26,m_creature->GetEntry(),3000); + break; + case 26: + m_pInstance->DoCloseDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR)); + m_pInstance->SetNextEvent(27,m_creature->GetEntry(),7000); + break; + case 27: + DoScriptText(SAY_LICH_KING_17, m_creature); + if (Creature* pUther = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_UTHER)))) + pUther->CastSpell(pUther, SPELL_UTHER_DESPAWN, false); + m_pInstance->SetNextEvent(28,m_creature->GetEntry(),1500); + break; + case 28: + if (Creature* pUther = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_UTHER)))) + pUther->ForcedDespawn(); + m_pInstance->SetNextEvent(29,m_creature->GetEntry(),10000); + break; + case 29: + DoScriptText(SAY_LICH_KING_18, m_creature); + m_pInstance->SetNextEvent(30,m_creature->GetEntry(),5000); + break; + case 30: + m_creature->CastSpell(m_creature, SPELL_TAKE_FROSTMOURNE, false); + m_pInstance->DoCloseDoor(m_pInstance->GetData64(GO_FROSTMOURNE)); + m_pInstance->SetNextEvent(31,m_creature->GetEntry(),1500); + break; + case 31: + if (GameObject* pFrostmourne = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_FROSTMOURNE))) + pFrostmourne->SetPhaseMask(0, true); + m_creature->CastSpell(m_creature, SPELL_FROSTMOURNE_VISUAL, false); + m_pInstance->SetNextEvent(31,GetLeader(),500); + break; + case 32: + DoScriptText(SAY_LICH_KING_19, m_creature); + m_pInstance->SetNextEvent(33,m_creature->GetEntry(),9000); + break; + case 33: + if (Creature* pFalric = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_FALRIC)))) + { + pFalric->SetVisibility(VISIBILITY_ON); + pFalric->CastSpell(pFalric, SPELL_BOSS_SPAWN_AURA, false); + pFalric->GetMotionMaster()->MovePoint(0, 5283.309f, 2031.173f, 709.319f); + } + if (Creature* pMarwyn = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MARWYN)))) + { + pMarwyn->SetVisibility(VISIBILITY_ON); + pMarwyn->CastSpell(pMarwyn, SPELL_BOSS_SPAWN_AURA, false); + pMarwyn->GetMotionMaster()->MovePoint(0, 5335.585f, 1981.439f, 709.319f); + } + m_creature->GetMotionMaster()->MovePoint(0, 5402.286f, 2104.496f, 707.695f); + m_pInstance->SetNextEvent(34,m_creature->GetEntry(),1000); + break; + case 34: + if (Creature* pFalric = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_FALRIC)))) + DoScriptText(SAY_FALRIC_INTRO, pFalric); + if (Creature* pMarwyn = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MARWYN)))) + DoScriptText(SAY_MARWYN_INTRO, pMarwyn); + m_pInstance->SetData(TYPE_EVENT, 5); + m_pInstance->SetNextEvent(35,m_creature->GetEntry(),3000); + break; + case 35: + if (GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR))) + pGate->SetGoState(GO_STATE_ACTIVE); + if (Creature* pFalric = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_FALRIC)))) + DoScriptText(SAY_FALRIC_INTRO2, pFalric); + m_pInstance->SetData(TYPE_FALRIC, SPECIAL); + m_pInstance->SetNextEvent(36,GetLeader(),4000); + break; + case 37: + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MovePoint(0, 5443.880f, 2147.095f, 707.695f); + if (GetLeader() == NPC_JAINA) + DoScriptText(SAY_LICH_KING_A_21, m_creature); + else if (GetLeader() == NPC_SYLVANA) + DoScriptText(SAY_LICH_KING_H_21, m_creature); + m_pInstance->SetNextEvent(38,m_creature->GetEntry(),8000); + break; + case 38: + m_pInstance->DoCloseDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR)); + m_pInstance->SetNextEvent(39,m_creature->GetEntry(),5000); + break; + case 39: + m_creature->SetVisibility(VISIBILITY_OFF); + m_pInstance->SetNextEvent(39,GetLeader(),1000); + break; + case 40: + m_pInstance->SetData(TYPE_PHASE, 2); + m_pInstance->SetNextEvent(0,0); + m_creature->ForcedDespawn(); + break; + default: + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetEventTimer(m_creature->GetEntry(),diff) && m_pInstance->GetData(TYPE_PHASE) == 1) + Event(); + + } +}; + +CreatureAI* GetAI_boss_lich_king_intro_hor(Creature* pCreature) +{ + return new boss_lich_king_intro_horAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_undead_horAI : public BSWScriptedAI +{ + npc_undead_horAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + } + + void EnterEvadeMode() + { + if (!m_pInstance) + return; + + m_creature->ForcedDespawn(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + doCastAll(uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_undead_hor(Creature* pCreature) +{ + return new npc_undead_horAI(pCreature); +} + +void AddSC_boss_lich_king_hr() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_lich_king_hr"; + newscript->GetAI = &GetAI_boss_lich_king_hr; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_lich_king_intro_hor"; + newscript->GetAI = &GetAI_boss_lich_king_intro_hor; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_undead_hor"; + newscript->GetAI = &GetAI_npc_undead_hor; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp index 9bc11a1fd..674508ddd 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,222 @@ /* ScriptData SDName: boss_marwyn -SD%Complete: 0% +SD%Complete: 60% SDComment: +SDAuthor: /dev/rsa, changed by MaxXx2021 aka Mioka SDCategory: Halls of Reflection EndScriptData */ #include "precompiled.h" +#include "def_halls.h" + +enum +{ + SAY_MARWYN_INTRO = -1594506, + SAY_MARWYN_AGGRO = -1594513, + SAY_MARWYN_DEATH = -1594514, + SAY_MARWYN_SLAY01 = -1594515, + SAY_MARWYN_SLAY02 = -1594516, + SAY_MARWYN_SP01 = -1594517, + SAY_MARWYN_SP02 = -1594518, + + SPELL_OBLITERATE = 72360, + SPELL_SHARED_SUFFERING = 72368, + SPELL_WELL_OF_CORRUPTION = 72362, + SPELL_CORRUPTED_FLESH = 72436, + + SPELL_BERSERK = 47008, +}; + +struct MANGOS_DLL_DECL boss_marwynAI : public BSWScriptedAI +{ + boss_marwynAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsCall; + uint32 m_uiSummonTimer; + + uint32 m_uiLocNo; + uint64 m_uiSummonGUID[16]; + uint32 m_uiCheckSummon; + + uint8 SummonCount; + + uint64 pSummon; + + void Reset() + { + SummonCount = 0; + m_bIsCall = false; + m_uiSummonTimer = 15000; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetVisibility(VISIBILITY_OFF); + } + + void Summon() + { + m_uiLocNo = 14; + + for(uint8 i = 0; i < 14; i++) + { + switch(urand(0,3)) + { + case 0: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_1; break; + case 2: pSummon = NPC_DARK_3; break; + case 3: pSummon = NPC_DARK_6; break; + } + break; + case 1: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_2; break; + case 2: pSummon = NPC_DARK_3; break; + case 3: pSummon = NPC_DARK_4; break; + } + break; + case 2: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_2; break; + case 2: pSummon = NPC_DARK_5; break; + case 3: pSummon = NPC_DARK_6; break; + } + break; + case 3: + switch(urand(1, 3)) + { + case 1: pSummon = NPC_DARK_1; break; + case 2: pSummon = NPC_DARK_5; break; + case 3: pSummon = NPC_DARK_4; break; + } + break; + } + + m_uiCheckSummon = 0; + + if(Creature* Summon = m_creature->SummonCreature(pSummon, SpawnLoc[m_uiLocNo].x, SpawnLoc[m_uiLocNo].y, SpawnLoc[m_uiLocNo].z, SpawnLoc[m_uiLocNo].o, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000)) + { + m_uiSummonGUID[i] = Summon->GetGUID(); + Summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Summon->setFaction(974); + } + m_uiLocNo++; + } + } + + void CallFallSoldier() + { + for(uint8 i = 0; i < 4; i++) + { + if(Creature* Summon = m_pInstance->instance->GetCreature(m_uiSummonGUID[m_uiCheckSummon])) + { + Summon->setFaction(14); + Summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Summon->SetInCombatWithZone(); + } + m_uiCheckSummon++; + } + } + + void JustDied(Unit* pKiller) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_MARWYN, DONE); + m_pInstance->SetData(TYPE_PHASE, 3); + } + + DoScriptText(SAY_MARWYN_DEATH, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0,1)) + { + case 0: DoScriptText(SAY_MARWYN_SLAY01, m_creature); break; + case 1: DoScriptText(SAY_MARWYN_SLAY02, m_creature); break; + } + } + + void Aggro(Unit* pVictim) + { + if (!m_pInstance) return; + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + DoScriptText(SAY_MARWYN_AGGRO, m_creature); + } + + void AttackStart(Unit* who) + { + if (!m_pInstance) return; + + if (m_pInstance->GetData(TYPE_MARWYN) != IN_PROGRESS) + return; + + ScriptedAI::AttackStart(who); + } + + void UpdateAI(const uint32 uiDiff) + { + if(!m_pInstance) return; + + if (m_pInstance->GetData(TYPE_EVENT) == 6) + { + m_pInstance->SetData(TYPE_EVENT, 7); + Summon(); + } + + if(m_pInstance->GetData(TYPE_MARWYN) == SPECIAL) + { + if(m_uiSummonTimer < uiDiff) + { + ++SummonCount; + if(SummonCount == 1) + DoScriptText(SAY_MARWYN_INTRO, m_creature); + + if(SummonCount > 4) + { + m_pInstance->SetData(TYPE_MARWYN, IN_PROGRESS); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetInCombatWithZone(); + } + else CallFallSoldier(); + m_uiSummonTimer = 60000; + } else m_uiSummonTimer -= uiDiff; + } + + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_OBLITERATE, uiDiff); + timedCast(SPELL_WELL_OF_CORRUPTION, uiDiff); + timedCast(SPELL_SHARED_SUFFERING, uiDiff); + timedCast(SPELL_CORRUPTED_FLESH, uiDiff); + + timedCast(SPELL_BERSERK, uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_marwyn(Creature* pCreature) +{ + return new boss_marwynAI(pCreature); +} + +void AddSC_boss_marwyn() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_marwyn"; + newscript->GetAI = &GetAI_boss_marwyn; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/def_halls.h b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/def_halls.h new file mode 100644 index 000000000..cb2ab947f --- /dev/null +++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/def_halls.h @@ -0,0 +1,128 @@ +#ifndef DEF_HALL_OF_REFLECTION_H +#define DEF_HALL_OF_REFLECTION_H +#include "BSW_ai.h" +#include "BSW_instance.h" + +enum Data +{ + TYPE_PHASE = 0, + TYPE_EVENT = 1, + TYPE_FALRIC = 2, + TYPE_MARWYN = 3, + TYPE_FROST_GENERAL = 4, + TYPE_LICH_KING = 5, + TYPE_HALLS = 6, + MAX_ENCOUNTERS, + + DATA_ESCAPE_LIDER = 101, + DATA_SUMMONS = 102, + + /*UNITS*/ + NPC_DARK_1 = 38177, //Shadowy Mercenary + NPC_DARK_2 = 38176, //Tortured Rifleman + NPC_DARK_3 = 38173, //Spectral Footman + NPC_DARK_4 = 38172, //Phantom Mage + NPC_DARK_5 = 38567, //Phantom Hallucination + NPC_DARK_6 = 38175, //Ghostly Priest + NPC_JAINA = 37221, + NPC_SYLVANA = 37223, + NPC_JAINA_OUTRO = 36955, + NPC_SYLVANA_OUTRO = 37554, + NPC_ALTAR_TARGET = 37704, + NPC_UTHER = 37225, + NPC_LICH_KING = 36954, + BOSS_LICH_KING = 37226, + NPC_ICE_WALL = 37014, + NPC_FALRIC = 38112, + NPC_MARWYN = 38113, + NPC_GHOSTLY_ROGUE = 38177, + NPC_GHOSTLY_PRIEST = 38175, + NPC_GHOSTLY_MAGE = 38172, + NPC_GHOSTLY_FOOTMAN = 38173, + NPC_GHOSTLY_RIFLEMAN = 38176, + NPC_GLUK = 38567, + + NPC_RAGING_GNOUL = 36940, + NPC_RISEN_WITCH_DOCTOR = 36941, + NPC_ABON = 37069, + + NPC_FROST_GENERAL = 36723, + NPC_SPIRITUAL_REFLECTION = 37068, + +// NPC_QUEL_DELAR = 37704, + NPC_QUEL_DELAR = 37158, + + GO_ICECROWN_DOOR = 201976, //72802 + GO_ICECROWN_DOOR_2 = 197342, + GO_ICECROWN_DOOR_3 = 197343, + GO_IMPENETRABLE_DOOR = 197341, //72801 + GO_FROSTMOURNE_ALTAR = 202236, //3551 + GO_FROSTMOURNE = 202302, //364 + + GO_ICE_WALL = 201385, + GO_CAVE = 201596, + GO_PORTAL = 202079, + + GO_CAPTAIN_CHEST_1 = 202212, //3145 + GO_CAPTAIN_CHEST_2 = 201710, //30357 + GO_CAPTAIN_CHEST_3 = 202337, //3246 + GO_CAPTAIN_CHEST_4 = 202336, //3333 +}; + +struct _Locations +{ + float x, y, z, o; + uint32 id; +}; + +static _Locations SpawnLoc[]= +{ + //Wing 01 + {5277.409f, 1993.161f, 707.694f, 0.05f}, //27 + {5301.876f, 2041.699f, 707.694f, 4.71f}, //1 + {5339.830f, 2020.887f, 707.694f, 3.14f}, //13 + {5311.041f, 2042.935f, 707.694f, 4.71f}, //3 + {5314.750f, 2039.969f, 707.694f, 4.71f}, //4 + {5342.823f, 2003.801f, 707.694f, 3.14f}, //10 + {5311.579f, 1972.823f, 707.694f, 1.62f}, //16 + + //Wing 02 + {5272.491f, 2005.673f, 707.694f, 0.05f}, //23 + {5302.669f, 1973.050f, 707.694f, 1.62f}, //18 + {5346.187f, 2008.058f, 707.694f, 3.14f}, //9 + {5319.752f, 2041.321f, 707.694f, 4.71f}, //5 + {5344.882f, 1998.714f, 707.694f, 3.14f}, //11 + {5340.552f, 1994.735f, 707.694f, 3.14f}, //12 + {5306.441f, 2040.358f, 707.694f, 4.71f}, //2 + + //Wing 03 + {5273.297f, 2014.009f, 707.694f, 0.05f}, //25 + {5316.062f, 1970.777f, 707.694f, 1.62f}, //15 + {5322.498f, 2037.415f, 707.694f, 4.71f}, //6 + {5307.087f, 1970.065f, 707.694f, 1.62f}, //17 + {5342.460f, 2012.391f, 707.694f, 3.14f}, //8 + {5297.601f, 1971.420f, 707.694f, 1.62f}, //19 + {5295.668f, 1975.853f, 707.694f, 1.62f}, //20 + + //Wing 04 + {5273.661f, 1996.767f, 707.694f, 0.05f}, //21 + {5275.228f, 2001.275f, 707.694f, 0.05f}, //22 + {5344.153f, 2017.753f, 707.694f, 3.14f}, //7 + {5275.310f, 2009.686f, 707.694f, 0.05f}, //24 + {5319.835f, 1975.177f, 707.694f, 1.62f}, //14 + {5277.445f, 2017.197f, 707.694f, 0.05f}, //26 + {5298.198f, 2037.762f, 707.694f, 4.71f} //0 +}; + +static _Locations WallLoc[]= +{ + {5540.39f, 2086.48f, 731.066f, 1.00057f}, + {5494.3f, 1978.27f, 736.689f, 1.0885f}, + {5434.27f, 1881.12f, 751.303f, 0.923328f}, + {5323.61f, 1755.85f, 770.305f, 0.784186f}, + {5239.01f, 1932.64f, 707.695f, 0.8f}, // Spawn point for Jaina && Silvana intro + {5266.779785f, 1953.42f, 707.697f, 1.0f}, + {5547.27002f, 2256.949951f, 733.010986f, 0.9f}, // Spawn point for Jaina && Silvana outro +}; + +#endif \ No newline at end of file diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp new file mode 100644 index 000000000..064beeee0 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp @@ -0,0 +1,1348 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Hall Of Reflection +SD%Complete: Who knows? :D +SDComment: event script! +SDErrors: They have, but i dont know were it! :D +SDCategory: hall_of_reflection +SDAuthor: MaxXx2021 aka Mioka +EndScriptData */ + +#include "precompiled.h" +#include "def_halls.h" +#include "escort_ai.h" + +enum +{ + /*INTRO - Pre Uther*/ + SAY_JAINA_INTRO_01 = -1594433, + SAY_SYLVANA_INTRO_01 = -1594434, + SAY_JAINA_INTRO_02 = -1594435, + SAY_JAINA_INTRO_03 = -1594436, + SAY_SYLVANA_INTRO_03 = -1594437, + SAY_JAINA_INTRO_04 = -1594438, + SAY_SYLVANA_INTRO_04 = -1594439, + + /*INTRO - Uther Dialog*/ + SAY_UTHER_A_01 = -1594440, + SAY_UTHER_H_01 = -1594441, + SAY_JAINA_02 = -1594442, + SAY_SYLVANA_02 = -1594443, + SAY_UTHER_A_03 = -1594444, + SAY_UTHER_H_03 = -1594445, + SAY_JAINA_04 = -1594446, + SAY_SYLVANA_04 = -1594447, + SAY_UTHER_A_05 = -1594448, + SAY_UTHER_H_05 = -1594449, + SAY_JAINA_06 = -1594450, + SAY_SYLVANA_06 = -1594451, + SAY_UTHER_A_07 = -1594452, + SAY_UTHER_H_07 = -1594453, + SAY_JAINA_08 = -1594454, + SAY_SYLVANA_08 = -1594455, + SAY_UTHER_A_09 = -1594456, + SAY_UTHER_H_09 = -1594457, + SAY_JAINA_10 = -1594458, + SAY_UTHER_A_11 = -1594459, + SAY_UTHER_H_11 = -1594460, + SAY_JAINA_12 = -1594461, + SAY_SYLVANA_12 = -1594462, + SAY_UTHER_A_13 = -1594463, + SAY_UTHER_A_14 = -1594464, + SAY_JAINA_15 = -1594465, + + /*INTRO - Lich King Arrive*/ + SAY_UTHER_A_16 = -1594466, + SAY_UTHER_H_16 = -1594467, + SAY_LICH_KING_17 = -1594468, + SAY_LICH_KING_18 = -1594469, + SAY_LICH_KING_19 = -1594470, + SAY_JAINA_20 = -1594471, + SAY_SYLVANA_20 = -1594472, + SAY_LICH_KING_A_21 = -1594473, + SAY_LICH_KING_H_21 = -1594474, + SAY_FALRIC_INTRO = -1594475, + SAY_MARWYN_INTRO = -1594476, + SAY_FALRIC_INTRO2 = -1594505, + + /*INTRO - Pre Escape*/ + SAY_LICH_KING_AGGRO_A = -1594477, + SAY_LICH_KING_AGGRO_H = -1594478, + SAY_JAINA_AGGRO = -1594479, + SAY_SYLVANA_AGGRO = -1594480, + + /*ESCAPE*/ + SAY_JAINA_WALL_01 = -1594487, + SAY_SYLVANA_WALL_01 = -1594488, + SAY_JAINA_WALL_02 = -1594489, + SAY_SYLVANA_WALL_02 = -1594490, + SAY_LICH_KING_WALL_02 = -1594491, + SAY_LICH_KING_WALL_03 = -1594492, + SAY_LICH_KING_WALL_04 = -1594493, + SAY_JAINA_WALL_03 = -1594494, + SAY_JAINA_WALL_04 = -1594495, + SAY_SYLVANA_WALL_03 = -1594496, + SAY_SYLVANA_WALL_04 = -1594497, + SAY_JAINA_ESCAPE_01 = -1594498, + SAY_JAINA_ESCAPE_02 = -1594499, + SAY_SYLVANA_ESCAPE_01 = -1594500, + SAY_SYLVANA_ESCAPE_02 = -1594501, + SAY_JAINA_TRAP = -1594502, + SAY_SYLVANA_TRAP = -1594503, + SAY_LICH_KING_END_01 = -1594506, + SAY_LICH_KING_END_02 = -1594507, + SAY_LICH_KING_END_03 = -1594508, + + SAY_ESCAPE_01 = -1594531, + SAY_ESCAPE_02 = -1594532, + SAY_ESCAPE_03 = -1594533, + + + /*SPELLS AND VISUAL EFFECTS*/ + SPELL_TAKE_FROSTMOURNE = 72729, + SPELL_FROSTMOURNE_DESPAWN = 72726, + SPELL_FROSTMOURNE_SOUNDS = 70667, + SPELL_CAST_VISUAL = 65633, //Jaina And Sylavana cast this when summon uther. + SPELL_BOSS_SPAWN_AURA = 72712, //Falric and Marwyn + SPELL_UTHER_DESPAWN = 70693, + SPELL_WINTER = 69780, + SPELL_FURY_OF_FROSTMOURNE = 70063, + SPELL_SOUL_REAPER = 73797, + SPELL_RAISE_DEAD = 69818, + SPELL_ICE_PRISON = 69708, + SPELL_DARK_ARROW = 70194, + SPELL_ICE_BARRIER = 69787, + SPELL_DESTROY_ICE_WALL_01 = 69784, //Jaina + SPELL_DESTROY_ICE_WALL_02 = 70224, + SPELL_DESTROY_ICE_WALL_03 = 70225, //Sylvana + SPELL_DESTRUCT_ICE_WALL = 69784, + SPELL_SUMMON_ICE_WALL = 69768, + SPELL_SYLVANA_JUMP = 68339, + SPELL_SYLVANA_STEP = 69087, + SPELL_SILENCE = 69413, + SPELL_LICH_KING_CAST = 57561, + SPELL_FROSTMOURNE_VISUAL = 73220, + SPELL_SHIELD_DISRUPTION = 58291, + + FACTION = 2076, +}; + +struct MANGOS_DLL_DECL npc_jaina_and_sylvana_HRintroAI : public ScriptedAI +{ + npc_jaina_and_sylvana_HRintroAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + BSWScriptedInstance* m_pInstance; + + Creature* pUther; + bool Small; + + void Reset() + { + m_creature->SetPhaseMask(65535, true); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + Small = false; + } + + void Event() + { + switch(m_pInstance->GetEvent(m_creature->GetEntry())) + { + case 1: + if (m_pInstance->GetData(TYPE_EVENT) == 2) + Small = true; + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + m_pInstance->SetNextEvent(2,m_creature->GetEntry(),2000); + break; + case 2: + if(m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_INTRO_01, m_creature); + m_pInstance->SetNextEvent(3,m_creature->GetEntry(),5000); + } + else if(m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_SYLVANA_INTRO_01, m_creature); + m_pInstance->SetNextEvent(3,m_creature->GetEntry(),8000); + } + break; + case 3: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_INTRO_02, m_creature); + m_pInstance->SetNextEvent(4,m_creature->GetEntry(),5000); + } + else if(m_creature->GetEntry() == NPC_SYLVANA) + m_pInstance->SetNextEvent(4,m_creature->GetEntry(),500); + break; + case 4: + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MovePoint(0, 5307.031f, 1997.920f, 709.341f); + m_pInstance->SetNextEvent(5,m_creature->GetEntry(),10000); + break; + case 5: + if(Creature* pTarget = m_creature->SummonCreature(NPC_ALTAR_TARGET,5309.374f,2006.788f,711.615f,1.37f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,360000)) + { + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTarget->GetGUID()); + pTarget->SetCreatorGuid(ObjectGuid()); + } + m_pInstance->SetNextEvent(6,m_creature->GetEntry(),1000); + break; + case 6: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_INTRO_03, m_creature); + m_pInstance->SetNextEvent(7,m_creature->GetEntry(),5000); + } + if (m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_SYLVANA_INTRO_03, m_creature); + m_pInstance->SetNextEvent(7,m_creature->GetEntry(),5000); + } + break; + case 7: + DoCast(m_creature, SPELL_CAST_VISUAL); + if (m_creature->GetEntry() == NPC_JAINA) + DoScriptText(SAY_JAINA_INTRO_04, m_creature); + else if (m_creature->GetEntry() == NPC_SYLVANA) + DoScriptText(SAY_SYLVANA_INTRO_04, m_creature); + m_pInstance->SetNextEvent(8,m_creature->GetEntry(),3000); + break; + case 8: + DoCast(m_creature, SPELL_FROSTMOURNE_SOUNDS); + if(GameObject* pFrostmourne = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_FROSTMOURNE))) + pFrostmourne->SetGoState(GO_STATE_ACTIVE); + if(m_creature->GetEntry() == NPC_JAINA) + m_pInstance->SetNextEvent(9,m_creature->GetEntry(),12000); + if(m_creature->GetEntry() == NPC_SYLVANA) + m_pInstance->SetNextEvent(9,m_creature->GetEntry(),8000); + break; + case 9: + if(Creature* Uther = m_creature->SummonCreature(NPC_UTHER,5308.228f,2003.641f,709.341f,4.17f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,360000)) + { + pUther = Uther; + Uther->SetCreatorGuid(ObjectGuid()); + Uther->SetRespawnDelay(DAY); + Uther->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Uther->GetGUID()); + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_UTHER_A_01, Uther); + m_pInstance->SetNextEvent(10,m_creature->GetEntry(),3000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_UTHER_H_01, Uther); + m_pInstance->SetNextEvent(10,m_creature->GetEntry(),10000); + } + } + break; + case 10: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_02, m_creature); + m_pInstance->SetNextEvent(11,m_creature->GetEntry(),5000); + } + else if(m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_SYLVANA_02, m_creature); + m_pInstance->SetNextEvent(11,m_creature->GetEntry(),3000); + } + break; + case 11: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + { + DoScriptText(SAY_UTHER_A_03, pUther); + m_pInstance->SetNextEvent(Small ? 24 : 12, m_creature->GetEntry(),7000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA && pUther) + { + DoScriptText(SAY_UTHER_H_03, pUther); + m_pInstance->SetNextEvent(Small ? 24 : 12, m_creature->GetEntry(),6000); + } + break; + case 12: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_04, m_creature); + m_pInstance->SetNextEvent(13,m_creature->GetEntry(),2000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_SYLVANA_04, m_creature); + m_pInstance->SetNextEvent(13,m_creature->GetEntry(),5000); + } + break; + case 13: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + { + DoScriptText(SAY_UTHER_A_05, pUther); + m_pInstance->SetNextEvent(14,m_creature->GetEntry(),10000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA && pUther) + { + DoScriptText(SAY_UTHER_H_05, pUther); + m_pInstance->SetNextEvent(14,m_creature->GetEntry(),19000); + } + break; + case 14: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_06, m_creature); + m_pInstance->SetNextEvent(15,m_creature->GetEntry(),6000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_SYLVANA_06, m_creature); + m_pInstance->SetNextEvent(15,m_creature->GetEntry(),2000); + } + break; + case 15: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + { + DoScriptText(SAY_UTHER_A_07, pUther); + m_pInstance->SetNextEvent(16,m_creature->GetEntry(),12000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA && pUther) + { + DoScriptText(SAY_UTHER_H_07, pUther); + m_pInstance->SetNextEvent(16,m_creature->GetEntry(),6000); + } + break; + case 16: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_08, m_creature); + m_pInstance->SetNextEvent(17,m_creature->GetEntry(),6000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_SYLVANA_08, m_creature); + m_pInstance->SetNextEvent(17,m_creature->GetEntry(),3000); + } + break; + case 17: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + { + DoScriptText(SAY_UTHER_A_09, pUther); + m_pInstance->SetNextEvent(18,m_creature->GetEntry(),12000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA && pUther) + { + DoScriptText(SAY_UTHER_H_09, pUther); + m_pInstance->SetNextEvent(18,m_creature->GetEntry(),11000); + } + break; + case 18: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_10, m_creature); + m_pInstance->SetNextEvent(19,m_creature->GetEntry(),12000); + } + else if(m_creature->GetEntry() == NPC_SYLVANA) + { + m_pInstance->SetNextEvent(19,m_creature->GetEntry(),500); + } + break; + case 19: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + { + DoScriptText(SAY_UTHER_A_11, pUther); + m_pInstance->SetNextEvent(20,m_creature->GetEntry(),24000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA && pUther) + { + DoScriptText(SAY_UTHER_H_11, pUther); + m_pInstance->SetNextEvent(20,m_creature->GetEntry(),9000); + } + break; + case 20: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_12, m_creature); + m_pInstance->SetNextEvent(21,m_creature->GetEntry(),2000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + DoScriptText(SAY_SYLVANA_12, m_creature); + m_pInstance->SetNextEvent(21,m_creature->GetEntry(),2100); + } + break; + case 21: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + { + DoScriptText(SAY_UTHER_A_13, pUther); + m_pInstance->SetNextEvent(22,m_creature->GetEntry(),5000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + m_pInstance->SetNextEvent(22,m_creature->GetEntry(),500); + } + break; + case 22: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + { + DoScriptText(SAY_UTHER_A_14, pUther); + m_pInstance->SetNextEvent(23,m_creature->GetEntry(),12000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + m_pInstance->SetNextEvent(23,m_creature->GetEntry(),500); + } + break; + case 23: + if (m_creature->GetEntry() == NPC_JAINA) + { + DoScriptText(SAY_JAINA_15, m_creature); + m_pInstance->SetNextEvent(24,m_creature->GetEntry(),2000); + } + else if (m_creature->GetEntry() == NPC_SYLVANA) + { + m_pInstance->SetNextEvent(24,m_creature->GetEntry(),500); + } + break; + case 24: + if (m_creature->GetEntry() == NPC_JAINA && pUther) + DoScriptText(SAY_UTHER_A_16, pUther); + else if (m_creature->GetEntry() == NPC_SYLVANA && pUther) + DoScriptText(SAY_UTHER_H_16, pUther); + if(Creature* LichKing = m_creature->SummonCreature(NPC_LICH_KING,5362.469f,2062.342f,707.695f,3.97f,TEMPSUMMON_MANUAL_DESPAWN,0,true)) + { + LichKing->SetRespawnDelay(DAY); + LichKing->SetCreatorGuid(ObjectGuid()); + } + m_pInstance->SetNextEvent(24,NPC_LICH_KING,2000); + break; + case 25: + if (pUther) + pUther->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); + m_pInstance->SetNextEvent(25,NPC_LICH_KING,2000); + break; + case 31: + m_creature->RemoveAurasDueToSpell(SPELL_FROSTMOURNE_SOUNDS); + m_pInstance->SetNextEvent(32,NPC_LICH_KING,4500); + break; + case 36: + if (m_creature->GetEntry() == NPC_JAINA) + DoScriptText(SAY_JAINA_20, m_creature); + else if(m_creature->GetEntry() == NPC_SYLVANA) + DoScriptText(SAY_SYLVANA_20, m_creature); + m_creature->GetMotionMaster()->MovePoint(0, 5443.880f, 2147.095f, 707.695f); + m_pInstance->SetNextEvent(37,NPC_LICH_KING,4000); + break; + case 39: + m_pInstance->SetNextEvent(40,NPC_LICH_KING,1000); + m_creature->ForcedDespawn(); + break; + default: + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetEventTimer(m_creature->GetEntry(),diff) && m_pInstance->GetData(TYPE_PHASE) == 1) + Event(); + + return; + } +}; + +bool GossipHello_npc_jaina_and_sylvana_HRintro(Player* pPlayer, Creature* pCreature) +{ + BSWScriptedInstance* m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData(); + + if(pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu( pCreature->GetGUID()); + + switch(pCreature->GetEntry()) + { + case NPC_JAINA: + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594536, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594537, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + break; + case NPC_SYLVANA: + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594538, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594539, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + break; + } + + pPlayer->PlayerTalkClass->SendGossipMenu(907,pCreature->GetGUID()); + return true; +} + +bool GossipSelect_npc_jaina_and_sylvana_HRintro(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + BSWScriptedInstance* m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData(); + + if (!m_pInstance) return false; + + switch (uiAction) + { + case GOSSIP_ACTION_INFO_DEF+1: + pPlayer->CLOSE_GOSSIP_MENU(); + m_pInstance->SetData(TYPE_EVENT, 1); + m_pInstance->SetData(TYPE_PHASE, 1); + break; + case GOSSIP_ACTION_INFO_DEF+2: + pPlayer->CLOSE_GOSSIP_MENU(); + m_pInstance->SetData(TYPE_EVENT, 2); + m_pInstance->SetData(TYPE_PHASE, 1); + break; + } + + m_pInstance->SetNextEvent(1, pCreature->GetEntry(), 500); + + m_pInstance->SetData64(DATA_ESCAPE_LIDER,pCreature->GetGUID()); + + return true; +} + +struct MANGOS_DLL_DECL npc_jaina_and_sylvana_HRextroAI : public npc_escortAI +{ + npc_jaina_and_sylvana_HRextroAI(Creature *pCreature) : npc_escortAI(pCreature) + { + m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + BSWScriptedInstance* m_pInstance; + + uint32 CastTimer; + int32 HoldTimer; + uint8 m_wallNum; + bool Fight; + ObjectGuid wallTarget; + uint32 m_chestID; + + void Reset() + { + if(!m_pInstance) return; + + if(m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS) return; + + HoldTimer = 10000; + Fight = true; + m_wallNum = 0; + wallTarget = ObjectGuid(); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + + if(m_creature->GetEntry() == NPC_JAINA_OUTRO) + { + m_creature->CastSpell(m_creature, SPELL_ICE_BARRIER, false); + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2HL); + } + + } + + void AttackStart(Unit* who) + { + if (!who) + return; + + if (m_creature->GetEntry() != NPC_SYLVANA_OUTRO) + return; + + if (m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS || Fight != true) + return; + + npc_escortAI::AttackStart(who); + + } + + void JustDied(Unit* pKiller) + { + if(!m_pInstance) + return; + DoDestructWall(); + } + + void DoSummonWall(uint8 wallNum) + { + if(!m_pInstance || wallNum > 3) + return; + + m_wallNum = wallNum+1; + HoldTimer = 20000; + + switch (wallNum) + { + case 0: m_pInstance->SetNextEvent(200,BOSS_LICH_KING,500); break; + case 1: m_pInstance->SetNextEvent(300,BOSS_LICH_KING,500); break; + case 2: m_pInstance->SetNextEvent(400,BOSS_LICH_KING,500); break; + case 3: m_pInstance->SetNextEvent(500,BOSS_LICH_KING,500); break; + default: + break; + } + + if (Creature* pWallTarget = m_creature->SummonCreature(NPC_ICE_WALL,WallLoc[wallNum].x,WallLoc[wallNum].y,WallLoc[wallNum].z,WallLoc[wallNum].o,TEMPSUMMON_MANUAL_DESPAWN,0, true)) + { + pWallTarget->SetPhaseMask(65535, true); + pWallTarget->setFaction(114); + pWallTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pWallTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + wallTarget = pWallTarget->GetObjectGuid(); + pWallTarget->CastSpell(pWallTarget, SPELL_SUMMON_ICE_WALL, false); + } + } + + void DoDestructWall() + { + m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICE_WALL)); + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + { + pWallTarget->ForcedDespawn(); + } + wallTarget = ObjectGuid(); + m_wallNum = 0; + } + + void WaypointReached(uint32 i) + { + switch(i) + { + case 0: + break; + case 1: + break; + case 2: + DoSummonWall(0); + break; + case 3: + break; + case 4: + if (m_creature->GetEntry() == NPC_JAINA_OUTRO) + DoScriptText(SAY_JAINA_WALL_01, m_creature); + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + DoScriptText(SAY_SYLVANA_WALL_01, m_creature); + CastTimer = 1000; + SetEscortPaused(true); + if(m_creature->GetEntry() == NPC_JAINA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false); + } + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false); + } + break; + case 5: + break; + case 6: + DoSummonWall(1); + break; + case 7: + break; + case 8: + if (m_creature->GetEntry() == NPC_JAINA_OUTRO) + DoScriptText(SAY_JAINA_WALL_02, m_creature); + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + DoScriptText(SAY_SYLVANA_WALL_02, m_creature); + CastTimer = 1000; + SetEscortPaused(true); + if(m_creature->GetEntry() == NPC_JAINA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false); + } + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false); + } + break; + case 9: + if (m_creature->GetEntry() == NPC_JAINA_OUTRO) + DoScriptText(SAY_JAINA_ESCAPE_01, m_creature); + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + DoScriptText(SAY_SYLVANA_ESCAPE_01, m_creature); + DoSummonWall(2); + break; + case 10: + break; + case 11: + break; + case 12: + if(m_creature->GetEntry() == NPC_JAINA_OUTRO) + DoScriptText(SAY_JAINA_WALL_03, m_creature); + if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + DoScriptText(SAY_SYLVANA_WALL_03, m_creature); + CastTimer = 1000; + SetEscortPaused(true); + if(m_creature->GetEntry() == NPC_JAINA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false); + } + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false); + } + break; + case 13: + if (m_creature->GetEntry() == NPC_JAINA_OUTRO) + DoScriptText(SAY_JAINA_ESCAPE_02, m_creature); + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + DoScriptText(SAY_SYLVANA_ESCAPE_02, m_creature); + break; + case 14: + break; + case 15: + DoSummonWall(3); + break; + case 16: + if (m_creature->GetEntry() == NPC_JAINA_OUTRO) + DoScriptText(SAY_JAINA_WALL_04, m_creature); + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + DoScriptText(SAY_SYLVANA_WALL_04, m_creature); + CastTimer = 1000; + SetEscortPaused(true); + if(m_creature->GetEntry() == NPC_JAINA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false); + } + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false); + } + break; + case 17: + break; + case 18: + break; + case 19: + if (m_creature->GetEntry() == NPC_JAINA_OUTRO) + DoScriptText(SAY_JAINA_TRAP, m_creature); + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + DoScriptText(SAY_SYLVANA_TRAP, m_creature); + break; + case 20: + SetEscortPaused(true); + if (m_creature->GetEntry() == NPC_JAINA_OUTRO) + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2HL); + else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H); + break; + default: + break; + } + } + + void Intro() + { + switch(m_pInstance->GetEvent(m_creature->GetEntry())) + { + case 100: + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + { + if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + AttackStart(pLichKing); + } + m_pInstance->SetNextEvent(101,BOSS_LICH_KING,500); + break; + case 102: + if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + Fight = false; + m_creature->GetMotionMaster()->MovePoint(0, (m_creature->GetPositionX()-5)+rand()%10, (m_creature->GetPositionY()-5)+rand()%10, m_creature->GetPositionZ()); + m_pInstance->SetNextEvent(103,m_creature->GetEntry(),3000); + } + else + m_pInstance->SetNextEvent(103,m_creature->GetEntry(),500); + break; + case 103: + if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + Fight = true; + m_pInstance->SetNextEvent(104,m_creature->GetEntry(),500); + break; + case 104: + if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + m_creature->CastSpell(pLichKing, SPELL_SYLVANA_STEP, false); + m_pInstance->SetNextEvent(105,m_creature->GetEntry(),3000); + } + else + m_pInstance->SetNextEvent(105,m_creature->GetEntry(),500); + break; + case 105: + if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + Fight = false; + m_creature->GetMotionMaster()->MovePoint(0, (m_creature->GetPositionX()-5)+rand()%10, (m_creature->GetPositionY()-5)+rand()%10, m_creature->GetPositionZ()); + m_pInstance->SetNextEvent(106,m_creature->GetEntry(),3000); + } + else + m_pInstance->SetNextEvent(106,m_creature->GetEntry(),12000); + break; + case 106: + Fight = true; + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + m_creature->CastSpell(pLichKing,(m_creature->GetEntry() == NPC_JAINA_OUTRO ? SPELL_ICE_PRISON : SPELL_DARK_ARROW),true); + m_pInstance->SetNextEvent(107,m_creature->GetEntry(),2500); + break; + case 107: + if(m_creature->GetEntry() == NPC_JAINA_OUTRO) + { + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + if (!pLichKing->HasAura(SPELL_ICE_PRISON)) + pLichKing->CastSpell(pLichKing,SPELL_ICE_PRISON,true); + m_creature->RemoveAurasDueToSpell(SPELL_ICE_BARRIER); + DoScriptText(SAY_JAINA_AGGRO, m_creature); + } + else if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO) + { + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + if (!pLichKing->HasAura(SPELL_DARK_ARROW)) + pLichKing->CastSpell(pLichKing,SPELL_DARK_ARROW,true); + DoScriptText(SAY_SYLVANA_AGGRO, m_creature); + } + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); + m_creature->AttackStop(); + m_pInstance->SetNextEvent(108,m_creature->GetEntry(),3000); + break; + case 108: + m_creature->GetMotionMaster()->MovePoint(0, 5577.187f, 2236.003f, 733.012f); + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_pInstance->GetData64(BOSS_LICH_KING)); + m_pInstance->SetNextEvent(109,m_creature->GetEntry(),10000); + break; + case 109: + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); +// Count = 1; + m_pInstance->SetNextEvent(110,m_creature->GetEntry(),10000); + break; + } + } + + void Outro() + { + switch(m_pInstance->GetEvent(m_creature->GetEntry())) + { + case 610: + m_creature->CastSpell(m_creature, SPELL_SHIELD_DISRUPTION,false); + m_pInstance->SetData(DATA_ESCAPE_LIDER,m_creature->GetEntry()); + m_creature->SummonGameobject(GO_CAVE, 5275.28f, 1694.23f, 786.147f, 0.981225f, 0); + m_pInstance->SetNextEvent(611,m_creature->GetEntry(),6000); + break; + case 611: + if (GameObject* pCave = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CAVE))) + pCave->SetGoState(GO_STATE_READY); + m_creature->RemoveAurasDueToSpell(SPELL_SILENCE); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + m_creature->CastSpell(m_creature, SPELL_SHIELD_DISRUPTION,false); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MovePoint(0, 5258.911328f,1652.112f,784.295166f); + DoScriptText(SAY_ESCAPE_01, m_creature); + m_pInstance->SetNextEvent(612,m_creature->GetEntry(),10000); + break; + case 612: + m_pInstance->SetData(TYPE_LICH_KING, DONE); + DoScriptText(SAY_ESCAPE_02, m_creature); + m_pInstance->SetNextEvent(613,m_creature->GetEntry(),10000); + break; + case 613: + DoScriptText(SAY_ESCAPE_03, m_creature); + m_pInstance->SetNextEvent(614,m_creature->GetEntry(),10000); + break; + case 614: + m_creature->GetMotionMaster()->MovePoint(0, 5240.66f, 1646.93f, 784.302f); + m_pInstance->SetNextEvent(615,m_creature->GetEntry(),5000); + break; + case 615: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); + m_creature->SetOrientation(0.68f); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + m_pInstance->SetNextEvent(616,m_creature->GetEntry(),5000); + break; + } + } + + void UpdateEscortAI(const uint32 diff) + { + if(!m_pInstance || m_pInstance->GetData(TYPE_PHASE) < 4) + return; + + if (m_pInstance->GetData(TYPE_PHASE) == 6 && m_pInstance->GetEventTimer(m_creature->GetEntry(),diff)) + { + Outro(); + return; + } + + DoMeleeAttackIfReady(); + + if (m_pInstance->GetData(TYPE_PHASE) == 4 && m_pInstance->GetEventTimer(m_creature->GetEntry(),diff)) + { + Intro(); + return; + } + + if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO && !wallTarget.IsEmpty() && m_wallNum && CastTimer < diff) + { + if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget)) + m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_03, false); + CastTimer = 1000; + } + else + CastTimer -= diff; + + if (!wallTarget.IsEmpty() && m_wallNum && m_pInstance->GetData(DATA_SUMMONS) == 0 && HoldTimer < 1000) + { + m_creature->InterruptNonMeleeSpells(false); + SetEscortPaused(false); + + switch(m_wallNum) + { + case 1: + DoDestructWall(); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + DoScriptText(SAY_LICH_KING_WALL_02, pLichKing); + break; + case 2: + DoDestructWall(); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + DoScriptText(SAY_LICH_KING_WALL_03, pLichKing); + break; + case 3: + DoDestructWall(); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + DoScriptText(SAY_LICH_KING_WALL_04, pLichKing); + break; + case 4: + DoDestructWall(); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING))) + { + pLichKing->RemoveAurasDueToSpell(SPELL_WINTER); + pLichKing->SetSpeedRate(MOVE_WALK, 2.5f, true); + } + break; + } + HoldTimer = 10000; + } + else + { + if (HoldTimer <= diff) + HoldTimer = 0; + else + HoldTimer -= diff; + } + } +}; + +bool GossipHello_npc_jaina_and_sylvana_HRextro(Player* pPlayer, Creature* pCreature) +{ + + ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + + if(!m_pInstance) return false; + + if(m_pInstance->GetData(TYPE_LICH_KING) == DONE) return false; + + if(pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu( pCreature->GetGUID()); + + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594540, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_jaina_and_sylvana_HRextro(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + switch (uiAction) + { + case GOSSIP_ACTION_INFO_DEF+1: + pPlayer->CLOSE_GOSSIP_MENU(); + ((npc_jaina_and_sylvana_HRextroAI*)pCreature->AI())->Start(true); + pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + pCreature->SetUInt64Value(UNIT_FIELD_TARGET, 0); + + if(m_pInstance) + { + m_pInstance->SetData64(DATA_ESCAPE_LIDER, pCreature->GetGUID()); + m_pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS); + m_pInstance->SetData(TYPE_PHASE, 5); + } + return true; + break; + default: return false; + } +} + +CreatureAI* GetAI_npc_jaina_and_sylvana_HRintro(Creature* pCreature) +{ + return new npc_jaina_and_sylvana_HRintroAI(pCreature); +} + +CreatureAI* GetAI_npc_jaina_and_sylvana_HRextro(Creature* pCreature) +{ + return new npc_jaina_and_sylvana_HRextroAI(pCreature); +} + +enum GENERAL_EVENT +{ + SAY_AGGRO = -1594519, + SAY_DEATH = -1594520, + + SPELL_SHIELD_THROWN = 69222, +}; + +struct MANGOS_DLL_DECL npc_frostworn_generalAI : public ScriptedAI +{ + npc_frostworn_generalAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiShieldTimer; + + void Reset() + { + if (!m_pInstance) + return; + m_uiShieldTimer = 5000; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + DoScriptText(SAY_DEATH, m_creature); + m_pInstance->SetData(TYPE_FROST_GENERAL, DONE); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_creature->getVictim()) + return; + + if (pWho->GetTypeId() != TYPEID_PLAYER + || m_pInstance->GetData(TYPE_MARWYN) != DONE + || !m_creature->IsWithinDistInMap(pWho, 30.0f) + ) return; + + if (Player* pPlayer = (Player*)pWho) + if (pPlayer->isGameMaster()) return; + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + AttackStart(pWho); + } + + void Aggro(Unit* pVictim) + { + if (!m_pInstance) + return; + DoScriptText(SAY_AGGRO, m_creature); + m_pInstance->SetData(TYPE_FROST_GENERAL, IN_PROGRESS); + + Map::PlayerList const &pList = m_creature->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i) + { + if (Player* pPlayer = i->getSource()) + { + if (pPlayer && pPlayer->isAlive() && pPlayer->IsInMap(m_creature)) + { + if (Creature* pMirror = m_creature->SummonCreature(NPC_SPIRITUAL_REFLECTION,0,0,0,0,TEMPSUMMON_DEAD_DESPAWN,0, true)) + { + pMirror->SetPhaseMask(65535, true); + pMirror->SetInCombatWith(pPlayer); + pMirror->AddThreat(pPlayer, 1000.0f); + } + + } + } + }; + + } + + void UpdateAI(const uint32 uiDiff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiShieldTimer < uiDiff) + { + if(Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget,SPELL_SHIELD_THROWN); + m_uiShieldTimer = urand(4000, 8000); + } + else m_uiShieldTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_frostworn_general(Creature* pCreature) +{ + return new npc_frostworn_generalAI(pCreature); +} + +enum spiritual_reflection +{ + SPELL_REFLECTION_GHOST = 69861, + SPELL_CLONE = 69828, + SPELL_CLONE2 = 69837, + + SPELL_BALEFUL_STRIKE = 69933, + SPELL_SPIRIT_BURST = 69900, + +}; + +struct MANGOS_DLL_DECL npc_spiritual_reflectionAI : public BSWScriptedAI +{ + npc_spiritual_reflectionAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool isMirror; + ObjectGuid victimGuid; + + void Reset() + { + if (!m_pInstance) + return; + isMirror = false; + victimGuid = ObjectGuid(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void Aggro(Unit* pVictim) + { + if (!m_pInstance || !pVictim || pVictim->GetTypeId() != TYPEID_PLAYER) + return; + + if (victimGuid.IsEmpty()) + victimGuid = pVictim->GetObjectGuid(); + + DoStartMovement(pVictim); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_pInstance || !m_creature ) + return; + + if (uiDamage >= m_creature->GetHealth()) + doCast(SPELL_SPIRIT_BURST); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_FROST_GENERAL) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (!isMirror) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit(victimGuid)) + if (m_creature->IsWithinDistInMap(pVictim, 5.0f)) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pVictim->CastSpell(m_creature, SPELL_CLONE, true); + pVictim->CastSpell(m_creature, SPELL_CLONE2, true); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, pVictim->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID)); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, pVictim->GetUInt32Value(PLAYER_VISIBLE_ITEM_17_ENTRYID)); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+2, pVictim->GetUInt32Value(PLAYER_VISIBLE_ITEM_18_ENTRYID)); + pVictim->CastSpell(m_creature, SPELL_REFLECTION_GHOST, true); + isMirror = true; + } + } + + if (!isMirror) + return; + + timedCast(SPELL_BALEFUL_STRIKE,uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_spiritual_reflection(Creature* pCreature) +{ + return new npc_spiritual_reflectionAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_queldelar_horAI : public ScriptedAI +{ + npc_queldelar_horAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + BSWScriptedInstance* m_pInstance; + bool intro; + Team team; + uint32 newLeader; + + void Reset() + { + intro = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_pInstance || intro) + return; + + if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER || !pWho->IsWithinDistInMap(m_creature, 22.0f)) + return; + + debug_log("HOR event started"); + + intro = true; + + if (m_pInstance->GetData(TYPE_LICH_KING) == DONE) + return; + else if (m_pInstance->GetData(TYPE_FROST_GENERAL) == DONE) + { + m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR)); + m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICECROWN_DOOR_2)); + m_pInstance->SetData(TYPE_PHASE, 3); + return; + } + else if (m_pInstance->GetData(TYPE_MARWYN) == DONE) + { + m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR)); + return; + } + else if (m_pInstance->GetData(TYPE_FALRIC) == DONE) + { + if (Creature* pMarwyn = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MARWYN))) + { + pMarwyn->SetVisibility(VISIBILITY_ON); + pMarwyn->CastSpell(pMarwyn, SPELL_BOSS_SPAWN_AURA, false); + m_pInstance->SetData(TYPE_EVENT, 7); + m_pInstance->SetData(TYPE_MARWYN, SPECIAL); + } + return; + } + + + if (Group* pGroup = ((Player*)pWho)->GetGroup()) + { + ObjectGuid LeaderGuid = pGroup->GetLeaderGuid(); + if (!LeaderGuid.IsEmpty()) + if (Player* pLeader =m_creature->GetMap()->GetPlayer(LeaderGuid)) + team = pLeader->GetTeam(); + } + else + team = ((Player*)pWho)->GetTeam(); + + + if (team == ALLIANCE) + newLeader = NPC_JAINA; + else + newLeader = NPC_SYLVANA; + + debug_log("HOR event: team %u, leader %u ",team,newLeader); + + if (Creature* pNewLeader = m_creature->SummonCreature(newLeader,WallLoc[4].x,WallLoc[4].y,WallLoc[4].z,WallLoc[4].o,TEMPSUMMON_MANUAL_DESPAWN,0,true)) + { + pNewLeader->SetCreatorGuid(ObjectGuid()); + pNewLeader->setFaction(35); + pNewLeader->SetPhaseMask(65535, true); + pNewLeader->GetMotionMaster()->MovePoint(0, WallLoc[5].x,WallLoc[5].y,WallLoc[5].z); + pNewLeader->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pNewLeader->SetSpeedRate(MOVE_RUN, 1.0f, true); + pNewLeader->SetRespawnDelay(DAY); + } +// m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 63135); + } + + void AttackStart(Unit* who) + { + return; + } + + void UpdateAI(const uint32 diff) + { + } +}; +CreatureAI* GetAI_npc_queldelar_hor(Creature* pCreature) +{ + return new npc_queldelar_horAI(pCreature); +} + + +void AddSC_halls_of_reflection() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_jaina_and_sylvana_HRintro"; + newscript->GetAI = &GetAI_npc_jaina_and_sylvana_HRintro; + newscript->pGossipHello = &GossipHello_npc_jaina_and_sylvana_HRintro; + newscript->pGossipSelect = &GossipSelect_npc_jaina_and_sylvana_HRintro; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_jaina_and_sylvana_HRextro"; + newscript->GetAI = &GetAI_npc_jaina_and_sylvana_HRextro; + newscript->pGossipHello = &GossipHello_npc_jaina_and_sylvana_HRextro; + newscript->pGossipSelect = &GossipSelect_npc_jaina_and_sylvana_HRextro; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_frostworn_general"; + newscript->GetAI = &GetAI_npc_frostworn_general; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_spiritual_reflection"; + newscript->GetAI = &GetAI_npc_spiritual_reflection; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_queldelar_hor"; + newscript->GetAI = &GetAI_npc_queldelar_hor; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.h b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.h new file mode 100644 index 000000000..b254d65cd --- /dev/null +++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.h @@ -0,0 +1,3 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp new file mode 100644 index 000000000..06354d2bd --- /dev/null +++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp @@ -0,0 +1,322 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: instance_halls_of_reflection +SD%Complete: 70% +SDComment: +SDErrors: +SDCategory: instance script +SDAuthor: /dev/rsa, modified by MaxXx2021 aka Mioka +EndScriptData */ + +#include "precompiled.h" +#include "def_halls.h" +#include "World.h" + +struct MANGOS_DLL_DECL instance_halls_of_reflection : public BSWScriptedInstance +{ + instance_halls_of_reflection(Map* pMap) : BSWScriptedInstance(pMap) + { + Difficulty = pMap->GetDifficulty(); + Initialize(); + } + + uint32 m_auiEncounter[MAX_ENCOUNTERS+1]; + std::string strSaveData; + + uint8 Difficulty; + uint8 m_uiSummons; + + uint32 m_auiLeader; + + uint64 m_uiFalricGUID; + uint64 m_uiMarwynGUID; + uint64 m_uiLichKingGUID; + uint64 m_uiLiderGUID; + uint64 m_uiUtherGUID; + + uint64 m_uiQuelDelarGUID; + + uint64 m_uiMainGateGUID; + uint64 m_uiExitGateGUID; + uint64 m_uiDoor2GUID; + uint64 m_uiDoor3GUID; + + uint64 m_uiFrostGeneralGUID; + uint64 m_uiCaptainsChestHordeGUID; + uint64 m_uiCaptainsChestAllianceGUID; + uint64 m_uiFrostmourneGUID; + uint64 m_uiFrostmourneAltarGUID; + uint64 m_uiPortalGUID; + uint64 m_uiIceWallGUID; + uint64 m_uiCaveGUID; + + void Initialize() + { + for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + m_auiEncounter[i] = NOT_STARTED; + m_uiMainGateGUID = 0; + m_uiFrostmourneGUID = 0; + m_uiFalricGUID = 0; + m_uiLiderGUID = 0; + m_uiLichKingGUID = 0; + m_uiExitGateGUID = 0; + m_uiSummons = 0; + m_uiIceWallGUID = 0; + m_uiCaveGUID = 0; + } + + void OnCreatureCreate(Creature* pCreature) + { + switch(pCreature->GetEntry()) + { + case NPC_FALRIC: + m_uiFalricGUID = pCreature->GetGUID(); + break; + case NPC_MARWYN: + m_uiMarwynGUID = pCreature->GetGUID(); + break; + case BOSS_LICH_KING: + m_uiLichKingGUID = pCreature->GetGUID(); + break; + case NPC_FROST_GENERAL: + m_uiFrostGeneralGUID = pCreature->GetGUID(); + break; + case NPC_QUEL_DELAR: + m_uiQuelDelarGUID = pCreature->GetGUID(); + break; + case NPC_UTHER: + m_uiUtherGUID = pCreature->GetGUID(); + break; + } + } + + void OnObjectCreate(GameObject* pGo) + { + switch(pGo->GetEntry()) + { + case GO_IMPENETRABLE_DOOR: m_uiMainGateGUID = pGo->GetGUID(); + if (GetData(TYPE_MARWYN) == DONE) + DoOpenDoor(m_uiMainGateGUID); + break; + case GO_FROSTMOURNE: m_uiFrostmourneGUID = pGo->GetGUID(); break; + case GO_ICECROWN_DOOR: m_uiExitGateGUID = pGo->GetGUID(); break; + case GO_ICECROWN_DOOR_2: m_uiDoor2GUID = pGo->GetGUID(); + if (GetData(TYPE_FROST_GENERAL) == DONE) + DoOpenDoor(m_uiDoor2GUID); + break; + case GO_ICECROWN_DOOR_3: m_uiDoor3GUID = pGo->GetGUID(); break; + case GO_PORTAL: m_uiPortalGUID = pGo->GetGUID(); break; + case GO_CAPTAIN_CHEST_1: + if (Difficulty == RAID_DIFFICULTY_10MAN_NORMAL) + m_uiCaptainsChestHordeGUID = pGo->GetGUID(); + break; + case GO_CAPTAIN_CHEST_3: + if (Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) + m_uiCaptainsChestHordeGUID = pGo->GetGUID(); + break; + case GO_CAPTAIN_CHEST_2: + if (Difficulty == RAID_DIFFICULTY_10MAN_NORMAL) + m_uiCaptainsChestAllianceGUID = pGo->GetGUID(); + break; + case GO_CAPTAIN_CHEST_4: + if (Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) + m_uiCaptainsChestAllianceGUID = pGo->GetGUID(); + break; + + case GO_ICE_WALL: m_uiIceWallGUID = pGo->GetGUID(); + pGo->SetPhaseMask(65535, true); + break; + case GO_CAVE: m_uiCaveGUID = pGo->GetGUID(); + DoOpenDoor(m_uiCaveGUID); + break; + } + } + + void SetData(uint32 uiType, uint32 uiData) + { + switch(uiType) + { + case TYPE_PHASE: m_auiEncounter[uiType] = uiData; break; + case TYPE_EVENT: m_auiEncounter[uiType] = uiData; + uiData = NOT_STARTED; + break; + case TYPE_FALRIC: m_auiEncounter[uiType] = uiData; + if (uiData == SPECIAL) + DoCloseDoor(m_uiExitGateGUID); + else if (uiData == FAIL) + DoOpenDoor(m_uiExitGateGUID); + break; + case TYPE_MARWYN: m_auiEncounter[uiType] = uiData; + if (uiData == SPECIAL) + DoCloseDoor(m_uiExitGateGUID); + else if (uiData == FAIL) + DoOpenDoor(m_uiExitGateGUID); + else if (uiData == DONE) + { + DoOpenDoor(m_uiMainGateGUID); + DoOpenDoor(m_uiExitGateGUID); + } + break; + case TYPE_FROST_GENERAL: m_auiEncounter[uiType] = uiData; + if(uiData == DONE) + DoOpenDoor(m_uiDoor2GUID); + break; + case TYPE_LICH_KING: m_auiEncounter[uiType] = uiData; + if(uiData == IN_PROGRESS) + DoOpenDoor(m_uiDoor3GUID); + if(uiData == DONE) + { + if (GameObject* pChest = instance->GetGameObject(m_uiCaptainsChestAllianceGUID)) + if (pChest && !pChest->isSpawned() && GetData(DATA_ESCAPE_LIDER) == NPC_JAINA_OUTRO) + { + pChest->SetRespawnTime(DAY); + } + if (GameObject* pChest = instance->GetGameObject(m_uiCaptainsChestHordeGUID)) + if (pChest && !pChest->isSpawned() && GetData(DATA_ESCAPE_LIDER) == NPC_SYLVANA_OUTRO) + { + pChest->SetRespawnTime(DAY); + }; + if (GameObject* pPortal = instance->GetGameObject(m_uiPortalGUID)) + if (pPortal && !pPortal->isSpawned()) + { + pPortal->SetRespawnTime(DAY); + }; + } + break; + case TYPE_HALLS: m_auiEncounter[uiType] = uiData; break; + case DATA_SUMMONS: if (uiData == 3) m_uiSummons = 0; + else if (uiData == 1) ++m_uiSummons; + else if (uiData == 0) --m_uiSummons; + uiData = NOT_STARTED; + break; + case DATA_ESCAPE_LIDER: m_auiLeader = uiData; + uiData = NOT_STARTED; + break; + default: + break; + } + + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + saveStream << m_auiEncounter[i] << " "; + + strSaveData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + const char* Save() + { + return strSaveData.c_str(); + } + + uint32 GetData(uint32 uiType) + { + switch(uiType) + { + case TYPE_PHASE: return m_auiEncounter[uiType]; + case TYPE_EVENT: return m_auiEncounter[uiType]; + case TYPE_FALRIC: return m_auiEncounter[uiType]; + case TYPE_MARWYN: return m_auiEncounter[uiType]; + case TYPE_LICH_KING: return m_auiEncounter[uiType]; + case TYPE_FROST_GENERAL: return m_auiEncounter[uiType]; + case TYPE_HALLS: return m_auiEncounter[uiType]; + case DATA_SUMMONS: return m_uiSummons; + case DATA_ESCAPE_LIDER: return m_auiLeader; + default: return 0; + } + return 0; + } + + void SetData64(uint32 uiData, uint64 uiGuid) + { + switch(uiData) + { + case DATA_ESCAPE_LIDER: + m_uiLiderGUID = uiGuid; + break; + } + } + + uint64 GetData64(uint32 uiData) + { + switch(uiData) + { + case GO_IMPENETRABLE_DOOR: return m_uiMainGateGUID; + case GO_FROSTMOURNE: return m_uiFrostmourneGUID; + case NPC_FALRIC: return m_uiFalricGUID; + case NPC_MARWYN: return m_uiMarwynGUID; + case NPC_UTHER: return m_uiUtherGUID; + case BOSS_LICH_KING: return m_uiLichKingGUID; + case DATA_ESCAPE_LIDER: return m_uiLiderGUID; + case NPC_FROST_GENERAL: return m_uiFrostGeneralGUID; + case NPC_QUEL_DELAR: return m_uiQuelDelarGUID; + case GO_ICECROWN_DOOR: return m_uiExitGateGUID; + case GO_ICECROWN_DOOR_2: return m_uiDoor2GUID; + case GO_ICECROWN_DOOR_3: return m_uiDoor3GUID; + case GO_ICE_WALL: return m_uiIceWallGUID; + case GO_CAVE: return m_uiCaveGUID; + } + return 0; + } + + void Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + { + loadStream >> m_auiEncounter[i]; + + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; + } + +}; + +InstanceData* GetInstanceData_instance_halls_of_reflection(Map* pMap) +{ + return new instance_halls_of_reflection(pMap); +} + +void AddSC_instance_halls_of_reflection() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_halls_of_reflection"; + newscript->GetInstanceData = &GetInstanceData_instance_halls_of_reflection; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp new file mode 100644 index 000000000..04f6657b6 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp @@ -0,0 +1,229 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_forgemaster_garfrost +SD%Complete: 70 +SDComment: TODO movement to the forges currently workaround (need core support for Jump-MMGen) +SDCategory: Pit of Saron +EndScriptData */ + +#include "precompiled.h" +#include "pit_of_saron.h" +enum saysSD2 +{ + SAY_AGGRO = -1658014, + SAY_SLAY_1 = -1658015, + SAY_BOULDER_HIT = -1658016, // TODO How must this be handled? + SAY_DEATH = -1658017, + SAY_FORGE_1 = -1658018, + SAY_FORGE_2 = -1658019, + SAY_TYRANNUS_GARFROST = -1658020, + SAY_GENERAL_GARFROST = -1658021, + + EMOTE_THROW_SARONITE = -1658022, + EMOTE_DEEP_FREEZE = -1658023, + + SPELL_PERMAFROST = 70326, + SPELL_THROW_SARONITE = 68788, + SPELL_THUNDERING_STOMP = 68771, + SPELL_FORGE_FROZEN_BLADE = 68774, + SPELL_CHILLING_WAVE = 68778, + SPELL_FORGE_FROSTBORN_MACE = 68785, + SPELL_DEEP_FREEZE = 70381, + + PHASE_NO_ENCHANTMENT = 1, + PHASE_BLADE_ENCHANTMENT = 2, + PHASE_MACE_ENCHANTMENT = 3, + PHASE_MOVEMENT = 4, +}; + +static const float aGarfrostMoveLocs[2][3] = +{ + {719.785f, -230.227f, 527.033f}, + {657.539f, -203.564f, 526.691f}, +}; + +struct MANGOS_DLL_DECL boss_forgemaster_garfrostAI : public ScriptedAI +{ + boss_forgemaster_garfrostAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiThrowSaroniteTimer; + uint32 m_uiPhase; + uint32 m_uiChillingWaveTimer; + uint32 m_uiDeepFreezeTimer; + + void Reset() + { + m_uiThrowSaroniteTimer = 13000; + m_uiChillingWaveTimer = 10000; + m_uiDeepFreezeTimer = 10000; + SetCombatMovement(true); + m_uiPhase = PHASE_NO_ENCHANTMENT; + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_AGGRO, m_creature, pWho); + DoCastSpellIfCan(m_creature, SPELL_PERMAFROST); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature, pKiller); + } + + void KilledUnit() + { + DoScriptText(SAY_SLAY_1, m_creature); + } + + void MovementInform(uint32 uiMotionType, uint32 uiPointId) + { + // TODO Change to jump movement type when proper implemented + if (uiMotionType != POINT_MOTION_TYPE) + return; + + if (uiPointId != PHASE_BLADE_ENCHANTMENT && uiPointId != PHASE_MACE_ENCHANTMENT) + return; + + // Cast and say expected spell + DoCastSpellIfCan(m_creature, uiPointId == PHASE_BLADE_ENCHANTMENT ? SPELL_FORGE_FROZEN_BLADE : SPELL_FORGE_FROSTBORN_MACE); + DoScriptText(uiPointId == PHASE_BLADE_ENCHANTMENT ? SAY_FORGE_1 : SAY_FORGE_2, m_creature); + + m_uiThrowSaroniteTimer += 5000; // Delay next Saronit + m_uiPhase = uiPointId; + SetCombatMovement(true); + + if (m_creature->getVictim()) + { + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // Do nothing more while moving + if (m_uiPhase == PHASE_MOVEMENT) + return; + + // Casted in every phase + if (m_uiThrowSaroniteTimer < uiDiff) + { + // TODO - only target players? + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_THROW_SARONITE) == CAST_OK) + { + DoScriptText(EMOTE_THROW_SARONITE, m_creature, pTarget); + m_uiThrowSaroniteTimer = 16000; + } + } + } + else + m_uiThrowSaroniteTimer -= uiDiff; + + switch (m_uiPhase) + { + case PHASE_NO_ENCHANTMENT: + { + if (m_creature->GetHealthPercent() < 66.0f) + { + DoCastSpellIfCan(m_creature, SPELL_THUNDERING_STOMP, CAST_INTERRUPT_PREVIOUS); + SetCombatMovement(false); + + // TODO This should actually be jump movement + m_creature->GetMotionMaster()->MovePoint(PHASE_BLADE_ENCHANTMENT, aGarfrostMoveLocs[0][0], aGarfrostMoveLocs[0][1], aGarfrostMoveLocs[0][2]); + m_uiPhase = PHASE_MOVEMENT; + + // Stop further action + return; + } + break; + } + case PHASE_BLADE_ENCHANTMENT: + { + if (m_creature->GetHealthPercent() < 33.0f) + { + DoCastSpellIfCan(m_creature, SPELL_THUNDERING_STOMP, CAST_INTERRUPT_PREVIOUS); + SetCombatMovement(false); + + // TODO This should actually be jump movement + m_creature->GetMotionMaster()->MovePoint(PHASE_MACE_ENCHANTMENT, aGarfrostMoveLocs[1][0], aGarfrostMoveLocs[1][1], aGarfrostMoveLocs[1][2]); + m_uiPhase = PHASE_MOVEMENT; + + // Stop further action + return; + } + + if (m_uiChillingWaveTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHILLING_WAVE) == CAST_OK) + m_uiChillingWaveTimer = 14000; + } + else + m_uiChillingWaveTimer -= uiDiff; + + break; + } + case PHASE_MACE_ENCHANTMENT: + { + if (m_uiDeepFreezeTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_DEEP_FREEZE) == CAST_OK) + { + DoScriptText(EMOTE_DEEP_FREEZE, m_creature, pTarget); + m_uiDeepFreezeTimer = 20000; + } + } + } + else + m_uiDeepFreezeTimer -= uiDiff; + + break; + } + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_forgemaster_garfrost(Creature* pCreature) +{ + return new boss_forgemaster_garfrostAI(pCreature); +} + +void AddSC_boss_garfrost() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_forgemaster_garfrost"; + pNewScript->GetAI = &GetAI_boss_forgemaster_garfrost; + pNewScript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_krick_and_ick.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_krick_and_ick.cpp index 728a83d48..f5b4b08c0 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_krick_and_ick.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_krick_and_ick.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: boss_krick_and_ick SD%Complete: 0% -SDComment: +SDComment: encounter need vehicle support; outro is missing; explosive barrage doesn't work fine; pursue doesn't work fine SDCategory: Pit of Saron EndScriptData */ @@ -51,9 +51,308 @@ enum SAY_TYRANNUS_KRICK_2 = -1658044, SAY_JAINA_KRICK_3 = -1658045, SAY_SYLVANAS_KRICK_3 = -1658046, + + // ick + SPELL_POISON_NOVA = 68989, + SPELL_POISON_NOVA_H = 70434, + SPELL_MIGHTY_KICK = 69021, + SPELL_PURSUED = 68987, + + // krick + SPELL_TOXIC_WASTE = 69024, + SPELL_TOXIC_WASTE_H = 70436, + SPELL_STRANGULATING = 69413, // spell used by tyrannus at the outro event + SPELL_SHADOW_BOLT = 69028, + SPELL_EXPLOSIVE_BARRAGE = 69263, // maybe 69012? + + NPC_EXPLOSIVE_ORB = 36610, + SPELL_EXPLOSIVE_BARRAGE_ORB = 69019, }; +struct MANGOS_DLL_DECL boss_ickAI : public ScriptedAI +{ + boss_ickAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (instance_pit_of_saron*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + instance_pit_of_saron* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiPoisonNovaTimer; + uint32 m_uiPursueTimer; + uint32 m_uiMightKickTimer; + + void Reset() + { + m_uiPoisonNovaTimer = 30000; + m_uiPursueTimer = 10000; + m_uiMightKickTimer = 20000; + } + + void KilledUnit(Unit* pVictim) + { + if(Creature* pKrick = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KRICK))) + DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, pKrick); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_KRICK, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_KRICK, DONE); + + // ToDo - remove this when outro implemented + if(Creature* pKrick = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KRICK))) + pKrick->DealDamage(pKrick, pKrick->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_KRICK, FAIL); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiPoisonNovaTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_POISON_NOVA : SPELL_POISON_NOVA_H)) + { + if(Creature* pKrick = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KRICK))) + DoScriptText(SAY_ORDER_BLOW, pKrick); + m_uiPoisonNovaTimer = 30000; + } + } + else + m_uiPoisonNovaTimer -= uiDiff; + + if (m_uiPursueTimer < uiDiff) + { + if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_PURSUED) == CAST_OK) + { + if(Creature* pKrick = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KRICK))) + { + switch (urand(0, 2)) + { + case 0: + DoScriptText(SAY_TARGET_1, pKrick); + break; + case 1: + DoScriptText(SAY_TARGET_2, pKrick); + break; + case 2: + DoScriptText(SAY_TARGET_3, pKrick); + break; + } + } + + DoScriptText(EMOTE_ICK_CHASING, m_creature, pTarget); + + m_uiPursueTimer = 13000; + } + } + } + else + m_uiPursueTimer -= uiDiff; + + if (m_uiMightKickTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MIGHTY_KICK) == CAST_OK) + m_uiMightKickTimer = 25000; + } + else + m_uiMightKickTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL boss_krickAI : public ScriptedAI +{ + boss_krickAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (instance_pit_of_saron*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + instance_pit_of_saron* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiToxicWasteTimer; + uint32 m_uiShadowboltTimer; + uint32 m_uiExplosivBarrageTimer; + // workaround + uint32 m_uiSummonOrbsTimer; + uint32 m_uiSummonOverTimer; + bool m_bIsSummoning; + + void Reset() + { + m_uiToxicWasteTimer = 5000; + m_uiShadowboltTimer = 15000; + m_uiExplosivBarrageTimer = 35000; + // workaround + m_uiSummonOrbsTimer = 600000; + m_uiSummonOverTimer = 600000; + m_bIsSummoning = false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiToxicWasteTimer < uiDiff) + { + if(Creature* pIck = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ICK))) + { + if (Unit* pTarget = pIck->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_TOXIC_WASTE : SPELL_TOXIC_WASTE_H) == CAST_OK) + m_uiToxicWasteTimer = 10000; + } + } + } + else + m_uiToxicWasteTimer -= uiDiff; + + if (m_uiShadowboltTimer < uiDiff) + { + if(Creature* pIck = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ICK))) + { + if (Unit* pTarget = pIck->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_BOLT) == CAST_OK) + m_uiShadowboltTimer = 5000; + } + } + } + else + m_uiShadowboltTimer -= uiDiff; + + if (m_uiExplosivBarrageTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_EXPLOSIVE_BARRAGE) == CAST_OK) + { + DoScriptText(SAY_ORDER_STOP, m_creature); + DoScriptText(EMOTE_KRICK_MINES, m_creature); + m_uiExplosivBarrageTimer = 45000; + } + + // workaround + m_uiSummonOrbsTimer = 3000; + m_uiSummonOverTimer = 18000; + m_bIsSummoning = true; + } + else + m_uiExplosivBarrageTimer -= uiDiff; + + // workaround + if (m_uiSummonOrbsTimer < uiDiff && m_bIsSummoning) + { + for(uint8 i = 0; i < 4; ++i) + { + if(Creature* pIck = GetClosestCreatureWithEntry(m_creature, NPC_ICK, 100.0f)) + { + if (Unit* pTarget = pIck->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_creature->SummonCreature(NPC_EXPLOSIVE_ORB, pTarget->GetPositionX() + urand(0, 3), pTarget->GetPositionY() + urand(0, 3), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 4000); + } + } + m_uiSummonOrbsTimer = 1500; + } + else + m_uiSummonOrbsTimer -= uiDiff; + + if (m_uiSummonOverTimer < uiDiff && m_bIsSummoning) + { + m_bIsSummoning = false; + m_uiSummonOverTimer = 60000; + } + else + m_uiSummonOverTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_boss_ick(Creature* pCreature) +{ + return new boss_ickAI (pCreature); +} + +CreatureAI* GetAI_boss_krick(Creature* pCreature) +{ + return new boss_krickAI (pCreature); +} +struct MANGOS_DLL_DECL mob_exploding_orbAI : public ScriptedAI +{ + mob_exploding_orbAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_creature->SetActiveObjectState(true); + Reset(); + } + + ScriptedInstance* pInstance; + uint32 ExplodeTimer; + + void Reset() + { + ExplodeTimer = 18000; + } + + void AttackStart(Unit* who) + { + return; + } + + void UpdateAI(const uint32 diff) + { + if(!pInstance) return; + + if (ExplodeTimer < diff) + { + DoCast(m_creature, SPELL_EXPLOSIVE_BARRAGE_ORB); + m_creature->ForcedDespawn(); + } else ExplodeTimer -= diff; + return; + } + +}; + +CreatureAI* GetAI_mob_exploding_orb(Creature* pCreature) +{ + return new mob_exploding_orbAI(pCreature); +} + void AddSC_boss_krick_and_ick() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_krick"; + newscript->GetAI = &GetAI_boss_krick; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_ick"; + newscript->GetAI = &GetAI_boss_ick; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_exploding_orb"; + newscript->GetAI = &GetAI_mob_exploding_orb; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp index d2d817a5a..546304785 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_scourgelord_tyrannus -SD%Complete: 0% -SDComment: +SD%Complete: 50% +SDComment: missing intro and outro; encounter need vehicle support SDCategory: Pit of Saron EndScriptData */ @@ -38,9 +38,243 @@ enum EMOTE_RIMEFANG_ICEBOLT = -1658059, EMOTE_SMASH = -1658060, + + SPELL_FORCEFUL_SMASH = 69155, + SPELL_FORCEFUL_SMASH_H = 69627, + SPELL_OVERLORDS_BRAND = 69172, + SPELL_DARK_MIGHT = 69167, + SPELL_DARK_MIGHT_H = 69629, + SPELL_HOARFROST = 69246, + SPELL_MARK_OF_RIMEFANG = 69275, + SPELL_ICY_BLAST = 69233, + SPELL_ICY_BLAST_H = 69646, + SPELL_ICY_BLAST_SLOW = 69238, + SPELL_ICY_BLAST_SLOW_H = 69628, + + NPC_ICY_BLAST = 36731, + SPELL_ICY_BLAST_AURA = 69238, + SPELL_ICY_BLAST_AURA_H = 69628, +}; + +struct MANGOS_DLL_DECL boss_rimefangAI : public ScriptedAI +{ + boss_rimefangAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (instance_pit_of_saron*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + instance_pit_of_saron* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiHoarfrostTimer; + uint32 m_uiIcyBlastTimer; + uint32 m_uiIcyBlastSlowTimer; + uint64 m_uiMainTargetGUID; + + void Reset() + { + m_uiHoarfrostTimer = 25000; + m_uiIcyBlastTimer = 35000; + m_uiIcyBlastSlowTimer = 30000; + m_uiMainTargetGUID = 0; + } + + void SetMainTarget(uint64 m_uiTargetGUID) + { + m_uiMainTargetGUID = m_uiTargetGUID; + } + + void JustSummoned(Creature* pSummoned) + { + if(pSummoned->GetEntry() == NPC_ICY_BLAST) + pSummoned->CastSpell(pSummoned, SPELL_ICY_BLAST_AURA, false); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiHoarfrostTimer < uiDiff) + { + if (Unit* pTarget = m_creature->GetMap()->GetUnit(m_uiMainTargetGUID)) + DoCastSpellIfCan(pTarget, SPELL_HOARFROST); + else if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCastSpellIfCan(pTarget, SPELL_HOARFROST); + m_uiHoarfrostTimer = 20000; + } + else + m_uiHoarfrostTimer -= uiDiff; + + if (m_uiIcyBlastTimer < uiDiff) + { + if (Unit* pTarget = m_creature->GetMap()->GetUnit(m_uiMainTargetGUID)) + DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_ICY_BLAST : SPELL_ICY_BLAST_H); + else if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_ICY_BLAST : SPELL_ICY_BLAST_H); + m_uiIcyBlastTimer = 35000; + } + else + m_uiIcyBlastTimer -= uiDiff; + + if (m_uiIcyBlastSlowTimer < uiDiff) + { + if (Unit* pTarget = m_creature->GetMap()->GetUnit(m_uiMainTargetGUID)) + DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_ICY_BLAST_SLOW : SPELL_ICY_BLAST_SLOW_H); + else if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_ICY_BLAST_SLOW : SPELL_ICY_BLAST_SLOW_H); + m_uiIcyBlastSlowTimer = 40000; + } + else + m_uiIcyBlastSlowTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL boss_tyrannusAI : public ScriptedAI +{ + boss_tyrannusAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (instance_pit_of_saron*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + instance_pit_of_saron* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiForcefulSmashTimer; + uint32 m_uiOverlordsBrandTimer; + uint32 m_uiDarkMightTimer; + uint32 m_uiMarkOfRimefangTimer; + + void Reset() + { + m_uiForcefulSmashTimer = 10000; + m_uiOverlordsBrandTimer = 35000; + m_uiDarkMightTimer = 40000; + m_uiMarkOfRimefangTimer = 30000; + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_TYRANNUS, FAIL); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_TYRANNUS, IN_PROGRESS); + + DoScriptText(SAY_AGGRO, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + // Temp hack until outro is implemented + if (Creature* pRimefang = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_RIMEFANG))) + { + pRimefang->GetMotionMaster()->Clear(); + pRimefang->GetMotionMaster()->MovePoint(0, 844.752f, 358.993f, 645.330f); + pRimefang->setFaction(35); + pRimefang->DeleteThreatList(); + pRimefang->RemoveAllAuras(); + pRimefang->ForcedDespawn(10000); + } + + if (m_pInstance) + m_pInstance->SetData(TYPE_TYRANNUS, DONE); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiForcefulSmashTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FORCEFUL_SMASH : SPELL_FORCEFUL_SMASH_H) == CAST_OK) + m_uiForcefulSmashTimer = 50000; + } + else + m_uiForcefulSmashTimer -= uiDiff; + + if (m_uiOverlordsBrandTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_OVERLORDS_BRAND) == CAST_OK) + m_uiOverlordsBrandTimer = 45000; + } + } + else + m_uiOverlordsBrandTimer -= uiDiff; + + if (m_uiDarkMightTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_DARK_MIGHT : SPELL_DARK_MIGHT_H) == CAST_OK) + { + DoScriptText(SAY_SMASH, m_creature); + DoScriptText(EMOTE_SMASH, m_creature); + + m_uiDarkMightTimer = 60000; + } + } + else + m_uiDarkMightTimer -= uiDiff; + + if (m_uiMarkOfRimefangTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (DoCastSpellIfCan(pTarget, SPELL_MARK_OF_RIMEFANG) == CAST_OK) + { + if (Creature* pRimefang = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_RIMEFANG))) + ((boss_rimefangAI*)pRimefang->AI())->SetMainTarget(pTarget->GetGUID()); + + DoScriptText(SAY_MARK, m_creature); + m_uiMarkOfRimefangTimer = urand(30000, 40000); + } + } + } + else + m_uiMarkOfRimefangTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } }; +CreatureAI* GetAI_boss_tyrannus(Creature* pCreature) +{ + return new boss_tyrannusAI (pCreature); +} + +CreatureAI* GetAI_boss_rimefang(Creature* pCreature) +{ + return new boss_rimefangAI (pCreature); +} + void AddSC_boss_tyrannus() { + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name="boss_scourgelord_tyrannus"; + pNewScript->GetAI = &GetAI_boss_tyrannus; + pNewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name="boss_rimefang"; + pNewScript->GetAI = &GetAI_boss_rimefang; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp index 1fd74c91b..c911186cd 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -154,6 +154,17 @@ uint64 instance_pit_of_saron::GetData64(uint32 uiData) } } +bool AreaTrigger_at_tyrannus(Player* pPlayer, AreaTriggerEntry const* pAt) +{ + if (instance_pit_of_saron* pInstance = (instance_pit_of_saron*)pPlayer->GetInstanceData()) + { + if (pInstance->GetData(TYPE_TYRANNUS) == NOT_STARTED) + pInstance->SetData(TYPE_TYRANNUS, SPECIAL); + } + + return false; +} + InstanceData* GetInstanceData_instance_pit_of_saron(Map* pMap) { return new instance_pit_of_saron(pMap); @@ -167,4 +178,9 @@ void AddSC_instance_pit_of_saron() pNewScript->Name = "instance_pit_of_saron"; pNewScript->GetInstanceData = &GetInstanceData_instance_pit_of_saron; pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "at_tyrannus"; + pNewScript->pAreaTrigger = &AreaTrigger_at_tyrannus; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp index 1dfe435b5..8336e9b58 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -21,9 +21,6 @@ SD%Complete: 0 SDCategory: Pit of Saron EndScriptData */ -/* ContentData -EndContentData */ - #include "precompiled.h" #include "pit_of_saron.h" @@ -59,7 +56,57 @@ enum SAY_SYLVANAS_OUTRO_2 = -1658067, }; +struct MANGOS_DLL_DECL npc_jaina_or_sylvanas_POSintroAI : public ScriptedAI +{ + npc_jaina_or_sylvanas_POSintroAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + } +}; + +struct MANGOS_DLL_DECL npc_jaina_or_sylvanas_POSoutroAI : public ScriptedAI +{ + npc_jaina_or_sylvanas_POSoutroAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + } +}; + +CreatureAI* GetAI_npc_jaina_or_sylvanas_POSintro(Creature* pCreature) +{ + return new npc_jaina_or_sylvanas_POSintroAI(pCreature); +} + +CreatureAI* GetAI_npc_jaina_or_sylvanas_POSoutro(Creature* pCreature) +{ + return new npc_jaina_or_sylvanas_POSoutroAI(pCreature); +} + void AddSC_pit_of_saron() { + Script *newscript; + + newscript = new Script; + newscript->Name="npc_jaina_or_sylvanas_POSintro"; + newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_POSintro; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name="npc_jaina_or_sylvana_POSoutro"; + newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_POSoutro; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.h b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.h index 2c8d8185e..aaab104a5 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.h +++ b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp index 65b26c3f6..a3ad8605d 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,1014 @@ /* ScriptData SDName: blood_prince_council -SD%Complete: 0% -SDComment: +SD%Complete: 90% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need implement true movement for kinetic bomb, correct yells. #include "precompiled.h" +#include "icecrown_citadel.h" + +enum BossSpells +{ + SPELL_BERSERK = 47008, + SPELL_FAKE_DEATH = 71598, + + //Darkfallen Orb + SPELL_INVOCATION_OF_BLOOD_V = 70952, // + SPELL_INVOCATION_OF_BLOOD_K = 70981, // + SPELL_INVOCATION_OF_BLOOD_T = 70982, // + SPELL_INVOCATION_OF_BLOOD_AURA = 70983, // Triggered, override + + //Valanar + SPELL_KINETIC_BOMB = 72053, + NPC_KINETIC_BOMB_TARGET = 38458, + NPC_KINETIC_BOMB = 38454, + SPELL_KINETIC_BOMB_EXPLODE = 72052, + SPELL_SHOCK_VORTEX = 72037, + NPC_SHOCK_VORTEX = 38422, + SPELL_SHOCK_VORTEX_AURA = 71945, + SPELL_SHOCK_VORTEX_2 = 72039, + + //Taldaram + SPELL_GLITTERING_SPARKS = 71807, + SPELL_CONJURE_FLAME_1 = 71718, + SPELL_SUMMON_FLAME_1 = 71719, //Dummy effect + NPC_BALL_OF_FLAMES_1 = 38332, + SPELL_CONJURE_FLAME_2 = 72040, + SPELL_SUMMON_FLAME_2 = 72041, //Dummy effect + NPC_BALL_OF_FLAMES_2 = 38451, + SPELL_FLAMES_AURA = 71709, + SPELL_FLAMES = 71393, + + //Keleseth + SPELL_SHADOW_LANCE = 71405, + SPELL_SHADOW_LANCE_2 = 71815, + SPELL_SHADOW_RESONANCE = 71943, + SPELL_SHADOW_RESONANCE_AURA = 71822, + NPC_DARK_NUCLEUS = 38369, + + // Blood orb + SPELL_BLOOD_ORB_STATE_VISUAL = 72100, + +}; + +struct MANGOS_DLL_DECL boss_valanar_iccAI : public BSWScriptedAI +{ + boss_valanar_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + Creature* pBrother1; + Creature* pBrother2; + bool invocated; + uint32 m_health; + + void Reset() + { + if(!m_pInstance) + return; + resetTimers(); + invocated = false; + m_health = m_creature->GetMaxHealth(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631302,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631303,m_creature,pVictim); + break; + } + } + + void EnterEvadeMode() + { + m_creature->CombatStop(true); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->GetMotionMaster()->MoveTargetedHome(); + m_creature->SetLootRecipient(NULL); + Reset(); + } + + void JustReachedHome() + { + if (!m_pInstance) + return; + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, FAIL); + m_creature->LoadCreatureAddon(); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + DoScriptText(-1631304,m_creature,pKiller); + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, DONE); + + if (pBrother1 && pBrother1->isAlive()) + pKiller->DealDamage(pBrother1, pBrother1->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + if (pBrother2 && pBrother2->isAlive()) + pKiller->DealDamage(pBrother2, pBrother2->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + + pBrother1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_TALDARAM)); + pBrother2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_KELESETH)); + + if (pBrother1 && !pBrother1->isAlive()) + pBrother1->Respawn(); + if (pBrother2 && !pBrother2->isAlive()) + pBrother2->Respawn(); + + if (pBrother1) pBrother1->SetInCombatWithZone(); + if (pBrother2) pBrother2->SetInCombatWithZone(); + + invocated = false; + m_health = m_creature->GetMaxHealth(); + m_creature->SetHealth(1); + + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, IN_PROGRESS); + m_creature->CastSpell(m_creature,(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_T : SPELL_INVOCATION_OF_BLOOD_K),true); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_pInstance) + return; + + if (!m_creature || !m_creature->isAlive()) + return; + + if (!invocated) + uiDamage = 0; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) + return; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (hasAura(SPELL_INVOCATION_OF_BLOOD_V)) + { + if (!invocated) + { + DoScriptText(-1631307,m_creature); + m_creature->SetHealth(m_health); + invocated = true; + } + if (timedQuery(SPELL_INVOCATION_OF_BLOOD_V, uiDiff)) + { + if (doCast(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_K : SPELL_INVOCATION_OF_BLOOD_T) == CAST_OK) + { + doRemove(SPELL_INVOCATION_OF_BLOOD_V); + invocated = false; + m_health = m_creature->GetHealth(); + m_creature->SetHealth(1); + } + } + timedCast(SPELL_KINETIC_BOMB, uiDiff); + timedCast(SPELL_SHOCK_VORTEX_2, uiDiff); + } + else + { + + timedCast(SPELL_KINETIC_BOMB, uiDiff); + timedCast(SPELL_SHOCK_VORTEX, uiDiff); + } + + if (timedQuery(SPELL_BERSERK, uiDiff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631305,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_valanar_icc(Creature* pCreature) +{ + return new boss_valanar_iccAI(pCreature); +} + +struct MANGOS_DLL_DECL boss_taldaram_iccAI : public BSWScriptedAI +{ + boss_taldaram_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + Creature* pBrother1; + Creature* pBrother2; + bool invocated; + uint8 ballscount; + uint32 m_health; + + void Reset() + { + if(!m_pInstance) + return; + resetTimers(); + invocated = false; + ballscount = 0; + m_health = m_creature->GetMaxHealth(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + } + + void EnterEvadeMode() + { + m_creature->CombatStop(true); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->GetMotionMaster()->MoveTargetedHome(); + m_creature->SetLootRecipient(NULL); + Reset(); + } + + void JustReachedHome() + { + if (!m_pInstance) + return; + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, FAIL); + m_creature->LoadCreatureAddon(); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, DONE); + + if (pBrother1 && pBrother1->isAlive()) + pKiller->DealDamage(pBrother1, pBrother1->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + if (pBrother2 && pBrother2->isAlive()) + pKiller->DealDamage(pBrother2, pBrother2->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + } + + void KilledUnit(Unit* pVictim) + { + if (!m_pInstance) + return; + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + + pBrother1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VALANAR)); + pBrother2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_KELESETH)); + if (pBrother1 && !pBrother1->isAlive()) + pBrother1->Respawn(); + if (pBrother2 && !pBrother2->isAlive()) + pBrother2->Respawn(); + if (pBrother1) + pBrother1->SetInCombatWithZone(); + if (pBrother2) + pBrother2->SetInCombatWithZone(); + + if (!hasAura(SPELL_INVOCATION_OF_BLOOD_T)) + { + invocated = false; + m_health = m_creature->GetMaxHealth(); + m_creature->SetHealth(1); + } + else + m_creature->SetHealth(m_creature->GetMaxHealth()); + + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, IN_PROGRESS); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_pInstance) + return; + + if (!m_creature || !m_creature->isAlive()) + return; + + if (!invocated) + uiDamage = 0; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) + return; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (hasAura(SPELL_INVOCATION_OF_BLOOD_T)) + { + if (!invocated) + { + DoScriptText(-1631307,m_creature); + m_creature->SetHealth(m_health); + invocated = true; + } + if (timedQuery(SPELL_INVOCATION_OF_BLOOD_T, uiDiff)) + { + if (doCast(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_V : SPELL_INVOCATION_OF_BLOOD_K) == CAST_OK) + { + doRemove(SPELL_INVOCATION_OF_BLOOD_T); + invocated = false; + m_health = m_creature->GetHealth(); + m_creature->SetHealth(1); + } + } + if (ballscount > 0 && !m_creature->IsNonMeleeSpellCasted(false)) + { + doCast(SPELL_SUMMON_FLAME_2); + --ballscount; + }; + timedCast(SPELL_GLITTERING_SPARKS, uiDiff); + if (timedCast(SPELL_CONJURE_FLAME_2, uiDiff) == CAST_OK) ballscount = 1; + } + else + { + if (ballscount > 0 && !m_creature->IsNonMeleeSpellCasted(false)) + { + doCast(SPELL_SUMMON_FLAME_1); + --ballscount; + }; + timedCast(SPELL_GLITTERING_SPARKS, uiDiff); + if (timedCast(SPELL_CONJURE_FLAME_1, uiDiff) == CAST_OK) + ballscount = 1; + } + + if (timedQuery(SPELL_BERSERK, uiDiff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631305,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_taldaram_icc(Creature* pCreature) +{ + return new boss_taldaram_iccAI(pCreature); +} + +struct MANGOS_DLL_DECL boss_keleseth_iccAI : public BSWScriptedAI +{ + boss_keleseth_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + Creature* pBrother1; + Creature* pBrother2; + bool invocated; + uint32 m_health; + + void Reset() + { + if(!m_pInstance) + return; + resetTimers(); + invocated = false; + m_health = m_creature->GetMaxHealth(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + } + + void EnterEvadeMode() + { + m_creature->CombatStop(true); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->GetMotionMaster()->MoveTargetedHome(); + m_creature->SetLootRecipient(NULL); + Reset(); + } + + void JustReachedHome() + { + if (!m_pInstance) + return; + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, FAIL); + m_creature->LoadCreatureAddon(); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, DONE); + + if (pBrother1 && pBrother1->isAlive()) + pKiller->DealDamage(pBrother1, pBrother1->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + if (pBrother2 && pBrother2->isAlive()) + pKiller->DealDamage(pBrother2, pBrother2->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + } + + void KilledUnit(Unit* pVictim) + { + if (!m_pInstance) + return; + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + pBrother1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_TALDARAM)); + pBrother2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VALANAR)); + + if (pBrother1 && !pBrother1->isAlive()) + pBrother1->Respawn(); + if (pBrother2 && !pBrother2->isAlive()) + pBrother2->Respawn(); + if (pBrother1) + pBrother1->SetInCombatWithZone(); + if (pBrother2) + pBrother2->SetInCombatWithZone(); + + if (!hasAura(SPELL_INVOCATION_OF_BLOOD_K)) + { + invocated = false; + m_health = m_creature->GetMaxHealth(); + m_creature->SetHealth(1); + } + else + m_creature->SetHealth(m_creature->GetMaxHealth()); + + m_pInstance->SetData(TYPE_BLOOD_COUNCIL, IN_PROGRESS); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + DoStartMovement(pWho, 30.0f); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_pInstance) + return; + + if (!m_creature || !m_creature->isAlive()) + return; + + if (!invocated) + uiDamage = 0; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) + return; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (hasAura(SPELL_INVOCATION_OF_BLOOD_K)) + { + if (!invocated) + { + DoScriptText(-1631307,m_creature); + m_creature->SetHealth(m_health); + invocated = true; + }; + + if (timedQuery(SPELL_INVOCATION_OF_BLOOD_K, uiDiff)) + { + if (doCast(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_V : SPELL_INVOCATION_OF_BLOOD_T) == CAST_OK) + { + doRemove(SPELL_INVOCATION_OF_BLOOD_K); + invocated = false; + m_health = m_creature->GetHealth(); + m_creature->SetHealth(1); + } + } + + timedCast(SPELL_SHADOW_LANCE_2, uiDiff); + timedCast(SPELL_SHADOW_RESONANCE, uiDiff); + } + else + { + timedCast(SPELL_SHADOW_LANCE, uiDiff); + timedCast(SPELL_SHADOW_RESONANCE, uiDiff); + } + + if (timedQuery(SPELL_BERSERK, uiDiff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631305,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_keleseth_icc(Creature* pCreature) +{ + return new boss_keleseth_iccAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_dark_nucleusAI : public ScriptedAI +{ + mob_dark_nucleusAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_lifetimer; + uint32 m_casttimer; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetInCombatWithZone(); + m_lifetimer = 180000; + m_casttimer = 2000; + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + m_creature->SetSpeedRate(MOVE_RUN, 0.5); + SetCombatMovement(true); + DoStartMovement(pWho); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_casttimer <= uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_RESONANCE_AURA) == CAST_OK) + m_lifetimer -= 4000; + + m_casttimer = 2000; + } else m_casttimer -= uiDiff; + + if (m_lifetimer <= uiDiff) + m_creature->ForcedDespawn(); + else m_lifetimer -= uiDiff; + + } +}; + +CreatureAI* GetAI_mob_dark_nucleus(Creature* pCreature) +{ + return new mob_dark_nucleusAI (pCreature); +}; + +struct MANGOS_DLL_DECL mob_ball_of_flamesAI : public ScriptedAI +{ + mob_ball_of_flamesAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 grow_timer; + float fPosX, fPosY, fPosZ; + float m_Size; + float m_Size0; + bool finita; + bool movementstarted; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetInCombatWithZone(); + finita = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + SetCombatMovement(false); + m_creature->GetPosition(fPosX, fPosY, fPosZ); + m_creature->GetRandomPoint(fPosX, fPosY, fPosZ, urand(40, 60), fPosX, fPosY, fPosZ); + m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ); + movementstarted = true; + m_Size0 = m_creature->GetObjectScale(); + m_Size = m_Size0; + grow_timer = 500; + + m_creature->SetDisplayId(26767); +// if (m_creature->GetEntry() == NPC_BALL_OF_FLAMES_2) + DoCast(m_creature, SPELL_FLAMES_AURA); + } + + void MovementInform(uint32 type, uint32 id) + { + if (!m_pInstance || type != POINT_MOTION_TYPE) return; + if (id != 1) + m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ); + else movementstarted = false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS || finita) + m_creature->ForcedDespawn(); + + if (!movementstarted) + { + DoCast(m_creature, SPELL_FLAMES); + finita = true; + return; + } + + if (m_creature->GetEntry() == NPC_BALL_OF_FLAMES_2) + { + if (!m_creature->HasAura(SPELL_FLAMES_AURA)) + DoCast(m_creature, SPELL_FLAMES_AURA); + + + if (grow_timer <= uiDiff) + { + m_Size = m_Size*1.03; + m_creature->SetObjectScale(m_Size); + grow_timer = 500; + } else grow_timer -= uiDiff; + } else return; + + } +}; + +CreatureAI* GetAI_mob_ball_of_flames(Creature* pCreature) +{ + return new mob_ball_of_flamesAI (pCreature); +}; + +struct MANGOS_DLL_DECL mob_kinetic_bombAI : public ScriptedAI +{ + mob_kinetic_bombAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_lifetimer; + float fPosX0, fPosY0, fPosZ0; + float fPosX1, fPosY1, fPosZ1; + bool finita; + Creature *owner; + + void Reset() + { + owner = m_creature->GetMap()->GetCreature(m_creature->GetCreatorGuid()); + + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetInCombatWithZone(); + + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->SetSpeedRate(MOVE_RUN, 0.2f); + m_creature->SetSpeedRate(MOVE_WALK, 0.2f); + SetCombatMovement(false); + + m_lifetimer = 60000; +// m_creature->SetDisplayId(31095); + + m_creature->GetPosition(fPosX0, fPosY0, fPosZ0); + + if (!owner) return; + owner->GetPosition(fPosX1, fPosY1, fPosZ1); + + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(1, fPosX1, fPosY1, fPosZ1); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) return; + if ( id ==1 ) + { + finita = true; + DoCast(m_creature, SPELL_KINETIC_BOMB_EXPLODE); + } + else m_creature->GetMotionMaster()->MovePoint(1, fPosX1, fPosY1, fPosZ1); + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + +/* +Place shock bomb movement here +*/ + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS || finita) + m_creature->ForcedDespawn(); + + } +}; + +CreatureAI* GetAI_mob_kinetic_bomb(Creature* pCreature) +{ + return new mob_kinetic_bombAI (pCreature); +}; + +struct MANGOS_DLL_DECL mob_shock_vortexAI : public ScriptedAI +{ + mob_shock_vortexAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_lifetimer; + bool finita; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetInCombatWithZone(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_lifetimer = 8000; + SetCombatMovement(false); + DoCast(m_creature, SPELL_SHOCK_VORTEX_AURA); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS || finita) + m_creature->ForcedDespawn(); + + if (!m_creature->HasAura(SPELL_SHOCK_VORTEX_AURA)) + DoCast(m_creature, SPELL_SHOCK_VORTEX_AURA); + + if (m_lifetimer <= uiDiff) + finita = true; + else m_lifetimer -= uiDiff; + + } +}; + +CreatureAI* GetAI_mob_shock_vortex(Creature* pCreature) +{ + return new mob_shock_vortexAI (pCreature); +}; + +struct MANGOS_DLL_DECL mob_kinetic_bomb_targetAI : public ScriptedAI +{ + mob_kinetic_bomb_targetAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + Creature* bomb; + ScriptedInstance* m_pInstance; + + void Reset() + { + m_creature->SetDisplayId(21342); + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + SetCombatMovement(false); + bomb = NULL; + } + + void SummonedCreatureJustDied(Creature* summoned) + { + if (!m_pInstance || !summoned) return; + + if (summoned == bomb) + m_creature->ForcedDespawn(); + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!bomb) + bomb = m_creature->SummonCreature(NPC_KINETIC_BOMB,m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()+50.0f,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,60000); + + } +}; + +CreatureAI* GetAI_mob_kinetic_bomb_target(Creature* pCreature) +{ + return new mob_kinetic_bomb_targetAI (pCreature); +}; + +struct MANGOS_DLL_DECL boss_blood_queen_lanathel_introAI : public BSWScriptedAI +{ + boss_blood_queen_lanathel_introAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint32 UpdateTimer; + + void Reset() + { + m_creature->SetVisibility(VISIBILITY_OFF); + + if(!pInstance) + return; + + if (pInstance->GetData(TYPE_BLOOD_COUNCIL) == IN_PROGRESS) + return; + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if (pInstance->GetData(TYPE_BLOOD_COUNCIL) == DONE) + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetVisibility(VISIBILITY_OFF); + } + else + { + if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_TALDARAM))) + doCast(SPELL_FAKE_DEATH,pPrince); + if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_KELESETH))) + doCast(SPELL_FAKE_DEATH,pPrince); + if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALANAR))) + doCast(SPELL_FAKE_DEATH,pPrince); + pInstance->SetData(TYPE_BLOOD_COUNCIL, NOT_STARTED); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + } + + void AttackStart(Unit *who) + { + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pInstance) + return; + + if (pInstance->GetData(TYPE_BLOOD_COUNCIL) != NOT_STARTED) + return; + + if (pWho && pWho->GetTypeId() == TYPEID_PLAYER && pWho->IsWithinDistInMap(m_creature, 50.0f)) + { + pInstance->SetData(TYPE_EVENT, 800); + pInstance->SetData(TYPE_BLOOD_COUNCIL,IN_PROGRESS); + } + } + + void UpdateAI(const uint32 diff) + { + + if (pInstance->GetData(TYPE_BLOOD_COUNCIL) == FAIL) + { + Reset(); + return; + } + + if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_LANATHEL_INTRO) + { + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + if (UpdateTimer <= diff) + { + debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT)); + switch (pInstance->GetData(TYPE_EVENT)) + { + case 800: + m_creature->SetVisibility(VISIBILITY_ON); + DoScriptText(-1631301, m_creature); + UpdateTimer = 15000; + pInstance->SetData(TYPE_EVENT,810); + break; + case 810: + DoScriptText(-1631311, m_creature); + if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_TALDARAM))) + { + doRemove(SPELL_FAKE_DEATH,pPrince); + } + if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_KELESETH))) + { + doRemove(SPELL_FAKE_DEATH,pPrince); + } + if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALANAR))) + { + doRemove(SPELL_FAKE_DEATH,pPrince); + } + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,820); + break; + case 820: + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetVisibility(VISIBILITY_OFF); + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,830); + break; + default: + break; + } + } + else + UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + } + + } +}; + +CreatureAI* GetAI_boss_blood_queen_lanathel_intro(Creature* pCreature) +{ + return new boss_blood_queen_lanathel_introAI(pCreature); +} + +void AddSC_blood_prince_council() +{ + Script* newscript; + + newscript = new Script; + newscript->Name = "boss_taldaram_icc"; + newscript->GetAI = &GetAI_boss_taldaram_icc; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_keleseth_icc"; + newscript->GetAI = &GetAI_boss_keleseth_icc; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_valanar_icc"; + newscript->GetAI = &GetAI_boss_valanar_icc; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_nucleus"; + newscript->GetAI = &GetAI_mob_dark_nucleus; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ball_of_flames"; + newscript->GetAI = &GetAI_mob_ball_of_flames; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_kinetic_bomb"; + newscript->GetAI = &GetAI_mob_kinetic_bomb; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_shock_vortex"; + newscript->GetAI = &GetAI_mob_shock_vortex; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_kinetic_bomb_target"; + newscript->GetAI = &GetAI_mob_kinetic_bomb_target; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_blood_queen_lanathel_intro"; + newscript->GetAI = &GetAI_boss_blood_queen_lanathel_intro; + newscript->RegisterSelf(); + +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp index 8a71d4575..006f1d30f 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,319 @@ /* ScriptData SDName: boss_blood_queen_lanathel -SD%Complete: 0% -SDComment: +SD%Complete: 70% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need correct work of spells and timers #include "precompiled.h" +#include "icecrown_citadel.h" + +enum BossSpells +{ + SPELL_BERSERK = 47008, + SPELL_SHROUD_OF_SORROW = 72981, + SPELL_DELRIOUS_SLASH = 71623, + SPELL_BLOOD_MIRROR = 70445, + SPELL_BLOOD_MIRROR_MARK = 70451, + SPELL_VAMPIRIC_BITE = 71726, + SPELL_ESSENCE_OF_BLOOD_QWEEN = 70867, + SPELL_ESSENCE_OF_BLOOD_QWEEN_2 = 70871, + SPELL_FRENZIED_BLOODTHIRST = 70877, + SPELL_UNCONTROLLABLE_FRENZY = 70923, + SPELL_PACT_OF_DARKFALLEN = 71340, + SPELL_SWARMING_SHADOWS = 71264, + SPELL_TWILIGHT_BLOODBOLT = 71446, + SPELL_BLOODBOLT_WHIRL = 71772, + SPELL_PRESENCE_OF_DARKFALLEN = 71952, + + NPC_SWARMING_SHADOWS = 38163, + SPELL_SWARMING_SHADOWS_VISUAL = 71267, + THIRST_QUENCHED_AURA = 72154, +}; + +static Locations SpawnLoc[]= +{ + {4595.640137f, 2769.195557f, 400.137054f}, // 0 Phased + {4595.904785f, 2769.315918f, 421.838623f}, // 1 Fly +}; + + +struct MANGOS_DLL_DECL boss_blood_queen_lanathelAI : public BSWScriptedAI +{ + boss_blood_queen_lanathelAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 stage; + uint8 nextPoint; + uint8 bloodbolts; + uint32 UpdateTimer; + bool movementstarted; + + void Reset() + { + if(!pInstance) + return; + if (m_creature->isAlive()) + pInstance->SetData(TYPE_LANATHEL, NOT_STARTED); + stage = 0; + UpdateTimer = 1000; + bloodbolts = 0; + movementstarted = false; + resetTimers(); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + } + + void JustReachedHome() + { + if (pInstance) pInstance->SetData(TYPE_LANATHEL, FAIL); + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631330,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631331,m_creature,pVictim); + break; + } + + if (pVictim && pVictim->HasAura(SPELL_BLOOD_MIRROR)) + doRemove(SPELL_BLOOD_MIRROR,pVictim); + + if (pVictim && pVictim->HasAura(SPELL_BLOOD_MIRROR_MARK)) + doRemove(SPELL_BLOOD_MIRROR_MARK,pVictim); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !movementstarted) return; + if (id == nextPoint) + { + movementstarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + } + } + + void StartMovement(uint32 id) + { + nextPoint = id; + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z); + movementstarted = true; + } + + void Aggro(Unit *who) + { + if(!pInstance) return; + pInstance->SetData(TYPE_LANATHEL, IN_PROGRESS); + + doCast(SPELL_SHROUD_OF_SORROW); + + DoScriptText(-1631321,m_creature,who); + + if (Unit* pTarget = doSelectRandomPlayer(SPELL_BLOOD_MIRROR_MARK, false, 100.0f)) + { + if (doCast(SPELL_BLOOD_MIRROR_MARK,pTarget) == CAST_OK) + { + if (Unit* pTarget1 = doSelectRandomPlayer(SPELL_BLOOD_MIRROR_MARK, false, 100.0f)) + pTarget->CastSpell(pTarget1,getSpellWithDifficulty(SPELL_BLOOD_MIRROR), true); + }; + }; + + if (Unit* pTarget = doSelectRandomPlayer(SPELL_SHADOWS_EDGE, true, 100.0f)) + doAura(THIRST_QUENCHED_AURA,pTarget); + + } + + void JustDied(Unit *killer) + { + if(!pInstance) + return; + + pInstance->SetData(TYPE_LANATHEL, DONE); + DoScriptText(-1631333,m_creature,killer); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + + doRemoveFromAll(getSpellWithDifficulty(SPELL_ESSENCE_OF_BLOOD_QWEEN)); + doRemoveFromAll(SPELL_ESSENCE_OF_BLOOD_QWEEN_2); + doRemoveFromAll(SPELL_PACT_OF_DARKFALLEN); + doRemoveFromAll(SPELL_BLOOD_MIRROR); + doRemoveFromAll(SPELL_BLOOD_MIRROR_MARK); + } + + + void UpdateAI(const uint32 diff) + { + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(stage) + { + case 0: + + if (timedQuery(SPELL_TWILIGHT_BLOODBOLT, diff)) + bloodbolts = 1; + + if (timedQuery(SPELL_DELRIOUS_SLASH, diff)) + if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) + doCast(SPELL_DELRIOUS_SLASH, pTarget); + +// timedCast(SPELL_PACT_OF_DARKFALLEN, diff); + + timedCast(SPELL_SWARMING_SHADOWS, diff); + + if (timedQuery(SPELL_VAMPIRIC_BITE,diff)) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631322,m_creature); + break; + case 1: + DoScriptText(-1631323,m_creature); + break; + } + doCast(SPELL_VAMPIRIC_BITE); + } + + if (timedQuery(SPELL_BLOODBOLT_WHIRL,diff) && m_creature->GetHealthPercent() > 10.0f) + { + stage = 1; + }; + + DoMeleeAttackIfReady(); + + break; + case 1: // Go in fly phase + m_creature->AttackStop(); + SetCombatMovement(false); + StartMovement(1); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + stage = 2; + break; + case 2: + if (movementstarted) + return; + DoScriptText(-1631327,m_creature); + doCast(SPELL_BLOODBOLT_WHIRL); + stage = 3; + return; + case 3: + if (m_creature->IsNonMeleeSpellCasted(false)) + return; + if (timedQuery(SPELL_TWILIGHT_BLOODBOLT,diff) || m_creature->GetHealthPercent() < 10.0f) + { + stage = 4; +// DoScriptText(-1631325,m_creature); + bloodbolts = 3; + }; + break; + case 4: // Go in grownd phase + m_creature->AttackStop(); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + StartMovement(0); + stage = 5; + break; + case 5: + if (movementstarted) return; + DoScriptText(-1631325,m_creature); + stage = 0; + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + return; + default: + break; + } + + if (bloodbolts > 0) + { + doCast(SPELL_TWILIGHT_BLOODBOLT); + --bloodbolts; + }; + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631332,m_creature); + }; + + } +}; + + +CreatureAI* GetAI_boss_blood_queen_lanathel(Creature* pCreature) +{ + return new boss_blood_queen_lanathelAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_swarming_shadowsAI : public ScriptedAI +{ + mob_swarming_shadowsAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_lifetimer; + + void Reset() + { + m_creature->SetDisplayId(11686); + m_creature->SetRespawnDelay(7*DAY); + SetCombatMovement(false); + m_creature->SetInCombatWithZone(); + m_lifetimer = 10000; + DoCast(m_creature, SPELL_SWARMING_SHADOWS_VISUAL); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_LANATHEL) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->HasAura(SPELL_SWARMING_SHADOWS_VISUAL)) + DoCast(m_creature, SPELL_SWARMING_SHADOWS_VISUAL); + + if (m_lifetimer <= uiDiff) + m_creature->ForcedDespawn(); + else m_lifetimer -= uiDiff; + + } +}; + +CreatureAI* GetAI_mob_swarming_shadows(Creature* pCreature) +{ + return new mob_swarming_shadowsAI (pCreature); +} + + +void AddSC_boss_blood_queen_lanathel() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_blood_queen_lanathel"; + newscript->GetAI = &GetAI_boss_blood_queen_lanathel; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_swarming_shadows"; + newscript->GetAI = &GetAI_mob_swarming_shadows; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp index 6faff7ab3..49d418175 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,297 @@ /* ScriptData SDName: boss_deathbringer_saurfang -SD%Complete: 0% -SDComment: +SD%Complete: 75% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - #include "precompiled.h" +#include "icecrown_citadel.h" + +enum +{ + //common + SPELL_BERSERK = 47008, + //yells + //summons + NPC_BLOOD_BEASTS = 38508, + //Abilities + SPELL_BLOOD_LINK = 72178, + SPELL_BLOOD_POWER = 72371, + SPELL_MARK = 72293, + SPELL_MARK_SELF = 72256, + SPELL_FRENZY = 72737, + SPELL_BOILING_BLOOD = 72385, + SPELL_BLOOD_NOVA = 72380, + SPELL_RUNE_OF_BLOOD = 72408, + SPELL_CALL_BLOOD_BEAST_1 = 72172, + SPELL_CALL_BLOOD_BEAST_2 = 72173, + SPELL_CALL_BLOOD_BEAST_3 = 72356, + SPELL_CALL_BLOOD_BEAST_4 = 72357, + SPELL_CALL_BLOOD_BEAST_5 = 72358, + + SPELL_SCENT_OF_BLOOD = 72769, + SPELL_RESISTANT_SKIN = 72723, + SPELL_BLOOD_LINK_BEAST = 72176, + + SPELL_ZERO_REGEN = 72242, + +}; + +enum Equipment +{ + EQUIP_MAIN = 50798, + EQUIP_OFFHAND = 50798, + EQUIP_RANGED = EQUIP_NO_CHANGE, + EQUIP_DONE = EQUIP_NO_CHANGE, +}; + +struct MANGOS_DLL_DECL boss_deathbringer_saurfangAI : public BSWScriptedAI +{ + boss_deathbringer_saurfangAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 beasts; + int32 oldPower; + + void Reset() + { + if(!pInstance) + return; + m_creature->SetRespawnDelay(7*DAY); + if (m_creature->isAlive()) + pInstance->SetData(TYPE_SAURFANG, NOT_STARTED); + setStage(0); + beasts = 0; + resetTimers(); + m_creature->SetPower(m_creature->getPowerType(), 0); + doCast(SPELL_ZERO_REGEN); + oldPower = 0; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pInstance) return; + + if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER) return; + + if (!m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 20.0f)) + { + m_creature->setFaction(21); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + AttackStart(pWho); + } + + ScriptedAI::MoveInLineOfSight(pWho); + } + + void Aggro(Unit *who) + { + if(!pInstance) + return; + + pInstance->SetData(TYPE_SAURFANG, IN_PROGRESS); + SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED); + DoScriptText(-1631100,m_creature); + doCast(SPELL_BLOOD_LINK); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void JustReachedHome() + { + if (pInstance) + pInstance->SetData(TYPE_SAURFANG, FAIL); + } + + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631103,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631104,m_creature,pVictim); + break; + }; + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned) + return; + + summoned->SetOwnerGuid(m_creature->GetObjectGuid()); + + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ) + { + summoned->AddThreat(pTarget, 100.0f); + summoned->GetMotionMaster()->MoveChase(pTarget); + } + } + + void JustDied(Unit *killer) + { + if(!pInstance) + return; + pInstance->SetData(TYPE_SAURFANG, DONE); + DoScriptText(-1631106,m_creature); + doRemoveFromAll(SPELL_MARK); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (!m_creature->HasAura(SPELL_BLOOD_POWER)) + doCast(SPELL_BLOOD_POWER); + + if (!m_creature->HasAura(SPELL_BLOOD_LINK)) + doCast(SPELL_BLOOD_LINK); + + if (!m_creature->HasAura(SPELL_MARK_SELF)) + doCast(SPELL_MARK_SELF); + + switch(getStage()) + { + case 0: + if (m_creature->GetHealthPercent() <= 30.0f) setStage(1); + break; + + case 1: + doCast(SPELL_FRENZY); + setStage(2); + DoScriptText(-1631101,m_creature); + break; + + case 2: + break; + + default: + break; + } + + if (timedQuery(SPELL_MARK, diff)) + { + if (Unit* pTarget = doSelectRandomPlayer(SPELL_MARK,false,120.0f)) + doCast(SPELL_MARK, pTarget); + } + + timedCast(SPELL_BLOOD_NOVA, diff); + + timedCast(SPELL_BOILING_BLOOD, diff); + + timedCast(SPELL_RUNE_OF_BLOOD, diff); + + if (timedQuery(SPELL_CALL_BLOOD_BEAST_1, diff)) + { + beasts = getSpellData(SPELL_CALL_BLOOD_BEAST_1); + DoScriptText(-1631102,m_creature); + }; + + if (beasts > 0) + { + CanCastResult res = CAST_FAIL_OTHER; + switch (beasts) + { + case 1: res = doCast(SPELL_CALL_BLOOD_BEAST_1); break; + case 2: res = doCast(SPELL_CALL_BLOOD_BEAST_2); break; + case 3: res = doCast(SPELL_CALL_BLOOD_BEAST_3); break; + case 4: res = doCast(SPELL_CALL_BLOOD_BEAST_4); break; + case 5: res = doCast(SPELL_CALL_BLOOD_BEAST_5); break; + default: break; + }; + + if ( res == CAST_OK) + { + --beasts; + }; + }; + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631108,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_deathbringer_saurfang(Creature* pCreature) +{ + return new boss_deathbringer_saurfangAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_blood_beastAI : public BSWScriptedAI +{ + mob_blood_beastAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + Creature* pOwner; + bool scentcasted; + + void Reset() + { + pOwner = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_DEATHBRINGER_SAURFANG)); + resetTimers(); + scentcasted = false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_SAURFANG) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (!m_creature->HasAura(SPELL_BLOOD_LINK_BEAST)) + doCast(SPELL_BLOOD_LINK_BEAST); + + if (!m_creature->HasAura(SPELL_RESISTANT_SKIN)) + doCast(SPELL_RESISTANT_SKIN); + + if (!scentcasted && (m_creature->GetHealthPercent() <= 20.0f)) + { + if (urand(0,1)) //50% + doCast(SPELL_SCENT_OF_BLOOD); + scentcasted = true; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_blood_beast(Creature* pCreature) +{ + return new mob_blood_beastAI(pCreature); +} + +void AddSC_boss_deathbringer_saurfang() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_deathbringer_saurfang"; + newscript->GetAI = &GetAI_boss_deathbringer_saurfang; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_blood_beast"; + newscript->GetAI = &GetAI_mob_blood_beast; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp index 63c2cd908..77b633ade 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,450 @@ /* ScriptData SDName: boss_festergut -SD%Complete: 0% -SDComment: +SD%Complete: 90% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need correct timers #include "precompiled.h" +#include "icecrown_citadel.h" + +enum BossSpells +{ + SPELL_GASEOUS_BLIGHT_1 = 69157, + SPELL_GASEOUS_BLIGHT_2 = 69162, + SPELL_GASEOUS_BLIGHT_3 = 69164, + SPELL_BLIGHT_VISUAL_1 = 69126, + SPELL_BLIGHT_VISUAL_2 = 69152, + SPELL_BLIGHT_VISUAL_3 = 69154, + SPELL_INHALE_BLIGHT = 69165, + SPELL_INHALED_BLIGHT = 69166, + SPELL_PUNGENT_BLIGHT = 69195, + SPELL_GAS_SPORE = 69278, + SPELL_SPORE_AURA_0 = 69279, + SPELL_SPORE_AURA_1 = 69290, + SPELL_INOCULATE = 69291, + SPELL_REMOVE_UNOCULATE = 69298, + SPELL_GASTRIC_BLOAT = 72219, + SPELL_VILE_GAS = 72272, + SPELL_VILE_GAS_AURA = 69244, + SPELL_VILE_GAS_AURA_0 = 69248, + SPELL_BERSERK = 47008, + + SPELL_GASEOUS_SPIGOT = 71379, + + SPELL_SUMMON_VILE_STALKER = 72287, + + NPC_VILE_GAS_STALKER = 38548, + NPC_BLIGHT_STALKER = 36659, + NPC_PUDDLE_STALKER = 37013, + MAX_SPORE_TARGETS = 6, +}; + +static Locations SpawnLoc[]= +{ + {4267.9399f, 3137.32f, 360.385986f, 0.0f}, // 0 (start point) + {4317.067383f, 3136.99f, 360.385590f, 3.21f}, // 1 right + {4220.801758f, 3136.99f, 360.385590f, 0.39f}, // 2 left + {4269.084473f, 3186.306641f, 360.385590f, 4.72f}, // 3 rear +}; +struct MANGOS_DLL_DECL boss_festergutAI : public BSWScriptedAI +{ + boss_festergutAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + bool intro; + bool pet; + uint64 blightTargetGUID; +// uint64 pPuddleStalkerGUID[3]; + + void Reset() + { + if(!pInstance) return; + resetTimers(); + if (m_creature->isAlive()) + pInstance->SetData(TYPE_FESTERGUT, NOT_STARTED); + setStage(0); + intro = false; + pet = false; +/* for(uint8 i = 0; i < 3; ++i) + if (!pPuddleStalkerGUID[i]) + { + Unit* pTemp = doSummon(NPC_PUDDLE_STALKER,SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z, TEMPSUMMON_MANUAL_DESPAWN); + if (pTemp) + { + pPuddleStalkerGUID[i] = pTemp->GetGUID(); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + } +*/ + Creature* pBlightTarget = doSelectNearestCreature(NPC_BLIGHT_STALKER,60.0f); + if (pBlightTarget && !pBlightTarget->isAlive()) + pBlightTarget->Respawn(); + if (pBlightTarget) + { + blightTargetGUID = pBlightTarget->GetGUID(); + pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget); + doCast(SPELL_BLIGHT_VISUAL_2,pBlightTarget); + doCast(SPELL_BLIGHT_VISUAL_3,pBlightTarget); + } + + } + + void MoveInLineOfSight(Unit* pWho) + { + ScriptedAI::MoveInLineOfSight(pWho); + if(!pInstance || intro) return; + if (pWho->GetTypeId() != TYPEID_PLAYER) return; + + pInstance->SetData(TYPE_EVENT, 500); + debug_log("EventMGR: creature %u send signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT)); + intro = true; + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) { + case 0: + DoScriptText(-1631204,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631205,m_creature,pVictim); + break; + } + } + + void JustReachedHome() + { + if (!pInstance) return; + pInstance->SetData(TYPE_FESTERGUT, FAIL); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_1); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_3); + if (Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID)) + { + doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget); + } + } + + void Aggro(Unit *pWho) + { + if(!pInstance) return; + if (pWho->GetTypeId() != TYPEID_PLAYER) + return; + + Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID); + + pInstance->SetData(TYPE_FESTERGUT, IN_PROGRESS); + DoScriptText(-1631203,m_creature,pWho); + if (pBlightTarget && !pBlightTarget->isAlive()) + pBlightTarget->Respawn(); + if (pBlightTarget) + { + pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + doRemove(SPELL_BLIGHT_VISUAL_1,pBlightTarget); + doRemove(SPELL_BLIGHT_VISUAL_2,pBlightTarget); + doRemove(SPELL_BLIGHT_VISUAL_3,pBlightTarget); + doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget); + } + doCast(SPELL_GASEOUS_BLIGHT_1); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_3); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_1); +/* for(uint8 i = 0; i < 3; ++i) + if (pPuddleStalkerGUID[i]) + doCast(SPELL_GASEOUS_SPIGOT, m_creature->GetMap()->GetCreature(pPuddleStalkerGUID[i])); +*/ + } + + void JustDied(Unit *killer) + { + if (!pInstance) return; + pInstance->SetData(TYPE_FESTERGUT, DONE); + pInstance->SetData(TYPE_EVENT, 550); + DoScriptText(-1631206,m_creature); + Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_1); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_3); + if (pBlightTarget) + { + doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget); + } +/* for(uint8 i = 0; i < 3; ++i) + if (pPuddleStalkerGUID[i]) + { + Creature* pTemp = m_creature->GetMap()->GetCreature(pPuddleStalkerGUID[i]); + if (pTemp) pTemp->ForcedDespawn(); + pPuddleStalkerGUID[i] = NULL; + } +*/ + } + + void UpdateAI(const uint32 diff) + { + + if(!pInstance) return; + + if (!pet) + { + if (Creature* pGuard = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_STINKY))) + if (!pGuard->isAlive()) + { + pet = true; + if (pInstance->GetData(TYPE_STINKY) == NOT_STARTED) + { + DoScriptText(-1631209,m_creature); + pInstance->SetData(TYPE_STINKY,DONE); + } + } + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID); + + switch(getStage()) + { + case 0: + if (timedQuery(SPELL_GASEOUS_BLIGHT_2, diff)) + setStage(1); + break; + case 1: + switch (urand(0,2)) + { + case 0: DoScriptText(-1631210,m_creature); break; + case 1: DoScriptText(-1631211,m_creature); break; + case 2: DoScriptText(-1631212,m_creature); break; + } + doCast(SPELL_INHALE_BLIGHT); + setStage(2); + break; + case 2: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + if (pBlightTarget) + { + doRemove(SPELL_GASEOUS_BLIGHT_1); + doRemove(SPELL_BLIGHT_VISUAL_1,pBlightTarget); + doRemove(SPELL_BLIGHT_VISUAL_1,m_creature); + doCast(SPELL_GASEOUS_BLIGHT_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_3); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_1); + } + setStage(3); + break; + case 3: + if (timedQuery(SPELL_GASEOUS_BLIGHT_3, diff)) + setStage(4); + break; + case 4: + switch (urand(0,2)) + { + case 0: DoScriptText(-1631210,m_creature); break; + case 1: DoScriptText(-1631211,m_creature); break; + case 2: DoScriptText(-1631212,m_creature); break; + } + doCast(SPELL_INHALE_BLIGHT); + setStage(5); + break; + case 5: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + if (pBlightTarget) + { + doRemove(SPELL_GASEOUS_BLIGHT_2); + doRemove(SPELL_BLIGHT_VISUAL_2,pBlightTarget); + doRemove(SPELL_BLIGHT_VISUAL_2,m_creature); + doCast(SPELL_GASEOUS_BLIGHT_3); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_3); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_1); + } + setStage(6); + break; + case 6: + if (timedQuery(SPELL_GASEOUS_BLIGHT_3, diff)) + setStage(7); + break; + case 7: + switch (urand(0,2)) + { + case 0: DoScriptText(-1631210,m_creature); break; + case 1: DoScriptText(-1631211,m_creature); break; + case 2: DoScriptText(-1631212,m_creature); break; + } + doCast(SPELL_INHALE_BLIGHT); + setStage(8); + break; + case 8: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + if (pBlightTarget) + { + doRemove(SPELL_GASEOUS_BLIGHT_3); + doRemove(SPELL_BLIGHT_VISUAL_3,pBlightTarget); + doRemove(SPELL_BLIGHT_VISUAL_3,m_creature); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_3); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_1); + } + setStage(9); + break; + case 9: + if (timedQuery(SPELL_PUNGENT_BLIGHT, diff)) + { + DoScriptText(-1631208,m_creature); + doCast(SPELL_PUNGENT_BLIGHT); + setStage(10); + } + break; + case 10: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + if (pBlightTarget) + { + doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_3); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_2); + doRemoveFromAll(SPELL_BLIGHT_VISUAL_1); + } + m_creature->RemoveAurasDueToSpell(SPELL_INHALED_BLIGHT); + setStage(0); + break; + } + + + timedCast(SPELL_GAS_SPORE, diff); + + timedCast(SPELL_GASTRIC_BLOAT, diff); + + if (timedQuery(SPELL_VILE_GAS, diff)) + { + float fPosX, fPosY, fPosZ; + m_creature->GetPosition(fPosX, fPosY, fPosZ); + m_creature->GetRandomPoint(fPosX, fPosY, fPosZ, 30.0f, fPosX, fPosY, fPosZ); + if (Unit* pTemp = doSummon(NPC_VILE_GAS_STALKER,fPosX, fPosY, fPosZ)) + doCast(SPELL_VILE_GAS, pTemp); + DoScriptText(-1631213,m_creature); + }; + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631207,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + + +CreatureAI* GetAI_boss_festergut(Creature* pCreature) +{ + return new boss_festergutAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_vile_gas_stalkerAI : public ScriptedAI +{ + mob_vile_gas_stalkerAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint32 m_lifetimer; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWithZone(); + SetCombatMovement(false); + m_creature->SetDisplayId(11686); + m_lifetimer = 12000; + } + + void AttackStart(Unit *pWho) + { + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_FESTERGUT) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_lifetimer <= uiDiff) + m_creature->ForcedDespawn(); + else m_lifetimer -= uiDiff; + + } +}; + +CreatureAI* GetAI_mob_vile_gas_stalker(Creature* pCreature) +{ + return new mob_vile_gas_stalkerAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_orange_gas_stalkerAI : public ScriptedAI +{ + mob_orange_gas_stalkerAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + m_creature->SetDisplayId(11686); + } + + void AttackStart(Unit *pWho) + { + } + + void UpdateAI(const uint32 uiDiff) + { +// if (!pInstance || pInstance->GetData(TYPE_FESTERGUT) != IN_PROGRESS) +// m_creature->ForcedDespawn(); + } +}; + +CreatureAI* GetAI_mob_orange_gas_stalker(Creature* pCreature) +{ + return new mob_orange_gas_stalkerAI(pCreature); +} + +void AddSC_boss_festergut() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_festergut"; + newscript->GetAI = &GetAI_boss_festergut; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_vile_gas_stalker"; + newscript->GetAI = &GetAI_mob_vile_gas_stalker; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_orange_gas_stalker"; + newscript->GetAI = &GetAI_mob_orange_gas_stalker; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp index e74986488..b90def829 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,540 @@ /* ScriptData SDName: boss_lady_deathwhisper -SD%Complete: 0% -SDComment: +SD%Complete: 80% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need correct spells on adds and timers #include "precompiled.h" +#include "icecrown_citadel.h" +enum BossSpells +{ + //common + SPELL_BERSERK = 47008, + //yells + //summons + NPC_VENGEFUL_SHADE = 38222, + NPC_FANATIC = 37890, + NPC_REANIMATED_FANATIC = 38009, + NPC_ADHERENT = 37949, + NPC_REANIMATED_ADHERENT = 38010, + //Abilities + SPELL_MANA_BARRIER = 70842, + SPELL_SHADOW_BOLT = 71254, + SPELL_DEATH_AND_DECAY = 71001, + SPELL_DARK_EMPOWERMENT = 70901, + SPELL_FROSTBOLT = 71420, + SPELL_INSIGNIFICANCE = 71204, + + SPELL_DOMINATE_MIND = 71289, + + SPELL_VENGEFUL_BLAST = 71494, + SPELL_VENGEFUL_BLAST_0 = 71544, + // summons + SPELL_FROST_FEVER = 71129, + SPELL_DEATHCHILL_BOLT = 70594, + SPELL_DEATHCHILL_BLAST = 70906, + SPELL_DARK_MARTYRDROM = 70903, + SPELL_CURSE_OF_TOPOR = 71237, + SPELL_SHORUD_OF_THE_OCCULUT = 70768, + SPELL_ADHERENTS_DETERMINIATION = 71234, + SPELL_SUMMON_VISUAL = 41236, + + SPELL_NECROTIC_STRIKE = 70659, + SPELL_SHADOW_CLEAVE = 70670, + SPELL_VAMPIRIC_MIGHT = 70674, +}; + +static Locations SpawnLoc[]= +{ + {-623.055481f, 2211.326660f, 51.764259f}, // 0 Lady's stay point + {-620.197449f, 2272.062256f, 50.848679f}, // 1 Right Door 1 + {-598.636353f, 2272.062256f, 50.848679f}, // 2 Right Door 2 + {-578.495728f, 2272.062256f, 50.848679f}, // 3 Right Door 3 + {-578.495728f, 2149.211182f, 50.848679f}, // 4 Left Door 1 + {-598.636353f, 2149.211182f, 50.848679f}, // 5 Left Door 2 + {-620.197449f, 2149.211182f, 50.848679f}, // 6 Left Door 3 + {-525.652466f, 2216.611328f, 62.823681f}, // 7 Upper marsh 1 + {-525.652466f, 2211.611328f, 62.823681f}, // 8 Upper marsh 2 + {-525.652466f, 2206.611328f, 62.823681f}, // 9 Upper marsh 3 +}; + +struct MANGOS_DLL_DECL boss_lady_deathwhisperAI : public BSWScriptedAI +{ + boss_lady_deathwhisperAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 stage; + bool MovementStarted; + bool intro; + + void Reset() + { + if(!pInstance) return; + if (m_creature->isAlive()) pInstance->SetData(TYPE_DEATHWHISPER, NOT_STARTED); + stage = 0; + MovementStarted = false; + intro = false; + resetTimers(); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (m_creature->CanInitiateAttack() && pWho->isTargetableForAttack() && + m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature)) + { + 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); + } + } + } + if (stage) return; + else intro = true; + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631029,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631030,m_creature,pVictim); + break; + }; + } + + void JustReachedHome() + { + if (pInstance) + pInstance->SetData(TYPE_DEATHWHISPER, FAIL); + } + + void MovementInform(uint32 type, uint32 id) + { + if(!pInstance) return; + if(type != POINT_MOTION_TYPE) return; + if(MovementStarted && id != 1) + { + m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z); + } + else + { + m_creature->GetMotionMaster()->MovementExpired(); + MovementStarted = false; + SetCombatMovement(false); + } + } + + void Aggro(Unit *who) + { + if (!pInstance) + return; + pInstance->SetData(TYPE_DEATHWHISPER, IN_PROGRESS); + doCast(SPELL_MANA_BARRIER ); + MovementStarted = true; + SetCombatMovement(false); + DoScriptText(-1631023,m_creature); + m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z); + } + + void JustDied(Unit *killer) + { + if(pInstance) + pInstance->SetData(TYPE_DEATHWHISPER, DONE); + DoScriptText(-1631032,m_creature,killer); + doRemoveFromAll(SPELL_INSIGNIFICANCE); + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned) return; + + if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ) + { + summoned->AddThreat(pTarget, 100.0f); + } + } + + void CallGuard(uint8 place) + { + if (place < 2) + { + doSummon(urand(0,1) ? NPC_FANATIC : NPC_ADHERENT, SpawnLoc[3*place+1].x, SpawnLoc[3*place+1].y, SpawnLoc[3*place+1].z); + doSummon(urand(0,1) ? NPC_FANATIC : NPC_ADHERENT, SpawnLoc[3*place+3].x, SpawnLoc[3*place+3].y, SpawnLoc[3*place+3].z); + } + doSummon(urand(0,1) ? NPC_FANATIC : NPC_ADHERENT, SpawnLoc[3*place+2].x, SpawnLoc[3*place+2].y, SpawnLoc[3*place+2].z); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_creature || !m_creature->isAlive()) + return; + + if (hasAura(SPELL_MANA_BARRIER, m_creature)) + { + if (m_creature->GetPower(POWER_MANA) > uiDamage) + { + m_creature->SetPower(POWER_MANA,m_creature->GetPower(POWER_MANA)-uiDamage); + uiDamage = 0; + } + else + { + m_creature->SetPower(POWER_MANA,0); + doRemove(SPELL_MANA_BARRIER); + }; + } + else + return; + } + + void UpdateAI(const uint32 diff) + { + if (intro && timedQuery(SPELL_SHADOW_BOLT,diff)) + { + switch (stage) + { + case 0: + DoScriptText(-1631020,m_creature); + stage = 1; + break; + case 1: + DoScriptText(-1631021,m_creature); + stage = 2; + break; + case 2: + DoScriptText(-1631022,m_creature); + stage = 3; + break; + default: + break; + } + } + + if (hasAura(SPELL_MANA_BARRIER, m_creature)) + { + if(m_creature->GetHealth() <= m_creature->GetMaxHealth()) + { + if (m_creature->GetPower(POWER_MANA) > (m_creature->GetMaxHealth() - m_creature->GetHealth())) + { + m_creature->SetPower(POWER_MANA,m_creature->GetPower(POWER_MANA)-(m_creature->GetMaxHealth() - m_creature->GetHealth())); + m_creature->SetHealth(m_creature->GetMaxHealth()); + } + else + m_creature->SetPower(POWER_MANA,0); + } + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (MovementStarted) + return; + + switch(stage) + { + case 3: { + if (IsCombatMovement()) + SetCombatMovement(false); + + timedCast(SPELL_SHADOW_BOLT,diff); + + if (timedQuery(NPC_FANATIC, diff)) + { + DoScriptText(-1631028,m_creature); + switch (currentDifficulty) { + case RAID_DIFFICULTY_10MAN_NORMAL: + CallGuard(urand(0,1)); + break; + case RAID_DIFFICULTY_10MAN_HEROIC: + CallGuard(urand(0,1)); + if (urand(0,1)) CallGuard(2); + break; + case RAID_DIFFICULTY_25MAN_NORMAL: + CallGuard(0); + CallGuard(1); + if (urand(0,1)) CallGuard(2); + break; + case RAID_DIFFICULTY_25MAN_HEROIC: + CallGuard(0); + CallGuard(1); + CallGuard(2); + break; + default: + break; + + } + } + + if (timedQuery(SPELL_DARK_EMPOWERMENT ,diff)) + { + switch (urand(0,1)) { + case 0: + if(Creature *pGuard = GetClosestCreatureWithEntry(m_creature, NPC_FANATIC, 100.0f)) + { + doCast(SPELL_DARK_EMPOWERMENT, pGuard); + DoScriptText(-1631026,m_creature); + }; + break; + case 1: + if(Creature *pGuard = GetClosestCreatureWithEntry(m_creature, NPC_ADHERENT, 100.0f)) + { + doCast(SPELL_DARK_EMPOWERMENT, pGuard); + DoScriptText(-1631027,m_creature); + }; + break; + } + } + + break;} + + case 4: { + timedCast(SPELL_FROSTBOLT, diff); + + timedCast(SPELL_INSIGNIFICANCE, diff); + + timedCast(NPC_VENGEFUL_SHADE, diff); + + if (is25()) timedCast(SPELL_DOMINATE_MIND, diff); + + if (timedQuery(NPC_FANATIC, diff)) + { + switch (currentDifficulty) { + case RAID_DIFFICULTY_10MAN_HEROIC: + CallGuard(urand(0,1)); + if (urand(0,1)) CallGuard(2); + break; + case RAID_DIFFICULTY_25MAN_HEROIC: + CallGuard(0); + CallGuard(1); + CallGuard(2); + break; + default: + break; + + } + } + + break;} + } + + timedCast(SPELL_DEATH_AND_DECAY, diff); + + + if (!hasAura(SPELL_MANA_BARRIER, m_creature) && stage == 3) + { + stage = 4; + DoScriptText(-1631024,m_creature); + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631031,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_lady_deathwhisper(Creature* pCreature) +{ + return new boss_lady_deathwhisperAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_vengeful_shadeAI : public BSWScriptedAI +{ + mob_vengeful_shadeAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance *m_pInstance; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetInCombatWithZone(); + if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ) { + m_creature->AddThreat(pTarget, 1000.0f); + m_creature->GetMotionMaster()->MoveChase(pTarget); + m_creature->SetSpeedRate(MOVE_RUN, 0.5); + } + doCast(SPELL_VENGEFUL_BLAST); + } + + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance && m_pInstance->GetData(TYPE_DEATHWHISPER) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (timedQuery(SPELL_VENGEFUL_BLAST_0, uiDiff)) + { + if (m_creature->IsWithinDist(m_creature->getVictim(), 1.0f, false)) + { + doCast(SPELL_VENGEFUL_BLAST_0); + m_creature->ForcedDespawn(); + } + else + { + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->SetSpeedRate(MOVE_RUN, 0.5); + } + } + } + +}; + +CreatureAI* GetAI_mob_vengeful_shade(Creature* pCreature) +{ + return new mob_vengeful_shadeAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_cult_adherentAI : public BSWScriptedAI +{ + mob_cult_adherentAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + bool bone; + + void Reset() + { + resetTimers(); + m_creature->SetRespawnDelay(DAY); + doCast(SPELL_SUMMON_VISUAL); + bone = false; + } + + void Aggro(Unit *who) + { + doCast(SPELL_SHORUD_OF_THE_OCCULUT); + DoStartMovement(who, 20.0f); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_DEATHWHISPER) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_FROST_FEVER, uiDiff); + + timedCast(SPELL_DEATHCHILL_BOLT, uiDiff); + + timedCast( SPELL_DEATHCHILL_BLAST, uiDiff); + + if (m_creature->GetHealthPercent() < 15.0f && !bone) + { + if (!urand(0,3)) doCast(SPELL_DARK_MARTYRDROM); //30% + bone = true; + } + } +}; + +CreatureAI* GetAI_mob_cult_adherent(Creature* pCreature) +{ + return new mob_cult_adherentAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_cult_fanaticAI : public BSWScriptedAI +{ + mob_cult_fanaticAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + bool bone; + + void Reset() + { + resetTimers(); + m_creature->SetRespawnDelay(DAY); + bone = false; + } + + void Aggro(Unit *who) + { + doCast(SPELL_VAMPIRIC_MIGHT); + DoStartMovement(who); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_DEATHWHISPER) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_NECROTIC_STRIKE, uiDiff); + + timedCast(SPELL_SHADOW_CLEAVE, uiDiff); + + if (m_creature->GetHealthPercent() < 15.0f && !bone) + { + if (!urand(0,3)) doCast(SPELL_DARK_MARTYRDROM); //30% + bone = true; + } + } +}; + +CreatureAI* GetAI_mob_cult_fanatic(Creature* pCreature) +{ + return new mob_cult_fanaticAI(pCreature); +} + +void AddSC_boss_lady_deathwhisper() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_lady_deathwhisper"; + newscript->GetAI = &GetAI_boss_lady_deathwhisper; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_vengeful_shade"; + newscript->GetAI = &GetAI_mob_vengeful_shade; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_cult_adherent"; + newscript->GetAI = &GetAI_mob_cult_adherent; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_cult_fanatic"; + newscript->GetAI = &GetAI_mob_cult_fanatic; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp index b2a30aee9..8462b64be 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,417 @@ /* ScriptData SDName: boss_lord_marrowgar -SD%Complete: 0% -SDComment: +SD%Complete: 85% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - #include "precompiled.h" +#include "icecrown_citadel.h" +enum +{ + //common + SPELL_BERSERK = 47008, + //yells + //summons + NPC_BONE_SPIKE = 38711, + NPC_COLD_FLAME = 36672, + //Abilities + SPELL_SABER_LASH = 71021, + SPELL_CALL_COLD_FLAME = 69138, + SPELL_CALL_COLD_FLAME_1 = 71580, + SPELL_COLD_FLAME = 69146, + SPELL_COLD_FLAME_0 = 69145, + SPELL_COLD_FLAME_1 = 69147, + SPELL_BONE_STRIKE = 69057, + SPELL_BONE_STORM = 69076, + SPELL_BONE_STRIKE_IMPALE = 69065, + SPELL_VEHICLE_HARDCODED = 46598, + SPELL_BONE_STORM_STRIKE = 69075, +}; + +struct MANGOS_DLL_DECL boss_lord_marrowgarAI : public BSWScriptedAI +{ + boss_lord_marrowgarAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + bool intro; + + void Reset() + { + if (!pInstance) return; + if (m_creature->isAlive()) pInstance->SetData(TYPE_MARROWGAR, NOT_STARTED); + resetTimers(); + m_creature->SetSpeedRate(MOVE_RUN, 1); + m_creature->SetSpeedRate(MOVE_WALK, 1); +// m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + void MoveInLineOfSight(Unit* pWho) + { + ScriptedAI::MoveInLineOfSight(pWho); + if (intro) return; + DoScriptText(-1631000,m_creature); + intro = true; + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned) return; + summoned->SetCreatorGuid(m_creature->GetObjectGuid()); + } + + void JustReachedHome() + { + if (pInstance) pInstance->SetData(TYPE_MARROWGAR, FAIL); + } + + void Aggro(Unit *who) + { + if(!pInstance) return; + pInstance->SetData(TYPE_MARROWGAR, IN_PROGRESS); + DoScriptText(-1631001,m_creature); + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) { + case 0: + DoScriptText(-1631006,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631007,m_creature,pVictim); + break; + }; + } + + void JustDied(Unit *killer) + { + if(pInstance) pInstance->SetData(TYPE_MARROWGAR, DONE); + DoScriptText(-1631009,m_creature); + } + + void doSummonSpike(Unit* pTarget) + { + if (!pTarget || !pTarget->isAlive()) return; + float fPosX, fPosY, fPosZ; + pTarget->GetPosition(fPosX, fPosY, fPosZ); + if (Unit* pSpike = doSummon(NPC_BONE_SPIKE, fPosX, fPosY, fPosZ + 0.5f)) + { + pSpike->SetOwnerGuid(m_creature->GetObjectGuid()); + pSpike->SetInCombatWith(pTarget); + pSpike->AddThreat(pTarget, 1000.0f); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(getStage()) + { + case 0: + if (timedQuery(SPELL_BONE_STRIKE, diff)) + if (Unit* pTarget = doSelectRandomPlayer(SPELL_BONE_STRIKE_IMPALE, false, 60.0f, isHeroic())) + if (doCast(SPELL_BONE_STRIKE, pTarget) == CAST_OK) + { + doSummonSpike(pTarget); + switch (urand(0,1)) { + case 0: + DoScriptText(-1631003,m_creature,pTarget); + break; + case 1: + DoScriptText(-1631004,m_creature,pTarget); + break; + case 2: + DoScriptText(-1631005,m_creature,pTarget); + break; + }; + + }; + + if (timedQuery(SPELL_BONE_STORM, diff)) setStage(1); + + if (timedQuery(SPELL_CALL_COLD_FLAME, diff)) + { + if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME); + else doCast(SPELL_CALL_COLD_FLAME_1); + + if (m_creature->GetHealthPercent() <= 30.0f) + { + if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME); + else doCast(SPELL_CALL_COLD_FLAME_1); + } + } + + timedCast(SPELL_SABER_LASH, diff); + + DoMeleeAttackIfReady(); + + break; + case 1: + m_creature->InterruptNonMeleeSpells(true); + doCast(SPELL_BONE_STORM); + setStage(2); + DoScriptText(-1631002,m_creature); + DoResetThreat(); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_RUN, 3); + m_creature->SetSpeedRate(MOVE_WALK, 3); + break; + case 2: + if (!m_creature->IsNonMeleeSpellCasted(false)) setStage(3); + break; + case 3: + if (isHeroic()) + if (timedQuery(SPELL_BONE_STRIKE, diff, true)) + if (Unit* pTarget = doSelectRandomPlayer(SPELL_BONE_STRIKE_IMPALE, false, 60.0f)) + doSummonSpike(pTarget); + + if (timedQuery(SPELL_CALL_COLD_FLAME, diff, true) + && m_creature->IsWithinDistInMap(m_creature->getVictim(),2.0f)) + { + pInstance->SetData(DATA_DIRECTION, (uint32)(1000*2.0f*M_PI_F*((float)urand(1,16)/16.0f))); +// if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME); +// else doCast(SPELL_CALL_COLD_FLAME_1); + float fPosX, fPosY, fPosZ; + m_creature->GetPosition(fPosX, fPosY, fPosZ); + doSummon(NPC_COLD_FLAME, fPosX, fPosY, fPosZ); + DoResetThreat(); + if (Unit* pTarget = doSelectRandomPlayerAtRange(60.0f)) + AttackStart(pTarget); + } + if (!hasAura(SPELL_BONE_STORM_STRIKE, m_creature) && !hasAura(SPELL_BONE_STORM, m_creature)) setStage(4); + break; + case 4: + pInstance->SetData(DATA_DIRECTION, 0); + m_creature->SetSpeedRate(MOVE_RUN, 1); + m_creature->SetSpeedRate(MOVE_WALK, 1); +// m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + setStage(0); + break; + default: + break; + } + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631008,m_creature); + } + + + } +}; + +struct MANGOS_DLL_DECL mob_coldflameAI : public BSWScriptedAI +{ + mob_coldflameAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool isFirst; + bool isXmode; + float m_direction; + float x, y, radius; + bool isCreator; + + void Reset() + { + if(!m_pInstance) return; +// m_creature->SetDisplayId(10045); + m_creature->SetRespawnDelay(7*DAY); + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + setStage(0); + isCreator = false; + + SetCombatMovement(false); + doCast(SPELL_COLD_FLAME_0); + } + + void AttackStart(Unit *who) + { + } + + void JustSummoned(Creature* summoned) + { + if(!m_pInstance || !summoned) return; + summoned->SetCreatorGuid(m_creature->GetObjectGuid()); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance && m_pInstance->GetData(TYPE_MARROWGAR) != IN_PROGRESS) + { + m_creature->ForcedDespawn(); + } + + if (m_creature->GetCreatorGuid().IsEmpty()) return; + + if (!isCreator) + { + if (m_creature->GetCreatorGuid() == m_pInstance->GetData64(NPC_LORD_MARROWGAR)) + { + isFirst = true; + uint32 m_tmpDirection = m_pInstance->GetData(DATA_DIRECTION); + m_pInstance->SetData(DATA_DIRECTION,0); + if (m_tmpDirection) + { + m_direction = m_tmpDirection/1000.0f; + isXmode = true; + } + else + { + m_direction = 2.0f*M_PI_F*((float)urand(1,16)/16.0f); + isXmode = false; + } + } else isFirst = false; + isCreator = true; + } + + if (timedQuery(SPELL_COLD_FLAME_0, uiDiff) && !isFirst) + m_creature->ForcedDespawn(); + + if (isFirst && timedQuery(SPELL_COLD_FLAME_1, uiDiff, true)) + { + if (getStage() < getSpellData(SPELL_COLD_FLAME_0)) + { + setStage(getStage()+1); + radius = getStage()*5; + m_creature->GetNearPoint2D(x, y, radius, m_direction); + doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1)); + if (isXmode) + { + m_creature->GetNearPoint2D(x, y, radius, m_direction+M_PI_F/2); + doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1)); + m_creature->GetNearPoint2D(x, y, radius, m_direction+M_PI_F); + doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1)); + m_creature->GetNearPoint2D(x, y, radius, m_direction+M_PI_F*1.5f); + doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1)); + } + } else m_creature->ForcedDespawn(); + } else timedCast(SPELL_COLD_FLAME, uiDiff); + + } +}; + +struct MANGOS_DLL_DECL mob_bone_spikeAI : public BSWScriptedAI +{ + mob_bone_spikeAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance* m_pInstance; + ObjectGuid victimGuid; + + void Reset() + { + SetCombatMovement(false); + m_creature->SetRespawnDelay(7*DAY); + victimGuid = ObjectGuid(); + m_creature->SetInCombatWithZone(); + } + + void Aggro(Unit* pWho) + { + if (victimGuid.IsEmpty() && pWho && pWho->GetTypeId() == TYPEID_PLAYER) + { + victimGuid = pWho->GetObjectGuid(); + m_creature->SetInCombatWith(pWho); + doCast(SPELL_BONE_STRIKE_IMPALE,pWho); + doCast(SPELL_VEHICLE_HARDCODED,pWho); + } + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (uiDamage > m_creature->GetHealth()) + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid)) + doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim); + } + + void AttackStart(Unit *who) + { + } + + void KilledUnit(Unit* _Victim) + { + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid)) + if (pVictim->GetObjectGuid() == victimGuid) + doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim); + } + + void JustDied(Unit* Killer) + { + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid)) + doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance && m_pInstance->GetData(TYPE_MARROWGAR) != IN_PROGRESS) + { + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid)) + doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim); + m_creature->ForcedDespawn(); + } + + if (victimGuid.IsEmpty()) + return; + + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid)) + { + if(!pVictim->isAlive()) + m_creature->ForcedDespawn(); + } + else + m_creature->ForcedDespawn(); + } +}; + +CreatureAI* GetAI_mob_bone_spike(Creature* pCreature) +{ + return new mob_bone_spikeAI(pCreature); +} + +CreatureAI* GetAI_mob_coldflame(Creature* pCreature) +{ + return new mob_coldflameAI(pCreature); +} + +CreatureAI* GetAI_boss_lord_marrowgar(Creature* pCreature) +{ + return new boss_lord_marrowgarAI(pCreature); +} + +void AddSC_boss_lord_marrowgar() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_lord_marrowgar"; + newscript->GetAI = &GetAI_boss_lord_marrowgar; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_coldflame"; + newscript->GetAI = &GetAI_mob_coldflame; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_bone_spike"; + newscript->GetAI = &GetAI_mob_bone_spike; + newscript->RegisterSelf(); + +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp index deef0ffa8..f58d0f7f0 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,10 +15,742 @@ */ /* ScriptData -SDName: boss_professor_putricide -SD%Complete: 0% -SDComment: +SDName: boss_proffesor_putricide +SD%Complete: 70% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need implement model (aura?) for phase 2 and visual effects +// I don't know how do mutated_abomination :( #include "precompiled.h" +#include "icecrown_citadel.h" + +enum BossSpells +{ + SPELL_UNSTABLE_EXPERIMENT = 70351, // Script effect not work on 10154. Spawn manually. + SPELL_TEAR_GAS = 71617, + SPELL_TEAR_GAS_1 = 71615, + SPELL_TEAR_GAS_2 = 71618, + SPELL_CREATE_CONCOCTION = 71621, + SPELL_MALLEABLE_GOO = 70852, + SPELL_GUZZLE_POTIONS = 71893, + SPELL_MUTATED_STRENGTH = 71603, + SPELL_MUTATED_PLAGUE = 72672, + SPELL_OOZE_THROW = 70342, // is triggered spell +// + SPELL_GREEN_BOTTLE_0 = 71826, + SPELL_ORANGE_BOTTLE_0 = 71827, + SPELL_GREEN_BOTTLE_1 = 71702, + SPELL_ORANGE_BOTTLE_1 = 71703, +// + SPELL_THROW_BOTTLE_1 = 71273, + SPELL_THROW_BOTTLE_2 = 71275, + SPELL_THROW_BOTTLE_3 = 71276, +// + NPC_GAS_CLOUD = 37562, + SPELL_GASEOUS_BLOAT = 70672, + SPELL_EXPUNGED_GAS = 70701, +// + NPC_VOLATILE_OOZE = 37697, + SPELL_OOZE_ADHESIVE = 70447, + SPELL_OOZE_ERUPTION = 70492, +// + SPELL_OOZE_GAS_PROTECTION = 70812, + SPELL_OOZE_BEAM_PROTECTION = 71530, + SPELL_OOZE_TANK_PROTECTION = 71770, +// + NPC_MUTATED_ABOMINATION = 37672, + SPELL_MUTATED_TRANSFORMATION = 70311, + SPELL_EAT_OOZE = 72527, + SPELL_REGURGITATED_OOZE = 70539, + SPELL_MUTATED_SLASH = 70542, + SPELL_MUTATED_AURA = 70405, +// + NPC_CHOKING_GAS_BOMB = 38159, + SPELL_CHOKING_GAS = 71259, + SPELL_CHOKING_GAS_AURA = 71278, + SPELL_CHOKING_GAS_EXPLODE = 71279, + SPELL_CHOKING_GAS_EXPLODE_TRIGGER = 71280, + SPELL_ORANGE_RADIATION = 45857, //Additional visual +// + NPC_OOZE_PUDDLE = 37690, + SPELL_SLIME_PUDDLE = 70343, + SPELL_SLIME_PUDDLE_AURA = 70346, + + SPELL_BERSERK = 47008, + QUEST_24749 = 71518, + SHADOW_INFUSION_AURA = 71516, +// + VIEW_1 = 30881, + VIEW_2 = 30881, + VIEW_3 = 30993, +}; + +static Locations SpawnLoc[]= +{ + {4356.779785f, 3263.510010f, 389.398010f, 1.586f}, // 0 Putricide start point o=1.586 + {4295.081055f, 3188.883545f, 389.330261f, 4.270f}, // 1 Puticide Festergut say, o=4.27 + {4417.302246f, 3188.219971f, 389.332520f, 5.102f}, // 2 Putricide Rotface say o=5.102 +}; + +struct MANGOS_DLL_DECL boss_proffesor_putricideAI : public BSWScriptedAI +{ + boss_proffesor_putricideAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 stage; + bool intro; + uint32 UpdateTimer; + bool movementstarted; + uint8 nextPoint; + uint8 slimetype; + + void Reset() + { + if (!pInstance) return; + if (m_creature->isAlive()) pInstance->SetData(TYPE_PUTRICIDE, NOT_STARTED); + stage = 0; + slimetype = 0; + intro = false; + movementstarted = false; + UpdateTimer = 1000; + resetTimers(); + m_creature->SetRespawnDelay(7*DAY); + } + + void MoveInLineOfSight(Unit* pWho) + { + ScriptedAI::MoveInLineOfSight(pWho); + + if (!pInstance || intro) return; + if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_PROFESSOR_PUTRICIDE + || !pWho->IsWithinDistInMap(m_creature, 60.0f)) return; + + DoScriptText(-1631240,m_creature, pWho); + intro = true; + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631241,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631242,m_creature,pVictim); + break; + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !movementstarted) return; + if (id == nextPoint) + { + movementstarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + } + } + + void Aggro(Unit *pWho) + { + if (!pInstance) return; + if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER) + return; + + pInstance->SetData(TYPE_PUTRICIDE, IN_PROGRESS); + DoScriptText(-1631249,m_creature, pWho); + + if (Unit* pTarget = doSelectRandomPlayer(SPELL_SHADOWS_EDGE, true, 100.0f)) //hack! need remove later + doAura(SHADOW_INFUSION_AURA,pTarget); + } + + void JustDied(Unit *killer) + { + if (!pInstance) return; + pInstance->SetData(TYPE_PUTRICIDE, DONE); + DoScriptText(-1631243,m_creature, killer); + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned) return; + + if ( summoned->GetEntry() == NPC_VOLATILE_OOZE + || summoned->GetEntry() == NPC_GAS_CLOUD) + if (Unit* pTarget = doSelectRandomPlayer()) + { + summoned->SetInCombatWith(pTarget); + summoned->AddThreat(pTarget, 100.0f); + } + + } + + void StartMovement(uint32 id) + { + nextPoint = id; + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z); + movementstarted = true; + } + + void CallOoze() + { + if (doCast(SPELL_UNSTABLE_EXPERIMENT) == CAST_OK) + switch(slimetype) + { + case 0: + doSummon(NPC_VOLATILE_OOZE); + slimetype = 1; + break; + case 1: + doSummon(NPC_GAS_CLOUD); + slimetype = 0; + break; + + default: break; + } + } + + void JustReachedHome() + { + if (pInstance) pInstance->SetData(TYPE_PUTRICIDE, FAIL); + } + + void UpdateAI(const uint32 diff) + { + if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_PROFESSOR_PUTRICIDE) + { + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + if (UpdateTimer <= diff) + { + debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT)); + switch (pInstance->GetData(TYPE_EVENT)) + { + case 500: + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->NearTeleportTo(SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, SpawnLoc[1].o); + DoScriptText(-1631201, m_creature); + UpdateTimer = 60000; + pInstance->SetData(TYPE_EVENT,510); + break; + case 510: + UpdateTimer = 5000; + if (pInstance->GetData(TYPE_FESTERGUT) == DONE) + pInstance->SetData(TYPE_EVENT,550); + if (pInstance->GetData(TYPE_FESTERGUT) == FAIL) + pInstance->SetData(TYPE_EVENT,630); + break; + case 550: + DoScriptText(-1631202, m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,630); + break; + case 600: + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->NearTeleportTo(SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z, SpawnLoc[2].o); + DoScriptText(-1631220, m_creature); + UpdateTimer = 60000; + pInstance->SetData(TYPE_EVENT,610); + break; + case 610: + UpdateTimer = 5000; + if (pInstance->GetData(TYPE_ROTFACE) == DONE) + pInstance->SetData(TYPE_EVENT,620); + if (pInstance->GetData(TYPE_ROTFACE) == FAIL) + pInstance->SetData(TYPE_EVENT,630); + break; + case 620: + DoScriptText(-1631202, m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,630); + break; + case 630: + m_creature->NearTeleportTo(SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, SpawnLoc[0].o); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,690); + break; + default: + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(stage) + { + case 0: + + if (timedQuery(SPELL_UNSTABLE_EXPERIMENT, diff)) + CallOoze(); + + timedCast(SPELL_OOZE_THROW, diff); + + if (timedQuery(SPELL_MALLEABLE_GOO, diff)) + { + doCast(SPELL_MALLEABLE_GOO); + } + + DoMeleeAttackIfReady(); + + if (m_creature->GetHealthPercent() < 80.0f ) stage = 1; + + break; + case 1: + m_creature->InterruptNonMeleeSpells(true); + m_creature->AttackStop(); + SetCombatMovement(false); + doCast(SPELL_TEAR_GAS_1); + DoScriptText(-1631245,m_creature); + StartMovement(0); + stage = 2; + break; + case 2: + if (movementstarted) return; + doCast(SPELL_CREATE_CONCOCTION); + stage = 3; + break; + case 3: + if (m_creature->IsNonMeleeSpellCasted(true,false,false) || + !doSelectRandomPlayer(SPELL_TEAR_GAS_1, false)) return; + DoScriptText(-1631246,m_creature); + m_creature->SetDisplayId(VIEW_2); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + SetCombatMovement(true); + stage = 4; + break; + case 4: + + if (timedQuery(SPELL_UNSTABLE_EXPERIMENT, diff)) + CallOoze(); + + if (timedQuery(SPELL_THROW_BOTTLE_1, diff)) + switch(urand(0,2)) + { + case 0: + doCast(SPELL_THROW_BOTTLE_1); + break; + case 1: + doCast(SPELL_THROW_BOTTLE_2); + break; + case 2: + doCast(SPELL_THROW_BOTTLE_3); + break; + default: break; + } + + timedCast(SPELL_OOZE_THROW, diff); + + timedCast(SPELL_MALLEABLE_GOO, diff); + + if (timedQuery(SPELL_MALLEABLE_GOO, diff)) + { + doCast(SPELL_MALLEABLE_GOO); + } + + if (m_creature->GetDisplayId() != VIEW_2) + m_creature->SetDisplayId(VIEW_2); + + DoMeleeAttackIfReady(); + + if (m_creature->GetHealthPercent() < 35.0f ) stage = 5; + + break; + case 5: + m_creature->InterruptNonMeleeSpells(true); + m_creature->AttackStop(); + SetCombatMovement(false); + doCast(SPELL_TEAR_GAS_1); + DoScriptText(-1631245,m_creature); + StartMovement(0); + stage = 6; + break; + case 6: + if (movementstarted) return; + doCast(SPELL_GUZZLE_POTIONS); + stage = 7; + break; + case 7: + if (m_creature->IsNonMeleeSpellCasted(true,false,false)) return; + if (m_creature->GetDisplayId() != VIEW_3) + m_creature->SetDisplayId(VIEW_3); + if (!doSelectRandomPlayer(SPELL_TEAR_GAS_1, false)) return; + DoScriptText(-1631247,m_creature); + m_creature->SetDisplayId(VIEW_3); + doCast(SPELL_MUTATED_STRENGTH); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + SetCombatMovement(true); + stage = 8; + break; + case 8: + timedCast(SPELL_MUTATED_PLAGUE, diff); + if (m_creature->GetDisplayId() != VIEW_3) + m_creature->SetDisplayId(VIEW_3); + DoMeleeAttackIfReady(); + + break; + default: + break; + } + + if (timedQuery(SPELL_BERSERK, diff)){ + doCast(SPELL_BERSERK); + DoScriptText(-1631244,m_creature); + } + } +}; + +CreatureAI* GetAI_boss_proffesor_putricide(Creature* pCreature) +{ + return new boss_proffesor_putricideAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_icc_gas_cloudAI : public BSWScriptedAI +{ + mob_icc_gas_cloudAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + Unit* pTarget; + bool expunded; + uint32 delay; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_WALK, 0.5f); + m_creature->SetSpeedRate(MOVE_RUN, 0.2f); + pTarget = NULL; + expunded = false; + delay = 10000; + } + + void JustDied(Unit *killer) + { + if (!m_pInstance) return; + if (pTarget && pTarget->isAlive()) + doRemove(SPELL_GASEOUS_BLOAT, pTarget); + } + + void Aggro(Unit *who) + { + if (!m_pInstance || who->GetTypeId() != TYPEID_PLAYER) return; + + if (!pTarget || pTarget != who ) pTarget = who; + else return; + + delay = 10000; + + if (pTarget) + { + doAura(SPELL_GASEOUS_BLOAT, pTarget); + } + DoStartMovement(who); + } + + void JustReachedHome() + { + if (!m_pInstance) return; + m_creature->ForcedDespawn(); + } + + void UpdateAI(const uint32 uiDiff) + { + + if (!m_pInstance ) return; + + if(m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (expunded) m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (!pTarget) Aggro(m_creature->getVictim()); + + if (delay <= uiDiff) + { + if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, 3.0f)) + { + doCast(SPELL_EXPUNGED_GAS, pTarget); + doRemove(SPELL_GASEOUS_BLOAT, pTarget); + expunded = true; + }; + } else delay -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_icc_gas_cloud(Creature* pCreature) +{ + return new mob_icc_gas_cloudAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_icc_volatile_oozeAI : public BSWScriptedAI +{ + mob_icc_volatile_oozeAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + Unit* pTarget; + bool finita; + uint32 delay; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_WALK, 0.5f); + m_creature->SetSpeedRate(MOVE_RUN, 0.2f); + pTarget = NULL; + finita = false; + delay = 10000; + } + + void JustDied(Unit *killer) + { + if (!m_pInstance) return; + if (pTarget && pTarget->isAlive()) + doRemove(SPELL_OOZE_ADHESIVE, pTarget); + } + + void Aggro(Unit *who) + { + if (!m_pInstance || !who || who->GetTypeId() != TYPEID_PLAYER) return; + + if (!pTarget || pTarget != who ) pTarget = who; + else return; + + delay = 10000; + + if (pTarget) + { + doAura(SPELL_OOZE_ADHESIVE, pTarget); + } + DoStartMovement(pTarget); + } + + void JustReachedHome() + { + if (!m_pInstance) return; + m_creature->ForcedDespawn(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance ) return; + + if ((m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS) || finita) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (!pTarget) + Aggro(m_creature->getVictim()); + + if (delay <= uiDiff) + { + if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, 3.0f)) + { + doCast(SPELL_OOZE_ERUPTION); + doRemove(SPELL_OOZE_ADHESIVE, pTarget); + finita = true; + }; + } else delay -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_icc_volatile_ooze(Creature* pCreature) +{ + return new mob_icc_volatile_oozeAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_choking_gas_bombAI : public ScriptedAI +{ + mob_choking_gas_bombAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool finita; + uint32 copy_timer; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetInCombatWithZone(); + m_creature->SetDisplayId(11686); + SetCombatMovement(false); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->CastSpell(m_creature, SPELL_ORANGE_RADIATION, false); + finita = false; + copy_timer = 8000; + } + + void AttackStart(Unit *pWho) + { + return; + } + + void JustReachedHome() + { + return; + } + + void JustDied(Unit *killer) + { + if (finita) return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) return; + + if (m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->HasAura(SPELL_CHOKING_GAS)) + m_creature->CastSpell(m_creature, SPELL_CHOKING_GAS, false); + + if (!finita && m_creature->HasAura(SPELL_CHOKING_GAS_EXPLODE_TRIGGER)) + { +// m_creature->CastSpell(m_creature,SPELL_CHOKING_GAS_EXPLODE,false); + finita = true; + } + + if (!finita) + { + if (copy_timer <= uiDiff) + { + float fPosX, fPosY, fPosZ; + m_creature->GetPosition(fPosX, fPosY, fPosZ); + if (Creature* pCopy = m_creature->SummonCreature(m_creature->GetEntry(), fPosX, fPosY, fPosZ, 0, TEMPSUMMON_TIMED_DESPAWN, 11200)) + pCopy->CastSpell(pCopy, SPELL_CHOKING_GAS_EXPLODE_TRIGGER, false); + copy_timer = 3600000; + } else copy_timer -= uiDiff; + } + + } + +}; + +CreatureAI* GetAI_mob_choking_gas_bomb(Creature* pCreature) +{ + return new mob_choking_gas_bombAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_ooze_puddleAI : public ScriptedAI +{ + mob_ooze_puddleAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *m_pInstance; + float m_Size; + float m_Size0; + uint32 grow_timer; + + void Reset() + { + if(!m_pInstance) return; + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetDisplayId(11686); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetInCombatWithZone(); + SetCombatMovement(false); + m_Size0 = m_creature->GetObjectScale(); + if (m_Size0 > 1.0f) + { + m_creature->SetObjectScale(1.0f); + m_Size0 = 1.0f; + } + m_Size = m_Size0; + grow_timer = 500; + } + + void AttackStart(Unit *who) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) return; + + if (m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->HasAura(SPELL_SLIME_PUDDLE)) + m_creature->CastSpell(m_creature, SPELL_SLIME_PUDDLE, false); + + // Override especially for clean core + if (m_Size / m_Size0 >= 2.6f) m_creature->ForcedDespawn(); + + if (grow_timer <= uiDiff) + { + m_Size = m_Size*1.01; + m_creature->SetObjectScale(m_Size); + grow_timer = 500; + } else grow_timer -= uiDiff; + } + +}; + +CreatureAI* GetAI_mob_ooze_puddle(Creature* pCreature) +{ + return new mob_ooze_puddleAI(pCreature); +} + +void AddSC_boss_proffesor_putricide() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_proffesor_putricide"; + newscript->GetAI = &GetAI_boss_proffesor_putricide; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_icc_volatile_ooze"; + newscript->GetAI = &GetAI_mob_icc_volatile_ooze; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_icc_gas_cloud"; + newscript->GetAI = &GetAI_mob_icc_gas_cloud; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_choking_gas_bomb"; + newscript->GetAI = &GetAI_mob_choking_gas_bomb; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ooze_puddle"; + newscript->GetAI = &GetAI_mob_ooze_puddle; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp index 58ec9f0c9..abb512b58 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,425 @@ /* ScriptData SDName: boss_rotface -SD%Complete: 0% -SDComment: +SD%Complete: 80% +SDComment: by /dev/rsa. Need correct timers && infection logic SDCategory: Icecrown Citadel EndScriptData */ - +// Need correct timers #include "precompiled.h" +#include "icecrown_citadel.h" + +enum BossSpells +{ + SPELL_OOZE_FLOOD = 69789, + SPELL_OOZE_FLOOD_0 = 69788, + SPELL_OOZE_FLOOD_1 = 69783, + SPELL_SLIME_SPRAY = 69508, + SPELL_MUTATED_INFECTION_AURA = 69674, + SPELL_MUTATED_INFECTION = 70003, + SPELL_BERSERK = 47008, + + SPELL_STICKY_OOZE = 69774, + SPELL_STICKY_AURA = 69776, + SPELL_MERGE_OOZE = 69889, + SPELL_RADIATING_OOZE = 69750, + SPELL_RADIATING_OOZE_1 = 69760, + SPELL_UNSTABLE_OOZE = 69644, + SPELL_UNSTABLE_OOZE_AURA = 69558, + SPELL_OOZE_EXPLODE = 69839, + SPELL_OOZE_EXPLODE_AURA = 69840, + + NPC_BIG_OOZE = 36899, + NPC_SMALL_OOZE = 36897, + NPC_STICKY_OOZE = 37006, + NPC_OOZE_SPRAY_STALKER = 37986, + NPC_OOZE_STALKER = 37013, + NPC_OOZE_EXPLODE_STALKER = 38107, +}; + +static Locations SpawnLoc[]= +{ + {4471.821289f, 3162.986084f, 360.38501f}, // 0 + {4471.821289f, 3110.452148f, 360.38501f}, // 1 + {4418.825684f, 3110.452148f, 360.38501f}, // 2 + {4418.825684f, 3162.986084f, 360.38501f}, // 3 +}; + + +struct MANGOS_DLL_DECL boss_rotfaceAI : public BSWScriptedAI +{ + boss_rotfaceAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 stage; + bool intro; + bool pet; + bool nexttick; + + void Reset() + { + if(!pInstance) return; + if (m_creature->isAlive()) pInstance->SetData(TYPE_ROTFACE, NOT_STARTED); + stage = 0; + intro = false; + pet = false; + nexttick = false; + resetTimers(); + } + + void MoveInLineOfSight(Unit* pWho) + { + ScriptedAI::MoveInLineOfSight(pWho); + if(!pInstance || intro) return; + if (pWho->GetTypeId() != TYPEID_PLAYER) return; + + pInstance->SetData(TYPE_EVENT, 600); + debug_log("EventMGR: creature %u send signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT)); + intro = true; + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) { + case 0: + DoScriptText(-1631222,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631223,m_creature,pVictim); + break; + } + } + + void Aggro(Unit *who) + { + if(!pInstance) return; + pInstance->SetData(TYPE_ROTFACE, IN_PROGRESS); + DoScriptText(-1631221,m_creature,who); + } + + void JustDied(Unit *killer) + { + if(!pInstance) return; + pInstance->SetData(TYPE_ROTFACE, DONE); + DoScriptText(-1631224,m_creature, killer); + } + + void UpdateAI(const uint32 diff) + { + + if(!pInstance) return; + + if (!pet) + { + if (Creature* pGuard = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_PRECIOUS))) + if (!pGuard->isAlive()) + { + pet = true; + if (pInstance->GetData(TYPE_PRECIOUS) == NOT_STARTED) + { + DoScriptText(-1631228,m_creature); + pInstance->SetData(TYPE_PRECIOUS,DONE); + } + } + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (nexttick) + { + doCast(SPELL_OOZE_FLOOD_1); + DoScriptText(-1631227,m_creature); + nexttick = false; + }; + + if (timedQuery(SPELL_OOZE_FLOOD_1, diff)) + { + uint8 i = urand(0,3); + if (Unit* pTemp = doSummon(NPC_OOZE_STALKER,SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z, TEMPSUMMON_TIMED_DESPAWN, 15000)) + { + doCast(SPELL_OOZE_FLOOD, pTemp); + nexttick = true; + } + }; + + if (timedQuery(SPELL_SLIME_SPRAY, diff)) + if (doSummon(NPC_OOZE_SPRAY_STALKER)) + doCast(SPELL_SLIME_SPRAY); + + if (timedQuery(SPELL_MUTATED_INFECTION, diff)) + { + for(uint8 i = 0; i < getSpellData(SPELL_MUTATED_INFECTION); ++i) + if (Unit* pTarget = doSelectRandomPlayer(SPELL_MUTATED_INFECTION_AURA, false, 60.0f)) + doCast(SPELL_MUTATED_INFECTION, pTarget); + DoScriptText(-1631226,m_creature); + } + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631225,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + + +CreatureAI* GetAI_boss_rotface(Creature* pCreature) +{ + return new boss_rotfaceAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_small_oozeAI : public BSWScriptedAI +{ + mob_small_oozeAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + resetTimers(); + m_creature->SetRespawnDelay(7*DAY); + doCast(SPELL_RADIATING_OOZE); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_RUN, 0.5); + m_creature->SetSpeedRate(MOVE_WALK, 0.5); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_STICKY_OOZE, uiDiff); + + if (Creature* pTemp = doSelectNearestCreature(m_creature->GetEntry(),7.0f)) + { + doCast(SPELL_MERGE_OOZE, pTemp); + doSummon(NPC_BIG_OOZE); + pTemp->ForcedDespawn(); + m_creature->ForcedDespawn(); + }; + } +}; + +CreatureAI* GetAI_mob_small_ooze(Creature* pCreature) +{ + return new mob_small_oozeAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_big_oozeAI : public BSWScriptedAI +{ + mob_big_oozeAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + bool exploded; + + void Reset() + { + resetTimers(); + m_creature->SetRespawnDelay(7*DAY); + doCast(SPELL_UNSTABLE_OOZE); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_RUN, 0.5); + m_creature->SetSpeedRate(MOVE_WALK, 0.5); + exploded = false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_STICKY_OOZE, uiDiff); + + if (Creature* pSmall = doSelectNearestCreature(NPC_SMALL_OOZE,5.0f)) + { + pSmall->ForcedDespawn(); + doCast(SPELL_UNSTABLE_OOZE); + }; + + if (Creature* pBig = doSelectNearestCreature(NPC_BIG_OOZE, 8.0f)) + { + pBig->ForcedDespawn(); + doCast(SPELL_UNSTABLE_OOZE); + } + + if ( auraCount(SPELL_UNSTABLE_OOZE_AURA) > 4 && !exploded) + { + doCast(SPELL_OOZE_EXPLODE); + exploded = true; + } + + } +}; + +CreatureAI* GetAI_mob_big_ooze(Creature* pCreature) +{ + return new mob_big_oozeAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_sticky_oozeAI : public ScriptedAI +{ + mob_sticky_oozeAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + m_creature->SetDisplayId(11686); + m_creature->SetRespawnDelay(7*DAY); + m_creature->CastSpell(m_creature, SPELL_STICKY_AURA, true); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWithZone(); + SetCombatMovement(false); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + } +}; + +CreatureAI* GetAI_mob_sticky_ooze(Creature* pCreature) +{ + return new mob_sticky_oozeAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_ooze_explode_stalkerAI : public BSWScriptedAI +{ + mob_ooze_explode_stalkerAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + Creature* creator; + + void Reset() + { + m_creature->SetDisplayId(11686); + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + m_creature->SetInCombatWithZone(); + doCast(SPELL_OOZE_EXPLODE_AURA); + creator = doSelectNearestCreature(NPC_BIG_OOZE, 20.0f); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (creator && creator->isAlive()) + creator->ForcedDespawn(); + + if (timedQuery(SPELL_OOZE_EXPLODE_AURA, uiDiff)) + m_creature->ForcedDespawn(); + + } +}; + +CreatureAI* GetAI_mob_ooze_explode_stalker(Creature* pCreature) +{ + return new mob_ooze_explode_stalkerAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_ooze_spray_stalkerAI : public ScriptedAI +{ + mob_ooze_spray_stalkerAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + SetCombatMovement(false); + m_creature->SetDisplayId(11686); + } + + void AttackStart(Unit *pWho) + { + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS) + m_creature->ForcedDespawn(); + } +}; + +CreatureAI* GetAI_mob_ooze_spray_stalker(Creature* pCreature) +{ + return new mob_ooze_spray_stalkerAI(pCreature); +} + +void AddSC_boss_rotface() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_rotface"; + newscript->GetAI = &GetAI_boss_rotface; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_small_ooze"; + newscript->GetAI = &GetAI_mob_small_ooze; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_big_ooze"; + newscript->GetAI = &GetAI_mob_big_ooze; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_sticky_ooze"; + newscript->GetAI = &GetAI_mob_sticky_ooze; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ooze_explode_stalker"; + newscript->GetAI = &GetAI_mob_ooze_explode_stalker; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ooze_spray_stalker"; + newscript->GetAI = &GetAI_mob_ooze_spray_stalker; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp index f89bd8b31..c7cef46c8 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,700 @@ /* ScriptData SDName: boss_sindragosa -SD%Complete: 0% -SDComment: +SD%Complete: 80% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need correct timers and models #include "precompiled.h" +#include "icecrown_citadel.h" + +enum BossSpells +{ +// Sindragosa + SPELL_FROST_AURA_1 = 70084, + SPELL_CLEAVE_1 = 19983, + SPELL_TAIL_SMASH = 71077, + SPELL_FROST_BREATH_1 = 69649, + SPELL_PERMEATING_CHILL = 70107, + SPELL_UNCHAINED_MAGIC = 69762, + SPELL_INSTABILITY = 69766, + SPELL_ICY_GRIP = 70117, + SPELL_BLISTERING_COLD = 70123, + + SPELL_FROST_BEACON = 70126, + SPELL_ICY_TOMB = 70157, + SPELL_ASPHYXATION = 71665, + SPELL_FROST_BOMB = 69845, + SPELL_FROST_BOMB_TRIGGER = 69846, + SPELL_FROST_BOMB_VISUAL = 64624, + SPELL_FROST_BOMB_VISUAL2 = 64626, + SPELL_ICE_TOMB_TRIGGER = 69675, + SPELL_MYSTIC_BUFFET = 70128, + + NPC_ICE_TOMB = 36980, + NPC_FROST_BOMB = 37186, + + SPELL_FLY = 59553, + FROST_IMBUED_BLADE_AURA = 72290, + + SPELL_BERSERK = 47008, + +// Rimefang + SPELL_FROST_AURA = 71387, + SPELL_FROST_BREATH = 71386, + SPELL_ICY_BLAST = 71376, +// Spinestalker + SPELL_BELLOWING_ROAR = 36922, + SPELL_CLEAVE = 40505, + SPELL_TAIL_SWEEP = 71369, +}; + +static Locations SpawnLoc[]= +{ + {4408.052734f, 2484.825439f, 203.374207f}, // 0 Sindragosa spawn + {4474.239746f, 2484.243896f, 231.0f}, // 1 Sindragosa fly o=3.11 + {4474.239746f, 2484.243896f, 203.380402f}, // 2 Sindragosa fly - ground point o=3.11 +}; + +struct MANGOS_DLL_DECL boss_sindragosaAI : public BSWScriptedAI +{ + boss_sindragosaAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + bool MovementStarted; + bool gripped; + Unit* marked[5]; + uint8 bombs; + + void Reset() + { + if(!pInstance) + return; + + resetTimers(); + setStage(0); + bombs = 0; + gripped = false; + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetSpeedRate(MOVE_RUN, 1.0f); + m_creature->SetSpeedRate(MOVE_WALK, 1.0f); + + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + + Creature* pTemp1 = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_RIMEFANG)); + Creature* pTemp2 = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SPINESTALKER)); + + if (pTemp1 && pTemp1->isAlive() && pTemp2 && pTemp2->isAlive()) + m_creature->ForcedDespawn(); + + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631421,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631422,m_creature,pVictim); + break; + } + } + + void JustReachedHome() + { + if (!pInstance) + return; + + pInstance->SetData(TYPE_SINDRAGOSA, FAIL); + doRemoveFromAll(SPELL_ICY_TOMB); + DoScriptText(-1631422,m_creature); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_RIMEFANG))) + if (!pTemp->isAlive()) + pTemp->SetRespawnDelay(HOUR); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SPINESTALKER))) + if (!pTemp->isAlive()) + pTemp->SetRespawnDelay(HOUR); + } + + void EnterEvadeMode() + { + if (!pInstance) + return; + + if (getStage() == 4) + return; + SetCombatMovement(true); + m_creature->RemoveAurasDueToSpell(SPELL_FLY); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + + ScriptedAI::EnterEvadeMode(); + } + + void Aggro(Unit *who) + { + if(!pInstance) + return; + + DoScriptText(-1631420,m_creature,who); + doCast(SPELL_FROST_AURA_1); + + if (Unit* pTarget = doSelectRandomPlayer(SPELL_SHADOWS_EDGE, true, 100.0f)) + doAura(FROST_IMBUED_BLADE_AURA,pTarget); + } + + void JustDied(Unit *killer) + { + if (!pInstance) + return; + doRemoveFromAll(SPELL_ICY_TOMB); + pInstance->SetData(TYPE_SINDRAGOSA, DONE); + DoScriptText(-1631423,m_creature,killer); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_RIMEFANG))) + pTemp->SetRespawnDelay(7*DAY); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SPINESTALKER))) + pTemp->SetRespawnDelay(7*DAY); + } + + void MovementInform(uint32 type, uint32 id) + { + if (!pInstance) + return; + + if (type != POINT_MOTION_TYPE || !MovementStarted) + return; + + if (id == 1) + { + m_creature->GetMotionMaster()->MovementExpired(); + MovementStarted = false; + } + } + + void IceMark() + { + for (uint8 i = 0; i < getSpellData(SPELL_FROST_BEACON); i++) + marked[i] = NULL; + + for (uint8 i = 0; i < getSpellData(SPELL_FROST_BEACON); i++) + if (marked[i] = doSelectRandomPlayer(SPELL_FROST_BEACON, false, 200.0f)) + doCast(SPELL_FROST_BEACON, marked[i]); + } + + void IceBlock() + { + for (uint8 i = 0; i < getSpellData(SPELL_FROST_BEACON); i++) + if (marked[i] && marked[i]->isAlive()) + { + doCast(SPELL_ICY_TOMB, marked[i]); + marked[i]->RemoveAurasDueToSpell(SPELL_FROST_BEACON); + float fPosX, fPosY, fPosZ; + marked[i]->GetPosition(fPosX, fPosY, fPosZ); + if (Unit* pTemp1 = doSummon(NPC_ICE_TOMB,fPosX, fPosY, fPosZ)) + pTemp1->AddThreat(marked[i], 1000.0f); + }; + + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(getStage()) + { + case 0: + timedCast(SPELL_CLEAVE_1, diff); + timedCast(SPELL_TAIL_SMASH, diff); + timedCast(SPELL_FROST_BREATH_1, diff); + timedCast(SPELL_PERMEATING_CHILL, diff); + + timedCast(SPELL_UNCHAINED_MAGIC, diff); + + if (timedQuery(SPELL_ICY_GRIP, diff) && !gripped) + { + doCast(SPELL_ICY_GRIP); + gripped = true; + } + + if (gripped && !m_creature->IsNonMeleeSpellCasted(true,false,false)) + { + DoScriptText(-1631426,m_creature); + doCast(SPELL_BLISTERING_COLD); + gripped = false; + } + + if (timedQuery(SPELL_FROST_BEACON, diff) && m_creature->GetHealthPercent() < 85.0f) + setStage(1); + + if (m_creature->GetHealthPercent() < 35.0f) + { + doCast(SPELL_MYSTIC_BUFFET); + setStage(9); + DoScriptText(-1631429,m_creature); + } + break; + case 1: + DoScriptText(-1631425,m_creature); + IceMark(); + setStage(2); + MovementStarted = true; + SetCombatMovement(false); + m_creature->CastSpell(m_creature,SPELL_FLY, true); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_UP); + break; + case 2: + if (!MovementStarted) + { + setStage(3); + m_creature->SetOrientation(3.1f); + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_FLY_FALL); + }; + break; + case 3: + IceBlock(); + setStage(4); + break; + case 4: + if (timedQuery(SPELL_FROST_BOMB, diff)) + { + if (Unit* pTemp = doSelectRandomPlayerAtRange(300.0f)) + { + doCast(SPELL_FROST_BOMB_TRIGGER, pTemp); + } + ++bombs; + } + + timedCast(SPELL_FROST_BREATH_1, diff); + + if (timedQuery(SPELL_FROST_BEACON, diff) || bombs >= getSpellData(SPELL_FROST_BOMB)) + { + setStage(5); + } + break; + case 5: + bombs = 0; + MovementStarted = true; + SetCombatMovement(false); + m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z); + setStage(6); + m_creature->HandleEmoteCommand(EMOTE_STATE_FLY_SIT_GROUND); + break; + case 6: + if (!MovementStarted) + { + setStage(0); + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->RemoveAurasDueToSpell(SPELL_FLY); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + }; + break; + + case 9: + timedCast(SPELL_CLEAVE_1, diff); + timedCast(SPELL_TAIL_SMASH, diff); + timedCast(SPELL_FROST_BREATH_1, diff); + timedCast(SPELL_PERMEATING_CHILL, diff); + timedCast(SPELL_UNCHAINED_MAGIC, diff); + + if (timedQuery(SPELL_ICY_GRIP, diff) && !gripped) + { + doCast(SPELL_ICY_GRIP); + gripped = true; + } + + if (gripped && !m_creature->IsNonMeleeSpellCasted(true,false,false)) + { + DoScriptText(-1631426,m_creature); + doCast(SPELL_BLISTERING_COLD); + gripped = false; + } + + break; + default: + break; + } + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631424,m_creature); + }; + + DoMeleeAttackIfReady(); + } +}; + + +CreatureAI* GetAI_boss_sindragosa(Creature* pCreature) +{ + return new boss_sindragosaAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_ice_tombAI : public BSWScriptedAI +{ + mob_ice_tombAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint64 victimGUID; + + void Reset() + { + SetCombatMovement(false); + victimGUID = 0; + m_creature->SetRespawnDelay(7*DAY); + } + + void Aggro(Unit* pWho) + { + if (!victimGUID && pWho && pWho->GetTypeId() == TYPEID_PLAYER) + { + if (pWho->HasAura(SPELL_ICY_TOMB)) + { + victimGUID = pWho->GetGUID(); + m_creature->SetInCombatWith(pWho); + } + else if (Unit* pTarget = doSelectRandomPlayer(SPELL_ICY_TOMB,true,3.0f)) + { + victimGUID = pTarget->GetGUID(); + m_creature->SetInCombatWith(pTarget); + } + + } + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (uiDamage > m_creature->GetHealth()) + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID)) + doRemove(SPELL_ICY_TOMB, pVictim); + } + + void AttackStart(Unit *pWho) + { + } + + void KilledUnit(Unit* _Victim) + { + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID)) + doRemove(SPELL_ICY_TOMB,pVictim); + } + + void JustDied(Unit* Killer) + { + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID)) + doRemove(SPELL_ICY_TOMB,pVictim); + } + + void UpdateAI(const uint32 uiDiff) + { + if ((m_pInstance && m_pInstance->GetData(TYPE_SINDRAGOSA) != IN_PROGRESS) + || (victimGUID && !m_creature->GetMap()->GetPlayer(victimGUID)->HasAura(SPELL_ICY_TOMB))) + { + if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID)) + doRemove(SPELL_ICY_TOMB,pVictim); + m_creature->ForcedDespawn(); + } + } + +}; + +CreatureAI* GetAI_mob_ice_tomb(Creature* pCreature) +{ + return new mob_ice_tombAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_frost_bombAI : public ScriptedAI +{ + mob_frost_bombAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance *m_pInstance; + uint32 boom_timer; + uint32 visual_timer; + bool finita; + + void Reset() + { + SetCombatMovement(false); + m_creature->SetRespawnDelay(7*DAY); + visual_timer = 6000; + boom_timer = 9000; + finita = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void AttackStart(Unit *pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance && m_pInstance->GetData(TYPE_SINDRAGOSA) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (finita) + { + m_creature->CastSpell(m_creature, SPELL_FROST_BOMB, true); + m_creature->ForcedDespawn(); + } + + if (visual_timer <= uiDiff) + { + m_creature->CastSpell(m_creature, SPELL_FROST_BOMB_VISUAL, true); + visual_timer= DAY; + } + else visual_timer -= uiDiff; + + if (boom_timer <= uiDiff) + { + m_creature->CastSpell(m_creature,SPELL_FROST_BOMB_VISUAL2,false); + finita = true; + } + else boom_timer -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_frost_bomb(Creature* pCreature) +{ + return new mob_frost_bombAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_rimefangAI : public BSWScriptedAI +{ + mob_rimefangAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + Creature* pBrother; + + void Reset() + { + if(!pInstance) return; + if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) + pInstance->SetData(TYPE_SINDRAGOSA, NOT_STARTED); + resetTimers(); + m_creature->SetRespawnDelay(30*MINUTE); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pInstance || !pWho) return; + + if (pWho->GetTypeId() != TYPEID_PLAYER) + return; + + if (!m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 60.0f)) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + m_creature->GetMotionMaster()->MovementExpired(); + AttackStart(pWho); + SetCombatMovement(true); + } + ScriptedAI::MoveInLineOfSight(pWho); + } + + void JustReachedHome() + { + if (pInstance) + if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) + pInstance->SetData(TYPE_SINDRAGOSA, FAIL); + } + + void Aggro(Unit *who) + { + if(!pInstance) return; + if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) pInstance->SetData(TYPE_SINDRAGOSA, IN_PROGRESS); + pBrother = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SPINESTALKER)); + if (pBrother && !pBrother->isAlive()) pBrother->Respawn(); + if (pBrother) pBrother->SetInCombatWithZone(); + } + + void JustDied(Unit *killer) + { + if(!pInstance) return; + if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE) + return; + if (pBrother && !pBrother->isAlive()) + if (pBrother && !pBrother->isAlive()) + { + Creature* pSindr = m_creature->SummonCreature(NPC_SINDRAGOSA, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 3.17f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR*IN_MILLISECONDS, true); + if (pSindr) + pSindr->SetCreatorGuid(ObjectGuid()); + } + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance || !m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE) + { + m_creature->SetRespawnDelay(DAY); + m_creature->ForcedDespawn(); + return; + } + + doCastAll(diff); + DoMeleeAttackIfReady(); + } +}; + + +CreatureAI* GetAI_mob_rimefang(Creature* pCreature) +{ + return new mob_rimefangAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_spinestalkerAI : public BSWScriptedAI +{ + mob_spinestalkerAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + Creature* pBrother; + + void Reset() + { + if(!pInstance) return; + if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) + pInstance->SetData(TYPE_SINDRAGOSA, NOT_STARTED); + resetTimers(); + m_creature->SetRespawnDelay(30*MINUTE); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pInstance || !pWho) return; + + if (pWho->GetTypeId() != TYPEID_PLAYER) + return; + + if (!m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 60.0f)) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + m_creature->GetMotionMaster()->MovementExpired(); + AttackStart(pWho); + SetCombatMovement(true); + } + ScriptedAI::MoveInLineOfSight(pWho); + } + + void JustReachedHome() + { + if (pInstance) + if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) + pInstance->SetData(TYPE_SINDRAGOSA, FAIL); + } + + void Aggro(Unit *who) + { + if(!pInstance) return; + if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) pInstance->SetData(TYPE_SINDRAGOSA, IN_PROGRESS); + pBrother = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_RIMEFANG)); + if (pBrother && !pBrother->isAlive()) pBrother->Respawn(); + if (pBrother) pBrother->SetInCombatWithZone(); + } + + void JustDied(Unit *killer) + { + if (!pInstance) + return; + if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE) + return; + if (pBrother && !pBrother->isAlive()) + { + Creature* pSindr = m_creature->SummonCreature(NPC_SINDRAGOSA, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 3.17f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR*IN_MILLISECONDS, true); + if (pSindr) + pSindr->SetCreatorGuid(ObjectGuid()); + } + } + + void UpdateAI(const uint32 diff) + { + + if (!pInstance || !m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE) + { + m_creature->SetRespawnDelay(DAY); + m_creature->ForcedDespawn(); + return; + } + + doCastAll(diff); + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_spinestalker(Creature* pCreature) +{ + return new mob_spinestalkerAI(pCreature); +} + +void AddSC_boss_sindragosa() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_sindragosa"; + newscript->GetAI = &GetAI_boss_sindragosa; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_rimefang"; + newscript->GetAI = &GetAI_mob_rimefang; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_spinestalker"; + newscript->GetAI = &GetAI_mob_spinestalker; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ice_tomb"; + newscript->GetAI = &GetAI_mob_ice_tomb; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_frost_bomb"; + newscript->GetAI = &GetAI_mob_frost_bomb; + newscript->RegisterSelf(); + +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp index 1e5775b0c..50f101612 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,1210 @@ /* ScriptData SDName: boss_the_lich_king -SD%Complete: 0% -SDComment: +SD%Complete: 70% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need implement "in sword" phase #include "precompiled.h" +#include "icecrown_citadel.h" + +enum BossSpells +{ + SPELL_INFEST = 70541, + SPELL_NECROTIC_PLAGUE = 70337, + SPELL_PLAGUE_SIPHON = 74074, + SPELL_SOUL_REAPER = 69409, + SPELL_SPAWN_DEFILE = 72762, + SPELL_HARVEST_SOUL = 68980, + SPELL_HARVEST_SOUL_TELEPORT = 71372, +// + SPELL_CHANNEL_KING = 71769, + SPELL_BROKEN_FROSTMOURNE = 72398, + SPELL_BOOM_VISUAL = 72726, + SPELL_ICEBLOCK_TRIGGER = 71614, + SPELL_TIRION_LIGHT = 71797, + SPELL_FROSTMOURNE_TRIGGER = 72405, + SPELL_SUMMON_BROKEN_FROSTMOURNE = 72406, + SPELL_SUMMON_BROKEN_FROSTMOURNE_2 = 73017, + SPELL_DISENGAGE = 61508, + SPELL_FURY_OF_FROSTMOURNE = 70063, + SPELL_REVIVE_VISUAL = 37755, //Override? + SPELL_REVIVE = 51918, + SPELL_CLONE_PLAYER = 57507, + SPELL_BERSERK = 47008, + +//Transition phase + SPELL_REMORSELESS_WINTER = 68981, + SPELL_PAIN_AND_SUFFERING = 72133, + SPELL_QUAKE = 72262, + +//Raging spirit +// SPELL_SUMMON_RAGING_SPIRIT = 69201, // triggered + SPELL_SUMMON_RAGING_SPIRIT = 69200, + SPELL_SOUL_SHRIEK = 69242, + +//Ice sphere + SPELL_SUMMON_ICE_SPHERE = 69103, + SPELL_ICE_PULSE = 69099, + SPELL_ICE_BURST = 69108, + SPELL_ICE_SPHERE_VISUAL = 69090, + +//Drudge ghouls + SPELL_SUMMON_DRUDGE_GHOULS = 70358, + +//Shambling horror + SPELL_SUMMON_SHAMBLING_HORROR = 70372, + SPELL_SHOCKWAVE = 72149, + SPELL_HORROR_ENRAGE = 72143, + +//Vile spirits + SPELL_SUMMON_VILE_SPIRITS = 70498, + SPELL_SPIRITS_BURST = 70503, + +//Valkyr + SPELL_SUMMON_VALKYR = 69037, + NPC_VALKYR = 36609, + SPELL_WINGS_OF_THE_DAMNED = 74352, + +//Defile + SPELL_DEFILE = 72743, + +// Menethil + SPELL_REVALL = 26687, +// + NPC_ICE_SPHERE = 36633, + NPC_DEFILER = 38757, + NPC_RAGING_SPIRIT = 36701, + NPC_VILE_SPIRIT = 37799, + NPC_STRANGULATE_VEHICLE = 36598, + +}; + +enum Common +{ + FINAL_ARTHAS_MOVIE = 16, +}; + +static Locations SpawnLoc[]= +{ + {459.93689f, -2124.638184f, 1040.860107f}, // 0 Lich King Intro + {503.15652f, -2124.516602f, 1040.860107f}, // 1 Lich king move end + {491.27118f, -2124.638184f, 1040.860107f}, // 2 Tirion 1 + {481.69797f, -2124.638184f, 1040.860107f}, // 3 Tirion 2 + {498.00448f, -2201.573486f, 1046.093872f}, // 4 Valkyrs? + {517.48291f, -2124.905762f, 1040.861328f}, // 5 Tirion? + {529.85302f, -2124.709961f, 1040.859985f}, // 6 Lich king final, o=3.1146 + {520.311f, -2124.709961f, 1040.859985f}, // 7 Frostmourne +}; + +struct MANGOS_DLL_DECL boss_the_lich_king_iccAI : public BSWScriptedAI +{ + boss_the_lich_king_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (instance_icecrown_spire*)pCreature->GetInstanceData(); + oldflag = 0; + Reset(); + } + + instance_icecrown_spire* pInstance; + uint8 stage; + uint32 nextEvent; + uint32 nextPoint; + uint32 UpdateTimer; + uint32 oldflag; + bool movementstarted; + bool battlestarted; + bool finalphase; + Creature* pTirion; + Creature* pFrostmourne; + std::list mobsGUIDList; + + void Reset() + { + if(!pInstance) return; + resetTimers(); + mobsGUIDList.clear(); + stage = 0; + nextEvent = 0; + nextPoint = 0; + movementstarted = false; + battlestarted = false; + finalphase = false; + m_creature->SetOrientation(0.0f); + pInstance->DoCloseDoor(pInstance->GetData64(GO_ICESHARD_1)); + pInstance->DoCloseDoor(pInstance->GetData64(GO_ICESHARD_2)); + pInstance->DoCloseDoor(pInstance->GetData64(GO_ICESHARD_3)); + pInstance->DoCloseDoor(pInstance->GetData64(GO_ICESHARD_4)); + if (oldflag) + if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM))) + { + pGoFloor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN); + pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,oldflag); + } + pInstance->DoCloseDoor(pInstance->GetData64(GO_FROSTY_WIND)); + } + + void MoveInLineOfSight(Unit* pWho) + { + } + + void EnterEvadeMode() + { + if (!pInstance) return; + if (finalphase && pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS) return; + + DespawnMobs(); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + if (m_creature->isAlive()) + m_creature->GetMotionMaster()->MoveTargetedHome(); + + m_creature->SetLootRecipient(NULL); + + Reset(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !movementstarted) return; + if (id == nextPoint) + { + movementstarted = false; + pInstance->SetData(TYPE_EVENT,nextEvent); + m_creature->GetMotionMaster()->MovementExpired(); + } + } + + void KilledUnit(Unit* pVictim) + { + + if (!battlestarted) return; + + switch (urand(0,1)) { + case 0: + DoScriptText(-1631519,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631517,m_creature,pVictim); + break; + }; + } + + void JustReachedHome() + { + if (!pInstance) return; + pInstance->SetData(TYPE_LICH_KING, FAIL); + stage = 0; + battlestarted = false; + finalphase = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + + void StartMovement(uint32 id, uint32 _nextEvent) + { + nextPoint = id; + nextEvent = _nextEvent; + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z); + pInstance->SetData(TYPE_EVENT,0); + movementstarted = true; + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned) return; + + if (Unit* pTarget = doSelectRandomPlayerAtRange(60.0f)) + { + summoned->SetInCombatWith(pTarget); + summoned->AddThreat(pTarget,100.0f); + } + mobsGUIDList.push_back(summoned->GetGUID()); + } + + void DespawnMobs() + { + if (mobsGUIDList.empty()) + return; + + for(std::list::iterator itr = mobsGUIDList.begin(); itr != mobsGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + if (pTemp->isAlive()) + { + pTemp->DeleteThreatList(); + pTemp->CombatStop(true); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + mobsGUIDList.clear(); + } + + + void Aggro(Unit *who) + { + if(!pInstance) return; + pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS); + } + + void JustDied(Unit *killer) + { + if(!pInstance) return; + pInstance->SetData(TYPE_LICH_KING, DONE); + DoScriptText(-1631528,m_creature,killer); + + pInstance->SetData(TYPE_EVENT,14010); + DespawnMobs(); + + } + + void UpdateAI(const uint32 diff) + { + + if(!pInstance) return; + + if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_LICH_KING) + { + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + if (UpdateTimer <= diff) + { + debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT)); + switch (pInstance->GetData(TYPE_EVENT)) + { + case 12000: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + StartMovement(0,12020); + break; + case 12020: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK); + DoScriptText(-1631501, m_creature); + UpdateTimer = 12000; + pInstance->SetData(TYPE_EVENT,12030); + break; + case 12040: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); + DoScriptText(-1631503, m_creature); + UpdateTimer = 8000; + pInstance->SetData(TYPE_EVENT,12041); + break; + case 12041: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LAUGH); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,12042); + break; + case 12042: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_ONESHOT_POINT_NOSHEATHE); + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,12043); + break; + case 12043: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_ONESHOT_NONE); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,12050); + break; + case 12060: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK); + DoScriptText(-1631505, m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,12080); + break; + case 12080: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_STATE_READY2H); + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,12100); + break; + case 12100: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_ONESHOT_NONE); + UpdateTimer = 6000; + pInstance->SetData(TYPE_EVENT,12120); + break; + case 12120: + m_creature->GetMotionMaster()->Clear(); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + battlestarted = true; + pInstance->SetData(TYPE_EVENT,12200); + UpdateTimer = 10000; + break; + case 12200: + DoScriptText(-1631506, m_creature); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,12220); + break; + case 13000: + m_creature->SetOrientation(3.1146f); + DoScriptText(-1631507, m_creature); + UpdateTimer = 12000; + finalphase = true; + doCast(SPELL_FURY_OF_FROSTMOURNE); + pInstance->SetData(TYPE_EVENT,13020); + if (pTirion = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_TIRION))) { + m_creature->SetInCombatWith(pTirion); + pTirion->AddThreat(m_creature, 1000.0f); + } + m_creature->SetInCombatWithZone(); + break; + case 13020: + DoScriptText(-1631508, m_creature); + UpdateTimer = 12000; + pInstance->SetData(TYPE_EVENT,13060); + break; + case 13060: + DoScriptText(-1631509, m_creature); + UpdateTimer = 15000; + pInstance->SetData(TYPE_EVENT,13100); + break; + case 13100: + DoScriptText(-1631510, m_creature); + UpdateTimer = 15000; + pInstance->SetData(TYPE_EVENT,13110); + doCast(SPELL_CHANNEL_KING); + break; + case 13120: + DoScriptText(-1631511, m_creature); + UpdateTimer = 12000; + pInstance->SetData(TYPE_EVENT,13130); + break; + case 13140: + UpdateTimer = 6000; + doRemove(SPELL_CHANNEL_KING); + pInstance->SetData(TYPE_EVENT,13150); + m_creature->CastSpell(m_creature, SPELL_SUMMON_BROKEN_FROSTMOURNE, false); + break; + case 13160: + UpdateTimer = 6000; + pInstance->SetData(TYPE_EVENT,13170); + m_creature->CastSpell(m_creature, SPELL_SUMMON_BROKEN_FROSTMOURNE_2, false); + break; + case 13180: + UpdateTimer = 12000; + pInstance->SetData(TYPE_EVENT,13190); + if (pFrostmourne = m_creature->SummonCreature(NPC_FROSTMOURNE_HOLDER, SpawnLoc[7].x, SpawnLoc[7].y, SpawnLoc[7].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000)) + { + pFrostmourne->CastSpell(pFrostmourne, SPELL_BROKEN_FROSTMOURNE, false); + pFrostmourne->CastSpell(pFrostmourne, SPELL_FROSTMOURNE_TRIGGER, false); + pFrostmourne->GetMotionMaster()->MoveChase(m_creature); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + } + break; + case 13200: + DoScriptText(-1631512, m_creature); + m_creature->RemoveAurasDueToSpell(SPELL_SUMMON_BROKEN_FROSTMOURNE); + m_creature->RemoveAllAuras(); + pFrostmourne->RemoveAurasDueToSpell(SPELL_FROSTMOURNE_TRIGGER); + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,13210); + break; + case 13280: + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,13290); + stage = 13; + if (pFrostmourne) pFrostmourne->ForcedDespawn(); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_FROSTMOURNE_TRIGGER))) + pTemp->ForcedDespawn(); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_FROSTMOURNE_HOLDER))) + pTemp->ForcedDespawn(); + SetCombatMovement(true); + battlestarted = true; + break; + default: + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + } + + if (battlestarted && !m_creature->SelectHostileTarget() && !finalphase) + { + battlestarted = false; + pInstance->SetData(TYPE_LICH_KING, FAIL); + pInstance->SetData(TYPE_EVENT,0); + EnterEvadeMode(); + return; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(stage) + { + case 0: // Phase 1 +// timedCast(SPELL_SHOCKWAVE, diff); + timedCast(SPELL_INFEST, diff); + timedCast(SPELL_SUMMON_DRUDGE_GHOULS, diff); + timedCast(SPELL_PLAGUE_SIPHON, diff); + timedCast(SPELL_SUMMON_SHAMBLING_HORROR, diff); + timedCast(SPELL_NECROTIC_PLAGUE, diff); + + DoMeleeAttackIfReady(); + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631518,m_creature); + }; + + if (m_creature->GetHealthPercent() < 70.0f) + { + stage = 1; + DoScriptText(-1631515,m_creature); + } + break; + case 1: // Go in transition phase + m_creature->AttackStop(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + StartMovement(1,0); + stage = 2; + break; + case 2: + if (movementstarted) return; + doCast(SPELL_REMORSELESS_WINTER); + stage = 3; + break; + case 3: + timedCast(SPELL_SUMMON_RAGING_SPIRIT, diff); + timedCast(SPELL_SUMMON_ICE_SPHERE, diff); + timedCast(SPELL_PAIN_AND_SUFFERING, diff); + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631518,m_creature); + }; + + if (timedQuery(SPELL_REMORSELESS_WINTER, diff)) + { + doCast(SPELL_QUAKE); + stage = 4; + DoScriptText(-1631524, m_creature); + pInstance->DoOpenDoor(pInstance->GetData64(GO_SNOW_EDGE)); + }; + break; + case 4: // Platform destruct + if (timedQuery(SPELL_QUAKE, diff)) + { + pInstance->DoOpenDoor(pInstance->GetData64(GO_ICESHARD_1)); + pInstance->DoOpenDoor(pInstance->GetData64(GO_ICESHARD_2)); + pInstance->DoOpenDoor(pInstance->GetData64(GO_ICESHARD_3)); + pInstance->DoOpenDoor(pInstance->GetData64(GO_ICESHARD_4)); + if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM))) + { + pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN); + oldflag = pGoFloor->GetUInt32Value(GAMEOBJECT_BYTES_1); + pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449); + } + pInstance->DoCloseDoor(pInstance->GetData64(GO_FROSTY_WIND)); + pInstance->DoCloseDoor(pInstance->GetData64(GO_SNOW_EDGE)); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(true); + stage = 5; + } + break; + case 5: // Phase 2 + + if (timedQuery(SPELL_SPAWN_DEFILE, diff)) + { + doCast(SPELL_SPAWN_DEFILE); + DoScriptText(-1631531,m_creature); + } + if (timedQuery(SPELL_SUMMON_VALKYR, diff)) + { + doCast(SPELL_SUMMON_VALKYR); + DoScriptText(-1631527,m_creature); + } + + timedCast(SPELL_SOUL_REAPER, diff); + timedCast(SPELL_INFEST, diff); + + DoMeleeAttackIfReady(); + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631518,m_creature); + }; + + if (m_creature->GetHealthPercent() < 40.0f) + { + stage = 6; + DoScriptText(-1631523,m_creature); + } + break; + case 6: // Go in transition phase + m_creature->AttackStop(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + StartMovement(1,0); + stage = 7; + break; + case 7: // Platform restore + if (movementstarted) return; + if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM))) + { + pGoFloor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN); + pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,oldflag); + } + pInstance->DoOpenDoor(pInstance->GetData64(GO_FROSTY_WIND)); + doCast(SPELL_REMORSELESS_WINTER); + stage = 8; + break; + case 8: + timedCast(SPELL_SUMMON_RAGING_SPIRIT, diff); + timedCast(SPELL_SUMMON_ICE_SPHERE, diff); + timedCast(SPELL_PAIN_AND_SUFFERING, diff); + + if (timedQuery(SPELL_BERSERK, diff)) + { + doCast(SPELL_BERSERK); + DoScriptText(-1631518,m_creature); + }; + + if (timedQuery(SPELL_REMORSELESS_WINTER, diff)) + { + DoScriptText(-1631524, m_creature); + doCast(SPELL_SUMMON_VILE_SPIRITS); + for (uint8 i = 0; i < getSpellData(SPELL_SUMMON_VILE_SPIRITS); ++i) + doCast(NPC_VILE_SPIRIT); + doCast(SPELL_QUAKE); + stage = 9; + pInstance->DoOpenDoor(pInstance->GetData64(GO_SNOW_EDGE)); + }; + + break; + case 9: // Platform destruct + if (timedQuery(SPELL_QUAKE, diff)) + { + if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM))) + { + pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN); + oldflag = pGoFloor->GetUInt32Value(GAMEOBJECT_BYTES_1); + pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449); + } + pInstance->DoCloseDoor(pInstance->GetData64(GO_SNOW_EDGE)); + pInstance->DoCloseDoor(pInstance->GetData64(GO_FROSTY_WIND)); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(true); + stage = 10; + } + break; + case 10: // Phase 3 + if (timedQuery(SPELL_SPAWN_DEFILE, diff)) + { + doCast(SPELL_SPAWN_DEFILE); +// DoScriptText(-1631527,m_creature); + } + timedCast(SPELL_SOUL_REAPER, diff); + + if (timedQuery(SPELL_HARVEST_SOUL, diff)) + { + doCast(SPELL_HARVEST_SOUL); + DoScriptText(-1631520,m_creature); + } + + timedCast(SPELL_SOUL_REAPER, diff); + timedCast(SPELL_INFEST, diff); + + DoMeleeAttackIfReady(); + + if (m_creature->GetHealthPercent() < 10.0f) + { + stage = 11; + DoScriptText(-1631513,m_creature); + } + break; + case 11: // Ending Phase start + m_creature->AttackStop(); + SetCombatMovement(false); + StartMovement(6,13000); + stage = 12; + battlestarted = false; + break; + case 12: + break; + case 13: + DoMeleeAttackIfReady(); + break; + } + } +}; + + +CreatureAI* GetAI_boss_the_lich_king_icc(Creature* pCreature) +{ + return new boss_the_lich_king_iccAI(pCreature); +}; + +struct MANGOS_DLL_DECL boss_tirion_iccAI : public ScriptedAI +{ + boss_tirion_iccAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint32 UpdateTimer; + uint32 nextEvent; + uint32 nextPoint; + bool movementstarted; + uint64 MenethilGUID; + + void EnterEvadeMode() + { + if (!pInstance) return; + if (pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS) return; + ScriptedAI::EnterEvadeMode(); + } + + void Reset() + { + if(!pInstance) return; + movementstarted = false; + m_creature->RemoveAurasDueToSpell(SPELL_ICEBLOCK_TRIGGER); + m_creature->SetOrientation(M_PI_F); + } + + void StartMovement(uint32 id, uint32 _nextEvent) + { + nextPoint = id; + nextEvent = _nextEvent; + m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z); + pInstance->SetData(TYPE_EVENT,0); + movementstarted = true; + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !movementstarted) return; + if (id == nextPoint) + { + movementstarted = false; + pInstance->SetData(TYPE_EVENT,nextEvent); + m_creature->GetMotionMaster()->MovementExpired(); + } + } + + void doSendCinematic() + { + Map::PlayerList const &pList = m_creature->GetMap()->GetPlayers(); + if (pList.isEmpty()) return; + for (Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i) + if (Player* pPlayer = i->getSource()) + if (pPlayer && pPlayer->isAlive() && pPlayer->IsInMap(m_creature)) + pPlayer->SendMovieStart(FINAL_ARTHAS_MOVIE); + } + + void doRevivePlayers() + { + Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID); + Map::PlayerList const &pList = pMenethil->GetMap()->GetPlayers(); + if (pList.isEmpty()) return; + for (Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i) + { + if (Player* pPlayer = i->getSource()) + { + if (pPlayer && !pPlayer->isAlive() && pPlayer->IsInMap(pMenethil)) + { + pMenethil->CastSpell(pPlayer, SPELL_REVALL, true); + pPlayer->ResurrectPlayer(100, false); + } + } + }; + } + + void UpdateAI(const uint32 diff) + { + + if (pInstance->GetData(TYPE_LICH_KING) == FAIL && m_creature->HasAura(SPELL_ICEBLOCK_TRIGGER)) + { + m_creature->RemoveAurasDueToSpell(SPELL_ICEBLOCK_TRIGGER); + m_creature->GetMotionMaster()->MoveTargetedHome(); + Reset(); + } + + if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_TIRION) + { + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + if (UpdateTimer <= diff) + { + debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT)); + switch (pInstance->GetData(TYPE_EVENT)) + { + case 12030: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK); + DoScriptText(-1631552, m_creature); + UpdateTimer = 9000; + pInstance->SetData(TYPE_EVENT,12040); + break; + case 12050: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_POINT_NOSHEATHE); + DoScriptText(-1631554, m_creature); + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,12051); + break; + case 12051: + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + UpdateTimer = 1000; + pInstance->SetData(TYPE_EVENT,12052); + break; + case 12052: + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + StartMovement(3,12053); + break; + case 12053: + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,12060); + m_creature->CastSpell(m_creature, SPELL_ICEBLOCK_TRIGGER, true); + break; + case 13110: + DoScriptText(-1631555, m_creature); + UpdateTimer = 6000; + m_creature->CastSpell(m_creature, SPELL_TIRION_LIGHT, false); + pInstance->SetData(TYPE_EVENT,13120); + break; + case 13130: + SetCombatMovement(false); + m_creature->RemoveAurasDueToSpell(SPELL_ICEBLOCK_TRIGGER); + UpdateTimer = 500; + m_creature->SetOrientation(0.0f); + pInstance->SetData(TYPE_EVENT,13131); + break; + case 13131: + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + StartMovement(2,13132); + break; + case 13132: + StartMovement(5,13140); + DoScriptText(-1631556, m_creature); + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); + break; + case 13150: + UpdateTimer = 1000; + pInstance->SetData(TYPE_EVENT,13160); + break; + case 13170: + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,13180); + break; + case 13190: + UpdateTimer = 500; + pInstance->SetData(TYPE_EVENT,13200); + break; + case 13210: + UpdateTimer = 3000; + pInstance->SetData(TYPE_EVENT,13230); + break; + case 13230: + UpdateTimer = 12000; + { + Creature* pMenethil = m_creature->SummonCreature(NPC_MENETHIL, m_creature->GetPositionX()+5, m_creature->GetPositionY()+5, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + MenethilGUID = pMenethil->GetGUID(); + } + pInstance->SetData(TYPE_EVENT,13250); + DoScriptText(-1631560, m_creature->GetMap()->GetCreature(MenethilGUID)); + break; + case 13250: + UpdateTimer = 6000; + pInstance->SetData(TYPE_EVENT,13270); + { + Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID); + DoScriptText(-1631561, pMenethil); + pMenethil->CastSpell(pMenethil, SPELL_REVIVE_VISUAL, false); + } + doRevivePlayers(); + break; + case 13270: + UpdateTimer = 6000; + pInstance->SetData(TYPE_EVENT,13280); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LICH_KING))) + { + m_creature->SetInCombatWith(pLichKing); + pLichKing->SetInCombatWith(m_creature); + pLichKing->AddThreat(m_creature, 1000.0f); + m_creature->AI()->AttackStart(pLichKing); + Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID); + pMenethil->AI()->AttackStart(pLichKing); + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(pLichKing); + }; + break; + case 13290: + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,13310); + DoScriptText(-1631590,m_creature->GetMap()->GetCreature(MenethilGUID)); + break; + case 13310: + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,13330); + DoScriptText(-1631591, m_creature); + break; + case 13330: + UpdateTimer = 5000; + pInstance->SetData(TYPE_EVENT,13350); + DoScriptText(-1631592, m_creature->GetMap()->GetCreature(MenethilGUID)); + break; + case 13350: + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,13370); + DoScriptText(-1631593, m_creature); + break; + case 14010: + m_creature->AttackStop(); + SetCombatMovement(false); + UpdateTimer =90000; + pInstance->SetData(TYPE_EVENT,14030); + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LICH_KING))) + pLichKing->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + doSendCinematic(); + break; + case 14030: + UpdateTimer = 20000; + pInstance->SetData(TYPE_EVENT,14030); + DoScriptText(-1631594, m_creature); + { + if (Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID)) + if (pMenethil->isAlive()) + pMenethil->ForcedDespawn(); + if (Creature* pLichKing = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LICH_KING))) + pLichKing->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + pInstance->SetData(TYPE_EVENT,0); + EnterEvadeMode(); + break; + default: + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + DoMeleeAttackIfReady(); + } + + +}; + +bool GossipHello_boss_tirion_icc(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance* pInstance; + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + + if (pInstance->GetData(TYPE_LICH_KING) != NOT_STARTED && + pInstance->GetData(TYPE_LICH_KING) != FAIL ) + { + pPlayer->PlayerTalkClass->SendGossipMenu(721002, pCreature->GetGUID()); + return true; + }; + + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3631608, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + pPlayer->PlayerTalkClass->SendGossipMenu(721001, pCreature->GetGUID()); + return true; +}; + +bool GossipSelect_boss_tirion_icc(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance* pInstance; + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + if (!pInstance) return false; + + if (uiAction == GOSSIP_ACTION_INFO_DEF) + { + pPlayer->CLOSE_GOSSIP_MENU(); + pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS); + pInstance->SetData(TYPE_EVENT,12000); + return true; + } else return false; +}; + +CreatureAI* GetAI_boss_tirion_icc(Creature* pCreature) +{ + return new boss_tirion_iccAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_ice_sphere_iccAI : public BSWScriptedAI +{ + mob_ice_sphere_iccAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + resetTimers(); + doCast(SPELL_ICE_SPHERE_VISUAL); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!hasAura(SPELL_ICE_SPHERE_VISUAL)) + doCast(SPELL_ICE_SPHERE_VISUAL); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + { + if (Unit* pTarget = doSelectRandomPlayerAtRange(120.0f)) + { + m_creature->SetInCombatWith(pTarget); + m_creature->AddThreat(pTarget,100.0f); + } + return; + } + + if (m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) + return; + + timedCast(SPELL_ICE_PULSE, uiDiff); + + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 1.0f)) + timedCast(SPELL_ICE_BURST,uiDiff); + } +}; + +CreatureAI* GetAI_mob_ice_sphere_icc(Creature* pCreature) +{ + return new mob_ice_sphere_iccAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_defiler_iccAI : public BSWScriptedAI +{ + mob_defiler_iccAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance *m_pInstance; + uint32 life_timer; + float m_Size0; + float m_Size; + + void Reset() + { + SetCombatMovement(false); + life_timer = 30000; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->CastSpell(m_creature, SPELL_DEFILE, true); + m_Size0 = m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X); + m_Size = m_Size0; + } + + void AttackStart(Unit *pWho) + { + return; + } + + bool doSearchPlayers() + { + if(doSelectRandomPlayerAtRange(m_Size * 3.0f)) return true; + else return false; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance && m_pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (life_timer <= uiDiff) + m_creature->ForcedDespawn(); + else life_timer -= uiDiff; + + if (doSearchPlayers() && m_Size <= m_Size0 * 6.0f) { + m_Size = m_Size*1.01; + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_Size); + } + + } + +}; + +CreatureAI* GetAI_mob_defiler_icc(Creature* pCreature) +{ + return new mob_defiler_iccAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_strangulate_vehicleAI : public ScriptedAI +{ + mob_strangulate_vehicleAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance *m_pInstance; + + void Reset() + { + SetCombatMovement(false); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void AttackStart(Unit *pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + m_creature->ForcedDespawn(); + } + +}; + +CreatureAI* GetAI_mob_strangulate_vehicle(Creature* pCreature) +{ + return new mob_strangulate_vehicleAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_vile_spiritAI : public BSWScriptedAI +{ + mob_vile_spiritAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + bool movementstarted; + + void Reset() + { + resetTimers(); + if (Unit* pTarget = doSelectRandomPlayerAtRange(120.0f)) + { + m_creature->SetInCombatWith(pTarget); + m_creature->AddThreat(pTarget,1000.0f); + } + SetCombatMovement(false); + movementstarted = false; + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + } + + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (timedQuery(SPELL_SPIRITS_BURST, uiDiff) && !movementstarted) + { + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + movementstarted = true; + } + + if (m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) + return; + + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 1.0f)) + { + doCast(SPELL_SPIRITS_BURST); + m_creature->ForcedDespawn(); + }; + } +}; + +CreatureAI* GetAI_mob_vile_spirit(Creature* pCreature) +{ + return new mob_vile_spiritAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_raging_spiritAI : public BSWScriptedAI +{ + mob_raging_spiritAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + resetTimers(); + m_creature->SetDisplayId(10771); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + timedCast(SPELL_SOUL_SHRIEK, uiDiff); + } +}; + +CreatureAI* GetAI_mob_raging_spirit(Creature* pCreature) +{ + return new mob_raging_spiritAI(pCreature); +} + +void AddSC_boss_lich_king_icc() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_the_lich_king_icc"; + newscript->GetAI = &GetAI_boss_the_lich_king_icc; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_tirion_icc"; + newscript->GetAI = &GetAI_boss_tirion_icc; + newscript->pGossipHello = &GossipHello_boss_tirion_icc; + newscript->pGossipSelect = &GossipSelect_boss_tirion_icc; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ice_sphere_icc"; + newscript->GetAI = &GetAI_mob_ice_sphere_icc; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_defiler_icc"; + newscript->GetAI = &GetAI_mob_defiler_icc; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_strangulate_vehicle"; + newscript->GetAI = &GetAI_mob_strangulate_vehicle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_vile_spirit"; + newscript->GetAI = &GetAI_mob_vile_spirit; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_raging_spirit"; + newscript->GetAI = &GetAI_mob_raging_spirit; + newscript->RegisterSelf(); + +}; diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp index 528905ef0..1a71caa7a 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,9 +16,513 @@ /* ScriptData SDName: boss_valithria -SD%Complete: 0% -SDComment: +SD%Complete: 70% +SDComment: by /dev/rsa SDCategory: Icecrown Citadel EndScriptData */ - +// Need move emerald dream to phase 32, correct timers and other #include "precompiled.h" +#include "icecrown_citadel.h" + +static Locations SpawnLoc[]= +{ + {4203.470215f, 2484.500000f, 364.872009f}, // 0 Valithria + {4166.216797f, 2564.197266f, 364.873047f}, // 1 Valithria Room 1 + {4240.688477f, 2405.794678f, 364.868591f}, // 2 Valithria Room 2 + {4165.112305f, 2405.872559f, 364.872925f}, // 3 Valithria Room 3 + {4239.579102f, 2566.753418f, 364.868439f}, // 4 Valithria Room 4 + {4228.589844f, 2469.110107f, 364.868988f}, // 5 Mob 1 + {4236.000000f, 2479.500000f, 364.869995f}, // 6 Mob 2 + {4235.410156f, 2489.300049f, 364.872009f}, // 7 Mob 3 + {4228.509766f, 2500.310059f, 364.876007f}, // 8 Mob 4 +}; + +enum BossSpells +{ +// SPELL_NIGHTMARE_PORTAL = 72481, // Not worked yet. Use 71977 (visual effect) instead? + SPELL_NIGHTMARE_PORTAL = 71977, + SPELL_EMERALD_VIGOR = 70873, + SPELL_DREAMWALKER_RAGE = 71189, + SPELL_IMMUNITY = 72724, + SPELL_CORRUPTION = 70904, + SPELL_DREAM_SLIP = 71196, + SPELL_ICE_SPIKE = 70702, + +// Summons + NPC_RISEN_ARCHMAGE = 37868, + NPC_SUPPRESSOR = 37863, + NPC_BLASING_SKELETON = 36791, + NPC_BLISTERING_ZOMBIE = 37934, + NPC_GLUTTONOUS_ABOMINATION = 37886, + NPC_NIGHTMARE_PORTAL = 38429, // Not realized yet + // Mana void + NPC_MANA_VOID = 38068, // Bugged, need override + SPELL_VOID_BUFF = 71085, +}; + +struct MANGOS_DLL_DECL boss_valithria_dreamwalkerAI : public BSWScriptedAI +{ + boss_valithria_dreamwalkerAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (instance_icecrown_spire*)pCreature->GetInstanceData(); + Reset(); + } + + instance_icecrown_spire* pInstance; + bool battlestarted; + bool intro; + uint8 currentDoor; + uint8 currentDoor2; + int8 portalscount; + std::list mobsGUIDList; + uint32 speedK; + Creature* dummyTarget; + + void Reset() + { + if(!pInstance) return; + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetHealth(m_creature->GetMaxHealth()/2.0f); + if (pInstance->GetData(TYPE_VALITHRIA) != DONE) + pInstance->SetData(TYPE_VALITHRIA, NOT_STARTED); + else m_creature->ForcedDespawn(); + resetTimers(); + SetCombatMovement(false); + setStage(0); + speedK = 0; + portalscount = 0; + battlestarted = false; + intro = false; + currentDoor = 0; + currentDoor2 = 0; + mobsGUIDList.clear(); + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALITHRIA_QUEST))) + if (pTemp->GetVisibility() == VISIBILITY_ON) + pTemp->SetVisibility(VISIBILITY_OFF); + doCast(SPELL_CORRUPTION); + } + + uint64 GetDoor(uint8 doornum) + { + switch (doornum) { + case 1: + return pInstance->GetData64(GO_VALITHRIA_DOOR_1); + break; + case 2: + return pInstance->GetData64(GO_VALITHRIA_DOOR_2); + break; + case 3: + return pInstance->GetData64(GO_VALITHRIA_DOOR_3); + break; + case 4: + return pInstance->GetData64(GO_VALITHRIA_DOOR_4); + break; + default: + return 0; + break; + }; + } + + void CallMobs(uint8 door) + { + if(!door) return; + uint8 mobs; + uint32 randommob; + + switch (currentDifficulty) { + case RAID_DIFFICULTY_10MAN_NORMAL: + mobs = urand(1,3); + break; + case RAID_DIFFICULTY_10MAN_HEROIC: + mobs = urand(2,4); + break; + case RAID_DIFFICULTY_25MAN_NORMAL: + mobs = urand(2,5); + break; + case RAID_DIFFICULTY_25MAN_HEROIC: + mobs = urand(3,5); + break; + default: + mobs = urand(1,5); + break; + } + + for(uint8 i = 0; i <= mobs; ++i) + { + switch (urand(0,4)) { + case 0: randommob = NPC_RISEN_ARCHMAGE; break; + case 1: randommob = NPC_SUPPRESSOR; break; + case 2: randommob = NPC_BLASING_SKELETON; break; + case 3: randommob = NPC_BLISTERING_ZOMBIE; break; + case 4: randommob = NPC_GLUTTONOUS_ABOMINATION;break; + default: randommob = NPC_RISEN_ARCHMAGE; break; + } + if (Unit* pTemp = doSummon(randommob, SpawnLoc[door].x, SpawnLoc[door].y, SpawnLoc[door].z, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000)) + mobsGUIDList.push_back(pTemp->GetGUID()); + } + } + + void QueryEvadeMode() + { + + if ( m_creature->GetHealthPercent() > 1.0f ) { + Map* pMap = m_creature->GetMap(); + Map::PlayerList const &players = pMap->GetPlayers(); + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + { + if(Player* pPlayer = i->getSource()) + if(pPlayer->isAlive() && !pPlayer->isGameMaster() + && pPlayer->IsWithinDistInMap(m_creature, 90.0f)) return; + } + } + pInstance->SetData(TYPE_VALITHRIA, FAIL); + DoScriptText(-1631409,m_creature); + DespawnMobs(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->LoadCreatureAddon(); + if (m_creature->isAlive()) + m_creature->GetMotionMaster()->MoveTargetedHome(); + m_creature->SetLootRecipient(NULL); + pInstance->DoCloseDoor(GetDoor(currentDoor)); + pInstance->DoCloseDoor(GetDoor(currentDoor2)); + Reset(); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pInstance || ( intro && battlestarted)) return; + + if (pWho->GetTypeId() != TYPEID_PLAYER) return; + + if (!intro) + { + DoScriptText(-1631401,m_creature,pWho); + intro = true; + doCast(SPELL_IMMUNITY); + } + if (!battlestarted && pWho->isAlive() && pWho->IsWithinDistInMap(m_creature, 40.0f)) + { + DoScriptText(-1631401,m_creature,pWho); + battlestarted = true; + pInstance->SetData(TYPE_VALITHRIA, IN_PROGRESS); + m_creature->SetHealth(m_creature->GetMaxHealth()/2.0f); + dummyTarget = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_COMBAT_TRIGGER)); + if (!dummyTarget) + dummyTarget = m_creature->SummonCreature(NPC_COMBAT_TRIGGER, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 1000); + if (!dummyTarget->isAlive()) + dummyTarget->Respawn(); + if (dummyTarget) + { + dummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + dummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + dummyTarget->GetMotionMaster()->MoveIdle(); + dummyTarget->StopMoving(); + } + m_creature->SetInCombatWith(dummyTarget); + m_creature->SetHealth(m_creature->GetMaxHealth()/2.0f); + } + } + + void KilledUnit(Unit* pVictim) + { + if(!pInstance) return; + + switch (urand(0,1)) { + case 0: + DoScriptText(-1631403,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631404,m_creature,pVictim); + break; + }; + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned || !battlestarted) return; + + if ( summoned->GetEntry() != NPC_NIGHTMARE_PORTAL ) { + m_creature->SetInCombatWithZone(); + m_creature->SetInCombatWith(summoned); + summoned->SetInCombatWith(m_creature); + summoned->AddThreat(m_creature, 100.0f); + summoned->GetMotionMaster()->MoveChase(m_creature); + } + + } + + void DespawnMobs() + { + if (mobsGUIDList.empty()) + return; + + for(std::list::iterator itr = mobsGUIDList.begin(); itr != mobsGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + if (pTemp->isAlive()) + { + pTemp->DeleteThreatList(); + pTemp->CombatStop(true); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + mobsGUIDList.clear(); + } + + void JustDied(Unit *killer) + { + if(!pInstance) return + pInstance->SetData(TYPE_VALITHRIA, FAIL); + DoScriptText(-1631409,m_creature); + DespawnMobs(); + m_creature->Respawn(); + Reset(); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_creature || !m_creature->isAlive()) + return; + + if (uiDamage >= m_creature->GetHealth()) uiDamage = 0; + } + + void AttackStart(Unit *who) + { + } + + void UpdateAI(const uint32 diff) + { + + if (!hasAura(SPELL_CORRUPTION,m_creature) && getStage() == 0) + doCast(SPELL_CORRUPTION); + + if (!battlestarted) return; + + QueryEvadeMode(); + + switch(getStage()) + { + case 0: + if ( m_creature->GetHealthPercent() > 90.0f ) setStage(2); + if ( m_creature->GetHealthPercent() < 10.0f ) setStage(3); + break; + case 1: + if ( m_creature->GetHealthPercent() < 90.0f && m_creature->GetHealthPercent() > 10.0f ) setStage(0); + if ( m_creature->GetHealthPercent() > 99.9f ) setStage(5); + break; + case 2: + DoScriptText(-1631407,m_creature); + setStage(1); + break; + case 3: + DoScriptText(-1631406,m_creature); + setStage(1); + break; + case 4: + break; + case 5: + DoScriptText(-1631408,m_creature); + if (hasAura(SPELL_CORRUPTION,m_creature)) doRemove(SPELL_CORRUPTION); + setStage(6); + return; + break; + case 6: + if (timedQuery(SPELL_CORRUPTION, diff)) setStage(7); + return; + break; + case 7: + doCast(SPELL_DREAMWALKER_RAGE); + setStage(8); + return; + break; + case 8: + if (timedQuery(SPELL_CORRUPTION, diff)) + { + setStage(9); + DespawnMobs(); + } + return; + break; + case 9: + if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALITHRIA_QUEST))) + { + pTemp->SetPhaseMask(65535,true); + if (pTemp->HasAura(SPELL_CORRUPTION)) + pTemp->RemoveAurasDueToSpell(SPELL_CORRUPTION); + if (pTemp->GetVisibility() == VISIBILITY_OFF) + pTemp->SetVisibility(VISIBILITY_ON); + } + pInstance->SetData(TYPE_VALITHRIA, DONE); + setStage(10); + m_creature->ForcedDespawn(); + break; + default: + break; + } + + + if (timedQuery(NPC_RISEN_ARCHMAGE, (uint32)(diff + diff*(speedK/100)))) { + if (urand(0,1) == 1) DoScriptText(-1631402,m_creature); + speedK = speedK+10; + if (currentDifficulty == RAID_DIFFICULTY_25MAN_NORMAL + || currentDifficulty == RAID_DIFFICULTY_25MAN_HEROIC) { + pInstance->DoCloseDoor(GetDoor(currentDoor2)); + currentDoor2 = urand(1,2); + pInstance->DoOpenDoor(GetDoor(currentDoor2)); + CallMobs(currentDoor2); + + pInstance->DoCloseDoor(GetDoor(currentDoor)); + currentDoor = urand(3,4); + pInstance->DoOpenDoor(GetDoor(currentDoor)); + CallMobs(currentDoor); + } else { + pInstance->DoCloseDoor(GetDoor(currentDoor)); + currentDoor = urand(1,4); + pInstance->DoOpenDoor(GetDoor(currentDoor)); + CallMobs(currentDoor); + } + }; + + if (timedQuery(SPELL_NIGHTMARE_PORTAL, diff) || portalscount > 0) + { + if (!portalscount) { + portalscount = 3; + DoScriptText(-1631405,m_creature); + }; + doCast(SPELL_NIGHTMARE_PORTAL); + --portalscount; + }; + + timedCast(SPELL_ICE_SPIKE, diff); + + return; + } +}; + +CreatureAI* GetAI_boss_valithria_dreamwalker(Creature* pCreature) +{ + return new boss_valithria_dreamwalkerAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_nightmare_portalAI : public BSWScriptedAI +{ + mob_nightmare_portalAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool portalcasted; + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveRandom(); + m_creature->SetDisplayId(29352); + portalcasted = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_pInstance || portalcasted) return; + + if (pWho->isAlive() && pWho->GetTypeId() == TYPEID_PLAYER && pWho->IsWithinDistInMap(m_creature, 2.0f)) + { + doCast(SPELL_EMERALD_VIGOR); + portalcasted = true; + } + } + + void AttackStart(Unit *pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_VALITHRIA) != IN_PROGRESS || portalcasted) + if (timedQuery(SPELL_EMERALD_VIGOR, uiDiff)) + m_creature->ForcedDespawn(); + + } + +}; + +CreatureAI* GetAI_mob_nightmare_portal(Creature *pCreature) +{ + return new mob_nightmare_portalAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_mana_voidAI : public ScriptedAI +{ + mob_mana_voidAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_ui_Timer; + + void Reset() + { +// m_creature->SetDisplayId(29308); + SetCombatMovement(false); +// m_creature->GetMotionMaster()->MoveRandom(); + m_creature->CastSpell(m_creature, SPELL_VOID_BUFF, false); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_ui_Timer = 30000; + } + + void AttackStart(Unit *pWho) + { + return; + } + + void JustDied(Unit *killer) + { + m_creature->RemoveCorpse(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance || m_pInstance->GetData(TYPE_VALITHRIA) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_ui_Timer < uiDiff) + m_creature->ForcedDespawn(); + else m_ui_Timer -= uiDiff; + } + +}; + +CreatureAI* GetAI_mob_mana_void(Creature *pCreature) +{ + return new mob_mana_voidAI(pCreature); +}; + +void AddSC_boss_valithria_dreamwalker() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_valithria_dreamwalker"; + newscript->GetAI = &GetAI_boss_valithria_dreamwalker; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_nightmare_portal"; + newscript->GetAI = &GetAI_mob_nightmare_portal; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_mana_void"; + newscript->GetAI = &GetAI_mob_mana_void; + newscript->RegisterSelf(); + +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp index 669cd2198..575e43539 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,3 +22,7 @@ SDCategory: Icecrown Citadel EndScriptData */ #include "precompiled.h" + +void AddSC_gunship_battle() +{ +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h new file mode 100644 index 000000000..f2d543683 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h @@ -0,0 +1,319 @@ +/* Copyright (C) 2010 -2011 by /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_ICECROWN_SPIRE_H +#define DEF_ICECROWN_SPIRE_H +#include "BSW_instance.h" +#include "BSW_ai.h" + +enum +{ + + TYPE_TELEPORT = 0, + TYPE_MARROWGAR = 1, + TYPE_DEATHWHISPER = 2, + TYPE_FLIGHT_WAR = 3, + TYPE_SAURFANG = 4, + TYPE_FESTERGUT = 5, + TYPE_ROTFACE = 6, + TYPE_PUTRICIDE = 7, + TYPE_BLOOD_COUNCIL = 8, + TYPE_LANATHEL = 9, + TYPE_VALITHRIA = 10, + TYPE_SINDRAGOSA = 11, + TYPE_KINGS_OF_ICC = 12, + TYPE_LICH_KING = 13, + TYPE_ICECROWN_QUESTS = 14, + TYPE_COUNT = 15, + MAX_ENCOUNTERS, + + TYPE_STINKY, + TYPE_PRECIOUS, + + NPC_LORD_MARROWGAR = 36612, + NPC_LADY_DEATHWHISPER = 36855, + NPC_DEATHBRINGER_SAURFANG = 37813, + NPC_FESTERGUT = 36626, + NPC_ROTFACE = 36627, + NPC_PROFESSOR_PUTRICIDE = 36678, + NPC_TALDARAM = 37973, + NPC_VALANAR = 37970, + NPC_KELESETH = 37972, + NPC_LANATHEL = 37955, + NPC_VALITHRIA = 36789, + NPC_VALITHRIA_QUEST = 38589, + NPC_SINDRAGOSA = 36853, + NPC_LICH_KING = 36597, + + NPC_LANATHEL_INTRO = 38004, + NPC_BLOOD_ORB_CONTROL = 38008, + + NPC_MURADIN = 36948, + + NPC_TIRION = 38995, + NPC_MENETHIL = 38579, + NPC_SPIRIT_WARDEN = 38579, + + NPC_FROSTMOURNE_TRIGGER = 38584, + NPC_FROSTMOURNE_HOLDER = 27880, + + NPC_STINKY = 37025, + NPC_PRECIOUS = 37217, + + NPC_RIMEFANG = 37533, + NPC_SPINESTALKER = 37534, + + NPC_COMBAT_TRIGGER = 38752, + + GO_TELEPORT_GOSSIP_MESSAGE = 99323, + TELEPORT_GOSSIP_MESSAGE = 99322, + + GO_ICEWALL_1 = 201911, + GO_ICEWALL_2 = 201910, + + GO_MARROWGAR_DOOR = 201857, + + GO_ORATORY_DOOR = 201563, + GO_DEATHWHISPER_ELEVATOR = 202220, //5653 + + GO_SAURFANG_DOOR = 201825, + + GO_GAS_RELEASE_VALVE = 201616, //72479 + + GO_ORANGE_PLAGUE = 201371, //72536 + GO_GREEN_PLAGUE = 201370, //72537 + + GO_SCIENTIST_DOOR_GREEN = 201614, //72530 + GO_SCIENTIST_DOOR_ORANGE = 201613, //72531 + GO_SCIENTIST_DOOR_COLLISION = 201612, + GO_SCIENTIST_DOOR = 201372, //72541 + + GO_BLOODWING_DOOR = 201920, //72532 + GO_CRIMSON_HALL_DOOR = 201376, //72532 + GO_COUNCIL_DOOR_1 = 201377, //72533 + GO_COUNCIL_DOOR_2 = 201378, //72534 + + GO_BLOODPRINCE_DOOR = 201746, + GO_ICECROWN_GRATE = 201755, + + GO_FROSTWING_DOOR = 201919, + GO_GREEN_DRAGON_DOOR_1 = 201375, //1202 + GO_GREEN_DRAGON_DOOR_2 = 201374, //1200 + GO_VALITHRIA_DOOR_1 = 201380, //1618 + GO_VALITHRIA_DOOR_2 = 201382, //1482 + GO_VALITHRIA_DOOR_3 = 201383, //1335 + GO_VALITHRIA_DOOR_4 = 201381, //1558 + + GO_SINDRAGOSA_DOOR_1 = 201369, //1619 + GO_SINDRAGOSA_DOOR_2 = 201379, + + GO_SINDRAGOSA_ENTRANCE = 201373, + + GO_FROZENTRONE_TR = 202223, //72061 + + GO_SAURFANG_CACHE_10 = 202239, + GO_SAURFANG_CACHE_25 = 202240, + GO_SAURFANG_CACHE_10_H = 202238, + GO_SAURFANG_CACHE_25_H = 202241, + + GO_GUNSHIP_ARMORY_A_10 = 201872, // + GO_GUNSHIP_ARMORY_A_25 = 201873, // + GO_GUNSHIP_ARMORY_A_10H = 201874, // + GO_GUNSHIP_ARMORY_A_25H = 201875, // + + GO_GUNSHIP_ARMORY_H_10 = 202177, // + GO_GUNSHIP_ARMORY_H_25 = 202178, // + GO_GUNSHIP_ARMORY_H_10H = 202179, // + GO_GUNSHIP_ARMORY_H_25H = 202180, // + + GO_DREAMWALKER_CACHE_10 = 201959, // + GO_DREAMWALKER_CACHE_25 = 202339, // + GO_DREAMWALKER_CACHE_10_H = 202338, // + GO_DREAMWALKER_CACHE_25_H = 202340, // + + GO_PLAGUE_SIGIL = 202182, + GO_FROSTWING_SIGIL = 202181, + GO_BLOODWING_SIGIL = 202183, + + GO_ICESHARD_1 = 202142, //8304 + GO_ICESHARD_2 = 202141, //8364 + GO_ICESHARD_3 = 202143, //8310 + GO_ICESHARD_4 = 202144, //9007 + + GO_FROSTY_WIND = 202188, // + GO_FROSTY_EDGE = 202189, // + GO_SNOW_EDGE = 202190, // + GO_ARTHAS_PLATFORM = 202161, // + GO_ARTHAS_PRECIPICE = 202078, // + + TYPE_EVENT_TIMER = 99, + TYPE_EVENT = 100, + TYPE_EVENT_NPC = 101, + MAP_NUM = 631, + DATA_DIRECTION = 1001, + DATA_BLOOD_INVOCATION = 1002, + DESPAWN_TIME = 300000, + SPELL_SHADOWS_EDGE = 71168, + +}; + +class MANGOS_DLL_DECL instance_icecrown_spire : public BSWScriptedInstance +{ +public: + instance_icecrown_spire(Map* pMap); + ~instance_icecrown_spire() {} + + void Initialize(); + + void OnObjectCreate(GameObject* pGo); + void OnCreatureCreate(Creature* pCreature); + + void OpenAllDoors(); + void OnPlayerEnter(Player* pPlayer); + bool IsEncounterInProgress(); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiType); + + const char* Save() { return strSaveData.c_str(); } + void Load(const char* chrIn); + bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/); + +private: + + uint8 Difficulty; + bool needSave; + std::string strSaveData; + + //Creatures GUID + uint32 m_auiEncounter[MAX_ENCOUNTERS+1]; + uint64 m_uiMarrogwarGUID; + uint64 m_uiDeathWhisperGUID; + uint64 m_uiSaurfangGUID; + uint64 m_uiRotfaceGUID; + uint64 m_uiFestergutGUID; + uint64 m_uiPutricideGUID; + uint64 m_uiTaldaramGUID; + uint64 m_uiValanarGUID; + uint64 m_uiKelesethGUID; + uint64 m_uiLanathelGUID; + uint64 m_uiLanathelintroGUID; + uint64 m_uiValithriaGUID; + uint64 m_uiValithriaQuestGUID; + uint64 m_uiSindragosaGUID; + uint64 m_uiLichKingGUID; + uint64 m_uiGasReleaseValveGUID; + uint64 m_uiBloodOrbCtrlGUID; + + uint64 m_uiRimefangGUID; + uint64 m_uiSpinestalkerGUID; + + uint64 m_uiStinkyGUID; + uint64 m_uiPreciousGUID; + + uint64 m_uidummyTargetGUID; + + uint64 m_uiIcewall1GUID; + uint64 m_uiIcewall2GUID; + uint64 m_uiSaurfangDoorGUID; + uint64 m_uiOratoryDoorGUID; + uint64 m_uiDeathWhisperElevatorGUID; + uint64 m_uiOrangePlagueGUID; + uint64 m_uiGreenPlagueGUID; + uint64 m_uiSDoorGreenGUID; + uint64 m_uiSDoorOrangeGUID; + uint64 m_uiSDoorCollisionGUID; + uint64 m_uiScientistDoorGUID; + uint64 m_uiCrimsonDoorGUID; + uint64 m_uiBloodwingDoorGUID; + uint64 m_uiCounsilDoor1GUID; + uint64 m_uiCounsilDoor2GUID; + uint64 m_uiGreenDragonDoor1GUID; + uint64 m_uiGreenDragonDoor2GUID; + uint64 m_uiFrostwingDoorGUID; + + uint64 m_uiValithriaDoor1GUID; + uint64 m_uiValithriaDoor2GUID; + uint64 m_uiValithriaDoor3GUID; + uint64 m_uiValithriaDoor4GUID; + + uint64 m_uiSindragosaDoor1GUID; + uint64 m_uiSindragosaDoor2GUID; + + uint64 m_uiIceShard1GUID; + uint64 m_uiIceShard2GUID; + uint64 m_uiIceShard3GUID; + uint64 m_uiIceShard4GUID; + + uint64 m_uiFrostyWindGUID; + uint64 m_uiFrostyEdgeGUID; + uint64 m_uiSnowEdgeGUID; + uint64 m_uiArthasPlatformGUID; + uint64 m_uiArthasPrecipiceGUID; + + uint64 m_uiFrostmourneGUID; + uint64 m_uiFrostmourneTriggerGUID; + uint64 m_uiFrostmourneHolderGUID; + + uint64 m_uiSaurfangCacheGUID; + uint64 m_uiGunshipArmoryAGUID; + uint64 m_uiGunshipArmoryHGUID; + uint64 m_uiValitriaCacheGUID; + + uint64 m_uiGunshipArmoryH_ID; + uint64 m_uiGunshipArmoryA_ID; + + uint64 m_uiMarrogarDoor; + uint64 m_uiBloodPrinceDoor; + uint64 m_uiIceCrownGrate; + uint64 m_uiSindragosaEntrance; + + uint32 m_uiCouncilInvocation; + + uint32 m_auiEvent; + uint32 m_auiEventTimer; + uint32 m_uiDirection; + + uint32 m_uiStinkystate; + uint32 m_uiPreciousstate; + +}; + +enum AchievementCriteriaIds +{ + // Lord Marrowgar + CRITERIA_BONED_10N = 12775, + CRITERIA_BONED_25N = 12962, + CRITERIA_BONED_10H = 13393, + CRITERIA_BONED_25H = 13394, + + // Rotface + CRITERIA_DANCES_WITH_OOZES_10N = 12984, + CRITERIA_DANCES_WITH_OOZES_25N = 12966, + CRITERIA_DANCES_WITH_OOZES_10H = 12985, + CRITERIA_DANCES_WITH_OOZES_25H = 12983, + + // Professor Putricide + CRITERIA_NAUSEA_10N = 12987, + CRITERIA_NAUSEA_25N = 12968, + CRITERIA_NAUSEA_10H = 12988, + CRITERIA_NAUSEA_25H = 12981, + + // Blood Prince Council + CRITERIA_ORB_WHISPERER_10N = 13033, + CRITERIA_ORB_WHISPERER_25N = 12969, + CRITERIA_ORB_WHISPERER_10H = 13034, + CRITERIA_ORB_WHISPERER_25H = 13032, + + // Blood-Queen Lana'thel + CRITERIA_KILL_LANA_THEL_10M = 13340, + CRITERIA_KILL_LANA_THEL_25M = 13360, + CRITERIA_ONCE_BITTEN_TWICE_SHY_10N = 12780, + CRITERIA_ONCE_BITTEN_TWICE_SHY_25N = 13012, + CRITERIA_ONCE_BITTEN_TWICE_SHY_10V = 13011, + CRITERIA_ONCE_BITTEN_TWICE_SHY_25V = 13013, +}; + +#endif diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp new file mode 100644 index 000000000..165f4ef03 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp @@ -0,0 +1,175 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: icecrown_spire +SD%Complete: 100% +SDComment: by /dev/rsa +SDCategory: Icecrown Citadel - mobs +EndScriptData */ + +#include "precompiled.h" +#include "icecrown_citadel.h" +enum +{ + SPELL_BERSERK = 47008, + SPELL_FROST_BREATH = 70116, + SPELL_BLIZZARD = 70362, + SPELL_CLEAVE = 70361, + + SPELL_STOMP = 64652, + SPELL_DEATH_PLAGUE = 72865, +// SPELL_DEATH_PLAGUE = 72879, + +}; + +struct MANGOS_DLL_DECL mob_spire_frostwyrmAI : public BSWScriptedAI +{ + mob_spire_frostwyrmAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 stage; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + stage = 0; + resetTimers(); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(stage) + { + case 0: + break; + case 1: + doCast(SPELL_BERSERK); + stage = 2; + break; + case 2: + default: + break; + } + + timedCast(SPELL_CLEAVE, diff); + timedCast(SPELL_BLIZZARD, diff); + timedCast(SPELL_FROST_BREATH, diff); + + if (m_creature->GetHealthPercent() < 10.0f && stage == 0) stage = 1; + + timedCast(SPELL_BERSERK, diff); + + DoMeleeAttackIfReady(); + + } +}; + +CreatureAI* GetAI_mob_spire_frostwyrm(Creature* pCreature) +{ + return new mob_spire_frostwyrmAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_frost_giantAI : public BSWScriptedAI +{ + mob_frost_giantAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 stage; + + void Aggro(Unit *who) + { + if(pInstance) pInstance->SetData(TYPE_FLIGHT_WAR, IN_PROGRESS); + } + + void JustDied(Unit *killer) + { + if(!pInstance) return; + if (killer->GetTypeId() == TYPEID_PLAYER || killer->GetCharmerOrOwner()->GetTypeId() == TYPEID_PLAYER ) + pInstance->SetData(TYPE_FLIGHT_WAR, DONE); + } + + void JustReachedHome() + { + if (pInstance) pInstance->SetData(TYPE_FLIGHT_WAR, FAIL); + } + + void Reset() + { + m_creature->SetRespawnDelay(7*DAY); + stage = 0; + resetTimers(); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(stage) + { + case 0: + break; + case 1: + doCast(SPELL_BERSERK); + stage = 2; + break; + case 2: + default: + break; + } + timedCast(SPELL_STOMP, diff); + timedCast(SPELL_DEATH_PLAGUE, diff); + + if (m_creature->GetHealthPercent() < 2.0f && stage == 0) stage = 1; + + timedCast(SPELL_BERSERK, diff); + + DoMeleeAttackIfReady(); + + } +}; + +CreatureAI* GetAI_mob_frost_giant(Creature* pCreature) +{ + return new mob_frost_giantAI(pCreature); +} + +void AddSC_icecrown_spire() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "mob_spire_frostwyrm"; + newscript->GetAI = &GetAI_mob_spire_frostwyrm; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_frost_giant"; + newscript->GetAI = &GetAI_mob_frost_giant; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp new file mode 100644 index 000000000..2502ff827 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp @@ -0,0 +1,146 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: icecrown_teleport +SD%Complete: 100% +SDComment: by /dev/rsa +SDCategory: Icecrown Citadel +EndScriptData */ +#include "precompiled.h" +#include "icecrown_citadel.h" + +enum +{ +PORTALS_COUNT = 7 +}; + +struct t_Locations +{ + int textNum; + uint32 map_num; + float x, y, z, o; + uint32 spellID; + bool state; + bool active; + uint32 encounter; +}; + +static t_Locations PortalLoc[]= +{ +{-3631600,MAP_NUM,-17.1928f, 2211.44f, 30.1158f,3.14f,70856,true,true,TYPE_TELEPORT}, // +{-3631601,MAP_NUM,-503.62f, 2211.47f, 62.8235f,3.14f,70856,false,true,TYPE_MARROWGAR}, // +{-3631602,MAP_NUM,-615.145f, 2211.47f, 199.972f,0,70857,false,true,TYPE_DEATHWHISPER}, // +{-3631603,MAP_NUM,-549.131f, 2211.29f, 539.291f,0,70858,false,true,TYPE_FLIGHT_WAR}, // +{-3631604,MAP_NUM,4198.42f, 2769.22f, 351.065f,0,70859,false,true,TYPE_SAURFANG}, // +{-3631606,MAP_NUM,4356.580078f, 2565.75f, 220.401993f,4.90f,70861,false,true,TYPE_VALITHRIA}, // +{-3631607,MAP_NUM,528.767273f, -2124.845947f, 1043.1f,3.14f, 70860,false,true,TYPE_KINGS_OF_ICC}, // +}; + + +bool GOGossipSelect_go_icecrown_teleporter(Player *pPlayer, GameObject* pGo, uint32 sender, uint32 action) +{ + if(sender != GOSSIP_SENDER_MAIN) return false; + + if(!pPlayer->getAttackers().empty()) return false; + + if(action >= 0 && action < PORTALS_COUNT) + pPlayer->TeleportTo(PortalLoc[action].map_num, PortalLoc[action].x, PortalLoc[action].y, PortalLoc[action].z, PortalLoc[action].o); + if (PortalLoc[action].spellID != 0 ) + pPlayer->_AddAura(PortalLoc[action].spellID, 2000); + + pPlayer->CLOSE_GOSSIP_MENU(); + return true; +} + +bool GOGossipHello_go_icecrown_teleporter(Player *pPlayer, GameObject* pGo) +{ + ScriptedInstance *pInstance = (ScriptedInstance *) pGo->GetInstanceData(); + + if (!pInstance || !pPlayer) return false; + if (pPlayer->isInCombat()) return true; + + for(uint8 i = 0; i < PORTALS_COUNT; i++) { + if (PortalLoc[i].active == true && (PortalLoc[i].state == true || pInstance->GetData(PortalLoc[i].encounter) == DONE || pPlayer->isGameMaster())) + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_TAXI, PortalLoc[i].textNum, GOSSIP_SENDER_MAIN, i); + }; + pPlayer->SEND_GOSSIP_MENU(TELEPORT_GOSSIP_MESSAGE, pGo->GetGUID()); + return true; +} + +bool GOHello_go_plague_sigil(Player *player, GameObject* pGo) +{ + instance_icecrown_spire* pInstance = (instance_icecrown_spire*)pGo->GetInstanceData(); + if(!pInstance) return false; + + if (pInstance->GetData(TYPE_FESTERGUT) == DONE + && pInstance->GetData(TYPE_ROTFACE) == DONE) + { + pInstance->DoOpenDoor(pInstance->GetData64(GO_SCIENTIST_DOOR_ORANGE)); + pInstance->DoOpenDoor(pInstance->GetData64(GO_SCIENTIST_DOOR_GREEN)); + pInstance->DoOpenDoor(pInstance->GetData64(GO_SCIENTIST_DOOR_COLLISION)); + }; + return true; +} + +bool GOHello_go_bloodwing_sigil(Player *player, GameObject* pGo) +{ + instance_icecrown_spire* pInstance = (instance_icecrown_spire*)pGo->GetInstanceData(); + if(!pInstance) return false; + + if (pInstance->GetData(TYPE_SAURFANG) == DONE) + pInstance->DoOpenDoor(pInstance->GetData64(GO_BLOODWING_DOOR)); + + return true; +} + +bool GOHello_go_frostwing_sigil(Player *player, GameObject* pGo) +{ + instance_icecrown_spire* pInstance = (instance_icecrown_spire*)pGo->GetInstanceData(); + if(!pInstance) return false; + + if (pInstance->GetData(TYPE_SAURFANG) == DONE) + pInstance->DoOpenDoor(pInstance->GetData64(GO_FROSTWING_DOOR)); + + return true; +} + + +void AddSC_icecrown_teleporter() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "go_icecrown_teleporter"; + newscript->pGossipHelloGO = &GOGossipHello_go_icecrown_teleporter; + newscript->pGossipSelectGO = &GOGossipSelect_go_icecrown_teleporter; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "go_plague_sigil"; + newscript->pGOUse = &GOHello_go_plague_sigil; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "go_bloodwing_sigil"; + newscript->pGOUse = &GOHello_go_bloodwing_sigil; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "go_frostwing_sigil"; + newscript->pGOUse = &GOHello_go_frostwing_sigil; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp new file mode 100644 index 000000000..225939a60 --- /dev/null +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp @@ -0,0 +1,851 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: instance_icecrown_spire +SD%Complete: 90% +SDComment: by /dev/rsa +SDCategory: Icecrown Citadel +EndScriptData */ + +#include "precompiled.h" +#include "icecrown_citadel.h" +#include "World.h" + +static Locations SpawnLoc[]= +{ + {-446.788971f, 2003.362915f, 191.233948f}, // 0 Horde ship enter + {-428.140503f, 2421.336914f, 191.233078f}, // 1 Alliance ship enter +}; + + instance_icecrown_spire::instance_icecrown_spire(Map* pMap) : BSWScriptedInstance(pMap) + { + Difficulty = pMap->GetDifficulty(); + Initialize(); + } + + void instance_icecrown_spire::OpenAllDoors() + { + if (m_auiEncounter[1] == DONE) { + DoOpenDoor(m_uiIcewall1GUID); + DoOpenDoor(m_uiIcewall2GUID); + DoOpenDoor( m_uiOratoryDoorGUID); + }; + if (m_auiEncounter[2] == DONE) { + if (GameObject* pGO = instance->GetGameObject(m_uiDeathWhisperElevatorGUID)) + { + pGO->SetUInt32Value(GAMEOBJECT_LEVEL, 0); + pGO->SetGoState(GO_STATE_READY); + } + }; + if (m_auiEncounter[4] == DONE) { + DoOpenDoor(m_uiSaurfangDoorGUID); + DoOpenDoor(m_uiBloodwingDoorGUID); + DoOpenDoor(m_uiFrostwingDoorGUID); + }; + if (m_auiEncounter[5] == DONE) DoOpenDoor(m_uiSDoorOrangeGUID); + if (m_auiEncounter[6] == DONE) DoOpenDoor(m_uiSDoorGreenGUID); + if (m_auiEncounter[6] == DONE && m_auiEncounter[5] == DONE) DoOpenDoor(m_uiSDoorCollisionGUID); + if (m_auiEncounter[8] == DONE) { + DoOpenDoor(m_uiCounsilDoor1GUID); + DoOpenDoor(m_uiCounsilDoor2GUID); + }; + if (m_auiEncounter[10] == DONE) + { + DoOpenDoor(m_uiValithriaDoor2GUID); + DoOpenDoor(m_uiSindragosaDoor2GUID); + DoOpenDoor(m_uiSindragosaDoor1GUID); + }; + + } + + void instance_icecrown_spire::Initialize() + { + for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + m_auiEncounter[i] = NOT_STARTED; + + m_auiEncounter[0] = 0; + + m_uiMarrogwarGUID = 0; + m_uiDeathWhisperGUID = 0; + m_uiSaurfangGUID = 0; + m_uiSaurfangCacheGUID = 0; + m_uiGunshipArmoryAGUID = 0; + m_uiGunshipArmoryHGUID = 0; + m_uiIcewall1GUID = 0; + m_uiIcewall2GUID = 0; + m_uiSDoorOrangeGUID = 0; + m_uiSDoorGreenGUID = 0; + m_uiBloodwingDoorGUID = 0; + m_uiSDoorCollisionGUID = 0; + m_auiEvent = 0; + m_auiEventTimer = 1000; + m_uiCouncilInvocation = 0; + m_uiDirection = 0; + m_uiStinkystate = NOT_STARTED; + m_uiPreciousstate = NOT_STARTED; + + switch (Difficulty) { + case RAID_DIFFICULTY_10MAN_NORMAL: + m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_10; + m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_10; + break; + case RAID_DIFFICULTY_10MAN_HEROIC: + m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_10H; + m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_10H; + break; + case RAID_DIFFICULTY_25MAN_NORMAL: + m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_25; + m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_25; + break; + case RAID_DIFFICULTY_25MAN_HEROIC: + m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_25H; + m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_25H; + break; + default: + m_uiGunshipArmoryH_ID = 0; + m_uiGunshipArmoryA_ID = 0; + break; + }; + } + + bool instance_icecrown_spire::IsEncounterInProgress() + { + for(uint8 i = 1; i < MAX_ENCOUNTERS-2 ; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) return true; + + return false; + } + + void instance_icecrown_spire::OnPlayerEnter(Player *pPlayer) + { + OpenAllDoors(); + + enum PhaseControl + { + HORDE_CONTROL_PHASE_SHIFT_1 = 55773, + HORDE_CONTROL_PHASE_SHIFT_2 = 60028, + ALLIANCE_CONTROL_PHASE_SHIFT_1 = 55774, + ALLIANCE_CONTROL_PHASE_SHIFT_2 = 60027, + }; +/* + + if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP)) return; + + switch (pPlayer->GetTeam()) + { + case ALLIANCE: + if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(HORDE_CONTROL_PHASE_SHIFT_1)) + pPlayer->RemoveAurasDueToSpell(HORDE_CONTROL_PHASE_SHIFT_1); + pPlayer->CastSpell(pPlayer, HORDE_CONTROL_PHASE_SHIFT_2, false); + break; + case HORDE: + if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(ALLIANCE_CONTROL_PHASE_SHIFT_1)) + pPlayer->RemoveAurasDueToSpell(ALLIANCE_CONTROL_PHASE_SHIFT_1); + pPlayer->CastSpell(pPlayer, ALLIANCE_CONTROL_PHASE_SHIFT_2, false); + break; + }; +*/ + }; + + void instance_icecrown_spire::OnCreatureCreate(Creature* pCreature) + { + switch(pCreature->GetEntry()) + { + case NPC_LORD_MARROWGAR: + m_uiMarrogwarGUID = pCreature->GetGUID(); + break; + case NPC_LADY_DEATHWHISPER: + m_uiDeathWhisperGUID = pCreature->GetGUID(); + break; + case NPC_DEATHBRINGER_SAURFANG: + m_uiSaurfangGUID = pCreature->GetGUID(); + break; + case NPC_FESTERGUT: + m_uiFestergutGUID = pCreature->GetGUID(); + break; + case NPC_ROTFACE: + m_uiRotfaceGUID = pCreature->GetGUID(); + break; + case NPC_PROFESSOR_PUTRICIDE: + m_uiPutricideGUID = pCreature->GetGUID(); + break; + case NPC_TALDARAM: + m_uiTaldaramGUID = pCreature->GetGUID(); + break; + case NPC_VALANAR: + m_uiValanarGUID = pCreature->GetGUID(); + break; + case NPC_KELESETH: + m_uiKelesethGUID = pCreature->GetGUID(); + break; + case NPC_LANATHEL: + m_uiLanathelGUID = pCreature->GetGUID(); + break; + case NPC_LANATHEL_INTRO: + m_uiLanathelintroGUID = pCreature->GetGUID(); + break; + case NPC_VALITHRIA: + m_uiValithriaGUID = pCreature->GetGUID(); + break; + case NPC_VALITHRIA_QUEST: + m_uiValithriaQuestGUID = pCreature->GetGUID(); + break; + case NPC_SINDRAGOSA: + m_uiSindragosaGUID = pCreature->GetGUID(); + break; + case NPC_LICH_KING: + m_uiLichKingGUID = pCreature->GetGUID(); + break; + case NPC_RIMEFANG: + m_uiRimefangGUID = pCreature->GetGUID(); + break; + case NPC_SPINESTALKER: + m_uiSpinestalkerGUID = pCreature->GetGUID(); + break; + case NPC_STINKY: + m_uiStinkyGUID = pCreature->GetGUID(); + break; + case NPC_PRECIOUS: + m_uiPreciousGUID = pCreature->GetGUID(); + break; + case NPC_COMBAT_TRIGGER: + m_uidummyTargetGUID = pCreature->GetGUID(); + break; + case NPC_FROSTMOURNE_TRIGGER: + m_uiFrostmourneTriggerGUID = pCreature->GetGUID(); + break; + case NPC_FROSTMOURNE_HOLDER: + m_uiFrostmourneHolderGUID = pCreature->GetGUID(); + break; + case NPC_BLOOD_ORB_CONTROL: + m_uiBloodOrbCtrlGUID = pCreature->GetGUID(); + break; + } + } + + void instance_icecrown_spire::OnObjectCreate(GameObject* pGo) + { + switch(pGo->GetEntry()) + { + case GO_ICEWALL_1: + m_uiIcewall1GUID = pGo->GetGUID(); + break; + case GO_ICEWALL_2: + m_uiIcewall2GUID = pGo->GetGUID(); + break; + case GO_ORATORY_DOOR: + m_uiOratoryDoorGUID = pGo->GetGUID(); + break; + case GO_DEATHWHISPER_ELEVATOR: + m_uiDeathWhisperElevatorGUID = pGo->GetGUID(); + break; + case GO_SAURFANG_DOOR: + m_uiSaurfangDoorGUID = pGo->GetGUID(); + break; + case GO_ORANGE_PLAGUE: + m_uiOrangePlagueGUID = pGo->GetGUID(); + break; + case GO_GREEN_PLAGUE: + m_uiGreenPlagueGUID = pGo->GetGUID(); + break; + case GO_SCIENTIST_DOOR_GREEN: + m_uiSDoorGreenGUID = pGo->GetGUID(); + break; + case GO_SCIENTIST_DOOR_ORANGE: + m_uiSDoorOrangeGUID = pGo->GetGUID(); + break; + case GO_SCIENTIST_DOOR_COLLISION: + m_uiSDoorCollisionGUID = pGo->GetGUID(); + break; + case GO_SCIENTIST_DOOR: + m_uiScientistDoorGUID = pGo->GetGUID(); + break; + case GO_CRIMSON_HALL_DOOR: + m_uiCrimsonDoorGUID = pGo->GetGUID(); + break; + case GO_BLOODWING_DOOR: + m_uiBloodwingDoorGUID = pGo->GetGUID(); + break; + case GO_COUNCIL_DOOR_1: + m_uiCounsilDoor1GUID = pGo->GetGUID(); + break; + case GO_COUNCIL_DOOR_2: + m_uiCounsilDoor2GUID = pGo->GetGUID(); + break; + case GO_FROSTWING_DOOR: + m_uiFrostwingDoorGUID = pGo->GetGUID(); + break; + case GO_GREEN_DRAGON_DOOR_1: + m_uiGreenDragonDoor1GUID = pGo->GetGUID(); + break; + case GO_GREEN_DRAGON_DOOR_2: + m_uiGreenDragonDoor2GUID = pGo->GetGUID(); + break; + case GO_VALITHRIA_DOOR_1: + m_uiValithriaDoor1GUID = pGo->GetGUID(); + break; + case GO_VALITHRIA_DOOR_2: + m_uiValithriaDoor2GUID = pGo->GetGUID(); + break; + case GO_VALITHRIA_DOOR_3: + m_uiValithriaDoor3GUID = pGo->GetGUID(); + break; + case GO_VALITHRIA_DOOR_4: + m_uiValithriaDoor4GUID = pGo->GetGUID(); + break; + case GO_SINDRAGOSA_DOOR_1: + m_uiSindragosaDoor1GUID = pGo->GetGUID(); + break; + case GO_SINDRAGOSA_DOOR_2: + m_uiSindragosaDoor2GUID = pGo->GetGUID(); + break; + case GO_SAURFANG_CACHE_10: + if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL) + m_uiSaurfangCacheGUID = pGo->GetGUID(); + break; + case GO_SAURFANG_CACHE_25: + if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) + m_uiSaurfangCacheGUID = pGo->GetGUID(); + break; + case GO_SAURFANG_CACHE_10_H: + if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC) + m_uiSaurfangCacheGUID = pGo->GetGUID(); + break; + case GO_SAURFANG_CACHE_25_H: + if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC) + m_uiSaurfangCacheGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_A_10: + if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL) + m_uiGunshipArmoryAGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_A_25: + if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) + m_uiGunshipArmoryAGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_A_10H: + if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC) + m_uiGunshipArmoryAGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_A_25H: + if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC) + m_uiGunshipArmoryAGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_H_10: + if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL) + m_uiGunshipArmoryHGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_H_25: + if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) + m_uiGunshipArmoryHGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_H_10H: + if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC) + m_uiGunshipArmoryHGUID = pGo->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_H_25H: + if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC) + m_uiGunshipArmoryHGUID = pGo->GetGUID(); + break; + case GO_DREAMWALKER_CACHE_10: + if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL) + m_uiValitriaCacheGUID = pGo->GetGUID(); + break; + case GO_DREAMWALKER_CACHE_25: + if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) + m_uiValitriaCacheGUID = pGo->GetGUID(); + break; + case GO_DREAMWALKER_CACHE_10_H: + if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC) + m_uiValitriaCacheGUID = pGo->GetGUID(); + break; + case GO_DREAMWALKER_CACHE_25_H: + if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC) + m_uiValitriaCacheGUID = pGo->GetGUID(); + break; + case GO_ICESHARD_1: + m_uiIceShard1GUID = pGo->GetGUID(); + break; + case GO_ICESHARD_2: + m_uiIceShard2GUID = pGo->GetGUID(); + break; + case GO_ICESHARD_3: + m_uiIceShard3GUID = pGo->GetGUID(); + break; + case GO_ICESHARD_4: + m_uiIceShard4GUID = pGo->GetGUID(); + break; + case GO_FROSTY_WIND: + m_uiFrostyWindGUID = pGo->GetGUID(); + break; + case GO_FROSTY_EDGE: + m_uiFrostyEdgeGUID = pGo->GetGUID(); + break; + case GO_SNOW_EDGE: + m_uiSnowEdgeGUID = pGo->GetGUID(); + break; + case GO_ARTHAS_PLATFORM: + m_uiArthasPlatformGUID = pGo->GetGUID(); + break; + case GO_ARTHAS_PRECIPICE: + m_uiArthasPrecipiceGUID = pGo->GetGUID(); + break; + case GO_GAS_RELEASE_VALVE: + m_uiGasReleaseValveGUID = pGo->GetGUID(); + break; + case GO_MARROWGAR_DOOR: m_uiMarrogarDoor = pGo->GetGUID(); break; + case GO_BLOODPRINCE_DOOR: m_uiBloodPrinceDoor = pGo->GetGUID(); break; + case GO_ICECROWN_GRATE: m_uiIceCrownGrate = pGo->GetGUID(); break; + case GO_SINDRAGOSA_ENTRANCE: m_uiSindragosaEntrance = pGo->GetGUID(); break; + } + OpenAllDoors(); + } + + void instance_icecrown_spire::SetData(uint32 uiType, uint32 uiData) + { + switch(uiType) + { + case TYPE_TELEPORT: + break; + case TYPE_MARROWGAR: + m_auiEncounter[TYPE_MARROWGAR] = uiData; + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiMarrogarDoor); + else DoOpenDoor(m_uiMarrogarDoor); + + if (uiData == DONE) + { + DoOpenDoor(m_uiIcewall1GUID); + DoOpenDoor(m_uiIcewall2GUID); + DoOpenDoor(m_uiOratoryDoorGUID); + } + break; + case TYPE_DEATHWHISPER: + m_auiEncounter[TYPE_DEATHWHISPER] = uiData; + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiOratoryDoorGUID); + else DoOpenDoor(m_uiOratoryDoorGUID); + + if (uiData == DONE) + { + if (GameObject* pGO = instance->GetGameObject(m_uiDeathWhisperElevatorGUID)) + { + pGO->SetUInt32Value(GAMEOBJECT_LEVEL, 0); + pGO->SetGoState(GO_STATE_READY); + } + } + break; + case TYPE_FLIGHT_WAR: + if (uiData == DONE && m_auiEncounter[TYPE_FLIGHT_WAR] != DONE ) { + if (GameObject* pChest = instance->GetGameObject(m_uiGunshipArmoryAGUID)) + if (pChest && !pChest->isSpawned()) { + pChest->SetRespawnTime(7*DAY); + }; + + if (GameObject* pChest = instance->GetGameObject(m_uiGunshipArmoryHGUID)) + if (pChest && !pChest->isSpawned()) { + pChest->SetRespawnTime(7*DAY); + }; + }; + m_auiEncounter[3] = uiData; + break; + case TYPE_SAURFANG: + m_auiEncounter[TYPE_SAURFANG] = uiData; + if (uiData == DONE) + { + DoOpenDoor(m_uiSaurfangDoorGUID); + DoOpenDoor(m_uiBloodwingDoorGUID); + DoOpenDoor(m_uiFrostwingDoorGUID); + + if (GameObject* pChest = instance->GetGameObject(m_uiSaurfangCacheGUID)) + if (pChest && !pChest->isSpawned()) + { + pChest->SetRespawnTime(7*DAY); + }; + }; + break; + case TYPE_FESTERGUT: + m_auiEncounter[TYPE_FESTERGUT] = uiData; + + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiOrangePlagueGUID); + else DoOpenDoor(m_uiOrangePlagueGUID); + + if (uiData == DONE) + { + DoOpenDoor(m_uiSDoorOrangeGUID); + if (m_auiEncounter[TYPE_ROTFACE] == DONE) + { + DoOpenDoor(m_uiSDoorCollisionGUID); + DoOpenDoor(m_uiGreenPlagueGUID); + } + } + break; + case TYPE_ROTFACE: + m_auiEncounter[TYPE_ROTFACE] = uiData; + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiGreenPlagueGUID); + else + DoOpenDoor(m_uiGreenPlagueGUID); + if (uiData == DONE) + { + DoOpenDoor(m_uiSDoorGreenGUID); + if (m_auiEncounter[TYPE_FESTERGUT] == DONE) + { + DoOpenDoor(m_uiSDoorOrangeGUID); + DoOpenDoor(m_uiSDoorCollisionGUID); + } + } + break; + case TYPE_PUTRICIDE: + m_auiEncounter[TYPE_PUTRICIDE] = uiData; + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiScientistDoorGUID); + else + DoOpenDoor(m_uiScientistDoorGUID); + if (uiData == DONE) + { + if (m_auiEncounter[TYPE_SINDRAGOSA] == DONE + && m_auiEncounter[TYPE_LANATHEL] == DONE) + m_auiEncounter[TYPE_KINGS_OF_ICC] = DONE; + } + break; + case TYPE_BLOOD_COUNCIL: + m_auiEncounter[TYPE_BLOOD_COUNCIL] = uiData; + + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiCrimsonDoorGUID); + else + DoOpenDoor(m_uiCrimsonDoorGUID); + + if (uiData == DONE) + { + DoOpenDoor(m_uiCounsilDoor1GUID); + DoOpenDoor(m_uiCounsilDoor2GUID); + } + break; + case TYPE_LANATHEL: + m_auiEncounter[TYPE_LANATHEL] = uiData; + + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiBloodPrinceDoor); + else DoOpenDoor(m_uiBloodPrinceDoor); + + if (uiData == DONE) + { + DoOpenDoor(m_uiIceCrownGrate); + + if (m_auiEncounter[TYPE_PUTRICIDE] == DONE + && m_auiEncounter[TYPE_SINDRAGOSA] == DONE) + m_auiEncounter[TYPE_KINGS_OF_ICC] = DONE; + } + break; + case TYPE_VALITHRIA: + m_auiEncounter[TYPE_VALITHRIA] = uiData; + + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiGreenDragonDoor1GUID); + else + DoOpenDoor(m_uiGreenDragonDoor1GUID); + + if (uiData == DONE) + { + DoOpenDoor(m_uiGreenDragonDoor2GUID); + DoOpenDoor(m_uiSindragosaDoor1GUID); + DoOpenDoor(m_uiSindragosaDoor2GUID); + if (GameObject* pChest = instance->GetGameObject(m_uiValitriaCacheGUID)) + if (pChest && !pChest->isSpawned()) + { + pChest->SetRespawnTime(7*DAY); + }; + }; + break; + case TYPE_SINDRAGOSA: + m_auiEncounter[TYPE_SINDRAGOSA] = uiData; + + if (uiData == IN_PROGRESS) + DoCloseDoor(m_uiSindragosaEntrance); + else + DoOpenDoor(m_uiSindragosaEntrance); + + if (uiData == DONE) + { + if (m_auiEncounter[TYPE_PUTRICIDE] == DONE + && m_auiEncounter[TYPE_LANATHEL] == DONE) + m_auiEncounter[TYPE_KINGS_OF_ICC] = DONE; + } + break; + case TYPE_LICH_KING: + m_auiEncounter[TYPE_LICH_KING] = uiData; + break; + case TYPE_ICECROWN_QUESTS: + m_auiEncounter[TYPE_ICECROWN_QUESTS] = uiData; + break; + case TYPE_COUNT: + m_auiEncounter[TYPE_COUNT] = uiData; + uiData = NOT_STARTED; + break; + case DATA_BLOOD_INVOCATION: m_uiCouncilInvocation = uiData; + uiData = NOT_STARTED; + break; + case DATA_DIRECTION: m_uiDirection = uiData; + uiData = NOT_STARTED; + break; + case TYPE_EVENT: m_auiEvent = uiData; uiData = NOT_STARTED; break; + case TYPE_EVENT_TIMER: m_auiEventTimer = uiData; uiData = NOT_STARTED; break; + case TYPE_STINKY: m_uiStinkystate = uiData; uiData = NOT_STARTED; break; + case TYPE_PRECIOUS: m_uiPreciousstate = uiData; uiData = NOT_STARTED; break; + } + + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + saveStream << m_auiEncounter[i] << " "; + + strSaveData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + uint32 instance_icecrown_spire::GetData(uint32 uiType) + { + switch(uiType) + { + case TYPE_TELEPORT: + case TYPE_MARROWGAR: + case TYPE_DEATHWHISPER: + case TYPE_FLIGHT_WAR: + case TYPE_SAURFANG: + case TYPE_FESTERGUT: + case TYPE_ROTFACE: + case TYPE_PUTRICIDE: + case TYPE_BLOOD_COUNCIL: + case TYPE_LANATHEL: + case TYPE_VALITHRIA: + case TYPE_SINDRAGOSA: + case TYPE_KINGS_OF_ICC: + case TYPE_LICH_KING: + case TYPE_ICECROWN_QUESTS: + case TYPE_COUNT: + return m_auiEncounter[uiType]; + + case DATA_DIRECTION: return m_uiDirection; + case DATA_BLOOD_INVOCATION: return m_uiCouncilInvocation; + case TYPE_STINKY: return m_uiStinkystate; + case TYPE_PRECIOUS: return m_uiPreciousstate; + case TYPE_EVENT: return m_auiEvent; + case TYPE_EVENT_TIMER: return m_auiEventTimer; + case TYPE_EVENT_NPC: switch (m_auiEvent) + { + case 12030: + case 12050: + case 12051: + case 12052: + case 12053: + case 12070: + case 12090: + case 12110: + case 12130: + case 12150: + case 12170: + case 13110: + case 13130: + case 13131: + case 13132: + case 13150: + case 13170: + case 13190: + case 13210: + case 13230: + case 13250: + case 13270: + case 13290: + case 13310: + case 13330: + case 13350: + case 13370: + case 14010: + case 14030: + case 14050: + case 14070: + return NPC_TIRION; + break; + + case 12000: + case 12020: + case 12040: + case 12041: + case 12042: + case 12043: + case 12060: + case 12080: + case 12100: + case 12120: + case 12200: + case 13000: + case 13020: + case 13040: + case 13060: + case 13080: + case 13100: + case 13120: + case 13140: + case 13160: + case 13180: + case 13200: + case 13220: + case 13240: + case 13260: + case 13280: + case 13300: + case 14000: + return NPC_LICH_KING; + break; + case 500: + case 510: + case 550: + case 560: + case 570: + case 580: + case 590: + case 600: + case 610: + case 620: + case 630: + case 640: + case 650: + case 660: + return NPC_PROFESSOR_PUTRICIDE; + break; + + case 800: + case 810: + case 820: + return NPC_LANATHEL_INTRO; + break; + + default: + break; + }; + + } + return 0; + } + + uint64 instance_icecrown_spire::GetData64(uint32 uiData) + { + switch(uiData) + { + case NPC_LORD_MARROWGAR: return m_uiMarrogwarGUID; + case NPC_LADY_DEATHWHISPER: return m_uiDeathWhisperGUID; + case NPC_DEATHBRINGER_SAURFANG: return m_uiSaurfangGUID; + case NPC_FESTERGUT: return m_uiFestergutGUID; + case NPC_ROTFACE: return m_uiRotfaceGUID; + case NPC_PROFESSOR_PUTRICIDE: return m_uiPutricideGUID; + case NPC_TALDARAM: return m_uiTaldaramGUID; + case NPC_VALANAR: return m_uiValanarGUID; + case NPC_KELESETH: return m_uiKelesethGUID; + case NPC_LANATHEL: return m_uiLanathelGUID; + case NPC_LANATHEL_INTRO: return m_uiLanathelintroGUID; + case NPC_VALITHRIA: return m_uiValithriaGUID; + case NPC_VALITHRIA_QUEST: return m_uiValithriaQuestGUID; + case NPC_SINDRAGOSA: return m_uiSindragosaGUID; + case NPC_LICH_KING: return m_uiLichKingGUID; + case NPC_RIMEFANG: return m_uiRimefangGUID; + case NPC_SPINESTALKER: return m_uiSpinestalkerGUID; + case NPC_STINKY: return m_uiStinkyGUID; + case NPC_PRECIOUS: return m_uiPreciousGUID; + case GO_SCIENTIST_DOOR_ORANGE: return m_uiSDoorOrangeGUID; + case GO_SCIENTIST_DOOR_GREEN: return m_uiSDoorGreenGUID; + case GO_SCIENTIST_DOOR_COLLISION: return m_uiSDoorCollisionGUID; + case GO_BLOODWING_DOOR: return m_uiBloodwingDoorGUID; + case GO_FROSTWING_DOOR: return m_uiFrostwingDoorGUID; + case GO_VALITHRIA_DOOR_1: return m_uiValithriaDoor1GUID; + case GO_VALITHRIA_DOOR_2: return m_uiValithriaDoor2GUID; + case GO_VALITHRIA_DOOR_3: return m_uiValithriaDoor3GUID; + case GO_VALITHRIA_DOOR_4: return m_uiValithriaDoor4GUID; + case GO_ICESHARD_1: return m_uiIceShard1GUID; + case GO_ICESHARD_2: return m_uiIceShard2GUID; + case GO_ICESHARD_3: return m_uiIceShard3GUID; + case GO_ICESHARD_4: return m_uiIceShard4GUID; + case GO_FROSTY_WIND: return m_uiFrostyWindGUID; + case GO_FROSTY_EDGE: return m_uiFrostyEdgeGUID; + case GO_SNOW_EDGE: return m_uiSnowEdgeGUID; + case GO_ARTHAS_PLATFORM: return m_uiArthasPlatformGUID; + case GO_ARTHAS_PRECIPICE: return m_uiArthasPrecipiceGUID; + case NPC_FROSTMOURNE_TRIGGER: return m_uiFrostmourneTriggerGUID; + case NPC_FROSTMOURNE_HOLDER: return m_uiFrostmourneHolderGUID; + case NPC_COMBAT_TRIGGER: return m_uidummyTargetGUID; + case GO_GAS_RELEASE_VALVE: return m_uiGasReleaseValveGUID; + case NPC_BLOOD_ORB_CONTROL: return m_uiBloodOrbCtrlGUID; + case GO_MARROWGAR_DOOR: return m_uiMarrogarDoor; + case GO_BLOODPRINCE_DOOR: return m_uiBloodPrinceDoor; + case GO_ICECROWN_GRATE: return m_uiIceCrownGrate; + case GO_SINDRAGOSA_ENTRANCE: return m_uiSindragosaEntrance; + } + return 0; + } + + void instance_icecrown_spire::Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + { + loadStream >> m_auiEncounter[i]; + + if (m_auiEncounter[i] == IN_PROGRESS && i >= 1) + m_auiEncounter[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; + OpenAllDoors(); + } + + bool instance_icecrown_spire::CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* player, Unit const* /*target*/, uint32 /*miscvalue1*/) + { + return GetCriteriaState(criteria_id, player); + } + +InstanceData* GetInstanceData_instance_icecrown_spire(Map* pMap) +{ + return new instance_icecrown_spire(pMap); +} + + +void AddSC_instance_icecrown_spire() +{ + Script* pNewScript; + pNewScript = new Script; + pNewScript->Name = "instance_icecrown_spire"; + pNewScript->GetInstanceData = &GetInstanceData_instance_icecrown_spire; + pNewScript->RegisterSelf(); +} diff --git a/scripts/northrend/naxxramas/boss_anubrekhan.cpp b/scripts/northrend/naxxramas/boss_anubrekhan.cpp index 7805a5aa7..8b276a910 100644 --- a/scripts/northrend/naxxramas/boss_anubrekhan.cpp +++ b/scripts/northrend/naxxramas/boss_anubrekhan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/naxxramas/boss_faerlina.cpp b/scripts/northrend/naxxramas/boss_faerlina.cpp index f1e63af0c..a2f948021 100644 --- a/scripts/northrend/naxxramas/boss_faerlina.cpp +++ b/scripts/northrend/naxxramas/boss_faerlina.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,7 +16,7 @@ /* ScriptData SDName: Boss_Faerlina -SD%Complete: 50 +SD%Complete: 100 SDComment: SDCategory: Naxxramas EndScriptData */ @@ -26,26 +26,29 @@ EndScriptData */ enum { - SAY_GREET = -1533009, - SAY_AGGRO1 = -1533010, - SAY_AGGRO2 = -1533011, - SAY_AGGRO3 = -1533012, - SAY_AGGRO4 = -1533013, - SAY_SLAY1 = -1533014, - SAY_SLAY2 = -1533015, - SAY_DEATH = -1533016, - - EMOTE_BOSS_GENERIC_FRENZY = -1000005, - - //SOUND_RANDOM_AGGRO = 8955, //soundId containing the 4 aggro sounds, we not using this - - SPELL_POSIONBOLT_VOLLEY = 28796, - H_SPELL_POSIONBOLT_VOLLEY = 54098, - SPELL_ENRAGE = 28798, - H_SPELL_ENRAGE = 54100, - - SPELL_RAINOFFIRE = 28794 //Not sure if targeted AoEs work if casted directly upon a pPlayer + SAY_GREET = -1533009, + SAY_AGGRO_1 = -1533010, + SAY_AGGRO_2 = -1533011, + SAY_AGGRO_3 = -1533012, + SAY_AGGRO_4 = -1533013, + SAY_SLAY_1 = -1533014, + SAY_SLAY_2 = -1533015, + SAY_DEATH = -1533016, + + EMOTE_BOSS_GENERIC_FRENZY = -1000005, + + // SOUND_RANDOM_AGGRO = 8955, // soundId containing the 4 aggro sounds, we not using this + + SPELL_POSIONBOLT_VOLLEY = 28796, + SPELL_POSIONBOLT_VOLLEY_H = 54098, + SPELL_ENRAGE = 28798, + SPELL_ENRAGE_H = 54100, + SPELL_RAIN_OF_FIRE = 28794, + SPELL_RAIN_OF_FIRE_H = 54099, + SPELL_WIDOWS_EMBRACE = 28732, + SPELL_WIDOWS_EMBRACE_H = 54097, }; + struct MANGOS_DLL_DECL boss_faerlinaAI : public ScriptedAI { boss_faerlinaAI(Creature* pCreature) : ScriptedAI(pCreature) @@ -75,10 +78,10 @@ struct MANGOS_DLL_DECL boss_faerlinaAI : public ScriptedAI { switch(urand(0, 3)) { - case 0: DoScriptText(SAY_AGGRO1, m_creature); break; - case 1: DoScriptText(SAY_AGGRO2, m_creature); break; - case 2: DoScriptText(SAY_AGGRO3, m_creature); break; - case 3: DoScriptText(SAY_AGGRO4, m_creature); break; + case 0: DoScriptText(SAY_AGGRO_1, m_creature); break; + case 1: DoScriptText(SAY_AGGRO_2, m_creature); break; + case 2: DoScriptText(SAY_AGGRO_3, m_creature); break; + case 3: DoScriptText(SAY_AGGRO_4, m_creature); break; } if (m_pInstance) @@ -98,7 +101,7 @@ struct MANGOS_DLL_DECL boss_faerlinaAI : public ScriptedAI void KilledUnit(Unit* pVictim) { - DoScriptText(urand(0, 1)?SAY_SLAY1:SAY_SLAY2, m_creature); + DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); } void JustDied(Unit* pKiller) @@ -115,6 +118,35 @@ struct MANGOS_DLL_DECL boss_faerlinaAI : public ScriptedAI m_pInstance->SetData(TYPE_FAERLINA, FAIL); } + // Widow's Embrace prevents frenzy and poison bolt, if it removes frenzy, next frenzy is sceduled in 60s + // It is likely that this _should_ be handled with some dummy aura(s) - but couldn't find any + void SpellHit(Unit* pCaster, const SpellEntry* pSpellEntry) + { + // Check if we hit with Widow's Embrave + if (pSpellEntry->Id == SPELL_WIDOWS_EMBRACE || pSpellEntry->Id == SPELL_WIDOWS_EMBRACE_H) + { + bool bIsFrenzyRemove = false; + + // If we remove the Frenzy, the Enrage Timer is reseted to 60s + if (m_creature->HasAura(m_bIsRegularMode ? SPELL_ENRAGE : SPELL_ENRAGE_H)) + { + m_uiEnrageTimer = 60000; + m_creature->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_ENRAGE : SPELL_ENRAGE_H); + + bIsFrenzyRemove = true; + } + + // Achievement 'Momma said Knock you out': If we removed OR delayed the frenzy, the criteria is failed + if ((bIsFrenzyRemove || m_uiEnrageTimer < 30000) && m_pInstance) + m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_KNOCK_YOU_OUT, false); + + // In any case we prevent Frenzy and Poison Bolt Volley for Widow's Embrace Duration (30s) + // We do this be setting the timers to at least bigger than 30s + m_uiEnrageTimer = std::max(m_uiEnrageTimer, (uint32)30000); + m_uiPoisonBoltVolleyTimer = std::max(m_uiPoisonBoltVolleyTimer, urand(33000, 38000)); + } + } + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) @@ -123,8 +155,8 @@ struct MANGOS_DLL_DECL boss_faerlinaAI : public ScriptedAI // Poison Bolt Volley if (m_uiPoisonBoltVolleyTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_POSIONBOLT_VOLLEY); - m_uiPoisonBoltVolleyTimer = 11000; + if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_POSIONBOLT_VOLLEY : SPELL_POSIONBOLT_VOLLEY_H) == CAST_OK) + m_uiPoisonBoltVolleyTimer = 11000; } else m_uiPoisonBoltVolleyTimer -= uiDiff; @@ -133,23 +165,24 @@ struct MANGOS_DLL_DECL boss_faerlinaAI : public ScriptedAI if (m_uiRainOfFireTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, SPELL_RAINOFFIRE); - - m_uiRainOfFireTimer = 16000; + { + if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_RAIN_OF_FIRE : SPELL_RAIN_OF_FIRE_H) == CAST_OK) + m_uiRainOfFireTimer = 16000; + } } else m_uiRainOfFireTimer -= uiDiff; - //Enrage_Timer + // Enrage Timer if (m_uiEnrageTimer < uiDiff) { - if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ENRAGE : SPELL_ENRAGE_H) == CAST_OK) { DoScriptText(EMOTE_BOSS_GENERIC_FRENZY, m_creature); - m_uiEnrageTimer = 61000; + m_uiEnrageTimer = 60000; } } - else + else m_uiEnrageTimer -= uiDiff; DoMeleeAttackIfReady(); @@ -163,9 +196,10 @@ CreatureAI* GetAI_boss_faerlina(Creature* pCreature) void AddSC_boss_faerlina() { - Script* NewScript; - NewScript = new Script; - NewScript->Name = "boss_faerlina"; - NewScript->GetAI = &GetAI_boss_faerlina; - NewScript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_faerlina"; + pNewScript->GetAI = &GetAI_boss_faerlina; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/naxxramas/boss_four_horsemen.cpp b/scripts/northrend/naxxramas/boss_four_horsemen.cpp index 49a7a5732..7e8048030 100644 --- a/scripts/northrend/naxxramas/boss_four_horsemen.cpp +++ b/scripts/northrend/naxxramas/boss_four_horsemen.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/naxxramas/boss_gluth.cpp b/scripts/northrend/naxxramas/boss_gluth.cpp index e0475b5ed..73d94a626 100644 --- a/scripts/northrend/naxxramas/boss_gluth.cpp +++ b/scripts/northrend/naxxramas/boss_gluth.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/naxxramas/boss_gothik.cpp b/scripts/northrend/naxxramas/boss_gothik.cpp index 155043ded..0cf02502b 100644 --- a/scripts/northrend/naxxramas/boss_gothik.cpp +++ b/scripts/northrend/naxxramas/boss_gothik.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -108,8 +108,6 @@ struct MANGOS_DLL_DECL boss_gothikAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); - DoScriptText(SAY_SPEECH_1, m_creature); if (!m_pInstance) @@ -410,7 +408,7 @@ bool EffectDummyCreature_spell_anchor(Unit* pCaster, uint32 uiSpellId, SpellEffe uint32 uiNpcEntry = NPC_SPECT_TRAINEE; if (uiSpellId == SPELL_B_TO_SKULL) - uiNpcEntry = NPC_SPECT_DEATH_KNIGTH; + uiNpcEntry = NPC_SPECT_DEATH_KNIGHT; else if (uiSpellId == SPELL_C_TO_SKULL) uiNpcEntry = NPC_SPECT_RIDER; @@ -437,6 +435,6 @@ void AddSC_boss_gothik() newscript = new Script; newscript->Name = "spell_anchor"; - newscript->pEffectDummyCreature = &EffectDummyCreature_spell_anchor; + newscript->pEffectDummyNPC = &EffectDummyCreature_spell_anchor; newscript->RegisterSelf(); } diff --git a/scripts/northrend/naxxramas/boss_grobbulus.cpp b/scripts/northrend/naxxramas/boss_grobbulus.cpp index ba9dad6a0..e64ddd814 100644 --- a/scripts/northrend/naxxramas/boss_grobbulus.cpp +++ b/scripts/northrend/naxxramas/boss_grobbulus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Grobbulus -SD%Complete: 0 -SDComment: Place holder +SD%Complete: 80 +SDComment: Timer need more care; Spells of Adds (Posion Cloud) need Mangos Fixes, and further handling SDCategory: Naxxramas EndScriptData */ @@ -33,4 +33,190 @@ Enrages 26527*/ enum { EMOTE_SPRAY_SLIME = -1533021, + EMOTE_INJECTION = -1533158, + + SPELL_SLIME_STREAM = 28137, + SPELL_MUTATING_INJECTION = 28169, + SPELL_POISON_CLOUD = 28240, + SPELL_SLIME_SPRAY = 28157, + SPELL_SLIME_SPRAY_H = 54364, + SPELL_BERSERK = 26662, + + NPC_FALLOUT_SLIME = 16290 +}; + +struct MANGOS_DLL_DECL boss_grobbulusAI : public ScriptedAI +{ + boss_grobbulusAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (instance_naxxramas*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + + Reset(); + } + + instance_naxxramas* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiInjectionTimer; + uint32 m_uiPoisonCloudTimer; + uint32 m_uiSlimeSprayTimer; + uint32 m_uiBerserkTimeSecs; + uint32 m_uiBerserkTimer; + uint32 m_uiSlimeStreamTimer; + + void Reset() + { + m_uiInjectionTimer = 12*IN_MILLISECONDS; + m_uiPoisonCloudTimer = urand (20*IN_MILLISECONDS, 25*IN_MILLISECONDS); + m_uiSlimeSprayTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS); + m_uiBerserkTimeSecs = m_bIsRegularMode ? 12*MINUTE : 9*MINUTE; + m_uiBerserkTimer = m_uiBerserkTimeSecs*IN_MILLISECONDS; + m_uiSlimeStreamTimer = 5*IN_MILLISECONDS; // The first few secs it is ok to be out of range + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GROBBULUS, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GROBBULUS, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_GROBBULUS, FAIL); + } + + // This custom selecting function, because we only want to select players without mutagen aura + bool DoCastMutagenInjection() + { + if (m_creature->IsNonMeleeSpellCasted(true)) + return false; + + std::vector suitableTargets; + ThreatList const& threatList = m_creature->getThreatManager().getThreatList(); + ThreatList::const_iterator itr = threatList.begin(); + + for (itr; itr != threatList.end(); ++itr) + { + if (Unit* pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid())) + { + if (pTarget->GetTypeId() == TYPEID_PLAYER && !pTarget->HasAura(SPELL_MUTATING_INJECTION)) + suitableTargets.push_back(pTarget); + } + } + + if (suitableTargets.empty()) + return false; + + Unit* pTarget = suitableTargets[urand(0, suitableTargets.size() - 1)]; + if (DoCastSpellIfCan(pTarget, SPELL_MUTATING_INJECTION) == CAST_OK) + { + DoScriptText(EMOTE_INJECTION, m_creature, pTarget); + return true; + } + else + return false; + } + + void SpellHitTarget(Unit* pTarget, const SpellEntry* pSpell) + { + if ((pSpell->Id == SPELL_SLIME_SPRAY || pSpell->Id == SPELL_SLIME_SPRAY_H) && pTarget->GetTypeId() == TYPEID_PLAYER) + m_creature->SummonCreature(NPC_FALLOUT_SLIME, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10*IN_MILLISECONDS); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // Slime Stream + if (!m_uiSlimeStreamTimer) + { + if (!m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) + { + if (DoCastSpellIfCan(m_creature, SPELL_SLIME_STREAM) == CAST_OK) + // Give some time, to re-reach grobbulus + m_uiSlimeStreamTimer = 3*IN_MILLISECONDS; + } + } + else + { + if (m_uiSlimeStreamTimer < uiDiff) + m_uiSlimeStreamTimer = 0; + else + m_uiSlimeStreamTimer -= uiDiff; + } + + // Berserk + if (m_uiBerserkTimer) + { + if (m_uiBerserkTimer <= uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) + m_uiBerserkTimer = 0; + } + else + m_uiBerserkTimer -= uiDiff; + } + + // SlimeSpray + if (m_uiSlimeSprayTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SLIME_SPRAY : SPELL_SLIME_SPRAY_H) == CAST_OK) + { + m_uiSlimeSprayTimer = urand(30*IN_MILLISECONDS, 60*IN_MILLISECONDS); + DoScriptText(EMOTE_SPRAY_SLIME, m_creature); + } + } + else + m_uiSlimeSprayTimer -= uiDiff; + + // Mutagen Injection + if (m_uiInjectionTimer < uiDiff) + { + if (DoCastMutagenInjection()) + { + // Timer dependend on time of encounter - on enrage time between 5-8s, heroic 2-5s (TODO no reliable source for heroic) + if (m_bIsRegularMode) + m_uiInjectionTimer = urand(10*IN_MILLISECONDS, 13*IN_MILLISECONDS) - 5 * (m_uiBerserkTimeSecs*IN_MILLISECONDS - m_uiBerserkTimer) / m_uiBerserkTimeSecs; + else + m_uiInjectionTimer = urand(10*IN_MILLISECONDS, 13*IN_MILLISECONDS) - 8 * (m_uiBerserkTimeSecs*IN_MILLISECONDS - m_uiBerserkTimer) / m_uiBerserkTimeSecs; + } + } + else + m_uiInjectionTimer -= uiDiff; + + // Poison Cloud + if (m_uiPoisonCloudTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_POISON_CLOUD) == CAST_OK) + m_uiPoisonCloudTimer = 15*IN_MILLISECONDS; + } + else + m_uiPoisonCloudTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } }; + +CreatureAI* GetAI_boss_grobbulus(Creature* pCreature) +{ + return new boss_grobbulusAI(pCreature); +} + +void AddSC_boss_grobbulus() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_grobbulus"; + pNewScript->GetAI = &GetAI_boss_grobbulus; + pNewScript->RegisterSelf(); +} diff --git a/scripts/northrend/naxxramas/boss_heigan.cpp b/scripts/northrend/naxxramas/boss_heigan.cpp index f160fb883..fe26ce10a 100644 --- a/scripts/northrend/naxxramas/boss_heigan.cpp +++ b/scripts/northrend/naxxramas/boss_heigan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -93,8 +93,6 @@ struct MANGOS_DLL_DECL boss_heiganAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); - switch(urand(0, 2)) { case 0: DoScriptText(SAY_AGGRO1, m_creature); break; @@ -151,7 +149,7 @@ struct MANGOS_DLL_DECL boss_heiganAI : public ScriptedAI // Fever if (m_uiFeverTimer < uiDiff) { - DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_DECREPIT_FEVER_N : SPELL_DECREPIT_FEVER_H); +// DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_DECREPIT_FEVER_N : SPELL_DECREPIT_FEVER_H); m_uiFeverTimer = 21000; } else @@ -210,6 +208,35 @@ struct MANGOS_DLL_DECL boss_heiganAI : public ScriptedAI m_uiTauntTimer -= uiDiff; DoMeleeAttackIfReady(); + + // Handling of the erruptions, this is not related to melee attack or spell-casting + if (!m_pInstance) + return; + + // Eruption + if (m_uiEruptionTimer <= uiDiff) + { + static int const m_auiMaxHeiganTraps[MAX_HEIGAN_TRAP_AREAS] = + { + m_pInstance->GetData(TYPE_MAX_HEIGAN_TRAPS_1), m_pInstance->GetData(TYPE_MAX_HEIGAN_TRAPS_2), m_pInstance->GetData(TYPE_MAX_HEIGAN_TRAPS_3), m_pInstance->GetData(TYPE_MAX_HEIGAN_TRAPS_4) + }; + + for (uint8 uiArea = 0; uiArea < MAX_HEIGAN_TRAP_AREAS; ++uiArea) + { + if (uiArea == (m_uiPhaseEruption % 6) || uiArea == 6 - (m_uiPhaseEruption % 6)) + continue; + for (uint8 i = 0; i < m_auiMaxHeiganTraps[uiArea]; i++) + { + if (GameObject* pGo = m_creature->GetMap()->GetGameObject(m_pInstance->GetHeiganTrapData64(uiArea, i))) + pGo->Use(m_creature); + } + } + + m_uiEruptionTimer = m_uiPhase == PHASE_GROUND ? urand(8000, 12000) : urand(2000, 3000); + ++m_uiPhaseEruption; + } + else + m_uiEruptionTimer -= uiDiff; } }; @@ -226,4 +253,3 @@ void AddSC_boss_heigan() NewScript->GetAI = &GetAI_boss_heigan; NewScript->RegisterSelf(); } - diff --git a/scripts/northrend/naxxramas/boss_kelthuzad.cpp b/scripts/northrend/naxxramas/boss_kelthuzad.cpp index 4629551d4..cb4bdb7ec 100644 --- a/scripts/northrend/naxxramas/boss_kelthuzad.cpp +++ b/scripts/northrend/naxxramas/boss_kelthuzad.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -83,6 +83,8 @@ enum MAX_SOLDIER_COUNT = 71, MAX_ABOMINATION_COUNT = 8, MAX_BANSHEE_COUNT = 8, + + ACHIEV_REQ_KILLED_ABOMINATIONS = 18, }; static float M_F_ANGLE = 0.2f; // to adjust for map rotation @@ -130,6 +132,7 @@ struct MANGOS_DLL_DECL boss_kelthuzadAI : public ScriptedAI uint32 m_uiAbominationCount; uint32 m_uiSummonIntroTimer; uint32 m_uiIntroPackCount; + uint32 m_uiKilledAbomination; std::set m_lIntroMobsSet; std::set m_lAddsSet; @@ -154,6 +157,7 @@ struct MANGOS_DLL_DECL boss_kelthuzadAI : public ScriptedAI m_uiSoldierCount = 0; m_uiBansheeCount = 0; m_uiAbominationCount = 0; + m_uiKilledAbomination = 0; m_uiPhase = PHASE_INTRO; // it may be some spell should be used instead, to control the intro phase @@ -264,7 +268,7 @@ struct MANGOS_DLL_DECL boss_kelthuzadAI : public ScriptedAI MaNGOS::NormalizeMapCoord(fY); uint32 uiNpcEntry = NPC_SOUL_WEAVER; - + for(uint8 uiI = 0; uiI < 14; ++uiI) { if (uiI > 0) @@ -326,7 +330,7 @@ struct MANGOS_DLL_DECL boss_kelthuzadAI : public ScriptedAI { m_lAddsSet.insert(pSummoned->GetGUID()); - if(m_pInstance) + if (m_pInstance) { float fX, fY, fZ; m_pInstance->GetChamberCenterCoords(fX, fY, fZ); @@ -345,10 +349,17 @@ struct MANGOS_DLL_DECL boss_kelthuzadAI : public ScriptedAI { case NPC_GUARDIAN: case NPC_SOLDIER_FROZEN: - case NPC_UNSTOPPABLE_ABOM: case NPC_SOUL_WEAVER: m_lAddsSet.erase(pSummoned->GetGUID()); break; + case NPC_UNSTOPPABLE_ABOM: + m_lAddsSet.erase(pSummoned->GetGUID()); + + ++m_uiKilledAbomination; + if (m_uiKilledAbomination >= ACHIEV_REQ_KILLED_ABOMINATIONS) + m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_GET_ENOUGH, true); + + break; } } diff --git a/scripts/northrend/naxxramas/boss_loatheb.cpp b/scripts/northrend/naxxramas/boss_loatheb.cpp index 9e7ce1aef..8c57cfa12 100644 --- a/scripts/northrend/naxxramas/boss_loatheb.cpp +++ b/scripts/northrend/naxxramas/boss_loatheb.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -97,6 +97,12 @@ struct MANGOS_DLL_DECL boss_loathebAI : public ScriptedAI pSummoned->AddThreat(pTarget); } + void SummonedCreatureJustDied(Creature* pSummoned) + { + if (pSummoned->GetEntry() == NPC_SPORE && m_pInstance) + m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_SPORE_LOSER, false); + } + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) @@ -113,7 +119,7 @@ struct MANGOS_DLL_DECL boss_loathebAI : public ScriptedAI else m_uiBerserkTimer -= uiDiff; } - + // Inevitable Doom if (m_uiInevitableDoomTimer < uiDiff) { @@ -164,7 +170,7 @@ struct MANGOS_DLL_DECL boss_loathebAI : public ScriptedAI } else m_uiDeathbloomTimer -= uiDiff; - + DoMeleeAttackIfReady(); } }; diff --git a/scripts/northrend/naxxramas/boss_maexxna.cpp b/scripts/northrend/naxxramas/boss_maexxna.cpp index d1d30448f..a516a0a8d 100644 --- a/scripts/northrend/naxxramas/boss_maexxna.cpp +++ b/scripts/northrend/naxxramas/boss_maexxna.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -31,7 +31,8 @@ enum EMOTE_SPRAY = -1533148, EMOTE_BOSS_GENERIC_FRENZY = -1000005, - SPELL_WEBWRAP = 28622, //Spell is normally used by the webtrap on the wall NOT by Maexxna + SPELL_WEBWRAP = 28622, + SPELL_WEBWRAP_2 = 28673, // purpose unknown SPELL_WEBSPRAY = 29484, SPELL_WEBSPRAY_H = 54125, @@ -79,6 +80,7 @@ struct MANGOS_DLL_DECL npc_web_wrapAI : public ScriptedAI { if (pVictim) { + DoTeleportPlayer(pVictim, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), pVictim->GetOrientation()); m_uiVictimGUID = pVictim->GetGUID(); pVictim->CastSpell(pVictim, SPELL_WEBWRAP, true); } @@ -144,14 +146,14 @@ struct MANGOS_DLL_DECL boss_maexxnaAI : public ScriptedAI m_pInstance->SetData(TYPE_MAEXXNA, FAIL); } - void DoCastWebWrap() + bool DoCastWebWrap() { ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - std::vector targets; + std::vector vTargets; // This spell doesn't work if we only have 1 player on threat list if (tList.size() < 2) - return; + return false; // begin + 1 , so we don't target the one with the highest threat ThreatList::const_iterator itr = tList.begin(); @@ -160,26 +162,30 @@ struct MANGOS_DLL_DECL boss_maexxnaAI : public ScriptedAI // store the threat list in a different container for (;itr != tList.end(); ++itr) { - Unit* target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + Unit* pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); // only on alive players - if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER) - targets.push_back(target); + if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER) + vTargets.push_back(pTarget); } - // cut down to size if we have more than 3 targets - while(targets.size() > 3) - targets.erase(targets.begin()+rand()%targets.size()); + if (vTargets.empty()) + return false; + + // cut down to size if we have more than 1/2 targets (10m/25m) (was 3 in 40m) + uint8 uiMaxTargets = m_bIsRegularMode ? 1 : 2; + while(vTargets.size() > uiMaxTargets) + vTargets.erase(vTargets.begin() + urand(0, vTargets.size() - 1)); int i = 0; - for(std::vector::iterator iter = targets.begin(); iter!= targets.end(); ++iter, ++i) + // TODO check locations for 10m/25m + for(std::vector::const_iterator iter = vTargets.begin(); iter != vTargets.end(); ++iter, ++i) { - // Teleport the 3 targets to a location on the wall and summon a Web Wrap on them + // Teleport the targets to a location on the wall and summon a Web Wrap on them switch(i) { case 0: - DoTeleportPlayer((*iter), LOC_X1, LOC_Y1, LOC_Z1, (*iter)->GetOrientation()); if (Creature* pWrap = m_creature->SummonCreature(NPC_WEB_WRAP, LOC_X1, LOC_Y1, LOC_Z1, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000)) { if (npc_web_wrapAI* pWebAI = dynamic_cast(pWrap->AI())) @@ -187,7 +193,6 @@ struct MANGOS_DLL_DECL boss_maexxnaAI : public ScriptedAI } break; case 1: - DoTeleportPlayer((*iter), LOC_X2, LOC_Y2, LOC_Z2, (*iter)->GetOrientation()); if (Creature* pWrap = m_creature->SummonCreature(NPC_WEB_WRAP, LOC_X2, LOC_Y2, LOC_Z2, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000)) { if (npc_web_wrapAI* pWebAI = dynamic_cast(pWrap->AI())) @@ -195,7 +200,6 @@ struct MANGOS_DLL_DECL boss_maexxnaAI : public ScriptedAI } break; case 2: - DoTeleportPlayer((*iter), LOC_X3, LOC_Y3, LOC_Z3, (*iter)->GetOrientation()); if (Creature* pWrap = m_creature->SummonCreature(NPC_WEB_WRAP, LOC_X3, LOC_Y3, LOC_Z3, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000)) { if (npc_web_wrapAI* pWebAI = dynamic_cast(pWrap->AI())) @@ -204,6 +208,8 @@ struct MANGOS_DLL_DECL boss_maexxnaAI : public ScriptedAI break; } } + + return true; } void SummonSpiderlings() @@ -220,8 +226,8 @@ struct MANGOS_DLL_DECL boss_maexxnaAI : public ScriptedAI // Web Wrap if (m_uiWebWrapTimer < uiDiff) { - DoCastWebWrap(); - DoScriptText(EMOTE_SPIN_WEB, m_creature); + if (DoCastWebWrap()) + DoScriptText(EMOTE_SPIN_WEB, m_creature); m_uiWebWrapTimer = 40000; } else @@ -293,15 +299,15 @@ CreatureAI* GetAI_boss_maexxna(Creature* pCreature) void AddSC_boss_maexxna() { - Script* NewScript; + Script* pNewScript; - NewScript = new Script; - NewScript->Name = "boss_maexxna"; - NewScript->GetAI = &GetAI_boss_maexxna; - NewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "boss_maexxna"; + pNewScript->GetAI = &GetAI_boss_maexxna; + pNewScript->RegisterSelf(); - NewScript = new Script; - NewScript->Name = "npc_web_wrap"; - NewScript->GetAI = &GetAI_npc_web_wrap; - NewScript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "npc_web_wrap"; + pNewScript->GetAI = &GetAI_npc_web_wrap; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/naxxramas/boss_noth.cpp b/scripts/northrend/naxxramas/boss_noth.cpp index b175f4b56..e91438121 100644 --- a/scripts/northrend/naxxramas/boss_noth.cpp +++ b/scripts/northrend/naxxramas/boss_noth.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Noth -SD%Complete: 60 -SDComment: Summons need tuning, timers need tuning, need to add berserk "phase" after last skeleton phase +SD%Complete: 80 +SDComment: Summons need verify, need better phase-switch support (unattackable?) SDCategory: Naxxramas EndScriptData */ @@ -52,6 +52,8 @@ enum SPELL_CURSE_PLAGUEBRINGER = 29213, SPELL_CURSE_PLAGUEBRINGER_H = 54835, + SPELL_BERSERK = 26662, // guesswork, but very common berserk spell in naxx + SPELL_SUMMON_WARRIOR_1 = 29247, SPELL_SUMMON_WARRIOR_2 = 29248, SPELL_SUMMON_WARRIOR_3 = 29249, @@ -106,17 +108,15 @@ struct MANGOS_DLL_DECL boss_nothAI : public ScriptedAI { m_uiPhase = PHASE_GROUND; m_uiPhaseSub = PHASE_GROUND; - m_uiPhaseTimer = 110000; + m_uiPhaseTimer = 90000; m_uiBlinkTimer = 25000; m_uiCurseTimer = 4000; - m_uiSummonTimer = 30000; + m_uiSummonTimer = 12000; } void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); - switch(urand(0, 2)) { case 0: DoScriptText(SAY_AGGRO1, m_creature); break; @@ -165,24 +165,31 @@ struct MANGOS_DLL_DECL boss_nothAI : public ScriptedAI if (m_uiPhase == PHASE_GROUND) { - if (m_uiPhaseTimer < uiDiff) + if (m_uiPhaseTimer) // After PHASE_SKELETON_3 we won't have a balcony phase { - // TODO: avoid teleport when skeleton phases is ended - - if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT) == CAST_OK) + if (m_uiPhaseTimer <= uiDiff) { - DoScriptText(EMOTE_TELEPORT, m_creature); - m_creature->GetMotionMaster()->MoveIdle(); - m_uiPhaseTimer = 70000; - m_uiPhase = PHASE_BALCONY; - ++m_uiPhaseSub; - return; + if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT) == CAST_OK) + { + DoScriptText(EMOTE_TELEPORT, m_creature); + m_creature->GetMotionMaster()->MoveIdle(); + m_uiPhase = PHASE_BALCONY; + ++m_uiPhaseSub; + + switch(m_uiPhaseSub) // Set Duration of Skeleton phase + { + case PHASE_SKELETON_1: m_uiPhaseTimer = 70000; break; + case PHASE_SKELETON_2: m_uiPhaseTimer = 97000; break; + case PHASE_SKELETON_3: m_uiPhaseTimer = 120000; break; + } + return; + } } + else + m_uiPhaseTimer -= uiDiff; } - else - m_uiPhaseTimer -= uiDiff; - if (m_bIsRegularMode) + if (!m_bIsRegularMode) // Blink is used only in 25man { if (m_uiBlinkTimer < uiDiff) { @@ -191,7 +198,7 @@ struct MANGOS_DLL_DECL boss_nothAI : public ScriptedAI SPELL_BLINK_1, SPELL_BLINK_2, SPELL_BLINK_3, SPELL_BLINK_4 }; - if (DoCastSpellIfCan(m_creature, auiSpellBlink[urand(0,3)]) == CAST_OK) + if (DoCastSpellIfCan(m_creature, auiSpellBlink[urand(0, 3)]) == CAST_OK) { DoResetThreat(); m_uiBlinkTimer = 25000; @@ -236,7 +243,7 @@ struct MANGOS_DLL_DECL boss_nothAI : public ScriptedAI DoMeleeAttackIfReady(); } - else + else // PHASE_BALCONY { if (m_uiPhaseTimer < uiDiff) { @@ -244,8 +251,18 @@ struct MANGOS_DLL_DECL boss_nothAI : public ScriptedAI { DoScriptText(EMOTE_TELEPORT_RETURN, m_creature); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); - m_uiPhaseTimer = 90000; + switch (m_uiPhaseSub) + { + case PHASE_SKELETON_1: m_uiPhaseTimer = 110000; break; + case PHASE_SKELETON_2: m_uiPhaseTimer = 180000; break; + case PHASE_SKELETON_3: + m_uiPhaseTimer = 0; + // Go Berserk after third Balcony Phase + DoCastSpellIfCan(m_creature, SPELL_BERSERK, CAST_TRIGGERED); + break; + } m_uiPhase = PHASE_GROUND; + return; } } @@ -266,25 +283,28 @@ struct MANGOS_DLL_DECL boss_nothAI : public ScriptedAI SPELL_SUMMON_GUARD01, SPELL_SUMMON_GUARD02, SPELL_SUMMON_GUARD03, SPELL_SUMMON_GUARD04 }; - // A bit unclear how many in each sub phase, and if there are any clear difference in 25man + // A bit unclear how many in each sub phase switch(m_uiPhaseSub) { case PHASE_SKELETON_1: { - for(uint8 i = 0; i < 2; ++i) + for (uint8 i = 0; i < (m_bIsRegularMode ? 2 : 4); ++i) DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedChampion[urand(0,9)], CAST_TRIGGERED); break; } case PHASE_SKELETON_2: { - DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedChampion[urand(0,9)], CAST_TRIGGERED); - DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedGuardian[urand(0,3)], CAST_TRIGGERED); + for (uint8 i = 0; i < (m_bIsRegularMode ? 1 : 2); ++i) + { + DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedChampion[urand(0,9)], CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedGuardian[urand(0,3)], CAST_TRIGGERED); + } break; } case PHASE_SKELETON_3: { - for(uint8 i = 0; i < 2; ++i) + for (uint8 i = 0; i < (m_bIsRegularMode ? 2 : 4); ++i) DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedGuardian[urand(0,3)], CAST_TRIGGERED); break; @@ -306,9 +326,10 @@ CreatureAI* GetAI_boss_noth(Creature* pCreature) void AddSC_boss_noth() { - Script* NewScript; - NewScript = new Script; - NewScript->Name = "boss_noth"; - NewScript->GetAI = &GetAI_boss_noth; - NewScript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_noth"; + pNewScript->GetAI = &GetAI_boss_noth; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/naxxramas/boss_patchwerk.cpp b/scripts/northrend/naxxramas/boss_patchwerk.cpp index 4bf70a6c4..36aea9ff9 100644 --- a/scripts/northrend/naxxramas/boss_patchwerk.cpp +++ b/scripts/northrend/naxxramas/boss_patchwerk.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -113,7 +113,7 @@ struct MANGOS_DLL_DECL boss_patchwerkAI : public ScriptedAI if (Unit* pTempTarget = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid())) { - if (pTempTarget->GetHealth() > uiHighestHP && m_creature->IsWithinDistInMap(pTempTarget, ATTACK_DISTANCE)) + if (pTempTarget->GetHealth() > uiHighestHP && m_creature->CanReachWithMeleeAttack(pTempTarget)) { uiHighestHP = pTempTarget->GetHealth(); pTarget = pTempTarget; diff --git a/scripts/northrend/naxxramas/boss_razuvious.cpp b/scripts/northrend/naxxramas/boss_razuvious.cpp index fe732cee4..54380c3de 100644 --- a/scripts/northrend/naxxramas/boss_razuvious.cpp +++ b/scripts/northrend/naxxramas/boss_razuvious.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Razuvious -SD%Complete: 75% -SDComment: TODO: Timers and sounds need confirmation, implement spell Hopeless +SD%Complete: 85% +SDComment: TODO: Timers and sounds need confirmation - orb handling for normal-mode is missing SDCategory: Naxxramas EndScriptData */ @@ -37,7 +37,7 @@ enum SAY_COMMAND4 = -1533128, SAY_DEATH = -1533129, - SPELL_UNBALANCING_STRIKE = 26613, + SPELL_UNBALANCING_STRIKE = 55470, SPELL_DISRUPTING_SHOUT = 55543, SPELL_DISRUPTING_SHOUT_H = 29107, SPELL_JAGGED_KNIFE = 55550, @@ -85,6 +85,8 @@ struct MANGOS_DLL_DECL boss_razuviousAI : public ScriptedAI { DoScriptText(SAY_DEATH, m_creature); + DoCastSpellIfCan(m_creature, SPELL_HOPELESS, CAST_TRIGGERED); + if (m_pInstance) m_pInstance->SetData(TYPE_RAZUVIOUS, DONE); } @@ -116,8 +118,8 @@ struct MANGOS_DLL_DECL boss_razuviousAI : public ScriptedAI // Unbalancing Strike if (m_uiUnbalancingStrikeTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_UNBALANCING_STRIKE); - m_uiUnbalancingStrikeTimer = 30000; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_UNBALANCING_STRIKE) == CAST_OK) + m_uiUnbalancingStrikeTimer = 30000; } else m_uiUnbalancingStrikeTimer -= uiDiff; @@ -125,8 +127,8 @@ struct MANGOS_DLL_DECL boss_razuviousAI : public ScriptedAI // Disrupting Shout if (m_uiDisruptingShoutTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_DISRUPTING_SHOUT : SPELL_DISRUPTING_SHOUT_H); - m_uiDisruptingShoutTimer = 25000; + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_DISRUPTING_SHOUT : SPELL_DISRUPTING_SHOUT_H) == CAST_OK) + m_uiDisruptingShoutTimer = 25000; } else m_uiDisruptingShoutTimer -= uiDiff; @@ -135,8 +137,10 @@ struct MANGOS_DLL_DECL boss_razuviousAI : public ScriptedAI if (m_uiJaggedKnifeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, SPELL_JAGGED_KNIFE); - m_uiJaggedKnifeTimer = 10000; + { + if (DoCastSpellIfCan(pTarget, SPELL_JAGGED_KNIFE) == CAST_OK) + m_uiJaggedKnifeTimer = 10000; + } } else m_uiJaggedKnifeTimer -= uiDiff; @@ -167,9 +171,10 @@ CreatureAI* GetAI_boss_razuvious(Creature* pCreature) void AddSC_boss_razuvious() { - Script* NewScript; - NewScript = new Script; - NewScript->Name = "boss_razuvious"; - NewScript->GetAI = &GetAI_boss_razuvious; - NewScript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_razuvious"; + pNewScript->GetAI = &GetAI_boss_razuvious; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/naxxramas/boss_sapphiron.cpp b/scripts/northrend/naxxramas/boss_sapphiron.cpp index 8d178d92b..c068f2f41 100644 --- a/scripts/northrend/naxxramas/boss_sapphiron.cpp +++ b/scripts/northrend/naxxramas/boss_sapphiron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,11 +16,26 @@ /* ScriptData SDName: Boss_Sapphiron -SD%Complete: 0 -SDComment: Place Holder +SD%Complete: 80 +SDComment: Havy-Snow-Storms need proper handling, Some spells need core implementation, Hover is currently hacked SDCategory: Naxxramas EndScriptData */ +/* Additional comments: + * Bugged spells: 28560 (needs maxTarget = 1, Summon of 16474 implementation, TODO, how long?) + * 28526 (needs ScriptEffect to cast 28522 onto random target) + * + * Blizzard might need handling for their movement + * SetHover hackz must be replaced by proper opcodes 04D3(Liftoff) 04D4(Landing) + * Achievement-criteria check needs implementation + * + * Frost-Breath ability: the dummy spell 30101 is self cast, so it won't take the needed delay of ~7s until it reaches its target + * As Sapphiron is displayed visually in hight (hovering), and the spell is cast with target=self-location + * which is still on the ground, the client shows a nice slow falling of the visual animation + * Insisting on using the Dummy-Effect to cast the breath-dmg spells, would require, to relocate Sapphi internally, + * and to hack the targeting to be "on the ground" - Hence the prefered way as it is now! + */ + #include "precompiled.h" #include "naxxramas.h" @@ -28,15 +43,38 @@ enum { EMOTE_BREATH = -1533082, EMOTE_GENERIC_ENRAGED = -1000003, - EMOTE_FLY = -1533022, // NYI - EMOTE_GROUND = -1533083, // NYI + EMOTE_FLY = -1533022, + EMOTE_GROUND = -1533083, - SPELL_ICEBOLT = 28522, - SPELL_FROST_BREATH = 29318, + SPELL_CLEAVE = 19983, + SPELL_TAIL_SWEEP = 55697, + SPELL_TAIL_SWEEP_H = 55696, + SPELL_ICEBOLT = 28526, + SPELL_FROST_BREATH_DUMMY = 30101, + SPELL_FROST_BREATH_A = 28524, + SPELL_FROST_BREATH_B = 29318, SPELL_FROST_AURA = 28531, + SPELL_FROST_AURA_H = 55799, SPELL_LIFE_DRAIN = 28542, - SPELL_BLIZZARD = 28547, - SPELL_BESERK = 26662 + SPELL_LIFE_DRAIN_H = 55665, + SPELL_CHILL = 28547, + SPELL_CHILL_H = 55699, + SPELL_SUMMON_BLIZZARD = 28560, + SPELL_BESERK = 26662, + SPELL_ACHIEVEMENT_CHECK = 60539, // unused + + NPC_YOU_KNOW_WHO = 16474, +}; + +static const float aLiftOffPosition[3] = {3522.386f, -5236.784f, 137.709f}; + +enum Phases +{ + PHASE_GROUND = 1, + PHASE_LIFT_OFF = 2, + PHASE_AIR_BOLTS = 3, + PHASE_AIR_BREATH = 4, + PHASE_LANDING = 5, }; struct MANGOS_DLL_DECL boss_sapphironAI : public ScriptedAI @@ -51,37 +89,41 @@ struct MANGOS_DLL_DECL boss_sapphironAI : public ScriptedAI instance_naxxramas* m_pInstance; bool m_bIsRegularMode; - uint32 Icebolt_Count; - uint32 Icebolt_Timer; - uint32 FrostBreath_Timer; - uint32 FrostAura_Timer; - uint32 LifeDrain_Timer; - uint32 Blizzard_Timer; - uint32 Fly_Timer; - uint32 Beserk_Timer; - uint32 phase; - bool landoff; - uint32 land_Timer; + uint32 m_uiCleaveTimer; + uint32 m_uiTailSweepTimer; + uint32 m_uiIceboltTimer; + uint32 m_uiFrostBreathTimer; + uint32 m_uiLifeDrainTimer; + uint32 m_uiBlizzardTimer; + uint32 m_uiFlyTimer; + uint32 m_uiBerserkTimer; + uint32 m_uiLandTimer; + + uint32 m_uiIceboltCount; + Phases m_Phase; void Reset() { - FrostAura_Timer = 2000; - FrostBreath_Timer = 2500; - LifeDrain_Timer = 24000; - Blizzard_Timer = 20000; - Fly_Timer = 45000; - Icebolt_Timer = 4000; - land_Timer = 2000; - Beserk_Timer = 0; - phase = 1; - Icebolt_Count = 0; - landoff = false; + m_uiCleaveTimer = 5000; + m_uiTailSweepTimer = 12000; + m_uiFrostBreathTimer = 7000; + m_uiLifeDrainTimer = 11000; + m_uiBlizzardTimer = 15000; // "Once the encounter starts,based on your version of Naxx, this will be used x2 for normal and x6 on HC" + m_uiFlyTimer = 46000; + m_uiIceboltTimer = 5000; + m_uiLandTimer = 0; + m_uiBerserkTimer = 15 * MINUTE * IN_MILLISECONDS; + m_Phase = PHASE_GROUND; + m_uiIceboltCount = 0; + SetCombatMovement(true); //m_creature->ApplySpellMod(SPELL_FROST_AURA, SPELLMOD_DURATION, -1); } void Aggro(Unit* pWho) { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_FROST_AURA : SPELL_FROST_AURA_H); + if (m_pInstance) m_pInstance->SetData(TYPE_SAPPHIRON, IN_PROGRESS); } @@ -98,105 +140,172 @@ struct MANGOS_DLL_DECL boss_sapphironAI : public ScriptedAI m_pInstance->SetData(TYPE_SAPPHIRON, FAIL); } + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if (uiType == POINT_MOTION_TYPE && m_Phase == PHASE_LIFT_OFF) + { + DoScriptText(EMOTE_FLY, m_creature); + m_creature->HandleEmote(EMOTE_ONESHOT_LIFTOFF); + m_creature->SetHover(true); + m_Phase = PHASE_AIR_BOLTS; + + m_uiFrostBreathTimer = 5000; + m_uiIceboltTimer = 5000; + m_uiIceboltCount = 0; + } + } + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (phase == 1) + switch (m_Phase) { - if (FrostAura_Timer < uiDiff) - { - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FROST_AURA); - FrostAura_Timer = 5000; - }else FrostAura_Timer -= uiDiff; + case PHASE_GROUND: + if (m_uiCleaveTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) + m_uiCleaveTimer = urand(5000, 10000); + } + else + m_uiCleaveTimer -= uiDiff; - if (LifeDrain_Timer < uiDiff) - { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_LIFE_DRAIN); + if (m_uiTailSweepTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_TAIL_SWEEP : SPELL_TAIL_SWEEP) == CAST_OK) + m_uiTailSweepTimer = urand(7000, 10000); + } + else + m_uiTailSweepTimer -= uiDiff; - LifeDrain_Timer = 24000; - }else LifeDrain_Timer -= uiDiff; + if (m_uiLifeDrainTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_LIFE_DRAIN : SPELL_LIFE_DRAIN_H) == CAST_OK) + m_uiLifeDrainTimer = 23000; + } + else + m_uiLifeDrainTimer -= uiDiff; - if (Blizzard_Timer < uiDiff) - { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_BLIZZARD); + if (m_uiBlizzardTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_BLIZZARD) == CAST_OK) + m_uiBlizzardTimer = 20000; + } + else + m_uiBlizzardTimer -= uiDiff; + + if (m_creature->GetHealthPercent() > 10.0f) + { + if (m_uiFlyTimer < uiDiff) + { + m_Phase = PHASE_LIFT_OFF; + m_creature->InterruptNonMeleeSpells(false); + SetCombatMovement(false); + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MovePoint(1, aLiftOffPosition[0], aLiftOffPosition[1], aLiftOffPosition[2]); + // TODO This should clear the target, too - Blizzard_Timer = 20000; - }else Blizzard_Timer -= uiDiff; + return; + } + else + m_uiFlyTimer -= uiDiff; + } - if (m_creature->GetHealthPercent() > 10.0f) - { - if (Fly_Timer < uiDiff) + // Only Phase in which we have melee attack! + DoMeleeAttackIfReady(); + break; + case PHASE_LIFT_OFF: + break; + case PHASE_AIR_BOLTS: + // WOTLK Changed, originally was 5 + if (m_uiIceboltCount == (m_bIsRegularMode ? 2 : 3)) { - phase = 2; - m_creature->InterruptNonMeleeSpells(false); - m_creature->HandleEmote(EMOTE_ONESHOT_LIFTOFF); - m_creature->GetMotionMaster()->Clear(false); - m_creature->GetMotionMaster()->MoveIdle(); - DoCastSpellIfCan(m_creature,11010); - m_creature->SetHover(true); - DoCastSpellIfCan(m_creature,18430); - Icebolt_Timer = 4000; - Icebolt_Count = 0; - landoff = false; - }else Fly_Timer -= uiDiff; - } - } + if (m_uiFrostBreathTimer < uiDiff) + { + m_Phase = PHASE_AIR_BREATH; + DoScriptText(EMOTE_BREATH, m_creature); + DoCastSpellIfCan(m_creature, SPELL_FROST_BREATH_DUMMY); + m_uiFrostBreathTimer = 7000; + } + else + m_uiFrostBreathTimer -= uiDiff; + } + else + { + if (m_uiIceboltTimer < uiDiff) + { + DoCastSpellIfCan(m_creature, SPELL_ICEBOLT); - if (phase == 2) - { - if (Icebolt_Timer < uiDiff && Icebolt_Count < 5) - { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - DoCastSpellIfCan(target,SPELL_ICEBOLT); + ++m_uiIceboltCount; + m_uiIceboltTimer = 4000; + } + else + m_uiIceboltTimer -= uiDiff; + } - ++Icebolt_Count; - Icebolt_Timer = 4000; - }else Icebolt_Timer -= uiDiff; + break; + case PHASE_AIR_BREATH: + if (m_uiFrostBreathTimer) + { + if (m_uiFrostBreathTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature, SPELL_FROST_BREATH_A, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_FROST_BREATH_B, CAST_TRIGGERED); + m_uiFrostBreathTimer = 0; - if (Icebolt_Count == 5 && !landoff) - { - if (FrostBreath_Timer < uiDiff) + m_uiLandTimer = 4000; + } + else + m_uiFrostBreathTimer -= uiDiff; + } + + if (m_uiLandTimer) { - DoScriptText(EMOTE_BREATH, m_creature); - DoCastSpellIfCan(m_creature->getVictim(),SPELL_FROST_BREATH); - land_Timer = 2000; - landoff = true; - FrostBreath_Timer = 6000; - }else FrostBreath_Timer -= uiDiff; - } + if (m_uiLandTimer <= uiDiff) + { + // Begin Landing + DoScriptText(EMOTE_GROUND, m_creature); + m_creature->HandleEmote(EMOTE_ONESHOT_LAND); + m_creature->SetHover(false); - if (landoff) - { - if (land_Timer < uiDiff) + m_Phase = PHASE_LANDING; + m_uiLandTimer = 2000; + } + else + m_uiLandTimer -= uiDiff; + } + + break; + case PHASE_LANDING: + if (m_uiLandTimer < uiDiff) { - phase = 1; - m_creature->HandleEmote(EMOTE_ONESHOT_LAND); - m_creature->SetHover(false); + m_Phase = PHASE_GROUND; + + SetCombatMovement(false); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); - Fly_Timer = 67000; - }else land_Timer -= uiDiff; - } + + m_uiFlyTimer = 67000; + m_uiLandTimer = 0; + } + else + m_uiLandTimer -= uiDiff; + + break; } - if (m_creature->GetHealthPercent() <= 10.0f) + // Enrage can happen in any phase + if (m_uiBerserkTimer < uiDiff) { - if (Beserk_Timer < uiDiff) + if (DoCastSpellIfCan(m_creature, SPELL_BESERK) == CAST_OK) { - if (DoCastSpellIfCan(m_creature, SPELL_BESERK) == CAST_OK) - { - DoScriptText(EMOTE_GENERIC_ENRAGED, m_creature); - Beserk_Timer = 300000; - } - }else Beserk_Timer -= uiDiff; + DoScriptText(EMOTE_GENERIC_ENRAGED, m_creature); + m_uiBerserkTimer = 300000; + } } - - if (phase!=2) - DoMeleeAttackIfReady(); + else + m_uiBerserkTimer -= uiDiff; } }; @@ -207,9 +316,10 @@ CreatureAI* GetAI_boss_sapphiron(Creature* pCreature) void AddSC_boss_sapphiron() { - Script* NewScript; - NewScript = new Script; - NewScript->Name = "boss_sapphiron"; - NewScript->GetAI = &GetAI_boss_sapphiron; - NewScript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_sapphiron"; + pNewScript->GetAI = &GetAI_boss_sapphiron; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/naxxramas/boss_thaddius.cpp b/scripts/northrend/naxxramas/boss_thaddius.cpp index 44990a82d..63ab01a45 100644 --- a/scripts/northrend/naxxramas/boss_thaddius.cpp +++ b/scripts/northrend/naxxramas/boss_thaddius.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,11 +16,18 @@ /* ScriptData SDName: Boss_Thaddius -SD%Complete: 0 -SDComment: Placeholder. Includes Feugen & Stalagg. +SD%Complete: 85 +SDComment: Magnetic Pull, Tesla-Chains, Polaritiy-Shift missing (core!) SDCategory: Naxxramas EndScriptData */ +/* ContentData +boss_thaddius +npc_tesla_coil +boss_stalagg +boss_feugen +EndContentData */ + #include "precompiled.h" #include "naxxramas.h" @@ -31,48 +38,739 @@ enum SAY_STAL_SLAY = -1533024, SAY_STAL_DEATH = -1533025, - SPELL_POWERSURGE = 28134, - //Feugen SAY_FEUG_AGGRO = -1533026, SAY_FEUG_SLAY = -1533027, SAY_FEUG_DEATH = -1533028, - SPELL_MANABURN = 28135, - - //both - SPELL_WARSTOMP = 28125, + // Tesla Coils + EMOTE_LOSING_LINK = -1533149, + EMOTE_TESLA_OVERLOAD = -1533150, //Thaddus - SAY_GREET = -1533029, - SAY_AGGRO1 = -1533030, - SAY_AGGRO2 = -1533031, - SAY_AGGRO3 = -1533032, + SAY_AGGRO_1 = -1533030, + SAY_AGGRO_2 = -1533031, + SAY_AGGRO_3 = -1533032, SAY_SLAY = -1533033, SAY_ELECT = -1533034, SAY_DEATH = -1533035, + // Background screams in Instance if Thaddius still alive, needs general support most likely SAY_SCREAM1 = -1533036, SAY_SCREAM2 = -1533037, SAY_SCREAM3 = -1533038, SAY_SCREAM4 = -1533039, + EMOTE_POLARITY_SHIFT = -1533151, + // Thaddius Spells + SPELL_THADIUS_SPAWN = 28160, + SPELL_THADIUS_LIGHTNING_VISUAL = 28136, SPELL_BALL_LIGHTNING = 28299, + SPELL_CHAIN_LIGHTNING = 28167, + SPELL_CHAIN_LIGHTNING_H = 54531, + SPELL_POLARITY_SHIFT = 28089, + SPELL_BESERK = 27680, + SPELL_CLEAR_CHARGES = 63133, // TODO NYI, cast on death, most likely to remove remaining buffs - EMOTE_POLARITY_SHIFT = -1533151, + // Stalagg & Feugen Spells + //SPELL_WARSTOMP = 28125, // Not used in Wotlk Version + SPELL_MAGNETIC_PULL_A = 28338, + SPELL_MAGNETIC_PULL_B = 54517, // used by Feugen (wotlk) + SPELL_STATIC_FIELD = 28135, + SPELL_STATIC_FIELD_H = 54528, + SPELL_POWERSURGE_H = 28134, + SPELL_POWERSURGE = 54529, - SPELL_CHARGE_POSITIVE_DMGBUFF = 29659, - SPELL_CHARGE_POSITIVE_NEARDMG = 28059, + // Tesla Spells + SPELL_FEUGEN_CHAIN = 28111, + SPELL_STALAGG_CHAIN = 28096, + SPELL_SHOCK_OVERLOAD = 28159, + SPELL_SHOCK = 28099, + }; - SPELL_CHARGE_NEGATIVE_DMGBUFF = 29660, - SPELL_CHARGE_NEGATIVE_NEARDMG = 28084, +/************ +** boss_thaddius +************/ - SPELL_CHAIN_LIGHTNING = 28167, - SPELL_CHAIN_LIGHTNING_H = 54531, +// Actually this boss behaves like a NoMovement Boss (SPELL_BALL_LIGHTNING) - but there are some movement packages used, unknown what this means! +struct MANGOS_DLL_DECL boss_thaddiusAI : public Scripted_NoMovementAI +{ + boss_thaddiusAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) + { + m_pInstance = (instance_naxxramas*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); - SPELL_BESERK = 26662, + Reset(); + } - //generic - NPC_TESLA_COIL = 16218, //the coils (emotes "Tesla Coil overloads!") - EMOTE_LOSING_LINK = -1533149, - EMOTE_TESLA_OVERLOAD = -1533150, + instance_naxxramas* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiPolarityShiftTimer; + uint32 m_uiChainLightningTimer; + uint32 m_uiBallLightningTimer; + uint32 m_uiBerserkTimer; + + void Reset() + { + m_uiPolarityShiftTimer = 15*IN_MILLISECONDS; + m_uiChainLightningTimer = 8*IN_MILLISECONDS; + m_uiBallLightningTimer = 1*IN_MILLISECONDS; + m_uiBerserkTimer = 6*MINUTE*IN_MILLISECONDS; + } + + void Aggro(Unit* pWho) + { + switch (urand(0,2)) + { + case 0: DoScriptText(SAY_AGGRO_1, m_creature); break; + case 1: DoScriptText(SAY_AGGRO_2, m_creature); break; + case 2: DoScriptText(SAY_AGGRO_3, m_creature); break; + } + + // Make Attackable + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void EnterEvadeMode() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_THADDIUS, FAIL); + + // Respawn Adds: + Creature* pFeugen = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_FEUGEN)); + Creature* pStalagg = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_STALAGG)); + if (pFeugen) + { + pFeugen->ForcedDespawn(); + pFeugen->Respawn(); + } + if (pStalagg) + { + pStalagg->ForcedDespawn(); + pStalagg->Respawn(); + } + } + + // Reset + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + // Delay reloading of CreatureAddon until Reached home for proper handling + // Also note that m_creature->LoadCreatureAddon(); must _not_ be called before m_creature->GetMotionMaster()->MoveTargetedHome(); + // Done this way, because MoveTargetHome ensures proper positioning (orientation) + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + + if (m_creature->isAlive()) + m_creature->GetMotionMaster()->MoveTargetedHome(); + + m_creature->SetLootRecipient(NULL); + + Reset(); + } + + void JustReachedHome() + { + m_creature->LoadCreatureAddon(); + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_PLAYER) + return; + + DoScriptText(SAY_SLAY, m_creature); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + { + m_pInstance->SetData(TYPE_THADDIUS, DONE); + + // Force Despawn of Adds + Creature* pFeugen = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_FEUGEN)); + Creature* pStalagg = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_STALAGG)); + + if (pFeugen) + pFeugen->ForcedDespawn(); + if (pStalagg) + pStalagg->ForcedDespawn(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) + return; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // Berserk + if (m_uiBerserkTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_BESERK) == CAST_OK) // allow combat movement? + m_uiBerserkTimer = 10*MINUTE*IN_MILLISECONDS; + } + else + m_uiBerserkTimer -= uiDiff; + + // Polarity Shift + if (m_uiPolarityShiftTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_POLARITY_SHIFT, CAST_INTERRUPT_PREVIOUS) == CAST_OK) + { + DoScriptText(SAY_ELECT, m_creature); + DoScriptText(EMOTE_POLARITY_SHIFT, m_creature); + m_uiPolarityShiftTimer = 30*IN_MILLISECONDS; + } + } + else + m_uiPolarityShiftTimer -= uiDiff; + + // Chain Lightning + if (m_uiChainLightningTimer < uiDiff) + { + Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); + if (pTarget && DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H) == CAST_OK) + m_uiChainLightningTimer = 15*IN_MILLISECONDS; + } + else + m_uiChainLightningTimer -= uiDiff; + + // Ball Lightning if target not in melee range + // TODO: Verify, likely that the boss should attack any enemy in melee range before starting to cast + if (!m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) + { + if (m_uiBallLightningTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_BALL_LIGHTNING) == CAST_OK) + m_uiBallLightningTimer = 1*IN_MILLISECONDS; + } + else + m_uiBallLightningTimer -= uiDiff; + } + else + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_thaddius(Creature* pCreature) +{ + return new boss_thaddiusAI(pCreature); +} + +bool EffectDummyNPC_spell_thaddius_encounter(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +{ + switch (uiSpellId) + { + case SPELL_SHOCK_OVERLOAD: + if (uiEffIndex == EFFECT_INDEX_0) + { + // Only do something to Thaddius, and on the first hit. + if (pCreatureTarget->GetEntry() != NPC_THADDIUS || !pCreatureTarget->HasAura(SPELL_THADIUS_SPAWN)) + return true; + // remove Stun and then Cast + pCreatureTarget->RemoveAurasDueToSpell(SPELL_THADIUS_SPAWN); + pCreatureTarget->CastSpell(pCreatureTarget, SPELL_THADIUS_LIGHTNING_VISUAL, false); + } + return true; + case SPELL_THADIUS_LIGHTNING_VISUAL: + if (uiEffIndex == EFFECT_INDEX_0 && pCreatureTarget->GetEntry() == NPC_THADDIUS) + { + if (instance_naxxramas* pInstance = (instance_naxxramas*)pCreatureTarget->GetInstanceData()) + { + if (Player* pPlayer = pInstance->GetPlayerInMap(true, false)) + pCreatureTarget->AI()->AttackStart(pPlayer); + } + } + return true; + } + return false; +} + +/************ +** npc_tesla_coil +************/ + +struct MANGOS_DLL_DECL npc_tesla_coilAI : public Scripted_NoMovementAI +{ + npc_tesla_coilAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) + { + m_pInstance = (instance_naxxramas*)pCreature->GetInstanceData(); + m_uiSetupTimer = 1*IN_MILLISECONDS; + m_uiOverloadTimer = 0; + m_bReapply = false; + Reset(); + } + + instance_naxxramas* m_pInstance; + bool m_bToFeugen; + bool m_bReapply; + + uint32 m_uiSetupTimer; + uint32 m_uiOverloadTimer; + + void Reset() {} + void AttackStart(Unit* pWho) {} + void MoveInLineOfSight(Unit* pWho) {} + + bool SetupChain() + { + // Check, if instance_ script failed or encounter finished + if (!m_pInstance || m_pInstance->GetData(TYPE_THADDIUS) == DONE) + return true; + + GameObject* pNoxTeslaFeugen = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CONS_NOX_TESLA_FEUGEN)); + GameObject* pNoxTeslaStalagg = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CONS_NOX_TESLA_STALAGG)); + + // Try again, till Tesla GOs are spawned + if (!pNoxTeslaFeugen || !pNoxTeslaStalagg) + return false; + + m_bToFeugen = m_creature->GetDistanceOrder(pNoxTeslaFeugen, pNoxTeslaStalagg); + + return true; + + /* TODO Uncomment when Chain spells are proper implemented + * if (DoCastSpellIfCan(m_creature, m_bToFeugen ? SPELL_FEUGEN_CHAIN : SPELL_STALAGG_CHAIN) == CAST_OK) + * return true; + * + * return false; + */ + } + + void ReApplyChain(uint32 uiEntry) + { + if (uiEntry) // called from Stalagg/Feugen with their entry + { + // Only apply chain to own add + if ((uiEntry == NPC_FEUGEN && !m_bToFeugen) || (uiEntry == NPC_STALAGG && m_bToFeugen)) + return; + + m_bReapply = true; // Reapply Chains on next tick + } + else // if called from next tick, needed because otherwise the spell doesn't bind + { + m_bReapply = false; + m_creature->InterruptNonMeleeSpells(true); + m_pInstance->DoCloseDoorOrButton(m_pInstance->GetData64(m_bToFeugen ? GO_CONS_NOX_TESLA_FEUGEN : GO_CONS_NOX_TESLA_STALAGG)); + + // TODO Uncomment when chain spells are proper implemented + // DoCastSpellIfCan(m_creature, m_bToFeugen ? SPELL_FEUGEN_CHAIN : SPELL_STALAGG_CHAIN); + } + } + + void SetOverloading() + { + m_uiOverloadTimer = 14*IN_MILLISECONDS; // it takes some time to overload and activate Thaddius + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_uiOverloadTimer && !m_uiSetupTimer && !m_bReapply) + return; // Nothing to do this tick + + if (m_uiSetupTimer) + { + if (m_uiSetupTimer <= uiDiff) + { + if (SetupChain()) + m_uiSetupTimer = 0; + else + m_uiSetupTimer = 5*IN_MILLISECONDS; + } + else + m_uiSetupTimer -= uiDiff; + } + + if (m_uiOverloadTimer) + { + if (m_uiOverloadTimer <= uiDiff) + { + m_uiOverloadTimer = 0; + DoCastSpellIfCan(m_creature, SPELL_SHOCK_OVERLOAD, CAST_INTERRUPT_PREVIOUS); + DoScriptText(EMOTE_TESLA_OVERLOAD, m_creature); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(m_bToFeugen ? GO_CONS_NOX_TESLA_FEUGEN : GO_CONS_NOX_TESLA_STALAGG)); + } + else + m_uiOverloadTimer -= uiDiff; + } + + if (m_bReapply) + ReApplyChain(0); + } +}; + +CreatureAI* GetAI_npc_tesla_coil(Creature* pCreature) +{ + return new npc_tesla_coilAI(pCreature); +} + +/************ +** boss_thaddiusAddsAI - Superclass for Feugen & Stalagg +************/ + +struct MANGOS_DLL_DECL boss_thaddiusAddsAI : public ScriptedAI +{ + boss_thaddiusAddsAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (instance_naxxramas*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + + Reset(); + } + + instance_naxxramas* m_pInstance; + bool m_bIsRegularMode; + + bool m_bFakeDeath; + bool m_bBothDead; + + uint32 m_uiHoldTimer; + //uint32 m_uiWarStompTimer; + uint32 m_uiReviveTimer; + + void Reset() + { + m_bFakeDeath = false; + m_bBothDead = false; + + m_uiReviveTimer = 5*IN_MILLISECONDS; + m_uiHoldTimer = 2*IN_MILLISECONDS; + //m_uiWarStompTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS); + + // We might Reset while faking death, so undo this + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + } + + Creature* GetOtherAdd() // For Stalagg returns pFeugen, for Feugen returns pStalagg + { + switch (m_creature->GetEntry()) + { + case NPC_FEUGEN: return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_STALAGG)); + case NPC_STALAGG: return m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_FEUGEN)); + default: + return NULL; + } + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) + return; + + m_pInstance->SetData(TYPE_THADDIUS, IN_PROGRESS); + + if (Creature* pOtherAdd = GetOtherAdd()) + { + if (!pOtherAdd->isInCombat()) + pOtherAdd->AI()->AttackStart(pWho); + } + } + + void JustRespawned() + { + Reset(); // Needed to reset the flags properly + + std::list lTeslaGUIDList; + if (!m_pInstance) + return; + + m_pInstance->GetThadTeslaCreatures(lTeslaGUIDList); + if (lTeslaGUIDList.empty()) + return; + + for (std::list::const_iterator itr = lTeslaGUIDList.begin(); itr != lTeslaGUIDList.end(); itr++) + { + if (Creature* pTesla = m_pInstance->instance->GetCreature(*itr)) + { + if (npc_tesla_coilAI* pTeslaAI = dynamic_cast (pTesla->AI())) + pTeslaAI->ReApplyChain(m_creature->GetEntry()); + } + } + } + + void JustReachedHome() + { + if (!m_pInstance) + return; + + if (Creature* pOther = GetOtherAdd()) + { + if (boss_thaddiusAddsAI* pOtherAI = dynamic_cast (pOther->AI())) + { + if (pOtherAI->IsCountingDead()) + { + pOther->ForcedDespawn(); + pOther->Respawn(); + } + } + } + + // Reapply Chains if needed + if (!m_creature->HasAura(SPELL_FEUGEN_CHAIN) && !m_creature->HasAura(SPELL_STALAGG_CHAIN)) + JustRespawned(); + + m_pInstance->SetData(TYPE_THADDIUS, FAIL); + } + + void Revive() + { + DoResetThreat(); + PauseCombatMovement(); + Reset(); + } + + bool IsCountingDead() + { + return m_bFakeDeath || m_creature->isDead(); + } + + void PauseCombatMovement() + { + SetCombatMovement(false); + m_uiHoldTimer = 1500; + } + + virtual void UpdateAddAI(const uint32 uiDiff) {} // Used for Add-specific spells + + void UpdateAI(const uint32 uiDiff) + { + if (m_bBothDead) // This is the case while fighting Thaddius + return; + + if (m_bFakeDeath) + { + if (m_uiReviveTimer < uiDiff) + { + if (Creature* pOther = GetOtherAdd()) + { + if (boss_thaddiusAddsAI* pOtherAI = dynamic_cast (pOther->AI())) + { + if (!pOtherAI->IsCountingDead()) // Raid was to slow to kill the second add + Revive(); + else + { + m_bBothDead = true; // Now both adds are counting dead + pOtherAI->m_bBothDead = true; + // Set both Teslas to overload + std::list lTeslaGUIDList; + m_pInstance->GetThadTeslaCreatures(lTeslaGUIDList); + for (std::list::const_iterator itr = lTeslaGUIDList.begin(); itr != lTeslaGUIDList.end(); itr++) + { + if (Creature* pTesla = m_pInstance->instance->GetCreature(*itr)) + { + if (npc_tesla_coilAI* pTeslaAI = dynamic_cast (pTesla->AI())) + pTeslaAI->SetOverloading(); + } + } + } + } + } + } + else + m_uiReviveTimer -= uiDiff; + return; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiHoldTimer) // A short timer preventing combat movement after revive + { + if (m_uiHoldTimer <= uiDiff) + { + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_uiHoldTimer = 0; + } + else + m_uiHoldTimer -= uiDiff; + } + + /* Doesn't happen in wotlk version any more + if (m_uiWarStompTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_WARSTOMP) == CAST_OK) + m_uiWarStompTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS); + } + else + m_uiWarStompTimer -= uiDiff;*/ + + UpdateAddAI(uiDiff); // For Add Specific Abilities + + DoMeleeAttackIfReady(); + } + + void DamageTaken(Unit* pKiller, uint32& uiDamage) + { + if (uiDamage < m_creature->GetHealth()) + return; + + // Prevent glitch if in fake death + if (m_bFakeDeath) + { + uiDamage = 0; + return; + } + + // prevent death + uiDamage = 0; + m_bFakeDeath = true; + + m_creature->InterruptNonMeleeSpells(false); + m_creature->SetHealth(0); + 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); + + JustDied(pKiller); // Texts + } }; + +/************ +** boss_stalagg +************/ + +struct MANGOS_DLL_DECL boss_stalaggAI : public boss_thaddiusAddsAI +{ + boss_stalaggAI(Creature* pCreature) : boss_thaddiusAddsAI(pCreature) + { + Reset(); + } + uint32 m_uiPowerSurgeTimer; + + void Reset() + { + boss_thaddiusAddsAI::Reset(); + m_uiPowerSurgeTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS); + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_STAL_AGGRO, m_creature); + boss_thaddiusAddsAI::Aggro(pWho); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_STAL_DEATH, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() == TYPEID_PLAYER) + DoScriptText(SAY_STAL_SLAY, m_creature); + } + + void UpdateAddAI(const uint32 uiDiff) + { + if (m_uiPowerSurgeTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_POWERSURGE : SPELL_POWERSURGE_H) == CAST_OK) + m_uiPowerSurgeTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS); + } + else + m_uiPowerSurgeTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_boss_stalagg(Creature* pCreature) +{ + return new boss_stalaggAI(pCreature); +} + +/************ +** boss_feugen +************/ + +struct MANGOS_DLL_DECL boss_feugenAI : public boss_thaddiusAddsAI +{ + boss_feugenAI(Creature* pCreature) : boss_thaddiusAddsAI(pCreature) + { + Reset(); + } + uint32 m_uiStaticFieldTimer; + uint32 m_uiMagneticPullTimer; // TODO, missing + + void Reset() + { + boss_thaddiusAddsAI::Reset(); + m_uiStaticFieldTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS); + m_uiMagneticPullTimer = 20*IN_MILLISECONDS; + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_FEUG_AGGRO, m_creature); + boss_thaddiusAddsAI::Aggro(pWho); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_FEUG_DEATH, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() == TYPEID_PLAYER) + DoScriptText(SAY_FEUG_SLAY, m_creature); + } + + void UpdateAddAI(const uint32 uiDiff) + { + if (m_uiStaticFieldTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_STATIC_FIELD : SPELL_STATIC_FIELD_H) == CAST_OK) + m_uiStaticFieldTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS); + } + else + m_uiStaticFieldTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_boss_feugen(Creature* pCreature) +{ + return new boss_feugenAI(pCreature); +} + +void AddSC_boss_thaddius() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_thaddius"; + pNewScript->GetAI = &GetAI_boss_thaddius; + pNewScript->pEffectDummyNPC = &EffectDummyNPC_spell_thaddius_encounter; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "boss_stalagg"; + pNewScript->GetAI = &GetAI_boss_stalagg; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "boss_feugen"; + pNewScript->GetAI = &GetAI_boss_feugen; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_tesla_coil"; + pNewScript->GetAI = &GetAI_npc_tesla_coil; + pNewScript->pEffectDummyNPC = &EffectDummyNPC_spell_thaddius_encounter; + pNewScript->RegisterSelf(); +} diff --git a/scripts/northrend/naxxramas/instance_naxxramas.cpp b/scripts/northrend/naxxramas/instance_naxxramas.cpp index ef7a80127..0eb41de53 100644 --- a/scripts/northrend/naxxramas/instance_naxxramas.cpp +++ b/scripts/northrend/naxxramas/instance_naxxramas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -52,6 +52,8 @@ instance_naxxramas::instance_naxxramas(Map* pMap) : ScriptedInstance(pMap), m_uiPathExitDoorGUID(0), m_uiGlutExitDoorGUID(0), m_uiThadDoorGUID(0), + m_uiThadNoxTeslaFeugenGUID(0), + m_uiThadNoxTeslaStalaggGUID(0), m_uiAnubDoorGUID(0), m_uiAnubGateGUID(0), @@ -86,6 +88,9 @@ instance_naxxramas::instance_naxxramas(Map* pMap) : ScriptedInstance(pMap), void instance_naxxramas::Initialize() { memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + for (uint8 i = 0; i < MAX_SPECIAL_ACHIEV_CRITS; ++i) + m_abAchievCriteria[i] = false; } void instance_naxxramas::OnCreatureCreate(Creature* pCreature) @@ -104,6 +109,12 @@ void instance_naxxramas::OnCreatureCreate(Creature* pCreature) case NPC_GOTHIK: m_uiGothikGUID = pCreature->GetGUID(); break; case NPC_KELTHUZAD: m_uiKelthuzadGUID = pCreature->GetGUID(); break; case NPC_SUB_BOSS_TRIGGER: m_lGothTriggerList.push_back(pCreature->GetGUID()); break; + case NPC_TESLA_COIL: m_lThadTeslaCoilList.push_back(pCreature->GetGUID()); break; + + case NPC_NAXXRAMAS_FOLLOWER: + case NPC_NAXXRAMAS_WORSHIPPER: + m_lFaerlinaAddGUIDs.push_back(pCreature->GetGUID()); + break; } } @@ -116,7 +127,7 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) break; case GO_ARAC_ANUB_GATE: m_uiAnubGateGUID = pGo->GetGUID(); - if (m_auiEncounter[0] == DONE) + if (m_auiEncounter[TYPE_ANUB_REKHAN] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_ARAC_FAER_WEB: @@ -124,7 +135,7 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) break; case GO_ARAC_FAER_DOOR: m_uiFaerDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[1] == DONE) + if (m_auiEncounter[TYPE_FAERLINA] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_ARAC_MAEX_INNER_DOOR: @@ -132,7 +143,7 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) break; case GO_ARAC_MAEX_OUTER_DOOR: m_uiMaexOuterGUID = pGo->GetGUID(); - if (m_auiEncounter[1] == DONE) + if (m_auiEncounter[TYPE_FAERLINA] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; @@ -141,17 +152,17 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) break; case GO_PLAG_NOTH_EXIT_DOOR: m_uiNothExitDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[3] == DONE) + if (m_auiEncounter[TYPE_NOTH] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_PLAG_HEIG_ENTRY_DOOR: m_uiHeigEntryDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[3] == DONE) + if (m_auiEncounter[TYPE_NOTH] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_PLAG_HEIG_EXIT_DOOR: m_uiHeigExitDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[4] == DONE) + if (m_auiEncounter[TYPE_HEIGAN] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_PLAG_LOAT_DOOR: @@ -163,7 +174,7 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) break; case GO_MILI_GOTH_EXIT_GATE: m_uiGothikExitDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[7] == DONE) + if (m_auiEncounter[TYPE_GOTHIK] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_MILI_GOTH_COMBAT_GATE: @@ -171,7 +182,7 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) break; case GO_MILI_HORSEMEN_DOOR: m_uiHorsemenDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[7] == DONE) + if (m_auiEncounter[TYPE_GOTHIK] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; @@ -182,23 +193,33 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) case GO_CONS_PATH_EXIT_DOOR: m_uiPathExitDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[9] == DONE) + if (m_auiEncounter[TYPE_PATCHWERK] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_CONS_GLUT_EXIT_DOOR: m_uiGlutExitDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[11] == DONE) + if (m_auiEncounter[TYPE_GLUTH] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_CONS_THAD_DOOR: m_uiThadDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[11] == DONE) + if (m_auiEncounter[TYPE_GLUTH] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; + case GO_CONS_NOX_TESLA_FEUGEN: + m_uiThadNoxTeslaFeugenGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_THADDIUS] == DONE) + pGo->SetGoState(GO_STATE_READY); + break; + case GO_CONS_NOX_TESLA_STALAGG: + m_uiThadNoxTeslaStalaggGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_THADDIUS] == DONE) + pGo->SetGoState(GO_STATE_READY); + break; case GO_KELTHUZAD_WATERFALL_DOOR: m_uiKelthuzadDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[13] == DONE) + if (m_auiEncounter[TYPE_SAPPHIRON] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; @@ -208,22 +229,22 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) case GO_ARAC_EYE_RAMP: m_uiAracEyeRampGUID = pGo->GetGUID(); - if (m_auiEncounter[2] == DONE) + if (m_auiEncounter[TYPE_MAEXXNA] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_PLAG_EYE_RAMP: m_uiPlagEyeRampGUID = pGo->GetGUID(); - if (m_auiEncounter[5] == DONE) + if (m_auiEncounter[TYPE_LOATHEB] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_MILI_EYE_RAMP: m_uiMiliEyeRampGUID = pGo->GetGUID(); - if (m_auiEncounter[8] == DONE) + if (m_auiEncounter[TYPE_FOUR_HORSEMEN] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_CONS_EYE_RAMP: m_uiConsEyeRampGUID = pGo->GetGUID(); - if (m_auiEncounter[12] == DONE) + if (m_auiEncounter[TYPE_THADDIUS] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; @@ -240,12 +261,35 @@ void instance_naxxramas::OnObjectCreate(GameObject* pGo) m_uiConsPortalGUID = pGo->GetGUID(); break; } + + // Heigan Traps - many entries, and never used again + if (pGo->GetEntry() >= 181510 && pGo->GetEntry() <= 181695) + { + if (((pGo->GetEntry() >= 181517) && (pGo->GetEntry() <= 181524)) || (pGo->GetEntry() == 181678)) + m_avuiHeiganTraps[0].push_back(pGo->GetGUID()); + else if (((pGo->GetEntry() >= 181510) && (pGo->GetEntry() <= 181516)) || ((pGo->GetEntry() >= 181525) && (pGo->GetEntry() <= 181531)) || (pGo->GetEntry() == 181533 || pGo->GetEntry() == 181676)) + m_avuiHeiganTraps[1].push_back(pGo->GetGUID()); + else if (((pGo->GetEntry() >= 181534) && (pGo->GetEntry() <= 181544)) || (pGo->GetEntry() == 181532) || (pGo->GetEntry() == 181677)) + m_avuiHeiganTraps[2].push_back(pGo->GetGUID()); + else if (((pGo->GetEntry() >= 181545) && (pGo->GetEntry() <= 181552)) || (pGo->GetEntry() == 181695)) + m_avuiHeiganTraps[3].push_back(pGo->GetGUID()); + } + +} + +void instance_naxxramas::OnPlayerDeath(Player* pPlayer) +{ + if (IsEncounterInProgress()) + SetData(TYPE_UNDYING_FAILED, DONE); + + if (GetData(TYPE_HEIGAN) == IN_PROGRESS) + SetSpecialAchievementCriteria(TYPE_ACHIEV_SAFETY_DANCE, false); } bool instance_naxxramas::IsEncounterInProgress() const { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) + for (uint8 i = 0; i < TYPE_KELTHUZAD; ++i) + if (m_auiEncounter[i] == IN_PROGRESS || m_auiEncounter[i] == SPECIAL) return true; return false; @@ -256,22 +300,33 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) switch(uiType) { case TYPE_ANUB_REKHAN: - m_auiEncounter[0] = uiData; + m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(m_uiAnubDoorGUID); if (uiData == DONE) DoUseDoorOrButton(m_uiAnubGateGUID); break; case TYPE_FAERLINA: - m_auiEncounter[1] = uiData; DoUseDoorOrButton(m_uiFaerWebGUID); + if (uiData == IN_PROGRESS) + SetSpecialAchievementCriteria(TYPE_ACHIEV_KNOCK_YOU_OUT, true); if (uiData == DONE) { DoUseDoorOrButton(m_uiFaerDoorGUID); DoUseDoorOrButton(m_uiMaexOuterGUID); } + if (uiData == FAIL) + { + for (std::list::const_iterator itr = m_lFaerlinaAddGUIDs.begin(); itr != m_lFaerlinaAddGUIDs.end(); ++itr) + { + Creature* pAdd = instance->GetCreature(*itr); + if (pAdd && !pAdd->isAlive()) + pAdd->Respawn(); + } + } + m_auiEncounter[uiType] = uiData; break; case TYPE_MAEXXNA: - m_auiEncounter[2] = uiData; + m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(m_uiMaexInnerGUID, uiData); if (uiData == DONE) { @@ -281,7 +336,7 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) } break; case TYPE_NOTH: - m_auiEncounter[3] = uiData; + m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(m_uiNothEntryDoorGUID); if (uiData == DONE) { @@ -290,14 +345,19 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) } break; case TYPE_HEIGAN: - m_auiEncounter[4] = uiData; + m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(m_uiHeigEntryDoorGUID); + // uncomment when eruption is implemented + //if (uiData == IN_PROGRESS) + // SetSpecialAchievementCriteria(TYPE_ACHIEV_SAFETY_DANCE, true); if (uiData == DONE) DoUseDoorOrButton(m_uiHeigExitDoorGUID); break; case TYPE_LOATHEB: - m_auiEncounter[5] = uiData; + m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(m_uiLoathebDoorGUID); + if (uiData == IN_PROGRESS) + SetSpecialAchievementCriteria(TYPE_ACHIEV_SPORE_LOSER, true); if (uiData == DONE) { DoUseDoorOrButton(m_uiPlagEyeRampGUID); @@ -306,7 +366,7 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) } break; case TYPE_RAZUVIOUS: - m_auiEncounter[6] = uiData; + m_auiEncounter[uiType] = uiData; break; case TYPE_GOTHIK: switch(uiData) @@ -319,7 +379,7 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) DoUseDoorOrButton(m_uiGothCombatGateGUID); break; case FAIL: - if (m_auiEncounter[7] == IN_PROGRESS) + if (m_auiEncounter[uiType] == IN_PROGRESS) DoUseDoorOrButton(m_uiGothCombatGateGUID); DoUseDoorOrButton(m_uiGothikEntryDoorGUID); @@ -330,10 +390,10 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) DoUseDoorOrButton(m_uiHorsemenDoorGUID); break; } - m_auiEncounter[7] = uiData; + m_auiEncounter[uiType] = uiData; break; case TYPE_FOUR_HORSEMEN: - m_auiEncounter[8] = uiData; + m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(m_uiHorsemenDoorGUID); if (uiData == DONE) { @@ -344,15 +404,17 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) } break; case TYPE_PATCHWERK: - m_auiEncounter[9] = uiData; + m_auiEncounter[uiType] = uiData; + if (uiData == IN_PROGRESS) + DoStartTimedAchievement(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, ACHIEV_START_PATCHWERK_ID); if (uiData == DONE) DoUseDoorOrButton(m_uiPathExitDoorGUID); break; case TYPE_GROBBULUS: - m_auiEncounter[10] = uiData; + m_auiEncounter[uiType] = uiData; break; case TYPE_GLUTH: - m_auiEncounter[11] = uiData; + m_auiEncounter[uiType] = uiData; if (uiData == DONE) { DoUseDoorOrButton(m_uiGlutExitDoorGUID); @@ -360,8 +422,16 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) } break; case TYPE_THADDIUS: - m_auiEncounter[12] = uiData; - DoUseDoorOrButton(m_uiThadDoorGUID, uiData); + // Only process real changes here + if (m_auiEncounter[uiType] == uiData) + return; + + m_auiEncounter[uiType] = uiData; + if (uiData != SPECIAL) + DoUseDoorOrButton(m_uiThadDoorGUID, uiData); + // Uncomment when this achievement is implemented + //if (uiData == IN_PROGRESS) + // SetSpecialAchievementCriteria(TYPE_ACHIEV_SHOCKING, true); if (uiData == DONE) { DoUseDoorOrButton(m_uiConsEyeRampGUID); @@ -370,13 +440,21 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) } break; case TYPE_SAPPHIRON: - m_auiEncounter[13] = uiData; + m_auiEncounter[uiType] = uiData; + // Uncomment when achiev check implemented + //if (uiData == IN_PROGRESS) + // SetSpecialAchievementCriteria(TYPE_ACHIEV_HUNDRED_CLUB, true); if (uiData == DONE) DoUseDoorOrButton(m_uiKelthuzadDoorGUID); break; case TYPE_KELTHUZAD: - m_auiEncounter[14] = uiData; + m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(m_uiKelthuzadExitDoorGUID); + if (uiData == IN_PROGRESS) + SetSpecialAchievementCriteria(TYPE_ACHIEV_GET_ENOUGH, false); + break; + case TYPE_UNDYING_FAILED: + m_auiEncounter[uiType] = uiData; break; } @@ -389,7 +467,7 @@ void instance_naxxramas::SetData(uint32 uiType, uint32 uiData) << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8] << " " << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11] << " " - << m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiEncounter[14]; + << m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiEncounter[14] << " " << m_auiEncounter[15]; strInstData = saveStream.str(); @@ -412,7 +490,7 @@ void instance_naxxramas::Load(const char* 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] >> m_auiEncounter[10] >> m_auiEncounter[11] - >> m_auiEncounter[12] >> m_auiEncounter[13] >> m_auiEncounter[14]; + >> m_auiEncounter[12] >> m_auiEncounter[13] >> m_auiEncounter[14] >> m_auiEncounter[15]; for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) { @@ -425,38 +503,16 @@ void instance_naxxramas::Load(const char* chrIn) uint32 instance_naxxramas::GetData(uint32 uiType) { + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + switch(uiType) { - case TYPE_ANUB_REKHAN: - return m_auiEncounter[0]; - case TYPE_FAERLINA: - return m_auiEncounter[1]; - case TYPE_MAEXXNA: - return m_auiEncounter[2]; - case TYPE_NOTH: - return m_auiEncounter[3]; - case TYPE_HEIGAN: - return m_auiEncounter[4]; - case TYPE_LOATHEB: - return m_auiEncounter[5]; - case TYPE_RAZUVIOUS: - return m_auiEncounter[6]; - case TYPE_GOTHIK: - return m_auiEncounter[7]; - case TYPE_FOUR_HORSEMEN: - return m_auiEncounter[8]; - case TYPE_PATCHWERK: - return m_auiEncounter[9]; - case TYPE_GROBBULUS: - return m_auiEncounter[10]; - case TYPE_GLUTH: - return m_auiEncounter[11]; - case TYPE_THADDIUS: - return m_auiEncounter[12]; - case TYPE_SAPPHIRON: - return m_auiEncounter[13]; - case TYPE_KELTHUZAD: - return m_auiEncounter[14]; + // Number of Heigan traps per area + case TYPE_MAX_HEIGAN_TRAPS_1: return m_avuiHeiganTraps[0].size(); + case TYPE_MAX_HEIGAN_TRAPS_2: return m_avuiHeiganTraps[1].size(); + case TYPE_MAX_HEIGAN_TRAPS_3: return m_avuiHeiganTraps[2].size(); + case TYPE_MAX_HEIGAN_TRAPS_4: return m_avuiHeiganTraps[3].size(); } return 0; } @@ -465,32 +521,76 @@ uint64 instance_naxxramas::GetData64(uint32 uiData) { switch(uiData) { - case NPC_ANUB_REKHAN: - return m_uiAnubRekhanGUID; - case NPC_FAERLINA: - return m_uiFaerlinanGUID; - case GO_MILI_GOTH_COMBAT_GATE: - return m_uiGothCombatGateGUID; - case NPC_ZELIEK: - return m_uiZeliekGUID; - case NPC_THANE: - return m_uiThaneGUID; - case NPC_BLAUMEUX: - return m_uiBlaumeuxGUID; - case NPC_RIVENDARE: - return m_uiRivendareGUID; - case NPC_THADDIUS: - return m_uiThaddiusGUID; - case NPC_STALAGG: - return m_uiStalaggGUID; - case NPC_FEUGEN: - return m_uiFeugenGUID; - case NPC_GOTHIK: - return m_uiGothikGUID; - case NPC_KELTHUZAD: - return m_uiKelthuzadGUID; + case NPC_ANUB_REKHAN: return m_uiAnubRekhanGUID; + case NPC_FAERLINA: return m_uiFaerlinanGUID; + case GO_MILI_GOTH_COMBAT_GATE: return m_uiGothCombatGateGUID; + case NPC_ZELIEK: return m_uiZeliekGUID; + case NPC_THANE: return m_uiThaneGUID; + case NPC_BLAUMEUX: return m_uiBlaumeuxGUID; + case NPC_RIVENDARE: return m_uiRivendareGUID; + case NPC_THADDIUS: return m_uiThaddiusGUID; + case NPC_STALAGG: return m_uiStalaggGUID; + case NPC_FEUGEN: return m_uiFeugenGUID; + case GO_CONS_NOX_TESLA_FEUGEN: return m_uiThadNoxTeslaFeugenGUID; + case GO_CONS_NOX_TESLA_STALAGG: return m_uiThadNoxTeslaStalaggGUID; + case NPC_GOTHIK: return m_uiGothikGUID; + case NPC_KELTHUZAD: return m_uiKelthuzadGUID; + default: + return 0; + } +} + +void instance_naxxramas::SetSpecialAchievementCriteria(uint32 uiType, bool bIsMet) +{ + if (uiType < MAX_SPECIAL_ACHIEV_CRITS) + m_abAchievCriteria[uiType] = bIsMet; +} + +bool instance_naxxramas::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/) +{ + switch (uiCriteriaId) + { + case ACHIEV_CRIT_SAFETY_DANCE_N: + case ACHIEV_CRIT_SAFETY_DANCE_H: + return m_abAchievCriteria[TYPE_ACHIEV_SAFETY_DANCE]; + case ACHIEV_CRIT_KNOCK_YOU_OUT_N: + case ACHIEV_CRIT_KNOCK_YOU_OUT_H: + return m_abAchievCriteria[TYPE_ACHIEV_KNOCK_YOU_OUT]; + case ACHIEV_CRIT_HUNDRED_CLUB_N: + case ACHIEV_CRIT_HUNDRED_CLUB_H: + return m_abAchievCriteria[TYPE_ACHIEV_HUNDRED_CLUB]; + case ACHIEV_CRIT_SHOCKING_N: + case ACHIEV_CRIT_SHOCKING_H: + return m_abAchievCriteria[TYPE_ACHIEV_SHOCKING]; + case ACHIEV_CRIT_SPORE_LOSER_N: + case ACHIEV_CRIT_SPORE_LOSER_H: + return m_abAchievCriteria[TYPE_ACHIEV_SPORE_LOSER]; + case ACHIEV_CRIT_GET_ENOUGH_N: + case ACHIEV_CRIT_GET_ENOUGH_H: + return m_abAchievCriteria[TYPE_ACHIEV_GET_ENOUGH]; + // 'The Immortal'(25m) or 'Undying'(10m) - (achievs 2186, 2187) + case ACHIEV_CRIT_IMMORTAL_KEL: + case ACHIEV_CRIT_IMMOORTAL_LOA: + case ACHIEV_CRIT_IMMOORTAL_THAD: + case ACHIEV_CRIT_IMMOORTAL_MAEX: + case ACHIEV_CRIT_IMMOORTAL_HORSE: + case ACHIEV_CRIT_UNDYING_KEL: + case ACHIEV_CRIT_UNDYING_HORSE: + case ACHIEV_CRIT_UNDYING_MAEX: + case ACHIEV_CRIT_UNDYING_LOA: + case ACHIEV_CRIT_UNDYING_THAD: + { + // First, check if all bosses are killed (except the last encounter) + uint8 uiEncounterDone = 0; + for (uint8 i = 0; i < TYPE_KELTHUZAD; ++i) + if (m_auiEncounter[i] == DONE) + ++uiEncounterDone; + + return uiEncounterDone >= 14 && GetData(TYPE_UNDYING_FAILED) != DONE; + } + default: + return false; } - return 0; } void instance_naxxramas::SetGothTriggers() @@ -562,6 +662,13 @@ bool instance_naxxramas::IsInRightSideGothArea(Unit* pUnit) return true; } +uint64 instance_naxxramas::GetHeiganTrapData64(uint8 uiAreaIndex, uint32 uiIndex) +{ + if (0 <= uiAreaIndex && uiAreaIndex < MAX_HEIGAN_TRAP_AREAS && uiIndex < m_avuiHeiganTraps[uiAreaIndex].size()) + return m_avuiHeiganTraps[uiAreaIndex].at(uiIndex); + return 0; +} + void instance_naxxramas::SetChamberCenterCoords(float fX, float fY, float fZ) { m_fChamberCenterX = fX; @@ -631,6 +738,21 @@ bool AreaTrigger_at_naxxramas(Player* pPlayer, AreaTriggerEntry const* pAt) } } + if (pAt->id == AREATRIGGER_THADDIUS_DOOR) + { + if (instance_naxxramas* pInstance = (instance_naxxramas*)pPlayer->GetInstanceData()) + { + if (pInstance->GetData(TYPE_THADDIUS) == NOT_STARTED) + { + if (Creature* pThaddius = pInstance->instance->GetCreature(pInstance->GetData64(NPC_THADDIUS))) + { + pInstance->SetData(TYPE_THADDIUS, SPECIAL); + DoScriptText(SAY_THADDIUS_GREET, pThaddius); + } + } + } + } + return false; } diff --git a/scripts/northrend/naxxramas/naxxramas.h b/scripts/northrend/naxxramas/naxxramas.h index 933279a75..723d80ac9 100644 --- a/scripts/northrend/naxxramas/naxxramas.h +++ b/scripts/northrend/naxxramas/naxxramas.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,35 +7,52 @@ enum { - MAX_ENCOUNTER = 15, + MAX_ENCOUNTER = 16, + // A few instance-script related texts + SAY_THADDIUS_GREET = -1533029, // Kel'Thuzad's taunts after killing Wing Bosses SAY_KELTHUZAD_TAUNT1 = -1533090, SAY_KELTHUZAD_TAUNT2 = -1533091, SAY_KELTHUZAD_TAUNT3 = -1533092, SAY_KELTHUZAD_TAUNT4 = -1533093, - TYPE_ANUB_REKHAN = 1, - TYPE_FAERLINA = 2, - TYPE_MAEXXNA = 3, + TYPE_ANUB_REKHAN = 0, + TYPE_FAERLINA = 1, + TYPE_MAEXXNA = 2, - TYPE_NOTH = 4, - TYPE_HEIGAN = 5, - TYPE_LOATHEB = 6, + TYPE_NOTH = 3, + TYPE_HEIGAN = 4, + TYPE_LOATHEB = 5, - TYPE_RAZUVIOUS = 7, - TYPE_GOTHIK = 8, - TYPE_FOUR_HORSEMEN = 9, + TYPE_RAZUVIOUS = 6, + TYPE_GOTHIK = 7, + TYPE_FOUR_HORSEMEN = 8, - TYPE_PATCHWERK = 10, - TYPE_GROBBULUS = 11, - TYPE_GLUTH = 12, - TYPE_THADDIUS = 13, - TYPE_STALAGG = 14, - TYPE_FEUGEN = 15, + TYPE_PATCHWERK = 9, + TYPE_GROBBULUS = 10, + TYPE_GLUTH = 11, + TYPE_THADDIUS = 12, - TYPE_SAPPHIRON = 16, - TYPE_KELTHUZAD = 17, + TYPE_SAPPHIRON = 13, + TYPE_KELTHUZAD = 14, + + TYPE_UNDYING_FAILED = 15, // Achievements Undying and Immortal, needs to be saved to database + + MAX_HEIGAN_TRAP_AREAS = 4, + TYPE_MAX_HEIGAN_TRAPS_1 = 18, + TYPE_MAX_HEIGAN_TRAPS_2 = 19, + TYPE_MAX_HEIGAN_TRAPS_3 = 20, + TYPE_MAX_HEIGAN_TRAPS_4 = 21, + + MAX_SPECIAL_ACHIEV_CRITS = 6, + + TYPE_ACHIEV_SAFETY_DANCE = 0, + TYPE_ACHIEV_KNOCK_YOU_OUT = 1, + TYPE_ACHIEV_HUNDRED_CLUB = 2, + TYPE_ACHIEV_SHOCKING = 3, + TYPE_ACHIEV_SPORE_LOSER = 4, + TYPE_ACHIEV_GET_ENOUGH = 5, NPC_ANUB_REKHAN = 15956, NPC_FAERLINA = 15953, @@ -43,6 +60,7 @@ enum NPC_THADDIUS = 15928, NPC_STALAGG = 15929, NPC_FEUGEN = 15930, + NPC_TESLA_COIL = 16218, NPC_ZELIEK = 16063, NPC_THANE = 16064, @@ -51,6 +69,10 @@ enum NPC_KELTHUZAD = 15990, + // Faerlina + NPC_NAXXRAMAS_FOLLOWER = 16505, + NPC_NAXXRAMAS_WORSHIPPER = 16506, + // Gothik NPC_GOTHIK = 16060, NPC_SUB_BOSS_TRIGGER = 16137, //summon locations @@ -58,7 +80,7 @@ enum NPC_UNREL_DEATH_KNIGHT = 16125, NPC_UNREL_RIDER = 16126, NPC_SPECT_TRAINEE = 16127, - NPC_SPECT_DEATH_KNIGTH = 16148, + NPC_SPECT_DEATH_KNIGHT = 16148, NPC_SPECT_RIDER = 16150, NPC_SPECT_HORSE = 16149, @@ -98,6 +120,8 @@ enum GO_CONS_PATH_EXIT_DOOR = 181123, GO_CONS_GLUT_EXIT_DOOR = 181120, GO_CONS_THAD_DOOR = 181121, // Thaddius enc door + GO_CONS_NOX_TESLA_FEUGEN = 181477, + GO_CONS_NOX_TESLA_STALAGG = 181478, // Frostwyrm Lair GO_KELTHUZAD_WATERFALL_DOOR = 181225, // exit, open after sapphiron is dead @@ -115,9 +139,38 @@ enum GO_MILI_PORTAL = 181578, GO_CONS_PORTAL = 181576, - AREATRIGGER_FROSTWYRM = 4120, //not needed here, but AT to be scripted + AREATRIGGER_FROSTWYRM = 4120, // not needed here, but AT to be scripted AREATRIGGER_KELTHUZAD = 4112, - AREATRIGGER_GOTHIK = 4116 + AREATRIGGER_GOTHIK = 4116, + AREATRIGGER_THADDIUS_DOOR = 4113, + + // Achievement-related + ACHIEV_START_PATCHWERK_ID = 10286, + + ACHIEV_CRIT_SAFETY_DANCE_N = 7264, // Heigan, achievs 1996, 2139 + ACHIEV_CRIT_SAFETY_DANCE_H = 7548, + ACHIEV_CRIT_KNOCK_YOU_OUT_N = 7265, // Faerlina, achievs 1997, 2140 + ACHIEV_CRIT_KNOCK_YOU_OUT_H = 7549, + ACHIEV_CRIT_HUNDRED_CLUB_N = 7567, // Sapphiron, achievs 2146, 2147 + ACHIEV_CRIT_HUNDRED_CLUB_H = 7568, + ACHIEV_CRIT_SHOCKING_N = 7604, // Thaddius, achievs 2178, 2179 + ACHIEV_CRIT_SHOCKING_H = 7605, + ACHIEV_CRIT_SPORE_LOSER_N = 7612, // Loatheb, achievs 2182, 2183 + ACHIEV_CRIT_SPORE_LOSER_H = 7613, + ACHIEV_CRIT_GET_ENOUGH_N = 7614, // Kel'Thuzad, achievs 2184, 2185 + ACHIEV_CRIT_GET_ENOUGH_H = 7615, + + // 'The Immortal'(25m) or 'Undying'(10m) - (achievs 2186, 2187) + ACHIEV_CRIT_IMMORTAL_KEL = 7616, + ACHIEV_CRIT_IMMOORTAL_LOA = 13236, + ACHIEV_CRIT_IMMOORTAL_THAD = 13235, + ACHIEV_CRIT_IMMOORTAL_MAEX = 13234, + ACHIEV_CRIT_IMMOORTAL_HORSE = 13233, + ACHIEV_CRIT_UNDYING_KEL = 7617, + ACHIEV_CRIT_UNDYING_HORSE = 13237, + ACHIEV_CRIT_UNDYING_MAEX = 13238, + ACHIEV_CRIT_UNDYING_LOA = 13239, + ACHIEV_CRIT_UNDYING_THAD = 13240, }; struct GothTrigger @@ -139,10 +192,15 @@ class MANGOS_DLL_DECL instance_naxxramas : public ScriptedInstance void OnCreatureCreate(Creature* pCreature); void OnObjectCreate(GameObject* pGo); + void OnPlayerDeath(Player* pPlayer); + void SetData(uint32 uiType, uint32 uiData); uint32 GetData(uint32 uiType); uint64 GetData64(uint32 uiData); + void SetSpecialAchievementCriteria(uint32 uiType, bool bIsMet); + bool CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/); + const char* Save() { return strInstData.c_str(); } void Load(const char* chrIn); @@ -152,13 +210,20 @@ class MANGOS_DLL_DECL instance_naxxramas : public ScriptedInstance void GetGothSummonPointCreatures(std::list &lList, bool bRightSide); bool IsInRightSideGothArea(Unit* pUnit); + // Heigan + uint64 GetHeiganTrapData64(uint8 uiAreaIndex, uint32 uiIndex); + + // thaddius + void GetThadTeslaCreatures(std::list &lList){ lList = m_lThadTeslaCoilList; }; + // kel void SetChamberCenterCoords(float fX, float fY, float fZ); void GetChamberCenterCoords(float &fX, float &fY, float &fZ) { fX = m_fChamberCenterX; fY = m_fChamberCenterY; fZ = m_fChamberCenterZ; } void DoTaunt(); - + protected: uint32 m_auiEncounter[MAX_ENCOUNTER]; + bool m_abAchievCriteria[MAX_SPECIAL_ACHIEV_CRITS]; std::string strInstData; uint64 m_uiAracEyeRampGUID; @@ -187,7 +252,11 @@ class MANGOS_DLL_DECL instance_naxxramas : public ScriptedInstance uint64 m_uiPathExitDoorGUID; uint64 m_uiGlutExitDoorGUID; + uint64 m_uiThadDoorGUID; + std::list m_lThadTeslaCoilList; + uint64 m_uiThadNoxTeslaFeugenGUID; + uint64 m_uiThadNoxTeslaStalaggGUID; uint64 m_uiAnubDoorGUID; uint64 m_uiAnubGateGUID; @@ -195,6 +264,7 @@ class MANGOS_DLL_DECL instance_naxxramas : public ScriptedInstance uint64 m_uiFaerWebGUID; uint64 m_uiMaexOuterGUID; uint64 m_uiMaexInnerGUID; + std::list m_lFaerlinaAddGUIDs; uint64 m_uiGothikGUID; uint64 m_uiGothCombatGateGUID; @@ -211,6 +281,7 @@ class MANGOS_DLL_DECL instance_naxxramas : public ScriptedInstance uint64 m_uiHeigEntryDoorGUID; uint64 m_uiHeigExitDoorGUID; uint64 m_uiLoathebDoorGUID; + std::vector m_avuiHeiganTraps[MAX_HEIGAN_TRAP_AREAS]; uint64 m_uiKelthuzadDoorGUID; uint64 m_uiKelthuzadExitDoorGUID; diff --git a/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp b/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp new file mode 100644 index 000000000..4b1d8123f --- /dev/null +++ b/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp @@ -0,0 +1,1608 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Boss_Malygos +SD%Complete: 98% +SDComment: Hacks, hacks, hacks... +SDAuthor: Tasssadar + PSZ + some corrections from MaxXx2021 and /dev/rsa +SDCategory: Nexus, Eye of Eternity +EndScriptData */ + +#include "precompiled.h" +#include "eye_of_eternity.h" +#include "Vehicle.h" + +enum +{ + // ******************************** SPELLS ******************************** // + SPELL_BERSERK = 64238, + + //////////////// PHASE 0 //////////////// + SPELL_PORTAL_BEAM = 56046, + + //////////////// PHASE 1 //////////////// + SPELL_ARCANE_BREATH = 56272, + SPELL_ARCANE_BREATH_H = 60072, + SPELL_ARCANE_STORM = 61693, + SPELL_ARCANE_STORM_H = 61694, + SPELL_VORTEX = 56105, + SPELL_VORTEX_DMG_AURA = 56266, // on 10 sec, deal 2000 damage all player around caster + SPELL_VORTEX_VISUAL = 55873, // visual effect around platform. summon trigger + SPELL_VORTEX_CHANNEL = 56237, // Malygos Channel Effect + SPELL_POWER_SPARK = 56152, // if spark reach malygos then buff him + SPELL_POWER_SPARK_PLAYERS = 55852, // if spark is killed - buff players in area + SPELL_POWER_SPARK_VISUAL = 55845, + + //////////////// PHASE 2 //////////////// + SPELL_ARCANE_BOMB_MISSILE = 56430, + SPELL_ARCANE_BOMB_DAMAGE = 56431, // cast by arcane overload + SPELL_ARCANE_OVERLOAD = 56432, // cast this on arcane overload NPCs + SPELL_SURGE_OF_POWER_BREATH = 56505, // omfg, they say deep breath, but its this! + SPELL_DESTROY_PLATFORM_PRE = 58842, // lights all over the platform + SPELL_DESTROY_PLATFORM_BOOM = 59084, // Big Blue boom + //NPCs spells + SPELL_ARCANE_SHOCK = 57058, + SPELL_ARCANE_SHOCK_H = 60073, + SPELL_HASTE = 57060, + SPELL_ARCANE_BARRAGE = 50804, // hack, right spell is 56397 + + //////////////// PHASE 3 //////////////// + SPELL_STATIC_FIELD_MISSILE = 57430, + SPELL_STATIC_FIELD = 57428, + SPELL_SURGE_OF_POWER = 57407, // this is on one target + SPELL_SURGE_OF_POWER_H = 60936, // this is on unlimited tagets, must limit it in mangos + SPELL_ARCANE_PULSE = 57432, + + SPELL_ALEXSTRASZAS_GIFT_BEAM = 61028, + SPELL_ALEXSTRASZAS_GIFT_VISUAL = 61023, + + // ******************************** Items, NPCs & GameObjects ******************************** // + + ITEM_KEY_TO_FOCUSING_IRIS = 44582, + ITEM_KEY_TO_FOCUSING_IRIS_H = 44581, + + //////////////// PHASE 1 //////////////// + NPC_VORTEX = 30090, + NPC_POWER_SPARK = 30084, + NPC_SPARK_PORTAL = 30118, // for power sparks + VEHICLE_VORTEX = 168, + + //////////////// PHASE 2 //////////////// + NPC_HOVER_DISK = 30248, + NPC_NEXUS_LORD = 30245, // 2 (normal) and 4 (heroic) of them are spawned on beginning of phase 2 + NPC_SCION_OF_ETERNITY = 30249, // 4 (normal) and 8 (heroic) of them are spawned on beginning of phase 2 + NPC_ARCANE_OVERLOAD = 30282, + NPC_SURGE_OF_POWER = 30334, + + //////////////// PHASE 3 //////////////// + NPC_STATIC_FIELD = 30592, // trigger for that spell + NPC_WYRMREST_SKYTALON = 30161, // dragon vehicle in 3-d Phase + NPC_ALEXSTRASZA = 32295, + NPC_ALEXSTRASZAS_GIFT = 32448, + + SPELL_CALL_SKYTALON = 58846, + SPELL_CALL_SKYTALON_0 = 56070, + SPELL_VEHICLE_HARDCODED = 46598, + + SAY_INTRO1 = -1616000, + SAY_INTRO2 = -1616001, + SAY_INTRO3 = -1616002, + SAY_INTRO4 = -1616003, + SAY_INTRO5 = -1616004, + SAY_INTRO_PHASE3 = -1616018, + SAY_AGGRO1 = -1616005, + SAY_AGGRO2 = -1616013, + SAY_AGGRO3 = -1616019, + SAY_VORTEX = -1616006, + SAY_POWER_SPARK = -1616035, + SAY_POWER_SPARK_BUFF = -1616007, + SAY_KILL1_1 = -1616008, + SAY_KILL1_2 = -1616009, + SAY_KILL1_3 = -1616010, + SAY_KILL2_1 = -1616020, + SAY_KILL2_2 = -1616021, + SAY_KILL2_3 = -1616022, + SAY_KILL3_1 = -1616023, + SAY_KILL3_2 = -1616024, + SAY_KILL3_3 = -1616025, + SAY_END_PHASE1 = -1616012, + SAY_END_PHASE2 = -1616017, + SAY_ARCANE_PULSE = -1616014, + SAY_ARCANE_PULSE_WARN = -1616015, + SAY_ARCANE_OVERLOAD = -1616016, + SAY_SURGE_OF_POWER = -1616026, + SAY_CAST_SPELL1 = -1616027, + SAY_CAST_SPELL2 = -1616028, + SAY_CAST_SPELL3 = -1616029, + SAY_DEATH = -1616030, + // Alexstrasza + SAY_OUTRO1 = -1616031, + SAY_OUTRO2 = -1616032, + SAY_OUTRO3 = -1616033, + SAY_OUTRO4 = -1616034, + + PLATFORM_MIN_X = 722, + PLATFORM_MAX_X = 768, + PLATFORM_MIN_Y = 1290, + PLATFORM_MAX_Y = 1339, + + NEXUS_LORD_COUNT = 2, + NEXUS_LORD_COUNT_H = 4, + SCION_OF_ETERNITY_COUNT = 4, + SCION_OF_ETERNITY_COUNT_H = 8, + + PHASE_INTRO = 0, + PHASE_FLOOR = 1, + SUBPHASE_VORTEX = 11, + PHASE_ADDS = 2, + SUBPHASE_TALK = 21, + SUBPHASE_DEEP_BREATH = 22, + PHASE_DRAGONS = 3, + SUBPHASE_DESTROY_PLATFORM_1 = 31, + SUBPHASE_DESTROY_PLATFORM_2 = 32, + SUBPHASE_DESTROY_PLATFORM_3 = 33, + SUBPHASE_DESTROY_PLATFORM_4 = 34, + SUBPHASE_SURGE_OF_POWER = 35, + + POINT_ID_WAYPOINT = 1, + POINT_ID_LAND = 2, + POINT_ID_VORTEX_AIR = 3, + POINT_ID_PHASE_2_WP = 4, + POINT_ID_DEEP_BREATH = 5, + + //hacks + SPELL_FLIGHT = 59553, + MODEL_ID_INVISIBLE = 11686 +}; + +struct LocationsXY +{ + float x, y; +}; + +static LocationsXY WPs[]= +{ + {810.0f, 1248.0f}, + {810.0f, 1358.0f}, + {700.0f, 1358.0f}, + {700.0f, 1248.0f}, +}; + +//Also spawn locations for scions of eternity +static LocationsXY VortexLoc[]= +{ + {754, 1311}, + {739, 1325}, + {755, 1330}, + {774, 1321}, + {781, 1308}, + {779, 1288}, + {764, 1274}, + {744, 1274}, + {730, 1286}, + {726, 1299}, + {728, 1312}, + {739, 1325}, + {755, 1330}, + {774, 1321}, + {781, 1308}, + {779, 1288}, + {764, 1274}, + {744, 1274}, + {730, 1286}, + {726, 1299}, + {728, 1312}, +}; + +#define MAX_VORTEX 21 + +#define CENTER_X 754.50f +#define CENTER_Y 1301.76f +#define FLOOR_Z 266.17f +#define AIR_Z 296.17f +#define VORTEX_FARSIGHT_X 749.00f +#define VORTEX_FARSIGHT_Y 1244.00f +#define VORTEX_FARSIGHT_Z 332.00f +#define VORTEX_FARSIGHT_O 1.54f + +/*###### +## boss_malygos +######*/ + +struct MANGOS_DLL_DECL boss_malygosAI : public ScriptedAI +{ + boss_malygosAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint8 m_uiPhase; + uint8 m_uiSubPhase; + uint8 m_uiSpeechCount; + uint32 m_uiSpeechTimer; + uint32 m_uiPortalNeedResTimer; + uint8 m_uiVortexPhase; + std::list m_lSparkPortalGUIDList; + + uint32 m_uiTimer; + uint32 m_uiEnrageTimer; + uint32 m_uiVortexTimer; + uint32 m_uiArcaneBreathTimer; + uint32 m_uiPowerSparkTimer; + uint32 m_uiDeepBreathTimer; + uint32 m_uiShellTimer; + uint32 m_uiArcaneStormTimer; + uint32 m_uiStaticFieldTimer; + uint32 m_uiArcanePulseTimer; + uint32 m_uiSurgeOfPowerTimer; + uint32 m_uiCheckTimer; + uint32 m_uiMovingSteps; + + uint64 m_uiTargetSparkPortalGUID; + uint8 m_uiWP; + + bool m_bReadyForWPMove; + bool m_bPortalNeedRes; + + float m_fAngle; + + void Reset() + { + m_fAngle = 0.0f; + m_uiMovingSteps = 0; + m_bReadyForWPMove = true; + m_bPortalNeedRes = false; + m_uiPortalNeedResTimer = 0; + m_uiPhase = PHASE_INTRO; + m_uiSubPhase = 0; + m_uiVortexPhase = 0; + m_uiTimer = 0; + m_uiEnrageTimer = 600000; + m_uiArcaneBreathTimer = urand(13000, 16000); + m_uiArcaneStormTimer = urand(10000, 15000); + m_uiVortexTimer = 60000; + m_uiPowerSparkTimer = urand(20000, 30000); + m_uiDeepBreathTimer = 65000; + m_uiShellTimer = 0; + m_uiStaticFieldTimer = 10000; + m_uiArcanePulseTimer = 1000; + m_uiSurgeOfPowerTimer = 8000; + m_uiCheckTimer = 1000; + + m_uiTargetSparkPortalGUID = 0; + m_uiWP = 0; + m_uiSpeechCount = 0; + m_uiSpeechTimer = 15000; + m_creature->SetSpeedRate(MOVE_RUN, 2.85714f); + m_creature->SetSpeedRate(MOVE_WALK, 6.0f); + m_creature->SetSpeedRate(MOVE_FLIGHT, 2.0f); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->GetMotionMaster()->Clear(); + + DespawnCreatures(NPC_POWER_SPARK); + DespawnCreatures(NPC_ARCANE_OVERLOAD); + DespawnCreatures(NPC_NEXUS_LORD); + DespawnCreatures(NPC_SCION_OF_ETERNITY); + DespawnCreatures(NPC_HOVER_DISK); + DespawnCreatures(NPC_STATIC_FIELD); + + if (!m_lSparkPortalGUIDList.empty()) + for (std::list::iterator itr = m_lSparkPortalGUIDList.begin(); itr != m_lSparkPortalGUIDList.end(); ++itr) + if (Creature* pSparkPortal = m_creature->GetMap()->GetCreature(*itr)) + pSparkPortal->Respawn(); + + m_lSparkPortalGUIDList.clear(); + + if (m_pInstance) + m_pInstance->SetData(TYPE_MALYGOS, NOT_STARTED); + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_AGGRO1, m_creature); + std::list lSparkPortalList; + GetCreatureListWithEntryInGrid(lSparkPortalList, m_creature, NPC_SPARK_PORTAL, 200.0f); + if (!lSparkPortalList.empty()) + for (std::list::iterator itr = lSparkPortalList.begin(); itr != lSparkPortalList.end(); ++itr) + if (*itr) + m_lSparkPortalGUIDList.push_back((*itr)->GetGUID()); + + if (m_pInstance) + m_pInstance->SetData(TYPE_MALYGOS, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + DespawnCreatures(NPC_STATIC_FIELD); + m_creature->SummonCreature(NPC_ALEXSTRASZA, CENTER_X+20.0f, CENTER_Y+20.0f, AIR_Z, 0, TEMPSUMMON_DEAD_DESPAWN, 0); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), FLOOR_Z-500.0f, 0); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), FLOOR_Z-400.0f, SPLINETYPE_NORMAL , m_creature->GetSplineFlags(), 10000); + } + + void KilledUnit(Unit* pVictim) + { + uint8 uiText = 0; + switch (m_uiPhase) + { + case PHASE_FLOOR: uiText = urand(0, 2); break; + case PHASE_ADDS: uiText = urand(3, 5); break; + case PHASE_DRAGONS: uiText = urand(6, 8); break; + } + switch (uiText) + { + case 0: DoScriptText(SAY_KILL1_1, m_creature); break; + case 1: DoScriptText(SAY_KILL1_2, m_creature); break; + case 2: DoScriptText(SAY_KILL1_3, m_creature); break; + case 3: DoScriptText(SAY_KILL2_1, m_creature); break; + case 4: DoScriptText(SAY_KILL2_2, m_creature); break; + case 5: DoScriptText(SAY_KILL2_3, m_creature); break; + case 6: DoScriptText(SAY_KILL3_1, m_creature); break; + case 7: DoScriptText(SAY_KILL3_2, m_creature); break; + case 8: DoScriptText(SAY_KILL3_3, m_creature); break; + } + } + + void SpellHit(Unit* pCaster, const SpellEntry* pSpell) + { + if (pSpell->Id == SPELL_POWER_SPARK) + DoScriptText(SAY_POWER_SPARK_BUFF, m_creature); + } + + void SpellHitTarget(Unit* pUnit, const SpellEntry* pSpell) + { + if (pUnit->GetEntry() == NPC_ARCANE_OVERLOAD && pSpell->Id == SPELL_ARCANE_BOMB_MISSILE) + { + pUnit->CastSpell(pUnit, SPELL_ARCANE_BOMB_DAMAGE, true); + pUnit->CastSpell(pUnit, SPELL_ARCANE_OVERLOAD, false, 0, 0, m_creature->GetGUID()); + pUnit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + void JustSummoned(Creature* pSummoned) + { + uint32 uiEntry = pSummoned->GetEntry(); + if (uiEntry == NPC_VORTEX || uiEntry == NPC_STATIC_FIELD) + pSummoned->SetDisplayId(MODEL_ID_INVISIBLE); + + if (uiEntry == NPC_STATIC_FIELD) + { + pSummoned->CastSpell(m_creature, SPELL_STATIC_FIELD, false, 0, 0, m_creature->GetGUID()); + pSummoned->ForcedDespawn(30000); + } + + if (uiEntry == NPC_NEXUS_LORD || uiEntry == NPC_SCION_OF_ETERNITY) + { + if (Creature* pDisk = pSummoned->SummonCreature(NPC_HOVER_DISK, pSummoned->GetPositionX(), pSummoned->GetPositionY(), pSummoned->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0)) + { + pDisk->SetSplineFlags(SPLINEFLAG_FLYING); + pDisk->CastSpell(pDisk, SPELL_FLIGHT, true); + if (uiEntry == NPC_NEXUS_LORD) + pDisk->SetSpeedRate(MOVE_WALK, 1.5f); + if (VehicleKit* pDiskVehicle = pDisk->GetVehicleKit()) + pSummoned->EnterVehicle(pDiskVehicle, 0); + } + pSummoned->SetInCombatWithZone(); + } + } + + void SummonedCreatureJustDied(Creature* pSummoned) + { + if (Creature* pDisk = m_creature->getVictim()->SummonCreature(NPC_HOVER_DISK, pSummoned->GetPositionX(), pSummoned->GetPositionY(), pSummoned->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0)) + { + pDisk->setFaction(35); + pDisk->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + pDisk->CastSpell(pDisk, SPELL_FLIGHT, true); + pDisk->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + } + + bool IsThereAnyAdd() + { + if (GetClosestCreatureWithEntry(m_creature, NPC_NEXUS_LORD, 200.0f)) + return true; + + if (GetClosestCreatureWithEntry(m_creature, NPC_SCION_OF_ETERNITY, 200.0f)) + return true; + + return false; + } + + void DespawnCreatures(uint32 uiEntry) + { + std::list pCreatures; + GetCreatureListWithEntryInGrid(pCreatures, m_creature, uiEntry, 200.0f); + + if (pCreatures.empty()) + return; + + for (std::list::iterator iter = pCreatures.begin(); iter != pCreatures.end(); ++iter) + (*iter)->ForcedDespawn(); + } + + void AntiMagicShell() + { + if (Creature* pShell = m_creature->SummonCreature(NPC_ARCANE_OVERLOAD, urand(PLATFORM_MIN_X, PLATFORM_MAX_X), urand(PLATFORM_MIN_Y, PLATFORM_MAX_Y), FLOOR_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 45000)) + { + pShell->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->CastSpell(pShell, SPELL_ARCANE_BOMB_MISSILE, true); + } + } + + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if (uiType != POINT_MOTION_TYPE) + return; + + if (uiPointId == POINT_ID_WAYPOINT) + { + if (Creature* pSparkPortal = GetClosestCreatureWithEntry(m_creature, NPC_SPARK_PORTAL, 100.0f)) + { + m_creature->SetFacingToObject(pSparkPortal); + m_creature->CastSpell(pSparkPortal, SPELL_PORTAL_BEAM, true); + m_uiTargetSparkPortalGUID = pSparkPortal->GetGUID(); + } + + m_bReadyForWPMove = true; + m_uiTimer = 15000; + } + else if (uiPointId == POINT_ID_LAND) + { + if (Creature* pTargetSparkPortal = m_creature->GetMap()->GetCreature(m_uiTargetSparkPortalGUID)) + pTargetSparkPortal->Respawn(); + + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_uiPhase = PHASE_FLOOR; + m_creature->SetInCombatWithZone(); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(pTarget); + } + } + else if (uiPointId == POINT_ID_VORTEX_AIR) + { + if (Creature* pTempVortexVisual = m_creature->SummonCreature(NPC_VORTEX, CENTER_X, CENTER_Y, FLOOR_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000)) + { + //hacks to make Malygos not to turn during Vortex + pTempVortexVisual->SetMaxHealth(1000000); + pTempVortexVisual->SetHealth(1000000); + pTempVortexVisual->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + pTempVortexVisual->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTempVortexVisual->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pTempVortexVisual->setFaction(85); + m_creature->AddThreat(pTempVortexVisual, 1000000000.0f); + + pTempVortexVisual->CastSpell(pTempVortexVisual, SPELL_VORTEX_VISUAL, true); + } + + ++m_uiVortexPhase; + m_uiTimer = 0; + } + else if (uiPointId == POINT_ID_PHASE_2_WP) + { + m_bReadyForWPMove = true; + if (m_uiSubPhase == SUBPHASE_TALK) + { + DoScriptText(SAY_AGGRO2, m_creature); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + AntiMagicShell(); + m_uiShellTimer = urand(15000, 17000); + m_uiSubPhase = 0; + for (uint8 i = 0; i < (m_bIsRegularMode ? NEXUS_LORD_COUNT : NEXUS_LORD_COUNT_H); ++i) + m_creature->SummonCreature(NPC_NEXUS_LORD, urand(PLATFORM_MIN_X, PLATFORM_MAX_X), urand(PLATFORM_MIN_Y, PLATFORM_MAX_Y), FLOOR_Z+10.0f+urand(0, 15), 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + for (uint8 i = 0; i < (m_bIsRegularMode ? SCION_OF_ETERNITY_COUNT : SCION_OF_ETERNITY_COUNT_H); ++i) + m_creature->SummonCreature(NPC_SCION_OF_ETERNITY, urand(PLATFORM_MIN_X, PLATFORM_MAX_X), urand(PLATFORM_MIN_Y, PLATFORM_MAX_Y), FLOOR_Z+10.0f+urand(0, 15), 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + m_uiTimer = 5000; + return; + } + m_uiTimer = 0; + } + else if (uiPointId == POINT_ID_DEEP_BREATH) + { + DoScriptText(SAY_ARCANE_PULSE, m_creature); + DoScriptText(SAY_ARCANE_PULSE_WARN, m_creature); + + if (Creature* pTemp = m_creature->SummonCreature(NPC_VORTEX, CENTER_X, CENTER_Y, FLOOR_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000)) + m_creature->CastSpell(m_creature, SPELL_SURGE_OF_POWER_BREATH, false, 0, 0, pTemp->GetGUID()); + + m_uiShellTimer = urand(2000, 4000); + m_bReadyForWPMove = true; + m_uiTimer = 10000; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_bPortalNeedRes) + { + if (m_uiPortalNeedResTimer <= uiDiff) + { + if (Creature* pTargetSparkPortal = m_creature->GetMap()->GetCreature(m_uiTargetSparkPortalGUID)) + pTargetSparkPortal->Respawn(); + + m_bPortalNeedRes = false; + } + else + m_uiPortalNeedResTimer -= uiDiff; + } + + if (m_uiPhase == PHASE_INTRO && m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) + { + if (m_bReadyForWPMove) + { + if (m_uiTimer <= uiDiff) + { + if (Creature* pTargetSparkPortal = m_creature->GetMap()->GetCreature(m_uiTargetSparkPortalGUID)) + { + pTargetSparkPortal->ForcedDespawn(); + m_bPortalNeedRes = true; + m_uiPortalNeedResTimer = 0; + } + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(POINT_ID_WAYPOINT, WPs[m_uiWP].x, WPs[m_uiWP].y, AIR_Z); + m_bReadyForWPMove = false; + ++m_uiWP; + if (m_uiWP == 4) + m_uiWP = 0; + } + else + m_uiTimer -= uiDiff; + } + + if (m_uiSpeechTimer <= uiDiff) + { + switch(m_uiSpeechCount) + { + case 0: + { + DoScriptText(SAY_INTRO1, m_creature); + m_uiSpeechTimer = 22000; + break; + } + case 1: + { + DoScriptText(SAY_INTRO2, m_creature); + m_uiSpeechTimer = 24000; + break; + } + case 2: + { + DoScriptText(SAY_INTRO3, m_creature); + m_uiSpeechTimer = 26000; + break; + } + case 3: + { + DoScriptText(SAY_INTRO4, m_creature); + m_uiSpeechTimer = 23000; + break; + } + case 4: + { + DoScriptText(SAY_INTRO5, m_creature); + m_uiSpeechTimer = 120000; + break; + } + } + ++m_uiSpeechCount; + if (m_uiSpeechCount == 5) + m_uiSpeechCount = 0; + } + else + m_uiSpeechTimer -= uiDiff; + + return; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEnrageTimer <= uiDiff) + { + SetCombatMovement(true); + DoCast(m_creature, SPELL_BERSERK, true); + m_uiEnrageTimer = 600000; + m_creature->GetMotionMaster()->Clear(false, true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + else + m_uiEnrageTimer -= uiDiff; + + if (m_uiPhase == PHASE_FLOOR) + { + if (m_uiSubPhase == SUBPHASE_VORTEX) + { + if (m_uiVortexPhase > 0 && m_uiTimer <= uiDiff) + { + if (m_uiVortexPhase == 3) + { + Creature* pVortex = m_creature->SummonCreature(NPC_VORTEX, VORTEX_FARSIGHT_X, VORTEX_FARSIGHT_Y, VORTEX_FARSIGHT_Z, VORTEX_FARSIGHT_O, TEMPSUMMON_TIMED_DESPAWN, 15000); + Map* pMap = m_creature->GetMap(); + if (pMap && pVortex) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + if (itr->getSource()->isDead()) + continue; + + //Far sight, should be vehicle but this is enough + //Crash the server in group update far members, dunno why + //I will try to use this again, maybe I have fix... + itr->getSource()->GetCamera().SetView(pVortex); + itr->getSource()->CastSpell(itr->getSource(), SPELL_VORTEX_DMG_AURA, true); + } + } + //DoCast(m_creature, SPELL_VORTEX); + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); + DoCast(m_creature, SPELL_VORTEX_CHANNEL); + } + else if (m_uiVortexPhase > 3 && m_uiVortexPhase < MAX_VORTEX+3) + { + Map* pMap = m_creature->GetMap(); + if (pMap) + { + if (Creature *pVortex = m_creature->SummonCreature(NPC_VORTEX, VortexLoc[m_uiVortexPhase-4].x, VortexLoc[m_uiVortexPhase-4].y, FLOOR_Z+urand(10, 25), 0, TEMPSUMMON_TIMED_DESPAWN, 3000)) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + if (itr->getSource()->isDead()) + continue; + + itr->getSource()->KnockBackFrom(pVortex, -float(pVortex->GetDistance2d(itr->getSource())), 7); + } + } + } + } + else if (m_uiVortexPhase == MAX_VORTEX+3) + { + m_creature->RemoveAurasDueToSpell(SPELL_VORTEX_CHANNEL); + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + Map* pMap = m_creature->GetMap(); + if (pMap) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + if (itr->getSource()->isDead()) + continue; + itr->getSource()->GetCamera().SetView(itr->getSource()); + itr->getSource()->NearTeleportTo(CENTER_X, CENTER_Y, FLOOR_Z+20.0f, 0); + } + } + } + else if (m_uiVortexPhase == MAX_VORTEX+9) + { + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + m_uiSubPhase = 0; + m_creature->GetMotionMaster()->Clear(); + if (Unit* pTarget = m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(pTarget); + SetCombatMovement(true); + if (m_pInstance) + m_pInstance->SetData(TYPE_MALYGOS, IN_PROGRESS); + } + ++m_uiVortexPhase; + m_uiTimer = 500; + } + else + m_uiTimer -= uiDiff; + return; + } + + if (m_uiArcaneBreathTimer <= uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_ARCANE_BREATH : SPELL_ARCANE_BREATH_H); + m_uiArcaneBreathTimer = urand(13000, 16000); + } + else + m_uiArcaneBreathTimer -= uiDiff; + + if (m_uiArcaneStormTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_STORM : SPELL_ARCANE_STORM_H); + m_uiArcaneStormTimer = urand(10000, 15000); + } + else + m_uiArcaneStormTimer -= uiDiff; + + if (m_uiPowerSparkTimer <= uiDiff) + { + DoScriptText(SAY_POWER_SPARK, m_creature); + std::list::iterator pTargetSparkPortalGUID = m_lSparkPortalGUIDList.begin(); + advance(pTargetSparkPortalGUID, urand(0, m_lSparkPortalGUIDList.size()-1)); + if (Creature* pTargetSparkPortal = m_creature->GetMap()->GetCreature(*pTargetSparkPortalGUID)) + if (Creature *pSpark = pTargetSparkPortal->SummonCreature(NPC_POWER_SPARK, pTargetSparkPortal->GetPositionX(), pTargetSparkPortal->GetPositionY(), pTargetSparkPortal->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) + { + pTargetSparkPortal->CastSpell(pTargetSparkPortal, SPELL_PORTAL_BEAM, true); + m_uiTargetSparkPortalGUID = pTargetSparkPortal->GetGUID(); + pTargetSparkPortal->ForcedDespawn(19500); + m_uiPortalNeedResTimer = 19600; + m_bPortalNeedRes = true; + } + m_uiPowerSparkTimer = urand(20000, 30000); + } + else + m_uiPowerSparkTimer -= uiDiff; + + if (m_uiVortexTimer <= uiDiff) + { + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + SetCombatMovement(false); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(POINT_ID_VORTEX_AIR, CENTER_X, CENTER_Y, AIR_Z); + m_uiSubPhase = SUBPHASE_VORTEX; + m_uiVortexPhase = 0; + m_uiVortexTimer = 60000; + DoScriptText(SAY_VORTEX, m_creature); + if (m_pInstance) + m_pInstance->SetData(TYPE_MALYGOS, SPECIAL); + return; + } + else + m_uiVortexTimer -= uiDiff; + + if (m_uiTimer <= uiDiff) + { + if (m_creature->GetHealthPercent() <= 50.0f) + { + m_creature->InterruptNonMeleeSpells(true); + DoScriptText(SAY_END_PHASE1, m_creature); + DespawnCreatures(NPC_POWER_SPARK); + m_uiPhase = PHASE_ADDS; + m_uiSubPhase = SUBPHASE_TALK; + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + SetCombatMovement(false); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, AIR_Z); + m_bReadyForWPMove = false; + m_uiTimer = 23000; + return; + } + m_uiTimer = 2000; + } + else + m_uiTimer -= uiDiff; + } + else if (m_uiPhase == PHASE_ADDS) + { + if (m_uiSubPhase == SUBPHASE_TALK) + { + if (m_uiTimer <= uiDiff) + { + m_creature->SetSpeedRate(MOVE_RUN, 6.0f); + m_creature->GetMotionMaster()->Clear(); + m_uiWP = urand(0, 3); + m_creature->GetMotionMaster()->MovePoint(POINT_ID_PHASE_2_WP, WPs[m_uiWP].x, WPs[m_uiWP].y, AIR_Z); + m_uiTimer = 15000; + } + else + m_uiTimer -= uiDiff; + + return; + } + + if (m_uiCheckTimer <= uiDiff) + { + if (!IsThereAnyAdd()) + { + m_creature->StopMoving(); + m_uiPhase = PHASE_DRAGONS; + m_uiSubPhase = SUBPHASE_DESTROY_PLATFORM_1; + DoScriptText(SAY_END_PHASE2, m_creature); + if (Creature* pTempTarget = m_creature->SummonCreature(NPC_VORTEX, CENTER_X, CENTER_Y, FLOOR_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 7000)) + { + pTempTarget->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.5f); + pTempTarget->CastSpell(pTempTarget, SPELL_DESTROY_PLATFORM_PRE, false); + } + m_uiTimer = 6000; + } + + Map* pMap = m_creature->GetMap(); + if (pMap) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + Player* pPlayer = itr->getSource(); + if (pPlayer->GetVehicle() && m_uiPhase == PHASE_ADDS) + pPlayer->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_ARCANE, true); + else + pPlayer->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_ARCANE, false); + } + } + + if (m_uiPhase == PHASE_DRAGONS) + return; + + m_uiCheckTimer = 1000; + } + else + m_uiCheckTimer -= uiDiff; + + if (m_bReadyForWPMove) + { + if (m_uiTimer <= uiDiff) + { + m_creature->GetMotionMaster()->Clear(); + if (m_uiSubPhase == SUBPHASE_DEEP_BREATH) + { + m_uiWP = urand(0, 3); + m_creature->GetMotionMaster()->MovePoint(POINT_ID_PHASE_2_WP, WPs[m_uiWP].x, WPs[m_uiWP].y, AIR_Z); + } + else + { + float fAng = M_PI/4 + m_creature->GetAngle(CENTER_X, CENTER_Y); + m_creature->GetMotionMaster()->MovePoint(POINT_ID_PHASE_2_WP, CENTER_X-80.0f*cos(fAng), CENTER_Y-80.0f*sin(fAng), AIR_Z); + } + m_uiSubPhase = 0; + m_bReadyForWPMove = false; + } + else + m_uiTimer -= uiDiff; + } + + if (m_uiSubPhase != SUBPHASE_DEEP_BREATH && m_uiShellTimer <= uiDiff) + { + m_creature->GetMotionMaster()->Clear(); + m_creature->StopMoving(); + + if (!urand(0, 3)) + DoScriptText(SAY_ARCANE_OVERLOAD, m_creature); + + AntiMagicShell(); + m_uiShellTimer = urand(15000, 17000); + m_bReadyForWPMove = true; + m_uiTimer = 2000; + } + else + m_uiShellTimer -= uiDiff; + + if (m_uiDeepBreathTimer <= uiDiff) + { + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(POINT_ID_DEEP_BREATH, CENTER_X, CENTER_Y, AIR_Z+20.0f); + m_bReadyForWPMove = false; + m_uiTimer = 20000; + m_uiDeepBreathTimer = 63000; + m_uiSubPhase = SUBPHASE_DEEP_BREATH; + } + else + m_uiDeepBreathTimer -= uiDiff; + } + else if (m_uiPhase == PHASE_DRAGONS) + { + if (m_uiSubPhase == SUBPHASE_DESTROY_PLATFORM_1) + { + if (m_uiTimer <= uiDiff) + { + DespawnCreatures(NPC_ARCANE_OVERLOAD); + DespawnCreatures(NPC_HOVER_DISK); + + if (Creature* pTempCaster = m_creature->SummonCreature(NPC_VORTEX, CENTER_X, CENTER_Y, FLOOR_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 5000)) + { + pTempCaster->CastSpell(pTempCaster, SPELL_CALL_SKYTALON, true); + pTempCaster->CastSpell(pTempCaster, SPELL_DESTROY_PLATFORM_BOOM, false); + } + + m_creature->SetInCombatWithZone(); + + m_uiSubPhase = SUBPHASE_DESTROY_PLATFORM_2; + m_uiTimer = 3000; + } + else + m_uiTimer -= uiDiff; + + return; + } + else if (m_uiSubPhase == SUBPHASE_DESTROY_PLATFORM_2) + { + if (m_uiTimer <= uiDiff) + { + if (m_pInstance) + if (GameObject* pPlatform = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_PLATFORM))) + pPlatform->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); + + + m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, FLOOR_Z); + DoScriptText(SAY_INTRO_PHASE3, m_creature); + + m_uiSubPhase = SUBPHASE_DESTROY_PLATFORM_3; + m_uiTimer = 3000; + } + else + m_uiTimer -= uiDiff; + + return; + } + else if (m_uiSubPhase == SUBPHASE_DESTROY_PLATFORM_3) + { + if (m_uiTimer<= uiDiff) + { + m_uiSubPhase = SUBPHASE_DESTROY_PLATFORM_4; + m_uiTimer = 12000; + } + else + m_uiTimer -= uiDiff; + + return; + } + else if (m_uiSubPhase == SUBPHASE_DESTROY_PLATFORM_4) + { + if (m_uiTimer <= uiDiff) + { + m_uiSubPhase = 0; + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoScriptText(SAY_AGGRO3, m_creature); + m_uiArcaneStormTimer = 6000; + } + else + m_uiTimer -= uiDiff; + + return; + } + + if (m_uiSubPhase == SUBPHASE_SURGE_OF_POWER) + { + if (m_uiTimer <= uiDiff) + m_uiSubPhase = 0; + else + m_uiTimer -= uiDiff; + + return; + } + + if (m_uiArcanePulseTimer <= uiDiff) + { + DoCast(m_creature, SPELL_ARCANE_PULSE); + m_uiArcanePulseTimer = 1000; + } + else + m_uiArcanePulseTimer -= uiDiff; + + if (m_uiArcaneStormTimer <= uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_ARCANE_STORM : SPELL_ARCANE_STORM_H); + m_uiArcaneStormTimer = urand(6000, 10000); + } + else + m_uiArcaneStormTimer -= uiDiff; + + if (m_uiStaticFieldTimer <= uiDiff) + { + for (uint8 i = 0; i<=50; ++i) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (pTarget->GetEntry() == NPC_WYRMREST_SKYTALON) + { + switch (urand(0, 5)) + { + case 0: DoScriptText(SAY_CAST_SPELL1, m_creature); break; + case 1: DoScriptText(SAY_CAST_SPELL2, m_creature); break; + case 2: DoScriptText(SAY_CAST_SPELL3, m_creature); break; + } + DoCast(pTarget, SPELL_STATIC_FIELD_MISSILE); + break; + } + } + + m_uiStaticFieldTimer = urand(10000, 16000); + } + else + m_uiStaticFieldTimer -= uiDiff; + + if (m_uiSurgeOfPowerTimer <= uiDiff) + { + for (uint8 i = 0; i<=50; ++i) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (pTarget->GetEntry() == NPC_WYRMREST_SKYTALON) + { + m_uiSubPhase = SUBPHASE_SURGE_OF_POWER; + m_uiTimer = 6500; + if (urand(0, 1)) + DoScriptText(SAY_SURGE_OF_POWER, m_creature); + DoCast(pTarget, m_bIsRegularMode ? SPELL_SURGE_OF_POWER : SPELL_SURGE_OF_POWER_H); + break; + } + } + + m_uiSurgeOfPowerTimer = urand(5000, 15000); + } + else + m_uiSurgeOfPowerTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## npc_power_spark +######*/ +struct MANGOS_DLL_DECL npc_power_sparkAI : public ScriptedAI +{ + npc_power_sparkAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool isDead; + uint32 m_uiCheckTimer; + + void Reset() + { + isDead = false; + m_uiCheckTimer = 0; + + SetCombatMovement(false); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->CastSpell(m_creature, SPELL_POWER_SPARK_VISUAL, false); + } + + void AttackStart(Unit *pWho) + { + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + + if (isDead) + { + uiDamage = 0; + return; + } + + if (uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + isDead = true; + m_creature->RemoveAllAuras(); + m_creature->SetHealth(1); + m_creature->CastSpell(m_creature, SPELL_POWER_SPARK_PLAYERS, true); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), FLOOR_Z+1.5f, 0); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), FLOOR_Z+1.5f, SPLINETYPE_NORMAL , m_creature->GetSplineFlags(), 1000); + m_creature->ForcedDespawn(60000); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (isDead) + return; + + if (m_uiCheckTimer <= uiDiff) + { + if (m_pInstance) + if (Creature* pMalygos = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALYGOS))) + { + m_creature->GetMotionMaster()->Clear(); + if (m_pInstance->GetData(TYPE_MALYGOS) != SPECIAL) + { + if (m_creature->IsWithinDist(pMalygos, 5.0f, false)) + { + m_creature->CastSpell(pMalygos, SPELL_POWER_SPARK, true); + m_creature->ForcedDespawn(100); + } + else + m_creature->GetMotionMaster()->MovePoint(0, pMalygos->GetPositionX(), pMalygos->GetPositionY(), pMalygos->GetPositionZ()); + } + else + m_creature->StopMoving(); + } + + m_uiCheckTimer = 2000; + } + else + m_uiCheckTimer -= uiDiff; + } +}; + +/*###### +## npc_nexus_lord +######*/ + +struct MANGOS_DLL_DECL npc_nexus_lordAI : public ScriptedAI +{ + npc_nexus_lordAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + + float m_fTargetOldX; + float m_fTargetOldY; + float m_fVehicleOldX; + float m_fVehicleOldY; + uint32 m_uiCheckTimer; + uint32 m_uiArcaneShockTimer; + uint32 m_uiHasteTimer; + + void Reset() + { + m_uiCheckTimer = 0; + m_fTargetOldX = 0.0f; + m_fTargetOldY = 0.0f; + m_fVehicleOldX = 0.0f; + m_fVehicleOldY = 0.0f; + m_uiArcaneShockTimer = urand(8000, 9000); + m_uiHasteTimer = urand(10000, 12000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (VehicleKit* pDiskVehicle = m_creature->GetVehicle()) + { + if (Unit* pDiskUnit = pDiskVehicle->GetBase()) + { + Creature* pDisk = (Creature*)pDiskUnit; + + float fX = pDisk->GetPositionX(); + float fY = pDisk->GetPositionY(); + + if (fX != m_fVehicleOldX || fY != m_fVehicleOldY) + m_creature->Relocate(fX, fY, pDisk->GetPositionZ(), 0); + + m_fVehicleOldX = fX; + m_fVehicleOldY = fY; + + Unit* pTarget = m_creature->getVictim(); + if (m_creature->IsWithinDistInMap(pTarget, 4.0f)) + { + pDisk->GetMotionMaster()->Clear(); + pDisk->StopMoving(); + } + else + { + if (m_uiCheckTimer <= uiDiff) + { + float fX = pTarget->GetPositionX(); + float fY = pTarget->GetPositionY(); + if (abs(fX - m_fTargetOldX) > 1.0f || abs(fY-m_fTargetOldY) > 1.0f) + { + pDisk->GetMotionMaster()->Clear(); + pDisk->GetMotionMaster()->MovePoint(0, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ()); + } + m_fTargetOldX = fX; + m_fTargetOldY = fY; + m_uiCheckTimer = 100; + } + else + m_uiCheckTimer -= uiDiff; + } + } + } + + if (m_uiArcaneShockTimer <= uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ARCANE_SHOCK : SPELL_ARCANE_SHOCK_H); + m_uiArcaneShockTimer = urand(8000, 10000); + } + else + m_uiArcaneShockTimer -= uiDiff; + + if (m_uiHasteTimer <= uiDiff) + { + DoCast(m_creature, SPELL_HASTE); + m_uiHasteTimer = urand(25000, 30000); + } + else + m_uiHasteTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## npc_scion_of_eternity +######*/ + +struct MANGOS_DLL_DECL npc_scion_of_eternityAI : public ScriptedAI +{ + npc_scion_of_eternityAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + uint32 m_uiArcaneBarrageTimer; + + void Reset() + { + m_uiArcaneBarrageTimer = urand(4000, 12000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiArcaneBarrageTimer <= uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (!pTarget->GetVehicle()) + { + int32 uiDmg = m_bIsRegularMode ? urand(14138, 15862) : urand(16965, 19035); + m_creature->CastCustomSpell(pTarget, SPELL_ARCANE_BARRAGE, &uiDmg, 0, 0, true); + m_uiArcaneBarrageTimer = urand(4000, 12000); + } + } + } + else + m_uiArcaneBarrageTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## npc_hover_disk +######*/ +struct MANGOS_DLL_DECL npc_hover_diskAI : public ScriptedAI +{ + npc_hover_diskAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiCheckTimer; + bool m_bPassengerHere; + bool m_bMoved; + + void Reset() + { + m_uiCheckTimer = 500; + m_bPassengerHere = false; + m_bMoved = false; + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->setFaction(35); + m_creature->CastSpell(m_creature, SPELL_FLIGHT, true); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + } + + void AttackStart(Unit *pWho) + { + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiCheckTimer <= uiDiff) + { + if (m_creature->GetVehicleKit()->GetPassenger(0) && !m_bPassengerHere) + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bMoved = false; + m_bPassengerHere = true; + } + else + if (!m_bMoved && m_bPassengerHere) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), FLOOR_Z+1.5f, 0); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), FLOOR_Z+1.5f, SPLINETYPE_NORMAL , m_creature->GetSplineFlags(), 4000); + m_bMoved = true; + m_bPassengerHere = false; + } + m_uiCheckTimer = 500; + } + else + m_uiCheckTimer -= uiDiff; + } +}; + +/*###### +## npc_alexstrasza +######*/ +struct MANGOS_DLL_DECL npc_alexstraszaAI : public ScriptedAI +{ + npc_alexstraszaAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_uiTimer; + uint8 m_uiCount; + + void Reset() + { + m_uiTimer = 9500; + m_uiCount = 0; + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + if (m_pInstance) + if (Creature* pMalygos = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MALYGOS))) + m_creature->SetFacingToObject(pMalygos); + } + + void SpellHitTarget(Unit* pUnit, const SpellEntry* pSpell) + { + if (pUnit->GetEntry() == NPC_ALEXSTRASZAS_GIFT && pSpell->Id == SPELL_ALEXSTRASZAS_GIFT_BEAM) + pUnit->CastSpell(pUnit, SPELL_ALEXSTRASZAS_GIFT_VISUAL, true); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiCount == 6) + return; + + if (m_uiTimer <= uiDiff) + { + switch (m_uiCount) + { + case 0: + if (m_pInstance) + if (Creature* pMalygos = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MALYGOS))) + pMalygos->RemoveCorpse(); + DoScriptText(SAY_OUTRO1, m_creature); + m_uiTimer = 5000; + break; + case 1: + DoScriptText(SAY_OUTRO2, m_creature); + m_uiTimer = 3500; + break; + case 2: + DoScriptText(SAY_OUTRO3, m_creature); + m_uiTimer = 22000; + break; + case 3: + DoScriptText(SAY_OUTRO4, m_creature); + m_uiTimer = 19500; + break; + case 4: + DoCast(m_creature, SPELL_ALEXSTRASZAS_GIFT_BEAM); + m_uiTimer = 3000; + break; + case 5: + if (m_pInstance) + m_pInstance->SetData(TYPE_MALYGOS, DONE); + break; + } + ++m_uiCount; + } + else + m_uiTimer -= uiDiff; + } +}; + +/*###### +## go_focusing_iris +######*/ +bool GOHello_go_focusing_iris(Player* pPlayer, GameObject* pGo) +{ + if (ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData()) + { + if (Unit* pMalygos = pGo->GetMap()->GetUnit(pInstance->GetData64(NPC_MALYGOS))) + { + if (Creature* pSparkPortal = GetClosestCreatureWithEntry(pMalygos, NPC_SPARK_PORTAL, 100.0f)) + if (pSparkPortal->HasAura(SPELL_PORTAL_BEAM)) + pSparkPortal->ForcedDespawn(); + + pMalygos->GetMotionMaster()->Clear(); + float fAng = pMalygos->GetAngle(CENTER_X, CENTER_Y); + pMalygos->GetMotionMaster()->MovePoint(POINT_ID_LAND, CENTER_X-40.76f*cos(fAng), CENTER_Y-40.76f*sin(fAng), FLOOR_Z+7.0f); + return true; + } + else + return false; + } + return false; +} + +CreatureAI* GetAI_boss_malygos(Creature* pCreature) +{ + return new boss_malygosAI(pCreature); +} + +CreatureAI* GetAI_npc_power_spark(Creature* pCreature) +{ + return new npc_power_sparkAI(pCreature); +} + +CreatureAI* GetAI_npc_nexus_lord(Creature* pCreature) +{ + return new npc_nexus_lordAI(pCreature); +} + +CreatureAI* GetAI_npc_scion_of_eternity(Creature* pCreature) +{ + return new npc_scion_of_eternityAI(pCreature); +} + +CreatureAI* GetAI_npc_hover_disk(Creature* pCreature) +{ + return new npc_hover_diskAI(pCreature); +} + +CreatureAI* GetAI_npc_alexstrasza(Creature* pCreature) +{ + return new npc_alexstraszaAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_whyrmrest_skytalonAI : public ScriptedAI +{ + npc_whyrmrest_skytalonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool Active; + bool seated; + ObjectGuid ownerGUID; + uint32 StartTimer; + uint32 SeatTimer; + + void Reset() + { + Active = false; + seated = false; + ownerGUID = ObjectGuid(); + StartTimer = 500; + SeatTimer = 2000; + ownerGUID = m_creature->GetCreatorGuid(); + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + } + + void AttackStart(Unit *) {} + void MoveInLineOfSight(Unit*) {} + + void JustDied(Unit* killer) + { + if (!m_creature || m_creature->GetTypeId() != TYPEID_UNIT) + return; + + if (ownerGUID.IsEmpty()) + ownerGUID = m_creature->GetCreatorGuid(); + + Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID); + + if (!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + owner->RemoveAurasDueToSpell(SPELL_VEHICLE_HARDCODED); + m_creature->SetCreatorGuid(ObjectGuid()); + } + + void UpdateAI(const uint32 uiDiff) + { + + if (ownerGUID.IsEmpty()) + { + ownerGUID = m_creature->GetCreatorGuid(); + if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID)) + m_creature->setFaction(owner->getFaction()); + } + + if (!ownerGUID.IsEmpty() && !seated && Active) + { + if (SeatTimer < uiDiff) + { + if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID)) + { + m_creature->setFaction(owner->getFaction()); + owner->CastSpell(m_creature, SPELL_VEHICLE_HARDCODED, true); + if (Creature* pMalygos = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALYGOS))) + { + pMalygos->SetInCombatWith(m_creature); + pMalygos->AddThreat(m_creature); + } + seated = true; + } + } + else + SeatTimer -= uiDiff; + } + + if (!ownerGUID.IsEmpty() && !Active) + { + if (StartTimer < uiDiff) + { + if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID)) + { + float x, y, z; + owner->GetClosePoint(x, y, z, owner->GetObjectBoundingRadius(), 1.0f, owner->GetAngle(m_creature)); + m_creature->GetMotionMaster()->MovePoint(0, x, y, z); + Active = true; + } + } + else + StartTimer -= uiDiff; + } + } +}; + +CreatureAI* GetAI_npc_whyrmrest_skytalon(Creature* pCreature) +{ + return new npc_whyrmrest_skytalonAI(pCreature); +} + +void AddSC_boss_malygos() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_malygos"; + newscript->GetAI = &GetAI_boss_malygos; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_power_spark"; + newscript->GetAI = &GetAI_npc_power_spark; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_nexus_lord"; + newscript->GetAI = &GetAI_npc_nexus_lord; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_scion_of_eternity"; + newscript->GetAI = &GetAI_npc_scion_of_eternity; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_hover_disk"; + newscript->GetAI = &GetAI_npc_hover_disk; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_whyrmrest_skytalon"; + newscript->GetAI = &GetAI_npc_whyrmrest_skytalon; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_alexstrasza"; + newscript->GetAI = &GetAI_npc_alexstrasza; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "go_focusing_iris"; + newscript->pGOUse = &GOHello_go_focusing_iris; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h b/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h new file mode 100644 index 000000000..fe926530e --- /dev/null +++ b/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h @@ -0,0 +1,21 @@ +#ifndef DEF_EYE_OF_ETERNITY_H +#define DEF_EYE_OF_ETERNITY_H + +enum +{ + MAX_ENCOUNTER = 1, + + TYPE_MALYGOS = 1, + + NPC_MALYGOS = 28859, + + GO_PLATFORM = 193070, + GO_EXIT_PORTAL = 193908, + GO_FOCUSING_IRIS = 193958, + GO_FOCUSING_IRIS_H = 193960, + GO_ALEXSTRASZAS_GIFT = 193905, + GO_ALEXSTRASZAS_GIFT_H = 193967, + GO_HEART_OF_MAGIC = 194158, + GO_HEART_OF_MAGIC_H = 194159, +}; +#endif diff --git a/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp b/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp new file mode 100644 index 000000000..01296b96a --- /dev/null +++ b/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp @@ -0,0 +1,207 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Instance_Eye_of_Eternity +SD%Complete: 90% +SDComment: +SDAuthor: Tassadar +SDCategory: Nexus, Eye of Eternity +EndScriptData */ + +#include "precompiled.h" +#include "eye_of_eternity.h" + +struct MANGOS_DLL_DECL instance_eye_of_eternity : public ScriptedInstance +{ + instance_eye_of_eternity(Map* pMap) : ScriptedInstance(pMap) {Initialize();} + + std::string strInstData; + uint32 m_auiEncounter[MAX_ENCOUNTER]; + + uint64 m_uiMalygosGUID; + uint64 m_uiPlatformGUID; + uint64 m_uiExitPortalGUID; + uint64 m_uiFocusingIrisGUID; + uint64 m_uiGiftGUID; + uint64 m_uiHeartGUID; + + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + m_uiMalygosGUID = 0; + m_uiPlatformGUID = 0; + m_uiExitPortalGUID = 0; + m_uiFocusingIrisGUID = 0; + m_uiGiftGUID = 0; + m_uiHeartGUID = 0; + } + + void OnCreatureCreate(Creature* pCreature) + { + switch(pCreature->GetEntry()) + { + case NPC_MALYGOS: + m_uiMalygosGUID = pCreature->GetGUID(); + pCreature->SetActiveObjectState(true); + break; + } + } + + void OnObjectCreate(GameObject* pGo) + { + switch(pGo->GetEntry()) + { + case GO_PLATFORM: + m_uiPlatformGUID = pGo->GetGUID(); + break; + case GO_EXIT_PORTAL: + m_uiExitPortalGUID = pGo->GetGUID(); + break; + case GO_FOCUSING_IRIS: + case GO_FOCUSING_IRIS_H: + m_uiFocusingIrisGUID = pGo->GetGUID(); + break; + case GO_ALEXSTRASZAS_GIFT: + case GO_ALEXSTRASZAS_GIFT_H: + m_uiGiftGUID = pGo->GetGUID(); + break; + case GO_HEART_OF_MAGIC: + case GO_HEART_OF_MAGIC_H: + m_uiHeartGUID = pGo->GetGUID(); + break; + } + } + + bool IsEncounterInProgress() const + { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) + return true; + + return false; + } + + void SetData(uint32 uiType, uint32 uiData) + { + switch(uiType) + { + case TYPE_MALYGOS: + { + if (uiData == NOT_STARTED) + { + if (GameObject* pFocusingIris = instance->GetGameObject(m_uiFocusingIrisGUID)) + { + pFocusingIris->SetGoState(GO_STATE_READY); + pFocusingIris->SetPhaseMask(1, true); + } + if (GameObject* pExitPortal = instance->GetGameObject(m_uiExitPortalGUID)) + pExitPortal->SetPhaseMask(1, true); + if (GameObject* pPlatform = instance->GetGameObject(m_uiPlatformGUID)) + pPlatform->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); + } + if (uiData == IN_PROGRESS) + { + if (GameObject* pFocusingIris = instance->GetGameObject(m_uiFocusingIrisGUID)) + pFocusingIris->SetPhaseMask(2, true); + if (GameObject* pExitPortal = instance->GetGameObject(m_uiExitPortalGUID)) + pExitPortal->SetPhaseMask(2, true); + } + if (uiData == DONE) + { + if (GameObject* pExitPortal = instance->GetGameObject(m_uiExitPortalGUID)) + pExitPortal->SetPhaseMask(1, true); + DoRespawnGameObject(m_uiGiftGUID, HOUR*IN_MILLISECONDS); + DoRespawnGameObject(m_uiHeartGUID, HOUR*IN_MILLISECONDS); + } + m_auiEncounter[0] = uiData; + break; + } + } + OUT_SAVE_INST_DATA; + std::ostringstream saveStream; + saveStream << m_auiEncounter[0]; + + strInstData = saveStream.str(); + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + + } + + const char* Save() + { + return strInstData.c_str(); + } + + void 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]; + + 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 GetData(uint32 uiType) + { + switch(uiType) + { + case TYPE_MALYGOS: + return m_auiEncounter[0]; + } + return 0; + } + + uint64 GetData64(uint32 uiData) + { + switch(uiData) + { + case NPC_MALYGOS: + return m_uiMalygosGUID; + case GO_PLATFORM: + return m_uiPlatformGUID; + } + return 0; + } +}; + +InstanceData* GetInstanceData_instance_eye_of_eternity(Map* pMap) +{ + return new instance_eye_of_eternity(pMap); +} + +void AddSC_instance_eye_of_eternity() +{ + Script* pNewScript; + pNewScript = new Script; + pNewScript->Name = "instance_eye_of_eternity"; + pNewScript->GetInstanceData = &GetInstanceData_instance_eye_of_eternity; + pNewScript->RegisterSelf(); +} diff --git a/scripts/northrend/nexus/nexus/boss_anomalus.cpp b/scripts/northrend/nexus/nexus/boss_anomalus.cpp index 46f96d36d..6e9c16946 100644 --- a/scripts/northrend/nexus/nexus/boss_anomalus.cpp +++ b/scripts/northrend/nexus/nexus/boss_anomalus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/nexus/nexus/boss_keristrasza.cpp b/scripts/northrend/nexus/nexus/boss_keristrasza.cpp index fa11d676c..b236122fa 100644 --- a/scripts/northrend/nexus/nexus/boss_keristrasza.cpp +++ b/scripts/northrend/nexus/nexus/boss_keristrasza.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/nexus/nexus/boss_ormorok.cpp b/scripts/northrend/nexus/nexus/boss_ormorok.cpp index aa8b4c080..016f424b5 100644 --- a/scripts/northrend/nexus/nexus/boss_ormorok.cpp +++ b/scripts/northrend/nexus/nexus/boss_ormorok.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/nexus/nexus/boss_telestra.cpp b/scripts/northrend/nexus/nexus/boss_telestra.cpp index 2f26dc7a9..a41914b62 100644 --- a/scripts/northrend/nexus/nexus/boss_telestra.cpp +++ b/scripts/northrend/nexus/nexus/boss_telestra.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/nexus/nexus/instance_nexus.cpp b/scripts/northrend/nexus/nexus/instance_nexus.cpp index 64c30401b..6976b5aca 100644 --- a/scripts/northrend/nexus/nexus/instance_nexus.cpp +++ b/scripts/northrend/nexus/nexus/instance_nexus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,7 +24,7 @@ EndScriptData */ #include "precompiled.h" #include "nexus.h" -bool GOHello_go_containment_sphere(Player* pPlayer, GameObject* pGo) +bool GOUse_go_containment_sphere(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -250,6 +250,6 @@ void AddSC_instance_nexus() newscript = new Script; newscript->Name = "go_containment_sphere"; - newscript->pGOHello = &GOHello_go_containment_sphere; + newscript->pGOUse = &GOUse_go_containment_sphere; newscript->RegisterSelf(); } diff --git a/scripts/northrend/nexus/nexus/nexus.h b/scripts/northrend/nexus/nexus/nexus.h index 9aabb9ece..35876a507 100644 --- a/scripts/northrend/nexus/nexus/nexus.h +++ b/scripts/northrend/nexus/nexus/nexus.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/northrend/nexus/oculus/boss_drakos.cpp b/scripts/northrend/nexus/oculus/boss_drakos.cpp new file mode 100644 index 000000000..301e7462c --- /dev/null +++ b/scripts/northrend/nexus/oculus/boss_drakos.cpp @@ -0,0 +1,227 @@ +/* Copyright (C) 2008 - 2010 TrinityCore +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ScriptData +SDName: Boss_Drakos +SD%Complete: 80% +SDComment: +SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" +#include "oculus.h" + +enum +{ + SAY_AGGRO = -1578000, + SAY_KILL_1 = -1578001, + SAY_KILL_2 = -1578002, + SAY_KILL_3 = -1578003, + SAY_DEATH = -1578004, + SAY_PULL_1 = -1578005, + SAY_PULL_2 = -1578006, + SAY_PULL_3 = -1578007, + SAY_PULL_4 = -1578008, + SAY_STOMP_1 = -1578009, + SAY_STOMP_2 = -1578010, + SAY_STOMP_3 = -1578011, + + SPELL_MAGIC_PULL = 51336, + SPELL_MAGIC_PULL_EFFECT = 50770, + SPELL_THUNDERING_STOMP_N = 50774, + SPELL_THUNDERING_STOMP_H = 59370, + SPELL_UNSTABLE_SPHERE_PASSIVE = 50756, + SPELL_UNSTABLE_SPHERE_PULSE = 50757, + SPELL_UNSTABLE_SPHERE_TIMER = 50758, + SPELL_UNSTABLE_SPHERE_EXPLODE = 50759, + + NPC_UNSTABLE_SPHERE = 28166 +}; + +#define CENTER_X 960.120f +#define CENTER_Y 1049.413f + +struct MANGOS_DLL_DECL boss_drakosAI : public ScriptedAI +{ + boss_drakosAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiMagicPullTimer ; + uint32 m_uiStompTimer ; + uint32 m_uiBombSummonTimer ; + + void Reset() + { + m_uiMagicPullTimer = urand(12000, 15000); + m_uiStompTimer = urand(3000, 6000); + m_uiBombSummonTimer = 7000; + if (m_pInstance && m_creature->isAlive()) + m_pInstance->SetData(TYPE_DRAKOS, NOT_STARTED); + } + + void Aggro(Unit* who) + { + DoScriptText(SAY_AGGRO, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_DRAKOS, IN_PROGRESS); + } + + void JustDied(Unit* killer) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_DRAKOS, DONE); + } + + void KilledUnit(Unit *victim) + { + switch (urand(0, 2)) + { + case 0: DoScriptText(SAY_KILL_1, m_creature); break; + case 1: DoScriptText(SAY_KILL_2, m_creature); break; + case 2: DoScriptText(SAY_KILL_3, m_creature); break; + } + } + + void SpellHitTarget(Unit *target, const SpellEntry *spell) + { + if (spell->Id == SPELL_MAGIC_PULL) + if (target->GetTypeId() == TYPEID_PLAYER) + DoCast(target, SPELL_MAGIC_PULL_EFFECT, true); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiBombSummonTimer < diff) + { + m_creature->SummonCreature(NPC_UNSTABLE_SPHERE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); + m_creature->SummonCreature(NPC_UNSTABLE_SPHERE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); + m_uiBombSummonTimer = 3000; + } + else + m_uiBombSummonTimer -= diff; + + if (m_uiMagicPullTimer < diff) + { + DoCast(m_creature, SPELL_MAGIC_PULL); + m_uiMagicPullTimer = urand(15000, 25000); + switch (urand(0, 3)) + { + case 0: DoScriptText(SAY_PULL_1, m_creature); break; + case 1: DoScriptText(SAY_PULL_2, m_creature); break; + case 2: DoScriptText(SAY_PULL_3, m_creature); break; + case 3: DoScriptText(SAY_PULL_4, m_creature); break; + } + } + else + m_uiMagicPullTimer -= diff; + + if (m_uiStompTimer < diff) + { + DoCast(m_creature, SPELL_THUNDERING_STOMP_N); + m_uiStompTimer = urand(11000, 18000); + switch (urand(0, 2)) + { + case 0: DoScriptText(SAY_STOMP_1, m_creature); break; + case 1: DoScriptText(SAY_STOMP_2, m_creature); break; + case 2: DoScriptText(SAY_STOMP_3, m_creature); break; + } + } + else + m_uiStompTimer -= diff ; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_drakos(Creature* pCreature) +{ + return new boss_drakosAI (pCreature); +} + +struct MANGOS_DLL_DECL npc_unstable_sphereAI : public ScriptedAI +{ + npc_unstable_sphereAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_uiPulseTimer; + + void Reset() + { + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->GetMotionMaster()->MovePoint(0, (CENTER_X-35)+rand()%70, (CENTER_Y-35)+rand()%70, m_creature->GetPositionZ()); + m_creature->SetSpeedRate(MOVE_RUN, 2, true); + m_creature->setFaction(14); + DoCast(m_creature, SPELL_UNSTABLE_SPHERE_PASSIVE, true); + DoCast(m_creature, SPELL_UNSTABLE_SPHERE_TIMER, true); + m_uiPulseTimer = 3000; + m_creature->ForcedDespawn(19000); + } + + void AttackStart(Unit* pWho) + { + } + + void UpdateAI(const uint32 diff) + { + + if (m_pInstance && m_pInstance->GetData(TYPE_DRAKOS) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_uiPulseTimer < diff) + { + DoCast(m_creature, SPELL_UNSTABLE_SPHERE_PULSE, true); + m_uiPulseTimer = 3000; + } + else + m_uiPulseTimer -= diff; + } +}; + +CreatureAI* GetAI_npc_unstable_sphere(Creature* pCreature) +{ + return new npc_unstable_sphereAI (pCreature); +} + +void AddSC_boss_drakos() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_drakos"; + newscript->GetAI = &GetAI_boss_drakos; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_unstable_sphere"; + newscript->GetAI = &GetAI_npc_unstable_sphere; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/nexus/oculus/boss_eregos.cpp b/scripts/northrend/nexus/oculus/boss_eregos.cpp new file mode 100644 index 000000000..a881da6a3 --- /dev/null +++ b/scripts/northrend/nexus/oculus/boss_eregos.cpp @@ -0,0 +1,320 @@ +/* Copyright (C) 2008 - 2010 TrinityCore +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ScriptData +SDName: Boss_Eregos +SD%Complete: 60% +SDComment: +SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" +#include "oculus.h" + +enum Spells +{ + SAY_AGGRO = -1578030, + SAY_KILL_1 = -1578031, + SAY_KILL_2 = -1578032, + SAY_KILL_3 = -1578033, + SAY_DEATH = -1578034, + SAY_ARCANE_SHIELD = -1578035, + SAY_FIRE_SHIELD = -1578036, + SAY_NATURE_SHIELD = -1578037, + SAY_FRENZY = -1578038, + SAY_SPAWN = -1578039, + + SPELL_ARCANE_BARRAGE_N = 50804, + SPELL_ARCANE_BARRAGE_H = 59381, + SPELL_ARCANE_VOLLEY_N = 51153, + SPELL_ARCANE_VOLLEY_H = 59382, + SPELL_ENRAGED_ASSAULT = 51170, + SPELL_SUMMON_DRAKE = 51175, + SPELL_PLANAR_ANOMALIES = 57959, + SPELL_PLANAR_ANOMALIES_SUMMON = 57963, //need spell script on m_creature 27656 + SPELL_PLANAR_ANOMALIES_VISUAL = 57971, + SPELL_PLANAR_SHIFT = 51162, + SPELL_PLANAR_ANOMALIES_DMG = 57976, + + NPC_PLANAR_ANOMALY = 30879, + NPC_DRAGON = 28276 +}; + +struct MANGOS_DLL_DECL boss_eregosAI : public ScriptedAI +{ + boss_eregosAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 uiArcaneBarrageTimer; + uint32 uiArcaneVolleyTimer; + uint32 uiEnragedAssaultTimer; + uint32 uiSummonTimer; + + uint8 m_uiSummonCount; + + bool m_bIsMove; + + void Reset() + { + m_creature->SetVisibility(VISIBILITY_ON); + if (m_pInstance) + { + m_pInstance->SetData(TYPE_EREGOS, NOT_STARTED); + if(m_pInstance->GetData(TYPE_UROM) == DONE) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + else + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + uiArcaneBarrageTimer = 12000; + uiArcaneVolleyTimer = 17000; + uiEnragedAssaultTimer = 24000; + uiSummonTimer = 15000; + m_uiSummonCount = 0; + m_bIsMove = true; + } + + void MoveInLineOfSight(Unit* pWho) + { + if(pWho->GetTypeId() == TYPEID_PLAYER + && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) + && !((Player*)pWho)->isGameMaster() + && m_creature->IsWithinDistInMap(pWho, 100.0f) + && pWho->GetVehicle() + && m_pInstance->GetData(TYPE_UROM) == DONE) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + ScriptedAI::MoveInLineOfSight(pWho); + } + + void Aggro(Unit* who) + { + DoScriptText(SAY_AGGRO, m_creature); + if (m_pInstance) + m_pInstance->SetData(TYPE_EREGOS, IN_PROGRESS); + } + + void KilledUnit(Unit *victim) + { + uint8 uiText = urand(0, 2); + switch (uiText) + { + case 0: DoScriptText(SAY_KILL_1, m_creature); break; + case 1: DoScriptText(SAY_KILL_2, m_creature); break; + case 2: DoScriptText(SAY_KILL_3, m_creature); break; + } + } + + void JustDied(Unit* killer) + { + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()-100.0f, 0); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()-100.0f, SPLINETYPE_NORMAL , m_creature->GetSplineFlags(), 6000); + DoScriptText(SAY_DEATH, m_creature); + if (m_pInstance) + m_pInstance->SetData(TYPE_EREGOS, DONE); + } + + void DamageTaken(Unit *done_by, uint32 &damage) + { + if(m_creature->HasAura(SPELL_PLANAR_SHIFT)) + damage = 0; + } + + void JustSummoned(Creature* pSummoned) + { + if(pSummoned->GetEntry() == NPC_PLANAR_ANOMALY) + { + pSummoned->SetDisplayId(11686); + pSummoned->SetInCombatWithZone(); + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); + } + + if(pSummoned->GetEntry() == NPC_DRAGON) + { + pSummoned->SetInCombatWithZone(); + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); + } + } + + void AttackStart(Unit* who) + { + if (!who) + return; + + if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; + + ScriptedAI::AttackStart(who); + } + + void SummonAnomalies() + { + std::list t_list = m_creature->getThreatManager().getThreatList(); + if (t_list.size()) + { + for (std::list::iterator itr = t_list.begin(); itr != t_list.end(); ++itr) + { + Unit *pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER) + DoCast(m_creature, SPELL_PLANAR_ANOMALIES_SUMMON, true); + } + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_creature->GetHealthPercent() < 50.0f && m_uiSummonCount == 0) + { + SummonAnomalies(); + m_uiSummonCount = 1; + m_creature->CastSpell(m_creature, SPELL_PLANAR_SHIFT,true); + } + + if(m_creature->GetHealthPercent() < 25.0f && m_uiSummonCount == 1) + { + SummonAnomalies(); + m_uiSummonCount = 2; + m_creature->CastSpell(m_creature, SPELL_PLANAR_SHIFT,true); + } + + if(m_creature->GetDistance2d(m_creature->getVictim()) > 35.0f && !m_bIsMove) + { + m_bIsMove = true; + SetCombatMovement(m_bIsMove); + if(Unit* pTarget = m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(pTarget); + } + + if(m_creature->GetDistance2d(m_creature->getVictim()) < 20.0f && m_bIsMove) + { + m_bIsMove = false; + SetCombatMovement(m_bIsMove); + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->StopMoving(); + } + + if(uiArcaneBarrageTimer <= diff) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_ARCANE_BARRAGE_N : SPELL_ARCANE_BARRAGE_H); + uiArcaneBarrageTimer = 3000; + } else uiArcaneBarrageTimer -= diff; + + if(uiSummonTimer <= diff) + { + for(uint8 i = 1; i < 3; i++) + DoCast(m_creature, SPELL_SUMMON_DRAKE, true); + uiSummonTimer = 15000; + } else uiSummonTimer -= diff; + + if(uiArcaneVolleyTimer <= diff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ARCANE_VOLLEY_N : SPELL_ARCANE_VOLLEY_H); + uiArcaneVolleyTimer = 17000; + } else uiArcaneVolleyTimer -= diff; + + if(uiEnragedAssaultTimer <= diff) + { + DoCast(m_creature, SPELL_ENRAGED_ASSAULT, true); + uiEnragedAssaultTimer = 44000; + } else uiEnragedAssaultTimer -= diff; + } +}; + +struct MANGOS_DLL_DECL npc_planar_anomalyAI : public ScriptedAI +{ + npc_planar_anomalyAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 uiPulseTimer; + uint32 uiDeathTimer; + + void Reset() + { + m_creature->SetDisplayId(11686); + m_creature->SetObjectScale(2.0f); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->SetSpeedRate(MOVE_RUN, 1.5, true); + m_creature->setFaction(14); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, SPELL_PLANAR_ANOMALIES_VISUAL, true); + uiDeathTimer = 20500; + uiPulseTimer = 19000; + } + + void UpdateAI(const uint32 diff) + { + if (uiPulseTimer < diff) + { + m_creature->RemoveAurasDueToSpell(SPELL_PLANAR_ANOMALIES_VISUAL); + m_creature->CastSpell(m_creature, SPELL_PLANAR_ANOMALIES_DMG, true); + uiPulseTimer = 6000; + } else uiPulseTimer -= diff; + + if (uiDeathTimer < diff) + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else uiDeathTimer -= diff; + } +}; + +CreatureAI* GetAI_boss_eregos(Creature* pCreature) +{ + return new boss_eregosAI (pCreature); +} + +CreatureAI* GetAI_npc_planar_anomaly(Creature* pCreature) +{ + return new npc_planar_anomalyAI (pCreature); +} + +void AddSC_boss_eregos() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_eregos"; + newscript->GetAI = &GetAI_boss_eregos; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_planar_anomaly"; + newscript->GetAI = &GetAI_npc_planar_anomaly; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/nexus/oculus/boss_urom.cpp b/scripts/northrend/nexus/oculus/boss_urom.cpp new file mode 100644 index 000000000..897a417b4 --- /dev/null +++ b/scripts/northrend/nexus/oculus/boss_urom.cpp @@ -0,0 +1,378 @@ +/* Copyright (C) 2008 - 2010 TrinityCore +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* ScriptData +SDName: Boss_Urom +SD%Complete: 70% +SDComment: +SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" +#include "oculus.h" + +enum +{ + SAY_AGGRO = -1578012, + SAY_KILL_1 = -1578013, + SAY_KILL_2 = -1578014, + SAY_KILL_3 = -1578015, + SAY_DEATH = -1578016, + SAY_EXPLOSION_1 = -1578017, + SAY_EXPLOSION_2 = -1578018, + SAY_SUMMON_1 = -1578019, + SAY_SUMMON_2 = -1578020, + SAY_SUMMON_3 = -1578021, + + SPELL_ARCANE_BARRIER = 53813, //Dummy --> Channeled, shields the caster from damage. + SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110, + SPELL_EMPOWERED_ARCANE_EXPLOSION_2 = 59377, + SPELL_FROSTBOMB = 51103, //Urom throws a bomb, hitting its target with the highest aggro which inflict directly 650 frost damage and drops a frost zone on the ground. This zone deals 650 frost damage per second and reduce the movement speed by 35%. Lasts 1 minute. + SPELL_SUMMON_MENAGERIE = 50476, //Summons an assortment of creatures and teleports the caster to safety. + SPELL_SUMMON_MENAGERIE_2 = 50495, + SPELL_SUMMON_MENAGERIE_3 = 50496, + SPELL_TELEPORT = 51112, //Teleports to the center of Oculus + SPELL_TIME_BOMB = 51121, //Deals arcane damage to a random player, and after 6 seconds, deals zone damage to nearby equal to the health missing of the target afflicted by the debuff. + SPELL_TIME_BOMB_2 = 59376, + + //NPCs + NPC_PHANTASMAL_MAMMOTH = 27642, + NPC_PHANTASMAL_WOLF = 27644, + NPC_PHANTASMAL_CLOUDSCRAPER = 27645, + NPC_PHANTASMAL_OGRE = 27647, + NPC_PHANTASMAL_NAGA = 27648, + NPC_PHANTASMAL_MURLOC = 27649, + NPC_PHANTASMAL_AIR = 27650, + NPC_PHANTASMAL_FIRE = 27651, + NPC_PHANTASMAL_WATER = 27653 +}; +/* +struct Locations +{ + float x, y, z, o; + uint32 id; +}; +*/ +struct Locations Teleport[]= +{ + {1177.469f, 937.721f, 527.405f, 2.21f}, //first platform + {968.5880f, 1042.58f, 527.321f, 0.13f}, //second platform + {1163.671f, 1171.02f, 527.321f, 4.19f}, //third platform + {1116.765f, 1075.93f, 508.361f, 4.26f}, //middle platform + {1103.659f, 1049.88f, 518.148f, 5.80f} //oculus center +}; + +struct MANGOS_DLL_DECL boss_uromAI : public BSWScriptedAI +{ + boss_uromAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiFrostBombTimer; + uint32 m_uiLiveBombTimer; + uint32 m_uiTeleportTimer; + uint32 m_uiArcaneExplodeTimer; + uint32 m_uiRelocateTimer; + uint32 m_uiBackTimer; + uint32 m_uiCheckTimer; + + bool m_bIsTeleported; + bool m_bIsTalk; + + void Reset() + { + m_uiFrostBombTimer = 9000; + m_uiLiveBombTimer = 14000; + m_uiTeleportTimer = 30000; + m_uiRelocateTimer = 31500; + m_uiBackTimer = 9000; + m_uiCheckTimer = 2000; + m_uiArcaneExplodeTimer = 1000; + + m_bIsTeleported = false; + m_bIsTalk = false; + + if (m_pInstance && m_pInstance->GetData(TYPE_UROM) != IN_PROGRESS) + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_pInstance->SetData(TYPE_UROM, NOT_STARTED); + if(m_pInstance->GetData(TYPE_VAROS) == DONE) + { + m_creature->RemoveAurasDueToSpell(SPELL_ARCANE_BARRIER); + m_creature->InterruptNonMeleeSpells(false); +// m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + else + { + DoCast(m_creature, SPELL_ARCANE_BARRIER); + } + } + } + + void DoSummon(uint32 Entry01, uint32 Entry02, uint32 Entry03, uint32 Entry04, uint32 Entry05 = 0) + { + m_creature->SummonCreature(Entry01, m_creature->GetPositionX() - (10.0f) * cos(M_PI / 2), m_creature->GetPositionY() - (10.0f) * sin(M_PI / 2), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); + m_creature->SummonCreature(Entry02, m_creature->GetPositionX() - (10.0f) * cos(M_PI * 2), m_creature->GetPositionY() - (10.0f) * sin(M_PI * 2), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); + m_creature->SummonCreature(Entry03, m_creature->GetPositionX() - (10.0f) * cos(M_PI + M_PI / 2), m_creature->GetPositionY() - (10.0f) * sin(M_PI + M_PI / 2), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); + m_creature->SummonCreature(Entry04, m_creature->GetPositionX() - (10.0f) * cos(M_PI), m_creature->GetPositionY() - (10.0f) * sin(M_PI), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); + if(Entry05 != 0) + m_creature->SummonCreature(Entry05, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); + } + + void SpellHit(Unit* pCaster, const SpellEntry* pSpell) + { + if(pSpell->Id == SPELL_SUMMON_MENAGERIE) //|| pSpell->Id == SPELL_SUMMON_MENAGERIE_2 || pSpell->Id == SPELL_SUMMON_MENAGERIE_3) + m_bIsTalk = false; + if(pSpell->Id == SPELL_SUMMON_MENAGERIE_2) + m_bIsTalk = false; + if(pSpell->Id == SPELL_SUMMON_MENAGERIE_3) + m_bIsTalk = false; + } + + void TeleportBoss(float X, float Y, float Z, float O) + { + m_creature->GetMap()->CreatureRelocation(m_creature, X, Y, Z, O); + m_creature->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL, SPLINEFLAG_DONE, 0); + m_creature->Relocate(X, Y, Z, O); + } + + void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if(m_pInstance->GetData(TYPE_UROM_PHASE) < 3) + return; + + if (m_bIsTeleported) + return; + + ScriptedAI::AttackStart(pWho); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_pInstance) + return; + + if(pWho->GetTypeId() == TYPEID_PLAYER + && !((Player*)pWho)->isGameMaster() + && m_creature->IsWithinDistInMap(pWho, 30.0f) + && !pWho->GetVehicle() + && m_pInstance->GetData(TYPE_VAROS) == DONE + && !m_bIsTalk) + { + switch(m_pInstance->GetData(TYPE_UROM_PHASE)) + { + case 0: + m_bIsTalk = true; + SetCombatMovement(false); + m_pInstance->SetData(TYPE_UROM, IN_PROGRESS); + m_creature->InterruptNonMeleeSpells(false); + m_creature->RemoveAurasDueToSpell(53813); + DoScriptText(SAY_SUMMON_1, m_creature); + DoSummon(NPC_PHANTASMAL_FIRE, NPC_PHANTASMAL_FIRE, NPC_PHANTASMAL_AIR, NPC_PHANTASMAL_WATER); + DoCast(m_creature, SPELL_SUMMON_MENAGERIE); + m_pInstance->SetData(TYPE_UROM_PHASE, 1); + break; + case 1: + m_bIsTalk = true; + DoScriptText(SAY_SUMMON_2, m_creature); + DoSummon(NPC_PHANTASMAL_OGRE, NPC_PHANTASMAL_OGRE, NPC_PHANTASMAL_NAGA, NPC_PHANTASMAL_MURLOC); + DoCast(m_creature, SPELL_SUMMON_MENAGERIE_2); + m_pInstance->SetData(TYPE_UROM_PHASE, 2); + break; + case 2: + m_bIsTalk = true; + DoScriptText(SAY_SUMMON_3, m_creature); + DoSummon(NPC_PHANTASMAL_MAMMOTH, NPC_PHANTASMAL_WOLF, NPC_PHANTASMAL_WOLF, NPC_PHANTASMAL_CLOUDSCRAPER, NPC_PHANTASMAL_CLOUDSCRAPER); + DoCast(m_creature, SPELL_SUMMON_MENAGERIE_3); + m_pInstance->SetData(TYPE_UROM_PHASE, 3); + break; + case 3: + m_bIsTalk = true; + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(true); + AttackStart(pWho); + break; + default: + break; + } + } + + ScriptedAI::MoveInLineOfSight(pWho); + } + + void Aggro(Unit* pWho) + { + if(pWho->GetTypeId() != TYPEID_PLAYER) + EnterEvadeMode(); + else DoScriptText(SAY_AGGRO, m_creature); + } + + void JustSummoned(Creature* summoned) + { + if(!m_pInstance || !summoned) return; + + if (Unit* pTarget = doSelectRandomPlayerAtRange(100.0f)) + { + summoned->SetInCombatWith(pTarget); + summoned->AddThreat(pTarget,100.0f); + } + } + + void EnterEvadeMode() + { + + if (!m_pInstance) + return; + + if( m_pInstance->GetData(TYPE_UROM_PHASE) < 3) + { + Map::PlayerList const &pList = m_creature->GetMap()->GetPlayers(); + if (!pList.isEmpty()) + return; + } + m_pInstance->SetData(TYPE_UROM, FAIL); + m_pInstance->SetData(TYPE_UROM_PHASE, 1); + ScriptedAI::EnterEvadeMode(); + } + + void JustDied(Unit* killer) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_UROM, DONE); + } + + void KilledUnit(Unit *victim) + { + uint8 uiText = urand(0, 2); + switch (uiText) + { + case 0: DoScriptText(SAY_KILL_1, m_creature); break; + case 1: DoScriptText(SAY_KILL_2, m_creature); break; + case 2: DoScriptText(SAY_KILL_3, m_creature); break; + } + } + + void CheckVehicle() + { + Map *map = m_creature->GetMap(); + if(map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if(PlayerList.isEmpty()) + return; + + for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if(i->getSource()->isAlive() && i->getSource()->GetVehicle()) + EnterEvadeMode(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(!m_bIsTeleported) + { + if(m_uiFrostBombTimer < uiDiff) + { + m_creature->CastSpell(m_creature->getVictim(), SPELL_FROSTBOMB, false); + m_uiFrostBombTimer = urand(5000, 7000); + } else m_uiFrostBombTimer -= uiDiff; + + if(m_uiLiveBombTimer < uiDiff) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_TIME_BOMB : SPELL_TIME_BOMB_2); + m_uiLiveBombTimer = urand(15000, 25000); + } else m_uiLiveBombTimer -= uiDiff; + + if(m_uiTeleportTimer < uiDiff) + { + DoCast(m_creature, SPELL_TELEPORT); + m_uiTeleportTimer = 31500; + } else m_uiTeleportTimer -= uiDiff; + + if(m_uiCheckTimer < uiDiff) + { + CheckVehicle(); + m_uiCheckTimer = 2000; + } else m_uiCheckTimer -= uiDiff; + + if(m_uiRelocateTimer < uiDiff) + { + m_bIsTeleported = true; + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->StopMoving(); + TeleportBoss(Teleport[4].x,Teleport[4].y,Teleport[4].z,Teleport[4].o); + m_uiRelocateTimer = 31500; + } else m_uiRelocateTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + else + { + if(m_uiArcaneExplodeTimer < uiDiff) + { + DoScriptText(urand(0,1) ? SAY_EXPLOSION_1 : SAY_EXPLOSION_2, m_creature); + DoCast(m_creature, SPELL_EMPOWERED_ARCANE_EXPLOSION); + m_uiArcaneExplodeTimer = 32000; + } else m_uiArcaneExplodeTimer -= uiDiff; + + if(m_uiBackTimer < uiDiff) + { + TeleportBoss((m_creature->getVictim())->GetPositionX(),(m_creature->getVictim())->GetPositionY(),(m_creature->getVictim())->GetPositionZ(),(m_creature->getVictim())->GetOrientation()); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + if(m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_uiBackTimer = 9000; + m_bIsTeleported = false; + m_uiArcaneExplodeTimer = 1000; + } else m_uiBackTimer -= uiDiff; + } + } +}; + +CreatureAI* GetAI_boss_urom(Creature* pCreature) +{ + return new boss_uromAI (pCreature); +} + +void AddSC_boss_urom() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_urom"; + newscript->GetAI = &GetAI_boss_urom; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/nexus/oculus/boss_varos.cpp b/scripts/northrend/nexus/oculus/boss_varos.cpp new file mode 100644 index 000000000..4e4423964 --- /dev/null +++ b/scripts/northrend/nexus/oculus/boss_varos.cpp @@ -0,0 +1,470 @@ +/* Copyright (C) 2008 - 2010 TrinityCore +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ScriptData +SDName: Boss_Varos +SD%Complete: 70% +SDComment: +SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" +#include "oculus.h" + +enum +{ + SAY_AGGRO = -1578022, + SAY_KILL_1 = -1578023, + SAY_KILL_2 = -1578024, + SAY_DEATH = -1578025, + SAY_STRIKE_1 = -1578026, + SAY_STRIKE_2 = -1578027, + SAY_STRIKE_3 = -1578028, + + SPELL_ARCANE_SHIELD = 50053, + SPELL_ENERGIZE_CORES = 50785, //Damage 5938 to 6562, effec2 Triggers 54069, effect3 Triggers 56251 + SPELL_ENERGIZE_CORES_TRIGGER_1 = 54069, + SPELL_ENERGIZE_CORES_TRIGGER_2 = 56251, + SPELL_ENERGIZE_CORES_2 = 59372, //Damage 9025 to 9975, effect2 Triggers 54069, effect 56251 + SPELL_CALL_AZURE_RING_CAPTAIN = 51002, //Effect Send Event (12229) + SPELL_CALL_AZURE_RING_CAPTAIN_2 = 51006, //Effect Send Event (10665) + SPELL_CALL_AZURE_RING_CAPTAIN_3 = 51007, //Effect Send Event (18454) + SPELL_CALL_AZURE_RING_CAPTAIN_4 = 51008, //Effect Send Event (18455) + SPELL_CALL_AMPLIFY_MAGIC = 51054, + SPELL_CALL_AMPLIFY_MAGIC_2 = 59371, + + NPC_AZURE_CAPTAIN = 28236, + NPC_BEAM = 28239, + NPC_VAROS_CORE = 28183, + + SPELL_CORE_VISUAL = 50798, + SPELL_CORE_MISSILE = 61407, //need core fix max target 4, and spell script on 28183 + SPELL_BEAM = 51024, //need spell scrip on 28239 + SPELL_BEAM_DMG_AURA = 51019, + SPELL_BEAM_VISUAL_SOUND = 51022, //need script target 28239 + SPELL_SUMMON_BEAM = 51017 +}; + +struct dLocations +{ + float x1, y1, x2, y2; + uint32 id; +}; + +struct dLocations Regions[]= +{ + {0, 0, 0}, + {1323.0f, 1056.0f, 1333.0f, 1066.0f}, //first orb 1 + {1319.3f, 1084.0f, 1329.5f, 1094.0f}, //second orb 2 + {1288.3f, 1108.8f, 1298.3f, 1118.8f}, //third orb 3 + {1260.3f, 1104.2f, 1270.3f, 1114.2f}, //four orb 4 + {1237.7f, 1074.5f, 1247.7f, 1084.5f}, //fifth orb 5 + {1241.8f, 1046.1f, 1251.8f, 1056.1f}, // 6 + {1272.0f, 1022.1f, 1282.0f, 1032.1f}, // 7 + {1300.5f, 1026.2f, 1310.5f, 1036.2f} // 8 +}; + +struct MANGOS_DLL_DECL boss_varosAI : public ScriptedAI +{ + boss_varosAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint8 MinOrb; + uint8 MaxOrb; + + uint32 m_uiCoreTimer; + uint32 m_uiOrbCast; + uint32 m_uiDragonAttackTimer; + uint32 m_uiDragonMoveTimer; + uint32 m_uiCheckTimer; + + uint64 m_uiAzureDrakeGUID; + + bool m_bIsCastChain; + + float angle01; + float angle02; + + void Reset() + { + MinOrb = 1; + MaxOrb = 4; + angle01 = 0; + angle02 = 0; + m_uiOrbCast = 7000; + m_uiCheckTimer = 2000; + m_uiDragonAttackTimer = 10000; + m_uiCoreTimer = urand(7000, 15000); + m_uiDragonMoveTimer = 16000; + m_bIsCastChain = false; + if(m_pInstance) + { + m_pInstance->SetData(TYPE_VAROS, NOT_STARTED); + if(m_pInstance->GetData(TYPE_ROBOTS) == 0) + { + m_creature->RemoveAurasDueToSpell(SPELL_ARCANE_SHIELD); + m_creature->InterruptNonMeleeSpells(false); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + else + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, SPELL_ARCANE_SHIELD); + } + if(Creature* Dragon = m_pInstance->instance->GetCreature(m_uiAzureDrakeGUID)) + Dragon->DealDamage(Dragon, Dragon->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + m_uiAzureDrakeGUID = 0; + } + + void CheckVehicle() + { + Map* map = m_creature->GetMap(); + if(map && map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if(PlayerList.isEmpty()) + return; + + for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if(i->getSource()->isAlive() && i->getSource()->GetVehicle()) + EnterEvadeMode(); + } + } + } + + void Aggro(Unit* who) + { + DoScriptText(SAY_AGGRO, m_creature); + + if(m_pInstance) + m_pInstance->SetData(TYPE_VAROS, IN_PROGRESS); + + if(Creature* Dragon = m_creature->SummonCreature(NPC_AZURE_CAPTAIN, (m_creature->GetPositionX()-45)+rand()%90, (m_creature->GetPositionY()-45)+rand()%90, m_creature->GetPositionZ() + 30.0f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 100)) + { + Dragon->AddSplineFlag(SPLINEFLAG_FLYING); + Dragon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_uiAzureDrakeGUID = Dragon->GetGUID(); + } + } + + void AttackStart(Unit* pWho) + { + if(m_pInstance) + if(m_pInstance->GetData(TYPE_ROBOTS) != 0) + return; + + ScriptedAI::AttackStart(pWho); + + } + + void JustDied(Unit* killer) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_VAROS, DONE); + } + + void KilledUnit(Unit *victim) + { + DoScriptText(urand(0,1) ? SAY_KILL_1 : SAY_KILL_2, m_creature); + } + + void JustSummoned(Creature* pSummoned) + { + if(pSummoned->GetEntry() == NPC_BEAM) + { + pSummoned->setFaction(14); + pSummoned->SetDisplayId(11686); + pSummoned->CastSpell(pSummoned, SPELL_BEAM_VISUAL_SOUND, false); + pSummoned->CastSpell(pSummoned, SPELL_BEAM_DMG_AURA, false); + pSummoned->SetInCombatWithZone(); + if(Unit* pTarget = pSummoned->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); + if(m_pInstance) + if(Creature* Dragon = m_pInstance->instance->GetCreature(m_uiAzureDrakeGUID)) + { + Dragon->GetMotionMaster()->MovementExpired(false); + Dragon->GetMotionMaster()->Clear(false); + Dragon->CastSpell(pSummoned, SPELL_BEAM, true); + } + } + } + + void SelectFourOrb() //huck work perfecly + { + MinOrb = MinOrb+2; + MaxOrb = MaxOrb+2; + if(MinOrb > 8) + MinOrb = 1; + if(MaxOrb > 8) + MaxOrb = 2; + + std::list m_pSpheres; + GetCreatureListWithEntryInGrid(m_pSpheres, m_creature, NPC_VAROS_CORE, DEFAULT_VISIBILITY_INSTANCE); + + if(!m_pSpheres.empty()) + for(std::list::iterator iter = m_pSpheres.begin(); iter != m_pSpheres.end(); ++iter) + { + for(uint8 i = 1; i < 9; i++) + if((i <= MaxOrb && i >= MinOrb) || (MinOrb == 7 && (i <= MaxOrb || i >= MinOrb))) + if((*iter)->GetPositionX() > Regions[i].x1 && (*iter)->GetPositionX() < Regions[i].x2) + if((*iter)->GetPositionY() > Regions[i].y1 && (*iter)->GetPositionY() < Regions[i].y2) + if(SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_CORE_MISSILE)) + { + pTempSpell->EffectImplicitTargetA[0] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[0] = 0; + pTempSpell->EffectImplicitTargetA[1] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[1] = 0; + pTempSpell->EffectImplicitTargetA[2] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[2] = 0; + (*iter)->CastSpell(m_creature, pTempSpell, true); + } + } + } + + void CastEnergy() + { + std::list m_pSpheres; + GetCreatureListWithEntryInGrid(m_pSpheres, m_creature, NPC_VAROS_CORE, DEFAULT_VISIBILITY_INSTANCE); + + if(!m_pSpheres.empty()) + for(std::list::iterator iter = m_pSpheres.begin(); iter != m_pSpheres.end(); ++iter) + { + for(uint8 i = 1; i < 9; i++) + if((i <= MaxOrb && i >= MinOrb) || (MinOrb == 7 && (i <= MaxOrb || i >= MinOrb))) + if((*iter)->GetPositionX() > Regions[i].x1 && (*iter)->GetPositionX() < Regions[i].x2) + if((*iter)->GetPositionY() > Regions[i].y1 && (*iter)->GetPositionY() < Regions[i].y2) + { + if(SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_ENERGIZE_CORES_TRIGGER_1)) + { + pTempSpell->EffectImplicitTargetA[0] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[0] = 0; + pTempSpell->EffectImplicitTargetA[1] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[1] = 0; + pTempSpell->EffectImplicitTargetA[2] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[2] = 0; + (*iter)->CastSpell(m_creature, pTempSpell, true); + } + + if(i == MinOrb) + angle01 = m_creature->GetAngle((*iter)); + if(i == MaxOrb) + angle02 = m_creature->GetAngle((*iter)); + + Map *map = m_creature->GetMap(); + if(map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if(PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive()) + { + float pAngle = m_creature->GetAngle(i->getSource()); + if(angle01 < angle02) + if(pAngle < angle02 && pAngle > angle01) + DoEnergy(i->getSource()); + if(angle01 > angle02) + if(pAngle < angle02 || pAngle > angle01) + DoEnergy(i->getSource()); + } + } + } + } + } + } + + void DoEnergy(Unit* pTarget) + { + if(SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(m_bIsRegularMode ? SPELL_ENERGIZE_CORES : SPELL_ENERGIZE_CORES_2)) + { + pTempSpell->EffectImplicitTargetA[0] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[0] = 0; + pTempSpell->EffectImplicitTargetA[1] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[1] = 0; + pTempSpell->EffectImplicitTargetA[2] = TARGET_EFFECT_SELECT; + pTempSpell->EffectImplicitTargetB[2] = 0; + m_creature->CastSpell(pTarget, pTempSpell, true); + } + + } + + /*void SpellHitTarget(Unit *target, const SpellEntry *spell) + { + if(spell->Id == (m_bIsRegularMode ? SPELL_ENERGIZE_CORES : SPELL_ENERGIZE_CORES_2) && target->GetTypeId() == TYPEID_PLAYER) + { + int32 uiDmg = m_bIsRegularMode ? urand(5938, 6562) : urand(9025, 9975); + m_creature->DealDamage(target, uiDmg,NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, NULL, false); + } + }*/ + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiCheckTimer < uiDiff) + { + CheckVehicle(); + m_uiCheckTimer = 2000; + } else m_uiCheckTimer -= uiDiff; + + if(m_uiDragonAttackTimer <= uiDiff) + { + DoCast(m_creature, SPELL_SUMMON_BEAM, true); + m_uiDragonAttackTimer = 25000; + m_uiDragonMoveTimer = 16000; + uint8 uiText = urand(0, 2); + switch (uiText) + { + case 0: DoScriptText(SAY_STRIKE_1, m_creature); break; + case 1: DoScriptText(SAY_STRIKE_2, m_creature); break; + case 2: DoScriptText(SAY_STRIKE_3, m_creature); break; + } + } else m_uiDragonAttackTimer -= uiDiff; + + if(m_uiDragonMoveTimer <= uiDiff) + { + if(m_pInstance) + if(Creature* Dragon = m_pInstance->instance->GetCreature(m_uiAzureDrakeGUID)) + { + Dragon->GetMotionMaster()->MovementExpired(false); + Dragon->GetMotionMaster()->Clear(false); + Dragon->GetMotionMaster()->MovePoint(0, (m_creature->GetPositionX()-45)+rand()%90, (m_creature->GetPositionY()-45)+rand()%90, m_creature->GetPositionZ() + 30.0f); + } + m_uiDragonMoveTimer = 25000; + } else m_uiDragonMoveTimer -= uiDiff; + + if(!m_bIsCastChain) + { + if(m_uiOrbCast <= uiDiff) + { + m_uiOrbCast = 1000; + m_bIsCastChain = true; + SelectFourOrb(); + m_uiCoreTimer = 5000; + } else m_uiOrbCast -= uiDiff; + } + else + { + if(m_uiCoreTimer <= uiDiff) + { + m_uiCoreTimer = 5000; + m_bIsCastChain = false; + CastEnergy(); + m_uiOrbCast = 1000; + } else m_uiCoreTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL npc_varos_orbAI : public ScriptedAI +{ + npc_varos_orbAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->setFaction(14); + DoCast(m_creature, SPELL_CORE_VISUAL, true); + } + + void AttackStart(Unit* pWho) + { + } + + void UpdateAI(const uint32 diff) + { + } +}; + +struct MANGOS_DLL_DECL npc_varos_beam_targetAI : public ScriptedAI +{ + npc_varos_beam_targetAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + uint32 uiDeathTimer; + + void Reset() + { + m_creature->SetSpeedRate(MOVE_RUN, 0.5f, true); + uiDeathTimer = 15000; + } + + void UpdateAI(const uint32 diff) + { + if (uiDeathTimer < diff) + m_creature->ForcedDespawn(); + else uiDeathTimer -= diff; + } +}; + +CreatureAI* GetAI_boss_varos(Creature* pCreature) +{ + return new boss_varosAI (pCreature); +} + +CreatureAI* GetAI_npc_varos_orb(Creature* pCreature) +{ + return new npc_varos_orbAI (pCreature); +} + +CreatureAI* GetAI_npc_varos_beam_target(Creature* pCreature) +{ + return new npc_varos_beam_targetAI (pCreature); +} + +void AddSC_boss_varos() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_varos"; + newscript->GetAI = &GetAI_boss_varos; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_varos_orb"; + newscript->GetAI = &GetAI_npc_varos_orb; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_varos_beam_target"; + newscript->GetAI = &GetAI_npc_varos_beam_target; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/nexus/oculus/instance_oculus.cpp b/scripts/northrend/nexus/oculus/instance_oculus.cpp new file mode 100644 index 000000000..52b996c59 --- /dev/null +++ b/scripts/northrend/nexus/oculus/instance_oculus.cpp @@ -0,0 +1,240 @@ +/* Copyright (C) 2008 - 2010 TrinityCore +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ScriptData +SDName: instance_oculus +SD%Complete: 70% +SDComment: +SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" +#include "oculus.h" + +/* The Occulus encounters: +0 - Drakos the Interrogator +1 - Varos Cloudstrider +2 - Mage-Lord Urom +3 - Ley-Guardian Eregos */ + +enum +{ + SAY_VAROS_SPAWN = -1578029, +}; + +struct MANGOS_DLL_DECL instance_oculus : public ScriptedInstance +{ + instance_oculus(Map* pMap) : ScriptedInstance(pMap) + { + m_bIsRegularMode = pMap->IsRegularDifficulty(); + Initialize(); + }; + + uint64 uiDrakos; + uint64 m_uiVarosGUID; + uint64 m_uiUromGUID; + uint64 m_uiEregosGUID; + uint64 uiProect; + uint64 uiCacheEregosGUID; + uint64 uiCacheEregosHGUID; + uint64 m_uiSpotLightGUID; + + uint32 m_auiEncounter[MAX_ENCOUNTERS+1]; + + std::string strSaveData; + bool m_bIsRegularMode; + + void Initialize() + { + for (uint8 i = 0; i < MAX_ENCOUNTERS+1; ++i) + m_auiEncounter[i] = NOT_STARTED; + + uiCacheEregosGUID = 0; + m_uiSpotLightGUID = 0; + uiProect = 0; + m_uiVarosGUID = 0; + m_uiUromGUID = 0; + m_uiEregosGUID = 0; + m_auiEncounter[TYPE_ROBOTS] = 10; + m_auiEncounter[TYPE_UROM_PHASE] = 0; + } + + void OnObjectCreate(GameObject* pGO) + { + switch(pGO->GetEntry()) + { + case GO_EREGOS_CACHE: + uiCacheEregosGUID = pGO->GetGUID(); + break; + case GO_EREGOS_CACHE_H: + uiCacheEregosHGUID = pGO->GetGUID(); + break; + case GO_SPOTLIGHT: + m_uiSpotLightGUID = pGO->GetGUID(); + break; + } + } + + void OnCreatureCreate(Creature* pCreature) + { + switch(pCreature->GetEntry()) + { + case NPC_DRAKOS: + uiDrakos = pCreature->GetGUID(); + break; + case NPC_VAROS: + m_uiVarosGUID = pCreature->GetGUID(); + break; + case NPC_UROM: + m_uiUromGUID = pCreature->GetGUID(); + break; + case NPC_EREGOS: + m_uiEregosGUID = pCreature->GetGUID(); + break; + case NPC_BALGAR_IMAGE: + uiProect = pCreature->GetGUID(); + break; + } + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case TYPE_DRAKOS: + case TYPE_VAROS: + case TYPE_UROM: + m_auiEncounter[type] = data; + break; + case TYPE_EREGOS: + m_auiEncounter[type] = data; + if (data == DONE) + { + DoRespawnGameObject((m_bIsRegularMode ? uiCacheEregosGUID : uiCacheEregosHGUID), HOUR); + DoRespawnGameObject(m_uiSpotLightGUID, HOUR); + } + break; + case TYPE_ROBOTS: + m_auiEncounter[type] = m_auiEncounter[type] - data; + if(m_auiEncounter[type] == 0) + { + if(Creature* pVaros = instance->GetCreature(m_uiVarosGUID)) + { + DoScriptText(SAY_VAROS_SPAWN, pVaros); + pVaros->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pVaros->InterruptNonMeleeSpells(false); + pVaros->RemoveAurasDueToSpell(50053); + } + } + data = NOT_STARTED; + break; + case TYPE_UROM_PHASE: + m_auiEncounter[type] = data; + data = NOT_STARTED; + break; + } + + if (data == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + saveStream << m_auiEncounter[i] << " "; + + strSaveData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + uint32 GetData(uint32 type) + { + switch(type) + { + case TYPE_DRAKOS: + case TYPE_VAROS: + case TYPE_UROM: + case TYPE_EREGOS: + case TYPE_ROBOTS: + case TYPE_UROM_PHASE: + return m_auiEncounter[type]; + default: + return 0; + } + return 0; + } + + uint64 GetData64(uint32 identifier) + { + switch(identifier) + { + case DATA_DRAKOS: return uiDrakos; + case NPC_VAROS: return m_uiVarosGUID; + case NPC_UROM: return m_uiUromGUID; + case NPC_EREGOS: return m_uiEregosGUID; + } + return 0; + } + + const char* Save() + { + return strSaveData.c_str(); + } + + void Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + { + loadStream >> m_auiEncounter[i]; + + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } + + m_auiEncounter[TYPE_ROBOTS] = 10; + m_auiEncounter[TYPE_UROM_PHASE] = 0; + + OUT_LOAD_INST_DATA_COMPLETE; + } +}; + +InstanceData* GetInstanceData_instance_oculus(Map* pMap) +{ + return new instance_oculus(pMap); +} + +void AddSC_instance_oculus() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_oculus"; + newscript->GetInstanceData = &GetInstanceData_instance_oculus; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/nexus/oculus/oculus.cpp b/scripts/northrend/nexus/oculus/oculus.cpp new file mode 100644 index 000000000..d2fd61c45 --- /dev/null +++ b/scripts/northrend/nexus/oculus/oculus.cpp @@ -0,0 +1,232 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: oculus +SD%Complete: ?% +SDComment: by /dev/rsa +SDCategory: Oculus - mobs and special +EndScriptData */ + +#include "precompiled.h" +#include "oculus.h" +enum Spells +{ + SPELL_GREEN_SEAT = 49346, + SPELL_YELLOW_SEAT = 49460, + SPELL_RED_SEAT = 49464, +}; + +enum NPC +{ + NPC_GREEN_DRAGON = 27692, + NPC_YELLOW_DRAGON = 27755, + NPC_RED_DRAGON = 27756, +}; + +struct MANGOS_DLL_DECL mob_oculus_dragonAI : public ScriptedAI +{ + mob_oculus_dragonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + bool Active; + ObjectGuid ownerGUID; + uint32 seatSpell; + uint32 StartTimer; + + void Reset() + { + Active = false; + ownerGUID = ObjectGuid(); + StartTimer = 2000; + switch (m_creature->GetEntry()) + { + case NPC_GREEN_DRAGON: + seatSpell = SPELL_GREEN_SEAT; + break; + case NPC_RED_DRAGON: + seatSpell = SPELL_RED_SEAT; + break; + case NPC_YELLOW_DRAGON: + seatSpell = SPELL_YELLOW_SEAT; + break; + default: + seatSpell = 0; + break; + } + ownerGUID = m_creature->GetCreatorGuid(); + + if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID)) + owner->RemoveAurasDueToSpell(53797); + } + + void AttackStart(Unit *) {} + void MoveInLineOfSight(Unit*) {} + + void JustSummoned() + { + } + + void JustDied(Unit* killer) + { + if (!m_creature || m_creature->GetTypeId() != TYPEID_UNIT) + return; + + if (ownerGUID.IsEmpty()) + ownerGUID = m_creature->GetCreatorGuid(); + + Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID); + + if (!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + owner->RemoveAurasDueToSpell(seatSpell); + owner->RemoveAurasDueToSpell(53797); + m_creature->SetCreatorGuid(ObjectGuid()); + } + + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if (uiType != POINT_MOTION_TYPE && uiPointId == 0) + return; + + if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID)) + { + m_creature->setFaction(owner->getFaction()); + owner->CastSpell(m_creature, seatSpell, true); + owner->CastSpell(owner, 53797, true); + } + } + + void UpdateAI(const uint32 uiDiff) + { + + if (ownerGUID.IsEmpty()) + ownerGUID = m_creature->GetCreatorGuid(); + + if (!ownerGUID.IsEmpty()) + { + if (StartTimer < uiDiff && !Active) + { + if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID)) + { + float x, y, z; + owner->GetClosePoint(x, y, z, owner->GetObjectBoundingRadius(), 1.0f, owner->GetAngle(m_creature)); + m_creature->GetMotionMaster()->MovePoint(0, x, y, z); + Active = true; + } + } + else + StartTimer -= uiDiff; + } + else + if (StartTimer < uiDiff) + m_creature->ForcedDespawn(); + } +}; + +CreatureAI* GetAI_mob_oculus_dragon(Creature* pCreature) +{ + return new mob_oculus_dragonAI(pCreature); +} + +/*##### +# npc_robot +#####*/ + +struct MANGOS_DLL_DECL npc_oculus_robotAI : public ScriptedAI +{ + npc_oculus_robotAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + } + + void JustDied(Unit* pKiller) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_ROBOTS, 1); + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_oculus_robot(Creature* pCreature) +{ + return new npc_oculus_robotAI (pCreature); +} + +struct MANGOS_DLL_DECL npc_belgar_imageAI : public ScriptedAI +{ + npc_belgar_imageAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + } + + void UpdateAI(const uint32 diff) + { + if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + } +}; + +CreatureAI* GetAI_npc_belgar_image(Creature* pCreature) +{ + return new npc_belgar_imageAI (pCreature); +} + +void AddSC_oculus() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "mob_oculus_dragon"; + newscript->GetAI = &GetAI_mob_oculus_dragon; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_oculus_robot"; + newscript->GetAI = &GetAI_npc_oculus_robot; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_belgar_image"; + newscript->GetAI = &GetAI_npc_belgar_image; + newscript->RegisterSelf(); + +} diff --git a/scripts/northrend/nexus/oculus/oculus.h b/scripts/northrend/nexus/oculus/oculus.h new file mode 100644 index 000000000..586d85d5f --- /dev/null +++ b/scripts/northrend/nexus/oculus/oculus.h @@ -0,0 +1,43 @@ +/* Copyright (C) 2010 by /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_OCULUS_H +#define DEF_OCULUS_H +#include "BSW_ai.h" +#include "BSW_instance.h" + +enum +{ + TYPE_DRAKOS, + TYPE_VAROS, + TYPE_UROM, + TYPE_EREGOS, + TYPE_ROBOTS, + TYPE_UROM_PHASE, + MAX_ENCOUNTERS, + + DATA_DRAKOS, + DATA_VAROS, + DATA_UROM, + DATA_EREGOS, + + NPC_ROBOT = 27641, + NPC_BALGAR_IMAGE = 28012, + NPC_DRAKOS = 27654, + NPC_VAROS = 27447, + NPC_UROM = 27655, + NPC_EREGOS = 27656, +// + GO_DRAGON_CAGE_DOOR = 193995, + GO_EREGOS_CACHE = 191349, + GO_EREGOS_CACHE_H = 193603, + GO_SPOTLIGHT = 191351, + + BELGAR_TEXT_0 = 13267, + BELGAR_TEXT_1 = 13268, + BELGAR_TEXT_2 = 13269, + +}; + +#endif diff --git a/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp b/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp index 881126b53..825fc29da 100644 --- a/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp +++ b/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: Boss Sartharion -SD%Complete: 70% -SDComment: Flame wave, achievement and portal events need to be implemented +SD%Complete: 100% +SDComment: It's alive! ;) Now this is script is alive realy! (c) MaxXx2021 and PSZ SDCategory: Obsidian Sanctum EndScriptData */ @@ -58,12 +58,14 @@ enum SPELL_TAIL_LASH_H = 58957, // A sweeping tail strike hits all enemies behind the caster, inflicting 4375 to 5625 damage and stunning them for 2 sec. SPELL_WILL_OF_SARTHARION = 61254, // Sartharion's presence bolsters the resolve of the Twilight Drakes, increasing their total health by 25%. This effect also increases Sartharion's health by 25%. SPELL_LAVA_STRIKE = 57571, // (Real spell casted should be 57578) 57571 then trigger visual missile, then summon Lava Blaze on impact(spell 57572) + SPELL_CYCLONE_AURA_2 = 57598, SPELL_TWILIGHT_REVENGE = 60639, SPELL_PYROBUFFET = 56916, // currently used for hard enrage after 15 minutes SPELL_PYROBUFFET_RANGE = 58907, // possibly used when player get too far away from dummy creatures (2x creature entry 30494) SPELL_TWILIGHT_SHIFT_ENTER = 57620, // enter phase. Player get this when click GO + SPELL_TWILIGHT_SHIFT_DMG = 57874, // damage during being in twilight realm SPELL_TWILIGHT_SHIFT_REMOVAL = 61187, // leave phase SPELL_TWILIGHT_SHIFT_REMOVAL_ALL = 61190, // leave phase (probably version to make all leave) @@ -103,6 +105,8 @@ enum SPELL_HATCH_EGGS_EFFECT_H = 59190, SPELL_HATCH_EGGS_EFFECT = 58685, + NPC_TWILIGHT_EGG = 30882, + //Whelps NPC_TWILIGHT_WHELP = 30890, NPC_SHARTHARION_TWILIGHT_WHELP = 31214, @@ -112,9 +116,12 @@ enum SPELL_FLAME_TSUNAMI = 57494, // the visual dummy SPELL_FLAME_TSUNAMI_LEAP = 60241, // SPELL_EFFECT_138 some leap effect, causing caster to move in direction SPELL_FLAME_TSUNAMI_DMG_AURA = 57492, // periodic damage, npc has this aura + SPELL_FLAME_TSUNAMI_DMG = 57491, // damage players + SPELL_FLAME_TSUNAMI_BUFF = 60430, // buff Lava Blazes NPC_FLAME_TSUNAMI = 30616, // for the flame waves NPC_LAVA_BLAZE = 30643, // adds spawning from flame strike + NPC_FIRE_CYCLONE = 30648, //using these custom points for dragons start and end POINT_ID_INIT = 100, @@ -156,6 +163,21 @@ Waypoint m_aDragonCommon[]= {3209.969f, 566.523f, 98.652f} }; +float m_afTsunamiStartLoc[5][4]= +{ + //left to right + {3201.0f, 487.75f, 58.6f, 6.23f}, + {3201.0f, 533.54f, 58.6f, 6.23f}, + {3201.0f, 579.14f, 58.6f, 6.23f}, + //right to left + {3287.5f, 552.53f, 58.6f, 3.19f}, + {3287.5f, 511.10f, 58.6f, 3.19f}, +}; + +uint64 m_uiAcolyteShadronGUID; +uint64 m_uiAcolyteVesperonGUID; +std::list m_lEggsGUIDList; + /*###### ## Boss Sartharion ######*/ @@ -166,6 +188,9 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_bTenebronHelpedInFight = false; + m_bShadronHelpedInFight = false; + m_bVesperonHelpedInFight = false; Reset(); } @@ -186,11 +211,25 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI uint32 m_uiFlameBreathTimer; uint32 m_uiTailSweepTimer; uint32 m_uiCleaveTimer; - uint32 m_uiLavaStrikeTimer; + uint32 m_uiCycloneAuraTimer; bool m_bHasCalledTenebron; bool m_bHasCalledShadron; bool m_bHasCalledVesperon; + bool m_bTenebronHelpedInFight; + bool m_bShadronHelpedInFight; + bool m_bVesperonHelpedInFight; + + bool bCanUseWill; + bool bFirstWill; + uint32 m_uiSarthHealth; + uint32 m_uiTeneHealth; + uint32 m_uiShadHealth; + uint32 m_uiVespHealth; + + uint32 m_uiCheckTwilightTimer; + + std::list m_lFireCyclones; void Reset() { @@ -206,16 +245,58 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI m_uiFlameTsunamiTimer = 30000; m_uiFlameBreathTimer = 20000; - m_uiTailSweepTimer = 20000; + m_uiTailSweepTimer = 5000; m_uiCleaveTimer = 7000; - m_uiLavaStrikeTimer = 5000; + m_uiCycloneAuraTimer = 10000; m_bHasCalledTenebron = false; m_bHasCalledShadron = false; m_bHasCalledVesperon = false; - if (m_creature->HasAura(SPELL_TWILIGHT_REVENGE)) - m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_REVENGE); + bFirstWill = true; + + m_uiCheckTwilightTimer = 2000; + + if (m_pInstance) + { + Creature* pTene = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_TENEBRON)); + Creature* pShad = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADRON)); + Creature* pVesp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VESPERON)); + + if (m_bTenebronHelpedInFight && pTene) + { + if (pTene->isDead()) + pTene->Respawn(); + else + pTene->AI()->EnterEvadeMode(); + } + + if (m_bShadronHelpedInFight && pShad) + { + if (pShad->isDead()) + pShad->Respawn(); + else + pShad->AI()->EnterEvadeMode(); + } + + if (m_bVesperonHelpedInFight && pVesp) + { + if (pVesp->isDead()) + pVesp->Respawn(); + else + pVesp->AI()->EnterEvadeMode(); + } + } + + m_lFireCyclones.clear(); + GetCreatureListWithEntryInGrid(m_lFireCyclones, m_creature, NPC_FIRE_CYCLONE, 100.0f); + + m_bTenebronHelpedInFight = false; + m_bShadronHelpedInFight = false; + m_bVesperonHelpedInFight = false; + + m_creature->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SAR); + m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_REVENGE); } void JustReachedHome() @@ -228,8 +309,6 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI { DoScriptText(SAY_SARTHARION_AGGRO,m_creature); - m_creature->SetInCombatWithZone(); - if (m_pInstance) { m_pInstance->SetData(TYPE_SARTHARION_EVENT, IN_PROGRESS); @@ -237,9 +316,26 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI } } + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (uiDamage > m_creature->GetHealth()) + { + uint8 uiHardMode = 0; + if (m_bTenebronHelpedInFight) + ++uiHardMode; + if (m_bShadronHelpedInFight) + ++uiHardMode; + if (m_bVesperonHelpedInFight) + ++uiHardMode; + + if (uiHardMode) + m_creature->UpdateEntry(m_creature->GetEntry()*10+uiHardMode); + } + } + void JustDied(Unit* pKiller) { - DoScriptText(SAY_SARTHARION_DEATH,m_creature); + DoScriptText(SAY_SARTHARION_DEATH, m_creature); if (m_pInstance) m_pInstance->SetData(TYPE_SARTHARION_EVENT, DONE); @@ -247,7 +343,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI void KilledUnit(Unit* pVictim) { - switch(urand(0, 2)) + switch (urand(0, 2)) { case 0: DoScriptText(SAY_SARTHARION_SLAY_1, m_creature); break; case 1: DoScriptText(SAY_SARTHARION_SLAY_2, m_creature); break; @@ -257,16 +353,19 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI void FetchDragons() { - Creature* pTene = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_TENEBRON)); - Creature* pShad = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SHADRON)); - Creature* pVesp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_VESPERON)); + Creature* pTene = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_TENEBRON)); + Creature* pShad = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADRON)); + Creature* pVesp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VESPERON)); //if at least one of the dragons are alive and are being called - bool bCanUseWill = false; + uint8 uiCountFetchableDragons = 0; if (pTene && pTene->isAlive() && !pTene->getVictim()) { - bCanUseWill = true; + ++uiCountFetchableDragons; + pTene->CastSpell(pTene, SPELL_POWER_OF_TENEBRON, false); + pTene->AddSplineFlag(SPLINEFLAG_FLYING); + pTene->RemoveSplineFlag(SPLINEFLAG_WALKMODE); pTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ); if (!pTene->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) @@ -275,7 +374,10 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI if (pShad && pShad->isAlive() && !pShad->getVictim()) { - bCanUseWill = true; + ++uiCountFetchableDragons; + pShad->CastSpell(pShad, SPELL_POWER_OF_SHADRON, false); + pShad->AddSplineFlag(SPLINEFLAG_FLYING); + pShad->RemoveSplineFlag(SPLINEFLAG_WALKMODE); pShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ); if (!pShad->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) @@ -284,46 +386,65 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI if (pVesp && pVesp->isAlive() && !pVesp->getVictim()) { - bCanUseWill = true; + ++uiCountFetchableDragons; + pVesp->CastSpell(pVesp, SPELL_POWER_OF_VESPERON, false); + pVesp->AddSplineFlag(SPLINEFLAG_FLYING); + pVesp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); pVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ); if (!pVesp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) pVesp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } - if (bCanUseWill) + if (uiCountFetchableDragons) DoCastSpellIfCan(m_creature, SPELL_WILL_OF_SARTHARION); + + m_pInstance->SetData(TYPE_ALIVE_DRAGONS, uiCountFetchableDragons); } - void CallDragon(uint32 uiDataId) + void CallDragon(uint32 uiEntry) { if (m_pInstance) { - Creature* pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(uiDataId)); + Creature* pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(uiEntry)); if (pTemp && pTemp->isAlive() && !pTemp->getVictim()) { - if (pTemp->HasSplineFlag(SPLINEFLAG_WALKMODE)) - pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (pTemp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_uiSarthHealth = m_creature->GetHealth(); + DoCast(m_creature, SPELL_WILL_OF_SARTHARION, false); + bCanUseWill = true; int32 iTextId = 0; - switch(pTemp->GetEntry()) + Creature* pAdd = NULL; + pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_TENEBRON)); + if (pAdd) + m_uiTeneHealth = pAdd->GetHealth(); + pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_SHADRON)); + if (pAdd) + m_uiShadHealth = pAdd->GetHealth(); + pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_VESPERON)); + if (pAdd) + m_uiVespHealth = pAdd->GetHealth(); + + switch(uiEntry) { case NPC_TENEBRON: iTextId = SAY_SARTHARION_CALL_TENEBRON; pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aTene[1].m_fX, m_aTene[1].m_fY, m_aTene[1].m_fZ); + m_bTenebronHelpedInFight = true; break; case NPC_SHADRON: iTextId = SAY_SARTHARION_CALL_SHADRON; pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aShad[1].m_fX, m_aShad[1].m_fY, m_aShad[1].m_fZ); + m_bShadronHelpedInFight = true; break; case NPC_VESPERON: iTextId = SAY_SARTHARION_CALL_VESPERON; pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aVesp[1].m_fX, m_aVesp[1].m_fY, m_aVesp[1].m_fZ); + m_bVesperonHelpedInFight = true; break; } @@ -345,10 +466,19 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->isAlive()) - DoScriptText(WHISPER_LAVA_CHURN, m_creature,i->getSource()); + DoScriptText(WHISPER_LAVA_CHURN, m_creature, i->getSource()); } } } + + uint8 uiTsunamiDirection = urand(0, 1); + uint8 uiTsunamiWavesAmount = 3; + if (uiTsunamiDirection) + uiTsunamiWavesAmount = 2; + for (uint8 i = uiTsunamiDirection*3; i < uiTsunamiDirection*3+uiTsunamiWavesAmount; ++i) + { + m_creature->SummonCreature(NPC_FLAME_TSUNAMI, m_afTsunamiStartLoc[i][0], m_afTsunamiStartLoc[i][1], m_afTsunamiStartLoc[i][2], m_afTsunamiStartLoc[i][3], TEMPSUMMON_TIMED_DESPAWN, 18000); + } } void UpdateAI(const uint32 uiDiff) @@ -357,18 +487,57 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + if (bCanUseWill) + { + if (bFirstWill) + { + m_creature->SetHealth(m_creature->GetHealth()*1.25); + } + else + { + m_creature->SetHealth(m_uiSarthHealth); + Creature* pTemp = NULL; + pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_TENEBRON)); + if (pTemp && pTemp->isAlive()) + pTemp->SetHealth(m_uiTeneHealth); + pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_SHADRON)); + if (pTemp && pTemp->isAlive()) + pTemp->SetHealth(m_uiShadHealth); + pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_VESPERON)); + if (pTemp && pTemp->isAlive()) + pTemp->SetHealth(m_uiVespHealth); + } + bCanUseWill = false; + bFirstWill = false; + } + //spell will target dragons, if they are still alive at 35% - if (!m_bIsBerserk && m_creature->GetHealthPercent() < 35.0f) + if (!m_bIsBerserk && m_creature->GetHealthPercent() <= 35.0f) { DoScriptText(SAY_SARTHARION_BERSERK, m_creature); - DoCastSpellIfCan(m_creature, SPELL_BERSERK); + //DoCast(m_creature, SPELL_BERSERK); + Creature* pTemp = NULL; + pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_TENEBRON)); + if (pTemp && pTemp->isAlive()) + pTemp->CastSpell(pTemp, 27680, true); + pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADRON)); + if (pTemp && pTemp->isAlive()) + pTemp->CastSpell(pTemp, 27680, true); + pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VESPERON)); + if (pTemp && pTemp->isAlive()) + pTemp->CastSpell(pTemp, 27680, true); + m_bIsBerserk = true; } //soft enrage if (!m_bIsSoftEnraged && m_creature->GetHealthPercent() <= 10.0f) { - // TODO + if (!m_lFireCyclones.empty()) + for (std::list::iterator iter = m_lFireCyclones.begin(); iter != m_lFireCyclones.end(); ++iter) + if (*iter) + (*iter)->CastSpell(*iter, SPELL_CYCLONE_AURA_2, true); + m_bIsSoftEnraged = true; } @@ -377,7 +546,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI { if (m_uiEnrageTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_PYROBUFFET, CAST_TRIGGERED); + DoCast(m_creature, SPELL_PYROBUFFET, true); m_bIsHardEnraged = true; } else @@ -388,6 +557,14 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI if (m_uiFlameTsunamiTimer < uiDiff) { SendFlameTsunami(); + switch(urand(0, 3)) + { + case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break; + case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break; + case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break; + case 3: DoScriptText(SAY_SARTHARION_SPECIAL_4, m_creature); break; + } + m_uiFlameTsunamiTimer = 30000; } else @@ -397,7 +574,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI if (m_uiFlameBreathTimer < uiDiff) { DoScriptText(SAY_SARTHARION_BREATH, m_creature); - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H); + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H); m_uiFlameBreathTimer = urand(25000, 35000); } else @@ -406,8 +583,8 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI // Tail Sweep if (m_uiTailSweepTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H); - m_uiTailSweepTimer = urand(15000, 20000); + DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H); + m_uiTailSweepTimer = urand(5000, 7000); } else m_uiTailSweepTimer -= uiDiff; @@ -415,35 +592,43 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI // Cleave if (m_uiCleaveTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE); + DoCast(m_creature->getVictim(), SPELL_CLEAVE); m_uiCleaveTimer = urand(7000, 10000); } else m_uiCleaveTimer -= uiDiff; // Lavas Strike - if (m_uiLavaStrikeTimer < uiDiff) + if (m_uiCycloneAuraTimer < uiDiff) { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (!m_lFireCyclones.empty()) { - DoCastSpellIfCan(pTarget, SPELL_LAVA_STRIKE); - - switch(urand(0, 15)) + std::list::iterator iter = m_lFireCyclones.begin(); + advance(iter, urand(0, m_lFireCyclones.size()-1)); + if (*iter) { - case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break; - case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break; - case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break; + (*iter)->CastSpell(*iter, SPELL_CYCLONE_AURA_2, true); + + switch(urand(0, 15)) + { + case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break; + case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break; + case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break; + } } } - m_uiLavaStrikeTimer = urand(5000, 20000); + if (m_bIsSoftEnraged) + m_uiCycloneAuraTimer = 10000; + else + m_uiCycloneAuraTimer = urand(20000, 25000); } else - m_uiLavaStrikeTimer -= uiDiff; + m_uiCycloneAuraTimer -= uiDiff; // call tenebron if (!m_bHasCalledTenebron && m_uiTenebronTimer < uiDiff) { - CallDragon(DATA_TENEBRON); + CallDragon(NPC_TENEBRON); m_bHasCalledTenebron = true; } else @@ -452,7 +637,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI // call shadron if (!m_bHasCalledShadron && m_uiShadronTimer < uiDiff) { - CallDragon(DATA_SHADRON); + CallDragon(NPC_SHADRON); m_bHasCalledShadron = true; } else @@ -461,12 +646,67 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI // call vesperon if (!m_bHasCalledVesperon && m_uiVesperonTimer < uiDiff) { - CallDragon(DATA_VESPERON); + CallDragon(NPC_VESPERON); m_bHasCalledVesperon = true; } else m_uiVesperonTimer -= uiDiff; + if (m_uiCheckTwilightTimer < uiDiff) + { + bool bNoAliveTwilightRealm = true; + if (m_pInstance) + { + if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID)) + { + if (pAcolyte->isAlive()) + { + bNoAliveTwilightRealm = false; + } + } + if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID)) + { + if (pAcolyte->isAlive()) + { + bNoAliveTwilightRealm = false; + } + } + if (!m_lEggsGUIDList.empty()) + { + for (std::list::iterator itr = m_lEggsGUIDList.begin(); itr != m_lEggsGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + { + if (pTemp->isAlive()) + { + bNoAliveTwilightRealm = false; + break; + } + } + } + } + if (bNoAliveTwilightRealm) + { + Map* pMap = m_creature->GetMap(); + + if (pMap && pMap->IsDungeon()) + { + Map::PlayerList const &PlayerList = pMap->GetPlayers(); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive()) + i->getSource()->CastSpell(i->getSource(), SPELL_TWILIGHT_SHIFT_REMOVAL, true); + } + } + } + } + m_uiCheckTwilightTimer = 2000; + } + else + m_uiCheckTwilightTimer -= uiDiff; + DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(uiDiff); @@ -529,20 +769,38 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI uint32 m_uiWaypointId; uint32 m_uiMoveNextTimer; - int32 m_iPortalRespawnTime; bool m_bCanMoveFree; void Reset() { - if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_uiWaypointId = 0; m_uiMoveNextTimer = 500; - m_iPortalRespawnTime = 30000; m_bCanMoveFree = false; } + void AttackStart(Unit* pWho) + { + if (!pWho || m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) + 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); + } + } + + void JustReachedHome() + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + } + void MovementInform(uint32 uiType, uint32 uiPointId) { if (!m_pInstance || uiType != POINT_MOTION_TYPE) @@ -562,6 +820,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI { m_creature->GetMotionMaster()->Clear(); m_bCanMoveFree = false; + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); m_creature->SetInCombatWithZone(); return; } @@ -601,98 +860,206 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI } } + //Removes debuff from players + void RemoveDebuff(uint32 uiSpellId) + { + Map* pMap = m_creature->GetMap(); + + if (pMap && pMap->IsDungeon()) + { + Map::PlayerList const &PlayerList = pMap->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + i->getSource()->RemoveAurasDueToSpell(uiSpellId); + if (uiSpellId == SPELL_TWILIGHT_SHIFT_ENTER) + i->getSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_DMG); + } + } + } + //"opens" the portal and does the "opening" whisper void OpenPortal() { int32 iTextId = 0; + int32 iPortalRespawnTime = 0; //there are 4 portal spawn locations, each are expected to be spawned with negative spawntimesecs in database //using a grid search here seem to be more efficient than caching all four guids //in instance script and calculate range to each. - GameObject* pPortal = GetClosestGameObjectWithEntry(m_creature,GO_TWILIGHT_PORTAL,50.0f); - - switch(m_creature->GetEntry()) + if (GameObject* pPortal = GetClosestGameObjectWithEntry(m_creature, GO_TWILIGHT_PORTAL, 100.0f)) { - case NPC_TENEBRON: - iTextId = WHISPER_HATCH_EGGS; - break; - case NPC_SHADRON: - case NPC_VESPERON: - iTextId = WHISPER_OPEN_PORTAL; - break; - } + Creature* pAcolyte = NULL; + switch(m_creature->GetEntry()) + { + case NPC_TENEBRON: + iTextId = WHISPER_HATCH_EGGS; + m_lEggsGUIDList.clear(); + for (uint8 i=0; i<6; ++i) + { + if (Creature* pEgg = m_creature->SummonCreature(NPC_TWILIGHT_EGG, pPortal->GetPositionX()-10+urand(0, 20), pPortal->GetPositionY()-10+urand(0, 20), pPortal->GetPositionZ()+1.0f, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000)) + { + pEgg->SetPhaseMask(16, true); + m_lEggsGUIDList.push_back(pEgg->GetGUID()); + } + } + iPortalRespawnTime = 20; + break; + case NPC_SHADRON: + iTextId = WHISPER_OPEN_PORTAL; + if (m_pInstance) + { + pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID); + if (!pAcolyte || (pAcolyte && pAcolyte->isDead())) + { + pAcolyte = NULL; + if (pAcolyte = m_creature->SummonCreature(NPC_ACOLYTE_OF_SHADRON, pPortal->GetPositionX()-10+urand(0, 20), pPortal->GetPositionY()-10+urand(0, 20), pPortal->GetPositionZ()+1.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000)) + { + m_uiAcolyteShadronGUID = pAcolyte->GetGUID(); + pAcolyte->SetPhaseMask(16, true); + } + } + if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS) + { + if (Creature* pSarth = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SARTHARION))) + pSarth->CastSpell(pSarth, SPELL_GIFT_OF_TWILIGTH_SAR, true); + } + else + { + if (Creature* pShad = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADRON))) + pShad->CastSpell(pShad, SPELL_GIFT_OF_TWILIGTH_SHA, true); + } + } + iPortalRespawnTime = 60; + break; + case NPC_VESPERON: + iTextId = WHISPER_OPEN_PORTAL; + if (m_pInstance) + { + uint32 uiTempSpell; + if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS) + uiTempSpell = 58835; + else + uiTempSpell = 57935; + + SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(uiTempSpell); + if (pTempSpell) + { + pTempSpell->StackAmount = 1; + pTempSpell->procCharges = 0; + m_creature->CastSpell(m_creature, pTempSpell, true); + } + + pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID); + if (!pAcolyte || (pAcolyte && pAcolyte->isDead())) + { + pAcolyte = NULL; + if (pAcolyte = m_creature->SummonCreature(NPC_ACOLYTE_OF_VESPERON, pPortal->GetPositionX()-10+urand(0, 20), pPortal->GetPositionY()-10+urand(0, 20), pPortal->GetPositionZ()+1.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000)) + { + m_uiAcolyteVesperonGUID = pAcolyte->GetGUID(); + pAcolyte->SetPhaseMask(16, true); + } + } + } + iPortalRespawnTime = 60; + break; + } - DoRaidWhisper(iTextId); + DoRaidWhisper(iTextId); - //By using SetRespawnTime() we will actually "spawn" the object with our defined time. - //Once time is up, portal will disappear again. - if (pPortal && !pPortal->isSpawned()) - { - pPortal->SetRespawnTime(m_iPortalRespawnTime); - pPortal->Refresh(); - } + //By using SetRespawnTime() we will actually "spawn" the object with our defined time. + //Once time is up, portal will disappear again. - //Unclear what are expected to happen if one drake has a portal open already - //Refresh respawnTime so time again are set to 30secs? + pPortal->SetRespawnTime(iPortalRespawnTime); + pPortal->UpdateObjectVisibility(); + + //Unclear what are expected to happen if one drake has a portal open already + //Refresh respawnTime so time again are set to 30secs? + } } - //Removes each drakes unique debuff from players - void RemoveDebuff(uint32 uiSpellId) - { - Map* pMap = m_creature->GetMap(); - if (pMap && pMap->IsDungeon()) + void CheckTwilightRealm() + { + bool bNoAliveTwilightRealm = true; + if (m_pInstance) { - Map::PlayerList const &PlayerList = pMap->GetPlayers(); - - if (PlayerList.isEmpty()) - return; - - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - { - if (i->getSource()->isAlive() && i->getSource()->HasAura(uiSpellId)) - i->getSource()->RemoveAurasDueToSpell(uiSpellId); - } + if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID)) + if (pAcolyte->isAlive()) + bNoAliveTwilightRealm = false; + if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID)) + if (pAcolyte->isAlive()) + bNoAliveTwilightRealm = false; + if (!m_lEggsGUIDList.empty()) + for (std::list::iterator itr = m_lEggsGUIDList.begin(); itr != m_lEggsGUIDList.end(); ++itr) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( *itr)) + if (pTemp->isAlive()) + { + bNoAliveTwilightRealm = false; + break; + } + if (bNoAliveTwilightRealm) + RemoveDebuff(SPELL_TWILIGHT_SHIFT_ENTER); } } void JustDied(Unit* pKiller) { int32 iTextId = 0; - uint32 uiSpellId = 0; switch(m_creature->GetEntry()) { case NPC_TENEBRON: + { iTextId = SAY_TENEBRON_DEATH; - uiSpellId = SPELL_POWER_OF_TENEBRON; + + if (!m_lEggsGUIDList.empty()) + for (std::list::iterator itr = m_lEggsGUIDList.begin(); itr != m_lEggsGUIDList.end(); ++itr) + if (Creature* pEgg = m_creature->GetMap()->GetCreature( *itr)) + pEgg->ForcedDespawn(); break; + } case NPC_SHADRON: + { iTextId = SAY_SHADRON_DEATH; - uiSpellId = SPELL_POWER_OF_SHADRON; + + if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID)) + pAcolyte->DealDamage(pAcolyte, pAcolyte->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + break; + } case NPC_VESPERON: + { iTextId = SAY_VESPERON_DEATH; - uiSpellId = SPELL_POWER_OF_VESPERON; + + if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID)) + pAcolyte->DealDamage(pAcolyte, pAcolyte->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + break; + } } DoScriptText(iTextId, m_creature); - RemoveDebuff(uiSpellId); - if (m_pInstance) { // not if solo mini-boss fight if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS) + { + RemoveDebuff(SPELL_TWILIGHT_SHIFT_ENTER); return; + } // Twilight Revenge to main boss - if (Creature* pSartharion = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SARTHARION))) + if (Creature* pSartharion = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SARTHARION))) { if (pSartharion->isAlive()) - m_creature->CastSpell(pSartharion,SPELL_TWILIGHT_REVENGE,true); + m_creature->CastSpell(pSartharion, SPELL_TWILIGHT_REVENGE, true); + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); } } } @@ -721,23 +1088,30 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI struct MANGOS_DLL_DECL mob_tenebronAI : public dummy_dragonAI { - mob_tenebronAI(Creature* pCreature) : dummy_dragonAI(pCreature) { Reset(); } + mob_tenebronAI(Creature* pCreature) : dummy_dragonAI(pCreature) + { + Reset(); + } uint32 m_uiShadowBreathTimer; uint32 m_uiShadowFissureTimer; uint32 m_uiHatchEggTimer; + uint32 m_uiCheckTimer; + uint32 m_uiTailSweepTimer; void Reset() { - m_uiShadowBreathTimer = 20000; - m_uiShadowFissureTimer = 5000; - m_uiHatchEggTimer = 30000; + m_uiShadowBreathTimer = 10000; + m_uiShadowFissureTimer = 8000; + m_uiHatchEggTimer = 15000; + m_uiCheckTimer = 2000; + m_uiTailSweepTimer = 5000; + m_lEggsGUIDList.clear(); } void Aggro(Unit* pWho) { DoScriptText(SAY_TENEBRON_AGGRO, m_creature); - DoCastSpellIfCan(m_creature, SPELL_POWER_OF_TENEBRON); } void KilledUnit(Unit* pVictim) @@ -758,9 +1132,9 @@ struct MANGOS_DLL_DECL mob_tenebronAI : public dummy_dragonAI if (m_uiShadowFissureTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H); + DoCast(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H); - m_uiShadowFissureTimer = urand(15000, 20000); + m_uiShadowFissureTimer = urand(8000, 10000); } else m_uiShadowFissureTimer -= uiDiff; @@ -769,12 +1143,36 @@ struct MANGOS_DLL_DECL mob_tenebronAI : public dummy_dragonAI if (m_uiShadowBreathTimer < uiDiff) { DoScriptText(SAY_TENEBRON_BREATH, m_creature); - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H); - m_uiShadowBreathTimer = urand(20000, 25000); + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H); + m_uiShadowBreathTimer = urand(10000, 30000); } else m_uiShadowBreathTimer -= uiDiff; + if (m_uiTailSweepTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H); + m_uiTailSweepTimer = urand(5000, 7000); + } + else + m_uiTailSweepTimer -= uiDiff; + + if (m_uiHatchEggTimer < uiDiff) + { + OpenPortal(); + m_uiHatchEggTimer = 45000; + } + else + m_uiHatchEggTimer -= uiDiff; + + if (m_uiCheckTimer < uiDiff && m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS) + { + CheckTwilightRealm(); + m_uiCheckTimer = 2000; + } + else + m_uiCheckTimer -= uiDiff; + DoMeleeAttackIfReady(); } }; @@ -790,29 +1188,30 @@ CreatureAI* GetAI_mob_tenebron(Creature* pCreature) struct MANGOS_DLL_DECL mob_shadronAI : public dummy_dragonAI { - mob_shadronAI(Creature* pCreature) : dummy_dragonAI(pCreature) { Reset(); } + mob_shadronAI(Creature* pCreature) : dummy_dragonAI(pCreature) + { + Reset(); + } uint32 m_uiShadowBreathTimer; uint32 m_uiShadowFissureTimer; uint32 m_uiAcolyteShadronTimer; + uint32 m_uiCheckTimer; + uint32 m_uiTailSweepTimer; void Reset() { - m_uiShadowBreathTimer = 20000; - m_uiShadowFissureTimer = 5000; - m_uiAcolyteShadronTimer = 60000; - - if (m_creature->HasAura(SPELL_TWILIGHT_TORMENT_VESP)) - m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP); - - if (m_creature->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA)) - m_creature->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA); + m_uiShadowBreathTimer = 10000; + m_uiShadowFissureTimer = 8000; + m_uiAcolyteShadronTimer = 15000; + m_uiCheckTimer = 2000; + m_uiTailSweepTimer = 5000; + m_uiAcolyteShadronGUID = 0; } void Aggro(Unit* pWho) { DoScriptText(SAY_SHADRON_AGGRO,m_creature); - DoCastSpellIfCan(m_creature, SPELL_POWER_OF_SHADRON); } void KilledUnit(Unit* pVictim) @@ -833,9 +1232,9 @@ struct MANGOS_DLL_DECL mob_shadronAI : public dummy_dragonAI if (m_uiShadowFissureTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H); + DoCast(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H); - m_uiShadowFissureTimer = urand(15000, 20000); + m_uiShadowFissureTimer = urand(8000, 10000); } else m_uiShadowFissureTimer -= uiDiff; @@ -844,12 +1243,36 @@ struct MANGOS_DLL_DECL mob_shadronAI : public dummy_dragonAI if (m_uiShadowBreathTimer < uiDiff) { DoScriptText(SAY_SHADRON_BREATH, m_creature); - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H); - m_uiShadowBreathTimer = urand(20000, 25000); + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H); + m_uiShadowBreathTimer = urand(10000, 30000); } else m_uiShadowBreathTimer -= uiDiff; + if (m_uiTailSweepTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H); + m_uiTailSweepTimer = urand(5000, 7000); + } + else + m_uiTailSweepTimer -= uiDiff; + + if (m_uiAcolyteShadronTimer < uiDiff) + { + OpenPortal(); + m_uiAcolyteShadronTimer = 60000; + } + else + m_uiAcolyteShadronTimer -= uiDiff; + + if (m_uiCheckTimer < uiDiff && m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS) + { + CheckTwilightRealm(); + m_uiCheckTimer = 2000; + } + else + m_uiCheckTimer -= uiDiff; + DoMeleeAttackIfReady(); } }; @@ -865,23 +1288,30 @@ CreatureAI* GetAI_mob_shadron(Creature* pCreature) struct MANGOS_DLL_DECL mob_vesperonAI : public dummy_dragonAI { - mob_vesperonAI(Creature* pCreature) : dummy_dragonAI(pCreature) { Reset(); } + mob_vesperonAI(Creature* pCreature) : dummy_dragonAI(pCreature) + { + Reset(); + } uint32 m_uiShadowBreathTimer; uint32 m_uiShadowFissureTimer; uint32 m_uiAcolyteVesperonTimer; + uint32 m_uiCheckTimer; + uint32 m_uiTailSweepTimer; void Reset() { - m_uiShadowBreathTimer = 20000; - m_uiShadowFissureTimer = 5000; - m_uiAcolyteVesperonTimer = 60000; + m_uiShadowBreathTimer = 10000; + m_uiShadowFissureTimer = 8000; + m_uiAcolyteVesperonTimer = 15000; + m_uiCheckTimer = 2000; + m_uiTailSweepTimer = 5000; + m_uiAcolyteVesperonGUID = 0; } void Aggro(Unit* pWho) { DoScriptText(SAY_VESPERON_AGGRO,m_creature); - DoCastSpellIfCan(m_creature, SPELL_POWER_OF_VESPERON); } void KilledUnit(Unit* pVictim) @@ -902,9 +1332,9 @@ struct MANGOS_DLL_DECL mob_vesperonAI : public dummy_dragonAI if (m_uiShadowFissureTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H); + DoCast(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H); - m_uiShadowFissureTimer = urand(15000, 20000); + m_uiShadowFissureTimer = urand(8000, 10000); } else m_uiShadowFissureTimer -= uiDiff; @@ -913,12 +1343,36 @@ struct MANGOS_DLL_DECL mob_vesperonAI : public dummy_dragonAI if (m_uiShadowBreathTimer < uiDiff) { DoScriptText(SAY_VESPERON_BREATH, m_creature); - DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H); - m_uiShadowBreathTimer = urand(20000, 25000); + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H); + m_uiShadowBreathTimer = urand(10000, 30000); } else m_uiShadowBreathTimer -= uiDiff; + if (m_uiTailSweepTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H); + m_uiTailSweepTimer = urand(5000, 7000); + } + else + m_uiTailSweepTimer -= uiDiff; + + if (m_uiAcolyteVesperonTimer < uiDiff) + { + OpenPortal(); + m_uiAcolyteVesperonTimer = 60000; + } + else + m_uiAcolyteVesperonTimer -= uiDiff; + + if (m_uiCheckTimer < uiDiff && m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS) + { + CheckTwilightRealm(); + m_uiCheckTimer = 2000; + } + else + m_uiCheckTimer -= uiDiff; + DoMeleeAttackIfReady(); } }; @@ -944,14 +1398,6 @@ struct MANGOS_DLL_DECL mob_acolyte_of_shadronAI : public ScriptedAI void Reset() { - if (m_pInstance) - { - //if not solo figth, buff main boss, else place debuff on mini-boss. both spells TARGET_SCRIPT - if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS) - DoCastSpellIfCan(m_creature, SPELL_GIFT_OF_TWILIGTH_SAR); - else - DoCastSpellIfCan(m_creature, SPELL_GIFT_OF_TWILIGTH_SHA); - } } void JustDied(Unit* killer) @@ -963,7 +1409,7 @@ struct MANGOS_DLL_DECL mob_acolyte_of_shadronAI : public ScriptedAI if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS) { //not solo fight, so main boss has deduff - pDebuffTarget = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SARTHARION)); + pDebuffTarget = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SARTHARION)); if (pDebuffTarget && pDebuffTarget->isAlive() && pDebuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SAR)) pDebuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SAR); @@ -971,7 +1417,7 @@ struct MANGOS_DLL_DECL mob_acolyte_of_shadronAI : public ScriptedAI else { //event not in progress, then solo fight and must remove debuff mini-boss - pDebuffTarget = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SHADRON)); + pDebuffTarget = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SHADRON)); if (pDebuffTarget && pDebuffTarget->isAlive() && pDebuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA)) pDebuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA); @@ -1009,18 +1455,25 @@ struct MANGOS_DLL_DECL mob_acolyte_of_vesperonAI : public ScriptedAI void Reset() { - DoCastSpellIfCan(m_creature, SPELL_TWILIGHT_TORMENT_VESP_ACO); } void JustDied(Unit* pKiller) { - // remove twilight torment on Vesperon - if (m_pInstance) + // remove twilight torment + Map* pMap = m_creature->GetMap(); + + if (pMap && pMap->IsDungeon()) { - Creature* pVesperon = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_VESPERON)); + Map::PlayerList const &PlayerList = pMap->GetPlayers(); + + if (PlayerList.isEmpty()) + return; - if (pVesperon && pVesperon->isAlive() && pVesperon->HasAura(SPELL_TWILIGHT_TORMENT_VESP)) - pVesperon->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP); + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + i->getSource()->RemoveAurasDueToSpell(57935); + i->getSource()->RemoveAurasDueToSpell(58835); + } } } @@ -1046,12 +1499,36 @@ struct MANGOS_DLL_DECL mob_twilight_eggsAI : public ScriptedAI { mob_twilight_eggsAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + uint32 m_uiSummonWhelpTimer; + void Reset() { + m_uiSummonWhelpTimer = 20000; } - void AttackStart(Unit* pWho) { } - void MoveInLineOfSight(Unit* pWho) { } + void AttackStart(Unit* pWho) + { + } + + void MoveInLineOfSight(Unit* pWho) + { + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiSummonWhelpTimer < uiDiff) + { + if (Creature* pWhelp = DoSpawnCreature(NPC_TWILIGHT_WHELP, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pWhelp->SetPhaseMask(1, true); + pWhelp->SetInCombatWithZone(); + } + m_uiSummonWhelpTimer = 20000; + m_creature->ForcedDespawn(); + } + else + m_uiSummonWhelpTimer -= uiDiff; + } }; CreatureAI* GetAI_mob_twilight_eggs(Creature* pCreature) @@ -1083,7 +1560,7 @@ struct MANGOS_DLL_DECL mob_twilight_whelpAI : public ScriptedAI // twilight torment if (m_uiFadeArmorTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_FADE_ARMOR); + DoCast(m_creature->getVictim(), SPELL_FADE_ARMOR); m_uiFadeArmorTimer = urand(5000, 10000); } else @@ -1098,6 +1575,221 @@ CreatureAI* GetAI_mob_twilight_whelp(Creature* pCreature) return new mob_twilight_whelpAI(pCreature); } +/*###### +## Mob Fire Cyclone +######*/ + +struct MANGOS_DLL_DECL mob_fire_cycloneAI : public ScriptedAI +{ + mob_fire_cycloneAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiLavaStrikeTimer; + uint8 m_uiLavaStrikesCount; + bool m_bLavaStrikeAllowed; + + + void Reset() + { + m_bLavaStrikeAllowed = false; + } + + void AttackStart(Unit* pWho) + { + } + + void MoveInLineOfSight(Unit* pWho) + { + } + + void SpellHit(Unit* pCaster, const SpellEntry* pSpell) + { + if (pSpell->Id == SPELL_CYCLONE_AURA_2) + { + DoCast(m_creature, 57560, true); + m_bLavaStrikeAllowed = true; + m_uiLavaStrikeTimer = 0; + m_uiLavaStrikesCount = 0; + } + } + + void JustSummoned(Creature* pSummoned) + { + if (pSummoned->GetEntry() == NPC_LAVA_BLAZE) + if (urand(0, 3)) //25% to stay + pSummoned->ForcedDespawn(); + else + pSummoned->SetInCombatWithZone(); + } + + void UpdateAI(const uint32 uiDiff) + { + + if (m_bLavaStrikeAllowed) + { + if (m_uiLavaStrikeTimer < uiDiff) + { + m_creature->CastSpell(urand(3220, 3275), urand(486, 575), 58.8f, SPELL_LAVA_STRIKE, true); + m_uiLavaStrikeTimer = 1000; + ++m_uiLavaStrikesCount; + if (m_uiLavaStrikesCount>=5) + m_bLavaStrikeAllowed = false; + } + else + m_uiLavaStrikeTimer -= uiDiff; + } + } +}; + +CreatureAI* GetAI_mob_fire_cyclone(Creature* pCreature) +{ + return new mob_fire_cycloneAI(pCreature); +} + +/*###### +## Mob Flame Tsunami +######*/ + +struct MANGOS_DLL_DECL mob_flame_tsunamiAI : public ScriptedAI +{ + mob_flame_tsunamiAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiTickTimer; + uint32 m_uiMovementStartTimer; + uint64 m_uiDummyDamagerGUID; + + void Reset() + { + m_creature->SetDisplayId(11686); + DoCast(m_creature, SPELL_FLAME_TSUNAMI, true); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_uiMovementStartTimer = 4000; + m_uiTickTimer = 1000; + m_uiDummyDamagerGUID = 0; + if (Creature* pDummyDamager = DoSpawnCreature(31103, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 18000)) + { + pDummyDamager->SetDisplayId(11686); + pDummyDamager->setFaction(14); + pDummyDamager->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + pDummyDamager->SetSpeedRate(MOVE_RUN, m_creature->GetSpeedRate(MOVE_RUN)); + m_uiDummyDamagerGUID = pDummyDamager->GetGUID(); + } + } + + void AttackStart(Unit* pWho) + { + } + + void MoveInLineOfSight(Unit* pWho) + { + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiMovementStartTimer < uiDiff) + { + int8 uiDirection = 1; + if (m_creature->GetPositionX() > 3240.0f) + uiDirection = -1; + m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+uiDirection*86.5f, m_creature->GetPositionY(), m_creature->GetPositionZ()); + if (m_pInstance) + if (Creature* pDummyDamager = m_pInstance->instance->GetCreature(m_uiDummyDamagerGUID)) + pDummyDamager->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+uiDirection*86.5f, m_creature->GetPositionY(), m_creature->GetPositionZ()); + m_uiMovementStartTimer = 30000; + } + else + m_uiMovementStartTimer -= uiDiff; + + if (m_uiTickTimer < uiDiff) + { + if (m_pInstance) + if (Creature* pDummyDamager = m_pInstance->instance->GetCreature(m_uiDummyDamagerGUID)) + pDummyDamager->CastSpell(pDummyDamager, SPELL_FLAME_TSUNAMI_DMG, false); + + std::list lLavaBlazes; + GetCreatureListWithEntryInGrid(lLavaBlazes, m_creature, NPC_LAVA_BLAZE, 6.0f); + if (!lLavaBlazes.empty()) + { + SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_FLAME_TSUNAMI_BUFF); + if (pTempSpell) + { + pTempSpell->EffectImplicitTargetA[0] = TARGET_SELF; + pTempSpell->EffectImplicitTargetB[0] = 0; + pTempSpell->EffectImplicitTargetA[1] = TARGET_SELF; + pTempSpell->EffectImplicitTargetB[1] = 0; + pTempSpell->EffectImplicitTargetA[2] = TARGET_SELF; + pTempSpell->EffectImplicitTargetB[2] = 0; + for (std::list::iterator iter = lLavaBlazes.begin(); iter != lLavaBlazes.end(); ++iter) + { + (*iter)->CastSpell(*iter, pTempSpell, false); + (*iter)->SetHealth((*iter)->GetHealth()*4); + } + } + } + + Map* pMap = m_creature->GetMap(); + if (pMap && pMap->IsDungeon()) + { + Map::PlayerList const &PlayerList = pMap->GetPlayers(); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()) <= 5.0f) + { + i->getSource()->SetOrientation(m_creature->GetOrientation()); + i->getSource()->CastSpell(i->getSource(), SPELL_FLAME_TSUNAMI_LEAP, true); + } + } + + m_uiTickTimer = 1000; + } + else + m_uiTickTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_flame_tsunami(Creature* pCreature) +{ + return new mob_flame_tsunamiAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_lava_blazeAI : public ScriptedAI +{ + mob_lava_blazeAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS) + m_creature->ForcedDespawn(); + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_lava_blaze(Creature* pCreature) +{ + return new mob_lava_blazeAI(pCreature); +}; + void AddSC_boss_sartharion() { Script *newscript; @@ -1141,4 +1833,19 @@ void AddSC_boss_sartharion() newscript->Name = "mob_twilight_whelp"; newscript->GetAI = &GetAI_mob_twilight_whelp; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_fire_cyclone"; + newscript->GetAI = &GetAI_mob_fire_cyclone; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_flame_tsunami"; + newscript->GetAI = &GetAI_mob_flame_tsunami; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_lava_blaze"; + newscript->GetAI = &GetAI_mob_lava_blaze; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp b/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp index 4a149fb12..0da011f09 100644 --- a/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp +++ b/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -28,80 +28,93 @@ EndScriptData */ 0 - Sartharion */ -struct MANGOS_DLL_DECL instance_obsidian_sanctum : public ScriptedInstance -{ - instance_obsidian_sanctum(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint64 m_uiSartharionGUID; - uint64 m_uiTenebronGUID; - uint64 m_uiShadronGUID; - uint64 m_uiVesperonGUID; - - void Initialize() +instance_obsidian_sanctum::instance_obsidian_sanctum(Map* pMap) : ScriptedInstance(pMap), + m_uiAliveDragons(0), + m_uiSartharionGUID(0), + m_uiTenebronGUID(0), + m_uiShadronGUID(0), + m_uiVesperonGUID(0) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiSartharionGUID = 0; - m_uiTenebronGUID = 0; - m_uiShadronGUID = 0; - m_uiVesperonGUID = 0; + Initialize(); } - void OnCreatureCreate(Creature* pCreature) - { - switch(pCreature->GetEntry()) - { - case NPC_SARTHARION: - m_uiSartharionGUID = pCreature->GetGUID(); - break; - //three dragons below set to active state once created. - //we must expect bigger raid to encounter main boss, and then three dragons must be active due to grid differences - case NPC_TENEBRON: - m_uiTenebronGUID = pCreature->GetGUID(); - pCreature->SetActiveObjectState(true); - break; - case NPC_SHADRON: - m_uiShadronGUID = pCreature->GetGUID(); - pCreature->SetActiveObjectState(true); - break; - case NPC_VESPERON: - m_uiVesperonGUID = pCreature->GetGUID(); - pCreature->SetActiveObjectState(true); - break; - } - } +void instance_obsidian_sanctum::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - void SetData(uint32 uiType, uint32 uiData) +void instance_obsidian_sanctum::OnCreatureCreate(Creature* pCreature) +{ + switch(pCreature->GetEntry()) { - if (uiType == TYPE_SARTHARION_EVENT) - m_auiEncounter[0] = uiData; + case NPC_SARTHARION: + m_uiSartharionGUID = pCreature->GetGUID(); + break; + // The three dragons below set to active state once created. + // We must expect bigger raid to encounter main boss, and then three dragons must be active due to grid differences + case NPC_TENEBRON: + m_uiTenebronGUID = pCreature->GetGUID(); + pCreature->SetActiveObjectState(true); + break; + case NPC_SHADRON: + m_uiShadronGUID = pCreature->GetGUID(); + pCreature->SetActiveObjectState(true); + break; + case NPC_VESPERON: + m_uiVesperonGUID = pCreature->GetGUID(); + pCreature->SetActiveObjectState(true); + break; } +} - uint32 GetData(uint32 uiType) - { - if (uiType == TYPE_SARTHARION_EVENT) - return m_auiEncounter[0]; +void instance_obsidian_sanctum::SetData(uint32 uiType, uint32 uiData) +{ + if (uiType == TYPE_SARTHARION_EVENT) + m_auiEncounter[0] = uiData; + else if (uiType == TYPE_ALIVE_DRAGONS) + m_uiAliveDragons = uiData; - return 0; + // No need to save anything here +} + +uint32 instance_obsidian_sanctum::GetData(uint32 uiType) +{ + if (uiType == TYPE_SARTHARION_EVENT) + return m_auiEncounter[0]; + + return 0; +} + +uint64 instance_obsidian_sanctum::GetData64(uint32 uiData) +{ + switch(uiData) + { + case NPC_SARTHARION: return m_uiSartharionGUID; + case NPC_TENEBRON: return m_uiTenebronGUID; + case NPC_SHADRON: return m_uiShadronGUID; + case NPC_VESPERON: return m_uiVesperonGUID; + default: + return 0; } +} - uint64 GetData64(uint32 uiData) +bool instance_obsidian_sanctum::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/) +{ + switch (uiCriteriaId) { - switch(uiData) - { - case DATA_SARTHARION: - return m_uiSartharionGUID; - case DATA_TENEBRON: - return m_uiTenebronGUID; - case DATA_SHADRON: - return m_uiShadronGUID; - case DATA_VESPERON: - return m_uiVesperonGUID; - } - return 0; + case ACHIEV_DRAGONS_ALIVE_1_N: + case ACHIEV_DRAGONS_ALIVE_1_H: + return m_uiAliveDragons >= 1; + case ACHIEV_DRAGONS_ALIVE_2_N: + case ACHIEV_DRAGONS_ALIVE_2_H: + return m_uiAliveDragons >= 2; + case ACHIEV_DRAGONS_ALIVE_3_N: + case ACHIEV_DRAGONS_ALIVE_3_H: + return m_uiAliveDragons >= 3; + default: + return false; } -}; +} InstanceData* GetInstanceData_instance_obsidian_sanctum(Map* pMap) { @@ -110,9 +123,10 @@ InstanceData* GetInstanceData_instance_obsidian_sanctum(Map* pMap) void AddSC_instance_obsidian_sanctum() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_obsidian_sanctum"; - newscript->GetInstanceData = GetInstanceData_instance_obsidian_sanctum; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_obsidian_sanctum"; + pNewScript->GetInstanceData = GetInstanceData_instance_obsidian_sanctum; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h b/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h index b43ecb090..376da68a0 100644 --- a/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h +++ b/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -10,17 +10,50 @@ enum MAX_ENCOUNTER = 1, TYPE_SARTHARION_EVENT = 1, - - DATA_SARTHARION = 10, - DATA_TENEBRON = 11, - DATA_SHADRON = 12, - DATA_VESPERON = 13, + // internal used types for achievement + TYPE_ALIVE_DRAGONS = 2, NPC_SARTHARION = 28860, NPC_TENEBRON = 30452, NPC_SHADRON = 30451, NPC_VESPERON = 30449, - GO_TWILIGHT_PORTAL = 193988 + + GO_TWILIGHT_PORTAL = 193988, + + // Achievement related + ACHIEV_CRIT_VOLCANO_BLOW_N = 7326, // achievs 2047, 2048 (Go When the Volcano Blows) -- This is individual achievement! + ACHIEV_CRIT_VOLCANO_BLOW_H = 7327, + ACHIEV_DRAGONS_ALIVE_1_N = 7328, // achievs 2049, 2052 (Twilight Assist) + ACHIEV_DRAGONS_ALIVE_1_H = 7331, + ACHIEV_DRAGONS_ALIVE_2_N = 7329, // achievs 2050, 2053 (Twilight Duo) + ACHIEV_DRAGONS_ALIVE_2_H = 7332, + ACHIEV_DRAGONS_ALIVE_3_N = 7330, // achievs 2051, 2054 (The Twilight Zone) + ACHIEV_DRAGONS_ALIVE_3_H = 7333, +}; + +class MANGOS_DLL_DECL instance_obsidian_sanctum : public ScriptedInstance +{ + public: + instance_obsidian_sanctum(Map* pMap); + + void Initialize(); + + void OnCreatureCreate(Creature* pCreature); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + bool CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/); + + private: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + uint64 m_uiSartharionGUID; + uint64 m_uiTenebronGUID; + uint64 m_uiShadronGUID; + uint64 m_uiVesperonGUID; + + uint8 m_uiAliveDragons; }; #endif diff --git a/scripts/northrend/ruby_sanctum/boss_baltharus.cpp b/scripts/northrend/ruby_sanctum/boss_baltharus.cpp index bb0493cfb..0b9ce0934 100644 --- a/scripts/northrend/ruby_sanctum/boss_baltharus.cpp +++ b/scripts/northrend/ruby_sanctum/boss_baltharus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2010 /dev/rsa for 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 @@ -16,9 +16,338 @@ /* ScriptData SDName: boss_baltharus -SD%Complete: -SDComment: placeholder -SDCategory: Ruby Sanctum +SD%Complete: 90% +SDComment: by notagain and /dev/rsa +SDCategory: ruby_sanctum EndScriptData */ +// Not fully offlike clone work, but Blizz idea is intact. +// Need correct timers #include "precompiled.h" +#include "ruby_sanctum.h" + +static Locations SpawnLoc[]= +{ + {3152.329834f, 359.41757f, 85.301605f}, // Baltharus target point + {3153.06f, 389.486f, 86.2596f}, // Baltharus initial point +}; + +enum Equipment +{ + EQUIP_MAIN = 49888, + EQUIP_OFFHAND = EQUIP_NO_CHANGE, + EQUIP_RANGED = EQUIP_NO_CHANGE, + EQUIP_DONE = EQUIP_NO_CHANGE, +}; + +enum BossSpells +{ + SPELL_BLADE_TEMPEST = 75125, // every 22 secs + SPELL_ENERVATING_BRAND = 74502, // friendlys in 12yards = 74505 + SPELL_REPELLING_WAVE = 74509, // once if call clone + SPELL_SABER_LASH = 40504, // every 10-15 secs + SPELL_SUMMON_CLONE = 74511, // summons npc 39899 (Clone) + SPELL_CHANNEL_SPELL = 76221, // Channeling dummy spell +}; + +/*###### +## boss_baltharus +######*/ + +struct MANGOS_DLL_DECL boss_baltharusAI : public BSWScriptedAI +{ + boss_baltharusAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + Creature* pDummyTarget; + Creature* pClone; + bool inCombat; + bool intro; + + void Reset() + { + if(!pInstance) + return; + + if (m_creature->isAlive()) pInstance->SetData(TYPE_BALTHARUS, NOT_STARTED); + m_creature->SetRespawnDelay(7*DAY); + resetTimers(); + setStage(0); + pClone = NULL; + inCombat = false; + intro = false; + if (pDummyTarget = m_creature->GetMap()->GetCreature( pInstance->GetData64(NPC_BALTHARUS_TARGET))) + { + if (!pDummyTarget->isAlive()) pDummyTarget->Respawn(); + + pDummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pDummyTarget->GetMotionMaster()->MoveIdle(); + } + else if (pDummyTarget = m_creature->SummonCreature(NPC_BALTHARUS_TARGET, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 1000)) + { + pDummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pDummyTarget->GetMotionMaster()->MoveIdle(); + } + + if(Creature* pTarget = m_creature->GetMap()->GetCreature( pInstance->GetData64(NPC_XERESTRASZA))) + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTarget->GetGUID()); + } + + void JustReachedHome() + { + if (!pInstance) return; + + pInstance->SetData(TYPE_BALTHARUS, FAIL); + } + + void MoveInLineOfSight(Unit* pWho) + { + ScriptedAI::MoveInLineOfSight(pWho); + if(!pInstance || intro || + pWho->GetTypeId() != TYPEID_PLAYER || + !pWho->IsWithinDistInMap(m_creature, 60.0f)) return; + + pInstance->SetData(TYPE_EVENT, 10); + DoScriptText(-1666305,m_creature); + intro = true; + } + + void JustDied(Unit* pKiller) + { + if (!pInstance) return; + + if (pDummyTarget) pDummyTarget->ForcedDespawn(); + DoScriptText(-1666303,m_creature); + pInstance->SetData(TYPE_BALTHARUS, DONE); + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) { + case 0: + DoScriptText(-1666301,m_creature,pVictim); + break; + case 1: + DoScriptText(-1666302,m_creature,pVictim); + break; + }; + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned) return; + + if ( summoned->GetEntry() != NPC_BALTHARUS_TARGET ) + { + if (!pClone) pClone = summoned; + else if (!pClone->isAlive()) pClone = summoned; + pClone->SetInCombatWithZone(); + } + } + + void SummonedCreatureJustDied(Creature* summoned) + { + if (!pInstance || !summoned) return; + + if (summoned == pClone) pClone = NULL; + } + + void Aggro(Unit* pWho) + { + if (!pInstance) return; + if (pWho->GetTypeId() != TYPEID_PLAYER) return; + + if (pDummyTarget) pDummyTarget->ForcedDespawn(); + + SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED); + + inCombat = true; + m_creature->InterruptNonMeleeSpells(true); + SetCombatMovement(true); + pInstance->SetData(TYPE_BALTHARUS, IN_PROGRESS); + DoScriptText(-1666300,m_creature); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!pInstance) return; + + if (!m_creature || !m_creature->isAlive()) + return; + + if(pDoneBy->GetGUID() == m_creature->GetGUID()) + return; + + if (pClone && pClone->isAlive()) + { + pDoneBy->DealDamage(pClone, uiDamage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + uiDamage = 0; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance) return; + + if (!inCombat && !m_creature->IsNonMeleeSpellCasted(false)) + timedCast(SPELL_CHANNEL_SPELL, uiDiff, pDummyTarget); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch (getStage()) + { + case 0: + if ( m_creature->GetHealthPercent() <= 66.0f) setStage(1); + break; + + case 1: + m_creature->InterruptNonMeleeSpells(true); + if (is25()) + doCast(SPELL_SUMMON_CLONE); + setStage(2); + break; + + case 2: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + doCast(SPELL_REPELLING_WAVE); + setStage(3); + + case 3: + if ( m_creature->GetHealthPercent() <= 50.0f) setStage(4); + break; + + case 4: + m_creature->InterruptNonMeleeSpells(true); + if (!is25()) + doCast(SPELL_SUMMON_CLONE); + setStage(5); + break; + + case 5: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + doCast(SPELL_REPELLING_WAVE); + setStage(6); + + case 6: + if ( m_creature->GetHealthPercent() <= 33.0f) setStage(7); + break; + + case 7: + m_creature->InterruptNonMeleeSpells(true); + if (is25()) + doCast(SPELL_SUMMON_CLONE); + setStage(8); + break; + + case 8: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + doCast(SPELL_REPELLING_WAVE); + setStage(9); + + case 9: + default: + break; + } + +// timedCast(SPELL_BLADE_TEMPEST, uiDiff); + timedCast(SPELL_ENERVATING_BRAND, uiDiff); + timedCast(SPELL_SABER_LASH, uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_baltharus(Creature* pCreature) +{ + return new boss_baltharusAI(pCreature); +} + +/*###### +## mob_baltharus_clone +######*/ + +struct MANGOS_DLL_DECL mob_baltharus_cloneAI : public BSWScriptedAI +{ + mob_baltharus_cloneAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + if(!pInstance) return; + resetTimers(); + m_creature->SetRespawnDelay(7*DAY); + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) { + case 0: + DoScriptText(-1666301,m_creature,pVictim); + break; + case 1: + DoScriptText(-1666302,m_creature,pVictim); + break; + }; + } + + void JustDied(Unit* pKiller) + { + if (!pInstance) return; + } + + void Aggro(Unit* pWho) + { + if (!pInstance) return; + + SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED); + + m_creature->SetInCombatWithZone(); + } + + void UpdateAI(const uint32 uiDiff) + { + + if (!pInstance) return; + + if (pInstance->GetData(TYPE_BALTHARUS) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + doCastAll(uiDiff); + + DoMeleeAttackIfReady(); + + } +}; + +CreatureAI* GetAI_mob_baltharus_clone(Creature* pCreature) +{ + return new mob_baltharus_cloneAI(pCreature); +} + + +void AddSC_boss_baltharus() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_baltharus"; + newscript->GetAI = &GetAI_boss_baltharus; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_baltharus_clone"; + newscript->GetAI = &GetAI_mob_baltharus_clone; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/ruby_sanctum/boss_halion.cpp b/scripts/northrend/ruby_sanctum/boss_halion.cpp index f8542d35c..21f90aa7a 100644 --- a/scripts/northrend/ruby_sanctum/boss_halion.cpp +++ b/scripts/northrend/ruby_sanctum/boss_halion.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2010 /dev/rsa for 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 @@ -16,9 +16,1270 @@ /* ScriptData SDName: boss_halion -SD%Complete: -SDComment: placeholder -SDCategory: Ruby Sanctum +SD%Complete: 80% +SDComment: by notagain, corrected by /dev/rsa +SDCategory: ruby_sanctum EndScriptData */ +// TODO: correct timers, Add twilight interorbs connection, sql spells, TESTING +// Attention please! This script required some core modification. + #include "precompiled.h" +#include "ruby_sanctum.h" + +enum +{ + //SPELLS + //All + SPELL_TWILIGHT_PRECISION = 78243, // Increases Halion's chance to hit by 5% and decreases all players' chance to dodge by 20% + SPELL_BERSERK = 26663, // Increases the caster's attack and movement speeds by 150% and all damage it deals by 500% for 5 min. Also grants immunity to Taunt effects. + SPELL_START_PHASE2 = 74808, // Phases the caster into the Twilight realm, leaving behind a large rift. + SPELL_TWILIGHT_ENTER = 74807, // Phases the caster into the Twilight realm - phase 32 + SPELL_TWILIGHT_ENTER2 = 74812, // + SPELL_SUMMON_TWILIGHT_PORTAL = 74809, // + + //NEED SCRIPT + SPELL_TAIL_LASH = 74531, // A sweeping tail strike hits all enemies behind the caster, inflicting 3063 to 3937 damage and stunning them for 2 sec. + SPELL_TWILIGHT_DIVISION = 75063, // Phases the caster, allowing him to exist and act simultaneously in both the material and Twilight realms. + SPELL_TWILIGHT_CUTTER = 77844, // Inflicts 13,875 to 16,125 Shadow damage every second to players touched by the shadow beam + //CORPOREALITY + SPELL_CORPOREALITY_EVEN = 74826, // Deals & receives normal damage + SPELL_CORPOREALITY_20I = 74827, // Damage dealt increased by 10% & Damage taken increased by 15% + SPELL_CORPOREALITY_40I = 74828, // Damage dealt increased by 30% & Damage taken increased by 50% + SPELL_CORPOREALITY_60I = 74829, // Damage dealt increased by 60% & Damage taken increased by 100% + SPELL_CORPOREALITY_80I = 74830, // Damage dealt increased by 100% & Damage taken increased by 200% + SPELL_CORPOREALITY_100I = 74831, // Damage dealt increased by 200% & Damage taken increased by 400% + SPELL_CORPOREALITY_20D = 74832, // Damage dealt reduced by 10% & Damage taken reduced by 15% + SPELL_CORPOREALITY_40D = 74833, // Damage dealt reduced by 30% & Damage taken reduced by 50% + SPELL_CORPOREALITY_60D = 74834, // Damage dealt reduced by 60% & Damage taken reduced by 100% + SPELL_CORPOREALITY_80D = 74835, // Damage dealt reduced by 100% & Damage taken reduced by 200% + SPELL_CORPOREALITY_100D = 74836, // Damage dealt reduced by 200% & Damage taken reduced by 400% + //METEOR STRIKE + SPELL_METEOR = 74637, // Script Start (summon NPC_METEOR_STRIKE) + SPELL_METEOR_IMPACT = 74641, // IMPACT ZONE FOR METEOR + SPELL_METEOR_STRIKE = 74648, // Inflicts 18,750 to 21,250 Fire damage to enemies within 12 yards of the targeted area. Takes about 5 seconds to land. + SPELL_METEOR_FLAME = 74718, // FLAME FROM METEOR + //N10 + SPELL_FLAME_BREATH = 74525, // Inflicts 17,500 to 22,500 Fire damage to players in front of Halion + SPELL_DARK_BREATH = 74806, // Inflicts 17,500 to 22,500 Shadow damage to players in front of Halion + SPELL_DUSK_SHROUD = 75484, // Inflicts 3,000 Shadow damage every 2 seconds to everyone in the Twilight Realm + //Combustion + NPC_COMBUSTION = 40001, + SPELL_MARK_OF_COMBUSTION = 74567, // Dummy effect only + SPELL_FIERY_COMBUSTION = 74562, // Inflicts 4,000 Fire damage every 2 seconds for 30 seconds to a random raider. Every time Fiery Combustion does damage, it applies a stackable Mark of Combustion. + SPELL_COMBUSTION_EXPLODE = 74607, + SPELL_COMBUSTION_AURA = 74629, + //Consumption + NPC_CONSUMPTION = 40135, + SPELL_MARK_OF_CONSUMPTION = 74795, // Dummy effect only + SPELL_SOUL_CONSUMPTION = 74792, // Inflicts 4,000 Shadow damage every 2 seconds for 30 seconds to a random raider. Every time Soul Consumption does damage, it applies a stackable Mark of Consumption. + SPELL_CONSUMPTION_EXPLODE = 74799, + SPELL_CONSUMPTION_AURA = 74803, + //Summons + NPC_METEOR_STRIKE = 40029, //casts "impact zone" then meteor + NPC_METEOR_STRIKE_1 = 40041, + NPC_METEOR_STRIKE_2 = 40042, + + FR_RADIUS = 45, + + //SAYS + SAY_HALION_SPAWN = -1666100, //17499 Meddlesome insects, you're too late! The Ruby Sanctum is lost. + SAY_HALION_AGGRO = -1666101, //17500 Your world teeters on the brink of annihilation. You will all bear witness to the coming of a new age of destruction! + SAY_HALION_SLAY_1 = -1666102, //17501 Another hero falls. + SAY_HALION_SLAY_2 = -1666103, //17502 Ha Ha Ha! + SAY_HALION_DEATH = -1666104, //17503 Relish this victory mortals, for it will be your last. This world will burn with the Master's return! + SAY_HALION_BERSERK = -1666105, //17504 Not good enough! + SAY_HALION_SPECIAL_1 = -1666106, //17505 The heavens burn! + SAY_HALION_SPECIAL_2 = -1666107, //17506 Beware the shadow! + SAY_HALION_PHASE_2 = -1666108, //17507 You will find only suffering within the realm of Twilight. Enter if you dare. + SAY_HALION_PHASE_3 = -1666109, //17508 I am the light AND the darkness! Cower mortals before the Herald of Deathwing! + EMOTE_WARNING = -1666110, //orbs charge warning + EMOTE_REAL = -1666111, // To real world message + EMOTE_TWILIGHT = -1666112, // To twilight world message + EMOTE_NEITRAL = -1666113, // Halion reveal HP message +}; + +static Locations SpawnLoc[]= +{ + {3154.99f, 535.637f, 72.8887f}, // 0 - Halion spawn point (center) +}; + +/*###### +## boss_halion_real (Physical version) +######*/ +struct MANGOS_DLL_DECL boss_halion_realAI : public BSWScriptedAI +{ + boss_halion_realAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + bool intro; + uint8 nextPoint; + bool MovementStarted; + + void Reset() + { + if(!pInstance) + return; + m_creature->SetRespawnDelay(7*DAY); + + if (m_creature->isAlive()) + { + pInstance->SetData(TYPE_HALION, NOT_STARTED); + pInstance->SetData(TYPE_HALION_EVENT, FAIL); + } + + resetTimers(); + setStage(0); + nextPoint = 0; + intro = false; + SetCombatMovement(true); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_1))) + pGoPortal->Delete(); + if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_2))) + pGoPortal->Delete(); + if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_3))) + pGoPortal->Delete(); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pInstance) return; + + if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER) return; + + if (!intro && pWho->IsWithinDistInMap(m_creature, 60.0f)) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + DoScriptText(-1666100,m_creature); + intro = true; + m_creature->SetActiveObjectState(true); + } + + if (intro && !m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 20.0f)) + AttackStart(pWho); + + ScriptedAI::MoveInLineOfSight(pWho); + } + + void JustReachedHome() + { + if (!pInstance) return; + + if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL) return + + ScriptedAI::JustReachedHome(); + +// pInstance->SetData(TYPE_HALION, FAIL); + + m_creature->SetActiveObjectState(false); + } + + void EnterEvadeMode() + { + + if (!pInstance) return; + + if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL) return; + + ScriptedAI::EnterEvadeMode(); + + m_creature->SetActiveObjectState(false); + } + + void JustDied(Unit* pKiller) + { + if (!pInstance) + return; + m_creature->SetActiveObjectState(false); + + DoScriptText(-1666104,m_creature); + + if (Creature* pclone = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_TWILIGHT))) + { + if (!pclone->isAlive()) + { + pInstance->SetData(TYPE_HALION, DONE); + m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + pInstance->SetData(TYPE_COUNTER, COUNTER_OFF); + } + else + { + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631006,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631007,m_creature,pVictim); + break; + }; + } + + void Aggro(Unit* pWho) + { + if (!pInstance) + return; + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + doCast(SPELL_TWILIGHT_PRECISION); + m_creature->SetInCombatWithZone(); + pInstance->SetData(TYPE_HALION, IN_PROGRESS); + DoScriptText(-1666101,m_creature); + } + + void MovementInform(uint32 type, uint32 id) + { + if (!pInstance) return; + + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + + if (id == nextPoint) { + m_creature->GetMotionMaster()->MovementExpired(); + MovementStarted = false; + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + } + } + + void StartMovement(uint32 id) + { + nextPoint = id; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z); + MovementStarted = true; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance) + return; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch (getStage()) + { + case 0: //PHASE 1 PHYSICAL REALM + timedCast(SPELL_FLAME_BREATH, uiDiff); + timedCast(SPELL_FIERY_COMBUSTION, uiDiff); + timedCast(SPELL_METEOR, uiDiff); + if (m_creature->GetHealthPercent() < 75.0f) setStage(1); + break; + + case 1: // Switch to phase 2 + m_creature->AttackStop(); + m_creature->InterruptNonMeleeSpells(true); + DoScriptText(-1666108,m_creature); + pInstance->SetData(TYPE_HALION_EVENT, NOT_STARTED); + SetCombatMovement(false); + StartMovement(0); + { + Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL)); + if (!pControl) + pControl = m_creature->SummonCreature(NPC_HALION_CONTROL, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 1000); + else if (!pControl->isAlive()) + pControl->Respawn(); + pControl->SetActiveObjectState(true); + pControl->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWith(pControl); + pControl->SetInCombatWith(m_creature); + } + setStage(2); + break; + + case 2: + if (MovementStarted) return; + doCast(SPELL_SUMMON_TWILIGHT_PORTAL); + setStage(3); + if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_1))) + pGoPortal->SetPhaseMask(31,true); + if (GameObject* pGoRing = pInstance->instance->GetGameObject(pInstance->GetData64(GO_FLAME_RING))) + pGoRing->SetPhaseMask(65535,true); + break; + + case 3: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + m_creature->SetActiveObjectState(true); + doCast(SPELL_START_PHASE2); + setStage(4); + break; + + case 4: + if (!m_creature->IsNonMeleeSpellCasted(false)) + { + if (Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL))) + { + m_creature->SetInCombatWith(pControl); + pControl->SetInCombatWith(m_creature); + } + Creature* pTwilight = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_TWILIGHT)); + if (!pTwilight) + pTwilight = m_creature->SummonCreature(NPC_HALION_TWILIGHT, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 1000); + else if (!pTwilight->isAlive()) + pTwilight->Respawn(); + pTwilight->SetCreatorGuid(ObjectGuid()); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + setStage(5); + } + break; + + case 5: // HALION awaiting end battle in TWILIGHT REALM + if (pInstance->GetData(TYPE_HALION_EVENT) == IN_PROGRESS) + { +// pInstance->SetData(TYPE_HALION_EVENT, SPECIAL); + doRemove(SPELL_START_PHASE2); + if (Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL))) + { + m_creature->SetInCombatWith(pControl); + pControl->SetInCombatWith(m_creature); + } + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetHealth(m_creature->GetMaxHealth()/2); + m_creature->SetInCombatWithZone(); + setStage(6); + } + return; + + case 6: // Switch to phase 3 +// doCast(SPELL_TWILIGHT_DIVISION); + DoScriptText(-1666109,m_creature); + pInstance->SetData(TYPE_HALION_EVENT, SPECIAL); + setStage(7); + break; + + case 7: + if (m_creature->IsNonMeleeSpellCasted(false)) return; + if (m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return; + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + setStage(8); + break; + + case 8: //PHASE 3 BOTH REALMS + timedCast(SPELL_FLAME_BREATH, uiDiff); + timedCast(SPELL_FIERY_COMBUSTION, uiDiff); + timedCast(SPELL_METEOR, uiDiff); + break; + + default: + break; + } + + timedCast(SPELL_BERSERK, uiDiff); + + DoMeleeAttackIfReady(); + + } +}; + +CreatureAI* GetAI_boss_halion_real(Creature* pCreature) +{ + return new boss_halion_realAI(pCreature); +} + +/*###### +## boss_halion_twilight (Twilight version) +######*/ + +struct MANGOS_DLL_DECL boss_halion_twilightAI : public BSWScriptedAI +{ + boss_halion_twilightAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + uint8 stage; + bool intro; + + void Reset() + { + if(!pInstance) + return; + m_creature->SetRespawnDelay(7*DAY); + setStage(0); + intro = false; + resetTimers(); + m_creature->SetInCombatWithZone(); + if (Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL))) + { + m_creature->SetInCombatWith(pControl); + pControl->SetInCombatWith(m_creature); + } + Creature* pFocus = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ORB_ROTATION_FOCUS)); + if (!pFocus ) + pFocus = m_creature->SummonCreature(NPC_ORB_ROTATION_FOCUS, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 1000); + else if (!pFocus->isAlive()) + pFocus->Respawn(); + + if (Creature* pReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL))) + if (pReal->isAlive()) + m_creature->SetHealth(pReal->GetHealth()); + if (!hasAura(SPELL_TWILIGHT_ENTER)) + doCast(SPELL_TWILIGHT_ENTER); + } + + void JustReachedHome() + { + if (!pInstance) return; + + if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL || getStage() == 0) + return; + + ScriptedAI::JustReachedHome(); + } + + void EnterEvadeMode() + { + + if (!pInstance) return; + + if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL || getStage() == 0) + return; + + ScriptedAI::EnterEvadeMode(); + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pInstance) return; + + if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER) return; + + if (!intro && pWho->IsWithinDistInMap(m_creature, 20.0f)) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + intro = true; + AttackStart(pWho); + setStage(1); + doCast(SPELL_TWILIGHT_PRECISION); + if (Creature* pReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL))) + if (pReal->isAlive()) + m_creature->SetHealth(pReal->GetHealth()); + + + } + + ScriptedAI::MoveInLineOfSight(pWho); + } + + void JustDied(Unit* pKiller) + { + if (!pInstance) + return; + DoScriptText(-1666104,m_creature); + doRemoveFromAll(SPELL_TWILIGHT_ENTER); + if (Creature* pReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL))) + if (!pReal->isAlive()) + { + pInstance->SetData(TYPE_HALION, DONE); + pReal->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + pInstance->SetData(TYPE_COUNTER, COUNTER_OFF); + } + m_creature->ForcedDespawn(); + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) + { + case 0: + DoScriptText(-1631006,m_creature,pVictim); + break; + case 1: + DoScriptText(-1631007,m_creature,pVictim); + break; + }; + } + + void Aggro(Unit* pWho) + { + if (!pInstance) + return; + } + + void UpdateAI(const uint32 uiDiff) + { + + if (!hasAura(SPELL_TWILIGHT_ENTER)) + doCast(SPELL_TWILIGHT_ENTER); + + if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS || pInstance->GetData(TYPE_HALION_EVENT) == FAIL) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + + switch (getStage()) + { + case 1: //SPAWNED - Twilight realm +// doCast(SPELL_TWILIGHT_DIVISION); + timedCast(SPELL_DUSK_SHROUD, uiDiff); + timedCast(SPELL_DARK_BREATH, uiDiff); + timedCast(SPELL_SOUL_CONSUMPTION, uiDiff); + if (m_creature->GetHealthPercent() < 50.0f) setStage(2); + break; + + case 2: //To two realms + pInstance->SetData(TYPE_HALION_EVENT, IN_PROGRESS); + DoScriptText(-1666109,m_creature); + m_creature->SummonGameobject(GO_HALION_PORTAL_3, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, 0); + if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_3))) + pGoPortal->SetPhaseMask(32,true); + doCast(SPELL_TWILIGHT_DIVISION); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + setStage(3); + break; + + case 3: //PHASE 3 BOTH REALMS + timedCast(SPELL_DUSK_SHROUD, uiDiff); + timedCast(SPELL_DARK_BREATH, uiDiff); + timedCast(SPELL_SOUL_CONSUMPTION, uiDiff); + break; + + default: + break; + } + + timedCast(SPELL_BERSERK, uiDiff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_halion_twilight(Creature* pCreature) +{ + return new boss_halion_twilightAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_halion_meteorAI : public BSWScriptedAI +{ + mob_halion_meteorAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + Reset(); + } + + float direction; + + void Reset() + { + m_creature->SetDisplayId(11686); + m_creature->SetRespawnDelay(7*DAY); + SetCombatMovement(false); + setStage(0); + m_creature->SetInCombatWithZone(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void UpdateAI(const uint32 diff) + { + switch (getStage()) + { + case 0: + if (timedCast(SPELL_METEOR_IMPACT, diff) == CAST_OK) setStage(1); + break; + + case 1: + if (timedCast(SPELL_METEOR_STRIKE, diff) == CAST_OK) setStage(2); + break; + + case 2: + // Place summon flames there + { + direction = 2.0f*M_PI_F*((float)urand(0,15)/16.0f); + float x, y, radius; + radius = 0.0f; + for(uint8 i = 0; i < getSpellData(SPELL_METEOR_STRIKE); ++i) + { + radius = radius + 5.0f; + m_creature->GetNearPoint2D(x, y, radius, direction); + doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000); + m_creature->GetNearPoint2D(x, y, radius, direction+M_PI_F); + doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000); + } + }; + { + direction = direction + M_PI_F/4; + float x, y, radius; + radius = 0.0f; + for(uint8 i = 0; i < getSpellData(SPELL_METEOR_STRIKE); ++i) + { + radius = radius + 5.0f; + m_creature->GetNearPoint2D(x, y, radius, direction); + doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000); + m_creature->GetNearPoint2D(x, y, radius, direction+M_PI_F); + doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000); + } + + }; + setStage(3); + break; + + case 3: + if (timedQuery(SPELL_METEOR_IMPACT, diff)) m_creature->ForcedDespawn(); + break; + + default: + break; + } + + } +}; + +CreatureAI* GetAI_mob_halion_meteor(Creature* pCreature) +{ + return new mob_halion_meteorAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_halion_flameAI : public BSWScriptedAI +{ + mob_halion_flameAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + Reset(); + } + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetDisplayId(11686); + m_creature->SetRespawnDelay(7*DAY); + SetCombatMovement(false); + m_creature->SetInCombatWithZone(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!hasAura(SPELL_METEOR_FLAME)) + doCast(SPELL_METEOR_FLAME); + + } + +}; + +CreatureAI* GetAI_mob_halion_flame(Creature* pCreature) +{ + return new mob_halion_flameAI(pCreature); +}; + +struct HalionBuffLine +{ + float diff; // Health diff in percent + uint32 real, twilight; // Buff pair + uint8 disp_corp; // Displayed Corporeality +}; + +static HalionBuffLine Buff[]= +{ + {-10.0f, SPELL_CORPOREALITY_100D , SPELL_CORPOREALITY_100I , 0 }, + {-8.0f, SPELL_CORPOREALITY_80D , SPELL_CORPOREALITY_80I , 10 }, + {-6.0f, SPELL_CORPOREALITY_60D , SPELL_CORPOREALITY_60I , 20 }, + {-4.0f, SPELL_CORPOREALITY_40D , SPELL_CORPOREALITY_40I , 30 }, + {-2.0f, SPELL_CORPOREALITY_20D , SPELL_CORPOREALITY_20I , 40 }, + {-1.0f, SPELL_CORPOREALITY_EVEN , SPELL_CORPOREALITY_EVEN , 50 }, + {1.0f, SPELL_CORPOREALITY_EVEN , SPELL_CORPOREALITY_EVEN , 50 }, + {2.0f, SPELL_CORPOREALITY_20I , SPELL_CORPOREALITY_20D , 60 }, + {4.0f, SPELL_CORPOREALITY_40I , SPELL_CORPOREALITY_40D , 70 }, + {6.0f, SPELL_CORPOREALITY_60I , SPELL_CORPOREALITY_60D , 80 }, + {8.0f, SPELL_CORPOREALITY_80I , SPELL_CORPOREALITY_80D , 90 }, + {10.0f, SPELL_CORPOREALITY_100I , SPELL_CORPOREALITY_100D , 100 }, +}; + +struct MANGOS_DLL_DECL mob_halion_controlAI : public BSWScriptedAI +{ + mob_halion_controlAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + Creature* pHalionReal; + Creature* pHalionTwilight; + uint32 m_lastBuffReal, m_lastBuffTwilight; + bool m_detectplayers; + + void Reset() + { + if (!pInstance) return; + resetTimers(); + m_detectplayers = true; + m_creature->SetDisplayId(11686); + m_creature->SetPhaseMask(65535, true); +// m_creature->SetDisplayId(10045); + m_creature->SetRespawnDelay(7*DAY); + SetCombatMovement(false); + m_lastBuffReal = 0; + m_lastBuffTwilight = 0; + m_creature->SetActiveObjectState(true); + pInstance->SetData(TYPE_COUNTER, COUNTER_OFF); + pInstance->SetData(TYPE_HALION_EVENT, NOT_STARTED); + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!pInstance) return; + + if (timedQuery(SPELL_CORPOREALITY_EVEN, diff)) + { + if (!doSelectRandomPlayerAtRange(80.0f)) + { + debug_log("ruby_sanctum: cannot detect players in range! "); + if (!m_detectplayers) + { + pInstance->SetData(TYPE_HALION_EVENT, FAIL); + pInstance->SetData(TYPE_HALION, FAIL); + m_creature->ForcedDespawn(); + } + else + { + m_detectplayers = false; + } + } + else + { + m_detectplayers = true; + } + + if (pInstance->GetData(TYPE_HALION_EVENT) != SPECIAL) return; + + pHalionReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL)); + pHalionTwilight = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_TWILIGHT)); + + //pHalionReal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pHalionTwilight->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + float p_RealHP = (pHalionReal && pHalionReal->isAlive()) ? pHalionReal->GetHealthPercent() : 0.0f; + float p_TwilightHP = (pHalionTwilight && pHalionTwilight->isAlive()) ? pHalionTwilight->GetHealthPercent() : 0.0f; + + float m_diff = (p_RealHP - p_TwilightHP); + + uint8 buffnum; + if (m_diff <= Buff[0].diff) + { + buffnum = 0; + } + else + { + for (uint8 i = 0; i < 11; i++) + { + if (m_diff >= Buff[i].diff) + { + buffnum = i+1; + } + else + { + break; + } + } + } + + if (!m_lastBuffReal || m_lastBuffReal != Buff[buffnum].real) + { + if (m_lastBuffReal) + { + doRemove(m_lastBuffReal, pHalionReal); + } + doCast(Buff[buffnum].real, pHalionReal); + m_lastBuffReal = Buff[buffnum].real; + } + + if (!m_lastBuffTwilight || m_lastBuffTwilight != Buff[buffnum].twilight) + { + if (m_lastBuffTwilight) + { + doRemove(m_lastBuffTwilight, pHalionTwilight); + } + doCast(Buff[buffnum].twilight, pHalionTwilight); + m_lastBuffTwilight = Buff[buffnum].twilight; + } + + debug_log("ruby_sanctum: Buff num = %u, m_diff = %d ", buffnum, m_diff); + + pInstance->SetData(TYPE_COUNTER, (uint32)Buff[buffnum].disp_corp); + + } + + } + +}; + +CreatureAI* GetAI_mob_halion_control(Creature* pCreature) +{ + return new mob_halion_controlAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_orb_rotation_focusAI : public ScriptedAI +{ + mob_orb_rotation_focusAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + uint32 m_timer; + float m_direction, m_nextdirection; + bool m_warning; + + void Reset() + { + m_creature->SetDisplayId(11686); +// m_creature->SetDisplayId(10045); + m_creature->SetRespawnDelay(7*DAY); + m_creature->SetPhaseMask(65535, true); + SetCombatMovement(false); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_direction = 0.0f; + m_nextdirection = 0.0f; + m_timer = 30000; + m_warning = false; + + Creature* pPulsar1 = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SHADOW_PULSAR_N)); + if (!pPulsar1 ) + { + float x,y; + m_creature->GetNearPoint2D(x, y, FR_RADIUS, m_direction); + pPulsar1 = m_creature->SummonCreature(NPC_SHADOW_PULSAR_N, x, y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + } else if (!pPulsar1->isAlive()) + pPulsar1->Respawn(); + + Creature* pPulsar2 = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SHADOW_PULSAR_S)); + if (!pPulsar2) + { + float x,y; + m_creature->GetNearPoint2D(x, y, FR_RADIUS, m_direction + M_PI_F); + pPulsar2 = m_creature->SummonCreature(NPC_SHADOW_PULSAR_S, x, y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + } else if (!pPulsar2->isAlive()) + pPulsar2->Respawn(); + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (pInstance->GetData(DATA_ORB_S) == DONE && pInstance->GetData(DATA_ORB_N) == DONE) + { + m_direction = m_nextdirection; + m_nextdirection = (m_direction - M_PI_F/64.0f); + if (m_nextdirection < 0.0f ) m_nextdirection = m_nextdirection + 2.0f*M_PI_F; + pInstance->SetData(DATA_ORB_DIRECTION, (uint32)(m_nextdirection*1000)); + pInstance->SetData(DATA_ORB_N, SPECIAL); + pInstance->SetData(DATA_ORB_S, SPECIAL); + debug_log("EventMGR: creature %u send direction %u ",m_creature->GetEntry(),pInstance->GetData(DATA_ORB_DIRECTION)); + } + + if (m_timer - 6000 <= uiDiff && !m_warning) + { + DoScriptText(-1666110,m_creature); + m_warning = true; + } + + if (m_timer <= uiDiff) + { + float x,y; + m_creature->GetNearPoint2D(x, y, FR_RADIUS, m_nextdirection); + m_creature->SummonCreature(NPC_ORB_CARRIER, x, y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000); + m_timer = 30000; + m_warning = false; + } else m_timer -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_orb_rotation_focus(Creature* pCreature) +{ + return new mob_orb_rotation_focusAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_halion_orbAI : public BSWScriptedAI +{ + mob_halion_orbAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance *pInstance; + float m_direction,m_delta; + uint32 m_flag; + uint32 m_flag1; + bool MovementStarted; + Creature* focus; + uint32 nextPoint; + + void Reset() + { + if (!pInstance) return; + m_creature->SetRespawnDelay(7*DAY); + SetCombatMovement(false); + m_creature->SetPhaseMask(32, true); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (m_creature->GetEntry() == NPC_SHADOW_PULSAR_N) + { + m_flag = DATA_ORB_N; + m_delta = 0.0f; + } else if (m_creature->GetEntry() == NPC_SHADOW_PULSAR_S) + { + m_flag = DATA_ORB_S; + m_delta = M_PI_F; + }; + m_direction = 0.0f; + nextPoint = 0; + MovementStarted = false; + pInstance->SetData(m_flag, DONE); + debug_log("EventMGR: creature %u assume m_flag %u ",m_creature->GetEntry(),m_flag); + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void MovementInform(uint32 type, uint32 id) + { + if (!pInstance) return; + + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + + if (id == nextPoint) { + m_creature->GetMotionMaster()->MovementExpired(); + MovementStarted = false; + pInstance->SetData(m_flag, DONE); + } + } + + void StartMovement(uint32 id) + { + if (!pInstance) return; + nextPoint = id; + float x,y; + pInstance->SetData(m_flag, IN_PROGRESS); + MovementStarted = true; + m_direction = ((float)pInstance->GetData(DATA_ORB_DIRECTION)/1000 + m_delta); + if (m_direction > 2.0f*M_PI_F) m_direction = m_direction - 2.0f*M_PI_F; + if (focus = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ORB_ROTATION_FOCUS))) + focus->GetNearPoint2D(x, y, FR_RADIUS, m_direction); + else m_creature->ForcedDespawn(); +// debug_log("EventMGR: creature %u go to move point %u ",m_creature->GetEntry(),id); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(id, x, y, m_creature->GetPositionZ()); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (Unit* pTarget = doSelectRandomPlayerAtRange(2.0f)) + doCast(SPELL_TWILIGHT_CUTTER, pTarget); + + if (!MovementStarted && pInstance->GetData(m_flag) == SPECIAL) + { +// debug_log("EventMGR: creature %u get direction %u ",m_creature->GetEntry(),pInstance->GetData(DATA_ORB_DIRECTION)); + StartMovement(1); + } + + } +}; + +CreatureAI* GetAI_mob_halion_orb(Creature* pCreature) +{ + return new mob_halion_orbAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_orb_carrierAI : public BSWScriptedAI +{ + mob_orb_carrierAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance* pInstance; + bool MovementStarted; + + void Reset() + { +// m_creature->SetDisplayId(10045); + m_creature->SetRespawnDelay(7*DAY); + SetCombatMovement(false); + m_creature->SetPhaseMask(32, true); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = false; + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_RUN, 6.0f); + } + + void AttackStart(Unit *pWho) + { + return; + } + + void MovementInform(uint32 type, uint32 id) + { + if (!pInstance) return; + + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + + if (id == 1) { + m_creature->GetMotionMaster()->MovementExpired(); + MovementStarted = false; + m_creature->ForcedDespawn(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (Unit* pTarget = doSelectRandomPlayerAtRange(2.0f)) + doCast(SPELL_TWILIGHT_CUTTER, pTarget); + + if (!MovementStarted) + { + float x,y; + float m_direction = ((float)pInstance->GetData(DATA_ORB_DIRECTION)/1000.0f + M_PI_F - M_PI_F/32.0f); + if (m_direction > 2.0f*M_PI_F) m_direction = m_direction - 2.0f*M_PI_F; + if (Creature* focus = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ORB_ROTATION_FOCUS))) + focus->GetNearPoint2D(x, y, FR_RADIUS, m_direction); + else m_creature->ForcedDespawn(); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(1, x, y, m_creature->GetPositionZ()); + MovementStarted = true; + } + + } + +}; + +CreatureAI* GetAI_mob_orb_carrier(Creature* pCreature) +{ + return new mob_orb_carrierAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_soul_consumptionAI : public BSWScriptedAI +{ + mob_soul_consumptionAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance* m_pInstance; + float m_Size0; + float m_Size; + + void Reset() + { + if (!isHeroic()) m_creature->SetPhaseMask(32,true); + else m_creature->SetPhaseMask(65535,true); + SetCombatMovement(false); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + doCast(SPELL_CONSUMPTION_AURA); + m_Size0 = m_creature->GetObjectScale(); + m_Size = m_Size0; + } + + void AttackStart(Unit *pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance && m_pInstance->GetData(TYPE_HALION) != IN_PROGRESS) + m_creature->ForcedDespawn(); + +// if (!hasAura(SPELL_TWILIGHT_ENTER)) +// doCast(SPELL_TWILIGHT_ENTER); + + if (timedQuery(SPELL_CONSUMPTION_AURA, uiDiff)) + m_creature->ForcedDespawn(); + + if (doSelectRandomPlayerAtRange(m_Size * 3.0f) && m_Size <= m_Size0 * 3.0f) { + m_Size = m_Size*1.01; + m_creature->SetObjectScale(m_Size); + } + } +}; + +CreatureAI* GetAI_mob_soul_consumption(Creature* pCreature) +{ + return new mob_soul_consumptionAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_fiery_combustionAI : public BSWScriptedAI +{ + mob_fiery_combustionAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance* m_pInstance; + float m_Size0; + float m_Size; + + void Reset() + { + if (!isHeroic()) m_creature->SetPhaseMask(31,true); + else m_creature->SetPhaseMask(65535,true); + SetCombatMovement(false); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + doCast(SPELL_COMBUSTION_AURA); + m_Size0 = m_creature->GetObjectScale(); + m_Size = m_Size0; + } + + void AttackStart(Unit *pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance && m_pInstance->GetData(TYPE_HALION) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (timedQuery(SPELL_COMBUSTION_AURA, uiDiff)) + m_creature->ForcedDespawn(); + + if (doSelectRandomPlayerAtRange(m_Size * 3.0f) && m_Size <= m_Size0 * 3.0f) { + m_Size = m_Size*1.01; + m_creature->SetObjectScale(m_Size); + } + } + +}; + +CreatureAI* GetAI_mob_fiery_combustion(Creature* pCreature) +{ + return new mob_fiery_combustionAI(pCreature); +}; + + +bool GOHello_go_halion_portal_twilight(Player *player, GameObject* pGo) +{ + ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); + if(!pInstance) return false; + player->CastSpell(player,SPELL_TWILIGHT_ENTER,false); + return true; +} + +bool GOHello_go_halion_portal_real(Player *player, GameObject* pGo) +{ + ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); + if(!pInstance) return false; + player->RemoveAurasDueToSpell(SPELL_TWILIGHT_ENTER); + return true; +} + +void AddSC_boss_halion() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_halion_real"; + newscript->GetAI = &GetAI_boss_halion_real; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_halion_twilight"; + newscript->GetAI = &GetAI_boss_halion_twilight; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_halion_meteor"; + newscript->GetAI = &GetAI_mob_halion_meteor; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_halion_flame"; + newscript->GetAI = &GetAI_mob_halion_flame; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_halion_orb"; + newscript->GetAI = &GetAI_mob_halion_orb; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_halion_control"; + newscript->GetAI = &GetAI_mob_halion_control; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_orb_rotation_focus"; + newscript->GetAI = &GetAI_mob_orb_rotation_focus; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_orb_carrier"; + newscript->GetAI = &GetAI_mob_orb_carrier; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_soul_consumption"; + newscript->GetAI = &GetAI_mob_soul_consumption; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_fiery_combustion"; + newscript->GetAI = &GetAI_mob_fiery_combustion; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "go_halion_portal_twilight"; + newscript->pGOUse = &GOHello_go_halion_portal_twilight; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "go_halion_portal_real"; + newscript->pGOUse = &GOHello_go_halion_portal_real; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/ruby_sanctum/boss_saviana.cpp b/scripts/northrend/ruby_sanctum/boss_saviana.cpp index 1a44e564e..c6e2e32bf 100644 --- a/scripts/northrend/ruby_sanctum/boss_saviana.cpp +++ b/scripts/northrend/ruby_sanctum/boss_saviana.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2010 /dev/rsa for 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 @@ -15,10 +15,308 @@ */ /* ScriptData -SDName: boss_saviana -SD%Complete: -SDComment: placeholder -SDCategory: Ruby Sanctum +SDName: boss_ragefire +SD%Complete: 90% +SDComment: by notagain && /dev/rsa +SDCategory: ruby_sanctum EndScriptData */ #include "precompiled.h" +#include "ruby_sanctum.h" + +enum BossSpells +{ + SPELL_ENRAGE = 78722, //soft enrage + fire nova + SPELL_FLAME_BREATH = 74404, + SPELL_BEACON = 74453, //mark for conflag, in enter to fly phase, 2 in 10, 5 in 25 + SPELL_CONFLAGATION = 74452, // after fly up + SPELL_CONFLAGATION_1 = 74455, // Triggered? + SPELL_CONFLAGATION_2 = 74456, // Aura + + MAX_BEACON_TARGETS = 5, +}; + +static Locations SpawnLoc[]= +{ + {3151.3898f, 636.8519f, 78.7396f}, // 0 Saviana start point + {3149.635f, 668.9644f, 90.507f}, // 1 Saviana fly phase, o=4,69 +}; + +struct MANGOS_DLL_DECL boss_ragefireAI : public BSWScriptedAI +{ + boss_ragefireAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + uint8 nextPoint; + Unit* marked[MAX_BEACON_TARGETS]; + bool MovementStarted; + bool conflagated; + + void Reset() + { + if(!pInstance) + return; + m_creature->SetRespawnDelay(7*DAY); + if (m_creature->isAlive()) pInstance->SetData(TYPE_RAGEFIRE, NOT_STARTED); + resetTimers(); + setStage(0); + nextPoint = 0; + conflagated = false; + for (uint8 i = 0; i < MAX_BEACON_TARGETS; ++i) + marked[i] = NULL; + } + + void MovementInform(uint32 type, uint32 id) + { + if (!pInstance) return; + + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + + if (id == nextPoint) { + m_creature->GetMotionMaster()->MovementExpired(); + MovementStarted = false; + } + } + + void SetFly(bool command = false) + { + if (command) + { + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_UP); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + } + else + { + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + } + } + + void StartMovement(uint32 id) + { + nextPoint = id; + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z); + MovementStarted = true; + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) { + case 0: + DoScriptText(-1666401,m_creature,pVictim); + break; + case 1: + DoScriptText(-1666402,m_creature,pVictim); + break; + }; + } + + void JustReachedHome() + { + if (pInstance) + pInstance->SetData(TYPE_RAGEFIRE, FAIL); + } + + void Aggro(Unit *who) + { + if(!pInstance) return; + + pInstance->SetData(TYPE_RAGEFIRE, IN_PROGRESS); + m_creature->SetInCombatWithZone(); + DoScriptText(-1666400,m_creature); + } + + void JustDied(Unit *killer) + { + if(!pInstance) return; + + pInstance->SetData(TYPE_RAGEFIRE, DONE); + DoScriptText(-1666403,m_creature); + } + + void doBeacon(bool command = false) + { + if (command) + { + for(uint8 i = 0; i < getSpellData(SPELL_BEACON); ++i) + { + if (Unit* pTarget = doSelectRandomPlayer(SPELL_BEACON, false, 100.0f)) + { + if (doCast(SPELL_BEACON, pTarget) == CAST_OK) + marked[i] = pTarget; + else marked[i] = NULL; + } + } + conflagated = true; + } + else + { + m_creature->InterruptNonMeleeSpells(true); + for(uint8 i = 0; i < getSpellData(SPELL_BEACON); ++i) + { + if (marked[i]) + doCast(SPELL_CONFLAGATION_2, marked[i]); + marked[i] = NULL; + } + doCast(SPELL_CONFLAGATION_1); + conflagated = false; + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch (getStage()) + { + case 0: //GROUND + timedCast(SPELL_FLAME_BREATH, diff); + timedCast(SPELL_ENRAGE, diff); + if ( m_creature->GetHealthPercent() <= 80.0f) setStage(1); + break; + + case 1: //Air phase start + SetCombatMovement(false); + m_creature->InterruptNonMeleeSpells(true); + SetFly(true); + doBeacon(true); + StartMovement(1); + setStage(2); + break; + + case 2: // Wait for movement + if (MovementStarted) return; + doCast(SPELL_CONFLAGATION); + DoScriptText(-1666404,m_creature); + setStage(3); + break; + + case 3: // Wait for cast finish + if (!m_creature->IsNonMeleeSpellCasted(false)) + { + doBeacon(false); + setStage(4); + }; + break; + + case 4: // Air phase + timedCast(SPELL_FLAME_BREATH, diff); + if (timedQuery(SPELL_BEACON, diff)) + { + doBeacon(true); + doCast(SPELL_CONFLAGATION); + }; + if (conflagated && timedQuery(SPELL_CONFLAGATION_1, diff)) + { + doBeacon(false); + }; + if ( m_creature->GetHealthPercent() <= 60.0f) setStage(5); + break; + + case 5: //Air phase end + StartMovement(0); + setStage(6); + break; + + case 6: // Wait for movement + if (MovementStarted) return; + SetFly(false); + SetCombatMovement(true); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + setStage(7); + break; + + case 7: //GROUND + timedCast(SPELL_FLAME_BREATH, diff); + timedCast(SPELL_ENRAGE, diff); + if ( m_creature->GetHealthPercent() <= 40.0f) setStage(8); + break; + + case 8: //Air phase start + SetCombatMovement(false); + m_creature->InterruptNonMeleeSpells(true); + SetFly(true); + doBeacon(true); + StartMovement(1); + setStage(9); + break; + + case 9: // Wait for movement + if (MovementStarted) return; + doCast(SPELL_CONFLAGATION); + DoScriptText(-1666404,m_creature); + setStage(10); + break; + + case 10: // Wait for cast finish + if (!m_creature->IsNonMeleeSpellCasted(false)) + { + doBeacon(false); + setStage(11); + }; + break; + + case 11: // Air phase + timedCast(SPELL_FLAME_BREATH, diff); + if (timedQuery(SPELL_BEACON, diff)) + { + doBeacon(true); + doCast(SPELL_CONFLAGATION); + }; + if (conflagated && timedQuery(SPELL_CONFLAGATION_1, diff)) + { + doBeacon(false); + }; + if ( m_creature->GetHealthPercent() <= 20.0f) setStage(12); + break; + + case 12: //Air phase end + StartMovement(0); + setStage(13); + break; + + case 13: // Wait for movement + if (MovementStarted) return; + SetFly(false); + SetCombatMovement(true); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + setStage(14); + break; + + case 14: //GROUND + timedCast(SPELL_FLAME_BREATH, diff); + timedCast(SPELL_ENRAGE, diff*2); + break; + + default: + break; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_ragefire(Creature* pCreature) +{ + return new boss_ragefireAI(pCreature); +} + +void AddSC_boss_ragefire() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_ragefire"; + newscript->GetAI = &GetAI_boss_ragefire; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/ruby_sanctum/boss_zarithrian.cpp b/scripts/northrend/ruby_sanctum/boss_zarithrian.cpp new file mode 100644 index 000000000..eb8ef4e23 --- /dev/null +++ b/scripts/northrend/ruby_sanctum/boss_zarithrian.cpp @@ -0,0 +1,219 @@ +/* Copyright (C) 2010 /dev/rsa for 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 + */ +/* ScriptData +SDName: boss_zarithian +SD%Complete: 90% +SDComment: by /dev/rsa && notagain +SDCategory: ruby_sanctum +EndScriptData */ + +// Need correct timers + +#include "precompiled.h" +#include "ruby_sanctum.h" + +enum BossSpells +{ + SPELL_CALL_FLAMECALLER = 74398, + SPELL_CLEAVE_ARMOR = 74367, + SPELL_IMTIMIDATING_ROAR = 74384, + SPELL_LAVA_GOUT = 74394, + SPELL_BLAST_NOVA = 74392, + + NPC_FLAMECALLER = 39814, +}; + +enum Equipment +{ + EQUIP_MAIN = 47156, + EQUIP_OFFHAND = 51812, + EQUIP_RANGED = EQUIP_NO_CHANGE, + EQUIP_DONE = EQUIP_NO_CHANGE, +}; + +static Locations SpawnLoc[]= +{ + {3008.552734f, 530.471680f, 89.195290f}, // 0 - Zarithian start point, o = 6,16 + {3014.313477f, 486.453735f, 89.255096f}, // 1 - Mob spawn 1 + {3025.324951f, 580.588501f, 88.593185f}, // 2 - Mob spawn 2 +}; + +struct MANGOS_DLL_DECL boss_zarithianAI : public BSWScriptedAI +{ + boss_zarithianAI(Creature* pCreature) : BSWScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + if(!pInstance) + return; + + if (m_creature->isAlive()) + { + pInstance->SetData(TYPE_ZARITHIAN, NOT_STARTED); + resetTimers(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + setStage(0); + } + } + + void MoveInLineOfSight(Unit* pWho) + { + if (getStage()) + ScriptedAI::MoveInLineOfSight(pWho); + + if (!getStage() && + pInstance->GetData(TYPE_XERESTRASZA) == DONE && + pInstance->GetData(TYPE_BALTHARUS) == DONE && + pInstance->GetData(TYPE_RAGEFIRE) == DONE) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + setStage(1); + }; + } + + void KilledUnit(Unit* pVictim) + { + switch (urand(0,1)) { + case 0: + DoScriptText(-1666201,m_creature,pVictim); + break; + case 1: + DoScriptText(-1666202,m_creature,pVictim); + break; + }; + } + + void JustReachedHome() + { + if (!pInstance) return; + pInstance->SetData(TYPE_ZARITHIAN, FAIL); + } + + void JustSummoned(Creature* summoned) + { + if(!pInstance || !summoned) return; + + summoned->SetInCombatWithZone(); + if (Unit* pTarget = doSelectRandomPlayerAtRange(60.0f)) + { + summoned->AddThreat(pTarget, 100.0f); + summoned->GetMotionMaster()->MoveChase(pTarget); + } + + } + + void Aggro(Unit *who) + { + if(!pInstance) return; + + SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED); + pInstance->SetData(TYPE_ZARITHIAN, IN_PROGRESS); + DoScriptText(-1666200,m_creature); + } + + void JustDied(Unit *killer) + { + if(!pInstance) return; + + pInstance->SetData(TYPE_ZARITHIAN, DONE); + DoScriptText(-1666203,m_creature); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (timedQuery(SPELL_CALL_FLAMECALLER, diff)) + { + doSummon(NPC_FLAMECALLER, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z); + doSummon(NPC_FLAMECALLER, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z); + +// if (currentDifficulty == RAID_DIFFICULTY_25MAN_NORMAL +// || currentDifficulty == RAID_DIFFICULTY_25MAN_HEROIC) +// doCast(SPELL_CALL_FLAMECALLER); + + DoScriptText(-1666204,m_creature); + } + + timedCast(SPELL_CLEAVE_ARMOR, diff); + timedCast(SPELL_IMTIMIDATING_ROAR, diff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_zarithian(Creature* pCreature) +{ + return new boss_zarithianAI(pCreature); +}; + +struct MANGOS_DLL_DECL mob_flamecaller_rubyAI : public BSWScriptedAI +{ + mob_flamecaller_rubyAI(Creature *pCreature) : BSWScriptedAI(pCreature) + { + pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + + ScriptedInstance *pInstance; + + void Reset() + { + if(!pInstance) return; + resetTimers(); + m_creature->SetRespawnDelay(7*DAY); + } + + void UpdateAI(const uint32 diff) + { + + if (pInstance && pInstance->GetData(TYPE_ZARITHIAN) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + doCastAll(diff); + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_flamecaller_ruby(Creature* pCreature) +{ + return new mob_flamecaller_rubyAI(pCreature); +}; + +void AddSC_boss_zarithian() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_zarithian"; + newscript->GetAI = &GetAI_boss_zarithian; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_flamecaller_ruby"; + newscript->GetAI = &GetAI_mob_flamecaller_ruby; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/ruby_sanctum/instance_ruby_sanctum.cpp b/scripts/northrend/ruby_sanctum/instance_ruby_sanctum.cpp new file mode 100644 index 000000000..6ae13c35e --- /dev/null +++ b/scripts/northrend/ruby_sanctum/instance_ruby_sanctum.cpp @@ -0,0 +1,425 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: instance_ruby_sanctum +SD%Complete: 50% +SDComment: by notagain, corrected by /dev/rsa +SDCategory: ruby_sanctum +EndScriptData */ + +//TODO: Trash mobs, spawn and removal of fire ring/walls, spawn of halion + +#include "precompiled.h" +#include "ruby_sanctum.h" + +struct MANGOS_DLL_DECL instance_ruby_sanctum : public ScriptedInstance +{ + instance_ruby_sanctum(Map* pMap) : ScriptedInstance(pMap) + { + Initialize(); + } + + bool needSave; + std::string strSaveData; + + //Creatures GUID + uint32 m_auiEncounter[MAX_ENCOUNTERS+1]; + + uint32 m_auiEventTimer; + uint32 m_auiHalionEvent; + + uint32 m_auiOrbDirection; + uint32 m_auiOrbNState; + uint32 m_auiOrbSState; + + uint64 m_uiHalion_pGUID; + uint64 m_uiHalion_tGUID; + uint64 m_uiHalionControlGUID; + uint64 m_uiRagefireGUID; + uint64 m_uiZarithianGUID; + uint64 m_uiBaltharusGUID; + uint64 m_uiCloneGUID; + uint64 m_uiXerestraszaGUID; + + uint64 m_uiOrbNGUID; + uint64 m_uiOrbSGUID; + uint64 m_uiOrbFocusGUID; + uint64 m_uiOrbCarrierGUID; + + //object GUID + uint64 m_uiHalionPortal1GUID; + uint64 m_uiHalionPortal2GUID; + uint64 m_uiHalionPortal3GUID; + uint64 m_uiHalionFireWallSGUID; + uint64 m_uiHalionFireWallMGUID; + uint64 m_uiHalionFireWallLGUID; + uint64 m_uiBaltharusTargetGUID; + + uint64 m_uiFireFieldGUID; + uint64 m_uiFlameWallsGUID; + uint64 m_uiFlameRingGUID; + + void OpenDoor(uint64 guid) + { + if(!guid) + return; + + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) + pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + } + + void CloseDoor(uint64 guid) + { + if(!guid) + return; + + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) + pGo->SetGoState(GO_STATE_READY); + } + + void Initialize() + { + for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + m_auiEncounter[i] = NOT_STARTED; + + m_auiEventTimer = 1000; + + m_uiHalion_pGUID = 0; + m_uiHalion_tGUID = 0; + m_uiRagefireGUID = 0; + m_uiZarithianGUID = 0; + m_uiBaltharusGUID = 0; + m_uiCloneGUID = 0; + m_uiHalionPortal1GUID = 0; + m_uiHalionPortal2GUID = 0; + m_uiHalionPortal3GUID = 0; + m_uiXerestraszaGUID = 0; + m_uiHalionFireWallSGUID = 0; + m_uiHalionFireWallMGUID = 0; + m_uiHalionFireWallLGUID = 0; + m_uiBaltharusTargetGUID = 0; + m_auiOrbDirection = 0; + m_uiOrbNGUID = 0; + m_uiOrbSGUID = 0; + m_uiOrbFocusGUID = 0; + m_auiOrbNState = NOT_STARTED; + m_auiOrbSState = NOT_STARTED; + + } + + bool IsEncounterInProgress() const + { + for(uint8 i = 1; i < MAX_ENCOUNTERS ; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) + return true; + + return false; + } + + void UpdateWorldState(bool command, uint32 value) + { + Map::PlayerList const &players = instance->GetPlayers(); + + if (command) + { + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + { + if(Player* pPlayer = i->getSource()) + { + if(pPlayer->isAlive()) + { + pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,0); + if (pPlayer->HasAura(74807)) + { + pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_COUNT_T, 100 - value); + } + else + { + pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_COUNT_R, value); + } + pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,1); + } + } + } + } + else + { + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + { + if(Player* pPlayer = i->getSource()) + { + if(pPlayer->isAlive()) + { + pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,0); + } + } + } + } + } + + void OpenAllDoors() + { + if (m_auiEncounter[TYPE_RAGEFIRE] == DONE && + m_auiEncounter[TYPE_BALTHARUS] == DONE && + m_auiEncounter[TYPE_XERESTRASZA] == DONE) + OpenDoor(m_uiFlameWallsGUID); + else CloseDoor(m_uiFlameWallsGUID); + } + + void OnCreatureCreate(Creature* pCreature) + { + switch(pCreature->GetEntry()) + { + case NPC_HALION_REAL: m_uiHalion_pGUID = pCreature->GetGUID(); break; + case NPC_HALION_TWILIGHT: m_uiHalion_tGUID = pCreature->GetGUID(); break; + case NPC_HALION_CONTROL: m_uiHalionControlGUID = pCreature->GetGUID(); break; + case NPC_RAGEFIRE: m_uiRagefireGUID = pCreature->GetGUID(); break; + case NPC_ZARITHIAN: m_uiZarithianGUID = pCreature->GetGUID(); break; + case NPC_BALTHARUS: m_uiBaltharusGUID = pCreature->GetGUID(); break; + case NPC_BALTHARUS_TARGET: m_uiBaltharusTargetGUID = pCreature->GetGUID(); break; + case NPC_CLONE: m_uiCloneGUID = pCreature->GetGUID(); break; + case NPC_XERESTRASZA: m_uiXerestraszaGUID = pCreature->GetGUID(); break; + case NPC_SHADOW_PULSAR_N: m_uiOrbNGUID = pCreature->GetGUID(); break; + case NPC_SHADOW_PULSAR_S: m_uiOrbSGUID = pCreature->GetGUID(); break; + case NPC_ORB_ROTATION_FOCUS: m_uiOrbFocusGUID = pCreature->GetGUID(); break; + case NPC_ORB_CARRIER: m_uiOrbCarrierGUID = pCreature->GetGUID(); break; + } + } + + void OnObjectCreate(GameObject* pGo) + { + switch(pGo->GetEntry()) + { + case GO_HALION_PORTAL_1: m_uiHalionPortal1GUID = pGo->GetGUID(); break; + case GO_HALION_PORTAL_2: m_uiHalionPortal2GUID = pGo->GetGUID(); break; + case GO_HALION_PORTAL_3: m_uiHalionPortal3GUID = pGo->GetGUID(); break; + case GO_FLAME_WALLS: m_uiFlameWallsGUID = pGo->GetGUID(); break; + case GO_FLAME_RING: m_uiFlameRingGUID = pGo->GetGUID(); break; + case GO_FIRE_FIELD: m_uiFireFieldGUID = pGo->GetGUID(); break; + } + OpenAllDoors(); + } + + void SetData(uint32 uiType, uint32 uiData) + { + switch(uiType) + { + case TYPE_EVENT: m_auiEncounter[uiType] = uiData; uiData = NOT_STARTED; break; + case TYPE_RAGEFIRE: m_auiEncounter[uiType] = uiData; + OpenAllDoors(); + break; + case TYPE_BALTHARUS: m_auiEncounter[uiType] = uiData; + OpenAllDoors(); + break; + case TYPE_XERESTRASZA: m_auiEncounter[uiType] = uiData; + if (uiData == IN_PROGRESS) + OpenDoor(m_uiFireFieldGUID); + else if (uiData == NOT_STARTED) + { + CloseDoor(m_uiFireFieldGUID); + OpenAllDoors(); + } + else if (uiData == DONE) + { + OpenAllDoors(); + if (m_auiEncounter[TYPE_ZARITHIAN] == DONE) + { + m_auiEncounter[TYPE_EVENT] = 200; + m_auiEventTimer = 30000; + }; + } + break; + case TYPE_ZARITHIAN: m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + { + OpenDoor(m_uiFlameWallsGUID); + m_auiEncounter[TYPE_EVENT] = 200; + m_auiEventTimer = 30000; + } + else if (uiData == IN_PROGRESS) + CloseDoor(m_uiFlameWallsGUID); + else if (uiData == FAIL) + OpenDoor(m_uiFlameWallsGUID); + break; + case TYPE_HALION: m_auiEncounter[uiType] = uiData; + if (uiData == IN_PROGRESS) + { + CloseDoor(m_uiFlameRingGUID); + } + else + { + OpenDoor(m_uiFlameRingGUID); + } + break; + case TYPE_HALION_EVENT: m_auiHalionEvent = uiData; uiData = NOT_STARTED; break; + case TYPE_EVENT_TIMER: m_auiEventTimer = uiData; uiData = NOT_STARTED; break; + + case DATA_ORB_DIRECTION: m_auiOrbDirection = uiData; uiData = NOT_STARTED; break; + case DATA_ORB_N: m_auiOrbNState = uiData; uiData = NOT_STARTED; break; + case DATA_ORB_S: m_auiOrbSState = uiData; uiData = NOT_STARTED; break; + case TYPE_COUNTER: + if (uiData == COUNTER_OFF) + { + UpdateWorldState(false,0); + } + else + { + UpdateWorldState(true,uiData); + } + uiData = NOT_STARTED; + break; + } + + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + saveStream << m_auiEncounter[i] << " "; + + strSaveData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + const char* Save() + { + return strSaveData.c_str(); + } + + uint32 GetData(uint32 uiType) + { + switch(uiType) + { + case TYPE_RAGEFIRE: return m_auiEncounter[uiType]; + case TYPE_BALTHARUS: return m_auiEncounter[uiType]; + case TYPE_XERESTRASZA: return m_auiEncounter[uiType]; + case TYPE_ZARITHIAN: return m_auiEncounter[uiType]; + case TYPE_HALION: return m_auiEncounter[uiType]; + + case TYPE_EVENT: return m_auiEncounter[uiType]; + + case TYPE_HALION_EVENT: return m_auiHalionEvent; + + case TYPE_EVENT_TIMER: return m_auiEventTimer; + case TYPE_EVENT_NPC: switch (m_auiEncounter[TYPE_EVENT]) + { + case 10: + case 20: + case 30: + case 40: + case 50: + case 60: + case 70: + case 80: + case 90: + case 100: + case 110: + case 200: + case 210: + return NPC_XERESTRASZA; + break; + default: + break; + }; + return 0; + + case DATA_ORB_DIRECTION: return m_auiOrbDirection; + case DATA_ORB_N: return m_auiOrbNState; + case DATA_ORB_S: return m_auiOrbSState; + + } + return 0; + } + + uint64 GetData64(uint32 uiData) + { + switch(uiData) + { + case NPC_BALTHARUS: return m_uiBaltharusGUID; + case NPC_CLONE: return m_uiCloneGUID; + case NPC_ZARITHIAN: return m_uiZarithianGUID; + case NPC_RAGEFIRE: return m_uiRagefireGUID; + case NPC_HALION_REAL: return m_uiHalion_pGUID; + case NPC_HALION_TWILIGHT: return m_uiHalion_tGUID; + case NPC_HALION_CONTROL: return m_uiHalionControlGUID; + case NPC_XERESTRASZA: return m_uiXerestraszaGUID; + case NPC_BALTHARUS_TARGET: return m_uiBaltharusTargetGUID; + + case GO_FLAME_WALLS: return m_uiFlameWallsGUID; + case GO_FLAME_RING: return m_uiFlameRingGUID; + case GO_FIRE_FIELD: return m_uiFireFieldGUID; + + case GO_HALION_PORTAL_1: return m_uiHalionPortal1GUID; + case GO_HALION_PORTAL_2: return m_uiHalionPortal2GUID; + case GO_HALION_PORTAL_3: return m_uiHalionPortal3GUID; + + case NPC_SHADOW_PULSAR_N: return m_uiOrbNGUID; + case NPC_SHADOW_PULSAR_S: return m_uiOrbSGUID; + case NPC_ORB_ROTATION_FOCUS: return m_uiOrbFocusGUID; + case NPC_ORB_CARRIER: return m_uiOrbCarrierGUID; + } + return 0; + } + + void Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + + for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i) + { + loadStream >> m_auiEncounter[i]; + + if (m_auiEncounter[i] == IN_PROGRESS + || m_auiEncounter[i] == FAIL) + m_auiEncounter[i] = NOT_STARTED; + } + + m_auiEncounter[TYPE_XERESTRASZA] = NOT_STARTED; + + OUT_LOAD_INST_DATA_COMPLETE; + OpenAllDoors(); + } +}; + +InstanceData* GetInstanceData_instance_ruby_sanctum(Map* pMap) +{ + return new instance_ruby_sanctum(pMap); +} + +void AddSC_instance_ruby_sanctum() +{ + Script* pNewScript; + pNewScript = new Script; + pNewScript->Name = "instance_ruby_sanctum"; + pNewScript->GetInstanceData = &GetInstanceData_instance_ruby_sanctum; + pNewScript->RegisterSelf(); +} diff --git a/scripts/northrend/ruby_sanctum/ruby_sanctum.cpp b/scripts/northrend/ruby_sanctum/ruby_sanctum.cpp new file mode 100644 index 000000000..8cbc2cbda --- /dev/null +++ b/scripts/northrend/ruby_sanctum/ruby_sanctum.cpp @@ -0,0 +1,226 @@ +/* Copyright (C) 2010 /dev/rsa for 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 + */ +/* ScriptData +SDName: ruby_sanctum mobs +SD%Complete: 10% +SDComment: by notagain, corrected by /dev/rsa +SDCategory: ruby_sanctum +EndScriptData */ + +#include "precompiled.h" +#include "ruby_sanctum.h" + +static Locations SpawnLoc[]= +{ + {3155.540039f, 342.391998f, 84.596802f}, // 0 - start point + {3152.329834f, 359.41757f, 85.301605f}, // 1 - second say + {3152.078369f, 383.939178f, 86.337875f}, // 2 - other says and staying + {3154.99f, 535.637f, 72.8887f}, // 3 - Halion spawn point +}; + +struct MANGOS_DLL_DECL mob_xerestraszaAI : public ScriptedAI +{ + mob_xerestraszaAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + uint32 nextEvent; + uint32 nextPoint; + uint32 UpdateTimer; + bool movementstarted; + bool onSessionEvent; + + void Reset() + { + if(!pInstance) return; + nextEvent = 0; + nextPoint = 0; + movementstarted = false; + UpdateTimer = 2000; + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + pInstance->SetData(TYPE_XERESTRASZA, NOT_STARTED); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSpeedRate(MOVE_WALK, 0.8f); + m_creature->SetRespawnDelay(7*DAY); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !movementstarted) return; + if (id == nextPoint) + { + movementstarted = false; + pInstance->SetData(TYPE_EVENT,nextEvent); + m_creature->GetMotionMaster()->MovementExpired(); + } + } + + void StartMovement(uint32 id, uint32 _nextEvent) + { + nextPoint = id; + nextEvent = _nextEvent; + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z); + pInstance->SetData(TYPE_EVENT,0); + movementstarted = true; + } + + void AttackStart(Unit *who) + { + //ignore all attackstart commands + return; + } + + void MoveInLineOfSight(Unit *who) + { + if(!pInstance || !who || who->GetTypeId() != TYPEID_PLAYER) + return; + + if (pInstance->GetData(TYPE_BALTHARUS) != DONE + || pInstance->GetData(TYPE_XERESTRASZA) != NOT_STARTED) return; + + if(!who->IsWithinDistInMap(m_creature, 60.0f)) return; + + pInstance->SetData(TYPE_XERESTRASZA, IN_PROGRESS); + pInstance->SetData(TYPE_EVENT, 30); + onSessionEvent = true; + } + + void UpdateAI(const uint32 diff) + { + if(!pInstance) return; + + if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_XERESTRASZA) + { + UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER); + if (UpdateTimer <= diff) + { + debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT)); + switch (pInstance->GetData(TYPE_EVENT)) + { +// Xerestrasza intro + case 10: + UpdateTimer = 7000; + pInstance->SetData(TYPE_EVENT, 20); + break; + case 20: + DoScriptText(-1666000,m_creature); + pInstance->SetData(TYPE_EVENT,0); + break; +// Xerestrasza event + case 30: + m_creature->SetActiveObjectState(true); + DoScriptText(-1666001,m_creature); + StartMovement(1,40); + break; + case 40: + DoScriptText(-1666002,m_creature); + StartMovement(2,50); + break; + case 50: + DoScriptText(-1666003,m_creature); + UpdateTimer = 12000; + pInstance->SetData(TYPE_EVENT,60); + break; + case 60: + DoScriptText(-1666004,m_creature); + UpdateTimer = 12000; + pInstance->SetData(TYPE_EVENT,70); + break; + case 70: + DoScriptText(-1666005,m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,80); + break; + case 80: + DoScriptText(-1666006,m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,90); + break; + case 90: + DoScriptText(-1666007,m_creature); + UpdateTimer = 10000; + pInstance->SetData(TYPE_EVENT,100); + break; + case 100: + DoScriptText(-1666008,m_creature); + UpdateTimer = 4000; + pInstance->SetData(TYPE_EVENT,110); + break; + case 110: + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,0); + pInstance->SetData(TYPE_XERESTRASZA, DONE); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + m_creature->SetActiveObjectState(false); + break; +// Halion spawn + case 200: + m_creature->SetActiveObjectState(true); + { + Creature* pHalion = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL)); + if (pInstance->GetData(TYPE_BALTHARUS) == DONE && + pInstance->GetData(TYPE_RAGEFIRE) == DONE && + pInstance->GetData(TYPE_XERESTRASZA) == DONE && + pInstance->GetData(TYPE_ZARITHIAN) == DONE && + pInstance->GetData(TYPE_HALION) != DONE) + { + if (!pHalion) + pHalion = m_creature->SummonCreature(NPC_HALION_REAL, SpawnLoc[3].x, SpawnLoc[3].y, SpawnLoc[3].z, 6.23f, TEMPSUMMON_MANUAL_DESPAWN, HOUR*IN_MILLISECONDS); + if (pHalion && !pHalion->isAlive()) + pHalion->Respawn(); + if (pHalion) + pHalion->SetCreatorGuid(ObjectGuid()); + } + } + UpdateTimer = 4000; + pInstance->SetData(TYPE_EVENT,210); + break; + case 210: + m_creature->SetActiveObjectState(false); + UpdateTimer = 2000; + pInstance->SetData(TYPE_EVENT,0); + break; + + default: + break; + } + } else UpdateTimer -= diff; + pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer); + } + + } +}; + +CreatureAI* GetAI_mob_xerestrasza(Creature* pCreature) +{ + return new mob_xerestraszaAI(pCreature); +} + +void AddSC_ruby_sanctum() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "mob_xerestrasza"; + newscript->GetAI = &GetAI_mob_xerestrasza; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/ruby_sanctum/ruby_sanctum.h b/scripts/northrend/ruby_sanctum/ruby_sanctum.h new file mode 100644 index 000000000..cae9555d0 --- /dev/null +++ b/scripts/northrend/ruby_sanctum/ruby_sanctum.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2010 by /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_RUBY_SANCTUM_H +#define DEF_RUBY_SANCTUM_H +#include "BSW_ai.h" + +enum +{ + MAX_ENCOUNTERS = 6, + + TYPE_EVENT = 0, + TYPE_RAGEFIRE = 1, + TYPE_BALTHARUS = 2, + TYPE_XERESTRASZA = 3, + TYPE_ZARITHIAN = 4, + TYPE_HALION = 5, + + TYPE_COUNTER = 6, // for WorldUpdateState + TYPE_HALION_EVENT = 7, + + COUNTER_OFF = 255, + + TYPE_EVENT_TIMER = 50, + TYPE_EVENT_NPC = 51, + + NPC_HALION_REAL = 39863, // Halion Physical Realm NPC + NPC_HALION_TWILIGHT = 40142, // Halion Twilight Realm NPC + NPC_HALION_CONTROL = 40146, + + NPC_BALTHARUS = 39751, + NPC_CLONE = 39899, + NPC_ZARITHIAN = 39746, + NPC_RAGEFIRE = 39747, + + NPC_XERESTRASZA = 40429, + + NPC_BALTHARUS_TARGET = 39900, + NPC_ZARITHIAN_SPAWN_STALKER = 39794, + + // Orb rotation + NPC_SHADOW_PULSAR_N = 40083, //spinning orb N spawn + NPC_SHADOW_PULSAR_S = 40100, //spinning orb S spawn + NPC_ORB_CARRIER = 40081, + NPC_ORB_ROTATION_FOCUS = 40091, + + + GO_HALION_PORTAL_1 = 202794, //1327 ENTRY + GO_HALION_PORTAL_2 = 202795, //1327 ENTRY + GO_HALION_PORTAL_3 = 202796, //1327 EXIT + + GO_FIRE_FIELD = 203005, + GO_FLAME_WALLS = 203006, + GO_FLAME_RING = 203007, + + DATA_EVENT_TIMER = 101, + DATA_EVENT = 102, + + DATA_ORB_DIRECTION = 110, + DATA_ORB_S = 111, + DATA_ORB_N = 112, + +}; + +enum uiWorldStates +{ + UPDATE_STATE_UI_COUNT_R = 5049, + UPDATE_STATE_UI_COUNT_T = 5050, + UPDATE_STATE_UI_SHOW = 5051, +}; + +#endif diff --git a/scripts/northrend/sholazar_basin.cpp b/scripts/northrend/sholazar_basin.cpp index e35517e86..551d2e55b 100644 --- a/scripts/northrend/sholazar_basin.cpp +++ b/scripts/northrend/sholazar_basin.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,11 +17,12 @@ /* ScriptData SDName: Sholazar_Basin SD%Complete: 100 -SDComment: Quest support: 12573, 12570, 12580 +SDComment: Quest support: 12573, 12570, 12580, 12688 SDCategory: Sholazar Basin EndScriptData */ /* ContentData +npc_helice npc_injured_rainspeaker npc_mosswalker_victim npc_vekjik - TODO, can be moved to database (already exist) @@ -30,6 +31,171 @@ EndContentData */ #include "precompiled.h" #include "escort_ai.h" +/*###### +## npc_helice +######*/ + +enum +{ + QUEST_ENGINEERING_DISASTER = 12688, + + SAY_HELICE_ACCEPT = -1000657, + SAY_HELICE_EXPLOSIVES_1 = -1000658, + SAY_HELICE_EXPLODE_1 = -1000659, + SAY_HELICE_MOVE_ON = -1000660, + SAY_HELICE_EXPLOSIVES_2 = -1000661, + SAY_HELICE_EXPLODE_2 = -1000662, + SAY_HELICE_COMPLETE = -1000663, + + SPELL_DETONATE_EXPLOSIVES_1 = 52369, // first "barrel" + SPELL_DETONATE_EXPLOSIVES_2 = 52371, // second "barrel" +}; + +struct MANGOS_DLL_DECL npc_heliceAI : public npc_escortAI +{ + npc_heliceAI(Creature* pCreature) : npc_escortAI(pCreature) + { + m_uiExplodeTimer = 5000; + m_uiExplodePhase = 0; + m_bFirstBarrel = true; + Reset(); + } + + uint32 m_uiExplodeTimer; + uint32 m_uiExplodePhase; + bool m_bFirstBarrel; + + void Reset() + { + } + + void WaypointReached(uint32 uiPointId) + { + switch(uiPointId) + { + case 2: + { + if (Player* pPlayer = GetPlayerForEscort()) + { + DoScriptText(SAY_HELICE_EXPLOSIVES_1, m_creature, pPlayer); + SetEscortPaused(true); + } + break; + } + case 13: + { + if (Player* pPlayer = GetPlayerForEscort()) + { + DoScriptText(SAY_HELICE_EXPLOSIVES_2, m_creature, pPlayer); + SetEscortPaused(true); + } + break; + } + case 22: + { + if (Player* pPlayer = GetPlayerForEscort()) + { + DoScriptText(SAY_HELICE_COMPLETE, m_creature, pPlayer); + pPlayer->GroupEventHappens(QUEST_ENGINEERING_DISASTER, m_creature); + } + break; + } + } + } + + void UpdateEscortAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + return; + + if (HasEscortState(STATE_ESCORT_PAUSED)) + { + if (m_uiExplodeTimer < uiDiff) + { + if (m_bFirstBarrel) + { + switch(m_uiExplodePhase) + { + case 0: + DoCastSpellIfCan(m_creature, SPELL_DETONATE_EXPLOSIVES_1); + + if (Player* pPlayer = GetPlayerForEscort()) + DoScriptText(SAY_HELICE_EXPLODE_1, m_creature, pPlayer); + + m_uiExplodeTimer = 2500; + ++m_uiExplodePhase; + break; + case 1: + if (Player* pPlayer = GetPlayerForEscort()) + DoScriptText(SAY_HELICE_MOVE_ON, m_creature, pPlayer); + + m_uiExplodeTimer = 2500; + ++m_uiExplodePhase; + break; + case 2: + SetEscortPaused(false); + m_uiExplodePhase = 0; + m_uiExplodeTimer = 5000; + m_bFirstBarrel = false; + break; + } + } + else + { + switch(m_uiExplodePhase) + { + case 0: + DoCastSpellIfCan(m_creature, SPELL_DETONATE_EXPLOSIVES_2); + + if (Player* pPlayer = GetPlayerForEscort()) + DoScriptText(SAY_HELICE_EXPLODE_2, m_creature, pPlayer); + + m_uiExplodeTimer = 2500; + ++m_uiExplodePhase; + break; + case 1: + SetEscortPaused(false); + m_uiExplodePhase = 0; + m_uiExplodeTimer = 5000; + m_bFirstBarrel = true; + break; + } + } + } + else + m_uiExplodeTimer -= uiDiff; + } + + return; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_helice(Creature* pCreature) +{ + return new npc_heliceAI(pCreature); +} + +bool QuestAccept_npc_helice(Player* pPlayer, Creature* pCreature, const Quest* pQuest) +{ + if (pQuest->GetQuestId() == QUEST_ENGINEERING_DISASTER) + { + DoScriptText(SAY_HELICE_ACCEPT, pCreature, pPlayer); + + if (npc_heliceAI* pEscortAI = dynamic_cast(pCreature->AI())) + { + pEscortAI->Start(false, pPlayer->GetGUID(), pQuest); + pCreature->SetFactionTemporary(FACTION_ESCORT_N_NEUTRAL_PASSIVE, TEMPFACTION_RESTORE_RESPAWN); + } + } + + return false; +} + /*###### ## npc_injured_rainspeaker ######*/ @@ -44,15 +210,15 @@ enum SAY_START = -1000606, SAY_END_1 = -1000607, SAY_END_2 = -1000608, - SAY_TRACKER = -1000609, + SAY_TRACKER = -1000609, // not used in escort (aggro text for trackers? something for vekjik?) NPC_FRENZYHEART_TRACKER = 28077, + SPELL_ORACLE_ESCORT_START = 51341, // unknown purpose SPELL_FEIGN_DEATH = 51329, SPELL_ORACLE_INTRO = 51448, }; -// TODO: add, if faction change is expected. struct MANGOS_DLL_DECL npc_injured_rainspeakerAI : public npc_escortAI { npc_injured_rainspeakerAI(Creature* pCreature) : npc_escortAI(pCreature) { Reset(); } @@ -62,7 +228,10 @@ struct MANGOS_DLL_DECL npc_injured_rainspeakerAI : public npc_escortAI void JustStartedEscort() { if (Player* pPlayer = GetPlayerForEscort()) + { DoScriptText(SAY_START, m_creature, pPlayer); + DoCastSpellIfCan(m_creature, SPELL_ORACLE_ESCORT_START); + } } void WaypointReached(uint32 uiPointId) @@ -74,8 +243,7 @@ struct MANGOS_DLL_DECL npc_injured_rainspeakerAI : public npc_escortAI if (Player* pPlayer = GetPlayerForEscort()) { DoScriptText(SAY_END_1, m_creature, pPlayer); - // more likely m_creature->player, doesn't seem to work though. - pPlayer->CastSpell(pPlayer, SPELL_ORACLE_INTRO, true); + DoCastSpellIfCan(m_creature, SPELL_ORACLE_INTRO); } break; } @@ -96,11 +264,6 @@ struct MANGOS_DLL_DECL npc_injured_rainspeakerAI : public npc_escortAI } } - void JustSummoned(Creature* pSummoned) - { - DoScriptText(SAY_TRACKER, pSummoned); - } - void UpdateEscortAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) @@ -124,7 +287,10 @@ bool QuestAccept_npc_injured_rainspeaker(Player* pPlayer, Creature* pCreature, c // Workaround, GossipHello/GossipSelect doesn't work well when object already has gossip from database if (npc_injured_rainspeakerAI* pEscortAI = dynamic_cast(pCreature->AI())) + { pEscortAI->Start(true, pPlayer->GetGUID(), pQuest); + pCreature->SetFactionTemporary(FACTION_ESCORT_N_NEUTRAL_PASSIVE, TEMPFACTION_RESTORE_RESPAWN); + } } return false; @@ -301,10 +467,16 @@ void AddSC_sholazar_basin() { Script* pNewScript; + pNewScript = new Script; + pNewScript->Name = "npc_helice"; + pNewScript->GetAI = &GetAI_npc_helice; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_helice; + pNewScript->RegisterSelf(); + pNewScript = new Script; pNewScript->Name = "npc_injured_rainspeaker"; pNewScript->GetAI = &GetAI_npc_injured_rainspeaker; - pNewScript->pQuestAccept = &QuestAccept_npc_injured_rainspeaker; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_injured_rainspeaker; //pNewScript->pGossipHello = &GossipHello_npc_injured_rainspeaker; //pNewScript->pGossipSelect = &GossipSelect_npc_injured_rainspeaker; pNewScript->RegisterSelf(); diff --git a/scripts/northrend/storm_peaks.cpp b/scripts/northrend/storm_peaks.cpp index ec03553a5..e0109895c 100644 --- a/scripts/northrend/storm_peaks.cpp +++ b/scripts/northrend/storm_peaks.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp index b1a5b3c6c..6e1d503ae 100644 --- a/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp +++ b/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -40,20 +40,17 @@ enum EMOTE_DEFENSIVE_STANCE = -1602010, SPELL_DEFENSIVE_STANCE = 53790, - //SPELL_DEFENSIVE_AURA = 41105, SPELL_SPELL_REFLECTION = 36096, SPELL_PUMMEL = 12555, SPELL_KNOCK_AWAY = 52029, SPELL_IRONFORM = 52022, SPELL_BERSEKER_STANCE = 53791, - //SPELL_BERSEKER_AURA = 41107, SPELL_INTERCEPT = 58769, SPELL_WHIRLWIND = 52027, SPELL_CLEAVE = 15284, SPELL_BATTLE_STANCE = 53792, - //SPELL_BATTLE_AURA = 41106, SPELL_MORTAL_STRIKE = 16856, SPELL_SLAM = 52026, @@ -66,10 +63,6 @@ enum SPELL_RENEW_STEEL_N = 52774, SPELL_RENEW_STEEL_H = 59160, - EQUIP_SWORD = 37871, - EQUIP_SHIELD = 35642, - EQUIP_MACE = 43623, - STANCE_DEFENSIVE = 0, STANCE_BERSERKER = 1, STANCE_BATTLE = 2 @@ -147,13 +140,10 @@ struct MANGOS_DLL_DECL boss_bjarngrimAI : public ScriptedAI if (m_uiStance != STANCE_DEFENSIVE) { - DoRemoveStanceAura(m_uiStance); DoCastSpellIfCan(m_creature, SPELL_DEFENSIVE_STANCE); m_uiStance = STANCE_DEFENSIVE; } - SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE); - if (m_pInstance) m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED); } @@ -187,23 +177,6 @@ struct MANGOS_DLL_DECL boss_bjarngrimAI : public ScriptedAI m_pInstance->SetData(TYPE_BJARNGRIM, DONE); } - //TODO: remove when removal is done by mangos - void DoRemoveStanceAura(uint8 uiStance) - { - switch(uiStance) - { - case STANCE_DEFENSIVE: - m_creature->RemoveAurasDueToSpell(SPELL_DEFENSIVE_STANCE); - break; - case STANCE_BERSERKER: - m_creature->RemoveAurasDueToSpell(SPELL_BERSEKER_STANCE); - break; - case STANCE_BATTLE: - m_creature->RemoveAurasDueToSpell(SPELL_BATTLE_STANCE); - break; - } - } - void UpdateAI(const uint32 uiDiff) { //Return since we have no target @@ -217,8 +190,6 @@ struct MANGOS_DLL_DECL boss_bjarngrimAI : public ScriptedAI if (m_creature->IsNonMeleeSpellCasted(false)) return; - DoRemoveStanceAura(m_uiStance); - int uiTempStance = rand()%(3-1); if (uiTempStance >= m_uiStance) @@ -232,19 +203,16 @@ struct MANGOS_DLL_DECL boss_bjarngrimAI : public ScriptedAI DoScriptText(SAY_DEFENSIVE_STANCE, m_creature); DoScriptText(EMOTE_DEFENSIVE_STANCE, m_creature); DoCastSpellIfCan(m_creature, SPELL_DEFENSIVE_STANCE); - SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE); break; case STANCE_BERSERKER: DoScriptText(SAY_BERSEKER_STANCE, m_creature); DoScriptText(EMOTE_BERSEKER_STANCE, m_creature); DoCastSpellIfCan(m_creature, SPELL_BERSEKER_STANCE); - SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE); break; case STANCE_BATTLE: DoScriptText(SAY_BATTLE_STANCE, m_creature); DoScriptText(EMOTE_BATTLE_STANCE, m_creature); DoCastSpellIfCan(m_creature, SPELL_BATTLE_STANCE); - SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); break; } diff --git a/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp index 26701c87e..50fc2217b 100644 --- a/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp +++ b/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -188,6 +188,8 @@ struct MANGOS_DLL_DECL boss_ionarAI : public ScriptedAI if (pSpark->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) pSpark->GetMotionMaster()->MovementExpired(); + pSpark->SetSpeedRate(MOVE_RUN,2); + pSpark->GetMotionMaster()->MovePoint(POINT_CALLBACK, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); } } @@ -236,7 +238,7 @@ struct MANGOS_DLL_DECL boss_ionarAI : public ScriptedAI m_bIsSplitPhase = false; } // Lightning effect and restore Ionar - else if (m_uiSparkAtHomeCount == MAX_SPARKS) + else { m_creature->SetVisibility(VISIBILITY_ON); m_creature->CastSpell(m_creature, SPELL_SPARK_DESPAWN, false); @@ -379,7 +381,7 @@ void AddSC_boss_ionar() newscript = new Script; newscript->Name = "boss_ionar"; newscript->GetAI = &GetAI_boss_ionar; - newscript->pEffectDummyCreature = &EffectDummyCreature_boss_ionar; + newscript->pEffectDummyNPC = &EffectDummyCreature_boss_ionar; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp index 21f0f330f..2c00be856 100644 --- a/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp +++ b/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -125,7 +125,7 @@ struct MANGOS_DLL_DECL boss_lokenAI : public ScriptedAI if (m_bIsAura) { // workaround for PULSING_SHOCKWAVE - /*if (m_uiPulsingShockwave_Timer < uiDiff) + if (m_uiPulsingShockwave_Timer < uiDiff) { Map *map = m_creature->GetMap(); if (map->IsDungeon()) @@ -150,7 +150,7 @@ struct MANGOS_DLL_DECL boss_lokenAI : public ScriptedAI } } m_uiPulsingShockwave_Timer = 2000; - }else m_uiPulsingShockwave_Timer -= uiDiff;*/ + }else m_uiPulsingShockwave_Timer -= uiDiff; } else { diff --git a/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp index 4e9b7e809..803155517 100644 --- a/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp +++ b/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -329,8 +329,7 @@ bool EffectDummyCreature_npc_volkhan_anvil(Unit* pCaster, uint32 uiSpellId, Spel if (pCaster->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) pCaster->GetMotionMaster()->MovementExpired(); - ((Creature*)pCaster)->GetMap()->CreatureRelocation((Creature*)pCaster, fX, fY, fZ, pCreatureTarget->GetOrientation()); - ((Creature*)pCaster)->SendMonsterMove(fX, fY, fZ, SPLINETYPE_NORMAL, ((Creature*)pCaster)->GetSplineFlags(), 1); + ((Creature*)pCaster)->MonsterMove(fX, fY, fZ, 1); pCreatureTarget->CastSpell(pCaster, SPELL_TEMPER_DUMMY, false); @@ -462,12 +461,12 @@ void AddSC_boss_volkhan() newscript = new Script; newscript->Name = "boss_volkhan"; newscript->GetAI = &GetAI_boss_volkhan; - newscript->pEffectDummyCreature = &EffectDummyCreature_boss_volkhan; + newscript->pEffectDummyNPC = &EffectDummyCreature_boss_volkhan; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "npc_volkhan_anvil"; - newscript->pEffectDummyCreature = &EffectDummyCreature_npc_volkhan_anvil; + newscript->pEffectDummyNPC = &EffectDummyCreature_npc_volkhan_anvil; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h b/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h index 131107610..1eba693ff 100644 --- a/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h +++ b/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp b/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp index 3f2dc1762..6bd600442 100644 --- a/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp +++ b/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp b/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp new file mode 100644 index 000000000..3df44438d --- /dev/null +++ b/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp @@ -0,0 +1,175 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Boss Krystallus +SDAuthor: ckegg +SD%Complete: 0% +SDComment: +SDCategory: Halls of Stone +EndScriptData */ + +#include "precompiled.h" +#include "halls_of_stone.h" + +enum +{ + SAY_AGGRO = -1599000, + SAY_KILL = -1599001, + SAY_DEATH = -1599002, + SAY_SHATTER = -1599003, + + SPELL_BOULDER_TOSS = 50843, + SPELL_BOULDER_TOSS_H = 59742, + SPELL_GROUND_SPIKE = 59750, + SPELL_GROUND_SLAM = 50827, + SPELL_SHATTER = 50810, + SPELL_SHATTER_H = 61546, + SPELL_STOMP = 50868, + SPELL_STOMP_H = 59744, + +}; + +/*###### +## boss_krystallus +######*/ + +struct MANGOS_DLL_DECL boss_krystallusAI : public ScriptedAI +{ + boss_krystallusAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool m_bIsRegularMode; + bool m_bIsSlam; + + uint32 m_uiToss_Timer; + uint32 m_uiSpike_Timer; + uint32 m_uiSlam_Timer; + uint32 m_uiShatter_Timer; + uint32 m_uiStomp_Timer; + + void Reset() + { + m_bIsSlam = false; + m_uiToss_Timer = 3000 + rand()%6000; + m_uiSpike_Timer = 9000 + rand()%5000; + m_uiSlam_Timer = 15000 + rand()%3000; + m_uiStomp_Timer = 20000 + rand()%9000; + m_uiShatter_Timer = 0; + + if(m_pInstance) + m_pInstance->SetData(TYPE_KRYSTALLUS, NOT_STARTED); + } + + void EnterCombat(Unit* pWho) + { + DoScriptText(SAY_AGGRO,m_creature); + + if(m_pInstance) + m_pInstance->SetData(TYPE_KRYSTALLUS, IN_PROGRESS); + } + + void KilledUnit(Unit* pVictim) + { + DoScriptText(SAY_KILL, m_creature); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_KRYSTALLUS, DONE); + } + + void UpdateAI(const uint32 uiDiff) + { + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiToss_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_BOULDER_TOSS_H : SPELL_BOULDER_TOSS); + m_uiToss_Timer = 9000 + rand()%6000; + } + else + m_uiToss_Timer -= uiDiff; + + if (m_uiSpike_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_GROUND_SPIKE); + m_uiSpike_Timer = 12000 + rand()%5000; + } + else + m_uiSpike_Timer -= uiDiff; + + if (m_uiStomp_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_STOMP_H : SPELL_STOMP); + m_uiStomp_Timer = 20000 + rand()%9000; + } + else + m_uiStomp_Timer -= uiDiff; + + if (m_uiSlam_Timer < uiDiff) + { + DoCast(m_creature, SPELL_GROUND_SLAM); + m_bIsSlam = true; + m_uiShatter_Timer = 10000; + m_uiSlam_Timer = 15000 + rand()%3000; + } + else + m_uiSlam_Timer -= uiDiff; + + if (m_bIsSlam) + { + if (m_uiShatter_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHATTER_H : SPELL_SHATTER); + m_bIsSlam = false; + m_uiShatter_Timer = 0; + } + else + m_uiShatter_Timer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_krystallus(Creature* pCreature) +{ + return new boss_krystallusAI (pCreature); +} + +void AddSC_boss_krystallus() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_krystallus"; + newscript->GetAI = &GetAI_boss_krystallus; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp b/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp index cff0b1ad4..7ab81f81b 100644 --- a/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp +++ b/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,7 +16,7 @@ /* ScriptData SDName: Boss_Maiden_of_Grief -SD%Complete: 60% +SD%Complete: 20% SDComment: SDCategory: Halls of Stone EndScriptData */ @@ -34,16 +34,13 @@ enum SAY_STUN = -1599010, SAY_DEATH = -1599011, - SPELL_STORM_OF_GRIEF = 50752, - SPELL_STORM_OF_GRIEF_H = 59772, - - SPELL_SHOCK_OF_SORROW = 50760, - SPELL_SHOCK_OF_SORROW_H = 59726, - + SPELL_PARTING_SORROW = 59723, SPELL_PILLAR_OF_WOE = 50761, SPELL_PILLAR_OF_WOE_H = 59727, - - SPELL_PARTING_SORROW = 59723 + SPELL_SHOCK_OF_SORROW = 50760, + SPELL_SHOCK_OF_SORROW_H = 59726, + SPELL_STORM_OF_GRIEF = 50752, + SPELL_STORM_OF_GRIEF_H = 59772, }; /*###### @@ -62,25 +59,33 @@ struct MANGOS_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; - uint32 m_uiStormTimer; - uint32 m_uiShockTimer; - uint32 m_uiPillarTimer; + uint32 m_uiPartingSorrow_Timer; + uint32 m_uiPillarWoe_Timer; + uint32 m_uiShockSorrow_Timer; + uint32 m_uiStorm_Timer; void Reset() { - m_uiStormTimer = 5000; - m_uiShockTimer = 10000; - m_uiPillarTimer = 15000; + m_uiPartingSorrow_Timer = 9000 + rand()%5000; + m_uiPillarWoe_Timer = 3000 + rand()%4000; + m_uiStorm_Timer = 10000 + rand()%5000; + m_uiShockSorrow_Timer = 20000 + rand()%5000; + + if(m_pInstance) + m_pInstance->SetData(TYPE_GRIEF, NOT_STARTED); } void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); + + if(m_pInstance) + m_pInstance->SetData(TYPE_GRIEF, IN_PROGRESS); } void KilledUnit(Unit* pVictim) { - switch(urand(0, 3)) + switch(rand()%4) { case 0: DoScriptText(SAY_SLAY_1, m_creature); break; case 1: DoScriptText(SAY_SLAY_2, m_creature); break; @@ -94,7 +99,7 @@ struct MANGOS_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI DoScriptText(SAY_DEATH, m_creature); if (m_pInstance) - m_pInstance->SetData(TYPE_MAIDEN, DONE); + m_pInstance->SetData(TYPE_GRIEF, DONE); } void UpdateAI(const uint32 uiDiff) @@ -102,35 +107,40 @@ struct MANGOS_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (m_uiStormTimer < uiDiff) + if (m_uiPartingSorrow_Timer < uiDiff) { - if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_STORM_OF_GRIEF : SPELL_STORM_OF_GRIEF_H) == CAST_OK) - m_uiStormTimer = 20000; + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_PARTING_SORROW); + m_uiPartingSorrow_Timer = 12000 + rand()%5000; } else - m_uiStormTimer -= uiDiff; + m_uiPartingSorrow_Timer -= uiDiff; - if (m_uiPillarTimer < uiDiff) + if (m_uiPillarWoe_Timer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - { - if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_PILLAR_OF_WOE : SPELL_PILLAR_OF_WOE_H) == CAST_OK) - m_uiPillarTimer = 10000; - } + DoCast(pTarget, m_bIsRegularMode ? SPELL_PILLAR_OF_WOE_H : SPELL_PILLAR_OF_WOE); + m_uiPillarWoe_Timer = 9000 + rand()%4000; + } + else + m_uiPillarWoe_Timer -= uiDiff; + + if (m_uiStorm_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_STORM_OF_GRIEF_H : SPELL_STORM_OF_GRIEF); + m_uiStorm_Timer = 20000 + rand()%5000; } else - m_uiPillarTimer -= uiDiff; + m_uiStorm_Timer -= uiDiff; - if (m_uiShockTimer < uiDiff) + if (m_uiShockSorrow_Timer < uiDiff) { - if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHOCK_OF_SORROW : SPELL_SHOCK_OF_SORROW_H) == CAST_OK) - { - DoScriptText(SAY_STUN, m_creature); - m_uiShockTimer = 35000; - } + DoScriptText(SAY_STUN, m_creature); + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHOCK_OF_SORROW_H : SPELL_SHOCK_OF_SORROW); + m_uiShockSorrow_Timer = 20000 + rand()%5000; } else - m_uiShockTimer -= uiDiff; + m_uiShockSorrow_Timer -= uiDiff; DoMeleeAttackIfReady(); } diff --git a/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp b/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp index 7c4b37ee0..96867252b 100644 --- a/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp +++ b/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -26,43 +26,41 @@ EndScriptData */ enum { - SAY_AGGRO = -1599000, - SAY_SLAY_1 = -1599001, - SAY_SLAY_2 = -1599002, - SAY_SLAY_3 = -1599003, - SAY_DEATH = -1599004, - EMOTE_GENERIC_FRENZY = -1000002, - - SPELL_FRENZY = 28747, - - SPELL_CHAIN_LIGHTNING = 50830, - SPELL_CHAIN_LIGHTNING_H = 59844, - - SPELL_STATIC_CHARGE = 50834, - SPELL_STATIC_CHARGE_H = 59846, - - SPELL_LIGHTNING_SHIELD = 50831, - SPELL_LIGHTNING_SHIELD_H = 59845, - - SPELL_LIGHTNING_RING = 50840, - SPELL_LIGHTNING_RING_H = 59848, - - SPELL_SUMMON_IRON_DWARF = 50789, // periodic dummy aura, tick each 30sec or each 20sec in heroic - SPELL_SUMMON_IRON_DWARF_H = 59860, // left/right 50790,50791 - - SPELL_SUMMON_IRON_TROGG = 50792, // periodic dummy aura, tick each 10sec or each 7sec in heroic - SPELL_SUMMON_IRON_TROGG_H = 59859, // left/right 50793,50794 - - SPELL_SUMMON_MALFORMED_OOZE = 50801, // periodic dummy aura, tick each 5sec or each 3sec in heroic - SPELL_SUMMON_MALFORMED_OOZE_H = 59858, // left/right 50802,50803 + SAY_AGGRO = -1599000, + SAY_SLAY_1 = -1599001, + SAY_SLAY_2 = -1599002, + SAY_SLAY_3 = -1599003, + SAY_DEATH = -1599004, + EMOTE_GENERIC_FRENZY = -1000002, + + SPELL_CHAIN_LIGHTING = 50830, + SPELL_CHAIN_LIGHTING_H = 59844, + SPELL_FRENZY = 28747, + SPELL_LIGHTING_SHIELD = 50831, + SPELL_LIGHTING_SHIELD_H = 59845, + SPELL_STATIC_CHARGE = 50834, //Periodic Trigger 2s interval, spell =50835 + SPELL_STATIC_CHARGE_H = 59846, //Periodic Trigger 2s interval, spell =50847 + + SPELL_LIGHTING_RING = 51849, + SPELL_LIGHTING_RING_H = 59861, + SPELL_LIGHTING_RING1 = 50840, + SPELL_LIGHTING_RING1_H = 59848, + + NPC_FORGED_IRON_TROGG = 27979, + NPC_MALFORMED_OOZE = 27981, + NPC_FORGED_IRON_DWARF = 27982, +}; - SPELL_SUMMON_IRON_SLUDGE = 50747, // instakill TARGET_SCRIPT - SPELL_IRON_SLUDGE_SPAWN_VISUAL = 50777, +struct Locations +{ + float x, y, z; + uint32 id; +}; - NPC_IRON_TROGG = 27979, - NPC_IRON_DWARF = 27982, - NPC_MALFORMED_OOZE = 27981, - NPC_IRON_SLUDGE = 28165 +static Locations PipeLoc[]= +{ + {1295.44f, 734.07f, 200.3f}, // left + {1297.7f, 595.6f, 199.9f}, // right }; /*###### @@ -80,37 +78,46 @@ struct MANGOS_DLL_DECL boss_sjonnirAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + bool m_bIsFrenzy; + + std::list m_lDwarfGUIDList; + uint32 m_uiChainLightning_Timer; + uint32 m_uiLightningShield_Timer; + uint32 m_uiStaticCharge_Timer; + uint32 m_uiLightningRing_Timer; + uint32 m_uiSummon_Timer; + uint32 m_uiFrenzy_Timer; void Reset() { - if (m_creature->isAlive()) - m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_SHIELD : SPELL_LIGHTNING_SHIELD_H, false); - } + m_bIsFrenzy = false; - void Aggro(Unit* pWho) - { - DoScriptText(SAY_AGGRO, m_creature); + m_uiChainLightning_Timer = 3000 + rand()%5000; + m_uiLightningShield_Timer = 20000 + rand()%5000; + m_uiStaticCharge_Timer = 20000 + rand()%5000; + m_uiLightningRing_Timer = 30000 + rand()%5000; + m_uiSummon_Timer = 5000; + m_uiFrenzy_Timer = 300000; - m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_SUMMON_IRON_DWARF : SPELL_SUMMON_IRON_DWARF_H, true); - m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_SUMMON_IRON_TROGG : SPELL_SUMMON_IRON_TROGG_H, true); - } + DespawnDwarf(); + if(m_pInstance) + m_pInstance->SetData(TYPE_GRIEF, NOT_STARTED); + } - void JustSummoned(Creature* pSummoned) + void Aggro(Unit* pWho) { - if (pSummoned->GetEntry() == NPC_IRON_TROGG || pSummoned->GetEntry() == NPC_IRON_DWARF || pSummoned->GetEntry() == NPC_MALFORMED_OOZE) - { - float fX, fY, fZ; - pSummoned->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 10.0f, fX, fY, fZ); + DoScriptText(SAY_AGGRO, m_creature); - pSummoned->RemoveSplineFlag(SPLINEFLAG_WALKMODE); - pSummoned->GetMotionMaster()->MovePoint(0, fX, fY, fZ); - } + if(m_pInstance) + m_pInstance->SetData(TYPE_GRIEF, IN_PROGRESS); +// pSummoned->RemoveSplineFlag(SPLINEFLAG_WALKMODE); +// pSummoned->GetMotionMaster()->MovePoint(0, fX, fY, fZ); } void KilledUnit(Unit* pVictim) { - switch(urand(0, 2)) + switch(rand()%3) { case 0: DoScriptText(SAY_SLAY_1, m_creature); break; case 1: DoScriptText(SAY_SLAY_2, m_creature); break; @@ -121,6 +128,37 @@ struct MANGOS_DLL_DECL boss_sjonnirAI : public ScriptedAI void JustDied(Unit* pKiller) { DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_GRIEF, DONE); + } + + void DespawnDwarf() + { + if (m_lDwarfGUIDList.empty()) + return; + + for(std::list::iterator itr = m_lDwarfGUIDList.begin(); itr != m_lDwarfGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + { + if (pTemp->isAlive()) + pTemp->ForcedDespawn(); + } + } + + m_lDwarfGUIDList.clear(); + } + + void JustSummoned(Creature* pSummoned) + { + m_lDwarfGUIDList.push_back(pSummoned->GetGUID()); + + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pSummoned->AddThreat(pTarget, 0.0f); + pSummoned->AI()->AttackStart(pTarget); + } } void UpdateAI(const uint32 uiDiff) @@ -128,6 +166,66 @@ struct MANGOS_DLL_DECL boss_sjonnirAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + if (m_uiChainLightning_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTING_H : SPELL_CHAIN_LIGHTING); + m_uiChainLightning_Timer = 10000 + rand()%5000; + } + else + m_uiChainLightning_Timer -= uiDiff; + + if (m_uiLightningShield_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTING_SHIELD_H : SPELL_LIGHTING_SHIELD); + m_uiLightningShield_Timer = 20000 + rand()%5000; + } + else + m_uiLightningShield_Timer -= uiDiff; + + if (m_uiStaticCharge_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_STATIC_CHARGE_H : SPELL_STATIC_CHARGE); + m_uiStaticCharge_Timer = 20000 + rand()%5000; + } + else + m_uiStaticCharge_Timer -= uiDiff; + + if (m_uiLightningRing_Timer < uiDiff) + { + if (m_creature->IsNonMeleeSpellCasted(false)) + m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTING_RING_H : SPELL_LIGHTING_RING); + m_uiLightningRing_Timer = 30000 + rand()%5000; + } + else + m_uiLightningRing_Timer -= uiDiff; + + if (m_uiSummon_Timer < uiDiff) + { + uint32 SummonPipe = rand()%2; + uint32 SummonEntry = 0; + switch(rand()%3) + { + case 0: SummonEntry = NPC_FORGED_IRON_TROGG; break; + case 1: SummonEntry = NPC_MALFORMED_OOZE; break; + case 2: SummonEntry = NPC_FORGED_IRON_DWARF; break; + } + m_creature->SummonCreature(SummonEntry, PipeLoc[SummonPipe].x, PipeLoc[SummonPipe].y, PipeLoc[SummonPipe].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + m_uiSummon_Timer = 20000; + } + else + m_uiSummon_Timer -= uiDiff; + + if (!m_bIsFrenzy && m_uiFrenzy_Timer < uiDiff) + { + DoCast(m_creature, SPELL_FRENZY); + m_bIsFrenzy = true; + m_uiFrenzy_Timer = 0; + } + else + m_uiFrenzy_Timer -= uiDiff; + DoMeleeAttackIfReady(); } }; diff --git a/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp b/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp index 085fe2864..375bbc1e3 100644 --- a/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp +++ b/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,8 +22,8 @@ SDCategory: Halls of Stone EndScriptData */ #include "precompiled.h" -#include "halls_of_stone.h" #include "escort_ai.h" +#include "halls_of_stone.h" enum { @@ -91,12 +91,184 @@ enum SAY_ENTRANCE_MEET = -1599064, TEXT_ID_START = 13100, - TEXT_ID_PROGRESS = 13101 + TEXT_ID_PROGRESS = 13101, + + NPC_TRIBUNAL_OF_THE_AGES = 28234, + NPC_BRANN_BRONZEBEARD = 28070, + SPELL_STEALTH = 58506, + + // KADDRAK + SPELL_GLARE_OF_THE_TRIBUNAL = 50988, + SPELL_GLARE_OF_THE_TRIBUNAL_H = 59870, + + // MARNAK + SPELL_DARK_MATTER = 51012, + SPELL_DARK_MATTER_H = 59868, + NPC_DARK_MATTER_TARGET = 28237, + + // ABEDNEUM + SPELL_SEARING_GAZE = 51136, + SPELL_SEARING_GAZE_H = 59867, + NPC_SEARING_GAZE_TARGET = 28265, + + NPC_DARK_RUNE_PROTECTOR = 27983, + NPC_DARK_RUNE_STORMCALLER = 27984, + NPC_IRON_GOLEM_CUSTODIAN = 27985, + + QUEST_HALLS_OF_STONE = 13207, }; #define GOSSIP_ITEM_START "Brann, it would be our honor!" #define GOSSIP_ITEM_PROGRESS "Let's move Brann, enough of the history lessons!" +struct Locations +{ + float x, y, z; + uint32 id; +}; + +static Locations SpawnLoc[]= +{ + {946.992f, 397.016f, 208.374f}, + {960.748f, 382.944f, 208.374f}, +}; + + +/*###### +## mob_tribuna_controller +######*/ + +struct MANGOS_DLL_DECL mob_tribuna_controllerAI : public ScriptedAI +{ + mob_tribuna_controllerAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + std::list m_lKaddrakGUIDList; + //std::list m_lMarnakGUIDList; + //std::list m_lAbedneumGUIDList; + + bool m_bIsActivateKaddrak; + bool m_bIsActivateMarnak; + bool m_bIsActivateAbedneum; + + uint32 m_uiKaddrak_Encounter_timer; + uint32 m_uiMarnak_Encounter_timer; + uint32 m_uiAbedneum_Encounter_timer; + + void Reset() + { + m_bIsActivateKaddrak = false; + m_bIsActivateMarnak = false; + m_bIsActivateAbedneum = false; + + m_uiKaddrak_Encounter_timer = 1500; + m_uiMarnak_Encounter_timer = 10000; + m_uiAbedneum_Encounter_timer = 10000; + + m_lKaddrakGUIDList.clear(); + //m_lMarnakGUIDList.clear(); + //m_lAbedneumGUIDList.clear(); + } + + void UpdateFacesList() + { + std::list m_lKaddrakList; + m_lKaddrakGUIDList.clear(); + GetCreatureListWithEntryInGrid(m_lKaddrakList, m_creature, NPC_KADDRAK, 50.0f); + if (!m_lKaddrakGUIDList.empty()) + { + uint32 uiPositionCounter = 0; + for(std::list::iterator itr = m_lKaddrakList.begin(); itr != m_lKaddrakList.end(); ++itr) + { + if (!(*itr)) continue; + + if (Creature* c = (Creature *)(*itr)) + { + m_lKaddrakGUIDList.push_back((*itr)->GetGUID()); + if (c->isAlive()) + { + if (uiPositionCounter == 0) + { + c->GetMap()->CreatureRelocation((*itr), 927.265f, 333.200f, 218.780f, (*itr)->GetOrientation()); + c->MonsterMove(927.265f, 333.200f, 218.780f, 1); + } + else + { + c->GetMap()->CreatureRelocation((*itr), 921.745f, 328.076f, 218.780f, (*itr)->GetOrientation()); + c->MonsterMove(921.745f, 328.076f, 218.780f, 1); + } + } + ++uiPositionCounter; + } + } + } + //GetCreatureListWithEntryInGrid(m_lMarnakGUIDList, m_creature, NPC_MARNAK, 50.0f); + //GetCreatureListWithEntryInGrid(m_lAbedneumGUIDList, m_creature, NPC_ABEDNEUM, 50.0f); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_bIsActivateKaddrak) + { + if (m_uiKaddrak_Encounter_timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (!m_lKaddrakGUIDList.empty()) + for(std::list::iterator itr = m_lKaddrakGUIDList.begin(); itr != m_lKaddrakGUIDList.end(); ++itr) + if (Creature* pCreature = m_creature->GetMap()->GetCreature(*itr)) + if (pCreature->isAlive()) + pCreature->CastSpell(pTarget, m_bIsRegularMode ? SPELL_GLARE_OF_THE_TRIBUNAL_H : SPELL_GLARE_OF_THE_TRIBUNAL, true); + + m_uiKaddrak_Encounter_timer = 1500; + } + else + m_uiKaddrak_Encounter_timer -= uiDiff; + } + if (m_bIsActivateMarnak) + { + if (m_uiMarnak_Encounter_timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (Creature* pTemp = m_creature->SummonCreature(NPC_DARK_MATTER_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000)) + { + pTemp->SetDisplayId(11686); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->CastSpell(pTarget, m_bIsRegularMode ? SPELL_DARK_MATTER_H : SPELL_DARK_MATTER, true); + } + + m_uiMarnak_Encounter_timer = 30000 + rand()%1000; + } + else + m_uiMarnak_Encounter_timer -= uiDiff; + } + if (m_bIsActivateAbedneum) + { + if (m_uiAbedneum_Encounter_timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (Creature* pTemp = m_creature->SummonCreature(NPC_SEARING_GAZE_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000)) + { + pTemp->SetDisplayId(11686); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->CastSpell(pTemp, m_bIsRegularMode ? SPELL_SEARING_GAZE_H : SPELL_SEARING_GAZE, true); + } + + m_uiAbedneum_Encounter_timer = 30000 + rand()%1000; + } + else + m_uiAbedneum_Encounter_timer -= uiDiff; + } + } +}; + /*###### ## npc_brann_hos ######*/ @@ -112,18 +284,87 @@ struct MANGOS_DLL_DECL npc_brann_hosAI : public npc_escortAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + bool m_bIsBattle; + bool m_bIsLowHP; + + uint32 m_uiStep; + uint32 m_uiPhase_timer; + + uint64 m_uiControllerGUID; + std::list m_lDwarfGUIDList; void Reset() { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + m_bIsLowHP = false; + m_bIsBattle = false; + + m_uiStep = 0; + m_uiPhase_timer = 0; + + m_uiControllerGUID = 0; + + DespawnDwarf(); + + if(m_pInstance) + m_pInstance->SetData(TYPE_BRANN, NOT_STARTED); + } + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (!m_bIsBattle) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho, 0.0f); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } } void WaypointReached(uint32 uiPointId) { + switch(uiPointId) + { + case 7: + if (Creature* pCreature = GetClosestCreatureWithEntry(m_creature, NPC_TRIBUNAL_OF_THE_AGES, 100.0f)) + { + if (!pCreature->isAlive()) + pCreature->Respawn(); + ((mob_tribuna_controllerAI*)pCreature->AI())->UpdateFacesList(); + m_uiControllerGUID = pCreature->GetGUID(); + } + break; + case 13: + DoScriptText(SAY_EVENT_INTRO_1, m_creature); + SetEscortPaused(true); + SetRun(true); + JumpToNextStep(20000); + break; + case 17: + DoScriptText(SAY_EVENT_INTRO_2, m_creature); + if (m_pInstance) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_TRIBUNAL_CONSOLE)); + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + SetEscortPaused(true); + JumpToNextStep(8500); + break; + case 18: + SetEscortPaused(true); + break; + } } void KilledUnit(Unit* pVictim) { - switch(urand(0, 2)) + switch(rand()%3) { case 0: DoScriptText(SAY_KILL_1, m_creature); break; case 1: DoScriptText(SAY_KILL_2, m_creature); break; @@ -136,23 +377,367 @@ struct MANGOS_DLL_DECL npc_brann_hosAI : public npc_escortAI DoScriptText(SAY_DEATH, m_creature); } - void UpdateEscortAI(const uint32 uiDiff) + void DespawnDwarf() { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + if (m_lDwarfGUIDList.empty()) return; - DoMeleeAttackIfReady(); + for(std::list::iterator itr = m_lDwarfGUIDList.begin(); itr != m_lDwarfGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + { + if (pTemp->isAlive()) + pTemp->ForcedDespawn(); + } + } + + m_lDwarfGUIDList.clear(); + } + + void SpawnDwarf(uint32 uiType) + { + switch(uiType) + { + case 1: + { + uint32 uiSpawnNumber = (m_bIsRegularMode ? 3 : 2); + for (uint8 i = 0; i < uiSpawnNumber; ++i) + m_creature->SummonCreature(NPC_DARK_RUNE_PROTECTOR, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + m_creature->SummonCreature(NPC_DARK_RUNE_STORMCALLER, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + break; + } + case 2: + for (uint8 i = 0; i < 2; ++i) + m_creature->SummonCreature(NPC_DARK_RUNE_STORMCALLER, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + break; + case 3: + m_creature->SummonCreature(NPC_IRON_GOLEM_CUSTODIAN, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + break; + } + } + + void JustSummoned(Creature* pSummoned) + { + m_lDwarfGUIDList.push_back(pSummoned->GetGUID()); + pSummoned->AddThreat(m_creature, 0.0f); + pSummoned->AI()->AttackStart(m_creature); + } + + void JumpToNextStep(uint32 uiTimer) + { + m_uiPhase_timer = uiTimer; + m_uiStep++; + } + + void UpdateEscortAI(const uint32 uiDiff) + { + if (m_uiPhase_timer < uiDiff) + { + switch(m_uiStep) + { + case 0: // unused + break; + case 1: + if (m_pInstance) + { + if (m_pInstance->GetData(TYPE_BRANN) != NOT_STARTED) + return; + + m_pInstance->SetData(TYPE_BRANN, IN_PROGRESS); + } + m_bIsBattle = false; + DoScriptText(SAY_ESCORT_START, m_creature); + JumpToNextStep(0); + break; + case 3: + SetEscortPaused(false); + JumpToNextStep(0); + break; + case 5: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_INTRO_3_ABED, pTemp); + JumpToNextStep(8500); + break; + case 6: + DoScriptText(SAY_EVENT_A_1, m_creature); + JumpToNextStep(6500); + break; + case 7: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK))) + DoScriptText(SAY_EVENT_A_2_KADD, pTemp); + JumpToNextStep(12500); + break; + case 8: + DoScriptText(SAY_EVENT_A_3, m_creature); + if (m_pInstance) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_KADDRAK)); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID)) + ((mob_tribuna_controllerAI*)pTemp->AI())->m_bIsActivateKaddrak = true; + JumpToNextStep(5000); + break; + case 9: + SpawnDwarf(1); + JumpToNextStep(20000); + break; + case 10: + DoScriptText(SAY_EVENT_B_1, m_creature); + JumpToNextStep(6000); + break; + case 11: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK))) + DoScriptText(SAY_EVENT_B_2_MARN, pTemp); + SpawnDwarf(1); + JumpToNextStep(20000); + break; + case 12: + DoScriptText(SAY_EVENT_B_3, m_creature); + if (m_pInstance) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_MARNAK)); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID)) + ((mob_tribuna_controllerAI*)pTemp->AI())->m_bIsActivateMarnak = true; + JumpToNextStep(10000); + break; + case 13: + SpawnDwarf(1); + JumpToNextStep(10000); + break; + case 14: + SpawnDwarf(2); + JumpToNextStep(20000); + break; + case 15: + DoScriptText(SAY_EVENT_C_1, m_creature); + SpawnDwarf(1); + JumpToNextStep(10000); + break; + case 16: + SpawnDwarf(2); + JumpToNextStep(20000); + break; + case 17: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_C_2_ABED, pTemp); + SpawnDwarf(1); + JumpToNextStep(20000); + break; + case 18: + DoScriptText(SAY_EVENT_C_3, m_creature); + if (m_pInstance) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_ABEDNEUM)); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID)) + ((mob_tribuna_controllerAI*)pTemp->AI())->m_bIsActivateAbedneum = true; + JumpToNextStep(5000); + break; + case 19: + SpawnDwarf(2); + JumpToNextStep(10000); + break; + case 20: + SpawnDwarf(1); + JumpToNextStep(15000); + break; + case 21: + DoScriptText(SAY_EVENT_D_1, m_creature); + SpawnDwarf(3); + JumpToNextStep(20000); + break; + case 22: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_D_2_ABED, pTemp); + SpawnDwarf(1); + JumpToNextStep(5000); + break; + case 23: + SpawnDwarf(2); + JumpToNextStep(15000); + break; + case 24: + DoScriptText(SAY_EVENT_D_3, m_creature); + SpawnDwarf(3); + JumpToNextStep(5000); + break; + case 25: + SpawnDwarf(1); + JumpToNextStep(5000); + break; + case 26: + SpawnDwarf(2); + JumpToNextStep(10000); + break; + case 27: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_D_4_ABED, pTemp); + SpawnDwarf(1); + JumpToNextStep(10000); + break; + case 28: + DoScriptText(SAY_EVENT_END_01, m_creature); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + if (m_pInstance) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_SKY_FLOOR)); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID)) + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_bIsBattle = true; + SetEscortPaused(false); + JumpToNextStep(3500); + break; + case 29: + DoScriptText(SAY_EVENT_END_02, m_creature); + JumpToNextStep(3500); + break; + case 30: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_END_03_ABED, pTemp); + JumpToNextStep(4500); + break; + case 31: + DoScriptText(SAY_EVENT_END_04, m_creature); + JumpToNextStep(6500); + break; + case 32: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_END_05_ABED, pTemp); + JumpToNextStep(6500); + break; + case 33: + DoScriptText(SAY_EVENT_END_06, m_creature); + JumpToNextStep(2500); + break; + case 34: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_END_07_ABED, pTemp); + JumpToNextStep(10500); + break; + case 35: + DoScriptText(SAY_EVENT_END_08, m_creature); + JumpToNextStep(4500); + break; + case 36: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK))) + DoScriptText(SAY_EVENT_END_09_KADD, pTemp); + JumpToNextStep(7500); + break; + case 37: + DoScriptText(SAY_EVENT_END_10, m_creature); + JumpToNextStep(2500); + break; + case 38: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK))) + DoScriptText(SAY_EVENT_END_11_KADD, pTemp); + JumpToNextStep(10500); + break; + case 39: + DoScriptText(SAY_EVENT_END_12, m_creature); + JumpToNextStep(2500); + break; + case 40: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK))) + DoScriptText(SAY_EVENT_END_13_KADD, pTemp); + JumpToNextStep(9500); + break; + case 41: + DoScriptText(SAY_EVENT_END_14, m_creature); + JumpToNextStep(5500); + break; + case 42: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK))) + DoScriptText(SAY_EVENT_END_15_MARN, pTemp); + JumpToNextStep(3500); + break; + case 43: + DoScriptText(SAY_EVENT_END_16, m_creature); + JumpToNextStep(3500); + break; + case 44: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK))) + DoScriptText(SAY_EVENT_END_17_MARN, pTemp); + JumpToNextStep(11500); + break; + case 45: + DoScriptText(SAY_EVENT_END_18, m_creature); + JumpToNextStep(10500); + break; + case 46: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK))) + DoScriptText(SAY_EVENT_END_19_MARN, pTemp); + JumpToNextStep(2500); + break; + case 47: + DoScriptText(SAY_EVENT_END_20, m_creature); + JumpToNextStep(4500); + break; + case 48: + if (m_pInstance) + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM))) + DoScriptText(SAY_EVENT_END_21_ABED, pTemp); + JumpToNextStep(3500); + break; + case 49: + { + if (m_pInstance) + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_KADDRAK)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_MARNAK)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_ABEDNEUM)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_SKY_FLOOR)); + m_pInstance->SetData(TYPE_BRANN, DONE); + } + + Player* pPlayer = GetPlayerForEscort(); + if (pPlayer) + pPlayer->GroupEventHappens(QUEST_HALLS_OF_STONE, m_creature); + + m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + + JumpToNextStep(180000); + break; + } + case 50: + SetEscortPaused(false); + break; + } + } + else m_uiPhase_timer -= uiDiff; + + if (!m_bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 30) + { + DoScriptText(SAY_LOW_HEALTH, m_creature); + m_bIsLowHP = true; + } + else if (m_bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 30) + m_bIsLowHP = false; } }; bool GossipHello_npc_brann_hos(Player* pPlayer, Creature* pCreature) { + ScriptedInstance* m_pInstance; + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + if (pCreature->isQuestGiver()) pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - pPlayer->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID()); +if (m_pInstance->GetData(TYPE_BRANN) != DONE) pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID()); + //pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_PROGRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); //pPlayer->SEND_GOSSIP_MENU(TEXT_ID_PROGRESS, pCreature->GetGUID()); return true; @@ -161,7 +746,11 @@ bool GossipHello_npc_brann_hos(Player* pPlayer, Creature* pCreature) bool GossipSelect_npc_brann_hos(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { if (uiAction == GOSSIP_ACTION_INFO_DEF+1 || uiAction == GOSSIP_ACTION_INFO_DEF+2) + { pPlayer->CLOSE_GOSSIP_MENU(); + ((npc_brann_hosAI*)pCreature->AI())->m_uiStep = 1; + ((npc_brann_hosAI*)pCreature->AI())->Start(false, pPlayer->GetGUID()); + } return true; } @@ -171,14 +760,24 @@ CreatureAI* GetAI_npc_brann_hos(Creature* pCreature) return new npc_brann_hosAI(pCreature); } +CreatureAI* GetAI_mob_tribuna_controller(Creature* pCreature) +{ + return new mob_tribuna_controllerAI (pCreature); +} + void AddSC_halls_of_stone() { - Script* pNewScript; - - pNewScript = new Script; - pNewScript->Name = "npc_brann_hos"; - pNewScript->GetAI = &GetAI_npc_brann_hos; - pNewScript->pGossipHello = &GossipHello_npc_brann_hos; - pNewScript->pGossipSelect = &GossipSelect_npc_brann_hos; - pNewScript->RegisterSelf(); + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_brann_hos"; + newscript->GetAI = &GetAI_npc_brann_hos; + newscript->pGossipHello = &GossipHello_npc_brann_hos; + newscript->pGossipSelect = &GossipSelect_npc_brann_hos; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_tribuna_controller"; + newscript->GetAI = &GetAI_mob_tribuna_controller; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h b/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h index aca0a7b18..9b0f1fca1 100644 --- a/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h +++ b/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2009 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -9,29 +9,47 @@ enum { MAX_ENCOUNTER = 4, - TYPE_TRIBUNAL = 0, - TYPE_MAIDEN = 1, - TYPE_KRYSTALLUS = 2, - TYPE_SJONNIR = 3, + DATA_KRYSTALLUS = 1, + DATA_GRIEF = 2, + DATA_BRANN = 3, + DATA_SJONNIR = 4, - NPC_BRANN = 28070, + DATA_KADDRAK = 5, + DATA_ABEDNEUM = 6, + DATA_MARNAK = 7, - NPC_KADDRAK = 30898, - NPC_ABEDNEUM = 30899, - NPC_MARNAK = 30897, + DATA_GO_TRIBUNAL_CONSOLE = 8, + DATA_GO_SKY_FLOOR = 9, + DATA_GO_KADDRAK = 10, + DATA_GO_ABEDNEUM = 11, + DATA_GO_MARNAK = 12, - GO_DOOR_SJONNIR = 191296, - GO_DOOR_TRIBUNAL = 191294, // possibly closed during event? + TYPE_KRYSTALLUS = 20, + TYPE_GRIEF = 21, + TYPE_BRANN = 22, + TYPE_SJONNIR = 23, - GO_TRIBUNAL_CHEST = 190586, - GO_TRIBUNAL_CHEST_H = 193996, + NPC_KRYSTALLUS = 27977, + NPC_GRIEF = 27975, + NPC_BRANN = 28070, + NPC_SJONNIR = 27978, - GO_TRIBUNAL_HEAD_RIGHT = 191670, // marnak - GO_TRIBUNAL_HEAD_CENTER = 191669, // abedneum - GO_TRIBUNAL_HEAD_LEFT = 191671, // kaddrak + NPC_KADDRAK = 30898, // left + NPC_ABEDNEUM = 30899, // middle + NPC_MARNAK = 30897, // right + + GO_GRIEF_DOOR = 191292, + GO_BRANN_DOOR = 191293, + GO_SJONNIR_DOOR = 191296, + + GO_KADDRAK = 191671, // left + GO_ABEDNEUM = 191669, // middle + GO_MARNAK = 191670, // right GO_TRIBUNAL_CONSOLE = 193907, - GO_TRIBUNAL_FLOOR = 191527, + GO_TRIBUNAL_CHEST = 190586, + GO_TRIBUNAL_CHEST_H = 193996, + GO_TRIBUNAL_SKY_FLOOR = 191527, GO_SJONNIR_CONSOLE = 193906 }; diff --git a/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp b/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp index 2274a29e1..fc06ac2d7 100644 --- a/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp +++ b/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,7 +16,7 @@ /* ScriptData SDName: Instance_Halls_of_Stone -SD%Complete: 10% +SD%Complete: 0% SDComment: SDCategory: Halls of Stone EndScriptData */ @@ -24,54 +24,100 @@ EndScriptData */ #include "precompiled.h" #include "halls_of_stone.h" +/* Halls of Lightning encounters: +0 - Krystallus +1 - Maiden of Grief +2 - Brann Bronzebeard +3 - Sjonnir The Ironshaper +*/ + struct MANGOS_DLL_DECL instance_halls_of_stone : public ScriptedInstance { - instance_halls_of_stone(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + instance_halls_of_stone(Map* pMap) : ScriptedInstance(pMap) { + Regular = pMap->IsRegularDifficulty(); + Initialize(); + }; uint32 m_auiEncounter[MAX_ENCOUNTER]; + bool Regular; + std::string strSaveData; + uint64 m_uiKrystallusGUID; + uint64 m_uiGriefGUID; uint64 m_uiBrannGUID; + uint64 m_uiSjonnirGUID; + uint64 m_uiKaddrakGUID; uint64 m_uiAbedneumGUID; uint64 m_uiMarnakGUID; + uint64 m_uiGriefDoorGUID; + uint64 m_uiBrannDoorGUID; uint64 m_uiSjonnirDoorGUID; - uint64 m_uiTribunalDoorGUID; - uint64 m_uiTribunalChestGUID; - uint64 m_uiTribunalHeadRightGUID; - uint64 m_uiTribunalHeadCenterGUID; - uint64 m_uiTribunalHeadLeftGUID; - uint64 m_uiTribunalConsoleGUID; - uint64 m_uiTribunalFloorGUID; - uint64 m_uiSjonnirConsoleGUID; + + uint64 m_uiGoTribunalConsoleGUID; + uint64 m_uiGoTribunalChestGUID; + uint64 m_uiGoTribunalSkyFloorGUID; + uint64 m_uiGoKaddrakGUID; + uint64 m_uiGoAbedneumGUID; + uint64 m_uiGoMarnakGUID; + + void OpenDoor(uint64 guid) + { + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_ACTIVE); + } + + void CloseDoor(uint64 guid) + { + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_READY); + } void Initialize() { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiBrannGUID = 0; - m_uiKaddrakGUID = 0; - m_uiAbedneumGUID = 0; - m_uiMarnakGUID = 0; - - m_uiSjonnirDoorGUID = 0; - m_uiTribunalDoorGUID = 0; - m_uiTribunalChestGUID = 0; - m_uiTribunalHeadRightGUID = 0; - m_uiTribunalHeadCenterGUID = 0; - m_uiTribunalHeadLeftGUID = 0; - m_uiTribunalConsoleGUID = 0; - m_uiTribunalFloorGUID = 0; - m_uiSjonnirConsoleGUID = 0; + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + m_auiEncounter[i]=NOT_STARTED; + + m_uiKrystallusGUID = 0; + m_uiGriefGUID = 0; + m_uiBrannGUID = 0; + m_uiSjonnirGUID = 0; + + m_uiKaddrakGUID = 0; + m_uiAbedneumGUID = 0; + m_uiMarnakGUID = 0; + + m_uiGriefDoorGUID = 0; + m_uiBrannDoorGUID = 0; + m_uiSjonnirDoorGUID = 0; + + m_uiGoTribunalConsoleGUID = 0; + m_uiGoTribunalChestGUID = 0; + m_uiGoTribunalSkyFloorGUID = 0; + m_uiGoKaddrakGUID = 0; + m_uiGoAbedneumGUID = 0; + m_uiGoMarnakGUID = 0; } void OnCreatureCreate(Creature* pCreature) { switch(pCreature->GetEntry()) { + case NPC_KRYSTALLUS: + m_uiKrystallusGUID = pCreature->GetGUID(); + break; + case NPC_GRIEF: + m_uiGriefGUID = pCreature->GetGUID(); + break; case NPC_BRANN: m_uiBrannGUID = pCreature->GetGUID(); break; + case NPC_SJONNIR: + m_uiSjonnirGUID = pCreature->GetGUID(); + break; case NPC_KADDRAK: m_uiKaddrakGUID = pCreature->GetGUID(); break; @@ -88,67 +134,114 @@ struct MANGOS_DLL_DECL instance_halls_of_stone : public ScriptedInstance { switch(pGo->GetEntry()) { - case GO_DOOR_SJONNIR: + case GO_GRIEF_DOOR: + m_uiGriefDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[0] != DONE) + CloseDoor(m_uiGriefDoorGUID); + else OpenDoor(m_uiGriefDoorGUID); + break; + case GO_BRANN_DOOR: + m_uiBrannDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[1] != DONE) + CloseDoor(m_uiBrannDoorGUID); + else OpenDoor(m_uiBrannDoorGUID); + break; + case GO_SJONNIR_DOOR: m_uiSjonnirDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[2] != DONE) + CloseDoor(m_uiSjonnirDoorGUID); + else OpenDoor(m_uiSjonnirDoorGUID); break; - case GO_DOOR_TRIBUNAL: - m_uiTribunalDoorGUID = pGo->GetGUID(); + case GO_TRIBUNAL_CONSOLE: + m_uiGoTribunalConsoleGUID = pGo->GetGUID(); break; case GO_TRIBUNAL_CHEST: - case GO_TRIBUNAL_CHEST_H: - m_uiTribunalChestGUID = pGo->GetGUID(); - break; - case GO_TRIBUNAL_HEAD_RIGHT: - m_uiTribunalHeadRightGUID = pGo->GetGUID(); + if (Regular) m_uiGoTribunalChestGUID = pGo->GetGUID(); break; - case GO_TRIBUNAL_HEAD_CENTER: - m_uiTribunalHeadCenterGUID = pGo->GetGUID(); + case GO_TRIBUNAL_CHEST_H: + if (!Regular) m_uiGoTribunalChestGUID = pGo->GetGUID(); break; - case GO_TRIBUNAL_HEAD_LEFT: - m_uiTribunalHeadLeftGUID = pGo->GetGUID(); + case GO_TRIBUNAL_SKY_FLOOR: + m_uiGoTribunalSkyFloorGUID = pGo->GetGUID(); break; - case GO_TRIBUNAL_CONSOLE: - m_uiTribunalConsoleGUID = pGo->GetGUID(); + case GO_KADDRAK: + m_uiGoKaddrakGUID = pGo->GetGUID(); break; - case GO_TRIBUNAL_FLOOR: - m_uiTribunalFloorGUID = pGo->GetGUID(); + case GO_ABEDNEUM: + m_uiGoAbedneumGUID = pGo->GetGUID(); break; - case GO_SJONNIR_CONSOLE: - m_uiSjonnirConsoleGUID = pGo->GetGUID(); + case GO_MARNAK: + m_uiGoMarnakGUID = pGo->GetGUID(); break; } } + void OnPlayerEnter(Unit* pPlayer) + { + if (m_auiEncounter[0] != DONE) + CloseDoor(m_uiGriefDoorGUID); + else OpenDoor(m_uiGriefDoorGUID); + if (m_auiEncounter[1] != DONE) + CloseDoor(m_uiBrannDoorGUID); + else OpenDoor(m_uiBrannDoorGUID); + if (m_auiEncounter[2] != DONE) + CloseDoor(m_uiSjonnirDoorGUID); + else OpenDoor(m_uiSjonnirDoorGUID); + } + void SetData(uint32 uiType, uint32 uiData) { switch(uiType) { - case TYPE_TRIBUNAL: - m_auiEncounter[0] = uiData; + case TYPE_KRYSTALLUS: if (uiData == DONE) - DoRespawnGameObject(m_uiTribunalChestGUID); + OpenDoor(m_uiGriefDoorGUID); + m_auiEncounter[0] = uiData; break; - case TYPE_MAIDEN: + case TYPE_GRIEF: + if (uiData == DONE) + OpenDoor(m_uiBrannDoorGUID); m_auiEncounter[1] = uiData; break; - case TYPE_KRYSTALLUS: + case TYPE_BRANN: + if (uiData == DONE) + { + OpenDoor(m_uiSjonnirDoorGUID); + DoRespawnGameObject(m_uiGoTribunalChestGUID); + OpenDoor(m_uiGoTribunalChestGUID); + } m_auiEncounter[2] = uiData; break; case TYPE_SJONNIR: m_auiEncounter[3] = uiData; break; } + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + saveStream << m_auiEncounter[i] << " "; + + strSaveData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } uint32 GetData(uint32 uiType) { switch(uiType) { - case TYPE_TRIBUNAL: + case TYPE_KRYSTALLUS: return m_auiEncounter[0]; - case TYPE_MAIDEN: + case TYPE_GRIEF: return m_auiEncounter[1]; - case TYPE_KRYSTALLUS: + case TYPE_BRANN: return m_auiEncounter[2]; case TYPE_SJONNIR: return m_auiEncounter[3]; @@ -160,36 +253,62 @@ struct MANGOS_DLL_DECL instance_halls_of_stone : public ScriptedInstance { switch(uiData) { - case NPC_BRANN: + case DATA_KRYSTALLUS: + return m_uiKrystallusGUID; + case DATA_GRIEF: + return m_uiGriefGUID; + case DATA_BRANN: return m_uiBrannGUID; - case NPC_KADDRAK: + case DATA_SJONNIR: + return m_uiSjonnirGUID; + case DATA_KADDRAK: return m_uiKaddrakGUID; - case NPC_ABEDNEUM: + case DATA_ABEDNEUM: return m_uiAbedneumGUID; - case NPC_MARNAK: + case DATA_MARNAK: return m_uiMarnakGUID; - case GO_DOOR_SJONNIR: - return m_uiSjonnirDoorGUID; - case GO_DOOR_TRIBUNAL: - return m_uiTribunalDoorGUID; - case GO_TRIBUNAL_CHEST: - case GO_TRIBUNAL_CHEST_H: - return m_uiTribunalChestGUID; - case GO_TRIBUNAL_HEAD_RIGHT: - return m_uiTribunalHeadRightGUID; - case GO_TRIBUNAL_HEAD_CENTER: - return m_uiTribunalHeadCenterGUID; - case GO_TRIBUNAL_HEAD_LEFT: - return m_uiTribunalHeadLeftGUID; - case GO_TRIBUNAL_CONSOLE: - return m_uiTribunalConsoleGUID; - case GO_TRIBUNAL_FLOOR: - return m_uiTribunalFloorGUID; - case GO_SJONNIR_CONSOLE: - return m_uiSjonnirConsoleGUID; + case DATA_GO_TRIBUNAL_CONSOLE: + return m_uiGoTribunalConsoleGUID; + case DATA_GO_SKY_FLOOR: + return m_uiGoTribunalSkyFloorGUID; + case DATA_GO_KADDRAK: + return m_uiGoKaddrakGUID; + case DATA_GO_ABEDNEUM: + return m_uiGoAbedneumGUID; + case DATA_GO_MARNAK: + return m_uiGoMarnakGUID; } return 0; } + + const char* Save() + { + return strSaveData.c_str(); + } + + void Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + loadStream >> m_auiEncounter[i]; + + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; + } + }; InstanceData* GetInstanceData_instance_halls_of_stone(Map* pMap) @@ -205,3 +324,4 @@ void AddSC_instance_halls_of_stone() newscript->GetInstanceData = &GetInstanceData_instance_halls_of_stone; newscript->RegisterSelf(); } + diff --git a/scripts/northrend/ulduar/ulduar/assembly_of_iron.cpp b/scripts/northrend/ulduar/ulduar/assembly_of_iron.cpp index 9185c8152..bc67e7708 100644 --- a/scripts/northrend/ulduar/ulduar/assembly_of_iron.cpp +++ b/scripts/northrend/ulduar/ulduar/assembly_of_iron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,9 +15,9 @@ */ /* ScriptData -SDName: assembly_of_iron -SD%Complete: 0% -SDComment: +SDName: boss_iron_council +SD%Complete: +SDComment: Supercharge is bugged SDCategory: Ulduar EndScriptData */ @@ -26,34 +26,1184 @@ EndScriptData */ enum { - SAY_BRUNDIR_AGGRO = -1603056, - SAY_BRUNDIR_WHIRL = -1603057, - SAY_BRUNDIR_DEATH_1 = -1603058, - SAY_BRUNDIR_DEATH_2 = -1603059, - SAY_BRUNDIR_SLAY_1 = -1603060, - SAY_BRUNDIR_SLAY_2 = -1603061, - SAY_BRUNDIR_BERSERK = -1603062, - SAY_BRUNDIR_FLY = -1603063, - - SAY_MOLGEIM_AGGRO = -1603064, - SAY_MOLGEIM_DEATH_1 = -1603065, - SAY_MOLGEIM_DEATH_2 = -1603066, - SAY_MOLGEIM_DEATH_RUNE = -1603067, - SAY_MOLGEIM_SURGE = -1603068, - SAY_MOLGEIM_SLAY_1 = -1603069, - SAY_MOLGEIM_SLAY_2 = -1603070, - SAY_MOLGEIM_BERSERK = -1603071, - - SAY_STEEL_AGGRO = -1603072, - SAY_STEEL_DEATH_1 = -1603073, - SAY_STEEL_DEATH_2 = -1603074, - SAY_STEEL_SLAY_1 = -1603075, - SAY_STEEL_SLAY_2 = -1603076, - SAY_STEEL_OVERWHELM = -1603077, - SAY_STEEL_BERSERK = -1603078, + //yells + SAY_MOLGEIM_AGGRO = -1603040, + SAY_MOLGEIM_DEATH1 = -1603041, + SAY_MOLGEIM_DEATH2 = -1603042, + SAY_MOLGEIM_DEATH_RUNE = -1603043, + SAY_MOLGEIM_SUMMON = -1603044, + SAY_MOLGEIM_SLAY1 = -1603045, + SAY_MOLGEIM_SLAY2 = -1603046, + SAY_MOLGEIM_BERSERK = -1603047, + + SAY_STEEL_AGGRO = -1603050, + SAY_STEEL_DEATH1 = -1603051, + SAY_STEEL_DEATH2 = -1603052, + SAY_STEEL_SLAY1 = -1603053, + SAY_STEEL_SLAY2 = -1603054, + SAY_STEEL_OVERWHELMING = -1603055, + SAY_STEEL_BERSERK = -1603056, + + SAY_BRUNDIR_AGGR0 = -1603060, + SAY_BRUNDIR_WHIRL = -1603062, + SAY_BRUNDIR_DEATH1 = -1603063, + SAY_BRUNDIR_DEATH2 = -1603064, + SAY_BRUNDIR_SLAY1 = -1603065, + SAY_BRUNDIR_SLAY2 = -1603066, + SAY_BRUNDIR_BERSERK = -1603067, + SAY_BRUNDIR_FLY = -1603068, + + //all + SPELL_BERSERK = 47008, + SPELL_SUPERCHARGE = 61920, // spell is bugged. Should be cast on other bosses not on players!!! + //steelbreaker + SPELL_HIGH_VOLTAGE = 61890, + SPELL_HIGH_VOLTAGE_H = 63498, + SPELL_FUSION_PUNCH = 61903, + SPELL_FUSION_PUNCH_H = 63493, + SPELL_STATIC_DISRUPTION = 44008, + SPELL_STATIC_DISRUPTION_H = 63494, + SPELL_POWER = 64637, + SPELL_POWER_H = 61888, + SPELL_ELECTRICAL_CHARGE = 61902, + //runemaster molgeim + SPELL_SHIELD = 62274, + SPELL_SHIELD_H = 63489, + SPELL_RUNE_OF_POWER = 63513, + SPELL_RUNE_OF_DEATH = 62269, + SPELL_RUNE_OF_DEATH_H = 63490, + SPELL_RUNE_OF_SUMMONING = 62273, + //rune of power + AURA_RUNE_OF_POWER = 61974, + //rune of summoning + AURA_RUNE_OF_SUMMONING = 62019, + //lightning elemental + SPELL_LIGHTNING_BLAST = 62054, + SPELL_LIGHTNING_BLAST_H = 63491, + //stormcaller brundir + SPELL_CHAIN_LIGHTNING = 61879, + SPELL_CHAIN_LIGHTNING_H = 63479, + SPELL_OVERLOAD = 61869, + SPELL_LIGHTNING_WHIRL = 61915, + SPELL_LIGHTNING_WHIRL_H = 63483, + SPELL_STORMSHIELD = 64187, + SPELL_LIGHTNING_TENDRILS = 61887, + SPELL_LIGHTNING_TENDRILS_H = 63486, + LIGHTNING_TENDRILS_VISUAL = 61883, + //NPC ids + MOB_LIGHTNING_ELEMENTAL = 32958, + + ACHIEV_ON_YOUR_SIDE = 2945, + ACHIEV_ON_YOUR_SIDE_H = 2946, + SPELL_IRON_BOOT_AURA = 58501, + + ACHIEV_CHOOSE_BRUNDIR = 2940, + ACHIEV_CHOOSE_BRUNDIR_H = 2943, + ACHIEV_CHOOSE_MOLGEIM = 2939, + ACHIEV_CHOOSE_MOLGEIM_H = 2942, + ACHIEV_CHOOSE_STEELBREAKER = 2941, + ACHIEV_CHOOSE_STEELBREAKER_H= 2944, +}; + +// Rune of Power +struct MANGOS_DLL_DECL mob_rune_of_powerAI : public ScriptedAI +{ + mob_rune_of_powerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + SetCombatMovement(false); + Reset(); + } + + uint32 m_uiDeath_Timer; + + void Reset() + { + m_uiDeath_Timer = 60000; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, AURA_RUNE_OF_POWER); + } + + void UpdateAI(const uint32 diff) + { + if (m_uiDeath_Timer < diff) + { + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + }else m_uiDeath_Timer -= diff; + } +}; + +CreatureAI* GetAI_mob_rune_of_power(Creature* pCreature) +{ + return new mob_rune_of_powerAI(pCreature); +} + +// Lightning Elemental +struct MANGOS_DLL_DECL mob_ulduar_lightning_elementalAI : public ScriptedAI +{ + mob_ulduar_lightning_elementalAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiDeath_Timer; + uint32 m_uiCheck_Timer; + bool m_bWillExplode; + + void Reset() + { + m_bWillExplode = false; + m_uiCheck_Timer = 1000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiDeath_Timer < diff && m_bWillExplode) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDeath_Timer -= diff; + + if (m_uiCheck_Timer < diff) + { + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 15)) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_BLAST : SPELL_LIGHTNING_BLAST_H); + m_bWillExplode = true; + m_uiDeath_Timer = 500; + m_uiCheck_Timer = 5000; + } + m_uiCheck_Timer = 1000; + }else m_uiCheck_Timer -= diff; + } +}; + +CreatureAI* GetAI_mob_ulduar_lightning_elemental(Creature* pCreature) +{ + return new mob_ulduar_lightning_elementalAI(pCreature); +} + +// Rune of Summoning +struct MANGOS_DLL_DECL mob_rune_of_summoningAI : public ScriptedAI +{ + mob_rune_of_summoningAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiDeath_Timer; + uint32 m_uiSummon_Timer; + uint32 m_uiSummonNum; + + void Reset() + { + m_uiDeath_Timer = 0; + m_uiSummon_Timer = 5000; + m_uiSummonNum = 0; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, AURA_RUNE_OF_SUMMONING); + } + + void JustSummoned(Creature* pSummoned) + { + pSummoned->SetInCombatWithZone(); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AddThreat(pTarget, 100.0f); + } + + void UpdateAI(const uint32 diff) + { + if (m_uiSummon_Timer < diff) + { + if (Creature* pTemp = m_creature->SummonCreature(MOB_LIGHTNING_ELEMENTAL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + ++m_uiSummonNum; + + if (m_uiSummonNum > 9) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + m_uiSummon_Timer = 500; + } else m_uiSummon_Timer -= diff; + } +}; + +CreatureAI* GetAI_mob_rune_of_summoning(Creature* pCreature) +{ + return new mob_rune_of_summoningAI(pCreature); +} + +//Stormcaller Brundir +struct MANGOS_DLL_DECL boss_brundirAI : public ScriptedAI +{ + boss_brundirAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiChain_Lightning_Timer; + uint32 m_uiOverload_Timer; + uint32 m_uiWhirl_Timer; + uint32 m_uiTendrils_start_Timer; + uint32 m_uiTendrils_Change; + uint32 m_uiTendrils_end_Timer; + uint32 m_uiDie_delay; + uint32 m_uiEnrage_Timer; + uint32 m_uiCheckTimer; + + bool m_bHasSupercharge1; + bool m_bHasSupercharge2; + bool m_bIsTendrils; + bool m_bMustDie; + bool m_bIsSteelbreakerDead; + bool m_bIsMolgeimDead; + bool m_bIsEnrage; + + void Reset() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_uiChain_Lightning_Timer = 0; + m_uiOverload_Timer = 35000; + m_uiEnrage_Timer = 900000; + m_uiCheckTimer = 1000; + m_bIsEnrage = false; + m_bHasSupercharge1 = false; + m_bHasSupercharge2 = false; + m_bIsTendrils = false; + m_bIsSteelbreakerDead = false; + m_bIsMolgeimDead = false; + m_bMustDie = false; + if (m_creature->HasAura(SPELL_SUPERCHARGE)) + m_creature->RemoveAurasDueToSpell(SPELL_SUPERCHARGE); + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if (uiDamage > m_creature->GetHealth() && !m_bMustDie) + { + uiDamage = 0; + m_creature->CastStop(); + m_creature->RemoveAllAuras(); + DoCast(m_creature, SPELL_SUPERCHARGE); + m_uiDie_delay = 500; + m_bMustDie = true; + } + } + + void OnYourSide() + { + /* hacky way to complete achievements; use only if you have this function + Map* pMap = m_creature->GetMap(); + AchievementEntry const *AchievYourSide = GetAchievementStore()->LookupEntry(m_bIsRegularMode ? ACHIEV_ON_YOUR_SIDE : ACHIEV_ON_YOUR_SIDE_H); + if(AchievYourSide && pMap) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + if (!lPlayers.isEmpty()) + { + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + { + if(pPlayer->HasAura(SPELL_IRON_BOOT_AURA, EFFECT_INDEX_0)) + pPlayer->CompletedAchievement(AchievYourSide); + } + } + } + } + */ + } + + void JustDied(Unit* pKiller) + { + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + // if all of them are dead + if (m_pInstance) + { + // remove supercharge from players -> spell bug + //m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SUPERCHARGE); + // if the others are dead then give loot + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (!pTemp->isAlive()) + { + if (Creature* p2Temp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (!p2Temp->isAlive()) + { + m_pInstance->SetData(TYPE_ASSEMBLY, DONE); + // only the current one has loot, because loot modes are implemented in sql + m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + // I'm on your side + OnYourSide(); + + // ChooseBrundir + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHOOSE_BRUNDIR : ACHIEV_CHOOSE_BRUNDIR_H); + } + } + } + } + + // else make them full hp + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (pTemp->isAlive()) + pTemp->SetHealth(pTemp->GetMaxHealth()); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (pTemp->isAlive()) + pTemp->SetHealth(pTemp->GetMaxHealth()); + } + } + + if(irand(0,1)) + DoScriptText(SAY_BRUNDIR_DEATH1, m_creature); + else + DoScriptText(SAY_BRUNDIR_DEATH2, m_creature); + } + + void Aggro(Unit* pWho) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + if (m_pInstance) + { + if(m_pInstance->GetData(TYPE_ASSEMBLY) != IN_PROGRESS) + m_pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS); + } + + DoScriptText(SAY_BRUNDIR_AGGR0, m_creature); + } + + void JustReachedHome() + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + if (m_pInstance) + { + if(m_pInstance->GetData(TYPE_ASSEMBLY) != FAIL) + m_pInstance->SetData(TYPE_ASSEMBLY, FAIL); + } + } + + void KilledUnit(Unit *who) + { + if(irand(0,1)) + DoScriptText(SAY_BRUNDIR_SLAY1, m_creature); + else + DoScriptText(SAY_BRUNDIR_SLAY2, m_creature); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // level 1 spells + if (m_uiChain_Lightning_Timer < uiDiff && !m_bIsTendrils) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(target, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H); + m_uiChain_Lightning_Timer = 2000; + }else m_uiChain_Lightning_Timer -= uiDiff; + + if (m_uiOverload_Timer < uiDiff && !m_bIsTendrils) + { + m_creature->CastStop(); + DoCast(m_creature, SPELL_OVERLOAD); + m_uiOverload_Timer = 40000; + }else m_uiOverload_Timer -= uiDiff; + + // level 2 spells + if (m_uiWhirl_Timer < uiDiff && !m_bIsTendrils && m_bHasSupercharge1) + { + m_creature->CastStop(); + DoScriptText(SAY_BRUNDIR_WHIRL, m_creature); + DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_WHIRL : SPELL_LIGHTNING_WHIRL_H); + m_uiWhirl_Timer = 15000; + }else m_uiWhirl_Timer -= uiDiff; + + // level 3 spells + // boss doesn't fly during tendrils, needs fixing! + if (m_uiTendrils_start_Timer < uiDiff && m_bHasSupercharge2) + { + if (!m_bIsTendrils) + { + DoScriptText(SAY_BRUNDIR_FLY, m_creature); + m_creature->CastStop(); + DoCast(m_creature, LIGHTNING_TENDRILS_VISUAL); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + m_creature->AddThreat(pTarget,0.0f); + m_creature->AI()->AttackStart(pTarget); + } + m_bIsTendrils = true; + m_creature->SetSpeedRate(MOVE_RUN, 0.8f); + m_uiTendrils_start_Timer = 3000; + m_uiTendrils_end_Timer = 40000; + m_uiTendrils_Change = 5000; + } + else + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_TENDRILS : SPELL_LIGHTNING_TENDRILS_H); + m_uiTendrils_start_Timer = 90000; + } + }else m_uiTendrils_start_Timer -= uiDiff; + + if (m_uiTendrils_Change < uiDiff && m_bIsTendrils) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + m_creature->AddThreat(pTarget,0.0f); + m_creature->AI()->AttackStart(pTarget); + } + m_uiTendrils_Change = 6000; + }else m_uiTendrils_Change -= uiDiff; + + if (m_uiTendrils_end_Timer < uiDiff && m_bIsTendrils) + { + if (m_creature->HasAura(SPELL_LIGHTNING_TENDRILS)) + m_creature->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS); + if (m_creature->HasAura(SPELL_LIGHTNING_TENDRILS_H)) + m_creature->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS_H); + if (m_creature->HasAura(LIGHTNING_TENDRILS_VISUAL)) + m_creature->RemoveAurasDueToSpell(LIGHTNING_TENDRILS_VISUAL); + m_uiTendrils_start_Timer = 90000; + m_creature->SetSpeedRate(MOVE_RUN, 1.8f); + m_bIsTendrils = false; + m_uiChain_Lightning_Timer = 5000; + m_uiOverload_Timer = 35000; + m_uiWhirl_Timer = 10000; + }else m_uiTendrils_end_Timer -= uiDiff; + + // die after casting supercharge + if (m_uiDie_delay < uiDiff && m_bMustDie) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDie_delay -= uiDiff; + + if (m_uiEnrage_Timer < uiDiff && !m_bIsEnrage) + { + DoScriptText(SAY_BRUNDIR_BERSERK, m_creature); + m_creature->CastStop(); + DoCast(m_creature, SPELL_BERSERK); + m_bIsEnrage = true; + }else m_uiEnrage_Timer -= uiDiff; + + // check if the others are dead + if (m_uiCheckTimer < uiDiff && !m_bHasSupercharge2) + { + if (!m_bIsSteelbreakerDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (!pTemp->isAlive()) + { + m_bIsSteelbreakerDead = true; + if (!m_bHasSupercharge1) + { + m_bHasSupercharge1 = true; + m_uiWhirl_Timer = 10000; + } + else + { + m_bHasSupercharge2 = true; + m_uiTendrils_start_Timer = 40000; + m_uiTendrils_end_Timer = 60000; + m_uiTendrils_Change = 6000; + } + } + } + } + if (!m_bIsMolgeimDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (!pTemp->isAlive()) + { + m_bIsMolgeimDead = true; + if (!m_bHasSupercharge1) + { + m_bHasSupercharge1 = true; + m_uiWhirl_Timer = 10000; + } + else + { + m_bHasSupercharge2 = true; + m_uiTendrils_start_Timer = 40000; + m_uiTendrils_end_Timer = 60000; + m_uiTendrils_Change = 6000; + } + } + } + } + m_uiCheckTimer = 1000; + }else m_uiCheckTimer -= uiDiff; + + if (!m_bIsTendrils && !m_bMustDie) + DoMeleeAttackIfReady(); + } }; -void AddSC_boss_assembly_of_iron() +CreatureAI* GetAI_boss_brundir(Creature* pCreature) { + return new boss_brundirAI(pCreature); +} + +//Runemaster Molgeim +struct MANGOS_DLL_DECL boss_molgeimAI : public ScriptedAI +{ + boss_molgeimAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiShield_Timer; + uint32 m_uiRune_Power_Timer; + uint32 m_uiRune_Death_Timer; + uint32 m_uiRune_Summon_Timer; + uint32 m_uiDie_delay; + uint32 m_uiEnrage_Timer; + uint32 m_uiCheckTimer; + + bool m_bSupercharge1; + bool m_bSupercharge2; + bool m_bMustDie; + bool m_bBrundirDead; + bool m_bSteelbreakerDead; + bool m_bEnrage; + + void Reset() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_uiShield_Timer = 20000; + m_uiRune_Power_Timer = 10000; + m_uiEnrage_Timer = 900000; + m_uiCheckTimer = 1000; + m_bEnrage = false; + m_bBrundirDead = false; + m_bSteelbreakerDead = false; + m_bSupercharge1 = false; + m_bSupercharge2 = false; + m_bMustDie = false; + if (m_creature->HasAura(SPELL_SUPERCHARGE)) + m_creature->RemoveAurasDueToSpell(SPELL_SUPERCHARGE); + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if (uiDamage > m_creature->GetHealth() && !m_bMustDie) + { + uiDamage = 0; + m_creature->RemoveAllAuras(); + m_creature->CastStop(); + DoCast(m_creature, SPELL_SUPERCHARGE); + m_uiDie_delay = 500; + m_bMustDie = true; + } + } + + void OnYourSide() + { + /* hacky way to complete achievements; use only if you have this function + Map* pMap = m_creature->GetMap(); + AchievementEntry const *AchievYourSide = GetAchievementStore()->LookupEntry(m_bIsRegularMode ? ACHIEV_ON_YOUR_SIDE : ACHIEV_ON_YOUR_SIDE_H); + if(AchievYourSide && pMap) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + if (!lPlayers.isEmpty()) + { + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + { + if(pPlayer->HasAura(SPELL_IRON_BOOT_AURA, EFFECT_INDEX_0)) + pPlayer->CompletedAchievement(AchievYourSide); + } + } + } + } + */ + } + + void JustDied(Unit* pKiller) + { + //death yell + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (m_pInstance) + { + // remove supercharge from players -> spell bug + //m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SUPERCHARGE); + // if the others are dead then give loot + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (!pTemp->isAlive()) + { + if (Creature* p2Temp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (!p2Temp->isAlive()) + { + m_pInstance->SetData(TYPE_ASSEMBLY, DONE); + // only the current one has loot, because loot modes are implemented in sql + m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + // I'm on your side + OnYourSide(); + + // ChooseMolgeim + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHOOSE_MOLGEIM : ACHIEV_CHOOSE_MOLGEIM_H); + } + } + } + } + + // else make them full hp + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (pTemp->isAlive()) + pTemp->SetHealth(pTemp->GetMaxHealth()); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (pTemp->isAlive()) + pTemp->SetHealth(pTemp->GetMaxHealth()); + } + } + + if(irand(0,1)) + DoScriptText(SAY_MOLGEIM_DEATH1, m_creature); + else + DoScriptText(SAY_MOLGEIM_DEATH2, m_creature); + } + + void Aggro(Unit* pWho) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + if (m_pInstance) + { + if(m_pInstance->GetData(TYPE_ASSEMBLY) != IN_PROGRESS) + m_pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS); + } + + DoScriptText(SAY_MOLGEIM_AGGRO, m_creature); + } + + void JustReachedHome() + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + if (m_pInstance) + { + if(m_pInstance->GetData(TYPE_ASSEMBLY) != FAIL) + m_pInstance->SetData(TYPE_ASSEMBLY, FAIL); + } + } + + void KilledUnit(Unit *who) + { + if(irand(0,1)) + DoScriptText(SAY_MOLGEIM_SLAY1, m_creature); + else + DoScriptText(SAY_MOLGEIM_SLAY2, m_creature); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // level 1 spells + if (m_uiShield_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHIELD : SPELL_SHIELD_H); + m_uiShield_Timer = 50000; + }else m_uiShield_Timer -= uiDiff; + + if (m_uiRune_Power_Timer < uiDiff) + { + switch(urand(0, 2)) + { + case 0: + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (pTemp->isAlive()) + DoCast(pTemp, SPELL_RUNE_OF_POWER); + else + DoCast(m_creature, SPELL_RUNE_OF_POWER); + } + break; + case 1: + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (pTemp->isAlive()) + DoCast(pTemp, SPELL_RUNE_OF_POWER); + else + DoCast(m_creature, SPELL_RUNE_OF_POWER); + } + break; + case 2: + DoCast(m_creature, SPELL_RUNE_OF_POWER); + break; + } + m_uiRune_Power_Timer = 30000; + }else m_uiRune_Power_Timer -= uiDiff; + + // level2 spells + if (m_uiRune_Death_Timer < uiDiff && m_bSupercharge1) + { + DoScriptText(SAY_MOLGEIM_DEATH_RUNE, m_creature); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_RUNE_OF_DEATH : SPELL_RUNE_OF_DEATH_H); + m_uiRune_Death_Timer = 30000; + }else m_uiRune_Death_Timer -= uiDiff; + + // level 3 spells + if (m_uiRune_Summon_Timer < uiDiff && m_bSupercharge2) + { + DoScriptText(SAY_MOLGEIM_SUMMON, m_creature); + m_creature->CastStop(); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_RUNE_OF_SUMMONING); + m_uiRune_Summon_Timer = 30000; + }else m_uiRune_Summon_Timer -= uiDiff; + + // die after overloading + if (m_uiDie_delay < uiDiff && m_bMustDie) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDie_delay -= uiDiff; + + if (m_uiEnrage_Timer < uiDiff && !m_bEnrage) + { + DoScriptText(SAY_MOLGEIM_BERSERK, m_creature); + m_creature->CastStop(); + DoCast(m_creature, SPELL_BERSERK); + m_bEnrage = true; + }else m_uiEnrage_Timer -= uiDiff; + + if (m_uiCheckTimer < uiDiff) + { + if (!m_bSteelbreakerDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER))) + { + if (!pTemp->isAlive()) + { + m_bSteelbreakerDead = true; + if (!m_bSupercharge1) + { + m_bSupercharge1 = true; + m_uiRune_Death_Timer = 10000; + } + else + { + m_bSupercharge2 = true; + m_uiRune_Summon_Timer = 20000; + } + } + } + } + if (!m_bBrundirDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (!pTemp->isAlive()) + { + m_bBrundirDead = true; + if (!m_bSupercharge1) + { + m_bSupercharge1 = true; + m_uiRune_Death_Timer = 10000; + } + else + { + m_bSupercharge2 = true; + m_uiRune_Summon_Timer = 20000; + } + } + } + } + m_uiCheckTimer = 1000; + }else m_uiCheckTimer -= uiDiff; + + if (!m_bMustDie) + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_molgeim(Creature* pCreature) +{ + return new boss_molgeimAI(pCreature); +} + +//Steelbreaker +struct MANGOS_DLL_DECL boss_steelbreakerAI : public ScriptedAI +{ + boss_steelbreakerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiFusion_Punch_Timer; + uint32 m_uiStatic_Disruption_Timer; + uint32 m_uiPower_Timer; + uint32 m_uiDie_delay; + uint32 m_uiEnrage_Timer; + uint32 m_uiCheckTimer; + + bool m_bBrundirDead; + bool m_bMolgeimDead; + bool m_bSupercharge1; + bool m_bSupercharge2; + bool m_bMustDie; + bool m_bEnrage; + + void Reset() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_uiFusion_Punch_Timer = 20000; + m_uiEnrage_Timer = 900000; + m_uiCheckTimer = 1000; + m_bEnrage = false; + m_bBrundirDead = false; + m_bMolgeimDead = false; + m_bSupercharge1 = false; + m_bSupercharge2 = false; + m_bMustDie = false; + if (m_creature->HasAura(SPELL_SUPERCHARGE)) + m_creature->RemoveAurasDueToSpell(SPELL_SUPERCHARGE); + if (m_creature->HasAura(SPELL_ELECTRICAL_CHARGE)) + m_creature->RemoveAurasDueToSpell(SPELL_ELECTRICAL_CHARGE); + if (m_creature->HasAura(SPELL_HIGH_VOLTAGE)) + m_creature->RemoveAurasDueToSpell(SPELL_HIGH_VOLTAGE); + if (m_creature->HasAura(SPELL_HIGH_VOLTAGE_H)) + m_creature->RemoveAurasDueToSpell(SPELL_HIGH_VOLTAGE_H); + } + + void KilledUnit(Unit* pVictim) + { + if (m_bSupercharge2) + DoCast(m_creature, SPELL_ELECTRICAL_CHARGE); + + if(irand(0,1)) + DoScriptText(SAY_STEEL_SLAY1, m_creature); + else + DoScriptText(SAY_STEEL_SLAY2, m_creature); + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if (uiDamage > m_creature->GetHealth() && !m_bMustDie) + { + uiDamage = 0; + m_creature->CastStop(); + m_creature->RemoveAllAuras(); + DoCast(m_creature, SPELL_SUPERCHARGE); + m_uiDie_delay = 500; + m_bMustDie = true; + } + } + + void OnYourSide() + { + /* hacky way to complete achievements; use only if you have this function + Map* pMap = m_creature->GetMap(); + AchievementEntry const *AchievYourSide = GetAchievementStore()->LookupEntry(m_bIsRegularMode ? ACHIEV_ON_YOUR_SIDE : ACHIEV_ON_YOUR_SIDE_H); + if(AchievYourSide && pMap) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + if (!lPlayers.isEmpty()) + { + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + { + if(pPlayer->HasAura(SPELL_IRON_BOOT_AURA, EFFECT_INDEX_0)) + pPlayer->CompletedAchievement(AchievYourSide); + } + } + } + } + */ + } + + void JustDied(Unit* pKiller) + { + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if (m_pInstance) + { + // remove supercharge from players -> spell bug + // m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SUPERCHARGE); + // if the others are dead then give loot + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (!pTemp->isAlive()) + { + if (Creature* p2Temp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (!p2Temp->isAlive()) + { + m_pInstance->SetData(TYPE_ASSEMBLY, DONE); + m_pInstance->SetData(TYPE_ASSEMBLY_HARD, DONE); + // only the current one has loot, because loot modes are implemented in sql + m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + // I'm on your side + OnYourSide(); + + // ChooseSteelbreaker + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHOOSE_STEELBREAKER : ACHIEV_CHOOSE_STEELBREAKER_H); + } + } + } + } + + // else make them full hp + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (pTemp->isAlive()) + pTemp->SetHealth(pTemp->GetMaxHealth()); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (pTemp->isAlive()) + pTemp->SetHealth(pTemp->GetMaxHealth()); + } + } + + if(irand(0,1)) + DoScriptText(SAY_STEEL_DEATH1, m_creature); + else + DoScriptText(SAY_STEEL_DEATH2, m_creature); + } + + void Aggro(Unit* pWho) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + DoCast(m_creature, m_bIsRegularMode ? SPELL_HIGH_VOLTAGE : SPELL_HIGH_VOLTAGE_H); + if (m_pInstance) + { + if(m_pInstance->GetData(TYPE_ASSEMBLY) != IN_PROGRESS) + m_pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS); + } + + DoScriptText(SAY_STEEL_AGGRO, m_creature); + } + + void JustReachedHome() + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + if (m_pInstance) + { + if(m_pInstance->GetData(TYPE_ASSEMBLY) != FAIL) + m_pInstance->SetData(TYPE_ASSEMBLY, FAIL); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // level 1 spells + if (m_uiFusion_Punch_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FUSION_PUNCH : SPELL_FUSION_PUNCH_H); + m_uiFusion_Punch_Timer = 20000; + }else m_uiFusion_Punch_Timer -= uiDiff; + + // level 2 spells + if (m_uiStatic_Disruption_Timer < uiDiff && m_bSupercharge1) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_STATIC_DISRUPTION : SPELL_STATIC_DISRUPTION_H); + m_uiStatic_Disruption_Timer = 60000; + }else m_uiStatic_Disruption_Timer -= uiDiff; + + // level 3 spells + if (m_uiPower_Timer < uiDiff && m_bSupercharge2) + { + m_creature->CastStop(); + DoScriptText(SAY_STEEL_OVERWHELMING, m_creature); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_POWER : SPELL_POWER_H); + m_uiPower_Timer = m_bIsRegularMode ? 65000 : 35000; + }else m_uiPower_Timer -= uiDiff; + + if (m_uiDie_delay < uiDiff && m_bMustDie) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDie_delay -= uiDiff; + + if (m_uiEnrage_Timer < uiDiff && !m_bEnrage) + { + DoScriptText(SAY_STEEL_BERSERK, m_creature); + m_creature->CastStop(); + DoCast(m_creature, SPELL_BERSERK); + m_bEnrage = true; + }else m_uiEnrage_Timer -= uiDiff; + + if (m_uiCheckTimer < uiDiff) + { + if (!m_bBrundirDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR))) + { + if (!pTemp->isAlive()) + { + m_bBrundirDead = true; + if (!m_bSupercharge1) + { + m_bSupercharge1 = true; + m_uiStatic_Disruption_Timer = 12000; + } + else + { + m_bSupercharge2 = true; + m_uiPower_Timer = 5000; + } + } + } + } + if (!m_bMolgeimDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM))) + { + if (!pTemp->isAlive()) + { + m_bMolgeimDead = true; + if (!m_bSupercharge1) + { + m_bSupercharge1 = true; + m_uiStatic_Disruption_Timer = 22000; + } + else + { + m_bSupercharge2 = true; + m_uiPower_Timer = 5000; + } + } + } + } + m_uiCheckTimer = 1000; + }else m_uiCheckTimer -= uiDiff; + + if (!m_bMustDie) + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_steelbreaker(Creature* pCreature) +{ + return new boss_steelbreakerAI(pCreature); +} + +void AddSC_boss_iron_council() +{ + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "boss_brundir"; + NewScript->GetAI = GetAI_boss_brundir; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "boss_molgeim"; + NewScript->GetAI = GetAI_boss_molgeim; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "boss_steelbreaker"; + NewScript->GetAI = GetAI_boss_steelbreaker; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_rune_of_power"; + NewScript->GetAI = &GetAI_mob_rune_of_power; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_rune_of_summoning"; + NewScript->GetAI = &GetAI_mob_rune_of_summoning; + NewScript->RegisterSelf(); + NewScript = new Script; + NewScript->Name = "mob_ulduar_lightning_elemental"; + NewScript->GetAI = &GetAI_mob_ulduar_lightning_elemental; + NewScript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_algalon.cpp b/scripts/northrend/ulduar/ulduar/boss_algalon.cpp index fa2c76e81..b8b59c6ee 100644 --- a/scripts/northrend/ulduar/ulduar/boss_algalon.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_algalon.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_algalon -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: cosmic smash, phase punch, black hole phasing need some core support SDCategory: Ulduar EndScriptData */ @@ -26,33 +26,896 @@ EndScriptData */ enum { - SAY_INTRO_1 = -1603106, - SAY_INTRO_2 = -1603107, - SAY_INTRO_3 = -1603108, + SAY_INTRO1 = -1603270, + SAY_INTRO2 = -1603271, + SAY_INTRO3 = -1603272, + SAY_ENGAGE = -1603141, + SAY_AGGRO = -1603140, + SAY_SLAY1 = -1603145, + SAY_SLAY2 = -1603146, + SAY_SUMMON_STAR = -1603148, + SAY_BIGBANG1 = -1603142, + SAY_BIGBANG2 = -1603143, + SAY_PHASE2 = -1603144, + SAY_BERSERK = -1603147, + SAY_DESPAWN1 = -1603273, + SAY_DESPAWN2 = -1603274, + SAY_DESPAWN3 = -1603275, + SAY_OUTRO1 = -1603276, + SAY_OUTRO2 = -1603277, + SAY_OUTRO3 = -1603278, + SAY_OUTRO4 = -1603149, + SAY_OUTRO5 = -1603279, - SAY_ENGAGE = -1603109, - SAY_AGGRO = -1603110, - SAY_SLAY_1 = -1603111, - SAY_SLAY_2 = -1603112, - SAY_SUMMON_STAR = -1603113, - SAY_BIG_BANG_1 = -1603114, - SAY_BIG_BANG_2 = -1603115, - SAY_PHASE_2 = -1603116, - SAY_BERSERK = -1603117, + ITEM_PLANETARIUM_KEY = 45796, + ITEM_PLANETARIUM_KEY_H = 45798, - SAY_DESPAWN_1 = -1603118, - SAY_DESPAWN_2 = -1603119, - SAY_DESPAWN_3 = -1603120, + SPELL_ALGALON_EVENT_BEAM = 64367, + SPELL_ALGALON_EVENT_CLIMAX = 64580, // This spells are used for environment - SAY_OUTRO_1 = -1603121, - SAY_OUTRO_2 = -1603122, - SAY_OUTRO_3 = -1603123, - SAY_OUTRO_4 = -1603124, - SAY_OUTRO_5 = -1603125, + //spells to be casted + SPELL_QUANTUM_STRIKE = 64395, //Normal Quantum Strike + SPELL_QUANTUM_STRIKE_H = 64592, //Heroic Quantum Strike + SPELL_PHASE_PUNCH = 64412, //Phase punch + SPELL_PHASE_PUNCH_SHIFT = 64417, + SPELL_CONSTELLATION_TRIGGER = 65508, // this should make the space effect + SPELL_COSMIC_SMASH = 62301, //Normal Cosmic Smash + SPELL_COSMIC_SMASH_H = 64598, //Heroic Cosmic Smash + SPELL_COSMIC_SMASH_MISSILE = 62304, + SPELL_BIG_BANG = 64443, //Normal Big Bang + SPELL_BIG_BANG_H = 64584, //Heroic Big Bang + SPELL_ASCEND = 64487, //Ascend to the Heavens + SPELL_BERSERK = 47008, //Berserk + NPC_SMASH_TARGET_DUMMY = 33105, + // mobs + NPC_COLLAPSING_STAR = 32955, // they lose 1%hp per sec & cast black hole explosion when they die -> leave a black hole + SPELL_BLACK_HOLE_EXPLOSION = 64122, + SPELL_BLACK_HOLE_EXPLOSION_H = 65108, + SPELL_BLACK_HOLE_DESPAWN = 64391, // dummy spell + SPELL_SUMMON_BLACK_HOLE = 62189, + SPELL_BLACK_HOLE_VISUAL = 64135, + SPELL_BLACK_HOLE_SPAWN = 62003, + SPELL_BLACK_HOLE_TRIGG = 62185, // shifts the phase + SPELL_BLACK_HOLE_SHIFT = 62168, + SPELL_BLACK_HOLE_DMG = 62169, + + NPC_BLACK_HOLE = 32953, // players must stay inside to avoid big bang + + NPC_LIVING_CONSTELLATION = 33052, // if one enters a black hole they are despawned + SPELL_ARCANE_BARRAGE = 64599, //Arcane Barage + SPELL_ARCANE_BARRAGE_H = 64607, //Heroic Arcane Barage? + + NPC_DARK_MATTER = 33089, // populates the black holes + NPC_UNLEASHED_DARK_MATTER = 34097, // summoned by black holes in phase 2 + NPC_COSMIC_SMASH = 33104, + + ACHIEV_FEED_TEARS = 3004, + ACHIEV_FEED_TEARS_H = 3005, // nobody dies in the raid lockout + ACHIEV_HERALD_OF_TITANS = 3316, + ACHIEV_OBSERVED = 3036, + ACHIEV_OBSERVED_H = 3037, + ACHIEV_SUPERMASSIVE = 3003, + ACHIEV_SUPERMASSIVE_H = 3002, + + UI_STATE_ALGALON_TIMER_ON = 4132, + UI_STATE_ALGALON_TIMER_COUNT = 4131, +}; + +//Positional defines +struct LocationsXY +{ + float x, y; + uint32 id; +}; + +static LocationsXY PositionLoc[]= +{ + {1620, -320.75f}, + {1620, -290.75f }, + {1645.5f, -290.75f }, + {1645.5f, -320.75f }, +}; + +//Black hole +struct MANGOS_DLL_DECL mob_black_holeAI : public ScriptedAI +{ + mob_black_holeAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool m_bHasAura; + uint32 m_uiRaidCheckTimer; + bool m_bIsPhase2; + uint32 m_uiSummonTimer; + + void Reset() + { + m_bHasAura = false; + m_uiRaidCheckTimer = 1000; + m_bIsPhase2 = false; + m_uiSummonTimer = 5000; + DoCast(m_creature, SPELL_BLACK_HOLE_SPAWN); + m_creature->SetRespawnDelay(DAY); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // summon unleashed dark matter in phase 2 + if (m_uiSummonTimer < uiDiff && m_bIsPhase2) + { + if(Creature* pTemp = m_creature->SummonCreature(NPC_UNLEASHED_DARK_MATTER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + pTemp->SetInCombatWithZone(); + m_uiSummonTimer = urand(10000, 15000); + } + else m_uiSummonTimer -= uiDiff; + + // phase players into the void + if (m_uiRaidCheckTimer < uiDiff && !m_bIsPhase2) + { + if(!m_bHasAura) + { + DoCast(m_creature, SPELL_BLACK_HOLE_TRIGG); + m_bHasAura = true; + } + + if(Creature *pConstellation = GetClosestCreatureWithEntry(m_creature, NPC_LIVING_CONSTELLATION, 2)) + { + pConstellation->DealDamage(pConstellation, pConstellation->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + m_uiRaidCheckTimer = 500; + } + else m_uiRaidCheckTimer -= uiDiff; + } }; +//Algalon +struct MANGOS_DLL_DECL boss_algalonAI : public ScriptedAI +{ + boss_algalonAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bHasStarted = false; // flag used to check if the encounter has been started from the console + m_bIsInProgress = false; // flag used for time counter + m_bIsFirstTime = true; // flag used to show if this is the first aggro + m_uiDespawnTimer = 3600000; // 1h; + m_uiLastTimer = 3600000; // 1h; + m_bFeedOnTears = true; // flag used to check the Fead on Tears achiev + pCreature->SetVisibility(VISIBILITY_OFF); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiBerserk_Timer; + uint32 m_uiBigBang_Timer; + uint32 m_uiCosmicSmash_Timer; + uint32 m_uiPhasePunch_Timer; + uint32 m_uiQuantumStrike_Timer; + uint32 m_uiCollapsingStar_Timer; + uint32 m_uiLivingConstellationTimer; + uint32 m_uiRaidCheckTimer; + uint32 m_uiDarkMaterTimer; + uint32 m_uiDespawnTimer; + uint32 m_uiLastTimer; + + // intro & outro + bool m_bIsOutro; + uint32 m_uiOutroTimer; + uint32 m_uiOutroStep; + bool m_bIsIntro; + uint32 m_uiIntroTimer; + uint32 m_uiIntroStep; + + bool m_bHasStarted; + bool m_bIsFirstTime; + bool m_bIsInProgress; + + uint8 m_uiCombatPhase; + bool m_bIsPhase2; + + bool m_bIsDespawned; + bool m_bFeedOnTears; + + void Reset() + { + m_uiQuantumStrike_Timer = 4000 + rand()%10000; + m_uiBerserk_Timer = 360000; //6 minutes + m_uiCollapsingStar_Timer = urand(15000, 20000); //Spawns between 15 to 20 seconds + m_uiLivingConstellationTimer = 60000; + m_uiBigBang_Timer = 90000; + m_uiDarkMaterTimer = 90000; + m_uiPhasePunch_Timer = 8000; + m_uiCosmicSmash_Timer = urand(30000, 60000); + m_uiRaidCheckTimer = 1000; + + m_uiCombatPhase = 0; // it's 0 for idle, 1 for intro and 2 for combat + m_bIsPhase2 = false; // flag used below 30% hp + + m_uiOutroTimer = 10000; + m_uiOutroStep = 1; + m_bIsIntro = true; + m_uiIntroTimer = 10000; + m_uiIntroStep = 1; + m_bIsOutro = false; + + m_bIsDespawned = false; // flaged used to show that time has run out + } + + void KilledUnit(Unit *victim) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_SLAY2, m_creature); break; + } + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_ALGALON, NOT_STARTED); + m_bIsFirstTime = false; + } + + void DoOutro() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_ALGALON, DONE); + m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_ON, 0); + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_OBSERVED : ACHIEV_OBSERVED_H); + + if(m_bFeedOnTears) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_FEED_TEARS : ACHIEV_FEED_TEARS_H); + } + + m_creature->ForcedDespawn(); + } + + void AttackStart(Unit* pWho) + { + if(!m_bIsInProgress) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!pWho) + return; + + if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(pWho) && + pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40) && m_uiCombatPhase == 0 && m_bHasStarted && m_bIsFirstTime) + m_uiCombatPhase = 1; + } + + void StartEncounter() + { + m_creature->SetVisibility(VISIBILITY_ON); + m_bIsFirstTime = true; + m_bHasStarted = true; + m_bIsInProgress = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(m_creature->GetHealthPercent() < 1.0f) + { + uiDamage = 0; + m_bIsOutro = true; + } + } + + void SummonCreature(uint32 m_uiCreatureEntry) + { + float angle = (float) rand()*360/RAND_MAX + 1; + float homeX = 1630.475f + urand(15, 30)*cos(angle*(M_PI/180)); + float homeY = -286.989f + urand(15, 30)*sin(angle*(M_PI/180)); + if(Creature* pTemp = m_creature->SummonCreature(m_uiCreatureEntry, homeX, homeY, 417.32f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->SetInCombatWithZone(); + if(pTemp->GetEntry() == NPC_DARK_MATTER) + pTemp->CastSpell(pTemp, SPELL_BLACK_HOLE_SHIFT, false); + } + } + + void Aggro(Unit* pWho) + { + // set combat phase + m_uiCombatPhase = 2; + + if(m_bIsFirstTime) + { + m_bIsInProgress = true; + DoScriptText(SAY_ENGAGE, m_creature); + if(m_pInstance) + { + m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_ON, 1); + m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_COUNT, m_uiDespawnTimer / 60000); + } + } + else + DoScriptText(SAY_AGGRO, m_creature); + + m_creature->SetInCombatWithZone(); + DoCast(m_creature, SPELL_CONSTELLATION_TRIGGER); + + if (m_pInstance) + m_pInstance->SetData(TYPE_ALGALON, IN_PROGRESS); + } + + void UpdateAI(const uint32 uiDiff) + { + // despawn timer + if(m_uiDespawnTimer < uiDiff && !m_bIsDespawned && m_bIsInProgress) + { + m_bIsDespawned = true; + m_bIsOutro = true; + m_bIsInProgress = false; + } + else m_uiDespawnTimer -= uiDiff; + + // update world state + if(m_uiDespawnTimer < m_uiLastTimer - 60000 && !m_bIsDespawned) + { + m_uiLastTimer = m_uiDespawnTimer; + uint32 tMinutes = m_uiDespawnTimer / 60000; + if(m_pInstance) + m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_COUNT, tMinutes); + } + + if(!m_bIsOutro) + { + // intro + if(m_uiCombatPhase == 1) + { + if(m_bIsIntro && m_bIsFirstTime) + { + switch(m_uiIntroStep) + { + case 1: + DoScriptText(SAY_INTRO1, m_creature); + ++m_uiIntroStep; + m_uiIntroTimer = 8000; + break; + case 3: + DoScriptText(SAY_INTRO2, m_creature); + ++m_uiIntroStep; + m_uiIntroTimer = 6000; + break; + case 5: + DoScriptText(SAY_INTRO3, m_creature); + ++m_uiIntroStep; + m_uiIntroTimer = 10000; + break; + case 7: + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bIsIntro = false; + ++m_uiIntroStep; + m_uiIntroTimer = 10000; + break; + } + } + else return; + + if (m_uiIntroTimer <= uiDiff) + { + ++m_uiIntroStep; + m_uiIntroTimer = 330000; + } m_uiIntroTimer -= uiDiff; + } + + // combat + if(m_uiCombatPhase == 2) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // spells + if(m_uiQuantumStrike_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_QUANTUM_STRIKE : SPELL_QUANTUM_STRIKE_H); + m_uiQuantumStrike_Timer = 4000 + rand()%10000; + }else m_uiQuantumStrike_Timer -= uiDiff; + + if(m_uiBigBang_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_BIG_BANG : SPELL_BIG_BANG_H); + m_uiBigBang_Timer = 90000; + m_uiDarkMaterTimer = 1000; + }else m_uiBigBang_Timer -= uiDiff; + + if(m_uiCosmicSmash_Timer < uiDiff) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_COSMIC_SMASH : SPELL_COSMIC_SMASH_H); + m_uiCosmicSmash_Timer = urand(30000, 60000); + }else m_uiCosmicSmash_Timer -= uiDiff; + + if(m_uiPhasePunch_Timer < uiDiff) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget,SPELL_PHASE_PUNCH); + m_uiPhasePunch_Timer = 15000; + }else m_uiPhasePunch_Timer -= uiDiff; + + // hack, phase punch needs core support + // PLEASE REMOVE FOR REVISION! + if(m_uiRaidCheckTimer < uiDiff) + { + Map *map = m_creature->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_PHASE_PUNCH, EFFECT_INDEX_0)) + { + Aura *phasePunch = i->getSource()->GetAura(SPELL_PHASE_PUNCH, EFFECT_INDEX_0); + if(phasePunch->GetStackAmount() > 4) + { + i->getSource()->RemoveAurasDueToSpell(SPELL_PHASE_PUNCH); + i->getSource()->CastSpell(i->getSource(), SPELL_PHASE_PUNCH_SHIFT, false); + } + } + if (!i->getSource()->isAlive()) + m_bFeedOnTears = false; + } + } + m_uiRaidCheckTimer = 1000; + }else m_uiRaidCheckTimer -= uiDiff; + + // berserk + if(m_uiBerserk_Timer < uiDiff) + { + DoScriptText(SAY_BERSERK, m_creature); + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserk_Timer = 360000; + }else m_uiBerserk_Timer -= uiDiff; + + // summons + if(m_uiCollapsingStar_Timer < uiDiff && !m_bIsPhase2) + { + DoScriptText(SAY_SUMMON_STAR, m_creature); + SummonCreature(NPC_COLLAPSING_STAR); + m_uiCollapsingStar_Timer = urand(15000, 20000); + }else m_uiCollapsingStar_Timer -= uiDiff; + + if(m_uiLivingConstellationTimer < uiDiff && !m_bIsPhase2) + { + for(uint8 i = 0; i < urand (1, 3); i++) + SummonCreature(NPC_LIVING_CONSTELLATION); + m_uiLivingConstellationTimer = 30000; + }else m_uiLivingConstellationTimer -= uiDiff; + + if(m_uiDarkMaterTimer < uiDiff && !m_bIsPhase2) + { + for(uint8 i = 0; i < 7; i++) + SummonCreature(NPC_DARK_MATTER); + m_uiDarkMaterTimer = 90000; + }else m_uiDarkMaterTimer -= uiDiff; + + // hp check -> start phase 2 + if(!m_bIsPhase2 && m_creature->GetHealthPercent() < 20) + { + DoScriptText(SAY_PHASE2, m_creature); + m_bIsPhase2 = true; + + std::list lAdds; + GetCreatureListWithEntryInGrid(lAdds, m_creature, NPC_COLLAPSING_STAR, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lAdds, m_creature, NPC_BLACK_HOLE, DEFAULT_VISIBILITY_INSTANCE); + + if (!lAdds.empty()) + { + for(std::list::iterator iter = lAdds.begin(); iter != lAdds.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->ForcedDespawn(); + } + } + + for (uint8 i = 0; i < 4; ++i) + { + if(Creature* pTemp = m_creature->SummonCreature(NPC_BLACK_HOLE, PositionLoc[i].x, PositionLoc[i].y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 0)) + ((mob_black_holeAI*)pTemp->AI())->m_bIsPhase2 = true; + } + } + + DoMeleeAttackIfReady(); + + EnterEvadeIfOutOfCombatArea(uiDiff); + } + } + // outro: both for defeat and despawn + if(m_bIsOutro) + { + switch(m_uiOutroStep) + { + case 1: + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->InterruptNonMeleeSpells(false); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->GetMotionMaster()->MovePoint(0, 1631.970f, -302.635f, 417.321f); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + ++m_uiOutroStep; + m_uiOutroTimer = 5000; + break; + case 3: + // make boss kneel + m_creature->SetSplineFlags(SPLINEFLAG_UNKNOWN12); + if(m_bIsDespawned) + { + DoScriptText(SAY_DESPAWN1, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 15000; + } + else + { + DoScriptText(SAY_OUTRO1, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 37000; + } + break; + case 5: + if(m_bIsDespawned) + { + DoScriptText(SAY_DESPAWN2, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 8000; + } + else + { + DoScriptText(SAY_OUTRO2, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 17000; + } + break; + case 7: + if(m_bIsDespawned) + { + DoScriptText(SAY_DESPAWN3, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 7000; + } + else + { + DoScriptText(SAY_OUTRO3, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 12000; + } + break; + case 9: + if(m_bIsDespawned) + { + DoCast(m_creature, SPELL_ASCEND); + ++m_uiOutroStep; + m_uiOutroTimer = 5000; + } + else + { + DoScriptText(SAY_OUTRO4, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 11000; + } + break; + case 11: + if(m_bIsDespawned) + { + if(m_pInstance) + { + m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_ON, 0); + m_pInstance->SetData(TYPE_ALGALON, FAIL); + } + m_creature->ForcedDespawn(); + } + else + { + DoScriptText(SAY_OUTRO5, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 13000; + } + break; + case 13: + DoOutro(); + ++m_uiOutroStep; + m_uiOutroTimer = 10000; + break; + } + } + else + return; + + if (m_uiOutroTimer <= uiDiff) + { + ++m_uiOutroStep; + m_uiOutroTimer = 330000; + } m_uiOutroTimer -= uiDiff; + } +}; + +//Collapsing Star +struct MANGOS_DLL_DECL mob_collapsing_starAI : public ScriptedAI +{ + mob_collapsing_starAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiHealthTimer; + uint32 m_uiDieTimer; + uint32 m_uiSummonTimer; + + void Reset() + { + m_uiHealthTimer = 1000; + m_uiDieTimer = 600000; + m_uiSummonTimer = 600000; + m_creature->SetRespawnDelay(DAY); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if(uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_uiDieTimer = 1500; + m_uiSummonTimer = 1000; + DoCast(m_creature, m_bIsRegularMode ? SPELL_BLACK_HOLE_EXPLOSION : SPELL_BLACK_HOLE_EXPLOSION_H); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSummonTimer < uiDiff) + { + DoCast(m_creature, SPELL_SUMMON_BLACK_HOLE); + m_uiSummonTimer = 60000; + } + else m_uiSummonTimer -= uiDiff; + + if (m_uiDieTimer < uiDiff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else + m_uiDieTimer -= uiDiff; + + // movement should be improved + // npc should ignore threat tables + if(m_uiHealthTimer < uiDiff && m_creature->GetHealthPercent() > 1.0f) + { + m_creature->GetMotionMaster()->MoveConfused(); + m_creature->DealDamage(m_creature, (m_creature->GetMaxHealth() * 0.01), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_uiHealthTimer = 1000; + }else m_uiHealthTimer -= uiDiff; + } +}; + +//Living constellation +struct MANGOS_DLL_DECL mob_living_constellationAI : public ScriptedAI +{ + mob_living_constellationAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiArcaneBarrageTimer; + + void Reset() + { + m_uiArcaneBarrageTimer = 15000; + m_creature->SetRespawnDelay(DAY); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiArcaneBarrageTimer < uiDiff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)){ + DoCast(target, m_bIsRegularMode ? SPELL_ARCANE_BARRAGE : SPELL_ARCANE_BARRAGE_H); + } + m_uiArcaneBarrageTimer = 15000; + }else m_uiArcaneBarrageTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL mob_cosmic_smash_targetAI : public ScriptedAI +{ + mob_cosmic_smash_targetAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pCreature->SetDisplayId(11686); // make invisible + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiSpellTimer; + + void Reset() + { + m_uiSpellTimer = 5000; + m_creature->SetRespawnDelay(DAY); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpellTimer < uiDiff) + { + DoCast(m_creature, SPELL_COSMIC_SMASH_MISSILE); + m_uiSpellTimer = 60000; + }else m_uiSpellTimer -= uiDiff; + } +}; + + +bool GOHello_go_celestial_acces(Player* pPlayer, GameObject* pGo) +{ + ScriptedInstance* m_pInstance = (ScriptedInstance*)pGo->GetInstanceData(); + bool m_bIsRegularMode = pGo->GetMap()->IsRegularDifficulty(); + bool m_bHasItem = false; + + // check if the player has the key + if (m_bIsRegularMode) + { + if(pPlayer->HasItemCount(ITEM_PLANETARIUM_KEY, 1) || pPlayer->HasItemCount(ITEM_PLANETARIUM_KEY_H, 1)) + m_bHasItem = true; + } + else + { + if(pPlayer->HasItemCount(ITEM_PLANETARIUM_KEY_H, 1)) + m_bHasItem = true; + } + + if(!m_bHasItem) + return false; + + if (!m_pInstance) + return false; + + // disable if encounter is already done + if (m_pInstance->GetData(TYPE_ALGALON) == DONE) + { + pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + return false; + } + + // start encounter + if (Creature* pAlgalon = pGo->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ALGALON))) + { + if(pAlgalon->isAlive()) + { + ((boss_algalonAI*)pAlgalon->AI())->StartEncounter(); + pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + + // open celestial door + if(GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CELESTIAL_DOOR))) + m_pInstance->DoUseDoorOrButton(pDoor->GetGUID()); + } + } + + return false; +} + +CreatureAI* GetAI_boss_algalon(Creature* pCreature) +{ + return new boss_algalonAI(pCreature); +} + +CreatureAI* GetAI_mob_collapsing_star(Creature* pCreature) +{ + return new mob_collapsing_starAI(pCreature); +} + +CreatureAI* GetAI_mob_living_constellation(Creature* pCreature) +{ + return new mob_living_constellationAI(pCreature); +} + +CreatureAI* GetAI_mob_cosmic_smash_target(Creature* pCreature) +{ + return new mob_cosmic_smash_targetAI(pCreature); +} + +CreatureAI* GetAI_mob_black_hole(Creature* pCreature) +{ + return new mob_black_holeAI(pCreature); +} + void AddSC_boss_algalon() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_algalon"; + newscript->GetAI = &GetAI_boss_algalon; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_collapsing_star"; + newscript->GetAI = &GetAI_mob_collapsing_star; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_living_constellation"; + newscript->GetAI = &GetAI_mob_living_constellation; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_cosmic_smash_target"; + newscript->GetAI = &GetAI_mob_cosmic_smash_target; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_black_hole"; + newscript->GetAI = &GetAI_mob_black_hole; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "go_celestial_acces"; + newscript->pGOUse = &GOHello_go_celestial_acces; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp b/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp index b1038e19a..35e5ef8d3 100644 --- a/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_auriaya -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: need correct setstack for feral defender buff SDCategory: Ulduar EndScriptData */ @@ -26,16 +26,539 @@ EndScriptData */ enum { - SAY_AGGRO = -1603079, - SAY_SLAY_1 = -1603080, - SAY_SLAY_2 = -1603081, - SAY_BERSERK = -1603082, - SAY_DEATH = -1603083, - EMOTE_SCREECH = -1603084, - EMOTE_DEFENDER = -1603085, + //yells + SAY_AGGRO = -1603070, + SAY_SLAY1 = -1603071, + SAY_SLAY2 = -1603072, + SAY_BERSERK = -1603073, + SAY_DEATH = -1603074, + EMOTE_SCREECH = -1603358, + EMOTE_DEFENDER = -1603359, + + //auriaya + SPELL_BERSERK = 47008, + SPELL_GUARDIAN_SWARM = 64396, // broken + SPELL_SENTINEL_BLAST = 64389, + SPELL_SENTINEL_BLAST_H = 64678, + SPELL_SONIC_SCREECH = 64422, + SPELL_SONIC_SCREECH_H = 64688, + SPELL_FEAR = 64386, + + //feral defender + SPELL_FEIGN_DEATH = 57685, + SPELL_FERAL_ESSENCE = 64455, + SPELL_FERAL_POUNCE = 64478, + SPELL_FERAL_POUNCE_H = 64669, + SPELL_FERAL_RUSH = 64496, + SPELL_FERAL_RUSH_H = 64674, + + //sanctum sentry + SPELL_RIP_FLESH = 64375, + SPELL_RIP_FLESH_H = 64667, + SPELL_SAVAGE_POUNCE = 64666, + SPELL_SAVAGE_POUNCE_H = 64374, + SPELL_STRENGHT_OF_PACK = 64369, + //seeping feral essence + AURA_VOID_ZONE = 64458, + AURA_VOID_ZONE_H = 64676, + //NPC ids + MOB_VOID_ZONE = 34098, + MOB_FERAL_DEFENDER = 34035, + MOB_GUARDIAN_SWARN = 34034, + + ACHIEV_CRAZY_CAT_LADY = 3006, + ACHIEV_CRAZY_CAT_LADY_H = 3007, + + ACHIEV_NINE_LIVES = 3076, + ACHIEV_NINE_LIVES_H = 3077, +}; + +bool m_bCrazyCatLady; +bool m_bNineLives; + +// Seeping Feral Essence +struct MANGOS_DLL_DECL mob_seeping_feral_essenceAI : public ScriptedAI +{ + mob_seeping_feral_essenceAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + pCreature->setFaction(14); + pCreature->SetDisplayId(11686); // make invisible + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, m_bIsRegularMode ? AURA_VOID_ZONE : AURA_VOID_ZONE_H); + m_creature->SetRespawnDelay(DAY); + } + + void UpdateAI(const uint32 diff) + { + } +}; + +CreatureAI* GetAI_mob_seeping_feral_essence(Creature* pCreature) +{ + return new mob_seeping_feral_essenceAI(pCreature); +} + +// Sanctum Sentry +struct MANGOS_DLL_DECL mob_sanctum_sentryAI : public ScriptedAI +{ + mob_sanctum_sentryAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiRip_Flesh_Timer; + uint32 m_uiJump_Timer; + + std::list lSentrys; + + void Reset() + { + m_uiRip_Flesh_Timer = 13000; + m_uiJump_Timer = 0; + + lSentrys.clear(); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_AURIAYA))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + } + + GetCreatureListWithEntryInGrid(lSentrys, m_creature, NPC_SANCTUM_SENTRY, DEFAULT_VISIBILITY_INSTANCE); + if (!lSentrys.empty()) + { + for(std::list::iterator iter = lSentrys.begin(); iter != lSentrys.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->SetInCombatWithZone(); + } + } + + DoCast(m_creature, SPELL_STRENGHT_OF_PACK); + } + + void JustDied(Unit* pKiller) + { + m_bCrazyCatLady = false; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + { + // they should follow Auriaya, but this looks ugly! + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_AURIAYA))) + { + if (pTemp->isAlive()) + { + m_creature->GetMotionMaster()->MoveFollow(pTemp,0.0f,0.0f); + m_creature->GetMap()->CreatureRelocation(m_creature, pTemp->GetPositionX(), pTemp->GetPositionY(), pTemp->GetPositionZ(), 0.0f); + } + } + } + + if (m_uiRip_Flesh_Timer < diff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_RIP_FLESH : SPELL_RIP_FLESH_H); + m_uiRip_Flesh_Timer = 13000; + }else m_uiRip_Flesh_Timer -= diff; + + if (m_uiJump_Timer < diff) + { + if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 25)) + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SAVAGE_POUNCE : SPELL_SAVAGE_POUNCE_H); + m_uiJump_Timer = 1000; + }else m_uiJump_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_sanctum_sentry(Creature* pCreature) +{ + return new mob_sanctum_sentryAI(pCreature); +} + +// Feral Defender +struct MANGOS_DLL_DECL mob_feral_defenderAI : public ScriptedAI +{ + mob_feral_defenderAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiPounce_Timer; + uint32 m_uiRush_Start_Timer; + uint32 m_uiRush_Finish_Timer; + uint32 m_uiRush_Delay; + uint32 m_uiRevive_Delay; + + bool m_bIsRush; + bool m_bIsDead; + + bool m_bHasAura; + + void Reset() + { + m_uiPounce_Timer = 5000; + m_uiRush_Start_Timer = 9000; + m_bIsRush = false; + m_bIsDead = false; + m_bHasAura = false; + m_creature->SetRespawnDelay(DAY); + } + + void Aggro(Unit* pWho) + { + DoCast(m_creature, SPELL_FERAL_ESSENCE); + } + + void JustDied(Unit* pKiller) + { + m_bNineLives = true; + } + + // feign death + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if (uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + m_creature->CastStop(); + m_creature->RemoveArenaAuras(true); + m_creature->SummonCreature(MOB_VOID_ZONE, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_DEAD_DESPAWN, 0); + DoCast(m_creature, SPELL_FEIGN_DEATH); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (m_creature->HasAura(SPELL_FERAL_ESSENCE)) + { + // remove 1 stack of the aura + if(SpellAuraHolder* strenght = m_creature->GetSpellAuraHolder(SPELL_FERAL_ESSENCE)) + { + if(strenght->ModStackAmount(-1)) + m_creature->RemoveAurasDueToSpell(SPELL_FERAL_ESSENCE); + } + + m_uiRevive_Delay = 35000; + m_bIsDead = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_AURIAYA) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // hacky way of stacking aura, needs fixing + if(SpellAuraHolder* essence = m_creature->GetSpellAuraHolder(SPELL_FERAL_ESSENCE)) + { + if(essence->GetStackAmount() < 9 && !m_bHasAura) + { + m_bHasAura = true; + essence->SetStackAmount(9); + } + } + + if (m_uiPounce_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + DoCast(target, m_bIsRegularMode ? SPELL_FERAL_POUNCE : SPELL_FERAL_POUNCE_H); + m_creature->AddThreat(target,0.0f); + m_creature->AI()->AttackStart(target); + } + m_uiPounce_Timer = 5000; + }else m_uiPounce_Timer -= diff; + + if (m_uiRush_Start_Timer < diff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + DoCast(target, m_bIsRegularMode ? SPELL_FERAL_RUSH : SPELL_FERAL_RUSH_H); + m_creature->AddThreat(target,0.0f); + m_creature->AI()->AttackStart(target); + } + m_uiRush_Start_Timer = 35000; + m_uiRush_Finish_Timer = m_bIsRegularMode ? 2500 : 5000; + m_uiRush_Delay = 500; + m_bIsRush = true; + }else m_uiRush_Start_Timer -= diff; + + if (m_uiRush_Delay < diff && m_bIsRush) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + DoCast(target, m_bIsRegularMode ? SPELL_FERAL_RUSH : SPELL_FERAL_RUSH_H); + m_creature->AddThreat(target,0.0f); + m_creature->AI()->AttackStart(target); + } + m_uiRush_Delay = 500; + }else m_uiRush_Delay -= diff; + + if (m_uiRush_Finish_Timer < diff) + m_bIsRush = false; + else m_uiRush_Finish_Timer -= diff; + + if (m_uiRevive_Delay < diff && m_bIsDead) + { + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bIsDead = false; + }else m_uiRevive_Delay -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_feral_defender(Creature* pCreature) +{ + return new mob_feral_defenderAI(pCreature); +} + +// Auriaya +struct MANGOS_DLL_DECL boss_auriayaAI : public ScriptedAI +{ + boss_auriayaAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiEnrage_Timer; + uint32 m_uiSwarm_Timer; + uint32 m_uiSonic_Screech_Timer; + uint32 m_uiSentinel_Blast_Timer; + uint32 m_uiFear_Timer; + uint32 m_uiSummon_Timer; + uint8 m_uiSwarmcount; + + std::list lSentrys; + + bool m_bHasBerserk; + bool m_bIsDefender; + + void Reset() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_uiEnrage_Timer = 600000; + m_uiSwarm_Timer = urand(50000, 60000); + m_uiSonic_Screech_Timer = urand(90000, 100000); + m_uiSentinel_Blast_Timer = 62000; + m_uiFear_Timer = 60000; + m_uiSummon_Timer = urand(60000, 70000); + m_uiSwarmcount = 10; + m_bHasBerserk = false; + m_bIsDefender = false; + + lSentrys.clear(); + + // achievs + m_bCrazyCatLady = true; + m_bNineLives = false; + } + + void JustDied(Unit* pKiller) + { + //death yell + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_AURIAYA, DONE); + + // hacky way to complete achievements; use only if you have this function + if (m_bCrazyCatLady) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CRAZY_CAT_LADY : ACHIEV_CRAZY_CAT_LADY_H); + } + + if (m_bNineLives) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_NINE_LIVES : ACHIEV_NINE_LIVES_H); + } + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_AURIAYA, IN_PROGRESS); + + GetCreatureListWithEntryInGrid(lSentrys, m_creature, NPC_SANCTUM_SENTRY, DEFAULT_VISIBILITY_INSTANCE); + if (!lSentrys.empty()) + { + for(std::list::iterator iter = lSentrys.begin(); iter != lSentrys.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->SetInCombatWithZone(); + } + } + + DoScriptText(SAY_AGGRO, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY1, m_creature); + else + DoScriptText(SAY_SLAY2, m_creature); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_AURIAYA, FAIL); + + GetCreatureListWithEntryInGrid(lSentrys, m_creature, NPC_SANCTUM_SENTRY, DEFAULT_VISIBILITY_INSTANCE); + if (!lSentrys.empty()) + { + for(std::list::iterator iter = lSentrys.begin(); iter != lSentrys.end(); ++iter) + { + if ((*iter) && !(*iter)->isAlive()) + (*iter)->Respawn(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiFear_Timer < uiDiff) + { + DoScriptText(EMOTE_SCREECH, m_creature); + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_FEAR); + m_uiFear_Timer = 35000; + m_uiSentinel_Blast_Timer = 2500; + }else m_uiFear_Timer -= uiDiff; + + if (m_uiSentinel_Blast_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SENTINEL_BLAST : SPELL_SENTINEL_BLAST_H); + m_uiSentinel_Blast_Timer = urand(30000, 40000); + }else m_uiSentinel_Blast_Timer -= uiDiff; + + if (m_uiSummon_Timer < uiDiff && !m_bIsDefender) + { + if (Creature* pTemp = m_creature->SummonCreature(MOB_FERAL_DEFENDER, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTemp->AddThreat(pTarget,0.0f); + pTemp->AI()->AttackStart(pTarget); + } + DoScriptText(EMOTE_DEFENDER, m_creature); + m_bIsDefender = true; + } + }else m_uiSummon_Timer -= uiDiff; + + if (m_uiSonic_Screech_Timer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SONIC_SCREECH : SPELL_SONIC_SCREECH_H); + m_uiSonic_Screech_Timer = 27000; + }else m_uiSonic_Screech_Timer -= uiDiff; + + // summon swarm, spell needs core fix + if (m_uiSwarm_Timer < uiDiff) + { + for(int i = 0; i < 10; i++) + { + float angle = (float) rand()*360/RAND_MAX + 1; + float homeX = m_creature->GetPositionX() + 10*cos(angle*(M_PI/180)); + float homeY = m_creature->GetPositionY() + 10*sin(angle*(M_PI/180)); + if (Creature* pTemp = m_creature->SummonCreature(MOB_GUARDIAN_SWARN, homeX, homeY, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + DoCast(pTarget, SPELL_GUARDIAN_SWARM); + pTemp->AddThreat(pTarget, 100.0f); + pTemp->SetInCombatWithZone(); + } + } + } + m_uiSwarm_Timer = 35000; + }else m_uiSwarm_Timer -= uiDiff; + + if (m_uiEnrage_Timer < uiDiff && !m_bHasBerserk) + { + DoScriptText(SAY_BERSERK, m_creature); + m_creature->CastStop(); + DoCast(m_creature, SPELL_BERSERK); + m_bHasBerserk = true; + }else m_uiEnrage_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } }; +CreatureAI* GetAI_boss_auriaya(Creature* pCreature) +{ + return new boss_auriayaAI(pCreature); +} + void AddSC_boss_auriaya() { + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "boss_auriaya"; + NewScript->GetAI = GetAI_boss_auriaya; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_seeping_feral_essence"; + NewScript->GetAI = &GetAI_mob_seeping_feral_essence; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_sanctum_sentry"; + NewScript->GetAI = &GetAI_mob_sanctum_sentry; + NewScript->RegisterSelf(); + NewScript = new Script; + NewScript->Name = "mob_feral_defender"; + NewScript->GetAI = &GetAI_mob_feral_defender; + NewScript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index fcbc44d2b..d658b0998 100644 --- a/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,41 +15,383 @@ */ /* ScriptData -SDName: boss_flame_leviathan -SD%Complete: 0% -SDComment: +SDName: boss_leviathan +SD%Complete: +SDComment: needs vehicles SDCategory: Ulduar EndScriptData */ #include "precompiled.h" #include "ulduar.h" +#include "Vehicle.h" -enum +enum say { - SAY_AGGRO = -1603159, - SAY_SLAY = -1603160, - SAY_DEATH = -1603161, + SAY_AGGRO = -1603203, + SAY_DEATH = -1603202, + SAY_SLAY = -1603201, + SAY_CHANGE1 = -1603204, + SAY_CHANGE2 = -1603205, + SAY_CHANGE3 = -1603206, + SAY_PLAYER_ON_TOP = -1603207, + SAY_OVERLOAD1 = -1603208, + SAY_OVERLOAD2 = -1603209, + SAY_OVERLOAD3 = -1603210, + SAY_HARD_MODE = -1603211, + SAY_TOWERS_DOWN = -1603212, + SAY_FROST_TOWER = -1603213, + SAY_FIRE_TOWER = -1603214, + SAY_ENERGY_TOWER = -1603215, + SAY_NATURE_TOWER = -1603216, - SAY_CHANGE_1 = -1603162, - SAY_CHANGE_2 = -1603163, - SAY_CHANGE_3 = -1603164, - SAY_PLAYER_RIDE = -1603165, - SAY_OVERLOAD_1 = -1603166, - SAY_OVERLOAD_2 = -1603167, - SAY_OVERLOAD_3 = -1603168, + EMOTE_PURSUE = -1603352, +}; + +enum spells +{ + SPELL_PURSUED = 62374, + + SPELL_MISSILE_BARRAGE = 62400, + SPELL_FLAME_VENTS = 62396, + SPELL_BATTERING_RAM = 62376, + + SPELL_GATHERING_SPEED = 62375, + // interupted by + SPELL_OVERLOAD_CIRCUIT = 62399, + + SPELL_SEARING_FLAME = 62402, // used by defense turret + // interupted by + SPELL_SYSTEMS_SHUTDOWN = 62475, + + SPELL_FLAME_CANNON = 62395, + //SPELL_FLAME_CANNON = 64692, trigger the same spell + SPELL_BLAZE = 62292, + + // used by players -> to be added later + SPELL_ELECTROSHOCK = 62522, + SPELL_SMOKE_TRAIL = 63575, + + // tower of nature + SPELL_FREYAS_WARD = 62906, + SPELL_TOWER_OF_LIFE = 64482, + // tower of flames + SPELL_MIMIRON_INFERNO = 62910, + SPELL_TOWER_OF_FLAMES = 65075, + // tower of frost + SPELL_HODIR_FURY = 62297, // also + 10% hp + // tower of storms + SPELL_THORIMS_HAMMER = 62912, + SPELL_TOWER_OF_STORMS = 65076 +}; + +enum Mobs +{ + MOB_MECHANOLIFT = 33214, + MOB_LIQUID = 33189, + MOB_CONTAINER = 33218, + + DEFENSE_TURRET = 33142, + KEEPER_OF_NORGANNON = 33686 +}; + +enum Seats +{ + SEAT_PLAYER = 0, + SEAT_TURRET = 1, + SEAT_DEVICE = 2, +}; + + +struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI +{ + boss_flame_leviathan(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + // ### unit disabled, please remove if you want to test it! +// pCreature->setFaction(35); // remove this when vehicules fixed! +// pCreature->SetVisibility(VISIBILITY_OFF); + // ### + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiBatteringRamTimer; + uint32 m_uiFlameVentsTimer; + uint32 m_uiMissileBarrageTimer; + uint32 m_uiPursueTimer; + uint32 m_uiGatheringSpeedTimer; + uint32 m_uiSummonFlyerTimer; + uint8 maxFlyers; + + bool isHardMode; + bool isHodirsTower; + bool isFreyasTower; + bool isMimironsTower; + bool isThorimsTower; + + uint32 m_uiFreyaWardTimer; + uint32 m_uiMimironInfernoTimer; + uint32 m_uiHodirFuryTimer; + uint32 m_uiThorimHammerTimer; + + void Reset() + { + m_uiBatteringRamTimer = 15000 + rand()%20000; + m_uiFlameVentsTimer = 15000 + rand()%10000; + m_uiMissileBarrageTimer = 1000; + m_uiPursueTimer = 30000; + m_uiGatheringSpeedTimer = 50000; + m_uiSummonFlyerTimer = 2000; + maxFlyers = 10; + + isHardMode = false; + isHodirsTower = false; + isFreyasTower = false; + isMimironsTower = false; + isThorimsTower = false; + + m_uiFreyaWardTimer = 40000 + urand(1000, 10000); + m_uiMimironInfernoTimer = 40000 + urand(1000, 10000); + m_uiHodirFuryTimer = 40000 + urand(1000, 10000); + m_uiThorimHammerTimer = 40000 + urand(1000, 10000); + + m_creature->SetSpeedRate(MOVE_RUN, 0.3f); + } + + void Aggro(Unit *who) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_LEVIATHAN, IN_PROGRESS); + if(m_pInstance->GetData(TYPE_LEVIATHAN_TP) != DONE) + m_pInstance->SetData(TYPE_LEVIATHAN_TP, DONE); + } + + DoScriptText(SAY_AGGRO, m_creature); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_LEVIATHAN, DONE); + if(isHardMode) + m_pInstance->SetData(TYPE_LEVIATHAN_HARD, DONE); + } + + DoScriptText(SAY_DEATH, m_creature); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_LEVIATHAN, FAIL); + } - SAY_HARD_MODE = -1603169, + void KilledUnit(Unit *who) + { + DoScriptText(SAY_SLAY, m_creature); + } - SAY_TOWER_FROST = -1603170, - SAY_TOWER_FIRE = -1603171, - SAY_TOWER_ENERGY = -1603172, - SAY_TOWER_NATURE = -1603173, - SAY_TOWER_DOWN = -1603174, + // TODO: effect 0 and effect 1 may be on different target + void SpellHitTarget(Unit *pTarget, const SpellEntry *spell) + { + if (spell->Id == SPELL_PURSUED) + AttackStart(pTarget); + } - EMOTE_PURSUE = -1603175, + void SpellHit(Unit *caster, const SpellEntry *spell) + { + /*if(spell->Id == 62472) + vehicle->InstallAllAccessories(); + else if(spell->Id == SPELL_ELECTROSHOCK) + m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL);*/ + } + + void DamageTaken(Unit *pDoneBy, uint32 &uiDamage) + { + uiDamage *= 4; + if(m_creature->HasAura(SPELL_SYSTEMS_SHUTDOWN, EFFECT_INDEX_0)) + uiDamage += uiDamage/2; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // pursue + if(m_uiPursueTimer < uiDiff) + { + switch(urand(0, 3)) + { + case 0: DoScriptText(SAY_CHANGE1, m_creature); break; + case 1: DoScriptText(SAY_CHANGE2, m_creature); break; + case 2: DoScriptText(SAY_CHANGE3, m_creature); break; + } + DoScriptText(EMOTE_PURSUE, m_creature); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + m_creature->AddThreat(pTarget, 100.0f); + DoCast(pTarget, SPELL_PURSUED); + } + + m_uiPursueTimer = 30000; + } + else m_uiPursueTimer -= uiDiff; + + // flame vents + if(m_uiFlameVentsTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_FLAME_VENTS); + m_uiFlameVentsTimer = 30000 + rand()%20000; + } + else m_uiFlameVentsTimer -= uiDiff; + + // battering ram + if(m_uiBatteringRamTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_BATTERING_RAM); + m_uiBatteringRamTimer = 25000 + rand()%15000; + } + else m_uiBatteringRamTimer -= uiDiff; + + /* flyers + it should summon some flyers. needs more research! + if(m_uiSummonFlyerTimer < uiDiff) + { + m_creature->SummonCreature(MOB_MECHANOLIFT, m_creature->GetPositionX() + rand()%20, m_creature->GetPositionY() + rand()%20, m_creature->GetPositionZ() + 50, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 40000); + m_uiSummonFlyerTimer = 2000; + } + else m_uiSummonFlyerTimer -= uiDiff;*/ + + // missile barrage + if(m_uiMissileBarrageTimer < uiDiff) + { + DoCast(m_creature, SPELL_MISSILE_BARRAGE); + m_uiMissileBarrageTimer = 3000 + rand()%2000; + } + else m_uiMissileBarrageTimer -= uiDiff; + + if(m_uiGatheringSpeedTimer < uiDiff) + { + DoCast(m_creature, SPELL_GATHERING_SPEED); + m_uiGatheringSpeedTimer = urand(50000, 60000); + } + else m_uiGatheringSpeedTimer -= uiDiff; + + // Hard mode event. need more research and scripting + // this part should be done in other way + + // tower of freya + if(isFreyasTower) + { + DoCast(m_creature, SPELL_TOWER_OF_LIFE); + + if(m_uiFreyaWardTimer < uiDiff) + { + DoCast(m_creature, SPELL_FREYAS_WARD); + m_uiFreyaWardTimer = 40000 + urand(1000, 10000); + } + else m_uiFreyaWardTimer -= uiDiff; + } + + // tower of mimiron + if(isMimironsTower) + { + DoCast(m_creature, SPELL_TOWER_OF_FLAMES); + + if(m_uiMimironInfernoTimer < uiDiff) + { + DoCast(m_creature, SPELL_FREYAS_WARD); + m_uiMimironInfernoTimer = 40000 + urand(1000, 10000); + } + else m_uiMimironInfernoTimer -= uiDiff; + } + + // tower of hodir + if(isHodirsTower) + { + m_creature->SetHealth(m_creature->GetHealth() + 0.1* m_creature->GetHealth()); + + if(m_uiHodirFuryTimer < uiDiff) + { + DoCast(m_creature, SPELL_HODIR_FURY); + m_uiHodirFuryTimer = 40000 + urand(1000, 10000); + } + else m_uiHodirFuryTimer -= uiDiff; + } + + // tower of thorim + if(isThorimsTower) + { + DoCast(m_creature, SPELL_TOWER_OF_STORMS); + + if(m_uiThorimHammerTimer < uiDiff) + { + DoCast(m_creature, SPELL_THORIMS_HAMMER); + m_uiThorimHammerTimer = 40000 + urand(1000, 10000); + } + else m_uiThorimHammerTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_defense_turretAI : public ScriptedAI +{ + mob_defense_turretAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(10000, 15000); + } + + void SpellHit(Unit *caster, const SpellEntry *spell) + { + if(spell->Id == SPELL_SYSTEMS_SHUTDOWN) + m_creature->ForcedDespawn(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + DoCast(m_creature, SPELL_SEARING_FLAME); + m_uiSpell_Timer = urand(10000, 15000); + }else m_uiSpell_Timer -= uiDiff; + } }; -void AddSC_boss_flame_leviathan() +CreatureAI* GetAI_mob_defense_turret(Creature* pCreature) +{ + return new mob_defense_turretAI(pCreature); +} + +CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature) +{ + return new boss_flame_leviathan(pCreature); +} + +void AddSC_boss_leviathan() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_flame_leviathan"; + newscript->GetAI = &GetAI_boss_flame_leviathan; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "mob_defense_turret"; + newscript->GetAI = &GetAI_mob_defense_turret; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_freya.cpp b/scripts/northrend/ulduar/ulduar/boss_freya.cpp index 0e49ee743..1e5d7ce5d 100644 --- a/scripts/northrend/ulduar/ulduar/boss_freya.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_freya.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_freya -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: aura stacking need core support after the recent aura changes SDCategory: Ulduar EndScriptData */ @@ -26,39 +26,1484 @@ EndScriptData */ enum { - SAY_AGGRO = -1603000, - SAY_AGGRO_HARD = -1603001, - SAY_ADDS_CONSERVATOR = -1603002, - SAY_ADDS_TRIO = -1603003, - SAY_ADDS_LASHER = -1603004, - SAY_SLAY_1 = -1603005, - SAY_SLAY_2 = -1603006, - SAY_DEATH = -1603007, - SAY_BERSERK = -1603008, - SAY_HELP_YOGG = -1603009, - - EMOTE_ALLIES_NATURE = -1603010, - EMOTE_LIFEBINDER = -1603011, - EMOTE_TREMOR = -1603012, - EMOTE_IRON_ROOTS = -1603013, - - SAY_AGGRO_BRIGHT = -1603014, - SAY_SLAY_1_BRIGHT = -1603015, - SAY_SLAY_2_BRIGHT = -1603016, - SAY_DEATH_BRIGHT = -1603017, - - SAY_AGGRO_IRON = -1603018, - SAY_SLAY_1_IRON = -1603019, - SAY_SLAY_2_IRON = -1603020, - SAY_DEATH_IRON = -1603021, - - SAY_AGGRO_STONE = -1603022, - SAY_SLAY_1_STONE = -1603023, - SAY_SLAY_2_STONE = -1603024, - SAY_DEATH_STONE = -1603025, + /* YELLS */ + // freya + SAY_AGGRO = -1603000, + SAY_AGGRO_HARD = -1603001, + SAY_SUMMON1 = -1603002, + SAY_SUMMON2 = -1603003, + SAY_SUMMON3 = -1603004, + SAY_SLAY1 = -1603005, + SAY_SLAY2 = -1603006, + SAY_DEATH = -1603007, + SAY_BERSERK = -1603008, + EMOTE_ALLIES_NATURE = -1603362, + EMOTE_LIFEBINDERS_GIFT = -1603363, + EMOTE_GROUND_TREMMOR = -1603364, + EMOTE_IRON_ROOTS = -1603365, + //brightleaf + SAY_BRIGHTLEAF_AGGRO = -1603160, + SAY_BRIGHTLEAF_SLAY1 = -1603161, + SAY_BRIGHTLEAF_SLAY2 = -1603162, + SAY_BRIGHTLEAF_DEATH = -1603163, + //Ironbranch + SAY_IRONBRANCH_AGGRO = -1603170, + SAY_IRONBRANCH_SLAY1 = -1603171, + SAY_IRONBRANCH_SLAY2 = -1603172, + SAY_IRONBRANCH_DEATH = -1603173, + //Stonebark + SAY_STONEBARK_AGGRO = -1603180, + SAY_STONEBARK_SLAY1 = -1603181, + SAY_STONEBARK_SLAY2 = -1603182, + SAY_STONEBARK_DEATH = -1603183, + + /* BOSS SPELLS */ + SPELL_ATTUNED_TO_NATURE = 62519, //increases healing, start at 150 stacks + SPELL_ATTUNED_10_STACKS = 62525, + SPELL_ATTUNED_2_STACKS = 62524, + SPELL_ATTUNED_25_STACKS = 62521, + SPELL_TOUCH_OF_EONAR = 62528, //heals Freya, 6k per second + SPELL_TOUCH_OF_EONAR_H = 62892, //heals Freya, 24k per second + SPELL_SUNBEAM = 62623, + SPELL_SUNBEAM_H = 62872, + SPELL_BERSERK = 47008, // 10 min + + /* HARD MODE SPELLS */ + SPELL_DRAINED_OF_POWER = 62467, + // brightleaf + SPELL_UNSTABLE_ENERGY_FREYA = 62451, + SPELL_UNSTABLE_ENERGY_FREYA_H = 62865, + SPELL_BRIGHTLEAFS_ESSENCE = 62968, //62385, + SPELL_EFFECT_BRIGHTLEAF = 63294, + // ironbrach + SPELL_STRENGHTEN_IRON_ROOTS = 63601, + NPC_STRENGHENED_IRON_ROOTS = 33168, + SPELL_IRON_ROOTS_FREYA = 62438, + SPELL_IRON_ROOTS_FREYA_H = 62861, + SPELL_IRONBRANCH_ESSENCE = 62713, //62387, + SPELL_EFFECT_IRONBRANCH = 63292, + // stonebark + SPELL_GROUND_TREMOR_FREYA = 62437, + SPELL_GROUND_TREMOR_FREYA_H = 62859, + SPELL_STONEBARKS_ESSENCE = 65590, //62386, + SPELL_EFFECT_STONEBARK = 63295, + + NPC_SUN_BEAM = 33170, + NPC_UNSTABLE_SUN_BEAM = 33050, + + // sanctuary adds + NPC_EONARS_GIFT = 33228, + SPELL_LIFEBINDERS_GIFT = 62584, // after 12 secs, heals Freya & her allies for 30% + SPELL_LIFEBINDERS_GIFT_H = 64185, // the same but for 60% + SPELL_PHEROMONES = 62619, // protects from conservators grip + NPC_HEALTHY_SPORE = 33215, + + /* ADDS */ + // 6 waves of adds. 1 of the 3 each min + NPC_DETONATING_LASHER = 32918, // recude 2 stacks + // spells + SPELL_FLAME_LASH = 62608, + SPELL_DETONATE = 62598, + SPELL_DETONATE_H = 62937, + + NPC_ANCIENT_CONSERVATOR = 33203, // reduce 30 stacks + //spells + SPELL_CONSERVATORS_GRIP = 62532, + SPELL_NATURES_FURY = 62589, + SPELL_NATURES_FURY_H = 63571, + + /* elemental adds */ // each one reduces 10 stacks + NPC_WATER_SPIRIT = 33202, + // spells + SPELL_TIDAL_WAVE = 62653, + SPELL_TIDAL_WAVE_H = 62935, + + NPC_STORM_LASHER = 32919, + // spells + SPELL_STORMBOLT = 62649, + SPELL_STORMBOLT_H = 62938, + SPELL_LIGHTNING_LASH = 62648, // 3 targets + SPELL_LIGHTNING_LASH_H = 62939, // 5 targets + + NPC_SNAPLASHER = 32916, + // spells + SPELL_HARDENED_BARK = 62663, + SPELL_HARDENED_BARK_H = 64190, + + // nature bomb + NPC_NATURE_BOMB = 34129, + GO_NATURE_BOMB = 194902, + SPELL_NATURE_BOMB = 64587, + SPELL_NATURE_BOMB_H = 64650, + + /* ELDERS */ // used in phase 1 + ELDER_BRIGHTLEAF = 32915, + ELDER_IRONBRANCH = 32913, + ELDER_STONEBARK = 32914, + + // brightleaf spells + SPELL_BRIGHTLEAF_FLUX = 62262, + SPELL_SOLAR_FLARE = 62240, + SPELL_SOLAR_FLARE_H = 62920, + SPELL_UNSTABLE_SUN_BEAM = 62211, + SPELL_UNSTABLE_SUN_BEAM_A = 62243, + SPELL_UNSTABLE_ENERGY = 62217, // cancels sun bean + SPELL_UNSTABLE_ENERGY_H = 62922, + SPELL_PHOTOSYNTHESIS = 62209, + + // ironbrach spells + SPELL_IMPALE = 62310, + SPELL_IMPALE_H = 62928, + SPELL_IRON_ROOTS = 62283, + SPELL_IRON_ROOTS_H = 62930, + NPC_IRON_ROOTS = 33088, + SPELL_THORM_SWARM = 62285, + SPELL_THORM_SWARM_H = 62931, + + // stonebark spells + SPELL_FIST_OF_STONE = 62344, + SPELL_BROKEN_BONES = 62356, + SPELL_GROUND_TREMOR = 62325, + SPELL_GROUND_TREMOR_H = 62932, + SPELL_PETRIFIED_BARK = 62337, + SPELL_PETRIFIED_BARK_H = 62933, + + // not used because summoned chest doesn't despawn after looted + SPELL_SUMMON_CHEST_1 = 62950, + SPELL_SUMMON_CHEST_2 = 62952, + SPELL_SUMMON_CHEST_3 = 62953, + SPELL_SUMMON_CHEST_4 = 62954, + SPELL_SUMMON_CHEST_5 = 62955, + SPELL_SUMMON_CHEST_6 = 62956, + SPELL_SUMMON_CHEST_7 = 62957, + SPELL_SUMMON_CHEST_8 = 62958, + + SPELL_SUMMON_ALLIES_OF_NATURE = 62678, //better do that in sd2 + SPELL_SUMMON_LASHERS = 62688, // lashers - broken + SPELL_SUMMON_ELEMENTALS = 62686, // elementals -> better in sd2 + SPELL_SUMMON_CONSERVATOR = 62685, // conservator + SPELL_LIFEBINDERS_GIFT_SUMMON = 62869, + SPELL_NATURE_BOMB_SUMMON = 64606, + + SPELL_SPORE_SUMMON_NE = 62591, + SPELL_SPORE_SUMMON_SE = 62592, + SPELL_SPORE_SUMMON_SW = 62593, + SPELL_SPORE_SUMMON_NW = 62582, + + SPELL_HEALTHY_SPORE_VISUAL = 62538, + SPELL_NATURE_BOMB_VISUAL = 64604, + SPELL_LIFEBINDERS_VISUAL = 62579, + SPELL_LIFEBINDER_GROW = 44833, + + SPELL_PHEROMONES_LG = 62619, + SPELL_POTENT_PHEROMONES = 62541, + + ACHIEV_BACK_TO_NATURE = 2982, + ACHIEV_BACK_TO_NATURE_H = 2983, + ACHIEV_KNOCK_WOOD = 3177, + ACHIEV_KNOCK_WOOD_H = 3185, + ACHIEV_KNOCK_KNOCK_WOOD = 3178, + ACHIEV_KNOCK_KNOCK_WOOD_H = 3186, + ACHIEV_KNOCK_KNOCK_KNOCK_WOOD = 3179, + ACHIEV_KNOCK_KNOCK_KNOCK_WOOD_H = 3187, +}; + +// Iron roots & stranghned iron roots +struct MANGOS_DLL_DECL mob_iron_rootsAI : public ScriptedAI +{ + mob_iron_rootsAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint64 m_uiVictimGUID; + uint32 m_uiCreatureEntry; + + void Reset() + { + m_uiVictimGUID = 0; + m_uiCreatureEntry = m_creature->GetEntry(); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (uiDamage > m_creature->GetHealth()) + { + if (m_uiVictimGUID) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit(m_uiVictimGUID)) + { + switch(m_uiCreatureEntry) + { + case NPC_IRON_ROOTS: + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H); + break; + case NPC_STRENGHENED_IRON_ROOTS: + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H); + break; + } + } + } + } + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim) + { + switch(m_uiCreatureEntry) + { + case NPC_IRON_ROOTS: + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H); + break; + case NPC_STRENGHENED_IRON_ROOTS: + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H); + break; + } + } + } + + void JustDied(Unit* Killer) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit(m_uiVictimGUID)) + { + switch(m_uiCreatureEntry) + { + case NPC_IRON_ROOTS: + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H); + break; + case NPC_STRENGHENED_IRON_ROOTS: + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H); + break; + } + } + } + + void UpdateAI(const uint32 uiuiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + } +}; + +// Elder Brightleaf +struct MANGOS_DLL_DECL boss_elder_brightleafAI : public ScriptedAI +{ + boss_elder_brightleafAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint32 m_uiBrightleafFluxTimer; + uint32 m_uiSolarFlareTimer; + uint32 m_uiUnstableSunBeanTimer; + uint32 m_uiUnstabelEnergyTimer; + uint32 m_uiSunbeamStacks; + uint32 m_uiHealTimer; + bool m_bHasSunbeam; + + void Reset() + { + m_uiBrightleafFluxTimer = 5000; + m_uiSolarFlareTimer = 10000 + urand(1000, 5000); + m_uiUnstableSunBeanTimer = 15000; + m_uiUnstabelEnergyTimer = 30000; + m_uiSunbeamStacks = 1; + m_bHasSunbeam = false; + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_BRIGHTLEAF_AGGRO, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_BRIGHTLEAF_SLAY1, m_creature); + else + DoScriptText(SAY_BRIGHTLEAF_SLAY2, m_creature); + } + + void JustDied(Unit *killer) + { + DoScriptText(SAY_BRIGHTLEAF_DEATH, m_creature); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // this needs core suport + if(m_uiBrightleafFluxTimer < uiDiff) + { + DoCast(m_creature, SPELL_BRIGHTLEAF_FLUX); + m_uiBrightleafFluxTimer = 5000; + } + else m_uiBrightleafFluxTimer -= uiDiff; + + if(m_uiSolarFlareTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_SOLAR_FLARE : SPELL_SOLAR_FLARE_H); + m_uiSolarFlareTimer = 10000 + urand(1000, 5000); + } + else m_uiSolarFlareTimer -= uiDiff; + + // also the following spells need some core support -> hacky way of use + // PLEASE FIX FOR REVISION! + if(m_uiUnstableSunBeanTimer < uiDiff) + { + DoCast(m_creature, SPELL_UNSTABLE_SUN_BEAM); + m_bHasSunbeam = true; + m_uiHealTimer = 1000; + m_uiUnstableSunBeanTimer = urand(7000, 12000); + } + else m_uiUnstableSunBeanTimer -= uiDiff; + + // cast after the unstable sun bean + if (m_uiHealTimer < uiDiff && m_bHasSunbeam) + { + DoCast(m_creature, SPELL_PHOTOSYNTHESIS); + m_bHasSunbeam = false; + } + else m_uiHealTimer -= uiDiff; + + // removes photosynthesis when standing inside + if(m_uiUnstabelEnergyTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY: SPELL_UNSTABLE_ENERGY_H); + m_creature->RemoveAurasDueToSpell(SPELL_UNSTABLE_SUN_BEAM_A); + m_creature->RemoveAurasDueToSpell(SPELL_PHOTOSYNTHESIS); + m_uiSunbeamStacks = 1; + m_uiUnstabelEnergyTimer = urand(20000, 30000); + } + else m_uiUnstabelEnergyTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_elder_brightleaf(Creature* pCreature) +{ + return new boss_elder_brightleafAI(pCreature); +} + +// Elder Ironbranch +struct MANGOS_DLL_DECL boss_elder_ironbranchAI : public ScriptedAI +{ + boss_elder_ironbranchAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint32 m_uiImpaleTimer; + uint32 m_uiIronrootsTimer; + uint32 m_uiThornSwarmTimer; + + void Reset() + { + m_uiImpaleTimer = 10000 + urand (1000, 5000); + m_uiIronrootsTimer = 20000 + urand (1000, 7000); + m_uiThornSwarmTimer = 30000; + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_IRONBRANCH_AGGRO, m_creature); + } + + void JustDied(Unit *killer) + { + DoScriptText(SAY_IRONBRANCH_DEATH, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_IRONBRANCH_SLAY1, m_creature); + else + DoScriptText(SAY_IRONBRANCH_SLAY2, m_creature); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiImpaleTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_IMPALE : SPELL_IMPALE_H); + m_uiImpaleTimer = 10000 + urand (1000, 5000); + } + else m_uiImpaleTimer -= uiDiff; + + if(m_uiIronrootsTimer < uiDiff) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + DoCast(target, m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H); + m_uiIronrootsTimer = 20000 + urand (1000, 7000); + } + else m_uiIronrootsTimer -= uiDiff; + + if(m_uiThornSwarmTimer < uiDiff) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + DoCast(target, m_bIsRegularMode ? SPELL_THORM_SWARM : SPELL_THORM_SWARM_H); + m_uiThornSwarmTimer = 30000; + } + else m_uiThornSwarmTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_elder_ironbranch(Creature* pCreature) +{ + return new boss_elder_ironbranchAI(pCreature); +} + +// Stonebark +struct MANGOS_DLL_DECL boss_elder_stonebarkAI : public ScriptedAI +{ + boss_elder_stonebarkAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint32 m_uiFistsOfStoneTimer; + uint32 m_uiGroundTremorTimer; + uint32 m_uiPetrifiedBarkTimer; + + void Reset() + { + m_uiFistsOfStoneTimer = 20000; + m_uiGroundTremorTimer = 15000; + m_uiPetrifiedBarkTimer = 25000; + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_STONEBARK_AGGRO, m_creature); + } + + void JustDied(Unit *killer) + { + DoScriptText(SAY_STONEBARK_DEATH, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_STONEBARK_SLAY1, m_creature); + else + DoScriptText(SAY_STONEBARK_SLAY2, m_creature); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiFistsOfStoneTimer < uiDiff) + { + DoCast(m_creature, SPELL_FIST_OF_STONE); + m_uiFistsOfStoneTimer = 30000; + } + else m_uiFistsOfStoneTimer -= uiDiff; + + if(m_uiGroundTremorTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_GROUND_TREMOR : SPELL_GROUND_TREMOR_H); + m_uiGroundTremorTimer = 15000 + urand (1000, 5000); + } + else m_uiGroundTremorTimer -= uiDiff; + + if(m_uiPetrifiedBarkTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_PETRIFIED_BARK : SPELL_PETRIFIED_BARK_H); + m_uiPetrifiedBarkTimer = 20000 + urand (1000, 5000); + } + else m_uiPetrifiedBarkTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_elder_stonebark(Creature* pCreature) +{ + return new boss_elder_stonebarkAI(pCreature); +} + +// Freya +struct MANGOS_DLL_DECL boss_freyaAI : public ScriptedAI +{ + boss_freyaAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiSummonTimer; + uint32 m_uiWaveNumber; + uint32 m_uiWaveType; + uint32 m_uiWaveTypeInc; + uint32 m_uiSunbeamTimer; + uint32 m_uiEnrageTimer; + + bool m_bIsHardMode; + bool m_bHasAura; + + uint32 m_uiNatureBombTimer; + uint32 m_uiLifebindersGiftTimer; + + bool m_bIsOutro; + uint32 m_uiOutroTimer; + uint32 m_uiStep; + + // hard mode timers + uint32 m_uiUnstableEnergyTimer; + uint32 m_uiStrenghtenIronRootsTimer; + uint32 m_uiGroundTremorTimer; + + uint32 m_uiThreeWaveCheckTimer; + bool m_bWaveCheck; + uint64 m_uiWaterSpiritGUID; + uint64 m_uiStormLasherGUID; + uint64 m_uiSnapLasherGUID; + + bool m_bIsBrightleafAlive; + bool m_bIsIronbranchAlive; + bool m_bIsStonebarkAlive; + + uint32 m_uiAchievProgress; + bool m_bNature; + + void Reset() + { + m_uiSummonTimer = 15000; + m_uiWaveNumber = 0; + m_uiWaveType = irand(0,2); + m_uiWaveTypeInc = irand(1,2); + m_uiSunbeamTimer = rand()%10000; + m_uiEnrageTimer = 600000; //10 minutes + m_bIsHardMode = false; + m_uiLifebindersGiftTimer = 30000; + m_uiUnstableEnergyTimer = 25000; + m_uiStrenghtenIronRootsTimer = 25000 + urand(1000, 5000); + m_uiGroundTremorTimer = 20000; + m_uiNatureBombTimer = 7000; + m_uiThreeWaveCheckTimer = 1000; + m_uiAchievProgress = 10000; + m_bWaveCheck = false; + m_uiWaterSpiritGUID = 0; + m_uiStormLasherGUID = 0; + m_uiSnapLasherGUID = 0; + + m_uiOutroTimer = 10000; + m_uiStep = 1; + m_bIsOutro = false; + + m_uiAchievProgress = 0; + m_bNature = false; + m_bHasAura = false; + + if(m_pInstance) + { + // remove elder auras + if (Creature* pBrightleaf = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRIGHTLEAF))) + { + if (pBrightleaf->isAlive()) + pBrightleaf->RemoveAllAuras(); + } + if (Creature* pIronbranch = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IRONBRACH))) + { + if (pIronbranch->isAlive()) + pIronbranch->RemoveAllAuras(); + } + if (Creature* pStonebark = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STONEBARK))) + { + if (pStonebark->isAlive()) + pStonebark->RemoveAllAuras(); + } + } + } + + void Aggro(Unit *who) + { + // aura should stack up to 150 when casted, need core support + DoCast(m_creature, SPELL_ATTUNED_TO_NATURE); + + if(m_pInstance) + { + m_pInstance->SetData(TYPE_FREYA, IN_PROGRESS); + + // check brightleaf + if (Creature* pBrightleaf = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRIGHTLEAF))) + { + if (pBrightleaf->isAlive()) + { + pBrightleaf->CastSpell(pBrightleaf, SPELL_DRAINED_OF_POWER, false); + pBrightleaf->CastSpell(m_creature, SPELL_EFFECT_BRIGHTLEAF, false); + m_bIsBrightleafAlive = true; + m_uiAchievProgress += 1; + } + else + m_bIsBrightleafAlive = false; + } + + // check ironbranch + if (Creature* pIronbranch = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IRONBRACH))) + { + if (pIronbranch->isAlive()) + { + pIronbranch->CastSpell(pIronbranch, SPELL_DRAINED_OF_POWER, false); + pIronbranch->CastSpell(m_creature, SPELL_EFFECT_IRONBRANCH, false); + m_bIsIronbranchAlive = true; + m_uiAchievProgress += 1; + } + else + m_bIsIronbranchAlive = false; + } + + // check stonebark + if (Creature* pStonebark = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STONEBARK))) + { + if (pStonebark->isAlive()) + { + pStonebark->CastSpell(pStonebark, SPELL_DRAINED_OF_POWER, false); + pStonebark->CastSpell(m_creature, SPELL_EFFECT_STONEBARK, false); + m_bIsStonebarkAlive = true; + m_uiAchievProgress += 1; + } + else + m_bIsStonebarkAlive = false; + } + } + + m_bIsHardMode = CheckHardMode(); + + if(!m_bIsHardMode) + DoScriptText(SAY_AGGRO, m_creature); + else + DoScriptText(SAY_AGGRO_HARD, m_creature); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_FREYA, FAIL); + } + + void DoOutro() + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_FREYA_HARD, 0); + + // hacky way to complete achievements; use only if you have this function + if(m_uiAchievProgress == 1) + { + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_KNOCK_WOOD : ACHIEV_KNOCK_WOOD_H); + m_pInstance->SetData(TYPE_FREYA_HARD, 1); + } + else if (m_uiAchievProgress == 2) + { + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_KNOCK_KNOCK_WOOD : ACHIEV_KNOCK_KNOCK_WOOD_H); + m_pInstance->SetData(TYPE_FREYA_HARD, 2); + } + else if (m_uiAchievProgress == 3) + { + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_KNOCK_KNOCK_KNOCK_WOOD : ACHIEV_KNOCK_KNOCK_KNOCK_WOOD_H); + m_pInstance->SetData(TYPE_FREYA_HARD, 3); + } + + if (m_bNature) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_BACK_TO_NATURE : ACHIEV_BACK_TO_NATURE_H); + + m_pInstance->SetData(TYPE_FREYA, DONE); + } + + m_creature->ForcedDespawn(); + } + + // for debug only! + void JustDied(Unit* pKiller) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_FREYA, DONE); + if(m_bIsHardMode) + m_pInstance->SetData(TYPE_FREYA_HARD, DONE); + } + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(m_creature->GetHealthPercent() < 1.0f) + { + uiDamage = 0; + m_bIsOutro = true; + } + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY1, m_creature); + else + DoScriptText(SAY_SLAY2, m_creature); + } + + // summon 12 Lashers. Should be done by a spell which needs core fix + void SummonLashers() + { + DoScriptText(SAY_SUMMON3, m_creature); + int i; + float x,y; + for(i = 0; i < 12; ++i) + { + x = (rand_norm() * 30.0f) - 15.0f; + y = (rand_norm() * 30.0f) - 15.0f; + if(Creature* pLasher = DoSpawnCreature(NPC_DETONATING_LASHER, x, y, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pLasher->AddThreat(pTarget, 1.0f); + } + } + } + + // summon conservator. Should be done by a spell which needs core fix + void SummonConservator() + { + DoScriptText(SAY_SUMMON1, m_creature); + float x = (rand_norm() * 30.0f) - 15.0f; + float y = (rand_norm() * 30.0f) - 15.0f; + if(Creature* pAdd = DoSpawnCreature(NPC_ANCIENT_CONSERVATOR, x, y, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + { + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pAdd->AddThreat(pTarget, 1.0f); + } + } + + // summmon the 3 elementals. Should be done by a spell which needs core fix. + void SummonElementals() + { + DoScriptText(SAY_SUMMON2, m_creature); + m_bWaveCheck = true; + m_uiThreeWaveCheckTimer = 2000; + + if(Creature* pSpirit = DoSpawnCreature(NPC_WATER_SPIRIT, 0, 0, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + { + m_uiWaterSpiritGUID = pSpirit->GetGUID(); + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSpirit->AddThreat(pTarget, 1.0f); + } + + if(Creature* pStormLasher = DoSpawnCreature(NPC_STORM_LASHER, 0, 0, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + { + m_uiStormLasherGUID = pStormLasher->GetGUID(); + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pStormLasher->AddThreat(pTarget, 1.0f); + } + + if(Creature* pSnapLasher = DoSpawnCreature(NPC_SNAPLASHER, 0, 0, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + { + m_uiSnapLasherGUID = pSnapLasher->GetGUID(); + if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSnapLasher->AddThreat(pTarget, 1.0f); + } + } + + bool CheckHardMode() + { + if(m_bIsBrightleafAlive && m_bIsIronbranchAlive && m_bIsStonebarkAlive) + return true; + return false; + } + + void UpdateAI(const uint32 uiDiff) + { + if(!m_bIsOutro) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // hacky way of stacking aura. Please remove when fixed in core! + if(SpellAuraHolder* natureAura = m_creature->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE)) + { + if(natureAura->GetStackAmount() < 150 && !m_bHasAura) + { + m_bHasAura = true; + natureAura->SetStackAmount(150); + } + } + + if(!m_creature->HasAura(m_bIsRegularMode ? SPELL_TOUCH_OF_EONAR : SPELL_TOUCH_OF_EONAR_H)) + DoCast(m_creature, m_bIsRegularMode ? SPELL_TOUCH_OF_EONAR : SPELL_TOUCH_OF_EONAR_H); + + // check if the 3 elementals die at the same time + if(m_uiThreeWaveCheckTimer < uiDiff && m_bWaveCheck) + { + Creature* pWaterSpirit = m_pInstance->instance->GetCreature(m_uiWaterSpiritGUID); + Creature* pStormLasher = m_pInstance->instance->GetCreature(m_uiStormLasherGUID); + Creature* pSnapLasher = m_pInstance->instance->GetCreature(m_uiSnapLasherGUID); + + if(pWaterSpirit && pStormLasher && pSnapLasher) + { + if(!pWaterSpirit->isAlive() && !pStormLasher->isAlive() && !pSnapLasher->isAlive()) + { + m_bWaveCheck = false; + if(SpellAuraHolder* natureAura = m_creature->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE)) + { + if(natureAura->ModStackAmount(-30)) + m_creature->RemoveAurasDueToSpell(SPELL_ATTUNED_TO_NATURE); + } + } + else + { + // respawn the dead ones + if(!pWaterSpirit->isAlive()) + pWaterSpirit->Respawn(); + if(!pSnapLasher->isAlive()) + pSnapLasher->Respawn(); + if(!pStormLasher->isAlive()) + pStormLasher->Respawn(); + } + } + m_uiThreeWaveCheckTimer = 2000; + } + else + m_uiThreeWaveCheckTimer -= uiDiff; + + // Hardmode + if(m_bIsBrightleafAlive) + { + if(!m_creature->HasAura(SPELL_BRIGHTLEAFS_ESSENCE, EFFECT_INDEX_0)) + DoCast(m_creature, SPELL_BRIGHTLEAFS_ESSENCE); + + // hacky way, should be done by spell + if(m_uiUnstableEnergyTimer < uiDiff) + { + //DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY_FREYA : SPELL_UNSTABLE_ENERGY_FREYA_H); + for(int8 i = 0; i < 3; ++i) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + float x = target->GetPositionX(); + float y = target->GetPositionY(); + float z = target->GetPositionZ(); + m_creature->SummonCreature(NPC_SUN_BEAM, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 20000); + } + } + m_uiUnstableEnergyTimer = urand(25000, 30000); + } + else m_uiUnstableEnergyTimer -= uiDiff; + } + + if(m_bIsIronbranchAlive) + { + if(!m_creature->HasAura(SPELL_IRONBRANCH_ESSENCE, EFFECT_INDEX_0)) + DoCast(m_creature, SPELL_IRONBRANCH_ESSENCE); + + if(m_uiStrenghtenIronRootsTimer < uiDiff) + { + if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + DoScriptText(EMOTE_IRON_ROOTS, m_creature, target); + DoCast(target, m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H); + } + m_uiStrenghtenIronRootsTimer = 50000 + urand(10000, 20000); + } + else m_uiStrenghtenIronRootsTimer -= uiDiff; + } + + if(m_bIsStonebarkAlive) + { + // aura doesn't work. Needs core fix + if(!m_creature->HasAura(SPELL_STONEBARKS_ESSENCE, EFFECT_INDEX_0)) + DoCast(m_creature, SPELL_STONEBARKS_ESSENCE); + + if(m_uiGroundTremorTimer < uiDiff) + { + DoScriptText(EMOTE_GROUND_TREMMOR, m_creature); + DoCast(m_creature, m_bIsRegularMode ? SPELL_GROUND_TREMOR_FREYA : SPELL_GROUND_TREMOR_FREYA_H); + m_uiGroundTremorTimer = 20000; + } + else m_uiGroundTremorTimer -= uiDiff; + } + + //Phase 1, waves of adds + if(m_uiWaveNumber < 6) + { + if(m_uiSummonTimer < uiDiff) + { + DoScriptText(EMOTE_ALLIES_NATURE, m_creature); + switch(m_uiWaveType) + { + case 0: SummonLashers(); break; + case 1: SummonConservator(); break; + case 2: SummonElementals(); break; + } + m_uiWaveType = (m_uiWaveType + m_uiWaveTypeInc) % 3; + ++m_uiWaveNumber; + m_uiSummonTimer = 60000; + } + else m_uiSummonTimer -= uiDiff; + } + // Phase 2 + else + { + // nature bomb. Should be done by spell, not by summon. + if(m_uiNatureBombTimer < uiDiff) + { + DoCast(m_creature, SPELL_NATURE_BOMB_VISUAL); + DoCast(m_creature, SPELL_NATURE_BOMB_SUMMON); + + int8 count = urand(8,10); + for(int8 i = 0; i < count; ++i) + { + float radius = 30* rand_norm_f(); + float angle = 2.0f * M_PI_F * rand_norm_f(); + float x = m_creature->GetPositionX() + cos(angle) * radius; + float y = m_creature->GetPositionY() + sin(angle) * radius; + float z = m_creature->GetTerrain()->GetHeight(x, y, MAX_HEIGHT); + m_creature->SummonCreature(NPC_NATURE_BOMB, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 20000); + } + m_uiNatureBombTimer = urand(7000, 12000); + } + else m_uiNatureBombTimer -= uiDiff; + } + + //All phases + if(m_uiSunbeamTimer < uiDiff) + { + if( Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(target, m_bIsRegularMode ? SPELL_SUNBEAM : SPELL_SUNBEAM_H); + m_uiSunbeamTimer = 6000 + rand()%10000; + } + else m_uiSunbeamTimer -= uiDiff; + + if(m_uiLifebindersGiftTimer < uiDiff) + { + DoScriptText(EMOTE_LIFEBINDERS_GIFT, m_creature); + if(Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_LIFEBINDERS_GIFT_SUMMON); + m_uiLifebindersGiftTimer = 30000; + } + else m_uiLifebindersGiftTimer -= uiDiff; + + if(m_uiEnrageTimer < uiDiff) + { + DoScriptText(SAY_BERSERK, m_creature); + DoCast(m_creature, SPELL_BERSERK); + m_uiEnrageTimer = 30000; + } + else m_uiEnrageTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + // outro + if(m_bIsOutro) + { + switch(m_uiStep) + { + case 1: + if(m_creature->HasAura(SPELL_ATTUNED_TO_NATURE, EFFECT_INDEX_0)) + { + if(m_creature->GetAura(SPELL_ATTUNED_TO_NATURE, EFFECT_INDEX_0)->GetStackAmount() >= 25) + m_bNature = true; + } + m_creature->setFaction(35); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->InterruptNonMeleeSpells(false); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->GetMotionMaster()->MovePoint(0, 2359.40f, -52.39f, 425.64f); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + ++m_uiStep; + m_uiOutroTimer = 7000; + break; + case 3: + DoScriptText(SAY_DEATH, m_creature); + ++m_uiStep; + m_uiOutroTimer = 10000; + break; + case 5: + DoOutro(); + ++m_uiStep; + m_uiOutroTimer = 10000; + break; + } + } + else return; + + if (m_uiOutroTimer <= uiDiff) + { + ++m_uiStep; + m_uiOutroTimer = 330000; + } m_uiOutroTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_boss_freya(Creature* pCreature) +{ + return new boss_freyaAI(pCreature); +} + +// Script for all the npcs found on the ground during Freya encounter +struct MANGOS_DLL_DECL mob_freya_groundAI : public ScriptedAI +{ + mob_freya_groundAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiNatureBomb_Timer; + uint32 m_uiDieTimer; + uint32 m_uiEonarsGift_Timer; + uint32 m_uiNonSelectable_Timer; + uint32 m_uiGrow_Timer; + uint32 m_uiSunBeamDespawn_Timer; + uint32 m_uiUnstableEnergy_Timer; + uint32 m_uiHealthyGrow_Timer; + uint64 m_uiNatureBombGUID; + float m_fSize; + + bool m_bNpcNatureBomb; + bool m_bNpcEonarsGift; + bool m_bNpcHealthySpore; + bool m_bNpcSunBeamFreya; + bool m_bNpcSunBeamBright; + + bool m_bHasGrow; + + void Reset() + { + m_uiNatureBomb_Timer = urand(9000,11000); + m_uiDieTimer = 60000; + m_uiEonarsGift_Timer = urand(11000,13000); + m_uiNonSelectable_Timer = 5000; + m_uiUnstableEnergy_Timer = 1000; + m_uiGrow_Timer = 0; + m_uiSunBeamDespawn_Timer = urand(10000,11000); + m_bHasGrow = true; + m_uiHealthyGrow_Timer = urand(3000,12000); + m_bNpcNatureBomb = false; + m_bNpcEonarsGift = false; + m_bNpcHealthySpore = false; + m_bNpcSunBeamFreya = false; + m_bNpcSunBeamBright = false; + + // the invisible displayIds should be set in DB. + switch(m_creature->GetEntry()) + { + case NPC_NATURE_BOMB: + m_bNpcNatureBomb = true; + m_creature->setFaction(14); + m_fSize = 1; + m_creature->SetDisplayId(25865); // invisible + DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL); + break; + case NPC_EONARS_GIFT: + m_bNpcEonarsGift = true; + m_fSize = float(0.1); + DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL); + break; + case NPC_HEALTHY_SPORE: + m_bNpcHealthySpore = true; + DoCast(m_creature, SPELL_HEALTHY_SPORE_VISUAL); + DoCast(m_creature, SPELL_POTENT_PHEROMONES); + break; + case NPC_SUN_BEAM: + m_bNpcSunBeamFreya = true; + m_creature->SetDisplayId(25865); // invisible + DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL); + DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY_FREYA : SPELL_UNSTABLE_ENERGY_FREYA_H); + break; + case NPC_UNSTABLE_SUN_BEAM: + m_bNpcSunBeamBright = true; + m_creature->SetDisplayId(25865); // invisible + DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL); + //DoCast(m_creature, SPELL_PHOTOSYNTHESIS); // spell needs core fix, should be casted on Brighleaf! + break; + } + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetRespawnDelay(DAY); + } + + void AttackStart(Unit* pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_FREYA) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if(!m_creature->isAlive()) + return; + + // NATURE BOMB + if(m_bNpcNatureBomb) + { + if(m_uiNatureBomb_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_NATURE_BOMB : SPELL_NATURE_BOMB_H); + m_uiDieTimer = 500; + m_uiNatureBomb_Timer = 10000; + }else m_uiNatureBomb_Timer -= uiDiff; + + if(m_uiDieTimer < uiDiff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false); + else m_uiDieTimer -= uiDiff; + } + + // EONAR GIFT + if(m_bNpcEonarsGift) + { + if (m_uiGrow_Timer > 500 && m_fSize < 1.5) + { + m_fSize += float(m_uiGrow_Timer)/8000; + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fSize); + m_uiGrow_Timer = 0; + }else m_uiGrow_Timer += uiDiff; + + if(m_uiEonarsGift_Timer < uiDiff) + { + if (Creature* pFreya = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_FREYA))) + DoCast(pFreya, m_bIsRegularMode ? SPELL_LIFEBINDERS_GIFT : SPELL_LIFEBINDERS_GIFT_H); + m_uiEonarsGift_Timer = 1000; + }else m_uiEonarsGift_Timer -= uiDiff; + + if(m_uiNonSelectable_Timer < uiDiff && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(m_creature, SPELL_PHEROMONES_LG); + }else m_uiNonSelectable_Timer -= uiDiff; + } + + // HEALTHY SPORE + if(m_bNpcHealthySpore) + { + if(!m_bHasGrow && m_fSize < 0.25) + m_creature->ForcedDespawn(); + + if(m_uiHealthyGrow_Timer < uiDiff) + { + if(m_bHasGrow) + { + m_fSize = float(urand(150,225))/100; + m_bHasGrow = false; + } + else + m_fSize = float(urand(1,300))/100; + if(m_fSize < 1) + m_fSize = 0.1f; + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fSize); + m_uiHealthyGrow_Timer = urand(3000,5000); + }else m_uiHealthyGrow_Timer -= uiDiff; + } + + // SUN BEAM + if(m_bNpcSunBeamBright) + { + if(m_uiUnstableEnergy_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY : SPELL_UNSTABLE_ENERGY_H); + m_uiUnstableEnergy_Timer = 1000; + }else m_uiUnstableEnergy_Timer -= uiDiff; + } + + if(m_bNpcSunBeamFreya || m_bNpcSunBeamBright) + { + if(m_uiSunBeamDespawn_Timer < uiDiff) + m_creature->ForcedDespawn(); + else m_uiSunBeamDespawn_Timer -= uiDiff; + } + } +}; + +// Script for Freya's adds +struct MANGOS_DLL_DECL mob_freya_spawnedAI : public ScriptedAI +{ + mob_freya_spawnedAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + bool m_bAncientConservator; + bool m_bDetonatingLasher; + bool m_bAncientWaterSpirit; + bool m_bStormLasher; + bool m_bSnaplasher; + bool m_bHasExploded; + + uint32 m_uiDeathCountdown; + uint32 m_uiTidalWave_Timer; + uint32 m_uiStormbolt_Timer; + uint32 m_uiLightningLash_Timer; + uint32 m_uiFlameLash_Timer; + uint32 m_uiNaturesFury_Timer; + uint32 m_uiWave3_DeathCountdown; + uint32 m_uiRespawnSpores_Timer; + uint32 m_uiDieTimer; + uint8 m_uiHealthMultiplier; + + void Reset() + { + m_bAncientWaterSpirit = false; + m_bStormLasher = false; + m_bSnaplasher = false; + m_bAncientConservator = false; + m_bDetonatingLasher = false; + m_bHasExploded = false; + m_uiDieTimer = 120000; + m_uiDeathCountdown = 10000; + m_uiTidalWave_Timer = urand(2000,4000); + m_uiStormbolt_Timer = 1000; + m_uiLightningLash_Timer = urand(11000,14000); + m_uiFlameLash_Timer = urand(5000,10000); + m_uiNaturesFury_Timer = urand(8000,10000); + m_uiRespawnSpores_Timer = 5000; + m_uiHealthMultiplier = 1; + + switch(m_creature->GetEntry()) + { + // The Conservator's Grip needs core fix. It should be canceled by pheronomes! + case NPC_ANCIENT_CONSERVATOR: + m_bAncientConservator = true; + //DoCast(m_creature, SPELL_CONSERVATORS_GRIP); //spell disabled because it isn't negated by pheronomes + DoSpores(10); + break; + case NPC_DETONATING_LASHER: + m_bDetonatingLasher = true; + break; + case NPC_WATER_SPIRIT: + m_bAncientWaterSpirit = true; + break; + case NPC_SNAPLASHER: + m_bSnaplasher = true; + DoCast(m_creature, m_bIsRegularMode ? SPELL_HARDENED_BARK : SPELL_HARDENED_BARK_H); + break; + case NPC_STORM_LASHER: + m_bStormLasher = true; + break; + } + m_creature->SetRespawnDelay(DAY); + } + + void JustDied(Unit* Killer) + { + // remove some stacks from Freya's aura + // hacky way. Should be done by spell which needs core support + if (m_bAncientConservator) + { + if (Creature* pFreya = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_FREYA))) + { + if(SpellAuraHolder* natureAura = pFreya->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE)) + { + if(natureAura->ModStackAmount(-25)) + m_creature->RemoveAurasDueToSpell(SPELL_ATTUNED_TO_NATURE); + } + } + } + + if (m_bDetonatingLasher) + { + if (Creature* pFreya = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_FREYA))) + { + if(SpellAuraHolder* natureAura = pFreya->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE)) + { + if(natureAura->ModStackAmount(-2)) + m_creature->RemoveAurasDueToSpell(SPELL_ATTUNED_TO_NATURE); + } + } + } + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if (m_bDetonatingLasher && uiDamage > m_creature->GetHealth() && !m_bHasExploded) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_DETONATE : SPELL_DETONATE_H); + uiDamage = 0; + m_bHasExploded = true; + m_uiDieTimer = 500; + } + } + + void DoSpores(int8 times) + { + for(int8 i = 0; i < times; ++i) + { + for(int8 itr = 0; i < 3; ++i) + DoCast(m_creature, SPELL_SPORE_SUMMON_NE + itr); + DoCast(m_creature, SPELL_SPORE_SUMMON_NW); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_FREYA) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if(!m_creature->isAlive()) + return; + + // DETONATING LASHERS + if(m_bDetonatingLasher) + { + if(m_uiFlameLash_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_FLAME_LASH); + m_uiFlameLash_Timer = urand(5000,10000); + }else m_uiFlameLash_Timer -= uiDiff; + + if(m_uiDieTimer < uiDiff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false); + else m_uiDieTimer -= uiDiff; + } + + // CONSERVATOR + if(m_bAncientConservator) + { + if(m_uiNaturesFury_Timer < uiDiff) + { + DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_NATURES_FURY : SPELL_NATURES_FURY_H); + m_uiNaturesFury_Timer = urand(5000,6000); + }else m_uiNaturesFury_Timer -= uiDiff; + + if(m_uiRespawnSpores_Timer < uiDiff) + { + DoSpores(3); + m_uiRespawnSpores_Timer = 5000; + }else m_uiRespawnSpores_Timer -= uiDiff; + } + + // ELEMENTAL ADDS + // waterspirit + if(m_bAncientWaterSpirit && m_uiTidalWave_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_TIDAL_WAVE : SPELL_TIDAL_WAVE_H); + m_uiTidalWave_Timer = urand(7000,9000); + }else m_uiTidalWave_Timer -= uiDiff; + + // stormlasher + if(m_bStormLasher) + { + if (m_uiLightningLash_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_LIGHTNING_LASH : SPELL_LIGHTNING_LASH_H); + m_uiLightningLash_Timer = urand(11000,14000); + } + else + { + m_uiLightningLash_Timer -= uiDiff; + if (m_uiStormbolt_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_STORMBOLT : SPELL_STORMBOLT_H); + m_uiStormbolt_Timer = 2000; + }else m_uiStormbolt_Timer -= uiDiff; + } + } + + DoMeleeAttackIfReady(); + } }; +CreatureAI* GetAI_mob_freya_ground(Creature* pCreature) +{ + return new mob_freya_groundAI(pCreature); +} + +CreatureAI* GetAI_mob_freya_spawned(Creature* pCreature) +{ + return new mob_freya_spawnedAI(pCreature); +} + +CreatureAI* GetAI_mob_iron_roots(Creature* pCreature) +{ + return new mob_iron_rootsAI(pCreature); +} + void AddSC_boss_freya() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_freya"; + newscript->GetAI = &GetAI_boss_freya; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_elder_brightleaf"; + newscript->GetAI = &GetAI_boss_elder_brightleaf; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_elder_ironbranch"; + newscript->GetAI = &GetAI_boss_elder_ironbranch; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_elder_stonebark"; + newscript->GetAI = &GetAI_boss_elder_stonebark; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_freya_ground"; + newscript->GetAI = &GetAI_mob_freya_ground; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_freya_spawned"; + newscript->GetAI = &GetAI_mob_freya_spawned; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "mob_iron_roots"; + newscript->GetAI = &GetAI_mob_iron_roots; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp b/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp index 42ada8591..cc4fb8f86 100644 --- a/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,9 +15,9 @@ */ /* ScriptData -SDName: boss_general_vezax -SD%Complete: 0% -SDComment: +SDName: boss_vezax +SD%Complete: +SDComment: mark of the faceless needs core support. Searing flames needs fixing, cannot be interrupted SDCategory: Ulduar EndScriptData */ @@ -26,20 +26,461 @@ EndScriptData */ enum { - SAY_AGGRO = -1603096, - SAY_SLAY_1 = -1603097, - SAY_SLAY_2 = -1603098, - SAY_SURGE = -1603099, - SAY_DEATH = -1603100, - SAY_ENRAGE = -1603101, - SAY_HARD_MODE = -1603102, - - EMOTE_VAPOR = -1603103, - EMOTE_SURGE = -1603104, - EMOTE_ANIMUS = -1603105, + SAY_AGGRO = -1603120, + SAY_SURGE = -1603123, + SAY_HARD = -1603126, + SAY_SLAY1 = -1603121, + SAY_SLAY2 = -1603122, + SAY_BERSERK = -1603125, + SAY_DEATH = -1603124, + EMOTE_VAPORS = -1603366, + EMOTE_SURGE = -1603367, + EMOTE_ANIMUS = -1603368, + + SPELL_AURA_OF_DESPAIR = 62692, + SPELL_SHADOW_CRASH = 62660, + SPELL_MARK_OF_FACELESS = 63276, + SPELL_MARK_SIMPHON = 63278, + SPELL_SEARING_FLAMES = 62661, + SPELL_SURGE_OF_DARKNESS = 62662, + SPELL_BERSERK = 26662, + SPELL_SARONITE_BARRIER = 63364, + SPELL_SUMMON_ANIMUS = 63145, + SPELL_SUMMON_VAPORS = 63081, + + NPC_SARONITE_VAPOR = 33488, + SPELL_SARONITE_VAPORS = 63323, + + NPC_SARONITE_ANIMUS = 33524, + SPELL_PROFOUND_DARKNESS = 63420, + SPELL_ANIMUS_FORMATION = 63319, + + ACHIEV_MORNING_SARONITE = 3181, + ACHIEV_MORNING_SARONITE_H = 3188, +}; + +uint8 m_uiSaroniteVaporCount; + +struct MANGOS_DLL_DECL boss_vezaxAI : public ScriptedAI +{ + boss_vezaxAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiEnrageTimer; + uint32 m_uiCrashTimer; + uint32 m_uiMarkTimer; + uint32 m_uiFlamesTimer; + uint32 m_uiSurgeTimer; + uint32 m_uiSaroniteVaporTimer; + uint32 m_uiSimphonTimer; + uint32 m_uiEndSimphonTimer; + uint32 m_uiSummonAnimusTimer; + uint64 m_uiAnimusGUID; + uint64 m_uiMarkTargetGUID; + uint32 m_uiMarkCheckTimer; + uint32 m_uiMarkEndTimer; + + std::list lVapors; + + bool m_bIsHardMode; + bool m_bActiveHardMode; + bool m_bHasMark; + bool m_bHasSimphon; + bool m_bIsAnimusAlive; + + void Reset() + { + m_uiEnrageTimer = 600000; //10 minutes + m_uiFlamesTimer = urand(8000, 10000); + m_uiSaroniteVaporTimer = 30000; + m_bIsHardMode = false; + m_bActiveHardMode = false; + m_bHasMark = false; + m_bHasSimphon = false; + m_bIsAnimusAlive = false; + + m_uiSurgeTimer = 60000; + m_uiMarkTimer = urand(10000, 35000); + m_uiCrashTimer = 10000; + m_uiSimphonTimer = 1000; + m_uiEndSimphonTimer = 10000; + m_uiAnimusGUID = 0; + m_uiMarkTargetGUID = 0; + + lVapors.clear(); + + m_uiSaroniteVaporCount = 0; + } + + void Aggro(Unit *who) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_VEZAX, IN_PROGRESS); + + DoCast(m_creature, SPELL_AURA_OF_DESPAIR); + + DoScriptText(SAY_AGGRO, m_creature); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_VEZAX, FAIL); + + m_creature->RemoveAurasDueToSpell(SPELL_SARONITE_BARRIER); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_VEZAX, DONE); + + if(m_bIsHardMode) + { + m_pInstance->SetData(TYPE_VEZAX_HARD, DONE); + + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_MORNING_SARONITE : ACHIEV_MORNING_SARONITE_H); + // hack used when the hard mode loot is within the Animus corpse + // PLEASE REMOVE FOR REVISION + if(Creature* pAnimus = m_pInstance->instance->GetCreature(m_uiAnimusGUID)) + pAnimus->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + + DoScriptText(SAY_DEATH, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY1, m_creature); + else + DoScriptText(SAY_SLAY2, m_creature); + } + + void PrepareHardMode() + { + m_bActiveHardMode = true; + m_uiSummonAnimusTimer = 7000; + + GetCreatureListWithEntryInGrid(lVapors, m_creature, NPC_SARONITE_VAPOR, 200.0f); + + if (!lVapors.empty()) + { + // vapors need more speed + for(std::list::iterator iter = lVapors.begin(); iter != lVapors.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + { + (*iter)->RemoveAllAuras(); + (*iter)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + (*iter)->SetSpeedRate(MOVE_RUN, 3.0f); + (*iter)->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + (*iter)->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); + } + } + } + } + + void ActivateHardMode() + { + m_creature->CastStop(); + DoCast(m_creature, SPELL_SARONITE_BARRIER); + //DoCast(m_creature, SPELL_SUMMON_ANIMUS); // make it by summon creature because of better handling the auras + DoScriptText(EMOTE_ANIMUS, m_creature); + DoScriptText(SAY_HARD, m_creature); + + if(Creature* pAnimus = m_creature->SummonCreature(NPC_SARONITE_ANIMUS, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 900000)) + { + pAnimus->SetInCombatWithZone(); + m_uiAnimusGUID = pAnimus->GetGUID(); + } + + if (!lVapors.empty()) + { + for(std::list::iterator iter = lVapors.begin(); iter != lVapors.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->ForcedDespawn(); + } + } + + m_bIsHardMode = true; + m_bIsAnimusAlive = true; + } + + // hacky way for the mark of the faceless, needs core support + // PLEASE REMOVE FOR REVISION! + void CheckForMark(uint64 m_uiTargetGUID) + { + if(m_uiTargetGUID == 0) + return; + + m_bHasSimphon = false; + Map *map = m_creature->GetMap(); + Unit* pTarget = m_creature->GetMap()->GetUnit( m_uiTargetGUID); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if(pTarget && pTarget->isAlive() && !m_bHasSimphon && m_uiTargetGUID != i->getSource()->GetGUID()) + { + if (i->getSource()->isAlive() && pTarget->GetDistance2d(i->getSource()) < 10.0f) + { + DoCast(pTarget, SPELL_MARK_SIMPHON); + m_bHasSimphon = true; + } + } + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // prepare hard mode + if(m_uiSaroniteVaporCount == 6 && !m_bIsHardMode && !m_bActiveHardMode) + PrepareHardMode(); + + // summon animus + if(m_uiSummonAnimusTimer < uiDiff && !m_bIsHardMode && m_bActiveHardMode) + ActivateHardMode(); + else m_uiSummonAnimusTimer -= uiDiff; + + // saronite vapor + if(m_uiSaroniteVaporTimer < uiDiff && !m_bIsHardMode) + { + m_creature->CastStop(); + DoCast(m_creature, SPELL_SUMMON_VAPORS); + DoScriptText(EMOTE_VAPORS, m_creature); + m_uiSaroniteVaporCount += 1; + m_uiSaroniteVaporTimer = 30000; + } + else m_uiSaroniteVaporTimer -= uiDiff; + + // searing flames + if(m_uiFlamesTimer < uiDiff && !m_bIsAnimusAlive) + { + DoCast(m_creature, SPELL_SEARING_FLAMES); + m_uiFlamesTimer = urand(5000, 10000); + } + else m_uiFlamesTimer -= uiDiff; + + // surge of darkness + if(m_uiSurgeTimer < uiDiff) + { + m_creature->CastStop(); + DoScriptText(SAY_SURGE, m_creature); + DoScriptText(EMOTE_SURGE, m_creature); + DoCast(m_creature, SPELL_SURGE_OF_DARKNESS); + m_uiSurgeTimer = 60000; + } + else m_uiSurgeTimer -= uiDiff; + + // mark of faceless + if(m_uiMarkTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + m_uiMarkTargetGUID = pTarget->GetGUID(); + DoCast(pTarget, SPELL_MARK_OF_FACELESS); + } + m_bHasMark = true; + m_uiMarkCheckTimer = 1000; + m_uiMarkEndTimer = 10000; + m_uiMarkTimer = urand(25000, 30000); + } + else m_uiMarkTimer -= uiDiff; + + // HACK FOR MARK OF THE FACELESS + // mark check ending + if(m_uiMarkEndTimer < uiDiff && m_bHasMark) + m_bHasMark = false; + else m_uiMarkEndTimer -= uiDiff; + + // simphon life every sec + if(m_uiMarkCheckTimer < uiDiff && m_bHasMark) + { + CheckForMark(m_uiMarkTargetGUID); + m_uiMarkCheckTimer = 1000; + } + else m_uiMarkCheckTimer -= uiDiff; + + // shadow crash + if(m_uiCrashTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + DoCast(pTarget, SPELL_SHADOW_CRASH); + m_uiCrashTimer = 10000; + } + else m_uiCrashTimer -= uiDiff; + + // enrage 10 min + if(m_uiEnrageTimer < uiDiff) + { + DoScriptText(SAY_BERSERK, m_creature); + DoCast(m_creature, SPELL_BERSERK); + m_uiEnrageTimer = 30000; + } + else m_uiEnrageTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +// Saronite animus +struct MANGOS_DLL_DECL mob_saronite_animusAI : public ScriptedAI +{ + mob_saronite_animusAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiProfoundDarknessTimer; + + void Reset() + { + m_uiProfoundDarknessTimer = 3000; + DoCast(m_creature, SPELL_ANIMUS_FORMATION); + m_creature->SetRespawnDelay(DAY); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) + { + if (Creature* pVezax = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_VEZAX))) + { + if (pVezax->isAlive()) + { + pVezax->RemoveAurasDueToSpell(SPELL_SARONITE_BARRIER); + ((boss_vezaxAI*)pVezax->AI())->m_bIsAnimusAlive = false; + } + } + } + // used for hard mode loot + // REMOVE THIS FOR REVISION + //m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_VEZAX) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiProfoundDarknessTimer < uiDiff) + { + DoCast(m_creature, SPELL_PROFOUND_DARKNESS); + m_uiProfoundDarknessTimer = urand(2000, 3000); + } + else m_uiProfoundDarknessTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_saronite_vaporAI : public ScriptedAI +{ + mob_saronite_vaporAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiDieTimer; + + void Reset() + { + m_uiDieTimer = 600000; + m_creature->SetRespawnDelay(DAY); + } + + void AttackStart(Unit *pWho) + { + return; + } + + void JustDied(Unit *killer) + { + m_uiSaroniteVaporCount -= 1; + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + // Mana regen pool + if(uiDamage >= m_creature->GetHealth()) + { + uiDamage = 0; + m_uiDieTimer = 500; + DoCast(m_creature, SPELL_SARONITE_VAPORS); + } + } + + void UpdateAI(const uint32 diff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_VEZAX) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_uiDieTimer < diff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDieTimer -= diff; + } }; -void AddSC_boss_general_vezax() +CreatureAI* GetAI_boss_vezax(Creature* pCreature) { + return new boss_vezaxAI(pCreature); +} + +CreatureAI* GetAI_mob_saronite_animus(Creature* pCreature) +{ + return new mob_saronite_animusAI(pCreature); +} + +CreatureAI* GetAI_mob_saronite_vapor(Creature* pCreature) +{ + return new mob_saronite_vaporAI(pCreature); +} + +void AddSC_boss_vezax() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_vezax"; + newscript->GetAI = &GetAI_boss_vezax; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_saronite_animus"; + newscript->GetAI = &GetAI_mob_saronite_animus; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "mob_saronite_vapor"; + newscript->GetAI = &GetAI_mob_saronite_vapor; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_hodir.cpp b/scripts/northrend/ulduar/ulduar/boss_hodir.cpp index 49c4ca168..6a76ac0a4 100644 --- a/scripts/northrend/ulduar/ulduar/boss_hodir.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_hodir.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_hodir -SD%Complete: 0% -SDComment: +SD%Complete: 60% +SDComment:Auras needs core fix SDCategory: Ulduar EndScriptData */ @@ -26,20 +26,1073 @@ EndScriptData */ enum { - SAY_AGGRO = -1603086, - SAY_SLAY_1 = -1603087, - SAY_SLAY_2 = -1603088, - SAY_FLASH_FREEZE = -1603089, - SAY_FROZEN_BLOWS = -1603090, - SAY_DEATH = -1603091, - SAY_BERSERK = -1603092, - SAY_HELP_YOGG = -1603093, + SPELL_ENRAGE = 26662, - EMOTE_FLASH_FREEZE = -1603094, - EMOTE_FROZEN_BLOWS = -1603095, + SPELL_FROZEN_BLOWS = 62478, + SPELL_FROZEN_BLOWS_H = 63512, + SPELL_FREEZE = 62469, + SPELL_BITTER_COLD = 62038, // SPELL BROKEN!!!! + SPELL_ICICLE = 62460, // full spell -> needs core fix + SPELL_ICE_SHARDS = 65370, // icicle damage -> 14k + SPELL_ICICLE_DUMMY = 62453, + SPELL_SNOWDRIFT = 62463, + SPELL_FLASH_FREEZE = 61968, + SPELL_FLASH_FREEZE_VIS = 62148, + SPELL_FLASH_FREEZE_STUN = 64175, + SPELL_FLASH_FREEZE_KILL = 62226, + SPELL_FLASH_FREEZE_NPC_STUN = 61990, // used to freeze npcs + + NPC_SNOWDRIFT_TARGET = 33174, + NPC_ICICLE = 33169, + NPC_SNOW_ICICLE = 33173, + NPC_FLASH_FREEZE = 32926, + NPC_FLASH_FREEZE_NPC = 32938, + + SAY_AGGRO = -1603085, + SAY_DEATH = -1603084, + SAY_SLAY01 = -1603083, + SAY_SLAY02 = -1603082, + SAY_FLASH_FREEZE = -1603081, + SAY_FROZEN_BLOWS = -1603080, + SAY_BERSERK = -1603087, + EMOTE_FLASH_FREEZE = -1603360, + EMOTE_FROZEN_BLOWS = -1603361, + + ACHIEV_RARE_CACHE = 3182, + ACHIEV_RARE_CACHE_H = 3184, + ACHIEV_COOLEST_FRIEND = 2963, + ACHIEV_COOLEST_FRIEND_H = 2965, + ACHIEV_GETTING_COLD = 2967, + ACHIEV_GETTING_COLD_H = 2968, + ACHIEV_CHEESE_FREEZE = 2961, + ACHIEV_CHEESE_FREEZE_H = 2962, + + // helper npcs + // druid + SPELL_WRATH = 62793, + SPELL_STARLIGHT = 62807, // friendly + + // shaman + SPELL_LAVA_BURST = 61924, + SPELL_STORM_CLOUD = 65123, // friendly + SPELL_STORM_CLOUD_H = 65133, + SPELL_STORM_POWER = 65134, // friendly + + // mage + SPELL_FIREBALL = 61909, + SPELL_TOASTY_FIRE = 62823, // friendly -> summon + NPC_TOASTY_FIRE = 33342, + SPELL_TOASTY_FIRE_A = 62821, + SPELL_MELT_ICE = 64528, + SPELL_SIGNED = 65280, + + // priest + SPELL_SMITE = 61923, + SPELL_GREAT_HEAL = 62809, //friendly + SPELL_DISPEL_MAGIC = 63499, //friendly + +}; + +#define CENTER_X 2000.0f +#define CENTER_Y -234.21f + +bool m_bCoolestFriend; + +// script for Flash freeze +struct MANGOS_DLL_DECL mob_flashFreezeAI : public ScriptedAI +{ + mob_flashFreezeAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pCreature->SetDisplayId(11686); // make invisible + SetCombatMovement(false); + Reset(); + } + + bool m_bIsRegularMode; + uint64 m_uiVictimGUID; + + void Reset() + { + m_uiVictimGUID = 0; + if(m_bIsRegularMode) + m_creature->SetMaxHealth(35000); + m_creature->SetRespawnDelay(DAY); + } + + void Aggro(Unit* pWho) + { + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoCast(pWho, SPELL_FLASH_FREEZE_STUN); + pWho->CastSpell(pWho, SPELL_FLASH_FREEZE_STUN, false); + m_uiVictimGUID = pWho->GetGUID(); + // kill targets that are frozen + if(pWho->HasAura(SPELL_FREEZE, EFFECT_INDEX_0)) + { + pWho->CastSpell(pWho, SPELL_FLASH_FREEZE_KILL, false); + m_creature->ForcedDespawn(); + } + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim) + pVictim->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_STUN); + } + + void JustDied(Unit* Killer) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID)) + pVictim->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_STUN); + + if (Killer) + Killer->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_STUN); + } + + void UpdateAI(const uint32 diff) {} +}; + +// script for Icicles +struct MANGOS_DLL_DECL mob_icicleAI : public ScriptedAI +{ + mob_icicleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + SetCombatMovement(false); + pCreature->setFaction(14); + Reset(); + } + + uint32 m_uiSpellDelayTimer; + + void Reset() + { + DoCast(m_creature, SPELL_ICICLE); + m_uiSpellDelayTimer = 500; + } + + void AttackStart(Unit* pWho) + { + return; + } + + void UpdateAI(const uint32 diff) + { + if(m_uiSpellDelayTimer < diff) + { + DoCast(m_creature, SPELL_ICICLE_DUMMY); + m_uiSpellDelayTimer = 30000; + } + else m_uiSpellDelayTimer -= diff; + } +}; + +// Toasty fire. Used by mage +struct MANGOS_DLL_DECL mob_toasty_fireAI : public ScriptedAI +{ + mob_toasty_fireAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pCreature->SetDisplayId(11686); // make invisible + SetCombatMovement(false); + Reset(); + } + + void Reset() + { + DoCast(m_creature, SPELL_TOASTY_FIRE_A); + } + + void UpdateAI(const uint32 diff) {} +}; + +// Script for the Flash freeze which is enchasing the npcs in ice at the begginign of the fight +// this needs some fixing on spells +struct MANGOS_DLL_DECL mob_npc_flashFreezeAI : public ScriptedAI +{ + mob_npc_flashFreezeAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetDisplayId(25865); // invisible + pCreature->GetMotionMaster()->MoveIdle(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + std::list lVictims; + + void Reset() + { + lVictims.clear(); + SetVictim(); + DoCast(m_creature, SPELL_FLASH_FREEZE_NPC_STUN); + } + + void Aggro(Unit *who) + { + if (Creature* pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f)) + { + pHodir->AI()->AttackStart(who); + pHodir->AddThreat(who, 0.0f); + } + } + + void SetVictim() + { + // druids + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33325, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32901, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32941, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33333, 2.0f); + // shamys + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33328, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32900, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33332, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32950, 2.0f); + // mages + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32893, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33327, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33331, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32946, 2.0f); + // priests + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32897, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33326, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 32948, 2.0f); + GetCreatureListWithEntryInGrid(lVictims, m_creature, 33330, 2.0f); + if (!lVictims.empty()) + { + for(std::list::iterator iter = lVictims.begin(); iter != lVictims.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive() && !(*iter)->HasAura(SPELL_FLASH_FREEZE_NPC_STUN, EFFECT_INDEX_0)) + (*iter)->CastSpell((*iter), SPELL_FLASH_FREEZE_NPC_STUN, false); + } + } + } + + void JustDied(Unit* Killer) + { + if (!lVictims.empty()) + { + for(std::list::iterator iter = lVictims.begin(); iter != lVictims.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive() && (*iter)->HasAura(SPELL_FLASH_FREEZE_NPC_STUN, EFFECT_INDEX_0)) + { + (*iter)->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_NPC_STUN); + if (Creature* pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f)) + (*iter)->AddThreat(pHodir, 100.0f); + } + } + } + } + + void UpdateAI(const uint32 diff) + { } +}; + +// Hodir +struct MANGOS_DLL_DECL boss_hodirAI : public ScriptedAI +{ + boss_hodirAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + // hard mode timer + uint32 m_uiSpeedKillTimer; + + uint32 m_uiEnrageTimer; + uint32 m_uiFlashFreezeTimer; + uint32 m_uiFlashFreezeCastTimer; + uint32 m_uiFrozenBlowsTimer; + uint32 m_uiFreezeTimer; + uint32 m_uiIcicleTimer; + uint8 m_uiIcicleCount; + bool m_bIsCheese; + + bool m_bIsOutro; + uint32 m_uiOutroTimer; + uint32 m_uiStep; + + std::list lFriends; + + void Reset() + { + m_uiSpeedKillTimer = 0; + m_bCoolestFriend = true; + m_uiEnrageTimer = 480000; + m_uiFlashFreezeTimer = 50000; + m_uiFlashFreezeCastTimer= 90000; + m_uiFrozenBlowsTimer = 60000; + m_uiFreezeTimer = urand(15000, 20000); + m_uiIcicleTimer = 10000; + m_uiIcicleCount = 0; + m_uiOutroTimer = 10000; + m_uiStep = 1; + m_bIsOutro = false; + m_bIsCheese = true; + + // respawn friendly npcs + // druids + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33325, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32901, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32941, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33333, DEFAULT_VISIBILITY_INSTANCE); + // shamys + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33328, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32900, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33332, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32950, DEFAULT_VISIBILITY_INSTANCE); + // mages + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32893, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33327, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33331, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32946, DEFAULT_VISIBILITY_INSTANCE); + // priests + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32897, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33326, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32948, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFriends, m_creature, 33330, DEFAULT_VISIBILITY_INSTANCE); + // flash freeze for them: + GetCreatureListWithEntryInGrid(lFriends, m_creature, 32938, DEFAULT_VISIBILITY_INSTANCE); + if (!lFriends.empty()) + { + for(std::list::iterator iter = lFriends.begin(); iter != lFriends.end(); ++iter) + { + if ((*iter) && !(*iter)->isAlive()) + (*iter)->Respawn(); + } + } + } + + void JustReachedHome() + { + if(m_pInstance) + m_pInstance->SetData(TYPE_HODIR, NOT_STARTED); + } + + void Aggro(Unit *who) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_HODIR, IN_PROGRESS); + + DoScriptText(SAY_AGGRO, m_creature); + + DoCast(m_creature, SPELL_BITTER_COLD); + } + + void DoOutro() + { + if(m_pInstance) + { + if(m_uiSpeedKillTimer < 180000) + { + m_pInstance->SetData(TYPE_HODIR_HARD, DONE); + m_pInstance->SetData(TYPE_HODIR, DONE); + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_RARE_CACHE : ACHIEV_RARE_CACHE_H); + } + else + m_pInstance->SetData(TYPE_HODIR, DONE); + + // hacky way to complete achievements; use only if you have this function + if (m_bCoolestFriend) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_COOLEST_FRIEND : ACHIEV_COOLEST_FRIEND_H); + + if (m_bIsCheese) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHEESE_FREEZE : ACHIEV_CHEESE_FREEZE_H); + } + m_creature->ForcedDespawn(); + } + + // for debug only + void JustDied(Unit* pKiller) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_HODIR, DONE); + if(m_uiSpeedKillTimer > 0) + m_pInstance->SetData(TYPE_HODIR_HARD, DONE); + } + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(m_creature->GetHealthPercent() < 1.0f) + { + uiDamage = 0; + m_bIsOutro = true; + } + } + + void KilledUnit(Unit *who) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY01, m_creature); + else + DoScriptText(SAY_SLAY02, m_creature); + } + + // Flash freeze. Hacky way, needs core support + // PLEASE REMOVE FOR REVISION! + void DoFlashFreeze() + { + std::list lSnowdrift; + GetCreatureListWithEntryInGrid(lSnowdrift, m_creature, NPC_SNOWDRIFT_TARGET, DEFAULT_VISIBILITY_INSTANCE); + + Map* pMap = m_creature->GetMap(); + if(pMap) + { + Map::PlayerList const &lPlayers = pMap->GetPlayers(); + if (!lPlayers.isEmpty()) + { + for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + { + if(pPlayer && pPlayer->isAlive()) + { + if (!lSnowdrift.empty()) + { + for(std::list::iterator iter = lSnowdrift.begin(); iter != lSnowdrift.end(); ++iter) + { + if ((*iter) && pPlayer->GetDistance2d((*iter)) > 5.0f) + { + if(Creature* pTemp = m_creature->SummonCreature(NPC_FLASH_FREEZE, pPlayer->GetPositionX(), pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000)) + pTemp->AddThreat(pPlayer, 100.0f); + // don't complete achievement + m_bIsCheese = false; + } + } + } + else + { + if(Creature* pTemp = m_creature->SummonCreature(NPC_FLASH_FREEZE, pPlayer->GetPositionX(), pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000)) + pTemp->AddThreat(pPlayer, 100.0f); + } + } + } + } + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if(!m_bIsOutro) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // reset if fighting only the npcs + // this gets bugged if some of the npcs get top aggro + if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) + EnterEvadeMode(); + + // hard mode check + m_uiSpeedKillTimer += uiDiff; + + // Flash freeze visual + if(m_uiFlashFreezeTimer < uiDiff) + { + DoScriptText(EMOTE_FLASH_FREEZE, m_creature); + DoScriptText(SAY_FLASH_FREEZE, m_creature); + DoCast(m_creature, SPELL_FLASH_FREEZE); + m_uiFlashFreezeTimer = 50000; + m_uiFlashFreezeCastTimer = 9000; + } + else m_uiFlashFreezeTimer -= uiDiff; + + // hacky way for flash freeze + if (m_uiFlashFreezeCastTimer < uiDiff) + { + DoFlashFreeze(); + DoCast(m_creature, SPELL_FLASH_FREEZE_VIS); + m_uiFlashFreezeCastTimer = 90000; + } + else m_uiFlashFreezeCastTimer -= uiDiff; + + // icicles + // should be done be spell + if(m_uiIcicleTimer < uiDiff) + { + float angle = (float) rand()*360/RAND_MAX + 1; + float homeX = CENTER_X + urand(0, 30)*cos(angle*(M_PI/180)); + float homeY = CENTER_Y + urand(0, 30)*sin(angle*(M_PI/180)); + m_creature->SummonCreature(NPC_ICICLE, homeX, homeY, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 3000); + m_uiIcicleTimer = urand(2000, 5000); + } + else m_uiIcicleTimer -= uiDiff; + + // frozen blows + if(m_uiFrozenBlowsTimer < uiDiff) + { + DoScriptText(SAY_FROZEN_BLOWS, m_creature); + DoScriptText(EMOTE_FROZEN_BLOWS, m_creature); + DoCast(m_creature, m_bIsRegularMode ? SPELL_FROZEN_BLOWS : SPELL_FROZEN_BLOWS_H); + m_uiFrozenBlowsTimer = urand(50000, 60000); + } + else m_uiFrozenBlowsTimer -= uiDiff; + + // freeze + if(m_uiFreezeTimer < uiDiff) + { + if(Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(target, SPELL_FREEZE); + m_uiFreezeTimer = urand(5000, 10000); + } + else m_uiFreezeTimer -= uiDiff; + + // enrage + if(m_uiEnrageTimer < uiDiff) + { + DoScriptText(SAY_BERSERK, m_creature); + DoCast(m_creature, SPELL_ENRAGE); + m_uiEnrageTimer = 30000; + } + else m_uiEnrageTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + // outro + if(m_bIsOutro) + { + switch(m_uiStep) + { + case 1: + m_creature->setFaction(35); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->InterruptNonMeleeSpells(false); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->MovePoint(0, 1984.64f, -206.37f, 432.68f); + ++m_uiStep; + m_uiOutroTimer = 10000; + break; + case 3: + DoScriptText(SAY_DEATH, m_creature); + ++m_uiStep; + m_uiOutroTimer = 5000; + break; + case 5: + DoOutro(); + ++m_uiStep; + m_uiOutroTimer = 10000; + break; + } + } + else return; + + if (m_uiOutroTimer <= uiDiff) + { + ++m_uiStep; + m_uiOutroTimer = 330000; + } m_uiOutroTimer -= uiDiff; + } }; +// Helper npcs +struct MANGOS_DLL_DECL npc_hodir_druidAI : public ScriptedAI +{ + npc_hodir_druidAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + uint32 spellTimer; + std::list FriendlyList; + + void Reset() + { + spellTimer = 5000; + FriendlyList.clear(); + } + + void JustDied(Unit* pKiller) + { + m_bCoolestFriend = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + // friendly list + if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true)) + FriendlyList.push_back(pWho->GetGUID()); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho, 20.0f); + } + } + + uint64 SelectRandomPlayer() + { + //This should not appear! + if (FriendlyList.empty()){ + spellTimer = 5000; + return m_creature->GetGUID(); + } + + std::list::iterator iter = FriendlyList.begin(); + advance(iter, urand(0, FriendlyList.size()-1)); + + return *iter; + } + + bool ListContains(std::list &plist, uint64 element) + { + if (plist.empty()) + return false; + + std::list::iterator i; + for (i = plist.begin(); i!=plist.end(); ++i) + { + if ((*i) == element) + return true; + } + return false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (spellTimer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: + if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f)) + DoCast(pHodir, SPELL_WRATH); + break; + case 1: + Unit *pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer())); + if (pTemp && pTemp->isAlive() && m_creature->GetDistance(pTemp) < 40) + DoCast(pTemp, SPELL_STARLIGHT); + break; + } + spellTimer = urand(2000, 5000); + }else spellTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_hodir_druid(Creature* pCreature) +{ + return new npc_hodir_druidAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_hodir_shamanAI : public ScriptedAI +{ + npc_hodir_shamanAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance *pInstance; + + uint32 spellTimer; + std::list FriendlyList; + + void Reset() + { + spellTimer = 5000; + FriendlyList.clear(); + } + + void JustDied(Unit* pKiller) + { + m_bCoolestFriend = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + // friendly list + if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true)) + FriendlyList.push_back(pWho->GetGUID()); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho, 20.0f); + } + } + + uint64 SelectRandomPlayer() + { + //This should not appear! + if (FriendlyList.empty()){ + spellTimer = 5000; + return m_creature->GetGUID(); + } + + std::list::iterator iter = FriendlyList.begin(); + advance(iter, urand(0, FriendlyList.size()-1)); + + return *iter; + } + + bool ListContains(std::list &plist, uint64 element) + { + if (plist.empty()) + return false; + + std::list::iterator i; + for (i = plist.begin(); i!=plist.end(); ++i) + { + if ((*i) == element) + return true; + } + return false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (spellTimer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: + if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f)) + DoCast(pHodir, SPELL_LAVA_BURST); + break; + case 1: + Unit *pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer())); + if (pTemp && pTemp->isAlive() && m_creature->GetDistance(pTemp) < 40) + DoCast(pTemp, m_bIsRegularMode ? SPELL_STORM_CLOUD : SPELL_STORM_CLOUD_H); + break; + } + spellTimer = urand(2000,5000); + }else spellTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_hodir_shaman(Creature* pCreature) +{ + return new npc_hodir_shamanAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_hodir_mageAI : public ScriptedAI +{ + npc_hodir_mageAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + uint32 spellTimer; + std::list FriendlyList; + + void Reset() + { + spellTimer = 5000; + FriendlyList.clear(); + } + + void JustDied(Unit* pKiller) + { + m_bCoolestFriend = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + // friendly list + if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true)) + FriendlyList.push_back(pWho->GetGUID()); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho, 20.0f); + } + } + + uint64 SelectRandomPlayer() + { + //This should not appear! + if (FriendlyList.empty()){ + spellTimer = 5000; + return m_creature->GetGUID(); + } + + std::list::iterator iter = FriendlyList.begin(); + advance(iter, urand(0, FriendlyList.size()-1)); + + return *iter; + } + + bool ListContains(std::list &plist, uint64 element) + { + if (plist.empty()) + return false; + + std::list::iterator i; + for (i = plist.begin(); i!=plist.end(); ++i) + { + if ((*i) == element) + return true; + } + return false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (spellTimer < uiDiff) + { + switch(urand(0, 4)) + { + case 0: + if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f)) + DoCast(pHodir, SPELL_FIREBALL); + break; + case 1: + case 2: + if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f)) + DoCast(pHodir, SPELL_SIGNED); + break; + case 3: + if(Creature *pTemp = GetClosestCreatureWithEntry(m_creature, NPC_FLASH_FREEZE, 50.0f)) + DoCast(pTemp, SPELL_MELT_ICE); + break; + case 4: + Unit *pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer())); + if (pTemp && pTemp->isAlive() && m_creature->GetDistance(pTemp) < 40) + DoCast(pTemp, SPELL_TOASTY_FIRE); + break; + } + spellTimer = urand(2000,5000); + }else spellTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_hodir_mage(Creature* pCreature) +{ + return new npc_hodir_mageAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_hodir_priestAI : public ScriptedAI +{ + npc_hodir_priestAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance *pInstance; + + uint32 spellTimer; + std::list FriendlyList; + + void Reset() + { + spellTimer = 5000; + FriendlyList.clear(); + } + + void JustDied(Unit* pKiller) + { + m_bCoolestFriend = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + // friendly list + if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true)) + FriendlyList.push_back(pWho->GetGUID()); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho, 20.0f); + } + } + + uint64 SelectRandomPlayer() + { + //This should not appear! + if (FriendlyList.empty()){ + spellTimer = 5000; + return m_creature->GetGUID(); + } + + std::list::iterator iter = FriendlyList.begin(); + advance(iter, urand(0, FriendlyList.size()-1)); + + return *iter; + } + + bool ListContains(std::list &plist, uint64 element) + { + if (plist.empty()) + return false; + + std::list::iterator i; + for (i = plist.begin(); i!=plist.end(); ++i) + { + if ((*i) == element) + return true; + } + return false; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (spellTimer < uiDiff) + { + switch(urand(0, 4)) + { + case 0: + if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f)) + DoCast(pHodir, SPELL_SMITE); + break; + case 1: + case 2: + case 3: + if (Unit* pHealTarget = DoSelectLowestHpFriendly(40.0f)) + DoCast(pHealTarget, SPELL_GREAT_HEAL); + break; + case 4: + if (Unit* pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer()))) + DoCast(m_creature, SPELL_DISPEL_MAGIC); + break; + } + spellTimer = urand(2000,5000); + }else spellTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_hodir_priest(Creature* pCreature) +{ + return new npc_hodir_priestAI(pCreature); +} + +CreatureAI* GetAI_boss_hodir(Creature* pCreature) +{ + return new boss_hodirAI(pCreature); +} + +CreatureAI* GetAI_mob_flashFreeze(Creature* pCreature) +{ + return new mob_flashFreezeAI(pCreature); +} + +CreatureAI* GetAI_mob_icicle(Creature* pCreature) +{ + return new mob_icicleAI(pCreature); +} + +CreatureAI* GetAI_mob_toasty_fire(Creature* pCreature) +{ + return new mob_toasty_fireAI(pCreature); +} + +CreatureAI* GetAI_mob_npc_flashFreeze(Creature* pCreature) +{ + return new mob_npc_flashFreezeAI(pCreature); +} + void AddSC_boss_hodir() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_hodir"; + newscript->GetAI = &GetAI_boss_hodir; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_flashFreeze"; + newscript->GetAI = &GetAI_mob_flashFreeze; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_npc_flashFreeze"; + newscript->GetAI = &GetAI_mob_npc_flashFreeze; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_icicle"; + newscript->GetAI = &GetAI_mob_icicle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_toasty_fire"; + newscript->GetAI = &GetAI_mob_toasty_fire; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_hodir_priest"; + newscript->GetAI = &GetAI_npc_hodir_priest; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_hodir_mage"; + newscript->GetAI = &GetAI_npc_hodir_mage; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_hodir_druid"; + newscript->GetAI = &GetAI_npc_hodir_druid; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "npc_hodir_shaman"; + newscript->GetAI = &GetAI_npc_hodir_shaman; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_ignis.cpp b/scripts/northrend/ulduar/ulduar/boss_ignis.cpp index 59024c98a..5a82a7bc0 100644 --- a/scripts/northrend/ulduar/ulduar/boss_ignis.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_ignis.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_ignis -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: slag pot damage missing SDCategory: Ulduar EndScriptData */ @@ -26,20 +26,504 @@ EndScriptData */ enum { - SAY_AGGRO = -1603026, - SAY_SCORCH_1 = -1603027, - SAY_SCORCH_2 = -1603028, - SAY_SLAGPOT = -1603029, - SAY_ADDS = -1603030, - SAY_SLAY_1 = -1603031, - SAY_SLAY_2 = -1603032, - SAY_BERSERK = -1603033, - SAY_DEATH = -1603034, - - EMOTE_FLAME_JETS = -1603035, + //yells + SAY_AGGRO = -1603010, + SAY_SCORCH1 = -1603011, + SAY_SCORCH2 = -1603012, + SAY_SLAGPOT = -1603013, + EMOTE_FLAMEJETS = -1603014, + SAY_SUMMON = -1603015, + SAY_SLAY1 = -1603016, + SAY_SLAY2 = -1603017, + SAY_BERSERK = -1603018, + SAY_DEATH = -1603019, + + //ignis the furnace master + SPELL_FLAME_JETS = 62680, + SPELL_FLAME_JETS_H = 63472, + SPELL_SLAG_POT = 62717, + SPELL_SLAG_POT_H = 63477, + SPELL_SLAG_POT_DMG = 65722, + SPELL_SLAG_POT_DMG_H = 65723, + SPELL_SCORCH = 62546, + SPELL_SCORCH_H = 63474, + BUFF_STRENGHT_OF_CREATOR = 64473, + SPELL_STRENGHT_OF_CREATOR2 = 64474, + SPELL_STRENGHT_OF_CREATOR3 = 64475, + SPELL_HASTE = 66045, + SPELL_ENRAGE = 26662, + //iron construct + SPELL_HEAT = 65667, + SPELL_MOLTEN = 62373, + SPELL_BRITTLE = 62382, + SPELL_SHATTER = 62383, + //scorch target + AURA_SCORCH = 62548, + AURA_SCORCH_H = 63476, + AURA_HEAT = 65667, + SPELL_FREEZE_ANIM = 16245, + //NPC ids + MOB_IRON_CONSTRUCT = 33121, + MOB_SCORCH_TARGET = 33221, + + ACHIEV_STOKIN_THE_FURNACE = 2930, + ACHIEV_STOKIN_THE_FURNACE_H = 2929, + ACHIEV_SHATTERED = 2925, + ACHIEV_SHATTERED_H = 2926, +}; + +#define HOME_X 586.747009f +#define HOME_Y 381.997986f + +// scorch target +struct MANGOS_DLL_DECL mob_scorch_targetAI : public ScriptedAI +{ + mob_scorch_targetAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiDeath_Timer; + + void Reset() + { + m_uiDeath_Timer = 55000; + m_creature->SetDisplayId(11686); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, m_bIsRegularMode ? AURA_SCORCH : AURA_SCORCH_H); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + if (m_uiDeath_Timer < diff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDeath_Timer -= diff; + } +}; + +CreatureAI* GetAI_mob_scorch_target(Creature* pCreature) +{ + return new mob_scorch_targetAI(pCreature); +} + +// iron construct +struct MANGOS_DLL_DECL mob_iron_constructAI : public ScriptedAI +{ + mob_iron_constructAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiDeath_Timer; + uint32 m_uiAura_Check_Timer; + uint32 m_uiScorchTimer; + uint32 m_uiMoltenTimer; + uint32 m_uiBrittleTimer; + bool m_bIsBrittle; + bool m_bIsShatter; + bool m_bIsMolten; + bool m_bIsInCombat; + + uint32 m_uiWaterCheckTimer; + + void Reset() + { + m_bIsShatter = false; + m_bIsBrittle = false; + m_bIsMolten = false; + m_bIsInCombat = false; + m_uiWaterCheckTimer = 1000; + m_uiScorchTimer = 5000; + m_uiAura_Check_Timer = 1000; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(m_creature, SPELL_FREEZE_ANIM); + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + // remove 1 stack of the buff from Ignis, hacky way, should be done by spell + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IGNIS))) + { + if (pTemp->isAlive()) + { + if (pTemp->HasAura(BUFF_STRENGHT_OF_CREATOR)) + { + if(SpellAuraHolder* strenght = pTemp->GetSpellAuraHolder(BUFF_STRENGHT_OF_CREATOR)) + { + if(strenght->ModStackAmount(-1)) + pTemp->RemoveAurasDueToSpell(BUFF_STRENGHT_OF_CREATOR); + } + } + } + } + } + + // shatter if is brittle + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if (m_bIsBrittle) + { + if (uiDamage > 5000) + { + DoCast(m_creature, SPELL_SHATTER); + m_bIsShatter = true; + m_bIsBrittle = false; + m_uiDeath_Timer = 500; + } + } + } + + void AttackStart(Unit* pWho) + { + if(!m_bIsInCombat) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } + } + + // set in combat + void GetInCombat() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (m_creature->HasAura(SPELL_FREEZE_ANIM, EFFECT_INDEX_0)) + m_creature->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM); + m_bIsInCombat = true; + + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IGNIS))) + { + if (pTemp->isAlive()) + { + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MovePoint(0, pTemp->GetPositionX(), pTemp->GetPositionY(), pTemp->GetPositionZ()); + + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + m_creature->AddThreat(pTarget,100.0f); + m_creature->AI()->AttackStart(pTarget); + m_creature->SetInCombatWithZone(); + } + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // death after casted shatter + if (m_uiDeath_Timer < uiDiff && m_bIsShatter) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDeath_Timer -= uiDiff; + + // check for aura + if (m_uiAura_Check_Timer < uiDiff && !m_bIsMolten) + { + if(Aura* aura = m_creature->GetAura(SPELL_HEAT,EFFECT_INDEX_0)) + { + if(aura->GetStackAmount() > 9) + { + DoCast(m_creature, SPELL_MOLTEN); + m_creature->RemoveAurasDueToSpell(SPELL_HEAT); + m_uiMoltenTimer = 30000; + m_bIsMolten = true; + } + } + m_uiAura_Check_Timer = 1000; + }else m_uiAura_Check_Timer -= uiDiff; + + //Water checks + if(m_bIsMolten) + { + // should work with Vmaps3 + if (m_uiWaterCheckTimer <= uiDiff) + { + if(m_creature->IsInWater()) + { + DoCast(m_creature, SPELL_BRITTLE); + m_bIsBrittle = true; + m_bIsMolten = false; + } + // workaround + /* else use workaround + if( m_creature->GetDistance2d(524.15f, 277.0f) < 18 || m_creature->GetDistance2d(648.5f, 277.0f) < 18) + { + DoCast(m_creature, SPELL_BRITTLE); + m_creature->RemoveAurasDueToSpell(SPELL_MOLTEN); + m_bIsBrittle = true; + m_bIsMolten = false; + }*/ + m_uiWaterCheckTimer = 500; + }else m_uiWaterCheckTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } }; +CreatureAI* GetAI_mob_iron_construct(Creature* pCreature) +{ + return new mob_iron_constructAI(pCreature); +} + +//ignis the furnace master +struct MANGOS_DLL_DECL boss_ignisAI : public ScriptedAI +{ + boss_ignisAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + std::list m_lIronConstructGUIDList; + + uint32 m_uiFlame_Jets_Timer; + uint32 m_uiSlag_Pot_Timer; + uint32 m_uiSlag_Pot_Dmg_Timer; + uint32 m_uiScorch_Timer; + uint32 m_uiSummon_Timer; + uint32 m_uiPotDmgCount; + uint32 m_uiEnrageTimer; + + uint64 m_uiPotTargetGUID; + std::list lConstructs; + + uint32 m_uiEncounterTimer; + bool m_bHasSlagPotCasted; + + void Reset() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + + m_uiFlame_Jets_Timer = 20000; + m_uiSlag_Pot_Timer = 25000; + m_uiSlag_Pot_Dmg_Timer = 26000; + m_uiScorch_Timer = 13000; + m_uiSummon_Timer = 10000; + m_uiEnrageTimer = 600000; // 10 MIN + m_uiPotDmgCount = 0; + m_uiPotTargetGUID = 0; + m_lIronConstructGUIDList.clear(); + + m_uiEncounterTimer = 0; + m_bHasSlagPotCasted = false; + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_IGNIS, DONE); + + DoScriptText(SAY_DEATH, m_creature); + + if (m_uiEncounterTimer < 240000) + { + // hacky way to complete achievements; use only if you have this function + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_STOKIN_THE_FURNACE : ACHIEV_STOKIN_THE_FURNACE_H); + } + } + + Creature* SelectRandomConstruct(float fRange) + { + std::list lConstructList; + GetCreatureListWithEntryInGrid(lConstructList, m_creature, MOB_IRON_CONSTRUCT, fRange); + + if (lConstructList.empty()){ + m_uiSummon_Timer = 5000; + return NULL; + } + + std::list::iterator iter = lConstructList.begin(); + advance(iter, urand(0, lConstructList.size()-1)); + + if((*iter)->isAlive()) + return *iter; + else + { + m_uiSummon_Timer = 500; + return NULL; + } + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY1, m_creature); + else + DoScriptText(SAY_SLAY2, m_creature); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_IGNIS, IN_PROGRESS); + + DoScriptText(SAY_AGGRO, m_creature); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_IGNIS, FAIL); + + // respawn constructs + GetCreatureListWithEntryInGrid(lConstructs, m_creature, MOB_IRON_CONSTRUCT, DEFAULT_VISIBILITY_INSTANCE); + if (!lConstructs.empty()) + { + for(std::list::iterator iter = lConstructs.begin(); iter != lConstructs.end(); ++iter) + { + if ((*iter) && !(*iter)->isAlive()) + (*iter)->Respawn(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + m_uiEncounterTimer += uiDiff; + + // enrage + if(m_uiEnrageTimer < uiDiff) + { + DoScriptText(SAY_BERSERK, m_creature); + DoCast(m_creature, SPELL_ENRAGE); + m_uiEnrageTimer = 30000; + } + else m_uiEnrageTimer -= uiDiff; + + if (m_uiFlame_Jets_Timer < uiDiff) + { + DoScriptText(EMOTE_FLAMEJETS, m_creature); + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_JETS : SPELL_FLAME_JETS_H); + m_uiFlame_Jets_Timer = 35000; + }else m_uiFlame_Jets_Timer -= uiDiff; + + // need vehicle support!!! + if (m_uiSlag_Pot_Timer < uiDiff) + { + DoScriptText(SAY_SLAGPOT, m_creature); + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + { + DoCast(target, m_bIsRegularMode ? SPELL_SLAG_POT : SPELL_SLAG_POT_H); + m_uiPotTargetGUID = target->GetGUID(); + } + m_uiSlag_Pot_Timer = 30000; + m_uiSlag_Pot_Dmg_Timer = 1000; + m_bHasSlagPotCasted = true; + m_uiPotDmgCount = 0; + }else m_uiSlag_Pot_Timer -= uiDiff; + + // hacky way of doing damage + if (m_uiSlag_Pot_Dmg_Timer < uiDiff && m_bHasSlagPotCasted) + { + if (Unit* pPotTarget = m_creature->GetMap()->GetUnit( m_uiPotTargetGUID)) + { + if (m_uiPotDmgCount < 10) + DoCast(pPotTarget, m_bIsRegularMode ? SPELL_SLAG_POT_DMG : SPELL_SLAG_POT_DMG_H); + else if (m_uiPotDmgCount == 10) + { + if(pPotTarget->isAlive()) + pPotTarget->CastSpell(pPotTarget, SPELL_HASTE, false); + m_bHasSlagPotCasted = false; + } + } + ++m_uiPotDmgCount; + m_uiSlag_Pot_Dmg_Timer = 1000; + }else m_uiSlag_Pot_Dmg_Timer -= uiDiff; + + // call the golems + if (m_uiSummon_Timer < uiDiff) + { + DoScriptText(SAY_SUMMON, m_creature); + + if(Creature* pConstruct = SelectRandomConstruct(200.0f)) + { + ((mob_iron_constructAI*)pConstruct->AI())->GetInCombat(); + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pConstruct->AddThreat(target, 100.0f); + } + + m_uiSummon_Timer = 40000; + + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, BUFF_STRENGHT_OF_CREATOR); + }else m_uiSummon_Timer -= uiDiff; + + if (m_uiScorch_Timer < uiDiff) + { + if(irand(0,1)) + DoScriptText(SAY_SCORCH1, m_creature); + else + DoScriptText(SAY_SCORCH2, m_creature); + + DoCast(m_creature, m_bIsRegularMode ? SPELL_SCORCH : SPELL_SCORCH_H); + if (Creature* pTemp = m_creature->SummonCreature(MOB_SCORCH_TARGET, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), m_creature->getVictim()->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + pTemp->AddThreat(m_creature->getVictim(),0.0f); + pTemp->AI()->AttackStart(m_creature->getVictim()); + } + m_uiScorch_Timer = 28000; + }else m_uiScorch_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + + if (m_creature->GetDistance2d(HOME_X, HOME_Y) > 200) + EnterEvadeMode(); + } +}; + +CreatureAI* GetAI_boss_ignis(Creature* pCreature) +{ + return new boss_ignisAI(pCreature); +} + void AddSC_boss_ignis() { + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "boss_ignis"; + NewScript->GetAI = GetAI_boss_ignis; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_scorch_target"; + NewScript->GetAI = &GetAI_mob_scorch_target; + NewScript->RegisterSelf(); + NewScript = new Script; + NewScript->Name = "mob_iron_construct"; + NewScript->GetAI = &GetAI_mob_iron_construct; + NewScript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp b/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp index feb672581..71b5d4980 100644 --- a/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_kologarn -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: stone grip and arms need vehicles SDCategory: Ulduar EndScriptData */ @@ -26,22 +26,608 @@ EndScriptData */ enum { - SAY_AGGRO = -1603126, - SAY_SHOCKWAVE = -1603127, - SAY_GRAB = -1603128, - SAY_ARM_LOST_LEFT = -1603129, - SAY_ARM_LOST_RIGHT = -1603130, - SAY_SLAY_1 = -1603131, - SAY_SLAY_2 = -1603132, - SAY_BERSERK = -1603133, - SAY_DEATH = -1603134, - - EMOTE_ARM_RIGHT = -1603135, - EMOTE_ARM_LEFT = -1603136, - EMOTE_STONE_GRIP = -1603137, + //yells + SAY_AGGRO = -1603150, + SAY_SHOCKWEAVE = -1603151, + SAY_GRAB = -1603152, + SAY_LEFT_ARM_LOST = -1603153, + SAY_RIGHT_ARM_LOST = -1603154, + SAY_SLAY1 = -1603155, + SAY_SLAY2 = -1603156, + SAY_BERSERK = -1603157, + SAY_DEATH = -1603158, + EMOTE_RIGHT_ARM = -1603355, + EMOTE_LEFT_ARM = -1603356, + EMOTE_STONE_GRIP = -1603357, + + //kologarn + SPELL_OVERHEAD_SMASH = 63356, + SPELL_OVERHEAD_SMASH_H = 64003, + SPELL_ONE_ARMED_SMASH = 63573, + SPELL_ONE_ARMED_SMASH_H = 64006, + SPELL_STONE_SHOUT = 63716, + SPELL_STONE_SHOUT_H = 64005, + SPELL_PETRIFYING_BREATH = 62030, + SPELL_PETRIFYING_BREATH_H = 63980, + SPELL_FOCUSED_EYEBEAM = 63346, + SPELL_FOCUSED_EYEBEAM_H = 63976, + SPELL_FOCUSED_EYEBEAM_TRIG = 63369, + SPELL_FOCUSED_EYEBEAM_VISUAL= 63368, + SPELL_ENRAGE = 26662, + //left arm + SPELL_SHOCKWAVE = 63783, + SPELL_SHOCKWAVE_H = 63982, + //right arm + SPELL_STONE_GRIP_GRAB = 63981, // not working + SPELL_STONE_GRIP = 64290, + SPELL_STONE_GRIP_H = 64292, + //both + SPELL_ARM_VISUAL = 64753, + //rubble + SPELL_RUMBLE = 63818, // on 10 man + SPELL_STONE_NOVA = 63978, // on 25 man + //NPC ids + MOB_RUBBLE = 33768, + + ACHIEV_RUBBLE_AND_ROLL = 2959, + ACHIEV_RUBBLE_AND_ROLL_H = 2960, + ACHIEV_WITH_OPEN_ARMS = 2951, + ACHIEV_WITH_OPEN_ARMS_H = 2952, + ACHIEV_DISARMED = 2953, + ACHIEV_DISARMED_H = 2954, + ACHIEV_IF_LOOKS_COULD_KILL = 2955, + ACHIEV_IF_LOOKS_COULD_KILL_H= 2956, +}; + +float LeftArm[3] = {1784.742f, -39.962f, 448.805f}; +float RightArm[3] = {1785.615f, -5.516f, 448.810f}; +const float KoloFront[3] = {1771.683f, -24.230f, 448.806f}; + +// Rubble +struct MANGOS_DLL_DECL mob_ulduar_rubbleAI : public ScriptedAI +{ + mob_ulduar_rubbleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiStone_Nova_Timer; + + void Reset() + { + m_uiStone_Nova_Timer = urand(8000, 12000); + m_creature->SetRespawnDelay(DAY); + } + + void UpdateAI(const uint32 diff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_KOLOGARN) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiStone_Nova_Timer < diff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_RUMBLE : SPELL_STONE_NOVA); + m_uiStone_Nova_Timer = urand(7000, 9000); + }else m_uiStone_Nova_Timer -= diff; + + DoMeleeAttackIfReady(); + } }; +CreatureAI* GetAI_mob_ulduar_rubble(Creature* pCreature) +{ + return new mob_ulduar_rubbleAI(pCreature); +} + +// Left Arm +struct MANGOS_DLL_DECL boss_left_armAI : public ScriptedAI +{ + boss_left_armAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiShockwave_Timer; + + void Reset() + { + m_uiShockwave_Timer = 30000; + DoCast(m_creature, SPELL_ARM_VISUAL); + m_creature->SetRespawnDelay(DAY); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN))) + { + DoScriptText(SAY_LEFT_ARM_LOST, pTemp); + if (pTemp->isAlive()) + pTemp->DealDamage(pTemp, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiShockwave_Timer < diff) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN))) + DoScriptText(SAY_SHOCKWEAVE, pTemp); + + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHOCKWAVE : SPELL_SHOCKWAVE_H); + m_uiShockwave_Timer = 17000; + }else m_uiShockwave_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_left_arm(Creature* pCreature) +{ + return new boss_left_armAI(pCreature); +} + +// Right Arm +struct MANGOS_DLL_DECL boss_right_armAI : public ScriptedAI +{ + boss_right_armAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiStone_Grip_Timer; + uint32 m_uiFreeDamage; + uint32 m_uiMaxDamage; + uint64 m_uiGripTargetGUID[3]; + uint8 m_uiMaxTargets; + + void Reset() + { + m_uiStone_Grip_Timer = 20000; + m_uiMaxTargets = m_bIsRegularMode ? 1 : 3; + for(int i = 0; i < m_uiMaxTargets; i++) + m_uiGripTargetGUID[i] = 0; + m_uiFreeDamage = 0; + m_uiMaxDamage = m_bIsRegularMode ? 100000 : 480000; + + DoCast(m_creature, SPELL_ARM_VISUAL); + m_creature->SetRespawnDelay(DAY); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN))) + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim) + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H); + } + + void JustReachedHome() + { + //if (m_pInstance) + //m_pInstance->DoRemoveAurasDueToSpellOnPlayers(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H); + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + m_uiFreeDamage += uiDamage; + } + + void JustDied(Unit* pKiller) + { + if (!m_pInstance) + return; + + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN))) + { + DoScriptText(SAY_RIGHT_ARM_LOST, pTemp); + if (pTemp->isAlive()) + pTemp->DealDamage(pTemp, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + for(int i = 0; i < m_uiMaxTargets; i++) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiGripTargetGUID[i])) + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiFreeDamage > m_uiMaxDamage) + { + m_uiFreeDamage = 0; + for(int i = 0; i < m_uiMaxTargets; i++) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiGripTargetGUID[i])) + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H); + } + } + + if (m_uiStone_Grip_Timer < diff) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN))) + DoScriptText(SAY_GRAB, pTemp); + + DoScriptText(EMOTE_STONE_GRIP, m_creature); + + // this needs vehicles! + for(int i = 0; i < m_uiMaxTargets; i++) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)){ + pTarget->CastSpell(pTarget, m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H, false); + m_uiGripTargetGUID[i] = pTarget->GetGUID(); + } + } + m_uiStone_Grip_Timer = 30000; + }else m_uiStone_Grip_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_right_arm(Creature* pCreature) +{ + return new boss_right_armAI(pCreature); +} + +// Kologarn +struct MANGOS_DLL_DECL boss_kologarnAI : public ScriptedAI +{ + boss_kologarnAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiSpell_Timer; + uint32 m_uiCheck_Timer; + uint32 m_uiEyebeah_Timer; + uint32 m_uiRespawnRightTimer; + uint32 m_uiRespawnLeftTimer; + uint32 m_uiEnrageTimer; + + uint32 m_uiRubbleNo; + bool m_bHasLeftDied; + bool m_bHasRightDied; + uint32 m_uiDisarmedTimer; + bool m_bOpenArms; + + bool m_bIsRightDead; + bool m_bIsLeftDead; + + void Reset() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + + m_uiSpell_Timer = 10000; + m_uiCheck_Timer = 6300; + m_uiEnrageTimer = 600000; + m_uiEyebeah_Timer = 10000 + urand(1000, 5000); + m_bIsRightDead = false; + m_bIsLeftDead = false; + + m_uiRubbleNo = 0; + m_bHasLeftDied = false; + m_bHasRightDied = false; + m_bOpenArms = true; + m_uiDisarmedTimer = 0; + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + // hacky way to complete achievements; use only if you have this function + // Rubble and roll + if (m_uiRubbleNo >= 25) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_RUBBLE_AND_ROLL : ACHIEV_RUBBLE_AND_ROLL_H); + } + + // With open arms + if (m_bOpenArms) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_WITH_OPEN_ARMS : ACHIEV_WITH_OPEN_ARMS_H); + } + + // Disarmed + if (m_bHasLeftDied && m_bHasRightDied && m_uiDisarmedTimer <= 12000) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_DISARMED : ACHIEV_DISARMED_H); + } + + //death yell + if (m_pInstance) + { + m_pInstance->SetData(TYPE_KOLOGARN, DONE); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM))) + { + if (pTemp->isAlive()) + pTemp->ForcedDespawn(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM))) + { + if (pTemp->isAlive()) + pTemp->ForcedDespawn(); + } + } + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_KOLOGARN, IN_PROGRESS); + + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM))) + { + if (pTemp->isAlive()) + pTemp->SetInCombatWithZone(); + } + } + //aggro yell + DoScriptText(SAY_AGGRO, m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY1, m_creature); + else + DoScriptText(SAY_SLAY2, m_creature); + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_KOLOGARN, FAIL); + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM))) + { + if (!pTemp->isAlive()) + pTemp->Respawn(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + if (!m_bIsRightDead && !m_bIsLeftDead) + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_OVERHEAD_SMASH : SPELL_OVERHEAD_SMASH_H); + else if (m_bIsRightDead && m_bIsLeftDead) + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_STONE_SHOUT : SPELL_STONE_SHOUT_H); + else + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ONE_ARMED_SMASH : SPELL_ONE_ARMED_SMASH_H); + m_uiSpell_Timer = 20000; + }else m_uiSpell_Timer -= uiDiff; + + // to be fixed -> only damage, no animation + if (m_uiEyebeah_Timer < uiDiff) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + DoCast(target, SPELL_FOCUSED_EYEBEAM_VISUAL); + DoCast(target, m_bIsRegularMode ? SPELL_FOCUSED_EYEBEAM : SPELL_FOCUSED_EYEBEAM_H, true); + } + m_uiEyebeah_Timer = 20000; + }else m_uiEyebeah_Timer -= uiDiff; + + // respawn arms + if (m_uiRespawnLeftTimer < uiDiff && m_bIsLeftDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM))) + { + if (!pTemp->isAlive()) + { + pTemp->Respawn(); + m_bIsLeftDead = false; + m_bHasLeftDied = false; + DoScriptText(EMOTE_LEFT_ARM, m_creature); + } + } + }else m_uiRespawnLeftTimer -= uiDiff; + + if (m_uiRespawnRightTimer < uiDiff && m_bIsRightDead) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM))) + { + if (!pTemp->isAlive()) + { + pTemp->Respawn(); + m_bIsRightDead = false; + m_bHasRightDied = false; + DoScriptText(EMOTE_RIGHT_ARM, m_creature); + } + } + }else m_uiRespawnRightTimer -= uiDiff; + + // check if arms are dead and if there is no player in melee range + if (m_uiCheck_Timer < uiDiff) + { + if (Creature* lArm = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM))) + { + if (!lArm->isAlive() && !m_bIsLeftDead) + { + m_bHasLeftDied = true; + m_bOpenArms = false; + m_uiDisarmedTimer = 0; + + for(uint8 i = 0; i < 5; i ++) + { + if(Creature* pRubble = m_creature->SummonCreature(MOB_RUBBLE, LeftArm[0] - urand(0, 5), LeftArm[1] + urand(0, 10), LeftArm[2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + pRubble->GetMotionMaster()->MovePoint(0, KoloFront[0], KoloFront[1], KoloFront[2]); + + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pRubble->AddThreat(pTarget,0.0f); + pRubble->AI()->AttackStart(pTarget); + pRubble->SetInCombatWithZone(); + } + + m_uiRubbleNo += 1; + } + } + m_bIsLeftDead = true; + m_uiRespawnLeftTimer = 47000; + } + } + if (Creature* rArm = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM))) + { + if (!rArm->isAlive() && !m_bIsRightDead) + { + m_bHasRightDied = true; + m_bOpenArms = false; + m_uiDisarmedTimer = 0; + + for(uint8 i = 0; i < 5; i ++) + { + if(Creature* pRubble = m_creature->SummonCreature(MOB_RUBBLE, RightArm[0] - urand(0, 5), RightArm[1] + urand(0, 10), RightArm[2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + pRubble->GetMotionMaster()->MovePoint(0, KoloFront[0], KoloFront[1], KoloFront[2]); + + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pRubble->AddThreat(pTarget,0.0f); + pRubble->AI()->AttackStart(pTarget); + pRubble->SetInCombatWithZone(); + } + + m_uiRubbleNo += 1; + } + } + m_bIsRightDead = true; + m_uiRespawnRightTimer = 47000; + } + } + + //Petrifying breath + if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 5)) + DoCast(m_creature, m_bIsRegularMode ? SPELL_PETRIFYING_BREATH : SPELL_PETRIFYING_BREATH_H); + + m_uiCheck_Timer = 500; + }else m_uiCheck_Timer -= uiDiff; + + // disarmed achiev check + if (m_bHasLeftDied || m_bHasRightDied) + m_uiDisarmedTimer += uiDiff; + + if(m_uiEnrageTimer < uiDiff) + { + DoScriptText(SAY_BERSERK, m_creature); + DoCast(m_creature, SPELL_ENRAGE); + m_uiEnrageTimer = 30000; + } + else m_uiEnrageTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_kologarn(Creature* pCreature) +{ + return new boss_kologarnAI(pCreature); +} + void AddSC_boss_kologarn() { + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "boss_kologarn"; + NewScript->GetAI = GetAI_boss_kologarn; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_ulduar_rubble"; + NewScript->GetAI = &GetAI_mob_ulduar_rubble; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "boss_left_arm"; + NewScript->GetAI = &GetAI_boss_left_arm; + NewScript->RegisterSelf(); + NewScript = new Script; + NewScript->Name = "boss_right_arm"; + NewScript->GetAI = &GetAI_boss_right_arm; + NewScript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp b/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp index fa7ea5733..a010c5f5f 100644 --- a/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_mimiron -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: needs vehicles SDCategory: Ulduar EndScriptData */ @@ -26,36 +26,2240 @@ EndScriptData */ enum { - SAY_AGGRO = -1603176, - SAY_HARD_MODE = -1603177, - SAY_BERSERK = -1603178, + //yells + SAY_AGGRO = -1603241, + SAY_HARD_MODE = -1603242, + SAY_BERSERK = -1603243, + SAY_TANK_ACTIVE = -1603244, + SAY_TANK_SLAY1 = -1603245, + SAY_TANK_SLAY2 = -1603246, + SAY_TANK_DEATH = -1603247, + SAY_TORSO_ACTIVE = -1603248, + SAY_TORSO_SLAY1 = -1603249, + SAY_TORSO_SLAY2 = -1603250, + SAY_TORSO_DEATH = -1603251, + SAY_HEAD_ACTIVE = -1603252, + SAY_HEAD_SLAY1 = -1603253, + SAY_HEAD_SLAY2 = -1603254, + SAY_HEAD_DEATH = -1603255, + SAY_ROBOT_ACTIVE = -1603256, + SAY_ROBOT_SLAY1 = -1603257, + SAY_ROBOT_SLAY2 = -1603258, + SAY_ROBOT_DEATH = -1603259, - SAY_TANK_ACTIVE = -1603179, - SAY_TANK_SLAY_1 = -1603180, - SAY_TANK_SLAY_2 = -1603181, - SAY_TANK_DEATH = -1603182, + EMOTE_PLASMA_BLAST = -1603371, - SAY_TORSO_ACTIVE = -1603183, - SAY_TORSO_SLAY_1 = -1603184, - SAY_TORSO_SLAY_2 = -1603185, - SAY_TORSO_DEATH = -1603186, + SPELL_JET_PACK = 63341, // used by mimiron to change seats + SPELL_SELF_REPAIR = 64383, - SAY_HEAD_ACTIVE = -1603187, - SAY_HEAD_SLAY_1 = -1603188, - SAY_HEAD_SLAY_2 = -1603189, - SAY_HEAD_DEATH = -1603190, + // hard mode spells + SPELL_SELF_DESTRUCTION = 64613, // visual aura + SPELL_SELF_DESTRUCT = 64610, // damage aura + SPELL_EMERGENCY_MODE_AURA = 65101, + NPC_MIMIRON_INFERNO = 33370, // used to cast the self destruct - SAY_ROBOT_ACTIVE = -1603191, - SAY_ROBOT_SLAY_1 = -1603192, - SAY_ROBOT_SLAY_2 = -1603193, - SAY_ROBOT_DEATH = -1603194, + SPELL_FLAMES = 64561, // may be the fires spells + SPELL_FLAMES_SUMMON = 64563, // 64567 + SPELL_FLAMES_SPREAD = 64562, + NPC_FLAME = 34121, + NPC_FLAME_INITIAL = 34363, - SAY_HELP_YOGG = -1603195, + //spells + //leviathan + SPELL_PROXIMITY_MINES = 63016, // also in phase 4 + SPELL_MINE_SUMMON = 65347, + MOB_PROXIMITY_MINE = 34362, + SPELL_EXPLOSION = 66351, + SPELL_EXPLOSION_H = 63009, + SPELL_NAPALM_SHELL = 63666, + SPELL_NAPALM_SHELL_H = 65026, + SPELL_PLASMA_BLAST = 62997, + SPELL_PLASMA_BLAST_H = 64529, + SPELL_SHOCK_BLAST = 63631, // also in phase 4 + SPELL_FLAME_SUPRESSANT = 64570, // hard mode + LEVIATHAN_TURRET = 34071, - EMOTE_PLASMA_BLAST = -1603196, + //vx001 + SPELL_RAPID_BURST = 63387, + SPELL_RAPID_BURST_H = 64531, + SPELL_LASER_BARRAGE = 63293, // also in phase 4 + SPELL_LASER_VISUAL = 63300, + SPELL_LASER_TRIGG = 63274, + SPELL_ROCKET_STRIKE = 64064, + NPC_MIMIRON_FOCUS = 33835, //33369 + SPELL_HEAT_WAVE = 63677, + SPELL_HEAT_WAVE_H = 64533, + SPELL_HAND_PULSE = 64348, // only in phase 4 + SPELL_FLAME_SUPRESS = 65192, // used by robot in melee range + SPELL_HAND_PULSE_H = 64536, + + // frostbomb + SPELL_FROST_BOMB_EXPL = 64626, + SPELL_FROST_BOMB_AURA = 64624, // before explode + SPELL_FROST_BOMB_VISUAL = 64625, // bomb grows + SPELL_FROST_BOMB_SUMMON = 64627, // summon the frostbomb + + //aerial unit + SPELL_PLASMA_BALL = 63689, // also in phase 4 + SPELL_PLASMA_BALL_H = 64535, // also in phase 4 + MOB_ASSALT_BOT = 34057, + MOB_BOMB_BOT = 33836, + MOB_BOMB_BOT_321 = 33346, + MOB_BOMB_BOT_500 = 34192, + MOB_JUNK_BOT = 33855, + SPELL_MAGNETIC_FIELD = 64668, + SPELL_MAGNETIC_CORE = 64436, // increase dmg taken by 50%, used by magnetic core + MOB_MAGNETIC_CORE = 34068, + ITEM_MAGNETIC_CORE = 46029, + SPELL_BOMB_BOT_SUMMON = 63811, + SPELL_BOMB_BOT = 63767, + + //hard mode + // summons fires + SPELL_EMERGENCY_MODE = 64582, + MOB_FROST_BOMB = 34149, + MOB_EMERGENCY_FIRE_BOT = 34147, + SPELL_DEAFENING_SIREN = 64616, + SPELL_WATER_SPRAY = 64619, + + SPELL_MIMIRONS_INFERNO = 62910, // maybe used by rocket + SPELL_MIMIRONS_INFERNO2 = 62909, // maybe hard mode + SPELL_BERSERK = 26662, + + ACHIEV_FIREFIGHTER = 3180, + ACHIEV_FIREFIGHTER_H = 3189, +}; + +enum MimironPhase +{ + PHASE_IDLE = 0, + PHASE_INTRO = 1, + PHASE_LEVIATHAN = 2, + PHASE_TRANS_1 = 3, + PHASE_VX001 = 4, + PHASE_TRANS_2 = 5, + PHASE_AERIAL = 6, + PHASE_TRANS_3 = 7, + PHASE_ROBOT = 8, + PHASE_OUTRO = 9, +}; + +#define CENTER_X 2744.732f +#define CENTER_Y 2569.479f +#define CENTER_Z 364.312f + +const float PosTankHome[2]= {2794.86f, 2597.83f}; +struct LocationsXY +{ + float x, y; + uint32 id; +}; +static LocationsXY SummonLoc[]= +{ + {2753.665f, 2584.712f}, + {2754.150f, 2554.445f}, + {2726.966f, 2569.032f}, + {2759.085f, 2594.249f}, + {2759.977f, 2544.345f}, + {2715.542f, 2569.160f}, + {2765.070f, 2604.337f}, + {2765.676f, 2534.558f}, + {2703.810f, 2569.132f}, +}; + +// Leviathan Mk script +struct MANGOS_DLL_DECL boss_leviathan_mkAI : public ScriptedAI +{ + boss_leviathan_mkAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + bool m_bStartAttack; + + uint32 m_uiMinesTimer; + uint32 m_uiNapalmTimer; + uint32 m_uiPlasmaBlastTimer; + uint32 m_uiShockBlastTimer; + + bool m_bHasSuppresed; + uint32 m_uiSupressTimer; + uint32 m_uiSetFireTimer; + + // outro + bool m_bIsOutro; + uint32 m_uiOutroTimer; + uint32 m_uiOutroStep; + + bool m_bMustRepair; + uint32 m_uiRepairTimer; + + void Reset() + { + m_bStartAttack = false; + m_uiMinesTimer = 5000; + m_uiNapalmTimer = 20000; + m_uiPlasmaBlastTimer = 10000; + m_uiShockBlastTimer = 30000; + m_bHasSuppresed = false; + m_uiSetFireTimer = 10000; + m_uiSupressTimer = 10000; + + m_uiOutroTimer = 10000; + m_uiOutroStep = 1; + m_bIsOutro = false; + m_bMustRepair = false; + m_uiRepairTimer = 15000; + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if(m_pInstance) + m_pInstance->SetData(TYPE_LEVIATHAN_MK, NOT_STARTED); + } + + void AttackStart(Unit* pWho) + { + if(!m_bStartAttack) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN) + DoStartMovement(pWho); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN) + { + if(m_creature->GetHealthPercent() < 1.0f) + { + uiDamage = 0; + m_bIsOutro = true; + } + } + // hacky way for feign death + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT) + { + if(uiDamage > m_creature->GetHealth() && !m_bMustRepair) + { + uiDamage = 0; + m_creature->SetHealth(0); + m_creature->InterruptNonMeleeSpells(true); + m_creature->RemoveAllAuras(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->CombatStop(); + m_creature->SetStandState(UNIT_STAND_STATE_DEAD); + m_bMustRepair = true; + m_uiRepairTimer = 15000; + DoCast(m_creature, SPELL_SELF_REPAIR); + + if(m_pInstance) + m_pInstance->SetData(TYPE_LEVIATHAN_MK, SPECIAL); + } + } + } + + void KilledUnit(Unit* pVictim) + { + if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON))) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN) + { + if(irand(0,1)) + DoScriptText(SAY_TANK_SLAY1, pMimiron); + else + DoScriptText(SAY_TANK_SLAY2, pMimiron); + } + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT) + { + if(irand(0,1)) + DoScriptText(SAY_ROBOT_SLAY1, pMimiron); + else + DoScriptText(SAY_ROBOT_SLAY2, pMimiron); + } + } + } + + // hacky way for phase 4. needs rewriging when vehicles are fixed + void SetPhase() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bIsOutro = false; + m_uiMinesTimer = 10000; + m_uiShockBlastTimer = 30000; + m_bStartAttack = true; + // look like a robot + SetCombatMovement(false); + } + + // hacky way for phase 4. needs rewriging when vehicles are fixed + void Repair() + { + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->SetHealth(m_creature->GetMaxHealth() * 0.5); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->AI()->AttackStart(m_creature->getVictim()); + SetPhase(); + + if(m_pInstance) + m_pInstance->SetData(TYPE_LEVIATHAN_MK, IN_PROGRESS); + } + + void JustSummoned(Creature* pSummon) + { + pSummon->SetInCombatWithZone(); + } + + void SuppressFires() + { + std::list lFires; + GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, DEFAULT_VISIBILITY_INSTANCE); + if (!lFires.empty()) + { + for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->ForcedDespawn(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if(!m_bIsOutro) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiRepairTimer < uiDiff && m_bMustRepair) + { + SetPhase(); + Repair(); + m_bMustRepair = false; + } + else m_uiRepairTimer -= uiDiff; + + // return if repairing + if(m_bMustRepair) + return; + + // this should be removed when vehicles are implemented! The are casted by the turret + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN) + { + if(m_uiPlasmaBlastTimer < uiDiff) + { + DoScriptText(EMOTE_PLASMA_BLAST, m_creature); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_PLASMA_BLAST : SPELL_PLASMA_BLAST_H); + m_uiPlasmaBlastTimer = 30000; + } + else m_uiPlasmaBlastTimer -= uiDiff; + + if(m_uiNapalmTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if(!m_creature->IsWithinDistInMap(pTarget, 15)) + { + DoCast(pTarget, m_bIsRegularMode ? SPELL_NAPALM_SHELL : SPELL_NAPALM_SHELL_H); + m_uiNapalmTimer = 7000; + } + } + } + else m_uiNapalmTimer -= uiDiff; + } + + // proximity mines + if(m_uiMinesTimer < uiDiff) + { + //DoCast(m_crreature, SPELL_PROXIMITY_MINES); + for(uint8 i = 0; i < urand(8, 10); i++) + { + float angle = (float) rand()*360/RAND_MAX + 1; + float homeX = m_creature->GetPositionX() + 15*cos(angle*(M_PI/180)); + float homeY = m_creature->GetPositionY() + 15*sin(angle*(M_PI/180)); + m_creature->SummonCreature(MOB_PROXIMITY_MINE, homeX, homeY, m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 10000); + } + m_uiMinesTimer = 30000; + } + else m_uiMinesTimer -= uiDiff; + + // shock blast + if(m_uiShockBlastTimer < uiDiff) + { + DoCast(m_creature, SPELL_SHOCK_BLAST); + m_uiShockBlastTimer = 50000; + } + else m_uiShockBlastTimer -= uiDiff; + + // hard mode script + if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS && m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN) + { + if(m_creature->GetHealthPercent() < 50.0f && !m_bHasSuppresed) + { + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_FLAME_SUPRESSANT); + m_bHasSuppresed = true; + m_uiSupressTimer = 2000; + m_uiSetFireTimer = 10000; + } + + if(m_uiSupressTimer < uiDiff && m_bHasSuppresed) + { + SuppressFires(); + m_uiSupressTimer = 600000; + } + else m_uiSupressTimer -= uiDiff; + + if(m_uiSetFireTimer < uiDiff && m_bHasSuppresed) + { + // start again 3 fires + for(uint8 i = 0; i < 3; i++) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTarget->InterruptNonMeleeSpells(true); + pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false); + } + } + m_uiSetFireTimer = 600000; + } + else m_uiSetFireTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } + // outro for phase 1 + if(m_bIsOutro) + { + switch(m_uiOutroStep) + { + case 1: + m_bStartAttack = false; + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->InterruptNonMeleeSpells(false); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->GetMotionMaster()->MovePoint(0, PosTankHome[0], PosTankHome[1], CENTER_Z); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON))) + DoScriptText(SAY_TANK_DEATH, pMimiron); + ++m_uiOutroStep; + m_uiOutroTimer = 12000; + break; + case 3: + if(m_pInstance) + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_TRANS_1); + // reset the miniboss for phase 4 + EnterEvadeMode(); + ++m_uiOutroStep; + m_uiOutroTimer = 3000; + break; + } + } + else return; + + if (m_uiOutroTimer <= uiDiff) + { + ++m_uiOutroStep; + m_uiOutroTimer = 330000; + } m_uiOutroTimer -= uiDiff; + } +}; + +// VX001 script +struct MANGOS_DLL_DECL boss_vx001AI : public ScriptedAI +{ + boss_vx001AI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + bool m_bStartAttack; + uint32 m_uiAttackStartTimer; + + uint32 m_uiRapidBurstTimer; + uint32 m_uiLaserBarrageTimer; + uint32 m_uiRocketStrikeTimer; + uint32 m_uiHeatWaveTimer; + uint32 m_uiHandPulseTimer; + + uint32 m_uiFlameSuppressTimer; + uint32 m_uiFrostBombTimer; + uint32 m_uiSpreadFiresTimer; + + uint32 m_uiRepairTimer; + bool m_bMustRepair; + + void Reset() + { + m_bStartAttack = false; + m_uiAttackStartTimer = 12000; + m_bMustRepair = false; + m_uiRepairTimer = 15000; + + m_uiRapidBurstTimer = 1000; + m_uiLaserBarrageTimer = 60000; + m_uiRocketStrikeTimer = 25000; + m_uiHeatWaveTimer = 20000; + m_uiHandPulseTimer = 1000; + + m_uiFlameSuppressTimer = urand(10000, 15000); + m_uiFrostBombTimer = urand(25000, 30000); + m_uiSpreadFiresTimer = urand(40000, 50000); + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if(m_pInstance) + m_pInstance->SetData(TYPE_VX001, NOT_STARTED); + } + + void AttackStart(Unit* pWho) + { + if(!m_bStartAttack) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + void KilledUnit(Unit* pVictim) + { + if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON))) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001) + { + if(irand(0,1)) + DoScriptText(SAY_TORSO_SLAY1, pMimiron); + else + DoScriptText(SAY_TORSO_SLAY2, pMimiron); + } + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT) + { + if(irand(0,1)) + DoScriptText(SAY_ROBOT_SLAY1, pMimiron); + else + DoScriptText(SAY_ROBOT_SLAY2, pMimiron); + } + } + } + + // hacky way for phase 4. needs rewriging when vehicles are fixed + void SetPhase() + { + //SetCombatMovement(true); + m_uiLaserBarrageTimer = 60000; + m_uiRocketStrikeTimer = 25000; + m_uiHandPulseTimer = 1000; + + // look like a robot + m_creature->GetMotionMaster()->MoveIdle(); + SetCombatMovement(false); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 3, 0.0f); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 3, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + + void JustDied(Unit* pKiller) + { + if(m_pInstance) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001) + { + if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON))) + DoScriptText(SAY_TORSO_DEATH, pMimiron); + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_TRANS_2); + m_pInstance->SetData(TYPE_VX001, DONE); + } + } + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001) + return; + + // hacky way for feign death, needs fixing + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT) + { + if(uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + m_creature->SetHealth(0); + m_creature->InterruptNonMeleeSpells(true); + m_creature->RemoveAllAuras(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->CombatStop(); + m_bMustRepair = true; + m_uiRepairTimer = 15000; + m_creature->SetStandState(UNIT_STAND_STATE_DEAD); + if(m_pInstance) + m_pInstance->SetData(TYPE_VX001, SPECIAL); + } + } + } + + // hacky way for phase 4. needs rewriging when vehicles are fixed + void Repair() + { + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->SetHealth(m_creature->GetMaxHealth() * 0.5); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->AI()->AttackStart(m_creature->getVictim()); + SetPhase(); + + if(m_pInstance) + m_pInstance->SetData(TYPE_VX001, IN_PROGRESS); + } + + void SuppressFires() + { + std::list lFires; + GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, 10.0f); + GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, 10.0f); + if (!lFires.empty()) + { + for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->ForcedDespawn(); + } + } + } + + Creature* SelectRandomFire() + { + std::list lFires; + GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, DEFAULT_VISIBILITY_INSTANCE); + + //This should not appear! + if (lFires.empty()){ + m_uiFrostBombTimer = 5000; + return NULL; + } + + std::list::iterator iter = lFires.begin(); + advance(iter, urand(0, lFires.size()-1)); + + if((*iter)->isAlive()) + return *iter; + else + { + m_uiFrostBombTimer = 500; + return NULL; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiAttackStartTimer < uiDiff && !m_bStartAttack) + { + if(GameObject* pLift = GetClosestGameObjectWithEntry(m_creature, GO_MIMIRON_ELEVATOR, DEFAULT_VISIBILITY_INSTANCE)) + pLift->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWithZone(); + m_bStartAttack = true; + } + else m_uiAttackStartTimer -= uiDiff; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiRepairTimer < uiDiff && m_bMustRepair) + { + SetPhase(); + Repair(); + m_bMustRepair = false; + } + else m_uiRepairTimer -= uiDiff; + + // return if repairing + if(m_bMustRepair) + return; + + // only in VX001 phase + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001) + { + if(m_uiRapidBurstTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_RAPID_BURST : SPELL_RAPID_BURST_H); + m_uiRapidBurstTimer = 1000; + } + else m_uiRapidBurstTimer -= uiDiff; + + if(m_uiHeatWaveTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_HEAT_WAVE : SPELL_HEAT_WAVE_H); + m_uiHeatWaveTimer = 10000; + } + else m_uiHeatWaveTimer -= uiDiff; + } + + // only in robot phase + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT) + { + if(m_uiHandPulseTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_HAND_PULSE : SPELL_HAND_PULSE_H); + m_uiHandPulseTimer = 1000; + } + else m_uiHandPulseTimer -= uiDiff; + } + + if(m_uiLaserBarrageTimer < uiDiff) + { + DoCast(m_creature, SPELL_LASER_TRIGG); + m_uiLaserBarrageTimer = urand(50000, 60000); + } + else m_uiLaserBarrageTimer -= uiDiff; + + // this needs vehicles in order to make the rocket move to the target + if(m_uiRocketStrikeTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if(Creature* pTemp = m_creature->SummonCreature(NPC_MIMIRON_FOCUS, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000)) + { + pTemp->setFaction(14); + pTemp->GetMotionMaster()->MoveIdle(); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pTemp->CombatStop(); + pTemp->SetDisplayId(11686); // make invisible + pTemp->CastSpell(pTemp, SPELL_ROCKET_STRIKE, false); + } + } + m_uiRocketStrikeTimer = urand(25000, 30000); + } + else m_uiRocketStrikeTimer -= uiDiff; + + // hard mode + if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS) + { + // only in VX001 phase + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001) + { + if(m_uiFlameSuppressTimer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_FLAME_SUPRESS); + SuppressFires(); + m_uiFlameSuppressTimer = urand(9000, 10000); + } + else m_uiFlameSuppressTimer -= uiDiff; + } + + if(m_uiFrostBombTimer < uiDiff) + { + if(Creature* pFire = SelectRandomFire()) + m_creature->SummonCreature(MOB_FROST_BOMB, pFire->GetPositionX(), pFire->GetPositionY(), pFire->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 10000); + m_uiFrostBombTimer = urand(50000, 60000); + m_uiSpreadFiresTimer = urand(15000, 20000); + } + else m_uiFrostBombTimer -= uiDiff; + + if(m_uiSpreadFiresTimer < uiDiff) + { + // start again 3 fires + for(uint8 i = 0; i < 3; i++) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTarget->InterruptNonMeleeSpells(true); + pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false); + } + } + m_uiSpreadFiresTimer = 60000; + } + else m_uiSpreadFiresTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } +}; + +// Aerial command unit script +struct MANGOS_DLL_DECL boss_aerial_command_unitAI : public ScriptedAI +{ + boss_aerial_command_unitAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + bool m_bStartAttack; + uint32 m_uiAttackStartTimer; + + uint32 m_uiPlasmaBallTimer; + uint32 m_uiSummonWavesTimer; + uint32 m_uiGroundTimer; + bool m_bIsGrounded; + uint32 m_uiSpreadFiresTimer; + + uint32 m_uiRepairTimer; + bool m_bMustRepair; + + void Reset() + { + m_bStartAttack = false; + m_uiAttackStartTimer = 5000; + m_uiSpreadFiresTimer = urand(40000, 50000); + + m_uiPlasmaBallTimer = 3000; + m_uiSummonWavesTimer = 10000; + m_bIsGrounded = false; + + m_bMustRepair = false; + m_uiRepairTimer = 15000; + + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + + if(m_pInstance) + m_pInstance->SetData(TYPE_AERIAL_UNIT, NOT_STARTED); + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void AttackStart(Unit* pWho) + { + if(!m_bStartAttack) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + void Aggro(Unit *who) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL) + { + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->GetMotionMaster()->MoveIdle(); + SetCombatMovement(false); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, 0.0f); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL) + { + if(m_creature->HasAura(SPELL_MAGNETIC_CORE, EFFECT_INDEX_0)) + uiDamage += uiDamage; + return; + } + + // hacky way for feign death + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT) + { + if(uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + m_creature->SetHealth(0); + m_creature->InterruptNonMeleeSpells(true); + m_creature->RemoveAllAuras(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->MovementExpired(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->CombatStop(); + m_bMustRepair = true; + m_uiRepairTimer = 15000; + m_creature->SetStandState(UNIT_STAND_STATE_DEAD); + + if(m_pInstance) + m_pInstance->SetData(TYPE_AERIAL_UNIT, SPECIAL); + } + } + } + + // hacky way for phase 4. needs rewriging when vehicles are fixed + void Repair() + { + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->SetHealth(m_creature->GetMaxHealth() * 0.5); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_creature->AI()->AttackStart(m_creature->getVictim()); + SetPhase(); + + if(m_pInstance) + m_pInstance->SetData(TYPE_AERIAL_UNIT, IN_PROGRESS); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL) + { + if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON))) + DoScriptText(SAY_HEAD_DEATH, pMimiron); + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_TRANS_3); + m_pInstance->SetData(TYPE_AERIAL_UNIT, DONE); + } + } + } + + void KilledUnit(Unit* pVictim) + { + if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON))) + { + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL) + { + if(irand(0,1)) + DoScriptText(SAY_HEAD_SLAY1, pMimiron); + else + DoScriptText(SAY_HEAD_SLAY2, pMimiron); + } + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT) + { + if(irand(0,1)) + DoScriptText(SAY_ROBOT_SLAY1, pMimiron); + else + DoScriptText(SAY_ROBOT_SLAY2, pMimiron); + } + } + } + + // hacky way for phase 4. needs rewriging when vehicles are fixed + void SetPhase() + { + m_uiPlasmaBallTimer = 3000; + + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + SetCombatMovement(false); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 6.5f, 0.0f); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 6.5f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + + // get the boss down by the magnetic core + void SetToGround() + { + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), CENTER_Z, 0); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), CENTER_Z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + m_bIsGrounded = true; + // make boss land + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_uiGroundTimer = 20000; + } + + void JustSummoned(Creature* pSummon) + { + pSummon->SetInCombatWithZone(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiAttackStartTimer < uiDiff && !m_bStartAttack) + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWithZone(); + m_bStartAttack = true; + } + else m_uiAttackStartTimer -= uiDiff; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiRepairTimer < uiDiff && m_bMustRepair) + { + SetPhase(); + Repair(); + m_bMustRepair = false; + } + else m_uiRepairTimer -= uiDiff; + + // return if repairing + if(m_bMustRepair) + return; + + if (m_creature->HasAura(SPELL_MAGNETIC_CORE, EFFECT_INDEX_0)) + return; + + if (m_uiGroundTimer < uiDiff && m_bIsGrounded) + { + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, 0.0f); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + m_bIsGrounded = false; + // make boss fly + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_BOMB_BOT_SUMMON); + }else m_uiGroundTimer -= uiDiff; + + if(m_uiPlasmaBallTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_PLASMA_BALL : SPELL_PLASMA_BALL_H); + m_uiPlasmaBallTimer = urand(3000, 5000); + } + else m_uiPlasmaBallTimer -= uiDiff; + + // spawn adds in arena, only in phase 3 + if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL) + { + if(m_uiSummonWavesTimer < uiDiff) + { + uint32 m_uiCreatureEntry; + // summon emergency boots + if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS) + { + switch(urand(0, 4)) + { + case 0: + case 1: + m_uiCreatureEntry = MOB_JUNK_BOT; + break; + case 2: + case 3: + m_uiCreatureEntry = MOB_EMERGENCY_FIRE_BOT; + break; + case 4: + m_uiCreatureEntry = MOB_ASSALT_BOT; + break; + } + } + else + { + switch(urand(0, 2)) + { + case 0: + case 1: + m_uiCreatureEntry = MOB_JUNK_BOT; + break; + case 2: + m_uiCreatureEntry = MOB_ASSALT_BOT; + break; + } + } + uint8 m_uiSummonLoc = urand(0, 8); + if(m_uiCreatureEntry != 0) + m_creature->SummonCreature(m_uiCreatureEntry, SummonLoc[m_uiSummonLoc].x, SummonLoc[m_uiSummonLoc].y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + + m_uiSummonWavesTimer = urand (10000, 15000); + } + else m_uiSummonWavesTimer -= uiDiff; + + if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS) + { + if(m_uiSpreadFiresTimer < uiDiff) + { + // start again 3 fires + for(uint8 i = 0; i < 3; i++) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTarget->InterruptNonMeleeSpells(true); + pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false); + } + } + m_uiSpreadFiresTimer = urand(40000, 50000); + } + else m_uiSpreadFiresTimer -= uiDiff; + } + } + } }; +// Mimiron, event controller +// boss should be placed inside the vehicles when they are supported by mangos +struct MANGOS_DLL_DECL boss_mimironAI : public ScriptedAI +{ + boss_mimironAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance *m_pInstance; + + bool m_bIsHardMode; + uint32 m_uiSelfDestructTimer; + uint32 m_uiUseLiftTimer; + uint32 m_uiPhaseDelayTimer; + uint32 m_uiRobotDelayTimer; + uint32 m_uiSelfRepairTimer; + uint32 m_uiBerserkTimer; + bool m_bHasChecked; + uint32 m_uiOutroTimer; + uint32 m_uiHpCheckTimer; + bool m_bHasMoreHp; + + uint32 m_uiIntroTimer; + uint32 m_uiIntroStep; + bool m_bIsIntro; + bool m_bIsRobotReady; + + uint64 m_uiTankGUID; + uint64 m_uiTorsoGUID; + uint64 m_uiHeadGUID; + + bool m_bIsTankDead; + bool m_bIsTorsoDead; + bool m_bIsHeadDead; + + void Reset() + { + m_bIsHardMode = false; + m_uiSelfDestructTimer = 460000; // 8 min + m_bIsIntro = true; + m_uiPhaseDelayTimer = 7000; + m_uiUseLiftTimer = 4000; + m_uiBerserkTimer = 900000; // 15 min + m_bHasChecked = false; + m_bHasMoreHp = false; + m_bIsRobotReady = false; + + m_uiIntroTimer = 10000; + m_uiIntroStep = 1; + + m_bIsTankDead = false; + m_bIsTorsoDead = false; + m_bIsHeadDead = false; + + m_uiTankGUID = 0; + m_uiTorsoGUID = 0; + m_uiHeadGUID = 0; + + // reset button + if(GameObject* pButton = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_MIMIRON_BUTTON))) + pButton->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + + // reset elevator + if(GameObject* pLift = GetClosestGameObjectWithEntry(m_creature, GO_MIMIRON_ELEVATOR, DEFAULT_VISIBILITY_INSTANCE)) + pLift->SetGoState(GO_STATE_ACTIVE); + + // kill torso and Head + if(Creature* pTorso = GetClosestCreatureWithEntry(m_creature, NPC_VX001, 80.0f)) + pTorso->DealDamage(pTorso, pTorso->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + if(Creature* pHead = GetClosestCreatureWithEntry(m_creature, NPC_AERIAL_UNIT, 80.0f)) + pHead->DealDamage(pHead, pHead->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + // reset tank + if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK))) + { + if(pTank->isAlive()) + pTank->AI()->EnterEvadeMode(); + else + pTank->Respawn(); + } + + if(m_pInstance) + { + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_IDLE); + m_pInstance->SetData(TYPE_MIMIRON_HARD, NOT_STARTED); + } + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void JustReachedHome() + { + if(m_pInstance) + m_pInstance->SetData(TYPE_MIMIRON, NOT_STARTED); + } + + // start event + void Aggro(Unit *who) + { + DoScriptText(SAY_AGGRO, m_creature); + if (m_pInstance) + { + m_pInstance->SetData(TYPE_MIMIRON, IN_PROGRESS); + // activate teleporter + if(m_pInstance->GetData(TYPE_MIMIRON_TP) != DONE) + m_pInstance->SetData(TYPE_MIMIRON_TP, DONE); + // start intro + if(m_pInstance->GetData(TYPE_MIMIRON) != DONE) + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_INTRO); + } + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void DoOutro() + { + if(m_pInstance) + { + if(m_bIsHardMode) + { + m_pInstance->SetData(TYPE_MIMIRON_HARD, DONE); + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_FIREFIGHTER : ACHIEV_FIREFIGHTER_H); + } + m_pInstance->SetData(TYPE_MIMIRON, DONE); + } + m_creature->ForcedDespawn(); + } + + // for debug only + void JustDied(Unit* pKiller) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_MIMIRON, DONE); + if(m_bIsHardMode) + m_pInstance->SetData(TYPE_MIMIRON_HARD, DONE); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(m_pInstance->GetData(TYPE_MIMIRON_PHASE)) + { + case PHASE_INTRO: + { + if(m_bIsIntro) + { + //hard mode check + switch(m_uiIntroStep) + { + case 1: + ++m_uiIntroStep; + m_uiIntroTimer = 10000; + break; + case 3: + if(GameObject* pButton = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_MIMIRON_BUTTON))) + pButton->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + if(m_bIsHardMode) + { + DoScriptText(SAY_HARD_MODE, m_creature); + ++m_uiIntroStep; + m_uiIntroTimer = 15000; + } + else + { + ++m_uiIntroStep; + m_uiIntroTimer = 1000; + } + break; + case 5: + if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK))) + { + if(pTank->isAlive()) + { + DoScriptText(SAY_TANK_ACTIVE, m_creature); + pTank->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z); + m_uiTankGUID = pTank->GetGUID(); + } + else + EnterEvadeMode(); + } + ++m_uiIntroStep; + m_uiIntroTimer = 18000; + break; + case 7: + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + { + if(m_bIsHardMode) + { + pTank->CastSpell(pTank, SPELL_EMERGENCY_MODE, false); + ++m_uiIntroStep; + m_uiIntroTimer = 1000; + } + else + { + if(m_pInstance) + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_LEVIATHAN); + ((boss_leviathan_mkAI*)pTank->AI())->m_bStartAttack = true; + pTank->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTank->SetInCombatWithZone(); + m_uiBerserkTimer = 900000; // 15 min + m_bIsIntro = false; + ++m_uiIntroStep; + m_uiIntroTimer = 9000; + } + } + break; + case 9: + if(m_bIsHardMode) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_LEVIATHAN); + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + { + pTank->SetHealth(pTank->GetMaxHealth()+ (pTank->GetMaxHealth() * 0.3)); + ((boss_leviathan_mkAI*)pTank->AI())->m_bStartAttack = true; + pTank->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTank->SetInCombatWithZone(); + } + m_uiSelfDestructTimer = 460000; // 8 min + m_bIsIntro = false; + ++m_uiIntroStep; + m_uiIntroTimer = 9000; + } + break; + } + } + else return; + + if (m_uiIntroTimer <= uiDiff) + { + ++m_uiIntroStep; + m_uiIntroTimer = 330000; + } + m_uiIntroTimer -= uiDiff; + + break; + } + case PHASE_LEVIATHAN: + // leviathan MK phase: see above script + break; + case PHASE_TRANS_1: + { + if(m_uiUseLiftTimer < uiDiff) + { + if(GameObject* pLift = GetClosestGameObjectWithEntry(m_creature, GO_MIMIRON_ELEVATOR, DEFAULT_VISIBILITY_INSTANCE)) + m_pInstance->DoUseDoorOrButton(pLift->GetGUID()); + m_uiUseLiftTimer = 60000; + } + else m_uiUseLiftTimer -= uiDiff; + + if(m_uiPhaseDelayTimer < uiDiff && !m_bHasMoreHp) + { + DoScriptText(SAY_TORSO_ACTIVE, m_creature); + if(Creature* pTorso = m_creature->SummonCreature(NPC_VX001, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + { + if(m_bIsHardMode) + { + pTorso->CastSpell(pTorso, SPELL_EMERGENCY_MODE, false); + m_bHasMoreHp = true; + m_uiHpCheckTimer = 1000; + m_uiTorsoGUID = pTorso->GetGUID(); + } + else + { + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_VX001); + m_uiPhaseDelayTimer = 10000; + } + } + } + else m_uiPhaseDelayTimer -= uiDiff; + + if (m_uiHpCheckTimer <= uiDiff && m_bHasMoreHp) + { + if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID)) + pTorso->SetHealth(pTorso->GetMaxHealth()+ (pTorso->GetMaxHealth() * 0.3)); + m_bHasMoreHp = false; + m_uiPhaseDelayTimer = 10000; + m_uiHpCheckTimer = 10000; + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_VX001); + // start again 3 fires + for(uint8 i = 0; i < 3; i++) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTarget->InterruptNonMeleeSpells(true); + pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false); + } + } + } + else m_uiHpCheckTimer -= uiDiff; + + break; + } + case PHASE_VX001: + // VX001 phase: see above script + break; + case PHASE_TRANS_2: + { + if(m_uiPhaseDelayTimer < uiDiff && !m_bHasMoreHp) + { + DoScriptText(SAY_HEAD_ACTIVE, m_creature); + if(Creature* pHead = m_creature->SummonCreature(NPC_AERIAL_UNIT, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + { + if(m_bIsHardMode) + { + pHead->CastSpell(pHead, SPELL_EMERGENCY_MODE, false); + m_bHasMoreHp = true; + m_uiHpCheckTimer = 1000; + } + else + { + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_AERIAL); + m_uiPhaseDelayTimer = 15000; + } + m_uiHeadGUID = pHead->GetGUID(); + } + } + else m_uiPhaseDelayTimer -= uiDiff; + + if (m_uiHpCheckTimer <= uiDiff && m_bHasMoreHp) + { + if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID)) + pHead->SetHealth(pHead->GetMaxHealth()+ (pHead->GetMaxHealth() * 0.3)); + m_bHasMoreHp = false; + m_uiPhaseDelayTimer = 15000; + m_uiHpCheckTimer = 10000; + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_AERIAL); + // start again 3 fires + for(uint8 i = 0; i < 3; i++) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTarget->InterruptNonMeleeSpells(true); + pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false); + } + } + } + else m_uiHpCheckTimer -= uiDiff; + + break; + } + case PHASE_AERIAL: + // Aerial Unit phase: see above script + break; + case PHASE_TRANS_3: + { + if(m_uiPhaseDelayTimer < uiDiff && !m_bIsRobotReady) + { + if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK))) + { + if(pTank->isAlive()) + { + pTank->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z); + m_uiTankGUID = pTank->GetGUID(); + m_bIsRobotReady = true; + m_uiRobotDelayTimer = 15000; + } + else + EnterEvadeMode(); + } + m_uiPhaseDelayTimer = 100000; + } + else m_uiPhaseDelayTimer -= uiDiff; + + if(m_uiRobotDelayTimer < uiDiff && m_bIsRobotReady && !m_bHasMoreHp) + { + DoScriptText(SAY_ROBOT_ACTIVE, m_creature); + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + ((boss_leviathan_mkAI*)pTank->AI())->SetPhase(); + + if(Creature* pTorso = m_creature->SummonCreature(NPC_VX001, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000)) + { + ((boss_vx001AI*)pTorso->AI())->SetPhase(); + m_uiTorsoGUID = pTorso->GetGUID(); + } + + if(Creature* pHead = m_creature->SummonCreature(NPC_AERIAL_UNIT, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000)) + { + ((boss_aerial_command_unitAI*)pHead->AI())->SetPhase(); + m_uiHeadGUID = pHead->GetGUID(); + } + + if(m_bIsHardMode) + { + if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID)) + pTorso->CastSpell(pTorso, SPELL_EMERGENCY_MODE, false); + if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID)) + pHead->CastSpell(pHead, SPELL_EMERGENCY_MODE, false); + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + pTank->CastSpell(pTank, SPELL_EMERGENCY_MODE, false); + m_bHasMoreHp = true; + m_uiHpCheckTimer = 1000; + } + else + { + if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID)) + pTorso->SetHealth(pTorso->GetMaxHealth() * 0.5); + if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID)) + pHead->SetHealth(pHead->GetMaxHealth() * 0.5); + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + pTank->SetHealth(pTank->GetMaxHealth() * 0.5); + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_ROBOT); + } + m_uiRobotDelayTimer = 100000; + } + else m_uiRobotDelayTimer -= uiDiff; + + if (m_uiHpCheckTimer <= uiDiff && m_bHasMoreHp) + { + if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID)) + pHead->SetHealth(pHead->GetMaxHealth() * 0.5); + if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID)) + pTorso->SetHealth(pTorso->GetMaxHealth()* 0.5); + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + pTank->SetHealth(pTank->GetMaxHealth()* 0.5); + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_ROBOT); + // start again 3 fires + for(uint8 i = 0; i < 3; i++) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTarget->InterruptNonMeleeSpells(true); + pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false); + } + } + m_uiHpCheckTimer = 10000; + } + else m_uiHpCheckTimer -= uiDiff; + + break; + } + case PHASE_ROBOT: + { + if(m_pInstance->GetData(TYPE_LEVIATHAN_MK) == SPECIAL && !m_bHasChecked) + { + m_uiSelfRepairTimer = 15000; + m_bIsTankDead = true; + m_bHasChecked = true; + } + if(m_pInstance->GetData(TYPE_VX001) == SPECIAL && !m_bHasChecked) + { + m_uiSelfRepairTimer = 15000; + m_bIsTorsoDead = true; + m_bHasChecked = true; + } + if(m_pInstance->GetData(TYPE_AERIAL_UNIT) == SPECIAL && !m_bHasChecked) + { + m_uiSelfRepairTimer = 15000; + m_bIsHeadDead = true; + m_bHasChecked = true; + } + + if(m_uiSelfRepairTimer < uiDiff && m_bHasChecked) + { + if(m_pInstance->GetData(TYPE_LEVIATHAN_MK) == SPECIAL) + m_bIsTankDead = true; + if(m_pInstance->GetData(TYPE_VX001) == SPECIAL) + m_bIsTorsoDead = true; + if(m_pInstance->GetData(TYPE_AERIAL_UNIT) == SPECIAL) + m_bIsHeadDead = true; + + if(m_bIsTankDead && m_bIsTorsoDead && m_bIsHeadDead) + { + DoScriptText(SAY_ROBOT_DEATH, m_creature); + m_uiOutroTimer = 15000; + m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_OUTRO); + } + else + { + m_bHasChecked = false; + if(m_bIsTankDead) + { + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + ((boss_leviathan_mkAI*)pTank->AI())->Repair(); + } + if(m_bIsTorsoDead) + { + if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID)) + ((boss_vx001AI*)pTorso->AI())->Repair(); + } + if(m_bIsHeadDead) + { + if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID)) + ((boss_aerial_command_unitAI*)pHead->AI())->Repair(); + } + } + m_uiSelfRepairTimer = 1000; + } + else m_uiSelfRepairTimer -= uiDiff; + + break; + } + case PHASE_OUTRO: + { + if(m_uiOutroTimer < uiDiff) + { + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + m_creature->DealDamage(pTank, pTank->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID)) + m_creature->DealDamage(pHead, pHead->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID)) + m_creature->DealDamage(pTorso, pTorso->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + DoOutro(); + m_uiOutroTimer = 60000; + } + else m_uiOutroTimer -= uiDiff; + + break; + } + } + + // berserk + if (m_uiBerserkTimer <= uiDiff) + { + if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID)) + { + if(pTank && pTank->isAlive()) + pTank->CastSpell(pTank, SPELL_BERSERK, false); + } + + if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID)) + { + if(pTorso && pTorso->isAlive()) + pTorso->CastSpell(pTorso, SPELL_BERSERK, false); + } + + if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID)) + { + if(pHead && pHead->isAlive()) + pHead->CastSpell(pHead, SPELL_BERSERK, false); + } + + m_uiBerserkTimer = 330000; + } + else + m_uiBerserkTimer -= uiDiff; + + // self destruct platform in hard mode + if (m_uiSelfDestructTimer < uiDiff && m_bIsHardMode) + { + m_creature->SummonCreature(NPC_MIMIRON_INFERNO, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); + // visual part, hacky way + if(Creature* pTemp = m_creature->SummonCreature(NPC_MIMIRON_FOCUS, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000)) + { + pTemp->GetMotionMaster()->MoveIdle(); + pTemp->CombatStop(); + pTemp->SetDisplayId(11686); // make invisible + pTemp->CastSpell(pTemp, SPELL_SELF_DESTRUCTION, false); + } + m_uiSelfDestructTimer = 60000; + } + else m_uiSelfDestructTimer -= uiDiff; + } +}; + +// Leviathan MK turret +// used in phase 1; should be attached by a vehicle seat to the Leviathan MK +struct MANGOS_DLL_DECL leviathan_turretAI : public ScriptedAI +{ + leviathan_turretAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pCreature->SetVisibility(VISIBILITY_OFF); + //pCreature->setFaction(14); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiPlasmaBlastTimer; + uint32 m_uiNapalmShellTimer; + + void Reset() + { + m_uiPlasmaBlastTimer = 20000; + m_uiNapalmShellTimer = 10000; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiPlasmaBlastTimer < uiDiff) + { + if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK))) + { + DoScriptText(EMOTE_PLASMA_BLAST, m_creature); + if (Unit* pTarget = pTank->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_PLASMA_BLAST : SPELL_PLASMA_BLAST_H); + } + m_uiPlasmaBlastTimer = 30000; + } + else m_uiPlasmaBlastTimer -= uiDiff; + + if(m_uiNapalmShellTimer < uiDiff) + { + if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK))) + { + if (Unit* pTarget = pTank->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if(!pTank->IsWithinDistInMap(pTarget, 15)) + { + DoCast(pTarget, m_bIsRegularMode ? SPELL_NAPALM_SHELL : SPELL_NAPALM_SHELL_H); + m_uiNapalmShellTimer = 7000; + } + } + } + } + else m_uiNapalmShellTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL mob_proximity_mineAI : public ScriptedAI +{ + mob_proximity_mineAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiExplosionTimer; + uint32 m_uiRangeCheckTimer; + uint32 m_uiDieTimer; + + void Reset() + { + m_uiExplosionTimer = 60000; + m_uiRangeCheckTimer = 1000; + m_uiDieTimer = 65000; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_MIMIRON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiDieTimer < uiDiff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else + m_uiDieTimer -= uiDiff; + + if(m_uiExplosionTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLOSION : SPELL_EXPLOSION_H); + m_uiDieTimer = 500; + m_uiExplosionTimer = 20000; + } + else m_uiExplosionTimer -= uiDiff; + + if (m_uiRangeCheckTimer < uiDiff) + { + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 2)) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLOSION : SPELL_EXPLOSION_H); + m_uiDieTimer = 500; + m_uiRangeCheckTimer = 5000; + } + else + m_uiRangeCheckTimer = 500; + } + else m_uiRangeCheckTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL mob_bomb_botAI : public ScriptedAI +{ + mob_bomb_botAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiRangeCheckTimer; + uint32 m_uiDieTimer; + + void Reset() + { + m_uiRangeCheckTimer = 1000; + m_uiDieTimer = 600000; + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if(uiDamage > m_creature->GetHealth()) + { + DoCast(m_creature, SPELL_BOMB_BOT); + m_creature->SetHealth(m_creature->GetMaxHealth()); + uiDamage = 0; + m_uiDieTimer = 500; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiDieTimer < uiDiff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else + m_uiDieTimer -= uiDiff; + + if (m_uiRangeCheckTimer < uiDiff) + { + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 2)) + { + DoCast(m_creature, SPELL_BOMB_BOT); + m_uiDieTimer = 500; + m_uiRangeCheckTimer = 5000; + } + else + m_uiRangeCheckTimer = 500; + } + else m_uiRangeCheckTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_assault_botAI : public ScriptedAI +{ + mob_assault_botAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiMagneticFieldTimer; + + void Reset() + { + m_uiMagneticFieldTimer = 5000; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiMagneticFieldTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_MAGNETIC_FIELD); + m_uiMagneticFieldTimer = urand(10000, 15000); + } + else m_uiMagneticFieldTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_emergency_botAI : public ScriptedAI +{ + mob_emergency_botAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + uint32 m_uiWaterSprayTimer; + + void Reset() + { + m_uiWaterSprayTimer = urand(5000, 10000); + if(!m_bIsRegularMode) + DoCast(m_creature, SPELL_DEAFENING_SIREN); + } + + void SuppressFires() + { + std::list lFires; + GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, 15.0f); + GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, 15.0f); + if (!lFires.empty()) + { + for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->ForcedDespawn(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_uiWaterSprayTimer < uiDiff) + { + DoCast(m_creature, SPELL_WATER_SPRAY); + SuppressFires(); + m_uiWaterSprayTimer = urand(7000, 12000); + } + else m_uiWaterSprayTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_frost_bomb_ulduarAI : public ScriptedAI +{ + mob_frost_bomb_ulduarAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pCreature->setFaction(14); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance *pInstance; + bool m_bIsRegularMode; + + uint32 m_uiExplosionTimer; + uint32 m_uiDieTimer; + + void Reset() + { + m_uiExplosionTimer = 10000; + m_uiDieTimer = 15000; + DoCast(m_creature, SPELL_FROST_BOMB_VISUAL); + } + + void SuppressFires() + { + std::list lFires; + GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, 30.0f); + GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, 30.0f); + if (!lFires.empty()) + { + for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->ForcedDespawn(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiDieTimer < uiDiff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else + m_uiDieTimer -= uiDiff; + + if (m_uiExplosionTimer < uiDiff) + { + DoCast(m_creature, SPELL_FROST_BOMB_EXPL); + SuppressFires(); + m_uiExplosionTimer = 100000; + m_uiDieTimer = 500; + } + else m_uiExplosionTimer -= uiDiff; + } +}; + +// Flames used in hard mode +struct MANGOS_DLL_DECL mob_mimiron_flamesAI : public ScriptedAI +{ + mob_mimiron_flamesAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->setFaction(14); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiFlamesSpreadTimer; + + void Reset() + { + DoCast(m_creature, SPELL_FLAMES); + m_uiFlamesSpreadTimer = 5000; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_MIMIRON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + // spread flames + if(m_uiFlamesSpreadTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_FLAMES_SPREAD); + m_uiFlamesSpreadTimer = urand(2000, 5000); + } + else m_uiFlamesSpreadTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL mob_mimiron_infernoAI : public ScriptedAI +{ + mob_mimiron_infernoAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->setFaction(14); + pCreature->SetDisplayId(11686); // make invisible + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiFlamesTimer; + + void Reset() + { + DoCast(m_creature, SPELL_SELF_DESTRUCTION); + m_uiFlamesTimer = 2000; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_MIMIRON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if(m_uiFlamesTimer < uiDiff) + { + DoCast(m_creature, SPELL_SELF_DESTRUCT); + m_uiFlamesTimer = 1000; + } + else m_uiFlamesTimer -= uiDiff; + } +}; + +// item script, used to bring the aerial unit down +struct MANGOS_DLL_DECL mob_magnetic_coreAI : public ScriptedAI +{ + mob_magnetic_coreAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiSpellTimer; + uint32 m_uiDieTimer; + + void Reset() + { + m_uiSpellTimer = 2000; + m_uiDieTimer = 23000; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiSpellTimer < uiDiff) + { + if(Creature* pAerial = GetClosestCreatureWithEntry(m_creature, NPC_AERIAL_UNIT, 10.0f)) + { + DoCast(pAerial, SPELL_MAGNETIC_CORE); + ((boss_aerial_command_unitAI*)pAerial->AI())->SetToGround(); + } + m_uiSpellTimer = 100000; + } + else m_uiSpellTimer -= uiDiff; + + if (m_uiDieTimer < uiDiff) + m_creature->ForcedDespawn(); + else + m_uiDieTimer -= uiDiff; + } +}; + +// Red button -> used to start the hard mode +bool GOHello_go_red_button(Player* pPlayer, GameObject* pGo) +{ + ScriptedInstance* m_pInstance = (ScriptedInstance*)pGo->GetInstanceData(); + + if (!m_pInstance) + return false; + + if (Creature* pMimiron = pGo->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MIMIRON))) + { + pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + pPlayer->CastSpell(pPlayer, SPELL_FLAMES_SUMMON, false); + if(pMimiron->isAlive() && m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_INTRO) + ((boss_mimironAI*)pMimiron->AI())->m_bIsHardMode = true; + m_pInstance->SetData(TYPE_MIMIRON_HARD, IN_PROGRESS); + } + + return false; +} + +CreatureAI* GetAI_boss_mimiron(Creature* pCreature) +{ + return new boss_mimironAI(pCreature); +} + +CreatureAI* GetAI_boss_leviathan_mk(Creature* pCreature) +{ + return new boss_leviathan_mkAI(pCreature); +} + +CreatureAI* GetAI_boss_vx001(Creature* pCreature) +{ + return new boss_vx001AI(pCreature); +} + +CreatureAI* GetAI_boss_aerial_command_unit(Creature* pCreature) +{ + return new boss_aerial_command_unitAI(pCreature); +} + +CreatureAI* GetAI_leviathan_turret(Creature* pCreature) +{ + return new leviathan_turretAI(pCreature); +} + +CreatureAI* GetAI_mob_proximity_mine(Creature* pCreature) +{ + return new mob_proximity_mineAI(pCreature); +} + +CreatureAI* GetAI_mob_bomb_bot(Creature* pCreature) +{ + return new mob_bomb_botAI(pCreature); +} + +CreatureAI* GetAI_mob_assault_bot(Creature* pCreature) +{ + return new mob_assault_botAI(pCreature); +} + +CreatureAI* GetAI_mob_emergency_bot(Creature* pCreature) +{ + return new mob_emergency_botAI(pCreature); +} + +CreatureAI* GetAI_mob_frost_bomb_ulduar(Creature* pCreature) +{ + return new mob_frost_bomb_ulduarAI(pCreature); +} + +CreatureAI* GetAI_mob_mimiron_flames(Creature* pCreature) +{ + return new mob_mimiron_flamesAI(pCreature); +} + +CreatureAI* GetAI_mob_mimiron_inferno(Creature* pCreature) +{ + return new mob_mimiron_infernoAI(pCreature); +} + +CreatureAI* GetAI_mob_magnetic_core(Creature* pCreature) +{ + return new mob_magnetic_coreAI(pCreature); +} + void AddSC_boss_mimiron() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_mimiron"; + newscript->GetAI = &GetAI_boss_mimiron; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_leviathan_mk"; + newscript->GetAI = &GetAI_boss_leviathan_mk; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "leviathan_turret"; + newscript->GetAI = &GetAI_leviathan_turret; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_vx001"; + newscript->GetAI = &GetAI_boss_vx001; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_aerial_command_unit"; + newscript->GetAI = &GetAI_boss_aerial_command_unit; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_proximity_mine"; + newscript->GetAI = &GetAI_mob_proximity_mine; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_bomb_bot"; + newscript->GetAI = &GetAI_mob_bomb_bot; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_assault_bot"; + newscript->GetAI = &GetAI_mob_assault_bot; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_emergency_bot"; + newscript->GetAI = &GetAI_mob_emergency_bot; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_frost_bomb_ulduar"; + newscript->GetAI = &GetAI_mob_frost_bomb_ulduar; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_mimiron_flames"; + newscript->GetAI = &GetAI_mob_mimiron_flames; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_mimiron_inferno"; + newscript->GetAI = &GetAI_mob_mimiron_inferno; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_magnetic_core"; + newscript->GetAI = &GetAI_mob_magnetic_core; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "go_red_button"; + newscript->pGOUse = &GOHello_go_red_button; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp b/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp index 332e6b54f..529a2c93c 100644 --- a/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_razorscale -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: harpoons display should change when clicked SDCategory: Ulduar EndScriptData */ @@ -26,19 +26,864 @@ EndScriptData */ enum { - SAY_INTRO_WELCOME = -1603036, - SAY_INTRO_1 = -1603037, - SAY_INTRO_2 = -1603038, - SAY_INTRO_3 = -1603039, - SAY_GROUNDED = -1603040, - SAY_EXTINGUISH_FIRE = -1603041, + //yells/emotes + SAY_INTRO = -1603020, + SAY_AGGRO1 = -1603021, + SAY_AGGRO2 = -1603022, + SAY_AGGRO3 = -1603023, + SAY_GROUND = -1603024, + EMOTE_DEEP_BREATH = -1603025, + SAY_FIRES_EXTINGUISH = -1603026, + EMOTE_HARPOON = -1603353, + EMOTE_GROUNDED = -1603354, - EMOTE_BREATH = -1603042, - EMOTE_HARPOON_READY = -1603043, - EMOTE_GROUNDED = -1603044, + //razorscale air phase + SPELL_FIREBALL = 62796, + SPELL_FIREBALL_H = 63815, + SPELL_WING_BUFFET = 62666, + SPELL_STUN = 62794, + SPELL_SUMMON_DWARF = 62916, + //both + SPELL_BERSERK = 47008, + DEVOURING_FLAME_VISUAL = 63236, + SPELL_FLAME_BREATH = 63317, + SPELL_FLAME_BREATH_H = 64021, + //ground + SPELL_FLAME_BUFFET = 64016, + SPELL_FLAME_BUFFET_H = 64023, + SPELL_FUSE_ARMOR = 64771, + + //devouring flame target + AURA_DEVOURING_FLAME = 64709, + AURA_DEVOURING_FLAME_H = 64734, + + // mole machine + NPC_MOLE_MACHINE = 33245, // used to summon adds in phase 1 + NPC_HARPOONS_DUMMY = 33282, // used to cast spells for harpoons + SPELL_SUMMON_MOLE_MACHINE = 73071, + + // harpoons + SPELL_HARPOON_SHOT = 63659, + GO_HARPOON = 194543, // 41, 42, 194519 + + //dark rune watcher + SPELL_LIGHTNING_BOLT = 63809, + SPELL_LIGHTNING_BOLT_H = 64696, + SPELL_CHAIN_LIGHTNING = 64758, + SPELL_CHAIN_LIGHTNING_H = 64759, + + //dark rune sentinel + SPELL_BATTLE_SHOUT = 46763, + SPELL_BATTLE_SHOUT_H = 64062, + SPELL_WHIRLWIND = 63808, + + //dark rune guardian + SPELL_STORMSTRIKE = 64757, + + //NPC ids + MOB_DARK_RUNE_WATCHER = 33453, + MOB_DARK_RUNE_SENTINEL = 33846, + MOB_DARK_RUNE_GUARDIAN = 33388, + + NPC_EXP_ENGINEER = 33287, + + ACHIEV_QUICK_SHAVE = 2919, + ACHIEV_QUICK_SHAVE_H = 2921, + ACHIEV_MEDIUM_RARE = 2923, + ACHIEV_MEDIUM_RARE_H = 2924, +}; + +//Positional defines +struct LocationsXY +{ + float x, y, z, o; + uint32 id; +}; + +static LocationsXY PositionLoc[]= +{ + {621.633301f, -228.671371f, 391.180328f},//right + {564.140198f, -222.049149f, 391.517212f},//left + {591.629761f, -209.629761f, 392.629761f},//middle + {587.629761f, -179.022522f, 391.625061f},//ground + {587.629761f, -179.022522f, 435.415070f},//air +}; + +#define HOME_X 587.546997f +#define HOME_Y -174.927002f + +#define GOSSIP_START "Bring Razorscale down!" + +//expedition commander +// start the event +struct MANGOS_DLL_DECL npc_expedition_commanderAI : public ScriptedAI +{ + npc_expedition_commanderAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bHasPlayerNear = false; + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool m_bHasPlayerNear; + bool m_bIsIntro; + uint64 m_uiPlayerGUID; + uint32 m_uiSpeech_Timer; + uint32 m_uiIntro_Phase; + + void Reset() + { + m_uiPlayerGUID = 0; + m_uiSpeech_Timer = 3000; + m_bIsIntro = false; + m_uiIntro_Phase = 0; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_bHasPlayerNear && m_creature->IsWithinDistInMap(pWho, 40.0f)) + { + DoScriptText(SAY_INTRO, m_creature); + m_bHasPlayerNear = true; + } + } + + void GetRazorDown() + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RAZORSCALE))) + { + pTemp->SetInCombatWithZone(); + if(Unit* pPlayer = m_creature->GetMap()->GetUnit( m_uiPlayerGUID)) + { + pTemp->AddThreat(pPlayer,0.0f); + pTemp->AI()->AttackStart(pPlayer); + } + } + } + + void BeginRazorscaleEvent(Player* pPlayer) + { + m_uiPlayerGUID = pPlayer->GetGUID(); + m_bIsIntro = true; + m_uiSpeech_Timer = 3000; + m_uiIntro_Phase = 0; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_bIsIntro) + { + if(m_uiSpeech_Timer < uiDiff) + { + switch(m_uiIntro_Phase) + { + case 0: + if(Creature* pEngineer = GetClosestCreatureWithEntry(m_creature, NPC_EXP_ENGINEER, 50.0f)) + DoScriptText(SAY_AGGRO1, pEngineer); + GetRazorDown(); + ++m_uiIntro_Phase; + m_uiSpeech_Timer = 5000; + break; + case 1: + DoScriptText(SAY_AGGRO2, m_creature); + ++m_uiIntro_Phase; + m_uiSpeech_Timer = 7000; + break; + case 2: + if(Creature* pEngineer = GetClosestCreatureWithEntry(m_creature, NPC_EXP_ENGINEER, 50.0f)) + DoScriptText(SAY_AGGRO3, pEngineer); + ++m_uiIntro_Phase; + m_uiSpeech_Timer = 5000; + break; + case 3: + m_bIsIntro = false; + ++m_uiIntro_Phase; + m_uiSpeech_Timer = 10000; + break; + default: + m_uiSpeech_Timer = 100000; + } + }else m_uiSpeech_Timer -= uiDiff; + } + } }; +CreatureAI* GetAI_npc_expedition_commander(Creature* pCreature) +{ + return new npc_expedition_commanderAI(pCreature); +} + +bool GossipHello_npc_expedition_commander(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance* pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + + if(pInstance->GetData(TYPE_RAZORSCALE) != DONE) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + return true; +} + +bool GossipSelect_npc_expedition_commander(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + pPlayer->CLOSE_GOSSIP_MENU(); + pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + ((npc_expedition_commanderAI*)pCreature->AI())->BeginRazorscaleEvent(pPlayer); + } + + return true; +} + +// devouring_flame_target +struct MANGOS_DLL_DECL mob_devouring_flame_targetAI : public ScriptedAI +{ + mob_devouring_flame_targetAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiDeath_Timer; + + void Reset() + { + m_uiDeath_Timer = 25500; + m_creature->SetDisplayId(11686); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoCast(m_creature, m_bIsRegularMode ? AURA_DEVOURING_FLAME : AURA_DEVOURING_FLAME_H); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiDeath_Timer < uiDiff) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDeath_Timer -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_devouring_flame_target(Creature* pCreature) +{ + return new mob_devouring_flame_targetAI(pCreature); +} + +// dark rune watcher +struct MANGOS_DLL_DECL mob_dark_rune_watcherAI : public ScriptedAI +{ + mob_dark_rune_watcherAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(5000, 10000); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < diff) + { + switch(urand(0, 1)) + { + case 0: + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_LIGHTNING_BOLT : SPELL_LIGHTNING_BOLT_H); + break; + case 1: + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H); + break; + } + m_uiSpell_Timer = urand(5000, 10000); + }else m_uiSpell_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_watcher(Creature* pCreature) +{ + return new mob_dark_rune_watcherAI(pCreature); +} + +// dark rune sentinel +struct MANGOS_DLL_DECL mob_dark_rune_sentinelAI : public ScriptedAI +{ + mob_dark_rune_sentinelAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiWhirl_Timer; + uint32 m_uiShout_Timer; + + void Reset() + { + m_uiWhirl_Timer = 10000; + m_uiShout_Timer = 2000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiWhirl_Timer < diff) + { + DoCast(m_creature, SPELL_WHIRLWIND); + m_uiWhirl_Timer = urand(10000, 15000); + }else m_uiWhirl_Timer -= diff; + + if (m_uiShout_Timer < diff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_BATTLE_SHOUT : SPELL_BATTLE_SHOUT_H); + m_uiShout_Timer = 30000; + }else m_uiShout_Timer -= diff; + + DoMeleeAttackIfReady(); + } + +}; + +CreatureAI* GetAI_mob_dark_rune_sentinel(Creature* pCreature) +{ + return new mob_dark_rune_sentinelAI(pCreature); +} + +// dark rune guardian +struct MANGOS_DLL_DECL mob_dark_rune_guardianAI : public ScriptedAI +{ + mob_dark_rune_guardianAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiStormstrike_Timer; + + void Reset() + { + m_uiStormstrike_Timer = 10000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiStormstrike_Timer < diff) + { + DoCast(m_creature->getVictim(), SPELL_STORMSTRIKE); + m_uiStormstrike_Timer = urand(7000, 13000); + }else m_uiStormstrike_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_guardian(Creature* pCreature) +{ + return new mob_dark_rune_guardianAI(pCreature); +} + +/// mole machine +// used to summon dwarfes +struct MANGOS_DLL_DECL mob_mole_machineAI : public ScriptedAI +{ + mob_mole_machineAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetDisplayId(11686); // make invisible + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiSummonTimer; + bool m_bIsSentinel; + + void Reset() + { + m_uiSummonTimer = 8000; + m_bIsSentinel = false; + DoCast(m_creature, SPELL_SUMMON_MOLE_MACHINE); + } + + void UpdateAI(const uint32 diff) + { + if (m_uiSummonTimer < diff) + { + // summon 2 dwarfes + if(!m_bIsSentinel) + { + if (Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_WATCHER, m_creature->GetPositionX() + 5, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + pTemp->SetInCombatWithZone(); + pTemp->GetMotionMaster()->MovePoint(0, HOME_X, HOME_Y, m_creature->GetPositionZ()); + } + if (Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_GUARDIAN, m_creature->GetPositionX() - 5, m_creature->GetPositionY() - 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + pTemp->SetInCombatWithZone(); + pTemp->GetMotionMaster()->MovePoint(0, HOME_X, HOME_Y, m_creature->GetPositionZ()); + } + } + // summon 1 sentinel + else + { + if (Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_SENTINEL, m_creature->GetPositionX() - 5, m_creature->GetPositionY() - 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + { + pTemp->SetInCombatWithZone(); + pTemp->GetMotionMaster()->MovePoint(0, HOME_X, HOME_Y, m_creature->GetPositionZ()); + } + } + m_uiSummonTimer = 60000; + }else m_uiSummonTimer -= diff; + } +}; + +CreatureAI* GetAI_mob_mole_machine(Creature* pCreature) +{ + return new mob_mole_machineAI(pCreature); +} + +//razorscale +struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI +{ + boss_razorscaleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiFireball_Timer; + uint32 m_uiDevouring_Flame_Timer; + uint32 m_uiFlame_Buffet_Timer; + uint32 m_uiFuse_Armor_Timer; + uint32 m_uiFlame_Breath_Timer; + uint32 m_uiWave1_spawn; //right side, 1 of each + uint32 m_uiWave2_spawn; //left side, 1 of each + uint32 m_uiWave3_spawn; // big guy + uint32 m_uiBerserk_Timer; + uint32 m_uiGrounded_Timer; // 8 secs after ground fase is over, adds come + uint32 m_uiGround_Cast; + uint32 m_uiGround_Knockback; + uint32 m_uiRepairHarpoonTimer; + uint8 m_uiHarpoonsRepaired; + uint8 m_uiMaxHarpoons; + uint64 m_uiHarpoonsGUID[4]; + uint32 m_uiTimetoground; + uint32 m_uiStun_Timer; + bool m_bAirphase; + bool m_bIsGrounded; + bool m_bHasBerserk; + bool m_bKnockback; + uint8 m_uiHarpoonsUsed; + uint8 m_uiFlyNo; + + std::list lHarpoons; + + void Reset() + { + m_uiFireball_Timer = 10000; // 10 secs for the first, fckin spam after that ~2secs + m_uiDevouring_Flame_Timer = 18000; // 18 secs first, 12 seconds after + m_uiWave1_spawn = urand(5000, 10000); + m_uiWave2_spawn = urand(5000, 10000); + m_uiWave3_spawn = urand(5000, 10000); + m_uiBerserk_Timer = 600000; // 10 min + m_uiTimetoground = 80000; + m_uiRepairHarpoonTimer = 53000; + m_uiHarpoonsRepaired = 0; + m_uiMaxHarpoons = m_bIsRegularMode ? 2 : 4; + for(int i = 0; i < m_uiMaxHarpoons; i++) + m_uiHarpoonsGUID[i] = 0; + m_bAirphase = false; + m_bIsGrounded = false; + m_bHasBerserk = false; + m_bKnockback = false; + m_uiFlyNo = 0; + m_uiHarpoonsUsed = 0; + lHarpoons.clear(); + + if(m_creature->GetPositionZ() < 435.0f) + { + m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f); + m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->GetMotionMaster()->MoveConfused(); + + if (Creature* pCommander = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_COMMANDER))) + pCommander->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_RAZORSCALE, DONE); + + if (m_uiFlyNo < 2) + { + // hacky way to complete achievements; use only if you have this function + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_QUICK_SHAVE : ACHIEV_QUICK_SHAVE_H); + } + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_RAZORSCALE, IN_PROGRESS); + + GetGameObjectListWithEntryInGrid(lHarpoons, m_creature, GO_BROKEN_HARPOON, 200.0f); + if (!lHarpoons.empty()) + { + int i = 0; + for(std::list::iterator iter = lHarpoons.begin(); iter != lHarpoons.end(); ++iter) + { + if ((*iter)) + { + m_uiHarpoonsGUID[i] = (*iter)->GetGUID(); + i += 1; + } + } + } + + m_bAirphase = true; + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f); + m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_RAZORSCALE, NOT_STARTED); + + BreakHarpoons(); + } + + void BreakHarpoons() + { + // reset harpoons + if (!lHarpoons.empty()) + { + for(std::list::iterator iter = lHarpoons.begin(); iter != lHarpoons.end(); ++iter) + { + if ((*iter)) + { + (*iter)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + //(*iter)->SetUInt32Value(GAMEOBJECT_DISPLAYID, 8631); + } + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // AIR PHASE + // air position check (sometimes it falls to the ground like a rock + if(m_creature->GetPositionZ() < 430.0f && m_bAirphase && !m_bIsGrounded) + { + m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f); + m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + + // air spells + if (m_uiFireball_Timer < uiDiff && m_bAirphase && !m_bIsGrounded) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(target, m_bIsRegularMode ? SPELL_FIREBALL : SPELL_FIREBALL_H); + m_uiFireball_Timer = 2000; + }else m_uiFireball_Timer -= uiDiff; + + if (m_uiDevouring_Flame_Timer < uiDiff && !m_bIsGrounded) + { + if (m_bAirphase) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(target, DEVOURING_FLAME_VISUAL); + } + else + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(target, DEVOURING_FLAME_VISUAL); + } + m_uiDevouring_Flame_Timer = 12000; + }else m_uiDevouring_Flame_Timer -= uiDiff; + + // repair harpoons + if (m_uiRepairHarpoonTimer < uiDiff && m_bAirphase && !m_bIsGrounded && m_uiHarpoonsRepaired <= m_uiMaxHarpoons) + { + if(GameObject* pHarpoon = m_pInstance->instance->GetGameObject(m_uiHarpoonsGUID[m_uiHarpoonsRepaired])) + { + pHarpoon->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + //pHarpoon->SetUInt32Value(GAMEOBJECT_DISPLAYID, 8245); + m_uiHarpoonsRepaired += 1; + } + DoScriptText(EMOTE_HARPOON, m_creature); + m_uiRepairHarpoonTimer = 20000; + } + else m_uiRepairHarpoonTimer -= uiDiff; + + // ground adds + if (m_uiWave1_spawn < uiDiff && m_bAirphase && !m_bIsGrounded) + { + m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[0].x, PositionLoc[0].y, PositionLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); + m_uiWave1_spawn = urand(40000, 50000); + }else m_uiWave1_spawn -= uiDiff; + + if (m_uiWave2_spawn < uiDiff && m_bAirphase && !m_bIsGrounded) + { + m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[1].x, PositionLoc[1].y, PositionLoc[1].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); + m_uiWave2_spawn = urand(40000, 50000); + }else m_uiWave2_spawn -= uiDiff; + + if (m_uiWave3_spawn < uiDiff && m_bAirphase && !m_bIsGrounded) + { + switch(urand(0, 2)) //33% chance of spawning + { + case 0: + break; + case 1: + if(Creature* pTemp = m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[2].x, PositionLoc[2].y, PositionLoc[2].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000)) + ((mob_mole_machineAI*)pTemp->AI())->m_bIsSentinel = true; + break; + case 2: + break; + } + m_uiWave3_spawn = urand(40000, 50000); + }else m_uiWave3_spawn -= uiDiff; + + // berserk + if (m_uiBerserk_Timer < uiDiff && !m_bHasBerserk) + { + DoCast(m_creature, SPELL_BERSERK); + m_bHasBerserk = true; + }else m_uiBerserk_Timer -= uiDiff; + + if (m_uiHarpoonsUsed == m_uiMaxHarpoons && m_bAirphase) + { + if(Creature* pCommander = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_COMMANDER))) + DoScriptText(SAY_GROUND, pCommander); + m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[3].x, PositionLoc[3].y, PositionLoc[3].z, 1.5); + m_creature->SendMonsterMove(PositionLoc[3].x, PositionLoc[3].y, PositionLoc[3].z, SPLINETYPE_FACINGSPOT, m_creature->GetSplineFlags(), 1); + // timers + m_uiHarpoonsUsed = 0; + m_bIsGrounded = true; + m_uiStun_Timer = 2000; + m_uiGround_Cast = 35000; + m_uiGrounded_Timer = 45000; + // make boss land + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + }else m_uiTimetoground -= uiDiff; + + if (m_uiStun_Timer < uiDiff && m_bIsGrounded) + { + DoCast(m_creature, SPELL_STUN); + m_uiStun_Timer = 60000; + }else m_uiStun_Timer -= uiDiff; + + if (m_uiGround_Cast < uiDiff && m_bIsGrounded) + { + if (Creature* pCommander = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_COMMANDER))) + m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pCommander->GetGUID()); + m_creature->RemoveAurasDueToSpell(SPELL_STUN); + DoScriptText(EMOTE_DEEP_BREATH, m_creature); + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H); + m_uiGround_Cast = 15000; + m_uiGround_Knockback = 7000; + }else m_uiGround_Cast -= uiDiff; + + if (m_uiGround_Knockback < uiDiff && m_bIsGrounded) + { + m_creature->CastStop(); + DoCast(m_creature, SPELL_WING_BUFFET); + m_uiGround_Knockback = 15000; + m_uiGrounded_Timer = 3000; + }else m_uiGround_Knockback -= uiDiff; + + if (m_uiGrounded_Timer < uiDiff && m_bIsGrounded) + { + m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f); + m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + + m_bIsGrounded = false; + m_uiFireball_Timer = 10000; + m_uiDevouring_Flame_Timer = 18000; + m_uiWave1_spawn = urand(5000, 10000); + m_uiWave2_spawn = urand(5000, 10000); + m_uiWave3_spawn = urand(5000, 10000); + m_uiRepairHarpoonTimer = 50000; + m_uiHarpoonsRepaired = 0; + BreakHarpoons(); + // make boss fly + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + // achiev counter + m_uiFlyNo += 1; + }else m_uiGrounded_Timer -= uiDiff; + + // make boss land at 50% hp + if (m_bAirphase && m_creature->GetHealthPercent() < 50) + { + if (m_creature->HasAura(SPELL_STUN)) + m_creature->RemoveAurasDueToSpell(SPELL_STUN); + + DoScriptText(EMOTE_GROUNDED, m_creature); + m_uiGround_Knockback = m_bIsGrounded ? 0 : 3000; + m_bAirphase = false; + m_bIsGrounded = false; + m_uiDevouring_Flame_Timer = 12000; + m_uiFlame_Buffet_Timer = 10000; //every 10 secs + m_uiFuse_Armor_Timer = 13000; //every ~13 + m_uiFlame_Breath_Timer = 6000; //every 14 + SetCombatMovement(true); + + // make boss land + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + + // LAND PHASE + // knockback at the beginning at the land phase + if (m_uiGround_Knockback < uiDiff && !m_bKnockback && !m_bAirphase) + { + m_creature->CastStop(); + DoCast(m_creature, SPELL_WING_BUFFET); + m_bKnockback = true; + }else m_uiGround_Knockback -= uiDiff; + + if (m_uiFuse_Armor_Timer < uiDiff && !m_bAirphase) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget, SPELL_FUSE_ARMOR); + m_uiFuse_Armor_Timer = 13000; + } else m_uiFuse_Armor_Timer -= uiDiff; + + if (m_uiFlame_Buffet_Timer < uiDiff && !m_bAirphase) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BUFFET : SPELL_FLAME_BUFFET_H); + m_uiFlame_Buffet_Timer = 13000; + }else m_uiFlame_Buffet_Timer -= uiDiff; + + if (m_uiFlame_Breath_Timer < uiDiff && !m_bAirphase) + { + DoScriptText(EMOTE_DEEP_BREATH, m_creature); + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H); + m_uiFlame_Breath_Timer = 14000; + }else m_uiFlame_Breath_Timer -= uiDiff; + + if (!m_bAirphase && !m_bIsGrounded) + DoMeleeAttackIfReady(); + + if (m_creature->GetDistance2d(HOME_X, HOME_Y) > 100) + EnterEvadeMode(); + } +}; + +CreatureAI* GetAI_boss_razorscale(Creature* pCreature) +{ + return new boss_razorscaleAI(pCreature); +} + +bool GOHello_go_broken_harpoon(Player* pPlayer, GameObject* pGo) +{ + ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); + + if (!pInstance) + return false; + + pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + if (Creature* pRazor = pGo->GetMap()->GetCreature(pInstance->GetData64(NPC_RAZORSCALE))) + ((boss_razorscaleAI*)pRazor->AI())->m_uiHarpoonsUsed += 1; + + return false; +} + void AddSC_boss_razorscale() { + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "boss_razorscale"; + NewScript->GetAI = GetAI_boss_razorscale; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_devouring_flame_target"; + NewScript->GetAI = &GetAI_mob_devouring_flame_target; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_dark_rune_watcher"; + NewScript->GetAI = &GetAI_mob_dark_rune_watcher; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_dark_rune_sentinel"; + NewScript->GetAI = &GetAI_mob_dark_rune_sentinel; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_dark_rune_guardian"; + NewScript->GetAI = &GetAI_mob_dark_rune_guardian; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_mole_machine"; + NewScript->GetAI = &GetAI_mob_mole_machine; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "npc_expedition_commander"; + NewScript->GetAI = &GetAI_npc_expedition_commander; + NewScript->pGossipHello = &GossipHello_npc_expedition_commander; + NewScript->pGossipSelect = &GossipSelect_npc_expedition_commander; + NewScript->RegisterSelf(); + NewScript = new Script; + NewScript->Name = "go_broken_harpoon"; + NewScript->pGOUse = &GOHello_go_broken_harpoon; + NewScript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_thorim.cpp b/scripts/northrend/ulduar/ulduar/boss_thorim.cpp index 27bc53884..1fd90ae24 100644 --- a/scripts/northrend/ulduar/ulduar/boss_thorim.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_thorim.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_thorim -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: Implement lightning orbs, summon Sit on the platform in the first 3 min. SDCategory: Ulduar EndScriptData */ @@ -26,36 +26,1740 @@ EndScriptData */ enum { - SAY_AGGRO_1 = -1603138, - SAY_AGGRO_2 = -1603139, - SAY_SPECIAL_1 = -1603140, - SAY_SPECIAL_2 = -1603141, - SAY_SPECIAL_3 = -1603142, - SAY_JUMP = -1603143, + //yells + SAY_AGGRO1 = -1603221, + SAY_AGGRO2 = -1603222, + SAY_SPECIAL1 = -1603223, + SAY_SPECIAL2 = -1603224, + SAY_SPECIAL3 = -1603225, + SAY_JUMP = -1603226, + SAY_SLAY1 = -1603227, + SAY_SLAY2 = -1603228, + SAY_BERSERK = -1603229, + SAY_ARENA_WIPE = -1603230, + SAY_DEATH = -1603231, + SAY_OUTRO1 = -1603232, + SAY_OUTRO2 = -1603233, + SAY_OUTRO3 = -1603234, + SAY_OUTRO_HARD1 = -1603235, + SAY_OUTRO_HARD2 = -1603236, + SAY_OUTRO_HARD3 = -1603237, - SAY_SLAY_1 = -1603144, - SAY_SLAY_2 = -1603145, - SAY_BERSERK = -1603146, + // Sif + SAY_SIF_INTRO = -1603185, + SAY_SIF_EVENT = -1603186, + SAY_SIF_DESPAWN = -1603187, - SAY_ARENA_WIPE = -1603147, - SAY_DEFEATED = -1603148, + // spells + // phase1 + SPELL_SHEAT_OF_LIGHTNING = 62276, + SPELL_STORMHAMMER = 62042, + SPELL_DEAFENING_THUNDER = 62470, + SPELL_LIGHTNING_SHOCK = 62017, + SPELL_CHARGE_ORB = 62016, + NPC_THUNDER_ORB = 33378, // npc used to cast charged orb + SPELL_BERSERK_ADDS = 62560, // 5 min phase 1 -> for adds + SPELL_SUMMON_LIGHTNING_ORB = 62391, + // phase2 + SPELL_TOUTCH_OF_DOMINION = 62565, // not available in hard mode + SPELL_CHAIN_LIGHTNING = 62131, + SPELL_CHAIN_LIGHTNING_H = 64390, + SPELL_LIGHTNING_CHARGE = 62279, + SPELL_LIGHTNING_CHARGE_ORB = 62466, + SPELL_UNBALANCING_STRIKE = 62130, + SPELL_BERSERK = 26662, // 5 min phase 2 - SAY_OUTRO_1 = -1603149, - SAY_OUTRO_2 = -1603150, - SAY_OUTRO_3 = -1603151, + // hard mode + SPELL_FROSTBOLT_VOLLEY = 62580, + SPELL_FROSTBOLT_VOLLEY_H = 62604, + SPELL_FROST_NOVA = 62597, + SPELL_FROST_NOVA_H = 62605, + SPELL_BLIZZARD = 62576, + SPELL_BLIZZARD_H = 62602, + NPC_SIF = 33196, + SPELL_SOUL_CHANNEL = 40401, - SAY_OUTRO_HARD_1 = -1603152, - SAY_OUTRO_HARD_2 = -1603153, - SAY_OUTRO_HARD_3 = -1603154, + // arena + MOB_DARK_RUNE_CHAMPION = 32876, + MOB_DARK_RUNE_COMMONER = 32904, + MOB_DARK_RUNE_EVOKER = 32878, + MOB_DARK_RUNE_WARBRINGER = 32877, - SAY_HELP_YOGG = -1603155, + // traps + NPC_TRAP_BUNNY = 33725, + NPC_TRAP_BUNNY2 = 33054, + SPELL_PARALYTIC_FIELD = 63540, + SPELL_PARALYTIC_FIELD2 = 62241, - SAY_SIF_BEGIN = -1603156, - SAY_SIF_EVENT = -1603157, - SAY_SIF_DESPAWN = -1603158, + // mobs spells + // acolyte + SPELL_GREATER_HEAL = 62334, + SPELL_GREATER_HEAL_H = 62442, + SPELL_RENEW = 62333, + SPELL_RENEW_H = 62441, + SPELL_HOLY_SMITE = 62335, + SPELL_HOLY_SMITE_H = 62443, + // champion + SPELL_MORTAL_STRIKE = 35054, + SPELL_CHARGE_CHAMPION = 32323, + SPELL_WHIRLWIND = 15578, + // commoner + SPELL_LOW_BLOW = 62326, + SPELL_PUMMEL = 38313, + // evoker + SPELL_RUNIC_LIGHTNING = 62327, + SPELL_RUNIC_LIGHTNING_H = 62445, + SPELL_RUNIC_MENDING = 62328, + SPELL_RUNIC_MENDING_H = 62446, + SPELL_RUNIC_SHIELD = 62321, + SPELL_RUNIC_SHIELD_H = 62529, + // warbringer + SPELL_RUNIC_STRIKE = 62322, + SPELL_AURA_CELERITY = 62320, + + // ring guard + SPELL_WHIRLING_TRIP = 64151, + SPELL_IMPALE = 62331, + SPELL_IMPALE_H = 62418, + // honor guard + SPELL_CLEAVE = 42724, + SPELL_HAMSTRING = 48639, + SPELL_SHIELD_SMASH = 62332, + SPELL_SHIELD_SMASH_H = 62420, + + // hallway + MOB_DARK_RUNE_ACOLYTE = 33110, + MOB_IRON_RING_GUARD = 32874, + MINIBOSS_RUNIC_COLOSSUS = 32872, + SPELL_SMASH = 62339, + //SPELL_SMASH_RIGHT = 62414, + SPELL_RUNIC_SMASH = 62058, + SPELL_RUNIC_SMASH2 = 62057, + SPELL_RUNIC_SMASH_DMG = 62465, + SPELL_RUNIC_BARRIER = 62338, + SPELL_CHARGE = 62613, + SPELL_CHARGE_H = 62614, + + MOB_IRON_HOHOR_GUARD = 32875, + MINIBOSS_ANCIENT_RUNE_GIANT = 32873, + SPELL_RUNIC_FORTIFICATION = 62942, + SPELL_STOMP = 62411, + SPELL_STOMP_H = 62413, + SPELL_RUNE_DETONATION = 62526, + + // pre adds: + SPELL_ACID_BREATH = 62315, + SPELL_ACID_BREATH_H = 62415, + SPELL_SWEEP = 62316, + SPELL_SWEEP_H = 62417, + // captains + NPC_CAPTAIN_ALY = 32908, + NPC_CAPTAIN_HORDE = 32907, + SPELL_DEVASTATE = 62317, + SPELL_HEROIC_STRIKE = 62444, + // mercenary + NPC_MERCENARY_ALY = 32885, + NPC_MERCENARY_HORDE = 32883, + SPELL_SHOOT = 16496, + SPELL_BARBED_SHOT = 62318, + SPELL_WING_CLIP = 40652, + + ACHIEV_LOSE_ILLUSION = 3176, + ACHIEV_LOSE_ILLUSION_H = 3183, + ACHIEV_SIFFED = 2977, + ACHIEV_SIFFED_H = 2978, +}; + +enum phases +{ + PHASE_PREADDS = 0, + PHASE_INTRO = 1, + PHASE_BALCONY = 2, + PHASE_ARENA = 3, + PHASE_OUTRO = 4, +}; + +#define LOC_Z 419.5f +struct LocationsXY +{ + float x, y, z; + uint32 id; +}; +static LocationsXY ArenaLoc[]= +{ + {2158.082f, -240.572f}, + {2111.883f, -240.561f}, + {2105.243f, -274.499f}, + {2163.927f, -277.834f}, + {2104.865f, -251.027f}, + {2167.612f, -262.128f}, +}; + +static LocationsXY OrbLoc[]= +{ + {2134.57f, -440.31f, 438.33f}, + {2225.91f, -431.68f, 412.17f}, + {2228.26f, -266.46f, 412.17f}, +}; + +// trap bunny +struct MANGOS_DLL_DECL mob_thorim_trap_bunnyAI : public ScriptedAI +{ + mob_thorim_trap_bunnyAI(Creature* pCreature) : ScriptedAI(pCreature) + { + SetCombatMovement(false); + pCreature->setFaction(14); + Reset(); + } + + bool m_bHasStunAura; + uint32 m_uiAuraExpireTimer; + + void Reset() + { + m_bHasStunAura = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && !m_bHasStunAura && + pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 12) && m_creature->IsWithinLOSInMap(pWho)) + { + m_bHasStunAura = true; + m_uiAuraExpireTimer = 15000; + DoCast(m_creature, SPELL_PARALYTIC_FIELD); + } + } + + void AttackStart(Unit* pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiAuraExpireTimer < uiDiff && m_bHasStunAura) + m_bHasStunAura = false; + else m_uiAuraExpireTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_mob_thorim_trap_bunny(Creature* pCreature) +{ + return new mob_thorim_trap_bunnyAI(pCreature); +} + +// dark rune acolyte +struct MANGOS_DLL_DECL mob_dark_rune_acolyteAI : public ScriptedAI +{ + mob_dark_rune_acolyteAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(3000, 6000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + switch(urand(0, 4)) + { + case 0: + case 1: + if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_GREATER_HEAL : SPELL_GREATER_HEAL_H); + break; + case 2: + case 3: + if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H); + break; + case 4: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_HOLY_SMITE : SPELL_HOLY_SMITE_H); + break; + } + m_uiSpell_Timer = urand(3000, 6000); + }else m_uiSpell_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_acolyte(Creature* pCreature) +{ + return new mob_dark_rune_acolyteAI(pCreature); +} + +// dark rune champion +struct MANGOS_DLL_DECL mob_dark_rune_championAI : public ScriptedAI +{ + mob_dark_rune_championAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(3000, 6000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + switch(urand(0, 2)) + { + case 0: + DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE); + break; + case 1: + DoCast(m_creature->getVictim(), SPELL_CHARGE_CHAMPION); + break; + case 2: + DoCast(m_creature->getVictim(), SPELL_WHIRLWIND); + break; + } + m_uiSpell_Timer = urand(3000, 6000); + }else m_uiSpell_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_champion(Creature* pCreature) +{ + return new mob_dark_rune_championAI(pCreature); +} + +// dark rune commoner +struct MANGOS_DLL_DECL mob_dark_rune_commonerAI : public ScriptedAI +{ + mob_dark_rune_commonerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(3000, 6000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: + DoCast(m_creature->getVictim(), SPELL_LOW_BLOW); + break; + case 1: + DoCast(m_creature->getVictim(), SPELL_PUMMEL); + break; + } + m_uiSpell_Timer = urand(3000, 6000); + }else m_uiSpell_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_commoner(Creature* pCreature) +{ + return new mob_dark_rune_commonerAI(pCreature); +} + +// dark rune evoker +struct MANGOS_DLL_DECL mob_dark_rune_evokerAI : public ScriptedAI +{ + mob_dark_rune_evokerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(3000, 6000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + switch(urand(0, 4)) + { + case 0: + case 1: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_RUNIC_LIGHTNING : SPELL_RUNIC_LIGHTNING_H); + break; + case 2: + case 3: + if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_RUNIC_MENDING : SPELL_RUNIC_MENDING_H); + break; + case 4: + DoCast(m_creature, m_bIsRegularMode ? SPELL_RUNIC_SHIELD : SPELL_RUNIC_SHIELD_H); + break; + } + m_uiSpell_Timer = urand(3000, 6000); + }else m_uiSpell_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_evoker(Creature* pCreature) +{ + return new mob_dark_rune_evokerAI(pCreature); +} + +// dark rune warbringer +struct MANGOS_DLL_DECL mob_dark_rune_warbringerAI : public ScriptedAI +{ + mob_dark_rune_warbringerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(4000, 7000); + DoCast(m_creature, SPELL_AURA_CELERITY); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_RUNIC_STRIKE); + m_uiSpell_Timer = urand(4000, 7000); + }else m_uiSpell_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_warbringer(Creature* pCreature) +{ + return new mob_dark_rune_warbringerAI(pCreature); +} + +// dark rune ring guard +struct MANGOS_DLL_DECL mob_dark_rune_ring_guardAI : public ScriptedAI +{ + mob_dark_rune_ring_guardAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(3000, 6000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: + DoCast(m_creature->getVictim(), SPELL_WHIRLING_TRIP); + break; + case 1: + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_IMPALE : SPELL_IMPALE_H); + break; + } + m_uiSpell_Timer = urand(3000, 6000); + }else m_uiSpell_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_ring_guard(Creature* pCreature) +{ + return new mob_dark_rune_ring_guardAI(pCreature); +} + +// dark rune honor guard +struct MANGOS_DLL_DECL mob_dark_rune_honor_guardAI : public ScriptedAI +{ + mob_dark_rune_honor_guardAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + uint32 m_uiSpell_Timer; + + void Reset() + { + m_uiSpell_Timer = urand(3000, 6000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpell_Timer < uiDiff) + { + switch(urand(0, 2)) + { + case 0: + DoCast(m_creature->getVictim(), SPELL_CLEAVE); + break; + case 1: + DoCast(m_creature->getVictim(), SPELL_HAMSTRING); + break; + case 2: + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHIELD_SMASH : SPELL_SHIELD_SMASH_H); + break; + } + m_uiSpell_Timer = urand(3000, 6000); + }else m_uiSpell_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_dark_rune_honor_guard(Creature* pCreature) +{ + return new mob_dark_rune_honor_guardAI(pCreature); +} + +// thorim +struct MANGOS_DLL_DECL boss_thorimAI : public ScriptedAI +{ + boss_thorimAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint32 m_uiPhase; + + uint32 m_uiArenaBerserkTimer; + uint32 m_uiBerserkTimer; + uint32 m_uiArenaYellTimer; + uint32 m_uiStormHammerTimer; + uint32 m_uiDeafeningThunderTimer; + uint32 m_uiChargeOrbTimer; + uint32 m_uiSummonWavesTimer; + uint64 m_uiStormTargetGUID; + + uint32 m_uiChainLightningTimer; + uint32 m_uiLightningChargeTimer; + uint32 m_uiOrbChargeTimer; + uint32 m_uiUnbalancingStrikeTimer; + + uint32 m_uiPhase2Timer; + uint32 m_uiHardModeTimer; + + bool m_bIsPhaseEnd; + bool m_bIsHardMode; + uint32 m_uiPreAddsKilled; + + uint64 m_uiSifGUID; + + // intro & outro + bool m_bIsOutro; + uint32 m_uiOutroTimer; + uint32 m_uiOutroStep; + bool m_bIsIntro; + uint32 m_uiIntroTimer; + uint32 m_uiIntroStep; + + // mob list check + std::list lIronDwarfes; + std::list m_lOrbsGUIDList; + + void Reset() + { + m_uiPreAddsKilled = 0; + m_uiPhase = PHASE_PREADDS; + SetCombatMovement(false); + + m_bIsHardMode = true; + m_bIsPhaseEnd = false; + + m_uiArenaBerserkTimer = 280000; // 5 min - 20 secs intro + m_uiBerserkTimer = 300000; // 5 min + m_uiHardModeTimer = 160000; // 3 min - 20 sec intro + m_uiArenaYellTimer = 30000; + m_uiSummonWavesTimer = 10000; + + m_uiStormHammerTimer = 20000; + m_uiDeafeningThunderTimer = 22000; + m_uiChargeOrbTimer = 15000; + + m_uiChainLightningTimer = urand(10000, 15000); + m_uiLightningChargeTimer = urand(10000, 15000); + m_uiUnbalancingStrikeTimer = urand(15000, 20000); + m_uiOrbChargeTimer = 20000; + + m_uiOutroTimer = 10000; + m_uiOutroStep = 1; + m_bIsIntro = false; + m_uiIntroTimer = 10000; + m_uiIntroStep = 1; + m_bIsOutro = false; + m_uiSifGUID = 0; + lIronDwarfes.clear(); + m_lOrbsGUIDList.clear(); + + // exploit check + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + // respawn adds + GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, MOB_IRON_RING_GUARD, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, MOB_DARK_RUNE_ACOLYTE, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, MOB_IRON_HOHOR_GUARD, DEFAULT_VISIBILITY_INSTANCE); + // preadds + GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_MERCENARY_ALY, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_MERCENARY_HORDE, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_CAPTAIN_ALY, DEFAULT_VISIBILITY_INSTANCE); + GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_CAPTAIN_HORDE, DEFAULT_VISIBILITY_INSTANCE); + if (!lIronDwarfes.empty()) + { + for(std::list::iterator iter = lIronDwarfes.begin(); iter != lIronDwarfes.end(); ++iter) + { + if ((*iter) && !(*iter)->isAlive()) + (*iter)->Respawn(); + } + } + + if(m_pInstance) + { + // respawn runic colossus + if (Creature* pColossus = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RUNIC_COLOSSUS))) + { + if (!pColossus->isAlive()) + pColossus->Respawn(); + } + + // respawn ancient rune giant + if (Creature* pRuneGiant = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RUNE_GIANT))) + { + if (!pRuneGiant->isAlive()) + pRuneGiant->Respawn(); + } + + // respawn jormungar + if (Creature* pJormungar = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_JORMUNGAR_BEHEMOTH))) + { + if (!pJormungar->isAlive()) + pJormungar->Respawn(); + } + } + } + + void SpellHitTarget(Unit* pSpellTarget, const SpellEntry* pSpell) + { + if(pSpell->Id == SPELL_STORMHAMMER) + pSpellTarget->CastSpell(pSpellTarget, SPELL_DEAFENING_THUNDER, false); + } + + void JustReachedHome() + { + if(m_pInstance) + m_pInstance->SetData(TYPE_THORIM, NOT_STARTED); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY1, m_creature); + else + DoScriptText(SAY_SLAY2, m_creature); + } + + void DoOutro() + { + if(m_pInstance) + { + if(m_bIsHardMode) + { + m_pInstance->SetData(TYPE_THORIM_HARD, DONE); + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_LOSE_ILLUSION : ACHIEV_LOSE_ILLUSION_H); + } + m_pInstance->SetData(TYPE_THORIM, DONE); + } + + m_creature->ForcedDespawn(); + } + + // for debug only + void JustDied(Unit* pKiller) + { + if(m_pInstance) + { + if(m_bIsHardMode) + m_pInstance->SetData(TYPE_THORIM_HARD, DONE); + m_pInstance->SetData(TYPE_THORIM, DONE); + } + } + + // start phase 2 and outro + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + // phase 2 + if(uiDamage > 0 && m_uiPhase == PHASE_BALCONY && !m_bIsPhaseEnd) + { + if(m_pInstance->GetData(TYPE_RUNIC_COLOSSUS) == DONE && m_pInstance->GetData(TYPE_RUNE_GIANT) == DONE) + { + // say + DoScriptText(SAY_JUMP, m_creature); + // move in arena + m_creature->GetMotionMaster()->MovePoint(0, 2134.719f, -263.148f, 419.846f); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->SetSplineFlags(SPLINEFLAG_FALLING); + m_bIsPhaseEnd = true; + m_uiPhase2Timer = 9000; + } + } + + // outro + if(m_creature->GetHealthPercent() < 1.0f && m_uiPhase == PHASE_ARENA) + { + uiDamage = 0; + m_uiPhase = PHASE_OUTRO; + } + } + + void StartEncounter() + { + m_uiPhase = PHASE_INTRO; + m_bIsIntro = true; + } + + // hacky way for berserk in phase 1 :) + void KillPlayers() + { + Map *map = m_creature->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive() && m_creature->GetDistance(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ()) < 200.0f) + i->getSource()->DealDamage(i->getSource(), i->getSource()->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + } + + Creature* SelectRandomOrb() + { + std::list lThunderList; + GetCreatureListWithEntryInGrid(lThunderList, m_creature, NPC_THUNDER_ORB, 100.0f); + + //This should not appear! + if (lThunderList.empty()){ + m_uiChargeOrbTimer = 5000; + return NULL; + } + + std::list::iterator iter = lThunderList.begin(); + advance(iter, urand(0, lThunderList.size()-1)); + + return *iter; + } + + void UpdateAI(const uint32 uiDiff) + { + switch(m_uiPhase) + { + // start the encounter when all the preadds have died + case PHASE_PREADDS: + if(m_uiPreAddsKilled == 4) + StartEncounter(); + break; + // do intro + case PHASE_INTRO: + { + // intro + if(m_bIsIntro) + { + switch(m_uiIntroStep) + { + case 1: + // wait 10 secs + ++m_uiIntroStep; + m_uiIntroTimer = 10000; + break; + case 3: + DoScriptText(SAY_AGGRO1, m_creature); + DoCast(m_creature, SPELL_SHEAT_OF_LIGHTNING); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetInCombatWithZone(); + if (m_pInstance) + m_pInstance->SetData(TYPE_THORIM, IN_PROGRESS); + ++m_uiIntroStep; + m_uiIntroTimer = 10000; + break; + case 5: + DoScriptText(SAY_AGGRO2, m_creature); + if(Creature* pSif = m_creature->SummonCreature(NPC_SIF, m_creature->GetPositionX() + 10, m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 700000)) + { + pSif->setFaction(35); + m_uiSifGUID = pSif->GetGUID(); + } + ++m_uiIntroStep; + m_uiIntroTimer = 9000; + break; + case 7: + if(Creature* pSif = m_pInstance->instance->GetCreature(m_uiSifGUID)) + DoScriptText(SAY_SIF_INTRO, pSif); + m_uiPhase = PHASE_BALCONY; + m_bIsIntro = false; + ++m_uiIntroStep; + m_uiIntroTimer = 9000; + break; + } + } + else return; + + if (m_uiIntroTimer <= uiDiff) + { + ++m_uiIntroStep; + m_uiIntroTimer = 330000; + } m_uiIntroTimer -= uiDiff; + + break; + } + // balcony phase + case PHASE_BALCONY: + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // phase 2 prepared + if(m_uiPhase2Timer < uiDiff && m_bIsPhaseEnd) + { + m_creature->RemoveSplineFlag(SPLINEFLAG_FALLING); + m_creature->RemoveAurasDueToSpell(SPELL_SHEAT_OF_LIGHTNING); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if(!m_bIsHardMode) + DoCast(m_creature, SPELL_TOUTCH_OF_DOMINION); + if(m_bIsHardMode) + { + if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID)) + { + Sif->setFaction(14); + DoScriptText(SAY_SIF_EVENT, Sif); + Sif->SetInCombatWithZone(); + // hacky way to complete achievements; use only if you have this function + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_SIFFED : ACHIEV_SIFFED_H); + } + } + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + SetCombatMovement(true); + m_uiPhase = PHASE_ARENA; + m_bIsPhaseEnd = false; + } + else m_uiPhase2Timer -= uiDiff; + + // return if jumping to second phase + if(m_bIsPhaseEnd) + return; + + // hard mode check + if (m_uiHardModeTimer <= uiDiff && m_bIsHardMode) + { + m_bIsHardMode = false; + if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID)) + { + if(Sif && Sif->isAlive()) + { + DoScriptText(SAY_SIF_DESPAWN, Sif); + Sif->ForcedDespawn(); + } + } + m_uiHardModeTimer = 330000; + } m_uiHardModeTimer -= uiDiff; + + // spawn adds in arena + if(m_uiSummonWavesTimer < uiDiff) + { + // 1-2 warbringer + // 1 evoker + // 5-6 commoners + // 1 champion + // 1 acolyte + uint8 i; + uint8 k; + switch(urand(0, 4)) + { + case 0: + i = urand(0, 5); + if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_CHAMPION, ArenaLoc[i].x, ArenaLoc[i].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f); + if(pTemp->IsWithinLOSInMap(m_creature->getVictim())) + { + pTemp->AI()->AttackStart(m_creature->getVictim()); + pTemp->AddThreat(m_creature->getVictim(), 100.0f); + } + } + break; + case 1: + i = urand(0, 5); + if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_EVOKER, ArenaLoc[i].x, ArenaLoc[i].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f); + if(pTemp->IsWithinLOSInMap(m_creature->getVictim())) + { + pTemp->AI()->AttackStart(m_creature->getVictim()); + pTemp->AddThreat(m_creature->getVictim(), 100.0f); + } + } + break; + case 2: + i = urand(5, 6); + for(uint8 j = 0; j < i; j++) + { + if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_COMMONER, ArenaLoc[j].x, ArenaLoc[j].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f); + if(pTemp->IsWithinLOSInMap(m_creature->getVictim())) + { + pTemp->AI()->AttackStart(m_creature->getVictim()); + pTemp->AddThreat(m_creature->getVictim(), 100.0f); + } + } + } + break; + case 3: + k = urand(0, 3); + i = urand(k + 1, k + 2); + for(uint8 j = k; j < i; j++) + { + if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_WARBRINGER, ArenaLoc[j].x, ArenaLoc[j].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f); + if(pTemp->IsWithinLOSInMap(m_creature->getVictim())) + { + pTemp->AI()->AttackStart(m_creature->getVictim()); + pTemp->AddThreat(m_creature->getVictim(), 100.0f); + } + } + } + break; + case 4: + i = urand(0, 5); + if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_ACOLYTE, ArenaLoc[i].x, ArenaLoc[i].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f); + if(pTemp->IsWithinLOSInMap(m_creature->getVictim())) + { + pTemp->AI()->AttackStart(m_creature->getVictim()); + pTemp->AddThreat(m_creature->getVictim(), 100.0f); + } + } + break; + } + m_uiSummonWavesTimer = urand (7000, 10000); + } + else m_uiSummonWavesTimer -= uiDiff; + + // phase 1 spells + // charge orb + // doesn't work right, needs fixing + if(m_uiChargeOrbTimer < uiDiff) + { + if (Creature* pOrb = SelectRandomOrb()) + DoCast(pOrb, SPELL_CHARGE_ORB); + m_uiChargeOrbTimer = 20000; + } + else m_uiChargeOrbTimer -= uiDiff; + + // storm hammer + if(m_uiStormHammerTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + // should target only the players in the arena! + //if(pTarget->IsWithinLOSInMap(m_creature)) + { + DoCast(pTarget, SPELL_STORMHAMMER); + m_uiStormHammerTimer = 15000; + } + } + } + else m_uiStormHammerTimer -= uiDiff; + + if(m_uiArenaYellTimer < uiDiff) + { + switch(urand(0, 2)) + { + case 0: DoScriptText(SAY_SPECIAL1, m_creature); break; + case 1: DoScriptText(SAY_SPECIAL2, m_creature); break; + case 2: DoScriptText(SAY_SPECIAL3, m_creature); break; + } + m_uiArenaYellTimer = 30000; + } + else m_uiArenaYellTimer -= uiDiff; + + // phase 1 berserk + if(m_uiArenaBerserkTimer < uiDiff) + { + DoScriptText(SAY_ARENA_WIPE, m_creature); + //DoCast(m_creature, SPELL_BERSERK_ADDS); + // workaround because berserk doesn't work. It's casted on players not on adds. Needs core fix + KillPlayers(); + DoCast(m_creature, SPELL_SUMMON_LIGHTNING_ORB); + m_uiArenaBerserkTimer = 30000; + } + else m_uiArenaBerserkTimer -= uiDiff; + + break; + } + // arena phase + case PHASE_ARENA: + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // all spells + // chain lightning + if(m_uiChainLightningTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H); + m_uiChainLightningTimer = 10000 + rand()%5000; + } + else m_uiChainLightningTimer -= uiDiff; + + // lightning charge + if(m_uiLightningChargeTimer < uiDiff) + { + DoCast(m_creature, SPELL_LIGHTNING_CHARGE); + m_uiLightningChargeTimer = 15000; + m_uiOrbChargeTimer = 2000; + } + else m_uiLightningChargeTimer -= uiDiff; + + if(m_uiOrbChargeTimer < uiDiff) + { + if (Creature* pOrb = SelectRandomOrb()) + DoCast(pOrb, SPELL_LIGHTNING_CHARGE_ORB); + m_uiOrbChargeTimer = 20000; + } + else m_uiOrbChargeTimer -= uiDiff; + + // unbalancing strike + if(m_uiUnbalancingStrikeTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget, SPELL_UNBALANCING_STRIKE); + m_uiUnbalancingStrikeTimer = 25000; + } + else m_uiUnbalancingStrikeTimer -= uiDiff; + + // phase 2 berserk + if(m_uiBerserkTimer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(true); + DoScriptText(SAY_BERSERK, m_creature); + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserkTimer = 30000; + } + else m_uiBerserkTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + break; + } + // outro + case PHASE_OUTRO: + { + switch(m_uiOutroStep) + { + case 1: + m_creature->setFaction(35); + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(true); + m_creature->InterruptNonMeleeSpells(false); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + ++m_uiOutroStep; + m_uiOutroTimer = 1000; + break; + case 3: + m_creature->SetOrientation(4.99f); + DoScriptText(SAY_DEATH, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 3000; + break; + case 5: + if(m_bIsHardMode) + { + DoScriptText(SAY_OUTRO_HARD1, m_creature); + if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID)) + DoCast(Sif, SPELL_STORMHAMMER); + } + else + DoScriptText(SAY_OUTRO1, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 1000; + break; + case 7: + if(m_bIsHardMode) + { + if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID)) + { + //summon a tentacule + if(Creature* pTentacule = m_creature->SummonCreature(34266, Sif->GetPositionX(), Sif->GetPositionY(), Sif->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000)) + { + pTentacule->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pTentacule->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + Sif->ForcedDespawn(); + } + } + ++m_uiOutroStep; + m_uiOutroTimer = 7000; + break; + case 9: + if(m_bIsHardMode) + DoScriptText(SAY_OUTRO_HARD2, m_creature); + else + DoScriptText(SAY_OUTRO2, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 13000; + break; + case 11: + if(m_bIsHardMode) + DoScriptText(SAY_OUTRO_HARD3, m_creature); + else + DoScriptText(SAY_OUTRO3, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 15000; + break; + case 13: + DoOutro(); + ++m_uiOutroStep; + m_uiOutroTimer = 10000; + break; + } + + if (m_uiOutroTimer <= uiDiff) + { + ++m_uiOutroStep; + m_uiOutroTimer = 330000; + } m_uiOutroTimer -= uiDiff; + + break; + } + } + } }; +CreatureAI* GetAI_boss_thorim(Creature* pCreature) +{ + return new boss_thorimAI(pCreature); +} + +struct MANGOS_DLL_DECL boss_runic_colossusAI : public ScriptedAI +{ + boss_runic_colossusAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint32 m_uiSpellTimer; + uint32 m_uiRunicBarrierTimer; + uint32 m_uiSmashTimer; + uint64 m_uiSmashTargetGUID; + bool m_bIsSmash; + bool m_bMustSmash; + + void Reset() + { + m_uiSpellTimer = urand(5000, 10000); + m_uiRunicBarrierTimer = 15000; + m_uiSmashTimer = 3000; + m_uiSmashTargetGUID = 0; + m_bIsSmash = false; + m_bMustSmash = true; + + if(m_pInstance) + m_pInstance->SetData(TYPE_RUNIC_COLOSSUS, NOT_STARTED); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_RUNIC_COLOSSUS, DONE); + } + + void MoveInLineOfSight(Unit* pWho) + { + // start smashing + if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && + !m_bIsSmash && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 70) && m_creature->IsWithinLOSInMap(pWho)) + { + m_uiSmashTargetGUID = pWho->GetGUID(); + m_creature->GetMotionMaster()->MoveIdle(); + m_bIsSmash = true; + } + + if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && + m_bIsSmash && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 5) && m_creature->IsWithinLOSInMap(pWho)) + { + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + m_bMustSmash = false; + } + } + + void UpdateAI(const uint32 uiDiff) + { + // smash, doesn't work. Spell needs core fix + if(m_uiSmashTimer < uiDiff && m_bIsSmash && m_bMustSmash) + { + if(Unit* pTarget = m_creature->GetMap()->GetUnit( m_uiSmashTargetGUID)) + DoCast(pTarget, SPELL_RUNIC_SMASH_DMG); + m_uiSmashTimer = 10000; + } + else m_uiSmashTimer -= uiDiff; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpellTimer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: + DoCast(m_creature, SPELL_SMASH); + break; + case 1: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_CHARGE : SPELL_CHARGE_H); + break; + } + m_uiSpellTimer = urand(5000, 10000); + }else m_uiSpellTimer -= uiDiff; + + if (m_uiRunicBarrierTimer < uiDiff) + { + DoCast(m_creature, SPELL_RUNIC_BARRIER); + m_uiRunicBarrierTimer = urand(25000, 30000); + }else m_uiRunicBarrierTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_runic_colossus(Creature* pCreature) +{ + return new boss_runic_colossusAI(pCreature); +} + +struct MANGOS_DLL_DECL boss_ancient_rune_giantAI : public ScriptedAI +{ + boss_ancient_rune_giantAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + uint32 m_uiSpellTimer; + uint32 m_uiSummonTimer; + bool m_bIsSummoning; + bool m_bSummonStop; + + void Reset() + { + m_uiSpellTimer = urand(5000, 10000); + m_uiSummonTimer = 10000; + m_bIsSummoning = false; + m_bSummonStop = false; + + if(m_pInstance) + m_pInstance->SetData(TYPE_RUNE_GIANT, NOT_STARTED); + } + + void JustDied(Unit *killer) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_RUNE_GIANT, DONE); + } + + void Aggro(Unit *who) + { + // should be cast on adds, spell needs core fix + //DoCast(m_creature, SPELL_RUNIC_FORTIFICATION); + m_bSummonStop = true; + m_bIsSummoning = false; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_pInstance->GetData(TYPE_RUNIC_COLOSSUS) == DONE && !m_bIsSummoning && !m_bSummonStop) + m_bIsSummoning = true; + + // summon adds before aggro and after the runic colossus has died + if(m_uiSummonTimer < uiDiff && m_bIsSummoning) + { + switch(urand(0, 1)) + { + case 0: + // ring guard + if(Creature* pTemp = m_creature->SummonCreature(32874, OrbLoc[0].x + 30, OrbLoc[0].y, OrbLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MovePoint(0, OrbLoc[1].x, OrbLoc[1].y, OrbLoc[1].z); + pTemp->SetInCombatWithZone(); + } + break; + case 1: + // honor guard + if(Creature* pTemp = m_creature->SummonCreature(33125, OrbLoc[0].x + 30, OrbLoc[0].y, OrbLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MovePoint(0, OrbLoc[1].x, OrbLoc[1].y, OrbLoc[1].z); + pTemp->SetInCombatWithZone(); + } + break; + } + m_uiSummonTimer = 10000; + } + else m_uiSummonTimer -= uiDiff; + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpellTimer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: + DoCast(m_creature->getVictim(), m_bIsRegularMode? SPELL_STOMP : SPELL_STOMP_H); + break; + case 1: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_RUNE_DETONATION); + break; + } + m_uiSpellTimer = urand(5000,10000); + }else m_uiSpellTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_ancient_rune_giant(Creature* pCreature) +{ + return new boss_ancient_rune_giantAI(pCreature); +} + +struct MANGOS_DLL_DECL mob_thorim_preaddsAI : public ScriptedAI +{ + mob_thorim_preaddsAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance* m_pInstance; + + // jormungar + uint32 m_uiAcidBreathTimer; + uint32 m_uiSweepTimer; + + // captain + uint32 m_uiDevastateTimer; + uint32 m_uiHeroicStrikeTimer; + + // mercenary + uint32 m_uiShootTimer; + uint32 m_uiBarbedShotTimer; + uint32 m_uiWingClipTimer; + + void Reset() + { + // jormungar + m_uiAcidBreathTimer = urand(7000, 14000); + m_uiSweepTimer = urand(15000, 20000); + + // captain + m_uiDevastateTimer = urand(3000, 7000); + m_uiHeroicStrikeTimer = urand(8000, 15000); + + // mercenary + m_uiShootTimer = 1000; + m_uiBarbedShotTimer = urand(7000, 10000); + m_uiWingClipTimer = urand(10000, 15000); + } + + void AttackStart(Unit* pWho) + { + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + if(m_creature->GetEntry() == NPC_MERCENARY_ALY || m_creature->GetEntry() == NPC_MERCENARY_HORDE) + DoStartMovement(pWho, 20); + else + DoStartMovement(pWho); + } + } + + void JustDied(Unit *killer) + { + // start the encounter + if (Creature* pThorim = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_THORIM))) + { + if(pThorim->isAlive()) + ((boss_thorimAI*)pThorim->AI())->m_uiPreAddsKilled += 1; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + switch(m_creature->GetEntry()) + { + case NPC_JORMUNGAR_BEHEMOTH: + { + if(m_uiAcidBreathTimer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ACID_BREATH : SPELL_ACID_BREATH_H); + m_uiAcidBreathTimer = urand(7000, 14000); + } + else m_uiAcidBreathTimer -= uiDiff; + + if(m_uiSweepTimer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SWEEP : SPELL_SWEEP_H); + m_uiSweepTimer = urand(15000, 23000); + } + else m_uiSweepTimer -= uiDiff; + + break; + } + case NPC_CAPTAIN_ALY: + case NPC_CAPTAIN_HORDE: + { + if(m_uiDevastateTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) + DoCast(pTarget, SPELL_DEVASTATE); + m_uiDevastateTimer = urand(4000, 7000); + } + else m_uiDevastateTimer -= uiDiff; + + if(m_uiHeroicStrikeTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_HEROIC_STRIKE); + m_uiHeroicStrikeTimer = urand(10000, 15000); + } + else m_uiHeroicStrikeTimer -= uiDiff; + + break; + } + case NPC_MERCENARY_ALY: + case NPC_MERCENARY_HORDE: + { + if(m_uiShootTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_SHOOT); + m_uiShootTimer = urand(1000, 3000); + } + else m_uiShootTimer -= uiDiff; + + if(m_uiBarbedShotTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_BARBED_SHOT); + m_uiBarbedShotTimer = urand(7000, 10000); + } + else m_uiBarbedShotTimer -= uiDiff; + + if(m_uiWingClipTimer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_WING_CLIP); + m_uiWingClipTimer = urand(10000, 15000); + } + else m_uiWingClipTimer -= uiDiff; + + break; + } + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_thorim_preadds(Creature* pCreature) +{ + return new mob_thorim_preaddsAI(pCreature); +} + +// sif +struct MANGOS_DLL_DECL npc_sifAI : public ScriptedAI +{ + npc_sifAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiSpellTimer; + + void Reset() + { + m_uiSpellTimer = urand(5000, 10000); + m_creature->SetRespawnDelay(DAY); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho, 10.0f); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_THORIM) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSpellTimer < uiDiff) + { + switch(urand(0, 2)) + { + case 0: + DoCast(m_creature, m_bIsRegularMode? SPELL_FROSTBOLT_VOLLEY : SPELL_FROSTBOLT_VOLLEY_H); + break; + case 1: + DoCast(m_creature, m_bIsRegularMode? SPELL_FROST_NOVA : SPELL_FROST_NOVA_H); + break; + case 2: + // it should be casted around the room! + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode? SPELL_BLIZZARD : SPELL_BLIZZARD_H); + break; + } + + m_uiSpellTimer = urand(3000, 6000); + }else m_uiSpellTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_sif(Creature* pCreature) +{ + return new npc_sifAI(pCreature); +} + +// script for the orb on the hallway which should wipe the raid. Needs more research! +struct MANGOS_DLL_DECL npc_lightning_orbAI : public ScriptedAI +{ + npc_lightning_orbAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pCreature->setFaction(14); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiMoveTimer; + uint8 m_uiWaypoint; + + void Reset() + { + m_uiMoveTimer = 1000; + m_uiWaypoint = 0; + m_creature->SetRespawnDelay(DAY); + // find the correct aura for raid wipe!!! + } + + void AttackStart(Unit* pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_THORIM) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_uiMoveTimer < uiDiff && m_uiWaypoint < 4) + { + m_creature->GetMotionMaster()->MovePoint(0, OrbLoc[m_uiWaypoint].x, OrbLoc[m_uiWaypoint].y, OrbLoc[m_uiWaypoint].z); + m_uiWaypoint +=1; + m_uiMoveTimer = 10000; + } + else m_uiMoveTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_lightning_orb(Creature* pCreature) +{ + return new npc_lightning_orbAI(pCreature); +} + + void AddSC_boss_thorim() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_thorim"; + newscript->GetAI = &GetAI_boss_thorim; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_runic_colossus"; + newscript->GetAI = &GetAI_boss_runic_colossus; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_ancient_rune_giant"; + newscript->GetAI = &GetAI_boss_ancient_rune_giant; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_sif"; + newscript->GetAI = &GetAI_npc_sif; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_lightning_orb"; + newscript->GetAI = &GetAI_npc_lightning_orb; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_rune_acolyte"; + newscript->GetAI = &GetAI_mob_dark_rune_acolyte; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_rune_champion"; + newscript->GetAI = &GetAI_mob_dark_rune_champion; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_rune_commoner"; + newscript->GetAI = &GetAI_mob_dark_rune_commoner; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_rune_evoker"; + newscript->GetAI = &GetAI_mob_dark_rune_evoker; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_rune_warbringer"; + newscript->GetAI = &GetAI_mob_dark_rune_warbringer; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_rune_ring_guard"; + newscript->GetAI = &GetAI_mob_dark_rune_ring_guard; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_dark_rune_honor_guard"; + newscript->GetAI = &GetAI_mob_dark_rune_honor_guard; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_thorim_preadds"; + newscript->GetAI = &GetAI_mob_thorim_preadds; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "mob_thorim_trap_bunny"; + newscript->GetAI = &GetAI_mob_thorim_trap_bunny; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_xt_002.cpp b/scripts/northrend/ulduar/ulduar/boss_xt_002.cpp index 8935bb14c..1aa8c8b79 100644 --- a/scripts/northrend/ulduar/ulduar/boss_xt_002.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_xt_002.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,9 +15,9 @@ */ /* ScriptData -SDName: boss_xt_002 -SD%Complete: 0% -SDComment: +SDName: boss_xt002 +SD%Complete: +SDComment: need core support for light and gravity bomb. correct number of adds in 25man missing SDCategory: Ulduar EndScriptData */ @@ -26,21 +26,779 @@ EndScriptData */ enum { - SAY_AGGRO = -1603045, - SAY_SLAY_1 = -1603046, - SAY_SLAY_2 = -1603047, - SAY_BERSERK = -1603048, - SAY_ADDS = -1603049, - SAY_DEATH = -1603050, - SAY_HEART_OPEN = -1603051, - SAY_HEART_CLOSE = -1603052, - SAY_TANCTRUM = -1603053, + //xt yells + SAY_AGGRO = -1603038, + SAY_DEATH = -1603030, + SAY_TANCTRUM = -1603037, + SAY_SLAY_01 = -1603036, + SAY_SLAY_02 = -1603035, + SAY_BERSERK = -1603031, + SAY_ADDS = -1603032, + SAY_HEART_OPEN = -1603034, + SAY_HEART_CLOSE = -1603033, + EMOTE_HEART = -1603350, + EMOTE_REPAIR = -1603351, - EMOTE_HEART = -1603054, - EMOTE_REPAIR = -1603055, + //xt-002 + SPELL_TANCTRUM = 62776, + SPELL_LIGHT_BOMB_TRIG = 65598, + SPELL_LIGHT_BOMB = 63018, + SPELL_LIGHT_BOMB_H = 65121, + SPELL_GRAVITY_BOMB = 63024, + SPELL_GRAVITY_BOMB_H = 64234, + SPELL_ENRAGE = 47008, + SPELL_STUN = 3618, + + // hard mode + SPELL_HEARTBREAK = 65737, + SPELL_HEARTBREAK_H = 64193, + SPELL_VOIDZONE = 64203, + SPELL_VOIDZONE_H = 64235, + SPELL_LIFE_SPARK = 64210, + SPELL_STATIC_CHARGED = 64227, + + NPC_VOIDZONE = 34001, + NPC_LIFESPARK = 34004, + + //heart of the deconstructor + SPELL_EXPOSED_HEART = 63849, + + //XE-321 Boombot + SPELL_BOOM = 38831, // replacing real spell + + //XM-024 Pummeller + SPELL_CLEAVE = 8374, + SPELL_TRAMPLE = 5568, + SPELL_UPPERCUT = 10966, + + //NPC ids + NPC_HEART = 33329, + NPC_SCRAPBOT = 33343, + NPC_BOOMBOT = 33346, + NPC_PUMMELER = 33344, + + // Achievs + ACHIEV_HEARTBREAKER = 3058, + ACHIEV_HEARTBREAKER_H = 3059, + ACHIEV_DECONSTRUCT_FAST = 2937, + ACHIEV_DECONSTRUCT_FAST_H = 2938, + ACHIEV_NERF_ENGINEERING = 2931, + ACHIEV_NERF_ENGINEERING_H = 2932, + ACHIEV_NERF_GRAVITY_BOMBS = 2934, + ACHIEV_NERF_GRAVITY_BOMBS_H = 2936, + ACHIEV_NERF_SCRAPBOTS = 2933, + ACHIEV_NERF_SCRAPBOTS_H = 2935, +}; + +//Positional defines +struct LocationsXY +{ + float x, y, z, o; + uint32 id; +}; + +static LocationsXY SummonLoc[]= +{ + {792.706f, 64.033f, 409.632f}, // lower left + {879.750f, 64.815f, 409.804f}, // upper left + {896.488f, -93.018f, 409.731f}, // upper right + {791.016f, -83.516f, 409.804f}, // lower right +}; + +// void zone +struct MANGOS_DLL_DECL mob_voidzoneAI : public ScriptedAI +{ + mob_voidzoneAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->setFaction(14); + SetCombatMovement(false); + Reset(); + } + + uint32 Spell_Timer; + bool m_bIsRegularMode; + + void Reset() + { + Spell_Timer = 4000; + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // should be an aura here. Couldn't find it + // hacky way, needs fixing! + if (Spell_Timer < diff) + { + Map *map = m_creature->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) < 2) + i->getSource()->DealDamage(i->getSource(), m_bIsRegularMode ? 5000 : 7500, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false); + } + } + Spell_Timer = 4000; + }else Spell_Timer -= diff; + } +}; + +CreatureAI* GetAI_mob_voidzone(Creature* pCreature) +{ + return new mob_voidzoneAI(pCreature); +} + +// lifespark +struct MANGOS_DLL_DECL mob_lifesparkAI : public ScriptedAI +{ + mob_lifesparkAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + void Reset() + { + DoCast(m_creature, SPELL_STATIC_CHARGED); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + } +}; + +CreatureAI* GetAI_mob_lifespark(Creature* pCreature) +{ + return new mob_lifesparkAI(pCreature); +} + +// XM-024 Pummeller +struct MANGOS_DLL_DECL mob_pummelerAI : public ScriptedAI +{ + mob_pummelerAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + uint32 Spell_Timer; + + void Reset() + { + Spell_Timer = urand(5000, 10000); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (Spell_Timer < diff) + { + switch(urand(0, 2)) + { + case 0: + DoCast(m_creature->getVictim(), SPELL_CLEAVE); + break; + case 1: + DoCast(m_creature->getVictim(), SPELL_TRAMPLE); + break; + case 2: + DoCast(m_creature->getVictim(), SPELL_UPPERCUT); + break; + } + Spell_Timer = urand(5000, 10000); + }else Spell_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_pummeler(Creature* pCreature) +{ + return new mob_pummelerAI(pCreature); +} + +// XE-321 Boombot +struct MANGOS_DLL_DECL mob_boombotAI : public ScriptedAI +{ + mob_boombotAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + void Reset() + { + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if (uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + DoCast(m_creature, SPELL_BOOM); + } + } + + void DoMeleeAttackIfReady() + { + //If we are within range melee the target + if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + DoCast(m_creature, SPELL_BOOM); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_boombot(Creature* pCreature) +{ + return new mob_boombotAI(pCreature); +} + +// Heart of the Deconstructor +struct MANGOS_DLL_DECL mob_xtheartAI : public ScriptedAI +{ + mob_xtheartAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiDeathTimer; + uint32 m_uiTotalDamage; + + void Reset() + { + DoCast(m_creature, SPELL_EXPOSED_HEART); + m_creature->SetRespawnDelay(DAY); + m_uiTotalDamage = 0; + m_uiDeathTimer = 30000; + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + m_uiTotalDamage += uiDamage; + // double damage + uiDamage += uiDamage; + } + + void JustDied(Unit* pKiller) + { + // used for hard mode loot only when hard mode loot is within the heart's corpse + // remove this for revision + m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + if(m_pInstance) + m_pInstance->SetData(TYPE_XT002_HARD, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + // despawns the creature if not killed in 30 secs + if(m_uiDeathTimer < diff) + { + // pass damage to boss + if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_XT002))) + { + if (pTemp->isAlive()) + pTemp->DealDamage(pTemp, m_uiTotalDamage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + m_creature->ForcedDespawn(); + } + else + m_uiDeathTimer -= diff; + } }; -void AddSC_boss_xt_002() +CreatureAI* GetAI_mob_xtheart(Creature* pCreature) { + return new mob_xtheartAI(pCreature); +} + +//XT-002 Deconstructor +struct MANGOS_DLL_DECL boss_xt002AI : public ScriptedAI +{ + boss_xt002AI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + std::list m_lScrapbotsGUIDList; + std::list m_lBoombotsGUIDList; + std::list m_lPummelerGUIDList; + + // spell timers + uint32 m_uiHeart_Timer; + uint32 m_uiLight_Bomb_Timer; + uint32 m_uiGravity_Bomb_Timer; + uint32 m_uiTanctrum_Timer; + uint32 m_uiEnrage_Timer; + uint32 m_uiRange_Check_Timer; + uint32 m_uiVoidZoneTimer; + uint32 m_uiLifeSparkTimer; + + // summon timers + uint32 m_uiScrapbotTimer; + uint32 m_uiBoombotTimer; + uint32 m_uiPummellerTimer; + uint32 m_uiScrapbotCount; + uint32 m_uiBoombotCount; + uint32 m_uiPummellerCount; + uint32 m_uiMaxScrapbot; + uint32 m_uiMaxBoombot; + + // health timers + uint32 m_uiHealthPercent; + uint32 m_uiHpDelayTimer; + bool m_bIsEnrage; + bool m_bPhase2; + + uint64 pLightBombTarGUID; + uint64 pGravityBombTarGUID; + uint64 m_uiXtHeartGUID; + + bool m_bIsHardMode; + bool m_bHasMoreHealth; + + uint32 uiEncounterTimer; + bool m_bIsEngineer; + + void Reset() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + + // spell timers + m_uiLight_Bomb_Timer = 5000; // 7 seconds the first 14 secs all after(7 secs in 25man) + m_uiGravity_Bomb_Timer = 30000; // 11 seconds first 18 secs all after(11 secs in 25man) + m_uiTanctrum_Timer = 35000; // 38 seconds first 40 secs all after + m_uiEnrage_Timer = 600000; // 10 min + m_uiRange_Check_Timer = 1000; + m_uiVoidZoneTimer = 60000; + m_uiLifeSparkTimer = urand (5000, 10000); + // summon timers + m_uiScrapbotTimer = 5000; + m_uiBoombotTimer = 5000; + m_uiPummellerTimer = 5000; + m_uiScrapbotCount = 0; + m_uiBoombotCount = 0; + m_uiPummellerCount = 0; + m_uiMaxScrapbot = 0; + m_uiMaxBoombot = 0; + // health timers + m_uiHealthPercent = 75; + + m_bIsEnrage = false; + m_bPhase2 = false; + m_bIsHardMode = false; + m_bHasMoreHealth = false; + m_lScrapbotsGUIDList.clear(); + m_lBoombotsGUIDList.clear(); + m_lPummelerGUIDList.clear(); + + pLightBombTarGUID = 0; + pGravityBombTarGUID = 0; + m_uiXtHeartGUID = 0; + + uiEncounterTimer = 0; + m_bIsEngineer = true; + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_XT002, DONE); + if(m_bIsHardMode) + { + m_pInstance->SetData(TYPE_XT002_HARD, DONE); + // make the heart give the loot for hard mode + // hacky way of giving hard mode loot, used only when hard mode loot is within the heart's corpse + // PLEASE REMOVE FOR REVISION! + if(Creature* pHeart = m_pInstance->instance->GetCreature(m_uiXtHeartGUID)) + pHeart->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + } + + DoScriptText(SAY_DEATH, m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if (!m_lScrapbotsGUIDList.empty()) + { + for(std::list::iterator itr = m_lScrapbotsGUIDList.begin(); itr != m_lScrapbotsGUIDList.end(); ++itr) + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + pTemp->ForcedDespawn(); + } + if (!m_lBoombotsGUIDList.empty()) + { + for(std::list::iterator itr = m_lBoombotsGUIDList.begin(); itr != m_lBoombotsGUIDList.end(); ++itr) + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + pTemp->ForcedDespawn(); + } + if (!m_lPummelerGUIDList.empty()) + { + for(std::list::iterator itr = m_lPummelerGUIDList.begin(); itr != m_lPummelerGUIDList.end(); ++itr) + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + pTemp->ForcedDespawn(); + } + + // hacky way to complete achievements; use only if you have this function + // Deconstruct Fast + if (uiEncounterTimer < 205000) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_DECONSTRUCT_FAST : ACHIEV_DECONSTRUCT_FAST_H); + } + + // Heartbreaker + if (m_bIsHardMode) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_HEARTBREAKER : ACHIEV_HEARTBREAKER_H); + } + + // Nerf Engineer + if(m_bIsEngineer) + { + if(m_pInstance) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_NERF_ENGINEERING : ACHIEV_NERF_ENGINEERING_H); + } + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_XT002, IN_PROGRESS); + if(m_pInstance->GetData(TYPE_XT002_TP) != DONE) + m_pInstance->SetData(TYPE_XT002_TP, DONE); + } + + DoScriptText(SAY_AGGRO, m_creature); + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_XT002, FAIL); + m_pInstance->SetData(TYPE_XT002_HARD, NOT_STARTED); + } + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_SLAY_01, m_creature); break; + case 1: DoScriptText(SAY_SLAY_02, m_creature); break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // Achiev timer + uiEncounterTimer += uiDiff; + + // light bomb + if (m_uiLight_Bomb_Timer < uiDiff && !m_bPhase2) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + // fix spell range + DoCast(pTarget, m_bIsRegularMode ? SPELL_LIGHT_BOMB : SPELL_LIGHT_BOMB_H); + pLightBombTarGUID = pTarget->GetGUID(); + } + + // spawn a life spark from the target + if(m_bIsHardMode) + m_uiLifeSparkTimer = 9000; + + m_uiLight_Bomb_Timer = urand(10000, 14000); + }else m_uiLight_Bomb_Timer -= uiDiff; + + // graviti bomb + if (m_uiGravity_Bomb_Timer < uiDiff && !m_bPhase2) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + // fix spell range + DoCast(pTarget, m_bIsRegularMode ? SPELL_GRAVITY_BOMB : SPELL_GRAVITY_BOMB_H); + pGravityBombTarGUID = pTarget->GetGUID(); + } + + // spawn a void zone from the target + if(m_bIsHardMode) + m_uiVoidZoneTimer = 9000; + + m_uiGravity_Bomb_Timer = urand(25000, 30000); + }else m_uiGravity_Bomb_Timer -= uiDiff; + + if (m_uiTanctrum_Timer < uiDiff && !m_bPhase2) + { + DoCast(m_creature, SPELL_TANCTRUM); + DoScriptText(SAY_TANCTRUM, m_creature); + m_uiTanctrum_Timer = 60000; + }else m_uiTanctrum_Timer -= uiDiff; + + // enrage timer + if (m_uiEnrage_Timer < uiDiff && !m_bIsEnrage && !m_bPhase2) + { + DoCast(m_creature, SPELL_ENRAGE); + if (m_creature->HasAura(SPELL_ENRAGE)) + { + m_bIsEnrage = true; + DoScriptText(SAY_BERSERK, m_creature); + } + else + m_uiEnrage_Timer = 5000; + }else m_uiEnrage_Timer -= uiDiff; + + // adds range check + if (m_uiRange_Check_Timer < uiDiff) + { + if (!m_lScrapbotsGUIDList.empty()) + { + for(std::list::iterator itr = m_lScrapbotsGUIDList.begin(); itr != m_lScrapbotsGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + { + if (pTemp->isAlive() && m_creature->IsWithinDistInMap(pTemp, ATTACK_DISTANCE)) + { + m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.01); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_bIsEngineer = false; + DoScriptText(EMOTE_REPAIR, m_creature); + } + } + } + } + if (!m_lBoombotsGUIDList.empty()) + { + for(std::list::iterator itr = m_lBoombotsGUIDList.begin(); itr != m_lBoombotsGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + { + if (pTemp->isAlive() && m_creature->IsWithinDistInMap(pTemp, ATTACK_DISTANCE)) + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + } + m_uiRange_Check_Timer = 1000; + }else m_uiRange_Check_Timer -= uiDiff; + + // Hard mode + if (m_pInstance->GetData(TYPE_XT002_HARD) == IN_PROGRESS && !m_bIsHardMode) + { + DoScriptText(SAY_HEART_CLOSE, m_creature); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->RemoveAurasDueToSpell(SPELL_STUN); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->AI()->AttackStart(m_creature->getVictim()); + + DoCast(m_creature, m_bIsRegularMode ? SPELL_HEARTBREAK : SPELL_HEARTBREAK_H); + m_uiHpDelayTimer = 500; + m_bHasMoreHealth = true; + m_bIsHardMode = true; + } + + if(m_bIsHardMode) + { + m_bPhase2 = false; + + // the spell doesn't increase the boss' heart. Override + if(m_uiHpDelayTimer < uiDiff && m_bHasMoreHealth) + { + m_creature->SetHealth(m_creature->GetMaxHealth()+ (m_creature->GetMaxHealth() * m_bIsRegularMode ? 0.5 : 0.6)); + m_bHasMoreHealth = false; + }else m_uiHpDelayTimer -= uiDiff; + + if (m_uiLifeSparkTimer < uiDiff) + { + if (Unit* pTarget = m_creature->GetMap()->GetUnit( pLightBombTarGUID)) + { + Creature * LifeSpark = m_creature->SummonCreature(NPC_LIFESPARK, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); + if(m_bIsRegularMode) + LifeSpark->SetHealth(50400); + } + m_uiLifeSparkTimer = 60000; + }else m_uiLifeSparkTimer -= uiDiff; + + if (m_uiVoidZoneTimer < uiDiff) + { + if (Unit* pTarget = m_creature->GetMap()->GetUnit( pGravityBombTarGUID)) + m_creature->SummonCreature(NPC_VOIDZONE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000); + m_uiVoidZoneTimer = 60000; + }else m_uiVoidZoneTimer -= uiDiff; + } + + if (!m_bPhase2 && m_creature->GetHealthPercent() < m_uiHealthPercent && !m_bIsHardMode) + { + m_uiHeart_Timer = 30000; + m_creature->CastStop(); + m_uiHealthPercent = m_uiHealthPercent - 25; + m_bPhase2 = true; + DoScriptText(SAY_HEART_OPEN, m_creature); + DoCast(m_creature, SPELL_STUN); + DoScriptText(EMOTE_HEART, m_creature); + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + // timers + m_uiScrapbotTimer = urand(3000, 5000); + m_uiBoombotTimer = urand(3000, 5000); + m_uiPummellerTimer = 5000; + m_uiMaxScrapbot = urand(7, 10) * 5; + m_uiMaxBoombot = urand(3, 7); + m_uiScrapbotCount = 0; + m_uiBoombotCount = 0; + m_uiPummellerCount = 0; + + if(Creature *Heart = m_creature->SummonCreature(NPC_HEART, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 900000)) + { + m_uiXtHeartGUID = Heart->GetGUID(); + // this needs fixing in DB + if(!m_bIsRegularMode) + Heart->SetMaxHealth(7199999); + } + } + + if (m_bPhase2 && m_uiHeart_Timer < uiDiff) + { + DoScriptText(SAY_HEART_CLOSE, m_creature); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->RemoveAurasDueToSpell(SPELL_STUN); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->AI()->AttackStart(m_creature->getVictim()); + m_bPhase2 = false; + m_uiLight_Bomb_Timer = 7000; + m_uiGravity_Bomb_Timer = 11000; + m_uiTanctrum_Timer = 38000; + }else m_uiHeart_Timer -= uiDiff; + + //adds + if(m_bPhase2 && !m_bIsHardMode) + { + // pummeller + if(m_uiPummellerTimer < uiDiff && m_uiPummellerCount < 2) + { + if(m_uiPummellerCount == 0) + DoScriptText(SAY_ADDS, m_creature); + uint8 i = urand(0, 4); + if (Creature* pTemp = m_creature->SummonCreature(NPC_PUMMELER, SummonLoc[i].x + urand(0, 10), SummonLoc[i].y + urand(0, 10), SummonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + pTemp->AddThreat(pTarget,0.0f); + pTemp->AI()->AttackStart(pTarget); + m_lPummelerGUIDList.push_back(pTemp->GetGUID()); + } + } + m_uiPummellerCount += 1; + m_uiPummellerTimer = 4000; + } + else m_uiPummellerTimer -= uiDiff; + + // boombot + if(m_uiBoombotTimer < uiDiff && m_uiBoombotCount < m_uiMaxBoombot) + { + uint8 i = urand(0, 4); + if (Creature* pTemp = m_creature->SummonCreature(NPC_BOOMBOT, SummonLoc[i].x + urand(0, 10), SummonLoc[i].y + urand(0, 10), SummonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->AddThreat(m_creature->getVictim(),1000.0f); + pTemp->AI()->AttackStart(m_creature->getVictim()); + m_lBoombotsGUIDList.push_back(pTemp->GetGUID()); + } + m_uiBoombotCount += 1; + m_uiBoombotTimer = 4000; + } + else m_uiBoombotTimer -= uiDiff; + + // scrapbot + if(m_uiScrapbotTimer < uiDiff && m_uiScrapbotCount < m_uiMaxScrapbot) + { + uint8 i = urand(0, 4); + for(int j = 0; j < 5; j++) + { + if (Creature* pTemp = m_creature->SummonCreature(NPC_SCRAPBOT, SummonLoc[i].x + urand(0, 10), SummonLoc[i].y + urand(0, 10), SummonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + { + pTemp->GetMotionMaster()->MoveFollow(m_creature, 0, 0); + m_lScrapbotsGUIDList.push_back(pTemp->GetGUID()); + m_uiScrapbotCount += 1; + } + } + m_uiScrapbotTimer = 3000; + } + else m_uiScrapbotTimer -= uiDiff; + } + + if (!m_bPhase2) + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_xt002(Creature* pCreature) +{ + return new boss_xt002AI(pCreature); +} + +void AddSC_boss_xt002() +{ + Script* NewScript; + + NewScript = new Script; + NewScript->Name = "boss_xt002"; + NewScript->GetAI = GetAI_boss_xt002; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_pummeler"; + NewScript->GetAI = &GetAI_mob_pummeler; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_boombot"; + NewScript->GetAI = &GetAI_mob_boombot; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_xtheart"; + NewScript->GetAI = &GetAI_mob_xtheart; + NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "mob_voidzone"; + NewScript->GetAI = &GetAI_mob_voidzone; + NewScript->RegisterSelf(); + NewScript = new Script; + NewScript->Name = "mob_lifespark"; + NewScript->GetAI = &GetAI_mob_lifespark; + NewScript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp b/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp index 1cf0af23b..e6eb1d662 100644 --- a/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,8 +16,8 @@ /* ScriptData SDName: boss_yogg_saron -SD%Complete: 0% -SDComment: +SD%Complete: +SDComment: Implement sanity, some other spells need core support. If the topaggro target is teleported into a vision, the boss resets -> needs fixing! SDCategory: Ulduar EndScriptData */ @@ -26,53 +26,2744 @@ EndScriptData */ enum { - SAY_SARA_INTRO_1 = -1603197, - SAY_SARA_INTRO_2 = -1603198, - SAY_SARA_AGGRO = -1603199, - SAY_SARA_HELP_1 = -1603200, - SAY_SARA_HELP_2 = -1603201, - SAY_SARA_SLAY_1 = -1603202, - SAY_SARA_SLAY_2 = -1603203, - SAY_WIPE_PHASE_1 = -1603204, - - SAY_PHASE_2_INTRO = -1603205, - SAY_SARA_PHASE_2_INTRO_A = -1603206, - SAY_SARA_PHASE_2_INTRO_B = -1603207, - - SAY_MADNESS = -1603209, - SAY_PHASE_3 = -1603210, - SAY_SLAY_1 = -1603211, - SAY_SLAY_2 = -1603212, - SAY_DEATH = -1603213, - SAY_TO_INSANE_1 = -1603214, - SAY_TO_INSANE_2 = -1603215, - - SAY_LICH_KING_1 = -1603216, - SAY_CHAMPION_1 = -1603217, - SAY_CHAMPION_2 = -1603218, - SAY_LICH_KING_2 = -1603219, - SAY_YOGG_V3_1 = -1603220, - SAY_YOGG_V3_2 = -1603221, - - SAY_NELTHARION_1 = -1603222, - SAY_YSERA = -1603223, - SAY_NELTHARION_2 = -1603224, - SAY_MALYGOS = -1603225, - SAY_YOGG_V2 = -1603226, - - SAY_GARONA_1 = -1603227, - SAY_GARONA_2 = -1603228, - SAY_YOGG_V1_1 = -1603229, - SAY_YOGG_V1_2 = -1603230, - SAY_GARONA_3 = -1603231, - SAY_GARONA_4 = -1603232, - SAY_YOGG_V1_3 = -1603233, - - EMOTE_VISION_BLAST = -1603234, - EMOTE_SHATTER_BLAST = -1603235, + //yells + //sara + SAY_INTRO1 = -1603307, + SAY_INTRO2 = -1603308, + SAY_AGGRO = -1603300, + SAY_HELP1 = -1603301, + SAY_HELP2 = -1603302, + SAY_SPECIAL1 = -1603305, + SAY_SPECIAL2 = -1603306, + SAY_KILL1 = -1603303, + SAY_KILL2 = -1603304, + SAY_WIPE = -1603309, + + //yogg + SAY_PHASE2 = -1603321, + SAY_VISION = -1603322, + EMOTE_PORTALS = -1603372, + EMOTE_SHATTER = -1603373, + SAY_PHASE3 = -1603323, + SAY_SLAY1 = -1603324, + SAY_SLAY2 = -1603325, + SAY_DEATH = -1603326, + SAY_INSANITY1 = -1603327, + SAY_INSANITY2 = -1603328, + + //visions + //stormwind + SAY_GARONA1 = -1603341, + SAY_GARONA2 = -1603342, + SAY_YOGG_V1_1 = -1603343, + SAY_YOGG_V1_2 = -1603344, + SAY_GARONA3 = -1603345, + SAY_GARONA4 = -1603346, + SAY_YOGG_V1_3 = -1603347, + + //dragons + SAY_NELTHARION1 = -1603336, + SAY_YSERA = -1603337, + SAY_NELTHARION2 = -1603338, + SAY_MALYGOS = -1603339, + SAY_YOGG_V2 = -1603340, + + //lich king + SAY_LICH_KING1 = -1603330, + SAY_CHAMPION1 = -1603331, + SAY_CHAMPION2 = -1603332, + SAY_LICH_KING2 = -1603333, + SAY_YOGG_V3_1 = -1603334, + SAY_YOGG_V3_2 = -1603335, + + //keepers yells + SAY_HODIR_ACTIVE = -1603086, + SAY_FREYA_ACTIVE = -1603009, + SAY_THORIM_ACTIVE = -1603238, + SAY_MIMIRON_ACTIVE = -1603260, + + //vision npc + //stormwind + NPC_GARONA = 33436, + NPC_KING_LLANE = 33437, + + MOB_SUIT_OF_ARMOR = 33433, + + //dragons + NPC_NELTHARION = 33523, + NPC_YSERA = 33495, + NPC_MALYGOS = 33535, + NPC_ALEXSTRASZA = 33536, + GO_DRAGON_SOUL = 194462, + + MOB_RUBY_CONSORT = 33716, + MOB_AZURE_CONSORT = 33717, + MOB_BRONZE_CONSORT = 33718, + MOB_EMERALD_CONSORT = 33719, + MOB_OBSIDIAN_CONSORT = 33720, + + + //lich king + NPC_LICH_KING = 33441, + NPC_IMMOLATED_CHAMPION = 33442, + + NPC_VOICE_OF_YOGG_SARON = 33280, + MOB_VISION_TENTACLE = 33943, + SPELL_GRIM_REPRISAL = 63305, + // npc hp: 15k on 10 man; 40k on 25 man + // npc no: 10 + + //spells + //phase1 + SPELL_SARAS_FERVOR = 63138, + SPELL_SARAS_BLESSING = 63134, + SPELL_SARAS_ANGER = 63147, + + MOB_GUARDIAN_OF_YOGG = 33136, + SPELL_DARK_VOLLEY = 63038, + SPELL_SHADOW_NOVA = 62714, //when dies + SPELL_SHADOW_NOVA_H = 65209, + SPELL_DOMINATE_MIND = 63713, + + // clouds + SPELL_OMINOUS_CLOUD_VISUAL = 63084, + SPELL_SUMMON_GUARDIAN = 62978, + SPELL_SUMMON_GUARDIAN2 = 63031, + NPC_OMINOUS_CLOUD = 33292, + + //phase2 + SPELL_SHADOWY_BARRIER = 64775, + SPELL_SHADOWY_BARRIER_YOGG = 63894, + SPELL_SANITY = 63050, + SPELL_PHYCHOSIS = 65301, + SPELL_PHYCHOSIS_H = 63795, + SPELL_MALADY_OF_THE_MIND = 63830, + SPELL_BRAIN_LINK = 63802, + SPELL_BRAIN_LINK_DMG = 63803, + SPELL_BRAIN_LINK_NON_DMG = 63804, + SPELL_DEATH_RAY = 63891, //summons orb + SPELL_DEATH_RAY_TRIGG = 63883, + SPELL_DEATH_RAY_VISUAL = 63886, + SPELL_DEATH_RAY_VISUAL_ORI = 63893, + MOB_DEATH_ORB = 33882, + + MODEL_SARA_VALKYR = 29182, + MODEL_SARA_HUMAN = 29117, + + // sanity + SPELL_CLEAR_INSANE = 63122, + SPELL_INSANE = 63120, + SPELL_INSANE_VISUAL = 64464, + SPELL_INSANE_TRIGG = 64554, + + SPELL_LOW_SANITY_EFFECT = 63752, + SPELL_SANITY_TRIGG = 63786, + + // portals + MOB_DESCEND_INTO_MADNESS = 34072, + SPELL_LUNATIC_GAZE = 64167, //affects players which take the portal to madness + NPC_LAUGHING_SKULL = 33990, + SKULL_DISPLAY_ID = 25206, + + // brain's chamber + MOB_BRAIN_OF_YOGG_SARON = 33890, + SPELL_SHATTERED_ILLUSION = 64173, + SPELL_INDUCE_MADNESS = 64059, + SPELL_ILLUSION_ROOM = 63988, // reduce speed + SPELL_ILLUSION_CANCEL = 63993, + + + // tentacules + MOB_CRUSHER_TENTACLE = 33966, + SPELL_ERUPT = 64144, //also used by the corruptor tentacle + SPELL_DIMINISH_POWER = 64145, + SPELL_FOCUSED_ANGER = 57689, + SPELL_FOCUSED_ANGER_TRIGG = 57688, + SPELL_SUMMON_CRUSHER = 64139, + + MOB_CONSTRICTOR_TENTACLE = 33983, + SPELL_SQUEEZE = 64125, + SPELL_SQUEEZE_H = 64126, + SPELL_SUMMON_CONSTRICTOR = 64133, + + MOB_CORRUPTOR_TENTACLE = 33985, + SPELL_APATHY = 64156, + SPELL_BLACK_PLAGUE = 64153, + SPELL_CURSE_OF_DOOM = 64157, + SPELL_DRAINING_POISON = 64152, + + // phase 3 + SPELL_LUNATIC_GAZE_YOGG = 64163, + SPELL_SHADOW_BEACON = 64465, + SPELL_EMPOWERING_SHADOWS = 64468, + SPELL_EMPOWERING_SHADOWS_H = 64486, + SPELL_DEAFENING_ROAR = 64189, //only cast on 25 player with 0-3 keepes active + + MOB_IMMORTAL_GUARDIAN = 33988, + SPELL_EMPOWERED = 65294, //starts with 9 stacks and loses 1 stak at 10% hp + SPELL_EMPOWERED_AURA = 64161, + + SPELL_BERSERK = 64166, //extinguish all life + + // keepers + // freya + SPELL_RESILIENCE_OF_NATURE = 62670, + MOB_SANITY_WELL = 33991, + SPELL_SANITY_WELL = 64169, // regen sanity + SPELL_SANITY_WELL_VISUAL = 63288, + SPELL_SUMMON_SANITY_WELL = 64170, + + // hodir + SPELL_FORTITUDE_OF_FROST = 62650, + SPELL_HODIRS_PROTECTIVE_GAZE= 64174, // saves players from killing blows ~25secs cd + + // thorim + SPELL_SPEED_OF_INVENTION = 62671, + SPELL_DESTABILIZATION_MATRIX= 65210, // cast in phase 2 on the tentacules + + // mimiron + SPELL_FURY_OF_THE_STORM = 62702, + SPELL_TITANIC_STORM = 64171, // used in phase 3 to kill guardians + SPELL_TITANIC_STORM_DMG = 64172, +}; + +enum phases +{ + // yogg phases + PHASE_IDLE = 0, + PHASE_SARA = 1, + PHASE_TENTACLES = 2, + PHASE_OLD_GOD = 3, + // vision phases + PHASE_VISION_STORMWIND = 1, + PHASE_VISION_WYRMREST = 2, + PHASE_VISION_ICECROWN = 3, + PHASE_VISION_RETURN = 4, // used to set the portals to return to main chamber = idle +}; + +enum achievs +{ + ACHIEV_ALONE = 3159, + ACHIEV_ALONE_H = 3164, + ACHIEV_ONE_LIGHT = 3158, + ACHIEV_ONE_LIGHT_H = 3163, + ACHIEV_TWO_LIGHTS = 3141, + ACHIEV_TWO_LIGHTS_H = 3162, + ACHIEV_THREE_LIGHTS = 3157, + ACHIEV_THREE_LIGHTS_H = 3161, + ACHIEV_NOT_GETTING_OLDER = 3012, + ACHIEV_NOT_GETTING_OLDER_H = 3013, +}; + +//Positional defines +struct LocationsXY +{ + float x, y, z, o; + uint32 id; +}; +static LocationsXY SummonLoc[]= +{ + {1951.097412f,-25.42042f, 326.162598f}, + {1970.677490f,-0.211162f, 325.478638f}, + {2001.049805f,-4.201718f, 325.751831f}, + {2009.346924f,-26.001806f,325.603271f}, + {1998.081665f,-46.625187f,325.551605f}, + {1962.782715f,-51.363148f,325.458160f}, + {1988.847778f,-71.143738f,328.647614f}, + {2024.004150f,-40.749989f,327.876617f}, + {2018.806885f,-3.451158f,327.593933f}, + {1978.651001f,18.373478f,328.420532f}, + {1940.641602f,1.761525f, 327.921661f}, + {1941.203735f,-52.999535f,327.246948f}, +}; + +static LocationsXY SanityWellLoc[]= +{ + {1901.237915f, -46.305782f, 331.960754f}, + {1900.753052f, -2.259287f, 332.061249f}, + {1991.020996f, 43.943943f, 331.746979f}, + {2044.219482f, -21.878244f, 329.776855f}, + {1986.226807f, -95.087761f, 330.253998f}, +}; + +static LocationsXY KeepersLoc[]= +{ + {2036.859863f, -74.113884f, 338.415222f, 2.488684f}, //thorim + {1938.328247f, -90.742043f, 338.459442f, 0.992500f}, //hodir + {2036.107056f, 25.702380f, 338.415192f, 4.019527f}, // freya + {1939.021240f, 43.221031f, 338.460663f, 5.214388f}, // mimiron +}; + +static LocationsXY TeleportLoc[]= +{ + {1941.587402f, 43.526680f, 239.666336f}, // stormwind + {2055.460938f, -25.619570f, 239.721176f}, // dragons + {1941.131226f, -94.654694f, 239.989639f}, // icecrown + {1951.097f, -25.420f, 326.162f}, // yogg +}; + +static LocationsXY YoggPortalLoc[]= +{ + {1959.765137f, -20.697853f, 325.352966f}, + {1973.407837f, -6.656567f, 324.889526f}, + {1990.271851f, -47.992981f, 324.959991f}, + {1978.893433f, -49.858326f, 324.777618f}, + {1967.471924f, -46.298458f, 324.840759f}, + {1959.654297f, -39.954502f, 324.997253f}, + {1956.343872f, -25.642859f, 325.188354f}, + {1985.072021f, -2.515451f, 325.20010f}, + {1993.541626f, -10.527716f, 324.889587f}, + {2003.674316f, -23.050785f, 325.384064f}, +}; + +static LocationsXY MadnessPortalLoc[]= +{ + {2001.015f, 4.185f, 242.747f}, + {1999.690f, -54.931f, 242.418f}, + {1946.898f, -25.769f, 242.169f}, +}; +// vison pos +//Positional defines +struct VisionLocXY +{ + float x, y, z, o; + uint32 id; +}; +// dragons +const float PosYsera[4] = {2114.504f, -16.118f, 242.646f, 3.91f}; +const float PosMalygos[4] = {2113.388f, -34.381f, 242.646f, 2.26f}; +const float PosNeltharion[4] = {2117.588f, -25.318f, 242.646f, 3.15f}; +const float PosAlexstrasza[4] = {2091.679f, -25.289f, 242.646f, 6.282f}; +const float PosVoiceDragon[3] = {2104.555f, -25.635f, 242.646f}; +const float DisplayDragons[10] = {2718, 2718, 2717, 2717, 12869, 12869, 1687, 1687, 2719, 2719}; + +static VisionLocXY DragonLoc[]= +{ + {2071.951660f, 1.881840f, 239.794922f, 5.590341f}, + {2093.910156f, 19.939915f, 239.766830f, 4.962034f}, + {2114.737061f, 20.441664f, 239.757309f, 4.259104f}, + {2136.709473f, 4.874056f, 239.718658f, 3.889961f}, + {2147.894287f, -12.416141f, 239.757980f, 3.210588f}, + {2148.479004f, -37.655373f, 239.720169f, 3.033874f}, + {2136.296631f, -56.800838f, 239.754654f, 2.287745f}, + {2114.370117f, -68.110947f, 239.721100f, 1.789017f}, + {2093.946289f, -67.447899f, 239.720734f, 1.305995f}, + {2071.001709f, -54.414040f, 239.719345f, 0.528450f}, +}; + +static VisionLocXY SkullDragonLoc[]= +{ + {2075.898193f, -5.637041f, 239.787735f}, + {2137.949219f, -26.778023f, 239.717712f}, + {2084.131836f, -52.716999f, 239.720703f}, +}; + +// stormwind +const float PosGarona[4] = {1935.398926f, 54.017738f, 240.376465f, 2.008213f}; +const float PosKing[4] = {1930.465670f, 62.674065f, 242.376373f, 5.196925f}; +const float PosVoiceStormwind[3] = {1927.326f, 68.120f, 242.376f}; + +static VisionLocXY KeepLoc[]= +{ + {1930.854370f, 39.910034f, 239.666443f, 1.641476f}, + {1909.771240f, 45.685230f, 239.666443f, 0.962106f}, + {1898.966309f, 64.644989f, 239.666443f, 0.157073f}, + {1904.273926f, 85.369118f, 239.666443f, 5.662714f}, + {1923.474487f, 96.419815f, 239.666443f, 4.826267f}, + {1944.612061f, 91.062439f, 239.666443f, 4.076213f}, + {1955.231079f, 71.870926f, 239.666443f, 3.255475f}, + {1949.701416f, 51.040390f, 239.666443f, 2.481856f}, +}; + +static VisionLocXY SkullKeepLoc[]= +{ + {1908.942261f, 58.934380f, 239.666382f}, + {1916.902954f, 86.755638f, 239.66662f}, + {1944.789307f, 78.614716f, 239.666382f}, +}; + +// lich king +const float PosLichKing[4] = {1910.499268f,-147.709961f,239.989639f, 0.943203f}; +const float PosChampion[4] = {1915.371094f,-139.934219f,239.989639f, 4.159409f}; +const float PosVoiceIcecrown[3] = {1914.332f, -139.317f, 239.989f}; + +static VisionLocXY IcecrownLoc[]= +{ + {1952.521606f, -137.052094f, 239.989716f, 2.513270f}, + {1946.220337f, -130.236008f, 239.989716f, 5.387829f}, + {1942.029541f, -136.833328f, 239.989716f, 0.192416f}, + {1896.965210f, -104.922951f, 239.989716f, 5.647007f}, + {1904.356079f, -113.879349f, 239.989716f, 2.163766f}, + {1907.664795f, -106.186508f, 239.989716f, 2.976653f}, + {1919.831421f, -131.184784f, 239.989716f, 4.213656f}, + {1919.120728f, -145.960281f, 239.989716f, 1.908511f}, + {1907.462891f, -139.149307f, 239.989716f, 0.176708f}, +}; + +static VisionLocXY SkullIcecrownLoc[]= +{ + {1962.658569f, -111.356392f, 239.98986f}, + {1940.515625f, -152.933945f, 239.989868f}, + {1889.130371f, -122.932549f, 239.98986f}, + {1908.828003f, -88.593613f, 239.98986f}, +}; + +// location of the minds eye: +// X: 1981.422974 Y: -22.442831 Z: 236.104813 + +// transfer from brain +// X: 1951.097412 Y: -25.420420 Z: 326.162598 Orientation: 0.131792 +// brain room portal loc: +// sara -> type_flags = 108; original + +// SanityAura, needs core support, not used here +class MANGOS_DLL_DECL SanityAura : public Aura +{ +public: + SanityAura(const SpellEntry *spell, SpellEffectIndex eff, int32 *bp, SpellAuraHolder *holder, Unit *target, Unit *caster) : Aura(spell, eff, bp, holder, target, caster, NULL) + {} +}; + +// Yogg Saron, main event controller +struct MANGOS_DLL_DECL boss_yogg_saronAI : public ScriptedAI +{ + boss_yogg_saronAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiBerserkTimer; + uint32 m_uiSanityTimer; + uint32 m_uiKeepersActive; + + uint32 m_uiLunaticGazaTimer; + uint32 m_uiShadowBeaconTimer; + uint32 m_uiEmpoweringShadowsTimer; + uint32 m_uiSummonTimer; + uint32 m_uiDeafeningRoarTimer; + bool m_bIsShatter; + + uint32 m_uiAchievTimer; + + std::list lClouds; + + void Reset() + { + m_uiSanityTimer = 10000; + m_uiKeepersActive = 0; + + // phase 3 + m_uiLunaticGazaTimer = 20000; + m_uiShadowBeaconTimer = 15000; + m_uiEmpoweringShadowsTimer = 60000; + m_uiSummonTimer = 40000; + m_uiDeafeningRoarTimer = 30000; + m_uiAchievTimer = 0; + m_bIsShatter = false; + m_uiBerserkTimer = 900000; // 15 min + + m_creature->SetVisibility(VISIBILITY_OFF); + + if(m_creature->HasAura(SPELL_SHADOWY_BARRIER_YOGG)) + m_creature->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER_YOGG); + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if(m_pInstance) + { + m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_IDLE); + m_pInstance->SetData(TYPE_VISION_PHASE, PHASE_VISION_RETURN); + } + + // respawn clouds + GetCreatureListWithEntryInGrid(lClouds, m_creature, NPC_OMINOUS_CLOUD, DEFAULT_VISIBILITY_INSTANCE); + if (!lClouds.empty()) + { + for(std::list::iterator iter = lClouds.begin(); iter != lClouds.end(); ++iter) + { + if ((*iter) && !(*iter)->isAlive()) + (*iter)->Respawn(); + } + } + } + + void Aggro(Unit *who) + { + m_creature->SetInCombatWithZone(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + //StartSanity(); + + if(m_pInstance) + { + m_pInstance->SetData(TYPE_YOGGSARON, IN_PROGRESS); + m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_SARA); + // summon thorim + if(m_pInstance->GetData(TYPE_KEEPER_THORIM) == DONE) + { + m_creature->SummonCreature(KEEPER_THORIM, KeepersLoc[0].x, KeepersLoc[0].y, KeepersLoc[0].z, KeepersLoc[0].o, TEMPSUMMON_MANUAL_DESPAWN, 0); + m_uiKeepersActive += 1; + } + // summon hodir + if(m_pInstance->GetData(TYPE_KEEPER_HODIR) == DONE) + { + m_creature->SummonCreature(KEEPER_HODIR, KeepersLoc[1].x, KeepersLoc[1].y, KeepersLoc[1].z, KeepersLoc[1].o, TEMPSUMMON_MANUAL_DESPAWN, 0); + m_uiKeepersActive += 1; + } + // summon freya + if(m_pInstance->GetData(TYPE_KEEPER_FREYA) == DONE) + { + m_creature->SummonCreature(KEEPER_FREYA, KeepersLoc[2].x, KeepersLoc[2].y, KeepersLoc[2].z, KeepersLoc[2].o, TEMPSUMMON_MANUAL_DESPAWN, 0); + m_uiKeepersActive += 1; + } + // summon mimiron + if(m_pInstance->GetData(TYPE_KEEPER_MIMIRON) == DONE) + { + m_creature->SummonCreature(KEEPER_MIMIRON, KeepersLoc[3].x, KeepersLoc[3].y, KeepersLoc[3].z, KeepersLoc[3].o, TEMPSUMMON_MANUAL_DESPAWN, 0); + m_uiKeepersActive += 1; + } + + if(Creature* pSara = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SARA))) + DoScriptText(SAY_AGGRO, pSara); + } + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_YOGGSARON, NOT_STARTED); + + if(Creature* pSara = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SARA))) + { + if(!pSara->isAlive()) + pSara->Respawn(); + else + pSara->AI()->EnterEvadeMode(); + } + + if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN))) + { + if(!pYoggBrain->isAlive()) + pYoggBrain->Respawn(); + else + pYoggBrain->AI()->EnterEvadeMode(); + } + } + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_SLAY1, m_creature); + else + DoScriptText(SAY_SLAY2, m_creature); + } + + void JustDied(Unit *killer) + { + DoScriptText(SAY_DEATH, m_creature); + if(m_pInstance) + { + m_pInstance->SetData(TYPE_YOGGSARON, DONE); + m_pInstance->SetData(TYPE_YOGGSARON_HARD, 0); + + // hacky way to complete achievements; use only if you have this function + if(m_uiKeepersActive == 0) + { + m_pInstance->SetData(TYPE_YOGGSARON_HARD, 4); + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_ALONE : ACHIEV_ALONE_H); + } + else if (m_uiKeepersActive == 1) + { + m_pInstance->SetData(TYPE_YOGGSARON_HARD, 3); + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_ONE_LIGHT : ACHIEV_ONE_LIGHT_H); + } + else if (m_uiKeepersActive == 2) + { + m_pInstance->SetData(TYPE_YOGGSARON_HARD, 2); + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_TWO_LIGHTS : ACHIEV_TWO_LIGHTS_H); + } + else if (m_uiKeepersActive == 3) + { + m_pInstance->SetData(TYPE_YOGGSARON_HARD, 1); + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_THREE_LIGHTS : ACHIEV_THREE_LIGHTS_H); + } + + // under 7 min + if(m_uiAchievTimer < 420000) + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_NOT_GETTING_OLDER : ACHIEV_NOT_GETTING_OLDER_H); + + } + + if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA))) + { + if(pSara->isAlive()) + pSara->DealDamage(pSara, pSara->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN))) + { + if(pYoggBrain->isAlive()) + pYoggBrain->DealDamage(pYoggBrain, pYoggBrain->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + void StartSecondPhase() + { + m_creature->SetVisibility(VISIBILITY_ON); + DoCast(m_creature, SPELL_SHADOWY_BARRIER_YOGG); + StartSanity(); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + GetCreatureListWithEntryInGrid(lClouds, m_creature, NPC_OMINOUS_CLOUD, DEFAULT_VISIBILITY_INSTANCE); + if (!lClouds.empty()) + { + for(std::list::iterator iter = lClouds.begin(); iter != lClouds.end(); ++iter) + { + if ((*iter) && (*iter)->isAlive()) + (*iter)->ForcedDespawn(); + } + } + + m_uiSummonTimer = urand(3000, 7000); + } + + void StartThirdPhase() + { + DoScriptText(SAY_PHASE3, m_creature); + m_creature->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER_YOGG); + m_creature->SetHealth(m_creature->GetMaxHealth() * 0.3); + + m_uiSummonTimer = urand(15000, 20000); + + if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA))) + pSara->ForcedDespawn(); + + if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN))) + pYoggBrain->DealDamage(pYoggBrain, pYoggBrain->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + // hacky way of doing sanity before the recent aura changes + void StartSanity() + { + Map *map = m_creature->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + SpellEntry* spell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_SANITY); + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive()) + { + /* if(i->getSource()->HasAura(SPELL_SANITY, EFFECT_INDEX_0)) + i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0)->SetStackAmount(100); + else + { + if(i->getSource()->AddAura(new SanityAura(spell, EFFECT_INDEX_0, NULL, i->getSource(), m_creature))) + i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0)->SetStackAmount(100); + }*/ + } + } + } + } + + void DoCastSanity() + { + uint8 m_uiStacks; + Map *map = m_creature->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive()) + { + // reduce sanity + if(i->getSource()->HasAura(SPELL_SANITY, EFFECT_INDEX_0)) + { + if(Aura *aura = i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0)) + { + m_uiStacks = aura->GetStackAmount(); + if(m_uiStacks == 100) + DoCast(i->getSource(), SPELL_INSANE); + /*if(m_uiStacks > 1) + i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0)->SetStackAmount(stack - 1); + else + { + i->getSource()->RemoveAurasDueToSpell(SPELL_SANITY); + DoCast(i->getSource(), SPELL_INSANE); + }*/ + } + } + } + } + } + } + + Creature* SelectRandomGuardian(float fRange) + { + std::list lGuardiansList; + GetCreatureListWithEntryInGrid(lGuardiansList, m_creature, MOB_IMMORTAL_GUARDIAN, fRange); + + //This should not appear! + if (lGuardiansList.empty()){ + m_uiEmpoweringShadowsTimer = 30000; + return NULL; + } + + std::list::iterator iter = lGuardiansList.begin(); + advance(iter, urand(0, lGuardiansList.size()-1)); + + return *iter; + } + + void SummonTentacles() + { + float homeZ = 0; + float creatureDist = 0; + // set tentacle entry + uint32 m_uiTentacles[] = {MOB_CONSTRICTOR_TENTACLE, MOB_CORRUPTOR_TENTACLE, MOB_CRUSHER_TENTACLE}; + uint32 m_uiEntry = urand(0, 2); + if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, MOB_CRUSHER_TENTACLE, 100.0f)) + { + if(pTemp->isAlive()) + m_uiEntry = urand(0, 1); + } + uint32 m_uiTentacleEntry = m_uiTentacles[m_uiEntry]; + + // set distance + // Z factor needs some fixing, in some cases it should be smaller + switch(urand(0, 1)) + { + case 0: + creatureDist = urand(20, 30); + homeZ = 326 + creatureDist * 0.05f; + break; + case 1: + creatureDist = urand(30, 45); + homeZ = 328 + creatureDist * 0.05f; + break; + } + + // set coordonates + float angle = (float) rand()*360/RAND_MAX + 1; + float homeX = m_creature->GetPositionX() + creatureDist*cos(angle*(M_PI/180)); + float homeY = m_creature->GetPositionY() + creatureDist*sin(angle*(M_PI/180)); + // summon tentacle + if(Creature *pTemp = m_creature->SummonCreature(m_uiTentacleEntry, homeX, homeY, homeZ, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) + pTemp->SetInCombatWithZone(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // achiev timer + m_uiAchievTimer += uiDiff; + + switch(m_pInstance->GetData(TYPE_YOGG_PHASE)) + { + case PHASE_SARA: + // Friendly Sara phase: see script below + break; + case PHASE_TENTACLES: + { + if (m_uiSanityTimer < uiDiff) + { + //DoCastSanity(); + //DoCast(m_creature, SPELL_SANITY); + m_uiSanityTimer = 20000; + } + else m_uiSanityTimer -= uiDiff; + + // summon tentacles + if (m_uiSummonTimer < uiDiff && !m_bIsShatter) + { + SummonTentacles(); + m_uiSummonTimer = urand(10000, 15000); + } + else m_uiSummonTimer -= uiDiff; + + break; + } + case PHASE_OLD_GOD: + { + if (m_uiSummonTimer < uiDiff) + { + if(Creature *pTemp = m_creature->SummonCreature(MOB_IMMORTAL_GUARDIAN, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) + pTemp->SetInCombatWithZone(); + m_uiSummonTimer = 30000; + } + else m_uiSummonTimer -= uiDiff; + + if (m_uiLunaticGazaTimer < uiDiff) + { + DoCast(m_creature, SPELL_LUNATIC_GAZE_YOGG); + m_uiLunaticGazaTimer = urand(10000, 13000); + } + else m_uiLunaticGazaTimer -= uiDiff; + + if (m_uiEmpoweringShadowsTimer < uiDiff) + { + if (Creature* pGuardian = SelectRandomGuardian(80.0f)) + DoCast(pGuardian, SPELL_SHADOW_BEACON); + m_uiEmpoweringShadowsTimer = 45000; + } + else m_uiEmpoweringShadowsTimer -= uiDiff; + + if (m_uiDeafeningRoarTimer < uiDiff && !m_bIsRegularMode && m_uiKeepersActive < 4) + { + DoCast(m_creature, SPELL_DEAFENING_ROAR); + m_uiDeafeningRoarTimer = 30000; + } + else m_uiDeafeningRoarTimer -= uiDiff; + + DoMeleeAttackIfReady(); + + break; + } + } + + // extinguish all life + if (m_uiBerserkTimer < uiDiff) + { + DoCast(m_creature, SPELL_BERSERK); + m_uiBerserkTimer = 10000; + } + else m_uiBerserkTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL mob_madness_portalAI : public ScriptedAI +{ + mob_madness_portalAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint8 m_uiDestination; + uint32 m_uiCheckTimer; + bool m_bHasTeleported; + + void Reset() + { + m_uiCheckTimer = 500; + m_bHasTeleported = false; + m_creature->SetRespawnDelay(DAY); + if(m_pInstance) + m_uiDestination = m_pInstance->GetData(TYPE_VISION_PHASE) - 1; + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_creature->GetPositionZ() < 245.0f) + m_uiDestination = 3; + + // hacky way. This should be done by a spell + // this uses the Type_vision_phase in order to set vision destination + if(m_uiCheckTimer < uiDiff && !m_bHasTeleported) + { + Map *map = m_creature->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) < 2) + { + i->getSource()->TeleportTo(i->getSource()->GetMapId(), TeleportLoc[m_uiDestination].x, TeleportLoc[m_uiDestination].y, TeleportLoc[m_uiDestination].z, i->getSource()->GetOrientation()); + if(m_uiDestination < 3) + { + i->getSource()->CastSpell(i->getSource(), SPELL_ILLUSION_ROOM, false); + m_creature->ForcedDespawn(); + } + else + i->getSource()->RemoveAurasDueToSpell(SPELL_ILLUSION_ROOM); + } + } + } + m_uiCheckTimer = 500; + }else m_uiCheckTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL boss_brain_of_yogg_saronAI : public ScriptedAI +{ + boss_brain_of_yogg_saronAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiVisionPhase; + uint32 m_uiSpeechTimer; + uint32 m_uiMadnessTimer; + uint32 m_uiTentacleCheckTimer; + + bool m_bIsPhaseFinished; + bool m_bIsVisionFinished; + bool m_bHasShattered; + + uint64 m_uiLichKingGUID; + uint64 m_uiChampionGUID; + uint64 m_uiGaronaGUID; + uint64 m_uiKingLlaneGUID; + uint64 m_uiNeltharionGUID; + uint64 m_uiMalygosGUID; + uint64 m_uiYseraGUID; + uint64 m_uiVoiceOfYoggGUID; + + void Reset() + { + m_bIsPhaseFinished = false; + m_bIsVisionFinished = false; + m_bHasShattered = false; + m_uiLichKingGUID = 0; + m_uiChampionGUID = 0; + m_uiGaronaGUID = 0; + m_uiKingLlaneGUID = 0; + m_uiNeltharionGUID = 0; + m_uiMalygosGUID = 0; + m_uiYseraGUID = 0; + m_uiVoiceOfYoggGUID = 0; + + m_uiVisionPhase = 0; + m_uiSpeechTimer = 1000; + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if(m_pInstance) + m_pInstance->SetData(TYPE_YOGG_BRAIN, NOT_STARTED); + + // close doors on reset + if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR1, 100.0f)) + pVisionDoor->SetGoState(GO_STATE_READY); + if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR2, 100.0f)) + pVisionDoor->SetGoState(GO_STATE_READY); + if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR3, 100.0f)) + pVisionDoor->SetGoState(GO_STATE_READY); + } + + // for debug + void Aggro(Unit *who) + { + // For vision debug only + //StartVisions(); + //m_pInstance->SetData(TYPE_VISION_PHASE, PHASE_VISION_STORMWIND); + //m_creature->GetMotionMaster()->MoveIdle(); + //m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), 255.011f, 0.0f); + //m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), 255.011f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(uiDamage > 0 && !m_bHasShattered) + { + if (Creature* pYogg = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGGSARON))) + { + ((boss_yogg_saronAI*)pYogg->AI())->m_bIsShatter = true; + // spell bugged, need core fix. It should be cast on tentacles, not on players! + //pYogg->CastSpell(pYogg, SPELL_SHATTERED_ILLUSION, false); + } + m_bHasShattered = true; + } + } + + void SummonPortals() + { + for(uint8 i = 0; i < 3; i++) + m_creature->SummonCreature(MOB_DESCEND_INTO_MADNESS, MadnessPortalLoc[i].x, MadnessPortalLoc[i].y, MadnessPortalLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); + } + + void StartVisions() + { + DoCast(m_creature, SPELL_INDUCE_MADNESS); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_uiVisionPhase = 0; + m_uiSpeechTimer = 1000; + m_uiTentacleCheckTimer = 1000; + m_uiMadnessTimer = 60000; + m_bIsVisionFinished = false; + m_bHasShattered = false; + } + + // check if all the tentacles are dead + bool IsThereAnyAdd(WorldObject *pSource) + { + if(GetClosestCreatureWithEntry(pSource, MOB_VISION_TENTACLE, 80.0f)) + return true; + + if(m_pInstance) + { + // open doors + switch(m_pInstance->GetData(TYPE_VISION_PHASE)) + { + case PHASE_VISION_STORMWIND: + if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR3, 100.0f)) + pVisionDoor->SetGoState(GO_STATE_ACTIVE); + break; + case PHASE_VISION_WYRMREST: + if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR1, 100.0f)) + pVisionDoor->SetGoState(GO_STATE_ACTIVE); + break; + case PHASE_VISION_ICECROWN: + if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR2, 100.0f)) + pVisionDoor->SetGoState(GO_STATE_ACTIVE); + break; + } + } + return false; + } + + void UpdateAI(const uint32 uiDiff) + { + switch(m_pInstance->GetData(TYPE_VISION_PHASE)) + { + case PHASE_VISION_STORMWIND: + { + if(m_uiSpeechTimer < uiDiff) + { + switch(m_uiVisionPhase) + { + case 0: + if(Creature* Garona = m_creature->SummonCreature(NPC_GARONA, PosGarona[0], PosGarona[1], PosGarona[2], PosGarona[3], TEMPSUMMON_TIMED_DESPAWN, 60000)) + m_uiGaronaGUID = Garona->GetGUID(); + if(Creature* KingLlane = m_creature->SummonCreature(NPC_KING_LLANE, PosKing[0], PosKing[1], PosKing[2], PosKing[3], TEMPSUMMON_TIMED_DESPAWN, 60000)) + m_uiKingLlaneGUID = KingLlane->GetGUID(); + if(Creature* VoiceOfYogg = m_creature->SummonCreature(NPC_VOICE_OF_YOGG_SARON, PosVoiceStormwind[0], PosVoiceStormwind[1], PosVoiceStormwind[2], 0, TEMPSUMMON_TIMED_DESPAWN, 60000)) + { + m_uiVoiceOfYoggGUID = VoiceOfYogg->GetGUID(); + VoiceOfYogg->SetDisplayId(11686); // make invisible + } + for(uint8 i = 0; i < 8; i++) + { + if(Creature *pTemp = m_creature->SummonCreature(MOB_VISION_TENTACLE, KeepLoc[i].x, KeepLoc[i].y, KeepLoc[i].z, KeepLoc[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 80000)) + { + pTemp->SetDisplayId(28621); + pTemp->SetMaxHealth(m_bIsRegularMode ? 15000 : 40000); + pTemp->setFaction(7); + pTemp->CastSpell(pTemp, SPELL_GRIM_REPRISAL, false); + } + } + for(uint8 i = 0; i < 3; i++) + m_creature->SummonCreature(NPC_LAUGHING_SKULL, SkullKeepLoc[i].x, SkullKeepLoc[i].y, SkullKeepLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); + ++m_uiVisionPhase; + m_uiSpeechTimer = 1000; + break; + case 1: + if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID)) + DoScriptText(SAY_GARONA1, Garona); + ++m_uiVisionPhase; + m_uiSpeechTimer = 12000; + break; + case 2: + if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID)) + DoScriptText(SAY_GARONA2, Garona); + ++m_uiVisionPhase; + m_uiSpeechTimer = 12000; + break; + case 3: + if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID)) + DoScriptText(SAY_YOGG_V1_1, VoiceOfYogg); + ++m_uiVisionPhase; + m_uiSpeechTimer = 4000; + break; + case 4: + if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID)) + DoScriptText(SAY_YOGG_V1_2, VoiceOfYogg); + ++m_uiVisionPhase; + m_uiSpeechTimer = 4000; + break; + case 5: + if(Creature* KingLlane = m_pInstance->instance->GetCreature(m_uiKingLlaneGUID)) + DoScriptText(SAY_GARONA3, KingLlane); + ++m_uiVisionPhase; + m_uiSpeechTimer = 6000; + break; + case 6: + if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID)) + Garona->GetMotionMaster()->MovePoint(0, 1931.348f, 61.033f, 241.709f); + ++m_uiVisionPhase; + m_uiSpeechTimer = 6000; + break; + case 7: + if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID)) + { + DoScriptText(SAY_GARONA4, Garona); + if(Creature* KingLlane = m_pInstance->instance->GetCreature(m_uiKingLlaneGUID)) + { + KingLlane->SetStandState(UNIT_STAND_STATE_DEAD); + KingLlane->SetHealth(0); + Garona->Attack(KingLlane, true); + } + } + ++m_uiVisionPhase; + m_uiSpeechTimer = 6000; + break; + case 8: + if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID)) + Garona->AttackStop(); + if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID)) + DoScriptText(SAY_YOGG_V1_3, VoiceOfYogg); + ++m_uiVisionPhase; + m_uiSpeechTimer = 8000; + break; + default: + m_uiSpeechTimer = 100000; + } + } + else m_uiSpeechTimer -= uiDiff; + + break; + } + case PHASE_VISION_WYRMREST: + { + if(m_uiSpeechTimer < uiDiff) + { + switch(m_uiVisionPhase) + { + case 0: + m_creature->SummonCreature(NPC_ALEXSTRASZA, PosAlexstrasza[0], PosAlexstrasza[1], PosAlexstrasza[2], PosAlexstrasza[3], TEMPSUMMON_TIMED_DESPAWN, 60000); + if(Creature* Neltharion = m_creature->SummonCreature(NPC_NELTHARION, PosNeltharion[0], PosNeltharion[1], PosNeltharion[2], PosNeltharion[3], TEMPSUMMON_TIMED_DESPAWN, 60000)) + m_uiNeltharionGUID = Neltharion->GetGUID(); + if(Creature* Malygos = m_creature->SummonCreature(NPC_MALYGOS, PosMalygos[0], PosMalygos[1], PosMalygos[2], PosMalygos[3], TEMPSUMMON_TIMED_DESPAWN, 60000)) + m_uiMalygosGUID = Malygos->GetGUID(); + if(Creature* Ysera = m_creature->SummonCreature(NPC_YSERA, PosYsera[0], PosYsera[1], PosYsera[2], PosYsera[3], TEMPSUMMON_TIMED_DESPAWN, 60000)) + m_uiYseraGUID = Ysera->GetGUID(); + if(Creature* VoiceOfYogg = m_creature->SummonCreature(NPC_VOICE_OF_YOGG_SARON, PosVoiceDragon[0], PosVoiceDragon[1], PosVoiceDragon[2], 0, TEMPSUMMON_TIMED_DESPAWN, 60000)) + { + m_uiVoiceOfYoggGUID = VoiceOfYogg->GetGUID(); + VoiceOfYogg->SetVisibility(VISIBILITY_OFF); + } + for(uint8 i = 0; i < 10; i++) + { + if(Creature *pTemp = m_creature->SummonCreature(MOB_VISION_TENTACLE, DragonLoc[i].x, DragonLoc[i].y, DragonLoc[i].z, DragonLoc[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 80000)) + { + pTemp->SetDisplayId(DisplayDragons[i]); + pTemp->SetMaxHealth(m_bIsRegularMode ? 15000 : 40000); + pTemp->setFaction(7); + pTemp->CastSpell(pTemp, SPELL_GRIM_REPRISAL, false); + } + } + for(uint8 i = 0; i < 3; i++) + m_creature->SummonCreature(NPC_LAUGHING_SKULL, SkullDragonLoc[i].x, SkullDragonLoc[i].y, SkullDragonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); + ++m_uiVisionPhase; + m_uiSpeechTimer = 1000; + break; + case 1: + if(Creature* Neltharion = m_pInstance->instance->GetCreature(m_uiNeltharionGUID)) + DoScriptText(SAY_NELTHARION1, Neltharion); + ++m_uiVisionPhase; + m_uiSpeechTimer = 10000; + break; + case 2: + if(Creature* Ysera = m_pInstance->instance->GetCreature(m_uiYseraGUID)) + DoScriptText(SAY_YSERA, Ysera); + ++m_uiVisionPhase; + m_uiSpeechTimer = 7000; + break; + case 3: + if(Creature* Neltharion = m_pInstance->instance->GetCreature(m_uiNeltharionGUID)) + DoScriptText(SAY_NELTHARION2, Neltharion); + ++m_uiVisionPhase; + m_uiSpeechTimer = 6000; + break; + case 4: + if(Creature* Malygos = m_pInstance->instance->GetCreature(m_uiMalygosGUID)) + DoScriptText(SAY_MALYGOS, Malygos); + ++m_uiVisionPhase; + m_uiSpeechTimer = 9000; + break; + case 5: + if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID)) + DoScriptText(SAY_YOGG_V2, VoiceOfYogg); + ++m_uiVisionPhase; + m_uiSpeechTimer = 10000; + break; + default: + m_uiSpeechTimer = 100000; + } + }else m_uiSpeechTimer -= uiDiff; + + break; + } + case PHASE_VISION_ICECROWN: + { + if(m_uiSpeechTimer < uiDiff) + { + switch(m_uiVisionPhase) + { + case 0: + if(Creature* LichKing = m_creature->SummonCreature(NPC_LICH_KING, PosLichKing[0], PosLichKing[1], PosLichKing[2], PosLichKing[3], TEMPSUMMON_TIMED_DESPAWN, 60000)) + m_uiLichKingGUID = LichKing->GetGUID(); + if(Creature* Champion = m_creature->SummonCreature(NPC_IMMOLATED_CHAMPION, PosChampion[0], PosChampion[1], PosChampion[2], PosChampion[3], TEMPSUMMON_TIMED_DESPAWN, 60000)) + m_uiChampionGUID = Champion->GetGUID(); + if(Creature* VoiceOfYogg = m_creature->SummonCreature(NPC_VOICE_OF_YOGG_SARON, PosVoiceIcecrown[0], PosVoiceIcecrown[1], PosVoiceIcecrown[2], 0, TEMPSUMMON_TIMED_DESPAWN, 60000)) + { + m_uiVoiceOfYoggGUID = VoiceOfYogg->GetGUID(); + VoiceOfYogg->SetVisibility(VISIBILITY_OFF); + } + for(uint8 i = 0; i < 9; i++) + { + if(Creature *pTemp = m_creature->SummonCreature(MOB_VISION_TENTACLE, IcecrownLoc[i].x, IcecrownLoc[i].y, IcecrownLoc[i].z, IcecrownLoc[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 80000)) + { + pTemp->SetMaxHealth(m_bIsRegularMode ? 15000 : 40000); + pTemp->SetDisplayId(25627); + pTemp->setFaction(7); + pTemp->CastSpell(pTemp, SPELL_GRIM_REPRISAL, false); + } + } + for(uint8 i = 0; i < 4; i++) + m_creature->SummonCreature(NPC_LAUGHING_SKULL, SkullIcecrownLoc[i].x, SkullIcecrownLoc[i].y, SkullIcecrownLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); + ++m_uiVisionPhase; + m_uiSpeechTimer = 1000; + break; + case 1: + if(Creature* Champion = m_pInstance->instance->GetCreature(m_uiChampionGUID)) + { + Champion->SetStandFlags(UNIT_STAND_STATE_KNEEL); + if(Creature* LichKing = m_pInstance->instance->GetCreature(m_uiLichKingGUID)) + { + LichKing->CastSpell(Champion, 54142, false); + DoScriptText(SAY_LICH_KING1, LichKing); + } + } + ++m_uiVisionPhase; + m_uiSpeechTimer = 5000; + break; + case 2: + if(Creature* Champion = m_pInstance->instance->GetCreature(m_uiChampionGUID)) + DoScriptText(SAY_CHAMPION1, Champion); + ++m_uiVisionPhase; + m_uiSpeechTimer = 8000; + break; + case 3: + if(Creature* Champion = m_pInstance->instance->GetCreature(m_uiChampionGUID)) + DoScriptText(SAY_CHAMPION2, Champion); + ++m_uiVisionPhase; + m_uiSpeechTimer = 8000; + break; + case 4: + if(Creature* LichKing = m_pInstance->instance->GetCreature(m_uiLichKingGUID)) + DoScriptText(SAY_LICH_KING2, LichKing); + ++m_uiVisionPhase; + m_uiSpeechTimer = 7000; + break; + case 5: + if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID)) + DoScriptText(SAY_YOGG_V3_1, VoiceOfYogg); + ++m_uiVisionPhase; + m_uiSpeechTimer = 5000; + break; + case 6: + if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID)) + DoScriptText(SAY_YOGG_V3_2, VoiceOfYogg); + ++m_uiVisionPhase; + m_uiSpeechTimer = 10000; + break; + default: + m_uiSpeechTimer = 100000; + } + }else m_uiSpeechTimer -= uiDiff; + + break; + } + } + + // End phase after 30% + if(m_creature->GetHealthPercent() < 30 && !m_bIsPhaseFinished) + { + if(m_pInstance) + { + m_pInstance->SetData(TYPE_YOGG_BRAIN, DONE); + m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_OLD_GOD); + } + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (Creature* pYogg = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGGSARON))) + { + ((boss_yogg_saronAI*)pYogg->AI())->StartThirdPhase(); + pYogg->RemoveAurasDueToSpell(SPELL_SHATTERED_ILLUSION); + } + m_creature->CastStop(); + m_bIsPhaseFinished = true; + } + + // check if tentacles are dead + if (m_uiTentacleCheckTimer < uiDiff && !m_bIsVisionFinished) + { + if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID)) + { + if(!IsThereAnyAdd(VoiceOfYogg)) + { + SummonPortals(); + m_pInstance->SetData(TYPE_VISION_PHASE, PHASE_VISION_RETURN); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_uiTentacleCheckTimer = 300000; + } + else + m_uiTentacleCheckTimer = 500; + } + } + else m_uiTentacleCheckTimer -= uiDiff; + + // make boss unattackable -> exploit check + // Induced madness need core support, it should make the players insane + if (m_uiMadnessTimer < uiDiff) + { + if (Creature* pYogg = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGGSARON))) + { + ((boss_yogg_saronAI*)pYogg->AI())->m_bIsShatter = false; + ((boss_yogg_saronAI*)pYogg->AI())->m_uiSummonTimer = urand(5000, 8000); + pYogg->RemoveAurasDueToSpell(SPELL_SHATTERED_ILLUSION); + } + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_bIsVisionFinished = true; + m_uiMadnessTimer = 300000; + } + else m_uiMadnessTimer -= uiDiff; + } +}; + +// Sara script +struct MANGOS_DLL_DECL boss_saraAI : public ScriptedAI +{ + boss_saraAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_bIsIntroDone = false; + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + // intro + bool m_bIsIntro; + uint32 m_uiIntro_Phase; + uint32 m_uiSpeech_Timer; + bool m_bIsIntroDone; + bool m_bIsFactionSet; + + // phase 1 + uint32 m_uiPhaseYellTimer; + uint32 m_uiSummonTimer; + uint32 m_uiSarasFervorTimer; + uint32 m_uiSarasBlessingTimer; + uint32 m_uiSarasAngerTimer; + uint32 m_uiAllVisions; + + // transition + bool m_bIsOutro; + uint32 m_uiOutroTimer; + uint32 m_uiOutroStep; + + // phase 2 + uint32 m_uiPsychosisTimer; + uint32 m_uiPortalsTimer; + uint32 m_uiMaladyTimer; + uint32 m_uiBrainLinkTimer; + uint32 m_uiDeathRayTimer; + uint32 m_uiBrainLinkEndTimer; + uint32 m_uiBrainLinkTickTimer; + bool m_bIsBrainLink; + + uint32 m_uiFirstVision; + uint32 m_uiSecondVision; + + uint64 m_uiLinkTarget1GUID; + uint64 m_uiLinkTarget2GUID; + + void Reset() + { + // intro + m_bIsIntro = false; + m_uiIntro_Phase = 0; + m_uiSpeech_Timer = 1000; + m_bIsFactionSet = false; + + // phase 1 + m_uiPhaseYellTimer = 30000; + m_uiSummonTimer = 10000 + urand (1000, 5000); + m_uiSarasFervorTimer = urand(10000, 15000); + m_uiSarasBlessingTimer = urand(15000, 20000); + m_uiSarasAngerTimer = urand(20000, 25000); + m_uiAllVisions = 0; + + // transition + m_bIsOutro = false; + m_uiOutroTimer = 10000; + m_uiOutroStep = 1; + + // phase 2 + m_uiPortalsTimer = 60000; + m_uiPsychosisTimer = 15000; + m_uiMaladyTimer = 20000; + m_uiBrainLinkTimer = 25000; + m_uiDeathRayTimer = 30000; + m_uiBrainLinkTickTimer = 1000; + m_uiBrainLinkEndTimer = 0; + m_bIsBrainLink = false; + + m_uiFirstVision = 0; + m_uiSecondVision = 0; + + m_uiLinkTarget1GUID = 0; + m_uiLinkTarget2GUID = 0; + + if(m_creature->HasAura(SPELL_SHADOWY_BARRIER)) + m_creature->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER); + + m_creature->SetDisplayId(MODEL_SARA_HUMAN); + m_creature->setFaction(35); + m_creature->SetMaxHealth(199999); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->SetSplineFlags(SPLINEFLAG_FLYING); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, 5.9f); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + } + + void KilledUnit(Unit* pVictim) + { + if(irand(0,1)) + DoScriptText(SAY_KILL1, m_creature); + else + DoScriptText(SAY_KILL2, m_creature); + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(uiDamage > m_creature->GetHealth()) + { + m_bIsOutro = true; + m_creature->SetHealth(m_creature->GetMaxHealth()); + uiDamage = 0; + } + } + + void MoveInLineOfSight(Unit* pWho) + { + // start intro speech + if(m_pInstance->GetData(TYPE_YOGG_PHASE) == PHASE_IDLE) + { + if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && !m_bIsIntro && !m_bIsIntroDone && + pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 110) && m_creature->IsWithinLOSInMap(pWho)) + m_bIsIntro = true; + } + } + + // return a random npc from the selected entry + Creature* SelectRandomNpc(float fRange, uint32 uiEntry) + { + std::list lNpcList; + GetCreatureListWithEntryInGrid(lNpcList, m_creature, uiEntry, fRange); + + //This should not appear! + if (lNpcList.empty()){ + return NULL; + } + + std::list::iterator iter = lNpcList.begin(); + advance(iter, urand(0, lNpcList.size()-1)); + + return *iter; + } + + void DoBrainLink() + { + // workaround here + } + + void SummonPortals() + { + uint8 maxPortals = m_bIsRegularMode ? 4 : 10; + for(uint8 i = 0; i < maxPortals; i++) + m_creature->SummonCreature(MOB_DESCEND_INTO_MADNESS, YoggPortalLoc[i].x, YoggPortalLoc[i].y, YoggPortalLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); + } + + // set a random vision + uint32 GetCurrentVision() + { + switch(urand(0, 2)) + { + case 0: + return PHASE_VISION_STORMWIND; + break; + case 1: + return PHASE_VISION_WYRMREST; + break; + case 2: + return PHASE_VISION_ICECROWN; + break; + } + + return 0; + } + + // start a vision + void SetVisionPhase() + { + uint32 m_uiVisionType = 0; + + // set random different destination + if(m_uiFirstVision == 0 && m_uiSecondVision == 0) + { + m_uiVisionType = GetCurrentVision(); + m_uiFirstVision = m_uiVisionType; + } + else if(m_uiSecondVision == 0) + { + do m_uiVisionType = GetCurrentVision(); + while(m_uiVisionType == m_uiFirstVision); + m_uiSecondVision = m_uiVisionType; + } + else + { + do m_uiVisionType = GetCurrentVision(); + while(m_uiVisionType == m_uiFirstVision || m_uiVisionType == m_uiSecondVision); + } + + // set instance data for vision + if(m_uiVisionType != 0) + m_pInstance->SetData(TYPE_VISION_PHASE, m_uiVisionType); + + // summon portals + SummonPortals(); + // start the vision + if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN))) + { + if(pYoggBrain->isAlive()) + ((boss_brain_of_yogg_saronAI*)pYoggBrain->AI())->StartVisions(); + } + // increase the vision no. + m_uiAllVisions += 1; + } + + void UpdateAI(const uint32 uiDiff) + { + switch(m_pInstance->GetData(TYPE_YOGG_PHASE)) + { + case PHASE_IDLE: + { + // intro + if (m_bIsIntro && !m_bIsIntroDone) + { + if(m_uiSpeech_Timer < uiDiff) + { + switch(m_uiIntro_Phase) + { + case 0: + DoScriptText(SAY_INTRO1, m_creature); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->GetMotionMaster()->MoveIdle(); + SetCombatMovement(false); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, 5.9f); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + ++m_uiIntro_Phase; + m_uiSpeech_Timer = 8000; + break; + case 1: + DoScriptText(SAY_INTRO2, m_creature); + ++m_uiIntro_Phase; + m_uiSpeech_Timer = 8000; + break; + case 2: + m_bIsIntro = false; + m_bIsIntroDone = true; + m_uiSpeech_Timer = 12000; + break; + default: + m_uiSpeech_Timer = 100000; + } + } + else m_uiSpeech_Timer -= uiDiff; + } + break; + } + case PHASE_SARA: + { + if(!m_bIsOutro) + { + // wipe check + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + { + if(!pYogg->getVictim() || !pYogg->SelectHostileTarget() || pYogg->getVictim() == m_creature) + { + pYogg->AI()->EnterEvadeMode(); + DoScriptText(SAY_WIPE, m_creature); + } + } + + if (m_uiPhaseYellTimer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_HELP1, m_creature); break; + case 1: DoScriptText(SAY_HELP2, m_creature); break; + } + m_uiPhaseYellTimer = 30000; + }else m_uiPhaseYellTimer -= uiDiff; + + if (m_uiSummonTimer < uiDiff) + { + if (Creature* pCloud = SelectRandomNpc(120.0f, NPC_OMINOUS_CLOUD)) + pCloud->CastSpell(pCloud, SPELL_SUMMON_GUARDIAN2, false); + m_uiSummonTimer = urand(15000, 20000); + }else m_uiSummonTimer -= uiDiff; + + if (m_uiSarasFervorTimer < uiDiff) + { + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + { + if (Unit* pTarget = pYogg->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if(pTarget != m_creature) + { + DoCast(pTarget, SPELL_SARAS_FERVOR); + m_uiSarasFervorTimer = urand(20000, 30000); + } + } + } + }else m_uiSarasFervorTimer -= uiDiff; + + if (m_uiSarasBlessingTimer < uiDiff) + { + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + { + if (Unit* pTarget = pYogg->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if(pTarget != m_creature) + { + DoCast(pTarget, SPELL_SARAS_BLESSING); + m_uiSarasBlessingTimer = urand(20000, 30000); + } + } + } + }else m_uiSarasBlessingTimer -= uiDiff; + + if (m_uiSarasAngerTimer < uiDiff) + { + if (Creature* pGuardian = SelectRandomNpc(80.0f, MOB_GUARDIAN_OF_YOGG)) + DoCast(pGuardian, SPELL_SARAS_ANGER); + m_uiSarasAngerTimer = urand(20000, 30000); + }else m_uiSarasAngerTimer -= uiDiff; + } + // Phase 1 outro + if(m_bIsOutro) + { + switch(m_uiOutroStep) + { + case 1: + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->CombatStop(true); + m_creature->InterruptNonMeleeSpells(false); + ++m_uiOutroStep; + m_uiOutroTimer = 5000; + break; + case 3: + DoScriptText(SAY_PHASE2, m_creature); + ++m_uiOutroStep; + m_uiOutroTimer = 15000; + break; + case 5: + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + { + if (Unit* pTarget = pYogg->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + m_creature->AddThreat(pTarget, 100.0f); + m_creature->AI()->AttackStart(pTarget); + } + } + m_creature->setFaction(14); + m_creature->SetInCombatWithZone(); + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->SetDisplayId(MODEL_SARA_VALKYR); + DoCast(m_creature, SPELL_SHADOWY_BARRIER); + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 10, 5.9f); + m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 10, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1); + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + ((boss_yogg_saronAI*)pYogg->AI())->StartSecondPhase(); + m_uiPhaseYellTimer = 30000 + urand(5000, 10000); + m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_TENTACLES); + ++m_uiOutroStep; + m_uiOutroTimer = 3000; + break; + } + } + else return; + + if (m_uiOutroTimer <= uiDiff) + { + ++m_uiOutroStep; + m_uiOutroTimer = 330000; + } + m_uiOutroTimer -= uiDiff; + + break; + } + case PHASE_TENTACLES: + { + // wipe check + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + { + if(!pYogg->getVictim() || !pYogg->SelectHostileTarget()) + pYogg->AI()->EnterEvadeMode(); + } + + if (m_uiPhaseYellTimer < uiDiff) + { + switch(urand(0, 1)) + { + case 0: DoScriptText(SAY_SPECIAL1, m_creature); break; + case 1: DoScriptText(SAY_SPECIAL2, m_creature); break; + } + m_uiPhaseYellTimer = 30000 + urand(5000, 10000); + } + else m_uiPhaseYellTimer -= uiDiff; + + // summon madness portals + if (m_uiPortalsTimer < uiDiff && m_uiAllVisions < 3) + { + SetVisionPhase(); + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + DoScriptText(SAY_VISION, pYogg); + m_uiPortalsTimer = 85000; + } + else m_uiPortalsTimer -= uiDiff; + + if (m_uiPsychosisTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_PHYCHOSIS : SPELL_PHYCHOSIS_H); + m_uiPsychosisTimer = urand(15000, 20000); + } + else m_uiPsychosisTimer -= uiDiff; + + if (m_uiMaladyTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_MALADY_OF_THE_MIND); + m_uiMaladyTimer = urand(20000, 25000); + } + else m_uiMaladyTimer -= uiDiff; + + if (m_uiBrainLinkTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_uiLinkTarget1GUID = pTarget->GetGUID(); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_uiLinkTarget2GUID = pTarget->GetGUID(); + DoCast(m_creature, SPELL_BRAIN_LINK); + m_bIsBrainLink = true; + m_uiBrainLinkEndTimer = 30000; + m_uiBrainLinkTickTimer = 1000; + m_uiBrainLinkTimer = urand(25000, 30000); + } + else m_uiBrainLinkTimer -= uiDiff; + + // workaround for brainlink + // spell need core support + // REMOVE FOR REVISION! + if (m_uiBrainLinkTickTimer < uiDiff && m_bIsBrainLink) + { + DoBrainLink(); + m_uiBrainLinkTickTimer = 1000; + } + else m_uiBrainLinkTickTimer -= uiDiff; + + if (m_uiBrainLinkEndTimer < uiDiff && m_bIsBrainLink) + m_bIsBrainLink = false; + else m_uiBrainLinkEndTimer -= uiDiff; + + // workaround, should be done by spell + if (m_uiDeathRayTimer < uiDiff) + { + if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON))) + { + for(int i = 0; i < irand(3, 4); i++) + { + float angle = (float) rand()*360/RAND_MAX + 1; + float homeX = pYogg->GetPositionX() + urand(20, 40)*cos(angle*(M_PI/180)); + float homeY = pYogg->GetPositionY() + urand(20, 40)*sin(angle*(M_PI/180)); + m_creature->SummonCreature(MOB_DEATH_ORB, homeX, homeY, pYogg->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); + } + } + //DoCast(m_creature, SPELL_DEATH_RAY); + m_uiDeathRayTimer = 30000; + } + else m_uiDeathRayTimer -= uiDiff; + + break; + } + } + } +}; + +/* +* Keepers +*/ +struct MANGOS_DLL_DECL keeper_hodirAI : public ScriptedAI +{ + keeper_hodirAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiHodirProtectivGazeTimer; + + void Reset() + { + m_uiHodirProtectivGazeTimer = 30000; + m_creature->SetRespawnDelay(DAY); + DoCast(m_creature, SPELL_FORTITUDE_OF_FROST); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_uiHodirProtectivGazeTimer < uiDiff) + { + if(Unit* pTemp = DoSelectLowestHpFriendly(100.0f)) + DoCast(pTemp, SPELL_HODIRS_PROTECTIVE_GAZE); + m_uiHodirProtectivGazeTimer = 30000 + urand(10000,30000); + } + else m_uiHodirProtectivGazeTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL keeper_freyaAI : public ScriptedAI +{ + keeper_freyaAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + void Reset() + { + DoCast(m_creature, SPELL_RESILIENCE_OF_NATURE); + m_creature->SetRespawnDelay(DAY); + // Summon Wells + SummonSanityWells(); + } + + void SummonSanityWells() + { + for(uint8 i = 0; i < 5; i++) + m_creature->SummonCreature(MOB_SANITY_WELL, SanityWellLoc[i].x, SanityWellLoc[i].y, SanityWellLoc[i].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 30000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + } +}; + +struct MANGOS_DLL_DECL keeper_thorimAI : public ScriptedAI +{ + keeper_thorimAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + bool m_bHasTitanicStorm; + + void Reset() + { + m_bHasTitanicStorm = false; + m_creature->SetRespawnDelay(DAY); + DoCast(m_creature, SPELL_FURY_OF_THE_STORM); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_pInstance->GetData(TYPE_YOGG_PHASE) == PHASE_OLD_GOD && !m_bHasTitanicStorm) + { + DoCast(m_creature, SPELL_TITANIC_STORM); + m_bHasTitanicStorm = true; + } + } +}; + +struct MANGOS_DLL_DECL keeper_mimironAI : public ScriptedAI +{ + keeper_mimironAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiDestabilizationMatrixTimer; + std::list lTentacleList; + + void Reset() + { + lTentacleList.clear(); + m_uiDestabilizationMatrixTimer = 10000; + m_creature->SetRespawnDelay(DAY); + DoCast(m_creature, SPELL_SPEED_OF_INVENTION); + } + + Creature* SelectRandomTentacle(float fRange) + { + GetCreatureListWithEntryInGrid(lTentacleList, m_creature, MOB_CRUSHER_TENTACLE, fRange); + GetCreatureListWithEntryInGrid(lTentacleList, m_creature, MOB_CORRUPTOR_TENTACLE, fRange); + + if (lTentacleList.empty()){ + m_uiDestabilizationMatrixTimer = 30000; + return NULL; + } + + std::list::iterator iter = lTentacleList.begin(); + advance(iter, urand(0, lTentacleList.size()-1)); + + return *iter; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_pInstance->GetData(TYPE_YOGG_PHASE) == PHASE_TENTACLES) + { + if (m_uiDestabilizationMatrixTimer < uiDiff) + { + if(Unit* pTentacle = SelectRandomTentacle(120.0f)) + DoCast(pTentacle, SPELL_DESTABILIZATION_MATRIX); + m_uiDestabilizationMatrixTimer = 30000 + urand(10000,30000); + } + else m_uiDestabilizationMatrixTimer -= uiDiff; + } + } +}; + +/* +* Guardians +*/ +struct MANGOS_DLL_DECL mob_immortal_guardianAI : public ScriptedAI +{ + mob_immortal_guardianAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiStack; + uint32 m_uiHealth; + bool m_bHasAura; + + void Reset() + { + m_uiStack = 0; + m_uiHealth = 90; + m_bHasAura = false; + m_creature->SetRespawnDelay(DAY); + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(m_creature->GetHealthPercent() < 5) + { + if(uiDamage > m_creature->GetHealth()) + uiDamage = 0; + } + } + + void SpellHit(Unit *caster, const SpellEntry *spell) + { + if(m_creature->GetHealthPercent() < 5) + { + if(spell->Id == SPELL_TITANIC_STORM_DMG && caster->GetEntry() == KEEPER_THORIM) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + void Aggro(Unit *who) + { + DoCast(m_creature, SPELL_EMPOWERED); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + // hacky way of stacking aura, needs fixing + if(SpellAuraHolder* empoweredAura = m_creature->GetSpellAuraHolder(SPELL_EMPOWERED)) + { + if(empoweredAura->GetStackAmount() < 9 && !m_bHasAura) + { + m_bHasAura = true; + empoweredAura->SetStackAmount(9); + } + } + + if(m_creature->GetHealthPercent() > 10) + { + if(m_creature->GetHealthPercent() < m_uiHealth) + { + if(SpellAuraHolder* empoweredAura = m_creature->GetSpellAuraHolder(SPELL_EMPOWERED)) + { + if(empoweredAura->ModStackAmount(-1)) + m_creature->RemoveAurasDueToSpell(SPELL_EMPOWERED); + } + m_uiHealth -= 10; + } + } + + // empowering shadows, needs more research and core fix + if(m_creature->GetHealthPercent() > m_uiHealth + 10) + { + DoCast(m_creature, SPELL_EMPOWERED); + m_uiHealth += 10; + } + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_guardian_of_yogg_saronAI : public ScriptedAI +{ + mob_guardian_of_yogg_saronAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiDarkVolleyTimer; + uint32 m_uiDieTimer; + uint32 m_uiDominateMindTimer; + bool m_bHasCasted; + + void Reset() + { + m_uiDarkVolleyTimer = 10000; + m_uiDominateMindTimer = 30000; + m_bHasCasted = false; + m_creature->SetRespawnDelay(DAY); + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(uiDamage > m_creature->GetHealth()) + { + uiDamage = 0; + if(!m_bHasCasted) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHADOW_NOVA : SPELL_SHADOW_NOVA_H); + m_bHasCasted = true; + m_uiDieTimer = 500; + m_creature->SetHealth(m_creature->GetMaxHealth()); + + // workaround for dmg Sara + // need to find a way to damage Sara by spell! + if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA))) + { + if(m_creature->IsWithinDist2d(pSara->GetPositionX(), pSara->GetPositionY(), 15.0f)) + { + uint32 maxHealth = m_bIsRegularMode ? 21994 : 27500; + if(pSara->GetHealth() > maxHealth) + pSara->DealDamage(pSara, m_bIsRegularMode ? urand(20000, 21994) : urand(25000, 27500), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false); + else + { + ((boss_saraAI*)pSara->AI())->m_bIsOutro = true; + pSara->SetHealth(pSara->GetMaxHealth()); + } + } + } + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA))) + { + if(m_creature->getVictim() == pSara) + { + m_creature->AddThreat(pSara, -100000.0f); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO, 0)) + m_creature->AddThreat(pTarget, 1000000.0f); + } + } + + if (m_uiDarkVolleyTimer < uiDiff) + { + DoCast(m_creature, SPELL_DARK_VOLLEY); + m_uiDarkVolleyTimer = 15000; + } + else m_uiDarkVolleyTimer -= uiDiff; + + if (m_uiDominateMindTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_DOMINATE_MIND); + m_uiDominateMindTimer = 30000; + } + else m_uiDominateMindTimer -= uiDiff; + + if (m_uiDieTimer < uiDiff && m_bHasCasted) + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + else m_uiDieTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +/* +* Tentacules +*/ +struct MANGOS_DLL_DECL mob_corruptor_tentacleAI : public ScriptedAI +{ + mob_corruptor_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiEruptTimer; + bool m_bHasErupted; + uint32 m_uiSpellTimer; + + void Reset() + { + m_uiEruptTimer = 500; + m_bHasErupted = false; + m_uiSpellTimer = 10000; + m_creature->SetRespawnDelay(DAY); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEruptTimer < uiDiff && !m_bHasErupted) + { + DoCast(m_creature, SPELL_ERUPT); + m_bHasErupted = true; + }else m_uiEruptTimer -= uiDiff; + + if (m_uiSpellTimer < uiDiff) + { + switch(urand(0, 3)) + { + case 0: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_BLACK_PLAGUE); + break; + case 1: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_APATHY); + break; + case 2: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_CURSE_OF_DOOM); + break; + case 3: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_DRAINING_POISON); + break; + } + m_uiSpellTimer = urand(5000, 10000); + } + else m_uiSpellTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_constrictor_tentacleAI : public ScriptedAI +{ + mob_constrictor_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance *m_pInstance; + + uint32 m_uiSqueezeTimer; + uint64 m_uiVictimGUID; + + void Reset() + { + m_uiSqueezeTimer = 10000; + m_creature->SetRespawnDelay(DAY); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (uiDamage > m_creature->GetHealth()) + { + if (m_uiVictimGUID) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID)) + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H); + } + } + } + + void JustDied(Unit* pKiller) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID)) + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H); + + if (pKiller) + pKiller->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H); + } + + void KilledUnit(Unit* pVictim) + { + if (pVictim) + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + { + if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID)) + pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H); + m_creature->ForcedDespawn(); + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiSqueezeTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + // spell needs vehicles + //pTarget->CastSpell(pTarget, m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H, false); + m_uiVictimGUID = pTarget->GetGUID(); + } + m_uiSqueezeTimer = 30000; + }else m_uiSqueezeTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_crusher_tentacleAI : public ScriptedAI +{ + mob_crusher_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance *m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiEruptTimer; + bool m_bHasErupted; + uint32 m_uiDiminishPowerTimer; + + void Reset() + { + m_uiEruptTimer = 500; + m_bHasErupted = false; + m_uiDiminishPowerTimer = 10000; + m_creature->SetRespawnDelay(DAY); + DoCast(m_creature, SPELL_FOCUSED_ANGER_TRIGG); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEruptTimer < uiDiff && !m_bHasErupted) + { + DoCast(m_creature, SPELL_ERUPT); + m_bHasErupted = true; + } + else m_uiEruptTimer -= uiDiff; + + if (m_uiDiminishPowerTimer < uiDiff) + { + DoCast(m_creature, SPELL_DIMINISH_POWER); + m_uiDiminishPowerTimer = 10000 + urand(1000, 5000); + } + else m_uiDiminishPowerTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +struct MANGOS_DLL_DECL mob_vision_tentacleAI : public ScriptedAI +{ + mob_vision_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature) + { + SetCombatMovement(false); + Reset(); + } + + void Reset() + { + DoCast(m_creature, SPELL_GRIM_REPRISAL); + } + + void DamageTaken(Unit *done_by, uint32 &uiDamage) + { + if(uiDamage > 0 && m_creature->GetDisplayId() != 28813) + m_creature->SetDisplayId(28813); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; + +/* +* Other +*/ +struct MANGOS_DLL_DECL mob_death_orbAI : public ScriptedAI +{ + mob_death_orbAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + pCreature->setFaction(14); + Reset(); + } + + uint32 m_uiAuraTimer; + bool m_bHasAura; + + void Reset() + { + m_uiAuraTimer = 500; + m_bHasAura = false; + DoCast(m_creature, SPELL_DEATH_RAY_VISUAL); + m_creature->GetMotionMaster()->MoveConfused(); + } + + void UpdateAI(const uint32 uiDiff) + { + if(m_uiAuraTimer < uiDiff && !m_bHasAura) + { + DoCast(m_creature, SPELL_DEATH_RAY_TRIGG); + m_bHasAura = true; + } + else m_uiAuraTimer -= uiDiff; + } +}; + +struct MANGOS_DLL_DECL mob_sanity_wellAI : public ScriptedAI +{ + mob_sanity_wellAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->SetDisplayId(11686); // make invisible + pCreature->setFaction(14); + SetCombatMovement(false); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiAuraDelayTimer; + bool m_bHasAura; + + void Reset() + { + m_uiAuraDelayTimer = 1000; + m_bHasAura = false; + DoCast(m_creature, SPELL_SANITY_WELL_VISUAL); + m_creature->SetRespawnDelay(DAY); + } + + void AttackStart(Unit* pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS) + m_creature->ForcedDespawn(); + + if (m_uiAuraDelayTimer < uiDiff && !m_bHasAura) + { + // spell partially broken, it should be triggered by the visual aura + //DoCast(m_creature, SPELL_SANITY_WELL); + m_bHasAura = true; + } + else m_uiAuraDelayTimer -= uiDiff; + } }; +struct MANGOS_DLL_DECL mob_laughing_skullAI : public ScriptedAI +{ + mob_laughing_skullAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pCreature->SetDisplayId(SKULL_DISPLAY_ID); + pCreature->setFaction(14); + SetCombatMovement(false); + pCreature->GetMotionMaster()->MoveConfused(); + Reset(); + } + + void Reset() + { + m_creature->SetRespawnDelay(DAY); + DoCast(m_creature, SPELL_LUNATIC_GAZE); + } + + void AttackStart(Unit* pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + } +}; + +struct MANGOS_DLL_DECL mob_ominous_cloudAI : public ScriptedAI +{ + mob_ominous_cloudAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + SetCombatMovement(false); + pCreature->setFaction(14); + Reset(); + } + + ScriptedInstance *m_pInstance; + + uint32 m_uiRangeCheckTimer; + bool m_bSummonGuardian; + + void Reset() + { + m_uiRangeCheckTimer = 1000; + m_bSummonGuardian = false; + DoCast(m_creature, SPELL_OMINOUS_CLOUD_VISUAL); + m_creature->SetRespawnDelay(DAY); + } + + void AttackStart(Unit* pWho) + { + return; + } + + void JustSummoned(Creature* pSummon) + { + pSummon->SetInCombatWithZone(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiRangeCheckTimer < uiDiff) + { + Map *map = m_creature->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) <= 5) + m_bSummonGuardian = true; + + } + } + // cast summon guard + if(m_bSummonGuardian) + { + DoCast(m_creature, SPELL_SUMMON_GUARDIAN2); + m_uiRangeCheckTimer = 11000; + m_bSummonGuardian = false; + } + else + m_uiRangeCheckTimer = 1000; + } + else m_uiRangeCheckTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_boss_yogg_saron(Creature* pCreature) +{ + return new boss_yogg_saronAI(pCreature); +} + +CreatureAI* GetAI_boss_sara(Creature* pCreature) +{ + return new boss_saraAI(pCreature); +} + +CreatureAI* GetAI_mob_madness_portal(Creature* pCreature) +{ + return new mob_madness_portalAI(pCreature); +} + +CreatureAI* GetAI_boss_brain_of_yogg_saron(Creature* pCreature) +{ + return new boss_brain_of_yogg_saronAI(pCreature); +} + +CreatureAI* GetAI_mob_corruptor_tentacle(Creature* pCreature) +{ + return new mob_corruptor_tentacleAI(pCreature); +} + +CreatureAI* GetAI_mob_constrictor_tentacle(Creature* pCreature) +{ + return new mob_constrictor_tentacleAI(pCreature); +} + +CreatureAI* GetAI_mob_crusher_tentacle(Creature* pCreature) +{ + return new mob_crusher_tentacleAI(pCreature); +} + +CreatureAI* GetAI_mob_vision_tentacle(Creature* pCreature) +{ + return new mob_vision_tentacleAI(pCreature); +} + +CreatureAI* GetAI_mob_guardian_of_yogg_saron(Creature* pCreature) +{ + return new mob_guardian_of_yogg_saronAI(pCreature); +} + +CreatureAI* GetAI_mob_immortal_guardian(Creature* pCreature) +{ + return new mob_immortal_guardianAI(pCreature); +} + +CreatureAI* GetAI_keeper_hodir(Creature* pCreature) +{ + return new keeper_hodirAI(pCreature); +} + +CreatureAI* GetAI_keeper_freya(Creature* pCreature) +{ + return new keeper_freyaAI(pCreature); +} + +CreatureAI* GetAI_keeper_thorim(Creature* pCreature) +{ + return new keeper_thorimAI(pCreature); +} + +CreatureAI* GetAI_keeper_mimiron(Creature* pCreature) +{ + return new keeper_mimironAI(pCreature); +} + +CreatureAI* GetAI_mob_death_orb(Creature* pCreature) +{ + return new mob_death_orbAI(pCreature); +} + +CreatureAI* GetAI_mob_sanity_well(Creature* pCreature) +{ + return new mob_sanity_wellAI(pCreature); +} + +CreatureAI* GetAI_mob_laughing_skull(Creature* pCreature) +{ + return new mob_laughing_skullAI(pCreature); +} + +CreatureAI* GetAI_mob_ominous_cloud(Creature* pCreature) +{ + return new mob_ominous_cloudAI(pCreature); +} + void AddSC_boss_yogg_saron() { + Script *newscript; + newscript = new Script; + newscript->Name = "boss_yogg_saron"; + newscript->GetAI = &GetAI_boss_yogg_saron; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_sara"; + newscript->GetAI = &GetAI_boss_sara; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_madness_portal"; + newscript->GetAI = &GetAI_mob_madness_portal; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_brain_of_yogg_saron"; + newscript->GetAI = &GetAI_boss_brain_of_yogg_saron; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_corruptor_tentacle"; + newscript->GetAI = &GetAI_mob_corruptor_tentacle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_constrictor_tentacle"; + newscript->GetAI = &GetAI_mob_constrictor_tentacle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_crusher_tentacle"; + newscript->GetAI = &GetAI_mob_crusher_tentacle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_vision_tentacle"; + newscript->GetAI = &GetAI_mob_vision_tentacle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_guardian_of_yogg_saron"; + newscript->GetAI = &GetAI_mob_guardian_of_yogg_saron; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_immortal_guardian"; + newscript->GetAI = &GetAI_mob_immortal_guardian; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "keeper_hodir"; + newscript->GetAI = &GetAI_keeper_hodir; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "keeper_freya"; + newscript->GetAI = &GetAI_keeper_freya; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "keeper_thorim"; + newscript->GetAI = &GetAI_keeper_thorim; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "keeper_mimiron"; + newscript->GetAI = &GetAI_keeper_mimiron; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_death_orb"; + newscript->GetAI = &GetAI_mob_death_orb; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_sanity_well"; + newscript->GetAI = &GetAI_mob_sanity_well; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_laughing_skull"; + newscript->GetAI = &GetAI_mob_laughing_skull; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "mob_ominous_cloud"; + newscript->GetAI = &GetAI_mob_ominous_cloud; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp b/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp index 44fb693aa..7521de91f 100644 --- a/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp +++ b/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,7 +15,7 @@ */ /* ScriptData -SDName: instance_ulduar +SDName: Instance_Ulduar SD%Complete: SDComment: SDCategory: Ulduar @@ -24,131 +24,245 @@ EndScriptData */ #include "precompiled.h" #include "ulduar.h" -struct sSpawnLocation +struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance { - float m_fX, m_fY, m_fZ, m_fO; -}; + instance_ulduar(Map* pMap) : ScriptedInstance(pMap) + { + Regular = pMap->IsRegularDifficulty(); + Initialize(); + } -static sSpawnLocation m_aKeepersSpawnLocs[] = -{ - {2036.892f, 25.621f, 411.358f, 3.83f}, // Freya - {1939.215f, 42.677f, 411.355f, 5.31f}, // Mimiron - {1939.195f, -90.662f, 411.357f, 1.06f}, // Hodir - {2036.674f, -73.814f, 411.355f, 2.51f}, // Thorim -}; + bool Regular; + + // initialize the encouter variables + std::string m_strInstData; + uint32 m_auiEncounter[MAX_ENCOUNTER]; + uint32 m_auiHardBoss[HARD_ENCOUNTER]; + uint32 m_auiUlduarKeepers[KEEPER_ENCOUNTER]; + uint32 m_auiUlduarTeleporters[3]; + uint32 m_auiMiniBoss[6]; + + // boss phases which need to be used inside the instance script + uint32 m_uiMimironPhase; + uint32 m_uiYoggPhase; + uint32 m_uiVisionPhase; -instance_ulduar::instance_ulduar(Map* pMap) : ScriptedInstance(pMap), - // Creatures - m_uiLeviathanGUID(0), - m_uiIgnisGUID(0), - m_uiRazorscaleGUID(0), - m_uiCommanderGUID(0), - m_uiXT002GUID(0), - m_uiBrundirGUID(0), - m_uiMolgeimGUID(0), - m_uiSteelbreakerGUID(0), - m_uiKologarnGUID(0), - m_uiAuriayaGUID(0), - m_uiMimironGUID(0), - m_uiHodirGUID(0), - m_uiThorimGUID(0), - m_uiFreyaGUID(0), - m_uiVezaxGUID(0), - m_uiYoggSaronGUID(0), - m_uiAlgalonGUID(0), - m_uiRightArmGUID(0), - m_uiLeftArmGUID(0), - m_uiFeralDefenderGUID(0), - m_uiElderBrightleafGUID(0), - m_uiElderStonebarkGUID(0), - m_uiElderIronbrachGUID(0), - m_uiSaroniteAnimusGUID(0), - m_uiRunicColossusGUID(0), - m_uiRuneGiantGUID(0), - m_uiJormungarGUID(0), - m_uiLeviathanMkGUID(0), - m_uiSaraGUID(0), - m_uiYoggBrainGUID(0), - - // Chests - m_uiKologarnLootGUID(0), - m_uiHodirLootGUID(0), - m_uiHodirRareLootGUID(0), - m_uiThorimLootGUID(0), - m_uiThorimRareLootGUID(0), - m_uiMimironLootGUID(0), - m_uiMimironHardLootGUID(0), - m_uiAlagonLootGUID(0), - - // Doors + // creature guids + uint64 m_uiLeviathanGUID; + uint64 m_uiIgnisGUID; + uint64 m_uiRazorscaleGUID; + uint64 m_uiCommanderGUID; + uint64 m_uiXT002GUID; + uint64 m_auiAssemblyGUIDs[3]; + uint64 m_uiKologarnGUID; + uint64 m_uiAuriayaGUID; + uint64 m_uiMimironGUID; + uint64 m_uiHodirGUID; + uint64 m_uiThorimGUID; + uint64 m_uiFreyaGUID; + uint64 m_uiVezaxGUID; + uint64 m_uiYoggSaronGUID; + uint64 m_uiAlgalonGUID; + uint64 m_uiRightArmGUID; + uint64 m_uiLeftArmGUID; + uint64 m_uiFeralDefenderGUID; + uint64 m_uiElderBrightleafGUID; + uint64 m_uiElderStonebarkGUID; + uint64 m_uiElderIronbrachGUID; + uint64 m_uiSaroniteAnimusGUID; + uint64 m_uiRunicColossusGUID; + uint64 m_uiRuneGiantGUID; + uint64 m_uiJormungarGUID; + uint64 m_uiLeviathanMkGUID; + uint64 m_uiHodirImageGUID; + uint64 m_uiFreyaImageGUID; + uint64 m_uiThorimImageGUID; + uint64 m_uiMimironImageGUID; + uint64 m_uiSaraGUID; + uint64 m_uiYoggBrainGUID; + + //doors & objects // The siege - m_uiShieldWallGUID(0), - m_uiLeviathanGateGUID(0), - m_uiXT002GateGUID(0), - m_uiBrokenHarpoonGUID(0), + uint64 m_uiShieldWallGUID; + uint64 m_uiLeviathanGateGUID; + uint64 m_uiXT002GateGUID; + uint64 m_uiBrokenHarpoonGUID; // Archivum - m_uiIronCouncilDoorGUID(0), - m_uiArchivumDoorGUID(0), - m_uiArchivumConsoleGUID(0), - m_uiUniverseFloorArchivumGUID(0), + uint64 m_uiIronCouncilDoorGUID; + uint64 m_uiArchivumDoorGUID; + uint64 m_uiArchivumConsoleGUID; + uint64 m_uiUniverseFloorArchivumGUID; // Celestial planetarium - m_uiCelestialDoorGUID(0), - m_uiCelestialConsoleGUID(0), - m_uiUniverseFloorCelestialGUID(0), - m_uiAzerothGlobeGUID(0), + uint64 m_uiCelestialDoorGUID; + uint64 m_uiCelestialConsoleGUID; + uint64 m_uiUniverseFloorCelestialGUID; + uint64 m_uiAzerothGlobeGUID; // Kologarn - m_uiShatteredHallsDoorGUID(0), - m_uiKologarnBridgeGUID(0), + uint64 m_uiShatteredHallsDoorGUID; + uint64 m_uiKologarnBridgeGUID; // Hodir - m_uiHodirEnterDoorGUID(0), - m_uiHodirWallGUID(0), - m_uiHodirExitDoorGUID(0), + uint64 m_uiHodirEnterDoorGUID; + uint64 m_uiHodirWallGUID; + uint64 m_uiHodirExitDoorGUID; // Mimiron - m_uiMimironButtonGUID(0), - m_uiMimironDoor1GUID(0), - m_uiMimironDoor2GUID(0), - m_uiMimironDoor3GUID(0), - m_uiMimironElevatorGUID(0), + uint64 m_uiMimironTramGUID; + uint64 m_uiMimironButtonGUID; + uint64 m_uiMimironDoor1GUID; + uint64 m_uiMimironDoor2GUID; + uint64 m_uiMimironDoor3GUID; + uint64 m_uiMimironElevatorGUID; + uint64 m_uiMimironTelGUID[9]; // Thorim - m_uiArenaEnterDoorGUID(0), - m_uiArenaExitDoorGUID(0), - m_uiHallwayDoorGUID(0), - m_uiThorimEnterDoorGUID(0), - m_uiThorimLeverGUID(0), + uint64 m_uiArenaEnterDoorGUID; + uint64 m_uiArenaExitDoorGUID; + uint64 m_uiHallwayDoorGUID; + uint64 m_uiThorimEnterDoorGUID; + uint64 m_uiThorimLeverGUID; // Prison - m_uiAncientGateGUID(0), - m_uiVezaxGateGUID(0), - m_uiYoggGateGUID(0), - m_uiBrainDoor1GUID(0), - m_uiBrainDoor2GUID(0), - m_uiBrainDoor3GUID(0) -{ - Initialize(); -} + uint64 m_uiAncientGateGUID; + uint64 m_uiVezaxGateGUID; + uint64 m_uiYoggGateGUID; + uint64 m_uiBrainDoor1GUID; + uint64 m_uiBrainDoor2GUID; + uint64 m_uiBrainDoor3GUID; -void instance_ulduar::Initialize() -{ - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - memset(&m_auiHardBoss, 0, sizeof(m_auiHardBoss)); - memset(&m_auiUlduarKeepers, 0, sizeof(m_auiUlduarKeepers)); - memset(&m_auiUlduarTeleporters, 0, sizeof(m_auiUlduarTeleporters)); - memset(&m_auiMimironTelGUID, 0, sizeof(m_auiMimironTelGUID)); -} + // chests + uint64 m_uiKologarnLootGUID; + uint64 m_uiHodirLootGUID; + uint64 m_uiHodirRareLootGUID; + uint64 m_uiThorimLootGUID; + uint64 m_uiThorimRareLootGUID; + uint64 m_uiFreyaLootGUID; + uint64 m_uiFreyaLoot1GUID; + uint64 m_uiFreyaLoot2GUID; + uint64 m_uiFreyaLoot3GUID; + uint64 m_uiMimironLootGUID; + uint64 m_uiMimironHardLootGUID; + uint64 m_uiAlagonLootGUID; -bool instance_ulduar::IsEncounterInProgress() const -{ - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + memset(&m_auiHardBoss, 0, sizeof(m_auiHardBoss)); + memset(&m_auiUlduarKeepers, 0, sizeof(m_auiUlduarKeepers)); + memset(&m_auiUlduarTeleporters, 0, sizeof(m_auiUlduarTeleporters)); + + for(uint8 i = 0; i < 6; i++) + m_auiMiniBoss[i] = NOT_STARTED; + + for(uint8 i = 0; i < 9; i++) + m_uiMimironTelGUID[i] = 0; + + m_uiMimironPhase = 0; + m_uiYoggPhase = 0; + m_uiVisionPhase = 0; + + m_uiLeviathanGUID = 0; + m_uiIgnisGUID = 0; + m_uiRazorscaleGUID = 0; + m_uiCommanderGUID = 0; + m_uiXT002GUID = 0; + m_uiKologarnGUID = 0; + m_uiAuriayaGUID = 0; + m_uiMimironGUID = 0; + m_uiHodirGUID = 0; + m_uiThorimGUID = 0; + m_uiFreyaGUID = 0; + m_uiVezaxGUID = 0; + m_uiYoggSaronGUID = 0; + m_uiAlgalonGUID = 0; + m_uiRightArmGUID = 0; + m_uiLeftArmGUID = 0; + m_uiFeralDefenderGUID = 0; + m_uiElderBrightleafGUID = 0; + m_uiElderStonebarkGUID = 0; + m_uiElderIronbrachGUID = 0; + m_uiSaroniteAnimusGUID = 0; + m_uiRunicColossusGUID = 0; + m_uiRuneGiantGUID = 0; + m_uiJormungarGUID = 0; + m_uiLeviathanMkGUID = 0; + m_uiHodirImageGUID = 0; + m_uiFreyaImageGUID = 0; + m_uiThorimImageGUID = 0; + m_uiMimironImageGUID = 0; + m_uiSaraGUID = 0; + m_uiYoggBrainGUID = 0; + + // loot + m_uiKologarnLootGUID = 0; + m_uiHodirLootGUID = 0; + m_uiHodirRareLootGUID = 0; + m_uiThorimLootGUID = 0; + m_uiThorimRareLootGUID = 0; + m_uiFreyaLootGUID = 0; + m_uiFreyaLoot1GUID = 0; + m_uiFreyaLoot2GUID = 0; + m_uiFreyaLoot3GUID = 0; + m_uiMimironLootGUID = 0; + m_uiMimironHardLootGUID = 0; + m_uiAlagonLootGUID = 0; + + // doors + // The siege + m_uiShieldWallGUID = 0; + m_uiLeviathanGateGUID = 0; + m_uiXT002GateGUID = 0; + m_uiBrokenHarpoonGUID = 0; + // Archivum + m_uiIronCouncilDoorGUID = 0; + m_uiArchivumDoorGUID = 0; + m_uiArchivumConsoleGUID = 0; + m_uiUniverseFloorArchivumGUID = 0; + // Celestial planetarium + m_uiCelestialDoorGUID = 0; + m_uiCelestialConsoleGUID = 0; + m_uiUniverseFloorCelestialGUID = 0; + m_uiAzerothGlobeGUID = 0; + // Kologarn + m_uiShatteredHallsDoorGUID = 0; + m_uiKologarnBridgeGUID = 0; + // Hodir + m_uiHodirEnterDoorGUID = 0; + m_uiHodirWallGUID = 0; + m_uiHodirExitDoorGUID = 0; + // Mimiron + m_uiMimironTramGUID = 0; + m_uiMimironButtonGUID = 0; + m_uiMimironDoor1GUID = 0; + m_uiMimironDoor2GUID = 0; + m_uiMimironDoor3GUID = 0; + m_uiMimironElevatorGUID = 0; + // Thorim + m_uiArenaEnterDoorGUID = 0; + m_uiArenaExitDoorGUID = 0; + m_uiHallwayDoorGUID = 0; + m_uiThorimEnterDoorGUID = 0; + m_uiThorimLeverGUID = 0; + // Prison + m_uiAncientGateGUID = 0; + m_uiVezaxGateGUID = 0; + m_uiYoggGateGUID = 0; + m_uiBrainDoor1GUID = 0; + m_uiBrainDoor2GUID = 0; + m_uiBrainDoor3GUID = 0; + } + + bool IsEncounterInProgress() const { - if (m_auiEncounter[i] == IN_PROGRESS) - return true; + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + if (m_auiEncounter[i] == IN_PROGRESS) + return true; + } + + return false; } - return false; -} -void instance_ulduar::OnCreatureCreate(Creature* pCreature) -{ - switch (pCreature->GetEntry()) + void OnCreatureCreate(Creature* pCreature) { + switch(pCreature->GetEntry()) + { case NPC_LEVIATHAN: m_uiLeviathanGUID = pCreature->GetGUID(); break; @@ -164,15 +278,18 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) case NPC_XT002: m_uiXT002GUID = pCreature->GetGUID(); break; + + // Assembly of Iron case NPC_STEELBREAKER: - m_uiSteelbreakerGUID = pCreature->GetGUID(); + m_auiAssemblyGUIDs[0] = pCreature->GetGUID(); break; case NPC_MOLGEIM: - m_uiMolgeimGUID = pCreature->GetGUID(); + m_auiAssemblyGUIDs[1] = pCreature->GetGUID(); break; case NPC_BRUNDIR: - m_uiBrundirGUID = pCreature->GetGUID(); + m_auiAssemblyGUIDs[2] = pCreature->GetGUID(); break; + case NPC_KOLOGARN: m_uiKologarnGUID = pCreature->GetGUID(); break; @@ -190,21 +307,15 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) break; case NPC_MIMIRON: m_uiMimironGUID = pCreature->GetGUID(); - if(m_auiEncounter[7] == DONE) - SpawnFriendlyKeeper(NPC_MIMIRON_IMAGE); break; case NPC_LEVIATHAN_MK: m_uiLeviathanMkGUID = pCreature->GetGUID(); break; case NPC_HODIR: m_uiHodirGUID = pCreature->GetGUID(); - if(m_auiEncounter[8] == DONE) - SpawnFriendlyKeeper(NPC_HODIR_IMAGE); break; case NPC_THORIM: m_uiThorimGUID = pCreature->GetGUID(); - if(m_auiEncounter[9] == DONE) - SpawnFriendlyKeeper(NPC_THORIM_IMAGE); break; case NPC_RUNIC_COLOSSUS: m_uiRunicColossusGUID = pCreature->GetGUID(); @@ -217,22 +328,20 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) break; case NPC_FREYA: m_uiFreyaGUID = pCreature->GetGUID(); - if(m_auiEncounter[10] == DONE) - SpawnFriendlyKeeper(NPC_FREYA_IMAGE); break; - case NPC_ELDER_BRIGHTLEAF: + case NPC_BRIGHTLEAF: m_uiElderBrightleafGUID = pCreature->GetGUID(); break; - case NPC_ELDER_IRONBRACH: + case NPC_IRONBRACH: m_uiElderIronbrachGUID = pCreature->GetGUID(); break; - case NPC_ELDER_STONEBARK: + case NPC_STONEBARK: m_uiElderStonebarkGUID = pCreature->GetGUID(); break; case NPC_VEZAX: m_uiVezaxGUID = pCreature->GetGUID(); break; - case NPC_SARONITE_ANIMUS: + case NPC_ANIMUS: m_uiSaroniteAnimusGUID = pCreature->GetGUID(); break; case NPC_YOGGSARON: @@ -247,28 +356,54 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature) case NPC_ALGALON: m_uiAlgalonGUID = pCreature->GetGUID(); break; - } -} + // used to handle the keepers images + // set to invisible by default and only made visible if the encounter is done + case HODIR_IMAGE: + m_uiHodirImageGUID = pCreature->GetGUID(); + pCreature->SetVisibility(VISIBILITY_OFF); + if(m_auiEncounter[8] == DONE) + pCreature->SetVisibility(VISIBILITY_ON); + break; + case FREYA_IMAGE: + m_uiFreyaImageGUID = pCreature->GetGUID(); + pCreature->SetVisibility(VISIBILITY_OFF); + if(m_auiEncounter[10] == DONE) + pCreature->SetVisibility(VISIBILITY_ON); + break; + case THORIM_IMAGE: + m_uiThorimImageGUID = pCreature->GetGUID(); + pCreature->SetVisibility(VISIBILITY_OFF); + if(m_auiEncounter[9] == DONE) + pCreature->SetVisibility(VISIBILITY_ON); + break; + case MIMIRON_IMAGE: + m_uiMimironImageGUID = pCreature->GetGUID(); + pCreature->SetVisibility(VISIBILITY_OFF); + if(m_auiEncounter[7] == DONE) + pCreature->SetVisibility(VISIBILITY_ON); + break; + } + } -void instance_ulduar::OnObjectCreate(GameObject* pGo) -{ - switch(pGo->GetEntry()) + void OnObjectCreate(GameObject *pGo) { - // ----------------- Doors & Other ----------------- - // The siege + switch(pGo->GetEntry()) + { + // doors & other + // The siege case GO_SHIELD_WALL: m_uiShieldWallGUID = pGo->GetGUID(); break; case GO_LEVIATHAN_GATE: m_uiLeviathanGateGUID = pGo->GetGUID(); - if (m_auiEncounter[0] == DONE) + if(m_auiEncounter[0] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_XT002_GATE: pGo->SetGoState(GO_STATE_READY); - if (m_auiEncounter[3] == DONE) + if(m_auiEncounter[3] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); - if (m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE) + if(m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); m_uiXT002GateGUID = pGo->GetGUID(); break; @@ -277,13 +412,13 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); break; - // Archivum + // Archivum case GO_IRON_ENTRANCE_DOOR: m_uiIronCouncilDoorGUID = pGo->GetGUID(); break; case GO_ARCHIVUM_DOOR: m_uiArchivumDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[4]) + if(m_auiEncounter[4]) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_ARCHIVUM_CONSOLE: @@ -292,7 +427,7 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) case GO_UNIVERSE_FLOOR_ARCHIVUM: m_uiUniverseFloorArchivumGUID = pGo->GetGUID(); break; - // Celestial Planetarium + // Celestial Planetarium case GO_CELESTIAL_ACCES: m_uiCelestialConsoleGUID = pGo->GetGUID(); break; @@ -305,34 +440,45 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) case GO_AZEROTH_GLOBE: m_uiAzerothGlobeGUID = pGo->GetGUID(); break; - // Shattered Hallway + // Shattered Hallway case GO_KOLOGARN_BRIDGE: m_uiKologarnBridgeGUID = pGo->GetGUID(); pGo->SetGoState(GO_STATE_ACTIVE); - if (m_auiEncounter[5] == DONE) + if(m_auiEncounter[5] == DONE) + { + pGo->SetUInt32Value(GAMEOBJECT_LEVEL, 0); pGo->SetGoState(GO_STATE_READY); + } break; case GO_SHATTERED_DOOR: m_uiShatteredHallsDoorGUID = pGo->GetGUID(); break; - // ----------------- The Keepers ----------------- - // Hodir + // The keepers + // Hodir case GO_HODIR_EXIT: m_uiHodirExitDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[8]) + if(m_auiEncounter[8]) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_HODIR_ICE_WALL: m_uiHodirWallGUID = pGo->GetGUID(); - if (m_auiEncounter[8]) + if(m_auiEncounter[8]) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_HODIR_ENTER: m_uiHodirEnterDoorGUID = pGo->GetGUID(); break; - // Mimiron - case G0_MIMIRON_BUTTON: + // Mimiron + case GO_MIMIRON_TRAM: + m_uiMimironTramGUID = pGo->GetGUID(); + if (m_auiEncounter[6] == DONE) + { + pGo->SetUInt32Value(GAMEOBJECT_LEVEL, 0); + pGo->SetGoState(GO_STATE_READY); + } + break; + case GO_MIMIRON_BUTTON: m_uiMimironButtonGUID = pGo->GetGUID(); if (m_auiEncounter[7] == NOT_STARTED) pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); @@ -350,33 +496,33 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) m_uiMimironElevatorGUID = pGo->GetGUID(); break; case GO_MIMIRON_TEL1: - m_auiMimironTelGUID[0] = pGo->GetGUID(); + m_uiMimironTelGUID[0] = pGo->GetGUID(); break; case GO_MIMIRON_TEL2: - m_auiMimironTelGUID[1] = pGo->GetGUID(); + m_uiMimironTelGUID[1] = pGo->GetGUID(); break; case GO_MIMIRON_TEL3: - m_auiMimironTelGUID[2] = pGo->GetGUID(); + m_uiMimironTelGUID[2] = pGo->GetGUID(); break; case GO_MIMIRON_TEL4: - m_auiMimironTelGUID[3] = pGo->GetGUID(); + m_uiMimironTelGUID[3] = pGo->GetGUID(); break; case GO_MIMIRON_TEL5: - m_auiMimironTelGUID[4] = pGo->GetGUID(); + m_uiMimironTelGUID[4] = pGo->GetGUID(); break; case GO_MIMIRON_TEL6: - m_auiMimironTelGUID[5] = pGo->GetGUID(); + m_uiMimironTelGUID[5] = pGo->GetGUID(); break; case GO_MIMIRON_TEL7: - m_auiMimironTelGUID[6] = pGo->GetGUID(); + m_uiMimironTelGUID[6] = pGo->GetGUID(); break; case GO_MIMIRON_TEL8: - m_auiMimironTelGUID[7] = pGo->GetGUID(); + m_uiMimironTelGUID[7] = pGo->GetGUID(); break; case GO_MIMIRON_TEL9: - m_auiMimironTelGUID[8] = pGo->GetGUID(); + m_uiMimironTelGUID[8] = pGo->GetGUID(); break; - // Thorim + // Thorim case GO_DARK_IRON_PORTCULIS: m_uiArenaExitDoorGUID = pGo->GetGUID(); break; @@ -394,15 +540,15 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); break; - // Prison + // Prison case GO_ANCIENT_GATE: m_uiAncientGateGUID = pGo->GetGUID(); - DoOpenMadnessDoorIfCan(); + OpenMadnessDoor(); break; case GO_VEZAX_GATE: m_uiVezaxGateGUID = pGo->GetGUID(); pGo->SetGoState(GO_STATE_READY); - if (m_auiEncounter[11]) + if(m_auiEncounter[11]) pGo->SetGoState(GO_STATE_ACTIVE); break; case GO_YOGG_GATE: @@ -418,119 +564,216 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo) m_uiBrainDoor3GUID = pGo->GetGUID(); break; - // ----------------- Chests ----------------- - // Kologarn + // loot + // Kologarn case GO_CACHE_OF_LIVING_STONE: + if(Regular) + m_uiKologarnLootGUID = pGo->GetGUID(); + break; case GO_CACHE_OF_LIVING_STONE_H: - m_uiKologarnLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiKologarnLootGUID = pGo->GetGUID(); break; - // Hodir + // Hodir case GO_CACHE_OF_WINTER: + if(Regular) + m_uiHodirLootGUID = pGo->GetGUID(); + break; case GO_CACHE_OF_WINTER_H: - m_uiHodirLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiHodirLootGUID = pGo->GetGUID(); break; + // Hodir rare case GO_CACHE_OF_RARE_WINTER: + if(Regular) + m_uiHodirRareLootGUID = pGo->GetGUID(); + break; case GO_CACHE_OF_RARE_WINTER_H: - m_uiHodirRareLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiHodirRareLootGUID = pGo->GetGUID(); break; - // Thorim + // Freya + case GO_FREYA_GIFT: + if(Regular) + m_uiFreyaLootGUID = pGo->GetGUID(); + break; + case GO_FREYA_GIFT_H: + if(!Regular) + m_uiFreyaLootGUID = pGo->GetGUID(); + break; + // Freya rare + case GO_FREYA_GIFT_1: + if(Regular) + m_uiFreyaLoot1GUID = pGo->GetGUID(); + break; + case GO_FREYA_GIFT_H_1: + if(!Regular) + m_uiFreyaLoot1GUID = pGo->GetGUID(); + break; + case GO_FREYA_GIFT_2: + if(Regular) + m_uiFreyaLoot2GUID = pGo->GetGUID(); + break; + case GO_FREYA_GIFT_H_2: + if(!Regular) + m_uiFreyaLoot2GUID = pGo->GetGUID(); + break; + case GO_FREYA_GIFT_3: + if(Regular) + m_uiFreyaLoot3GUID = pGo->GetGUID(); + break; + case GO_FREYA_GIFT_H_3: + if(!Regular) + m_uiFreyaLoot3GUID = pGo->GetGUID(); + break; + + // Thorim case GO_CACHE_OF_STORMS: + if(Regular) + m_uiThorimLootGUID = pGo->GetGUID(); + break; case GO_CACHE_OF_STORMS_H: - m_uiThorimLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiThorimLootGUID = pGo->GetGUID(); break; + // Thorim rare case GO_CACHE_OF_RARE_STORMS: + if(Regular) + m_uiThorimRareLootGUID = pGo->GetGUID(); + break; case GO_CACHE_OF_RARE_STORMS_H: - m_uiThorimRareLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiThorimRareLootGUID = pGo->GetGUID(); break; - // Mimiron + // Mimiron case GO_CACHE_OF_INOV: + if(Regular) + m_uiMimironLootGUID = pGo->GetGUID(); + break; case GO_CACHE_OF_INOV_H: - m_uiMimironLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiMimironLootGUID = pGo->GetGUID(); break; case GO_CACHE_OF_INOV_HARD: + if(Regular) + m_uiMimironHardLootGUID = pGo->GetGUID(); + break; case GO_CACHE_OF_INOV_HARD_H: - m_uiMimironHardLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiMimironHardLootGUID = pGo->GetGUID(); break; - // Alagon + // Alagon case GO_GIFT_OF_OBSERVER: + if(Regular) + m_uiAlagonLootGUID = pGo->GetGUID(); + break; case GO_GIFT_OF_OBSERVER_H: - m_uiAlagonLootGUID = pGo->GetGUID(); + if(!Regular) + m_uiAlagonLootGUID = pGo->GetGUID(); break; + } } -} -Player* instance_ulduar::GetPlayerInMap() -{ - Map::PlayerList const& players = instance->GetPlayers(); + // functions to open or close some doors + void OpenDoor(uint64 guid) + { + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_ACTIVE); + } - if (!players.isEmpty()) + void CloseDoor(uint64 guid) { - for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* plr = itr->getSource()) - return plr; - } + if(!guid) return; + GameObject* pGo = instance->GetGameObject(guid); + if(pGo) pGo->SetGoState(GO_STATE_READY); } - return NULL; -} -// Used in order to unlock the door to Vezax -void instance_ulduar::DoOpenMadnessDoorIfCan() -{ - if (m_auiEncounter[TYPE_MIMIRON] == DONE && m_auiEncounter[TYPE_HODIR] == DONE && m_auiEncounter[TYPE_THORIM] == DONE && m_auiEncounter[TYPE_FREYA] == DONE) + // used in order to unlock the door to Vezax and make vezax attackable + void OpenMadnessDoor() { - if (GameObject* pDoor = instance->GetGameObject(m_uiAncientGateGUID)) - pDoor->SetGoState(GO_STATE_ACTIVE); + if(m_auiEncounter[7] == DONE && m_auiEncounter[8] == DONE && m_auiEncounter[9] == DONE && m_auiEncounter[10] == DONE) + OpenDoor(m_uiAncientGateGUID); + OpenDoor(m_uiAncientGateGUID); } -} -void instance_ulduar::SetData(uint32 uiType, uint32 uiData) -{ - switch (uiType) + // used to open the door to XT (custom script because Leviathan is disabled) + // this will be removed when the Leviathan will be implemented + void OpenXtDoor() + { + if(m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE) + OpenDoor(m_uiXT002GateGUID); + } + + void SetData(uint32 uiType, uint32 uiData) { + switch(uiType) + { case TYPE_LEVIATHAN: m_auiEncounter[0] = uiData; DoUseDoorOrButton(m_uiShieldWallGUID); if (uiData == DONE) { - DoUseDoorOrButton(m_uiXT002GateGUID); - DoUseDoorOrButton(m_uiLeviathanGateGUID); + OpenDoor(m_uiXT002GateGUID); + OpenDoor(m_uiLeviathanGateGUID); } break; case TYPE_IGNIS: m_auiEncounter[1] = uiData; + OpenXtDoor(); // remove when leviathan implemented break; case TYPE_RAZORSCALE: m_auiEncounter[2] = uiData; + OpenXtDoor(); // remove when leviathan implemented break; case TYPE_XT002: m_auiEncounter[3] = uiData; - DoUseDoorOrButton(m_uiXT002GateGUID); + if (uiData == DONE) + OpenDoor(m_uiXT002GateGUID); + else if (uiData == IN_PROGRESS) + CloseDoor(m_uiXT002GateGUID); break; case TYPE_ASSEMBLY: m_auiEncounter[4] = uiData; - DoUseDoorOrButton(m_uiIronCouncilDoorGUID); if (uiData == DONE) - DoUseDoorOrButton(m_uiArchivumDoorGUID); + { + OpenDoor(m_uiIronCouncilDoorGUID); + OpenDoor(m_uiArchivumDoorGUID); + CheckIronCouncil(); // used for a hacky achiev, remove for revision! + } else if (uiData == IN_PROGRESS) + CloseDoor(m_uiIronCouncilDoorGUID); break; case TYPE_KOLOGARN: m_auiEncounter[5] = uiData; - DoUseDoorOrButton(m_uiShatteredHallsDoorGUID); if (uiData == DONE) { DoRespawnGameObject(m_uiKologarnLootGUID, 30*MINUTE); - if(GameObject* pBridge = instance->GetGameObject(m_uiKologarnBridgeGUID)) - pBridge->SetGoState(GO_STATE_READY); + if(m_auiEncounter[5] == DONE) + if (GameObject* pGo = instance->GetGameObject(m_uiKologarnBridgeGUID)) + { + pGo->SetUInt32Value(GAMEOBJECT_LEVEL, 0); + pGo->SetGoState(GO_STATE_READY); + } } break; case TYPE_AURIAYA: m_auiEncounter[6] = uiData; + if (uiData == DONE) + { +// CheckIronCouncil(); // used for a hacky achiev, remove for revision! + if (GameObject* pGO = instance->GetGameObject(m_uiMimironTramGUID)) + { + pGO->SetUInt32Value(GAMEOBJECT_LEVEL, 0); + pGO->SetGoState(GO_STATE_READY); + } + } break; - // Keepers + + // Keepers case TYPE_MIMIRON: m_auiEncounter[7] = uiData; DoUseDoorOrButton(m_uiMimironDoor1GUID); @@ -538,9 +781,13 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) DoUseDoorOrButton(m_uiMimironDoor3GUID); if (uiData == DONE) { - if (m_auiHardBoss[3] != DONE) + if(m_auiHardBoss[3] != DONE) DoRespawnGameObject(m_uiMimironLootGUID, 30*MINUTE); - SpawnFriendlyKeeper(NPC_MIMIRON_IMAGE); + // used to make the friendly keeper visible + if(Creature* pImage = instance->GetCreature(m_uiMimironImageGUID)) + pImage->SetVisibility(VISIBILITY_ON); + OpenMadnessDoor(); + CheckKeepers(); // used for a hacky achiev, remove for revision! } break; case TYPE_HODIR: @@ -551,27 +798,51 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) DoUseDoorOrButton(m_uiHodirWallGUID); DoUseDoorOrButton(m_uiHodirExitDoorGUID); DoRespawnGameObject(m_uiHodirLootGUID, 30*MINUTE); - SpawnFriendlyKeeper(NPC_HODIR_IMAGE); + // used to make the friendly keeper visible + if(Creature* pImage = instance->GetCreature(m_uiHodirImageGUID)) + pImage->SetVisibility(VISIBILITY_ON); + OpenMadnessDoor(); + CheckKeepers(); // used for a hacky achiev, remove for revision! } break; case TYPE_THORIM: - m_auiEncounter[9] = uiData; + m_auiEncounter[9] = uiData; DoUseDoorOrButton(m_uiArenaEnterDoorGUID); if (uiData == IN_PROGRESS) DoUseDoorOrButton(m_uiArenaExitDoorGUID); if (uiData == DONE) { - if (m_auiHardBoss[5] != DONE) + if(m_auiHardBoss[5] != DONE) DoRespawnGameObject(m_uiThorimLootGUID, 30*MINUTE); - SpawnFriendlyKeeper(NPC_THORIM_IMAGE); + // used to make the friendly keeper visible + if(Creature* pImage = instance->GetCreature(m_uiThorimImageGUID)) + pImage->SetVisibility(VISIBILITY_ON); + OpenMadnessDoor(); + CheckKeepers(); // used for a hacky achiev, remove for revision! } break; case TYPE_FREYA: m_auiEncounter[10] = uiData; if (uiData == DONE) - SpawnFriendlyKeeper(NPC_FREYA_IMAGE); + { + // do this in order to see how many elders were alive and spawn the correct chest + if(m_auiHardBoss[6] == 0) + DoRespawnGameObject(m_uiFreyaLootGUID, 30*MINUTE); + else if(m_auiHardBoss[6] == 1) + DoRespawnGameObject(m_uiFreyaLoot1GUID, 30*MINUTE); + else if(m_auiHardBoss[6] == 2) + DoRespawnGameObject(m_uiFreyaLoot2GUID, 30*MINUTE); + else if(m_auiHardBoss[6] == 3) + DoRespawnGameObject(m_uiFreyaLoot3GUID, 30*MINUTE); + // used to make the friendly keeper visible + if(Creature* pImage = instance->GetCreature(m_uiFreyaImageGUID)) + pImage->SetVisibility(VISIBILITY_ON); + OpenMadnessDoor(); + CheckKeepers(); // used for a hacky achiev, remove for revision! + } break; - // Prison + + // Prison case TYPE_VEZAX: m_auiEncounter[11] = uiData; if (uiData == DONE) @@ -582,52 +853,51 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) DoUseDoorOrButton(m_uiYoggGateGUID); break; - // Celestial Planetarium + // Celestial Planetarium case TYPE_ALGALON: m_auiEncounter[13] = uiData; - //TODO: need to find the proper way to use these DoUseDoorOrButton(m_uiCelestialDoorGUID); DoUseDoorOrButton(m_uiUniverseFloorCelestialGUID); if (uiData == DONE) DoRespawnGameObject(m_uiAlagonLootGUID, 30*MINUTE); break; - // Hard modes + // Hard modes case TYPE_LEVIATHAN_HARD: - m_auiHardBoss[0] = uiData; // TODO: add extra loot + m_auiHardBoss[0] = uiData; // todo: add extra loot break; case TYPE_XT002_HARD: - m_auiHardBoss[1] = uiData; // TODO: add extra loot + m_auiHardBoss[1] = uiData; // hard mode loot in sql -> hacky way break; case TYPE_HODIR_HARD: m_auiHardBoss[4] = uiData; - if (uiData == DONE) + if(uiData == DONE) DoRespawnGameObject(m_uiHodirRareLootGUID, 30*MINUTE); break; case TYPE_ASSEMBLY_HARD: - m_auiHardBoss[2] = uiData; // TODO: add extra loot + m_auiHardBoss[2] = uiData; // hard mode loot in sql break; case TYPE_FREYA_HARD: - m_auiHardBoss[6] = uiData; // Hard mode loot in in script + m_auiHardBoss[6] = uiData; // hard mode loot in the script above break; case TYPE_THORIM_HARD: m_auiHardBoss[5] = uiData; - if (uiData == DONE) + if(uiData == DONE) DoRespawnGameObject(m_uiThorimRareLootGUID, 30*MINUTE); break; case TYPE_MIMIRON_HARD: m_auiHardBoss[3] = uiData; - if (uiData == DONE) + if(uiData == DONE) DoRespawnGameObject(m_uiMimironHardLootGUID, 30*MINUTE); break; case TYPE_VEZAX_HARD: - m_auiHardBoss[7] = uiData; // TODO: add extra loot + m_auiHardBoss[7] = uiData; // hard mode loot in sql -> hacky way break; case TYPE_YOGGSARON_HARD: - m_auiHardBoss[8] = uiData; // TODO: add extra loot + m_auiHardBoss[8] = uiData; // todo: add extra loot break; - // Ulduar keepers + // Ulduar keepers case TYPE_KEEPER_HODIR: m_auiUlduarKeepers[0] = uiData; break; @@ -641,7 +911,7 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) m_auiUlduarKeepers[3] = uiData; break; - // Teleporters + // teleporters case TYPE_LEVIATHAN_TP: m_auiUlduarTeleporters[0] = uiData; break; @@ -651,38 +921,81 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData) case TYPE_MIMIRON_TP: m_auiUlduarTeleporters[2] = uiData; break; - } - DoOpenMadnessDoorIfCan(); + // mini boss + case TYPE_RUNIC_COLOSSUS: + m_auiMiniBoss[0] = uiData; + if (uiData == DONE) + OpenDoor(m_uiHallwayDoorGUID); + else + CloseDoor(m_uiHallwayDoorGUID); + break; + case TYPE_RUNE_GIANT: + m_auiMiniBoss[1] = uiData; + if (uiData == DONE) + OpenDoor(m_uiThorimEnterDoorGUID); + else + CloseDoor(m_uiThorimEnterDoorGUID); + break; + case TYPE_LEVIATHAN_MK: + m_auiMiniBoss[2] = uiData; + break; + case TYPE_VX001: + m_auiMiniBoss[3] = uiData; + if (uiData == DONE) // just for animation :) + { + for(uint8 i = 0; i < 9; i++) + DoUseDoorOrButton(m_uiMimironTelGUID[i]); + } + break; + case TYPE_AERIAL_UNIT: + m_auiMiniBoss[4] = uiData; + break; + case TYPE_YOGG_BRAIN: + m_auiMiniBoss[5] = uiData; + break; + + //phases + case TYPE_MIMIRON_PHASE: + m_uiMimironPhase = uiData; + break; + case TYPE_YOGG_PHASE: + m_uiYoggPhase = uiData; + break; + case TYPE_VISION_PHASE: + m_uiVisionPhase = uiData; + break; + } - if (uiData == DONE || uiData == FAIL) - { - OUT_SAVE_INST_DATA; - - // Save all encounters, hard bosses, keepers and teleporters - 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_auiEncounter[10] << " " << m_auiEncounter[11] << " " - << m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiHardBoss[0] << " " - << m_auiHardBoss[1] << " " << m_auiHardBoss[2] << " " << m_auiHardBoss[2] << " " - << m_auiHardBoss[4] << " " << m_auiHardBoss[5] << " " << m_auiHardBoss[6] << " " - << m_auiHardBoss[7] << " " << m_auiHardBoss[8] << " " << m_auiUlduarKeepers[0] << " " - << m_auiUlduarKeepers[1] << " " << m_auiUlduarKeepers[2] << " " << m_auiUlduarKeepers[3]; - - strInstData = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; + if (uiData == DONE || uiData == FAIL) + { + OUT_SAVE_INST_DATA; + + // save all encounters, hard bosses and keepers + 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_auiEncounter[10] << " " << m_auiEncounter[11] << " " + << m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiHardBoss[0] << " " + << m_auiHardBoss[1] << " " << m_auiHardBoss[2] << " " << m_auiHardBoss[2] << " " + << m_auiHardBoss[4] << " " << m_auiHardBoss[5] << " " << m_auiHardBoss[6] << " " + << m_auiHardBoss[7] << " " << m_auiHardBoss[8] << " " << m_auiUlduarKeepers[0] << " " + << m_auiUlduarKeepers[1] << " " << m_auiUlduarKeepers[2] << " " << m_auiUlduarKeepers[3] << " " + << m_auiUlduarTeleporters[0] << " " << m_auiUlduarTeleporters[1] << " " << m_auiUlduarTeleporters[2]; + + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } } -} -uint64 instance_ulduar::GetData64(uint32 uiData) -{ - switch (uiData) + uint64 GetData64(uint32 uiData) { - // Siege + switch(uiData) + { + // Siege case NPC_LEVIATHAN: return m_uiLeviathanGUID; case NPC_IGNIS: @@ -693,13 +1006,13 @@ uint64 instance_ulduar::GetData64(uint32 uiData) return m_uiCommanderGUID; case NPC_XT002: return m_uiXT002GUID; - // Antechamber + // Antechamber case NPC_STEELBREAKER: - return m_uiSteelbreakerGUID; + return m_auiAssemblyGUIDs[0]; case NPC_MOLGEIM: - return m_uiMolgeimGUID; + return m_auiAssemblyGUIDs[1]; case NPC_BRUNDIR: - return m_uiBrundirGUID; + return m_auiAssemblyGUIDs[2]; case NPC_KOLOGARN: return m_uiKologarnGUID; case NPC_LEFT_ARM: @@ -708,7 +1021,7 @@ uint64 instance_ulduar::GetData64(uint32 uiData) return m_uiRightArmGUID; case NPC_AURIAYA: return m_uiAuriayaGUID; - // Keepers + // Keepers case NPC_MIMIRON: return m_uiMimironGUID; case NPC_LEVIATHAN_MK: @@ -725,11 +1038,11 @@ uint64 instance_ulduar::GetData64(uint32 uiData) return m_uiJormungarGUID; case NPC_FREYA: return m_uiFreyaGUID; - case NPC_ELDER_BRIGHTLEAF: + case NPC_BRIGHTLEAF: return m_uiElderBrightleafGUID; - case NPC_ELDER_IRONBRACH: + case NPC_IRONBRACH: return m_uiElderIronbrachGUID; - case NPC_ELDER_STONEBARK: + case NPC_STONEBARK: return m_uiElderStonebarkGUID; case NPC_VEZAX: return m_uiVezaxGUID; @@ -742,35 +1055,47 @@ uint64 instance_ulduar::GetData64(uint32 uiData) case NPC_ALGALON: return m_uiAlgalonGUID; - // Mimiron hard mode button - case G0_MIMIRON_BUTTON: + // mimiron hard mode button + case GO_MIMIRON_BUTTON: return m_uiMimironButtonGUID; - // Celestial door + // thorim encounter starter lever + case GO_DOOR_LEVER: + return m_uiThorimLeverGUID; + // celestial door case GO_CELESTIAL_DOOR: return m_uiCelestialDoorGUID; - } + } - return 0; -} + return 0; + } -// TODO: implement all hard mode loot here! -bool instance_ulduar::CheckConditionCriteriaMeet(Player const* pSource, uint32 uiMapId, uint32 uiInstanceConditionId) -{ - if (uiMapId != instance->GetId()) + // TODO: implement all achievs here! + bool CheckAchievementCriteriaMeet(uint32 criteria_id, const Player *source) + { + switch(criteria_id) + { + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: + break; + } return false; + } - switch (uiInstanceConditionId) - { - case TYPE_XT002_HARD: - break; - } - return false; -} + // TODO: implement all hard mode loot here! + bool CheckConditionCriteriaMeet(Player const* source, uint32 map_id, uint32 instance_condition_id) + { + if (map_id != instance->GetId()) + return false; + switch (instance_condition_id) + { + case TYPE_XT002_HARD: + break; + } + } -uint32 instance_ulduar::GetData(uint32 uiType) -{ - switch (uiType) - { + uint32 GetData(uint32 uiType) + { + switch(uiType) + { case TYPE_LEVIATHAN: return m_auiEncounter[0]; case TYPE_IGNIS: @@ -800,7 +1125,7 @@ uint32 instance_ulduar::GetData(uint32 uiType) case TYPE_ALGALON: return m_auiEncounter[13]; - // Hard modes + // hard modes case TYPE_LEVIATHAN_HARD: return m_auiHardBoss[0]; case TYPE_XT002_HARD: @@ -820,7 +1145,7 @@ uint32 instance_ulduar::GetData(uint32 uiType) case TYPE_YOGGSARON_HARD: return m_auiHardBoss[8]; - // Ulduar Keepers + // ulduar keepers case TYPE_KEEPER_HODIR: return m_auiUlduarKeepers[0]; case TYPE_KEEPER_THORIM: @@ -830,61 +1155,91 @@ uint32 instance_ulduar::GetData(uint32 uiType) case TYPE_KEEPER_MIMIRON: return m_auiUlduarKeepers[3]; - // Teleporters + // teleporters case TYPE_LEVIATHAN_TP: return m_auiUlduarTeleporters[0]; case TYPE_XT002_TP: return m_auiUlduarTeleporters[1]; case TYPE_MIMIRON_TP: return m_auiUlduarTeleporters[2]; - } - return 0; -} + // mini boss + case TYPE_RUNE_GIANT: + return m_auiMiniBoss[1]; + case TYPE_RUNIC_COLOSSUS: + return m_auiMiniBoss[0]; + case TYPE_LEVIATHAN_MK: + return m_auiMiniBoss[2]; + case TYPE_VX001: + return m_auiMiniBoss[3]; + case TYPE_AERIAL_UNIT: + return m_auiMiniBoss[4]; + case TYPE_YOGG_BRAIN: + return m_auiMiniBoss[5]; -// Spawn the friendly keepers in the central chamber -void instance_ulduar::SpawnFriendlyKeeper(uint32 uiWho) -{ - Player* pPlayer = GetPlayerInMap(); - if (!pPlayer) - return; + case TYPE_MIMIRON_PHASE: + return m_uiMimironPhase; + case TYPE_YOGG_PHASE: + return m_uiYoggPhase; + case TYPE_VISION_PHASE: + return m_uiVisionPhase; + } - switch(uiWho) - { - case NPC_MIMIRON_IMAGE: pPlayer->SummonCreature(NPC_MIMIRON_IMAGE, m_aKeepersSpawnLocs[1].m_fX, m_aKeepersSpawnLocs[1].m_fY, m_aKeepersSpawnLocs[1].m_fZ, m_aKeepersSpawnLocs[1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break; - case NPC_HODIR_IMAGE: pPlayer->SummonCreature(NPC_HODIR_IMAGE, m_aKeepersSpawnLocs[2].m_fX, m_aKeepersSpawnLocs[2].m_fY, m_aKeepersSpawnLocs[2].m_fZ, m_aKeepersSpawnLocs[2].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break; - case NPC_THORIM_IMAGE: pPlayer->SummonCreature(NPC_THORIM_IMAGE, m_aKeepersSpawnLocs[3].m_fX, m_aKeepersSpawnLocs[3].m_fY, m_aKeepersSpawnLocs[3].m_fZ, m_aKeepersSpawnLocs[3].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break; - case NPC_FREYA_IMAGE: pPlayer->SummonCreature(NPC_FREYA_IMAGE, m_aKeepersSpawnLocs[0].m_fX, m_aKeepersSpawnLocs[0].m_fY, m_aKeepersSpawnLocs[0].m_fZ, m_aKeepersSpawnLocs[0].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break; + return 0; } -} -void instance_ulduar::Load(const char* strIn) -{ - if (!strIn) + const char* Save() { - OUT_LOAD_INST_DATA_FAIL; - return; + return m_strInstData.c_str(); } - OUT_LOAD_INST_DATA(strIn); + void Load(const char* strIn) + { + if (!strIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(strIn); - std::istringstream loadStream(strIn); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] + std::istringstream loadStream(strIn); + 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] >> m_auiEncounter[10] >> m_auiEncounter[11] >> m_auiEncounter[12] >> m_auiEncounter[13] >> m_auiHardBoss[0] >> m_auiHardBoss[1] >> m_auiHardBoss[2] >> m_auiHardBoss[3] >> m_auiHardBoss[4] >> m_auiHardBoss[5] >> m_auiHardBoss[6] >> m_auiHardBoss[7] >> m_auiHardBoss[8] >> m_auiUlduarKeepers[0] - >> m_auiUlduarKeepers[1] >> m_auiUlduarKeepers[2] >> m_auiUlduarKeepers[3]; + >> m_auiUlduarKeepers[1] >> m_auiUlduarKeepers[2] >> m_auiUlduarKeepers[3] >> m_auiUlduarTeleporters[0] + >> m_auiUlduarTeleporters[1] >> m_auiUlduarTeleporters[2]; + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; + } - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + // Hacky way of completing some achievs + // PLEASE REMOVE FOR REVISION! + void CheckIronCouncil() { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; + // check if the other bosses in the antechamber are dead + // hacky way to complete achievements; use only if you have this function + if(m_auiEncounter[4] == DONE && m_auiEncounter[5] == DONE && m_auiEncounter[6] == DONE) + DoCompleteAchievement(instance->IsRegularDifficulty() ? ACHIEV_IRON_COUNCIL : ACHIEV_IRON_COUNCIL_H); } - OUT_LOAD_INST_DATA_COMPLETE; -} + void CheckKeepers() + { + // check if the other bosses in the antechamber are dead + // hacky way to complete achievements; use only if you have this function + if(m_auiEncounter[7] == DONE && m_auiEncounter[8] == DONE && m_auiEncounter[9] == DONE && m_auiEncounter[10] == DONE) + DoCompleteAchievement(instance->IsRegularDifficulty() ? ACHIEV_KEEPERS : ACHIEV_KEEPERS_H); + } +}; InstanceData* GetInstanceData_instance_ulduar(Map* pMap) { @@ -893,10 +1248,9 @@ InstanceData* GetInstanceData_instance_ulduar(Map* pMap) void AddSC_instance_ulduar() { - Script* pNewScript; - - pNewScript = new Script; - pNewScript->Name = "instance_ulduar"; - pNewScript->GetInstanceData = &GetInstanceData_instance_ulduar; - pNewScript->RegisterSelf(); + Script *newscript; + newscript = new Script; + newscript->Name = "instance_ulduar"; + newscript->GetInstanceData = &GetInstanceData_instance_ulduar; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/ulduar.cpp b/scripts/northrend/ulduar/ulduar/ulduar.cpp index ff84d9798..5a5f618d2 100644 --- a/scripts/northrend/ulduar/ulduar/ulduar.cpp +++ b/scripts/northrend/ulduar/ulduar/ulduar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,8 +15,8 @@ */ /* ScriptData -SDName: ulduar -SD%Complete: 0% +SDName: Ulduar teleport +SD%Complete: SDComment: SDCategory: Ulduar EndScriptData */ @@ -24,32 +24,178 @@ EndScriptData */ #include "precompiled.h" #include "ulduar.h" -/*##### -## Teleporters -#####*/ -enum TeleporterSpells -{ - SPELL_TELE_EXPEDITION_BASE_CAMP = 64014, - SPELL_TELE_FORMATION_GROUNDS = 64032, - SPELL_TELE_COLOSSAL_FORGE = 64028, - SPELL_TELE_SCRAPYARD = 64031, - SPELL_TELE_ANTECHAMBER_OF_ULDUAR = 64030, - SPELL_TELE_SHATTERED_WALKWAY = 64029, - SPELL_TELE_CONSERVATORY_OF_LIFE = 64024, - SPELL_TELE_SPARK_OF_IMAGINATION = 65061, - SPELL_TELE_PRISON_OF_YOGG = 65042, -}; - -// Teleporter Gossip handled by SD2 because depending on Instance Data -enum TeleporterGossipItems -{ - GOSSIP_ITEM_TELE_BASE_CAMP = -3603000, - GOSSIP_ITEM_TELE_FORMATION_GROUNDS = -3603001, - GOSSIP_ITEM_TELE_COLOSSAR_FORGE = -3603002, - GOSSIP_ITEM_TELE_SCRAPYARD = -3603003, - GOSSIP_ITEM_TELE_ANTECHAMBER = -3603004, - GOSSIP_ITEM_TELE_WALKWAY = -3603005, - GOSSIP_ITEM_TELE_CONSERVATORY = -3603006, - GOSSIP_ITEM_TELE_SPARK_IMAGINATION = -3603007, - GOSSIP_ITEM_TELE_YOGG_SARON = -3603008, -}; +#define REQUEST_HELP "Help me fight Yogg-Saron!" +#define DENY_HELP "I don't need your help." + +/* +* Here is the gossip for the keepers images +* Each image appears in the centra chamber after the corrupted keeper is defeated +* They should be spawned in script, but I added them into the DB by default as invisilbe +* After the players make theyr choice if the want help or not, this option is saved and there is no turning back, until raid reset +* If they are asked for help, at the beginning of the Yogg encounter each requested keeper will be summoned inside the chamber +* There should be more text in the gossip menu, I couldn't find it anywhere yet +*/ + +/*####### +*### Keepers images +#######*/ +// HODIR +bool GossipHello_hodir_image(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + + if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_HODIR) != DONE && m_pInstance->GetData(TYPE_KEEPER_HODIR) != FAIL) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + } + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + return true; +} + +bool GossipSelect_hodir_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + pPlayer->CLOSE_GOSSIP_MENU(); + + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_HODIR, DONE); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_HODIR, FAIL); + } + return true; +} + +// FREYA +bool GossipHello_freya_image(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + + if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_FREYA) != DONE && m_pInstance->GetData(TYPE_KEEPER_FREYA) != FAIL) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + } + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + return true; +} + +bool GossipSelect_freya_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + pPlayer->CLOSE_GOSSIP_MENU(); + + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_FREYA, DONE); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_FREYA, FAIL); + } + return true; +} +// MIMIRON +bool GossipHello_mimiron_image(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + + if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_MIMIRON) != DONE && m_pInstance->GetData(TYPE_KEEPER_MIMIRON) != FAIL) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + } + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + return true; +} + +bool GossipSelect_mimiron_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + pPlayer->CLOSE_GOSSIP_MENU(); + + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_MIMIRON, DONE); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_MIMIRON, FAIL); + } + return true; +} + +// THORIM +bool GossipHello_thorim_image(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + + if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_THORIM) != DONE && m_pInstance->GetData(TYPE_KEEPER_THORIM) != FAIL) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + } + + pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); + return true; +} + +bool GossipSelect_thorim_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) +{ + ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData(); + pPlayer->CLOSE_GOSSIP_MENU(); + + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_THORIM, DONE); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_KEEPER_THORIM, FAIL); + } + return true; +} + +void AddSC_ulduar() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "hodir_image"; + newscript->pGossipHello = &GossipHello_hodir_image; + newscript->pGossipSelect = &GossipSelect_hodir_image; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "freya_image"; + newscript->pGossipHello = &GossipHello_freya_image; + newscript->pGossipSelect = &GossipSelect_freya_image; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "thorim_image"; + newscript->pGossipHello = &GossipHello_thorim_image; + newscript->pGossipSelect = &GossipSelect_thorim_image; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mimiron_image"; + newscript->pGossipHello = &GossipHello_mimiron_image; + newscript->pGossipSelect = &GossipSelect_mimiron_image; + newscript->RegisterSelf(); + +} diff --git a/scripts/northrend/ulduar/ulduar/ulduar.h b/scripts/northrend/ulduar/ulduar/ulduar.h index c1eb6fa00..9f9dcbb9d 100644 --- a/scripts/northrend/ulduar/ulduar/ulduar.h +++ b/scripts/northrend/ulduar/ulduar/ulduar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,12 +7,12 @@ enum { + // encounters MAX_ENCOUNTER = 14, - HARD_MODE_ENCOUNTER = 9, + HARD_ENCOUNTER = 9, KEEPER_ENCOUNTER = 4, - TELEPORTER_ENCOUNTER = 3, - // Main boss types + // boss types TYPE_LEVIATHAN = 0, TYPE_IGNIS = 1, TYPE_RAZORSCALE = 2, @@ -28,39 +28,46 @@ enum TYPE_YOGGSARON = 12, TYPE_ALGALON = 13, - // Hard mode boss types - // Used for hard mode bosses only - TYPE_LEVIATHAN_HARD = 14, - TYPE_XT002_HARD = 15, - TYPE_ASSEMBLY_HARD = 16, - TYPE_MIMIRON_HARD = 17, - TYPE_HODIR_HARD = 18, - TYPE_THORIM_HARD = 19, - TYPE_FREYA_HARD = 20, - TYPE_VEZAX_HARD = 21, - TYPE_YOGGSARON_HARD = 22, - - // Keeper types - // Used to store the keepers which will be used at yogg - TYPE_KEEPER_HODIR = 23, - TYPE_KEEPER_FREYA = 24, - TYPE_KEEPER_THORIM = 25, - TYPE_KEEPER_MIMIRON = 26, - - // Teleporter types - // Some teleporters aren't depending directly on a boss, so we use a distinct type for them (maybe use areatrigger?) - TYPE_LEVIATHAN_TP = 27, - TYPE_XT002_TP = 28, - TYPE_MIMIRON_TP = 29, - - // The siege of ulduar + // hard mode bosses + TYPE_LEVIATHAN_HARD = 37, + TYPE_XT002_HARD = 38, + TYPE_ASSEMBLY_HARD = 39, + TYPE_MIMIRON_HARD = 40, + TYPE_HODIR_HARD = 41, + TYPE_THORIM_HARD = 42, + TYPE_FREYA_HARD = 43, + TYPE_VEZAX_HARD = 44, + TYPE_YOGGSARON_HARD = 45, + + // keepers help at Yogg + TYPE_KEEPER_HODIR = 46, + TYPE_KEEPER_FREYA = 47, + TYPE_KEEPER_THORIM = 48, + TYPE_KEEPER_MIMIRON = 49, + + // teleporters + TYPE_LEVIATHAN_TP = 50, + TYPE_XT002_TP = 51, + TYPE_MIMIRON_TP = 52, + + //other-> these won't be saved to db + TYPE_RUNE_GIANT = 14, + TYPE_RUNIC_COLOSSUS = 15, + TYPE_LEVIATHAN_MK = 16, + TYPE_VX001 = 17, + TYPE_AERIAL_UNIT = 18, + TYPE_YOGG_BRAIN = 22, + TYPE_MIMIRON_PHASE = 23, + TYPE_YOGG_PHASE = 24, + TYPE_VISION_PHASE = 25, + + // siege NPC_LEVIATHAN = 33113, NPC_IGNIS = 33118, NPC_RAZORSCALE = 33186, NPC_COMMANDER = 33210, NPC_XT002 = 33293, - - // The antechamber of ulduar + // antechamber NPC_STEELBREAKER = 32867, NPC_MOLGEIM = 32927, NPC_BRUNDIR = 32857, @@ -70,8 +77,7 @@ enum NPC_AURIAYA = 33515, NPC_SANCTUM_SENTRY = 34014, NPC_FERAL_DEFENDER = 34035, - - // The keepers of ulduar + // keepers NPC_MIMIRON = 33350, NPC_LEVIATHAN_MK = 33432, NPC_VX001 = 33651, @@ -82,96 +88,93 @@ enum NPC_RUNE_GIANT = 32873, NPC_JORMUNGAR_BEHEMOTH = 32882, NPC_FREYA = 32906, - NPC_ELDER_BRIGHTLEAF = 32915, - NPC_ELDER_IRONBRACH = 32913, - NPC_ELDER_STONEBARK = 32914, - - // The descent into madness + NPC_BRIGHTLEAF = 32915, + NPC_IRONBRACH = 32913, + NPC_STONEBARK = 32914, + // madness NPC_VEZAX = 33271, - NPC_SARONITE_ANIMUS = 33524, + NPC_ANIMUS = 33524, NPC_YOGGSARON = 33288, - NPC_SARA = 33134, - NPC_YOGG_BRAIN = 33890, - - // Celestial planetarium NPC_ALGALON = 32871, - - // Keepers images - // They spawn in the central room after they are released from Yogg's enslavement - // You may talk to them and ask them to help you fight Yogg-Saron - NPC_THORIM_IMAGE = 33413, - NPC_MIMIRON_IMAGE = 33412, - NPC_HODIR_IMAGE = 33411, - NPC_FREYA_IMAGE = 33410, - - // Keepers used to fight Yogg-Saron - NPC_KEEPER_FREYA = 33241, - NPC_KEEPER_HODIR = 33213, - NPC_KEEPER_MIMIRON = 33244, - NPC_KEEPER_THORIM = 33242, - - // Loot chests + NPC_SARA = 33134, + NPC_YOGG_BRAIN = 33890, + // keepers images used to start the encounter + THORIM_IMAGE = 33413, + MIMIRON_IMAGE = 33412, + HODIR_IMAGE = 33411, + FREYA_IMAGE = 33410, + // Keepers used at yogg saron encounter + KEEPER_FREYA = 33241, + KEEPER_HODIR = 33213, + KEEPER_MIMIRON = 33244, + KEEPER_THORIM = 33242, + + // loot chests // Kologarn GO_CACHE_OF_LIVING_STONE = 195046, - GO_CACHE_OF_LIVING_STONE_H = 195047, - + GO_CACHE_OF_LIVING_STONE_H = 195047, // Hodir GO_CACHE_OF_WINTER = 194307, GO_CACHE_OF_WINTER_H = 194308, GO_CACHE_OF_RARE_WINTER = 194200, GO_CACHE_OF_RARE_WINTER_H = 194201, - - // Mimiron - GO_CACHE_OF_INOV = 194789, - GO_CACHE_OF_INOV_H = 194956, - GO_CACHE_OF_INOV_HARD = 194957, - GO_CACHE_OF_INOV_HARD_H = 194958, - // Thorim GO_CACHE_OF_STORMS = 194312, - GO_CACHE_OF_STORMS_H = 194314, GO_CACHE_OF_RARE_STORMS = 194313, + GO_CACHE_OF_STORMS_H = 194314, GO_CACHE_OF_RARE_STORMS_H = 194315, - // Alagon GO_GIFT_OF_OBSERVER_H = 194821, GO_GIFT_OF_OBSERVER = 194822, - GO_GIFT_OF_OBSERVER_HH = 194823, // Purpose Unknown - - // Doors and other Objects - // The siege - GO_SHIELD_WALL = 194416, // Gate before Leviathan - GO_LEVIATHAN_GATE = 194630, // Gate after Leviathan -> this should be used before the boss enter the arena - // There should be another gate after the Leviathan here which should be used during the Leviathan encounter - GO_XT002_GATE = 194631, // Gate before Xt002 - GO_BROKEN_HARPOON = 194565, // Broken harpoon from Razorscale + GO_GIFT_OF_OBSERVER_HH = 194823, // unk + // Freya -> each chest is for a mode = more elders alive = more items in chest + // 10 man + GO_FREYA_GIFT = 194324,//10 normal + GO_FREYA_GIFT_1 = 194325,//10 1 elder + GO_FREYA_GIFT_2 = 194326,//10 2 elders + GO_FREYA_GIFT_3 = 194327,//10 3 elders + // 25 man + GO_FREYA_GIFT_H = 194328,//25 normal + GO_FREYA_GIFT_H_1 = 194329,//25 1 elder + GO_FREYA_GIFT_H_2 = 194330,//25 2 elder + GO_FREYA_GIFT_H_3 = 194331,//25 3 elders + // Mimiron + GO_CACHE_OF_INOV = 194789, + GO_CACHE_OF_INOV_H = 194956, + GO_CACHE_OF_INOV_HARD = 194957, + GO_CACHE_OF_INOV_HARD_H = 194958, - // Antechamber + // doors + // the siege + GO_SHIELD_WALL = 194416, + GO_LEVIATHAN_GATE = 194630, + GO_XT002_GATE = 194631, + GO_BROKEN_HARPOON = 194565, + // archivum GO_KOLOGARN_BRIDGE = 194232, - GO_SHATTERED_DOOR = 194553, // Door before kologarn - GO_IRON_ENTRANCE_DOOR = 194554, // Door before iron council - GO_ARCHIVUM_DOOR = 194556, // Entrance door to the archivum - GO_ARCHIVUM_CONSOLE = 194555, // Used at some sort of cinematic - GO_UNIVERSE_FLOOR_ARCHIVUM = 194715, // Used for animation - - // Planetarium - GO_CELESTIAL_ACCES = 194628, // Acces console for 10 man mode - GO_CELESTIAL_ACCES_H = 194752, // Acces console for 25 man mode - GO_CELESTIAL_DOOR = 194767, // Entrance door to the planetarium - GO_UNIVERSE_FLOOR_CELESTIAL = 194716, // For animation - GO_AZEROTH_GLOBE = 194148, // For animation - - // The keepers - // Hodir + GO_SHATTERED_DOOR = 194553, + GO_IRON_ENTRANCE_DOOR = 194554, + GO_ARCHIVUM_DOOR = 194556, + GO_ARCHIVUM_CONSOLE = 194555, + // planetarium: algalon + GO_CELESTIAL_ACCES = 194628, + GO_CELESTIAL_ACCES_H = 194752, + GO_CELESTIAL_DOOR = 194767, + GO_UNIVERSE_FLOOR_ARCHIVUM = 194715, + GO_UNIVERSE_FLOOR_CELESTIAL = 194716, + GO_AZEROTH_GLOBE = 194148, + // the keepers + // hodir GO_HODIR_EXIT = 194634, GO_HODIR_ICE_WALL = 194441, GO_HODIR_ENTER = 194442, - // Mimiron - G0_MIMIRON_BUTTON = 194739, // Used to start hard mode + // mimiron + GO_MIMIRON_TRAM = 194675, + GO_MIMIRON_BUTTON = 194739, GO_MIMIRON_DOOR_1 = 194774, GO_MIMIRON_DOOR_2 = 194775, GO_MIMIRON_DOOR_3 = 194776, - GO_MIMIRON_TEL1 = 194741, // Used to summon mobs in phase 3 + GO_MIMIRON_TEL1 = 194741, GO_MIMIRON_TEL2 = 194742, GO_MIMIRON_TEL3 = 194743, GO_MIMIRON_TEL4 = 194744, @@ -180,146 +183,31 @@ enum GO_MIMIRON_TEL7 = 194747, GO_MIMIRON_TEL8 = 194748, GO_MIMIRON_TEL9 = 194745, - GO_MIMIRON_ELEVATOR = 194749, // Central elevator + GO_MIMIRON_ELEVATOR = 194749, // Thorim - GO_DARK_IRON_PORTCULIS = 194560, // Door from the arena to the hallway - GO_RUNED_STONE_DOOR = 194557, // Door after the runic colossus - GO_THORIM_STONE_DOOR = 194558, // Door after the ancient rune giant - GO_LIGHTNING_DOOR = 194905, // Arena exit door - GO_LIGHTNING_FIELD = 194559, // For the platform animation - GO_DOOR_LEVER = 194264, // In front of the door - - // Descent to madness - GO_ANCIENT_GATE = 194255, // Door upstairs before vezax, opens when all keepers are freed - GO_VEZAX_GATE = 194750, // Door after vezax - GO_YOGG_GATE = 194773, // Yogg-Saron chamber door - GO_BRAIN_DOOR1 = 194635, // Brain chamber doors + GO_DARK_IRON_PORTCULIS = 194560, + GO_RUNED_STONE_DOOR = 194557, + GO_THORIM_STONE_DOOR = 194558, + GO_LIGHTNING_DOOR = 194905, + GO_LIGHTNING_FIELD = 194559, + GO_DOOR_LEVER = 194264, + //Yogg + GO_ANCIENT_GATE = 194255, + GO_VEZAX_GATE = 194750, + GO_YOGG_GATE = 194773, + GO_BRAIN_DOOR1 = 194635, GO_BRAIN_DOOR2 = 194636, GO_BRAIN_DOOR3 = 194637, - // World state used for algalon timer - WORLD_STATE_TIMER = 4132, - WORLD_STATE_TIMER_COUNT = 4131, -}; - -class MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance -{ - public: - instance_ulduar(Map* pMap); - ~instance_ulduar() {} - - void Initialize(); - bool IsEncounterInProgress() const; - - void OnCreatureCreate(Creature* pCreature); - void OnObjectCreate(GameObject* pGo); - - void SetData(uint32 uiType, uint32 uiData); - uint32 GetData(uint32 uiType); - uint64 GetData64(uint32 uiData); - - const char* Save() { return strInstData.c_str(); } - void Load(const char* chrIn); - - // Dummy, leave till correct solution for hardmode found - bool CheckConditionCriteriaMeet(Player const* pSource, uint32 uiMapId, uint32 uiInstanceConditionId); - - void DoOpenMadnessDoorIfCan(); - Player* GetPlayerInMap(); - void SpawnFriendlyKeeper(uint32 uiWho); - - protected: - std::string strInstData; - uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint32 m_auiHardBoss[HARD_MODE_ENCOUNTER]; - uint32 m_auiUlduarKeepers[KEEPER_ENCOUNTER]; - uint32 m_auiUlduarTeleporters[TELEPORTER_ENCOUNTER]; - - // Creatures - uint64 m_uiLeviathanGUID; - uint64 m_uiIgnisGUID; - uint64 m_uiRazorscaleGUID; - uint64 m_uiCommanderGUID; - uint64 m_uiXT002GUID; - uint64 m_uiBrundirGUID; - uint64 m_uiMolgeimGUID; - uint64 m_uiSteelbreakerGUID; - uint64 m_uiKologarnGUID; - uint64 m_uiAuriayaGUID; - uint64 m_uiMimironGUID; - uint64 m_uiHodirGUID; - uint64 m_uiThorimGUID; - uint64 m_uiFreyaGUID; - uint64 m_uiVezaxGUID; - uint64 m_uiYoggSaronGUID; - uint64 m_uiAlgalonGUID; - uint64 m_uiRightArmGUID; - uint64 m_uiLeftArmGUID; - uint64 m_uiFeralDefenderGUID; - uint64 m_uiElderBrightleafGUID; - uint64 m_uiElderStonebarkGUID; - uint64 m_uiElderIronbrachGUID; - uint64 m_uiSaroniteAnimusGUID; - uint64 m_uiRunicColossusGUID; - uint64 m_uiRuneGiantGUID; - uint64 m_uiJormungarGUID; - uint64 m_uiLeviathanMkGUID; - uint64 m_uiSaraGUID; - uint64 m_uiYoggBrainGUID; + ACHIEV_IRON_COUNCIL = 2888, + ACHIEV_IRON_COUNCIL_H = 2889, - // Doors & Objects - // The siege - uint64 m_uiShieldWallGUID; - uint64 m_uiLeviathanGateGUID; - uint64 m_uiXT002GateGUID; - uint64 m_uiBrokenHarpoonGUID; - // Archivum - uint64 m_uiIronCouncilDoorGUID; - uint64 m_uiArchivumDoorGUID; - uint64 m_uiArchivumConsoleGUID; - uint64 m_uiUniverseFloorArchivumGUID; - // Celestial planetarium - uint64 m_uiCelestialDoorGUID; - uint64 m_uiCelestialConsoleGUID; - uint64 m_uiUniverseFloorCelestialGUID; - uint64 m_uiAzerothGlobeGUID; - // Kologarn - uint64 m_uiShatteredHallsDoorGUID; - uint64 m_uiKologarnBridgeGUID; - // Hodir - uint64 m_uiHodirEnterDoorGUID; - uint64 m_uiHodirWallGUID; - uint64 m_uiHodirExitDoorGUID; - // Mimiron - uint64 m_uiMimironButtonGUID; - uint64 m_uiMimironDoor1GUID; - uint64 m_uiMimironDoor2GUID; - uint64 m_uiMimironDoor3GUID; - uint64 m_uiMimironElevatorGUID; - uint64 m_auiMimironTelGUID[9]; - // Thorim - uint64 m_uiArenaEnterDoorGUID; - uint64 m_uiArenaExitDoorGUID; - uint64 m_uiHallwayDoorGUID; - uint64 m_uiThorimEnterDoorGUID; - uint64 m_uiThorimLeverGUID; - // Prison - uint64 m_uiAncientGateGUID; - uint64 m_uiVezaxGateGUID; - uint64 m_uiYoggGateGUID; - uint64 m_uiBrainDoor1GUID; - uint64 m_uiBrainDoor2GUID; - uint64 m_uiBrainDoor3GUID; + ACHIEV_KEEPERS = 2890, + ACHIEV_KEEPERS_H = 2891, - // Chests - uint64 m_uiKologarnLootGUID; - uint64 m_uiHodirLootGUID; - uint64 m_uiHodirRareLootGUID; - uint64 m_uiThorimLootGUID; - uint64 m_uiThorimRareLootGUID; - uint64 m_uiMimironLootGUID; - uint64 m_uiMimironHardLootGUID; - uint64 m_uiAlagonLootGUID; + ACHIEV_CELESTIAL_DEFENDER = 3259, // realm first algalon + SPELL_ALGALON_ACHIEV_TRIGG = 65184, + ACHIEV_DEATHS_DEMISE = 3117, // realm first yogg }; #endif diff --git a/scripts/northrend/ulduar/ulduar/ulduar_teleport.cpp b/scripts/northrend/ulduar/ulduar/ulduar_teleport.cpp new file mode 100644 index 000000000..d7f045dd2 --- /dev/null +++ b/scripts/northrend/ulduar/ulduar/ulduar_teleport.cpp @@ -0,0 +1,119 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: ulduar_teleport +SD%Complete: 95% +SDComment: by /dev/rsa +SDCategory: Ulduar instance +EndScriptData */ + +#include "precompiled.h" +#include "ulduar.h" + +enum +{ + PORTALS_COUNT = 9, + TELEPORT_GOSSIP_MESSAGE = 14424, + + // spells + SPELL_TELEPORT_BASE_CAMP = 64014, + SPELL_TELEPORT_GROUNDS = 64032, + SPELL_TELEPORT_FORGE = 64028, + SPELL_TELEPORT_SCRAPYARD = 64031, + SPELL_TELEPORT_ANTECHAMBER = 64030, + SPELL_TELEPORT_WALKWAY = 64029, + SPELL_TELEPORT_CONSERVATORY = 64024, + SPELL_TELEPORT_SPARK = 65061, + SPELL_TELEPORT_PRISON = 65042, +}; + +struct t_Locations +{ + int textNum; + uint32 map_num; + float x, y, z, o; + uint32 spellID; + bool state; + bool active; + uint32 encounter; +}; + +static t_Locations PortalLoc[]= +{ +{-3050001,603, -706.122f, -92.6024f, 430.176f, 4.19f, SPELL_TELEPORT_BASE_CAMP, true,true, TYPE_LEVIATHAN}, // base camp +{-3050002,603, 131.248f, -35.3802f, 410.104f, 0, SPELL_TELEPORT_GROUNDS, true,true, TYPE_LEVIATHAN_TP}, // formation ground +{-3050003,603, 553.233f, -12.3247f, 409.979f, 0, SPELL_TELEPORT_FORGE, false,true,TYPE_LEVIATHAN}, // +{-3050004,603, 926.292f, -11.4635f, 418.895f, 3.19f, SPELL_TELEPORT_SCRAPYARD, false,true,TYPE_XT002_TP}, // +{-3050005,603, 1498.09f, -24.246f, 421.267f, 0, SPELL_TELEPORT_ANTECHAMBER, false,true,TYPE_XT002}, // +{-3050006,603, 1859.45f, -24.1f, 449.2f, 0, SPELL_TELEPORT_WALKWAY, false,true,TYPE_KOLOGARN}, // +{-3050007,603, 2086.27f, -24.3134f, 421.539f, 0, SPELL_TELEPORT_CONSERVATORY,false,true,TYPE_AURIAYA}, // +{-3050008,603, 2517.3979f, 2568.89f, 412.99f, 6.17f, SPELL_TELEPORT_SPARK, false,true,TYPE_MIMIRON_TP}, // +{-3050009,603, 1854.782f, -11.3819f, 335.27f, 5.86f, SPELL_TELEPORT_PRISON, false,true,TYPE_VEZAX}, // +}; + + +bool GOGossipSelect_go_ulduar_teleporter(Player *pPlayer, GameObject* pGo, uint32 sender, uint32 action) +{ + int32 damage = 0; + if(sender != GOSSIP_SENDER_MAIN) return false; + + if(!pPlayer->getAttackers().empty()) return false; + + if(action >= 0 && action <= PORTALS_COUNT) + pPlayer->TeleportTo(PortalLoc[action].map_num, PortalLoc[action].x, PortalLoc[action].y, PortalLoc[action].z, PortalLoc[action].o); + if (PortalLoc[action].spellID != 0 ) + if (SpellEntry const* spell = (SpellEntry *)GetSpellStore()->LookupEntry(PortalLoc[action].spellID)) + { + SpellAuraHolder *holder = CreateSpellAuraHolder(spell, pPlayer, pPlayer); + Aura *aura = CreateAura(spell, EFFECT_INDEX_2, NULL, holder, pPlayer); + holder->AddAura(aura, EFFECT_INDEX_2); + pPlayer->AddSpellAuraHolder(holder); + } + + pPlayer->CLOSE_GOSSIP_MENU(); + return true; +} + +bool GOGossipHello_go_ulduar_teleporter(Player *pPlayer, GameObject* pGo) +{ + ScriptedInstance *pInstance = (ScriptedInstance *) pGo->GetInstanceData(); + + if (!pInstance || !pPlayer) return false; + if (pPlayer->isInCombat()) return true; + + for(uint8 i = 0; i < PORTALS_COUNT; i++) { + if ((PortalLoc[i].active == true && + (PortalLoc[i].state == true || + pInstance->GetData(PortalLoc[i].encounter) == DONE || + pInstance->GetData(PortalLoc[i].encounter) == IN_PROGRESS)) + || pPlayer->isGameMaster()) + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_TAXI, PortalLoc[i].textNum, GOSSIP_SENDER_MAIN, i); + }; + pPlayer->SEND_GOSSIP_MENU(TELEPORT_GOSSIP_MESSAGE, pGo->GetGUID()); + return true; +} + +void AddSC_ulduar_teleport() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "go_ulduar_teleporter"; + newscript->pGossipHelloGO = &GOGossipHello_go_ulduar_teleporter; + newscript->pGossipSelectGO = &GOGossipSelect_go_ulduar_teleporter; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar.cpp b/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar.cpp index b9c7b24ae..a57b89afa 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp b/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp index d3cad4f63..3d12b552c 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -45,7 +45,6 @@ enum SPELL_DECREPIFY_H = 59397, SPELL_BONE_ARMOR = 59386, // casted on boss, heroic only - NPC_FROST_TOMB = 23965, NPC_VRYKUL_SKELETON = 23970 }; @@ -59,7 +58,7 @@ static float fAddPosition[4] = {163.5727f, 252.1900f, 42.8684f, 5.57052f}; struct MANGOS_DLL_DECL mob_vrykul_skeletonAI : public ScriptedAI { - mob_vrykul_skeletonAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_vrykul_skeletonAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); m_bIsRegularMode = m_creature->GetMap()->IsRegularDifficulty(); @@ -69,7 +68,6 @@ struct MANGOS_DLL_DECL mob_vrykul_skeletonAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; - Creature* m_pKeleseth; uint32 m_uiCastTimer; uint32 m_uiReviveTimer; @@ -77,11 +75,6 @@ struct MANGOS_DLL_DECL mob_vrykul_skeletonAI : public ScriptedAI { m_uiReviveTimer = 0; m_uiCastTimer = urand(5000, 10000); // taken out of thin air - - if (!m_pInstance) - return; - - m_pKeleseth = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KELESETH)); } void MoveInLineOfSight(Unit* pWho) @@ -115,7 +108,7 @@ struct MANGOS_DLL_DECL mob_vrykul_skeletonAI : public ScriptedAI void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) { - if (!m_pKeleseth || !m_pKeleseth->isAlive()) + if (!m_pInstance || m_pInstance->GetData(TYPE_KELESETH) != IN_PROGRESS) { uiDamage = m_creature->GetHealth(); return; @@ -164,8 +157,9 @@ struct MANGOS_DLL_DECL mob_vrykul_skeletonAI : public ScriptedAI { if (urand(0, 3)) DoCastSpellIfCan(m_creature->getVictim(), SPELL_DECREPIFY_H); - else if (m_pKeleseth && m_pKeleseth->isAlive()) - DoCastSpellIfCan(m_pKeleseth, SPELL_BONE_ARMOR); + else if (m_pInstance && m_pInstance->GetData(TYPE_KELESETH) == IN_PROGRESS) + if (Creature* pKeleseth = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_KELESETH))) + DoCastSpellIfCan(pKeleseth, SPELL_BONE_ARMOR); } m_uiCastTimer = urand(5000, 15000); @@ -198,11 +192,11 @@ struct MANGOS_DLL_DECL boss_kelesethAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; - uint32 m_uiFrostTombTimer; + uint32 m_uiFrostTombTimer; uint32 m_uiSummonTimer; uint32 m_uiShadowboltTimer; - void Reset() + void Reset() { // timers need confirmation m_uiFrostTombTimer = 20000; @@ -227,12 +221,15 @@ struct MANGOS_DLL_DECL boss_kelesethAI : public ScriptedAI void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_KELESETH, IN_PROGRESS); } void SummonAdds() { for (uint8 i=0; i<4; ++i) - m_creature->SummonCreature(NPC_VRYKUL_SKELETON, fAddPosition[0]+rand()%7, fAddPosition[1]+rand()%7, fAddPosition[2], fAddPosition[3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, MINUTE*IN_MILLISECONDS); + m_creature->SummonCreature(NPC_VRYKUL_SKELETON, fAddPosition[0]+rand()%7, fAddPosition[1]+rand()%7, fAddPosition[2], fAddPosition[3], TEMPSUMMON_DEAD_DESPAWN, 0); } void DespawnAdds() @@ -257,6 +254,15 @@ struct MANGOS_DLL_DECL boss_kelesethAI : public ScriptedAI void JustDied(Unit* pKiller) { DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_KELESETH, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_KELESETH, FAIL); } void KilledUnit(Unit* pVictim) @@ -322,15 +328,15 @@ CreatureAI* GetAI_boss_keleseth(Creature* pCreature) void AddSC_boss_keleseth() { - Script* newscript; + Script* pNewScript; - newscript = new Script; - newscript->Name = "boss_keleseth"; - newscript->GetAI = &GetAI_boss_keleseth; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "boss_keleseth"; + pNewScript->GetAI = &GetAI_boss_keleseth; + pNewScript->RegisterSelf(); - newscript = new Script; - newscript->Name = "mob_vrykul_skeleton"; - newscript->GetAI = &GetAI_mob_vrykul_skeleton; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "mob_vrykul_skeleton"; + pNewScript->GetAI = &GetAI_mob_vrykul_skeleton; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_and_dalronn.cpp b/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_and_dalronn.cpp index 095e52f98..5d739590c 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_and_dalronn.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_and_dalronn.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp b/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp index 0f9f9ee5f..2fea1f1d3 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,169 +24,174 @@ EndScriptData */ #include "precompiled.h" #include "utgarde_keep.h" -struct MANGOS_DLL_DECL instance_utgarde_keep : public ScriptedInstance +instance_utgarde_keep::instance_utgarde_keep(Map* pMap) : ScriptedInstance(pMap), + m_uiKelesethGUID(0), + m_uiSkarvaldGUID(0), + m_uiDalronnGUID(0), + + m_uiBellow1GUID(0), + m_uiBellow2GUID(0), + m_uiBellow3GUID(0), + m_uiForgeFire1GUID(0), + m_uiForgeFire2GUID(0), + m_uiForgeFire3GUID(0), + m_bKelesethAchievFailed(false) { - instance_utgarde_keep(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - uint64 m_uiKelesethGUID; - uint64 m_uiSkarvaldGUID; - uint64 m_uiDalronnGUID; + Initialize(); +} - uint64 m_uiBellow1GUID; - uint64 m_uiBellow2GUID; - uint64 m_uiBellow3GUID; - uint64 m_uiForgeFire1GUID; - uint64 m_uiForgeFire2GUID; - uint64 m_uiForgeFire3GUID; +void instance_utgarde_keep::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - void Initialize() +void instance_utgarde_keep::OnCreatureCreate(Creature* pCreature) +{ + switch(pCreature->GetEntry()) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiKelesethGUID = 0; - m_uiSkarvaldGUID = 0; - m_uiDalronnGUID = 0; - - m_uiBellow1GUID = 0; - m_uiBellow2GUID = 0; - m_uiBellow3GUID = 0; - m_uiForgeFire1GUID = 0; - m_uiForgeFire2GUID = 0; - m_uiForgeFire3GUID = 0; + case NPC_KELESETH: m_uiKelesethGUID = pCreature->GetGUID(); break; + case NPC_SKARVALD: m_uiSkarvaldGUID = pCreature->GetGUID(); break; + case NPC_DALRONN: m_uiDalronnGUID = pCreature->GetGUID(); break; } +} - void OnCreatureCreate(Creature* pCreature) +void instance_utgarde_keep::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) { - switch(pCreature->GetEntry()) - { - case NPC_KELESETH: m_uiKelesethGUID = pCreature->GetGUID(); break; - case NPC_SKARVALD: m_uiSkarvaldGUID = pCreature->GetGUID(); break; - case NPC_DALRONN: m_uiDalronnGUID = pCreature->GetGUID(); break; - } + case GO_BELLOW_1: + m_uiBellow1GUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_BELLOW_1] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_BELLOW_2: + m_uiBellow2GUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_BELLOW_2] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_BELLOW_3: + m_uiBellow3GUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_BELLOW_3] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_FORGEFIRE_1: + m_uiForgeFire1GUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_BELLOW_1] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_FORGEFIRE_2: + m_uiForgeFire2GUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_BELLOW_2] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_FORGEFIRE_3: + m_uiForgeFire3GUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_BELLOW_3] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; } +} - void OnObjectCreate(GameObject* pGo) +void instance_utgarde_keep::OnCreatureDeath(Creature* pCreature) +{ + if (pCreature->GetEntry() == NPC_FROST_TOMB) + m_bKelesethAchievFailed = true; +} + +void instance_utgarde_keep::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - switch(pGo->GetEntry()) - { - case GO_BELLOW_1: - m_uiBellow1GUID = pGo->GetGUID(); - if (m_auiEncounter[0] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_BELLOW_2: - m_uiBellow2GUID = pGo->GetGUID(); - if (m_auiEncounter[1] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_BELLOW_3: - m_uiBellow3GUID = pGo->GetGUID(); - if (m_auiEncounter[2] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_FORGEFIRE_1: - m_uiForgeFire1GUID = pGo->GetGUID(); - if (m_auiEncounter[0] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_FORGEFIRE_2: - m_uiForgeFire2GUID = pGo->GetGUID(); - if (m_auiEncounter[1] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case GO_FORGEFIRE_3: - m_uiForgeFire3GUID = pGo->GetGUID(); - if (m_auiEncounter[2] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - } + case TYPE_KELESETH: + if (uiData == IN_PROGRESS) + m_bKelesethAchievFailed = false; + m_auiEncounter[uiType] = uiData; + break; + case TYPE_SKARVALD_DALRONN: + case TYPE_INGVAR: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_BELLOW_1: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_BELLOW_2: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_BELLOW_3: + m_auiEncounter[uiType] = uiData; + break; } - void SetData(uint32 uiType, uint32 uiData) + if (uiData == DONE) { - switch(uiType) - { - case GO_BELLOW_1: - m_auiEncounter[0] = uiData; - break; - case GO_BELLOW_2: - m_auiEncounter[1] = uiData; - break; - case GO_BELLOW_3: - m_auiEncounter[2] = uiData; - break; - } - - if (uiData == DONE) - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2]; - - strInstData = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } + 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; } +} - const char* Save() +uint32 instance_utgarde_keep::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + + return 0; +} + +uint64 instance_utgarde_keep::GetData64(uint32 uiData) +{ + switch(uiData) { - return strInstData.c_str(); + case NPC_KELESETH: return m_uiKelesethGUID; + case NPC_SKARVALD: return m_uiSkarvaldGUID; + case NPC_DALRONN: return m_uiDalronnGUID; + case GO_BELLOW_1: return m_uiBellow1GUID; + case GO_BELLOW_2: return m_uiBellow2GUID; + case GO_BELLOW_3: return m_uiBellow3GUID; + case GO_FORGEFIRE_1: return m_uiForgeFire1GUID; + case GO_FORGEFIRE_2: return m_uiForgeFire2GUID; + case GO_FORGEFIRE_3: return m_uiForgeFire3GUID; + default: + return 0; } +} - uint64 GetData64(uint32 uiData) +void instance_utgarde_keep::Load(const char* chrIn) +{ + if (!chrIn) { - switch(uiData) - { - case NPC_KELESETH: - return m_uiKelesethGUID; - case NPC_SKARVALD: - return m_uiSkarvaldGUID; - case NPC_DALRONN: - return m_uiDalronnGUID; - case GO_BELLOW_1: - return m_uiBellow1GUID; - case GO_BELLOW_2: - return m_uiBellow2GUID; - case GO_BELLOW_3: - return m_uiBellow3GUID; - case GO_FORGEFIRE_1: - return m_uiForgeFire1GUID; - case GO_FORGEFIRE_2: - return m_uiForgeFire2GUID; - case GO_FORGEFIRE_3: - return m_uiForgeFire3GUID; - } - return 0; + OUT_LOAD_INST_DATA_FAIL; + return; } - void Load(const char* in) - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } + OUT_LOAD_INST_DATA(chrIn); - OUT_LOAD_INST_DATA(in); + std::istringstream loadStream(chrIn); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4] >> m_auiEncounter[5]; - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } + OUT_LOAD_INST_DATA_COMPLETE; +} - OUT_LOAD_INST_DATA_COMPLETE; - } -}; +bool instance_utgarde_keep::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/) +{ + if (uiCriteriaId == ACHIEV_CRIT_ON_THE_ROCKS) + return !m_bKelesethAchievFailed; + + return false; +} InstanceData* GetInstanceData_instance_utgarde_keep(Map* pMap) { @@ -195,9 +200,10 @@ InstanceData* GetInstanceData_instance_utgarde_keep(Map* pMap) void AddSC_instance_utgarde_keep() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_utgarde_keep"; - newscript->GetInstanceData = GetInstanceData_instance_utgarde_keep; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_utgarde_keep"; + pNewScript->GetInstanceData = GetInstanceData_instance_utgarde_keep; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp b/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp index d827506d0..9407b0c28 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -95,9 +95,9 @@ struct MANGOS_DLL_DECL mob_dragonflayer_forge_masterAI : public ScriptedAI switch(lGOList.front()->GetEntry()) { - case GO_BELLOW_1: uiGOFire = GO_FORGEFIRE_1; break; - case GO_BELLOW_2: uiGOFire = GO_FORGEFIRE_2; break; - case GO_BELLOW_3: uiGOFire = GO_FORGEFIRE_3; break; + case GO_BELLOW_1: uiGOFire = GO_FORGEFIRE_1; m_uiForgeEncounterId = TYPE_BELLOW_1; break; + case GO_BELLOW_2: uiGOFire = GO_FORGEFIRE_2; m_uiForgeEncounterId = TYPE_BELLOW_2; break; + case GO_BELLOW_3: uiGOFire = GO_FORGEFIRE_3; m_uiForgeEncounterId = TYPE_BELLOW_3; break; } if (GameObject* pGOTemp = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(uiGOFire))) @@ -107,8 +107,6 @@ struct MANGOS_DLL_DECL mob_dragonflayer_forge_masterAI : public ScriptedAI else if (pGOTemp->getLootState() == GO_ACTIVATED) pGOTemp->ResetDoorOrButton(); } - - m_uiForgeEncounterId = lGOList.front()->GetEntry(); } } diff --git a/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h b/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h index fb91b7e4b..dec46a9d7 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h +++ b/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,19 +7,69 @@ enum { - MAX_ENCOUNTER = 3, + MAX_ENCOUNTER = 6, + + TYPE_KELESETH = 0, + TYPE_SKARVALD_DALRONN = 1, + TYPE_INGVAR = 2, + TYPE_BELLOW_1 = 3, + TYPE_BELLOW_2 = 4, + TYPE_BELLOW_3 = 5, - //also using these as identifier for Set/GetData(), unlike normal naming NPC_KELESETH = 23953, NPC_SKARVALD = 24200, NPC_DALRONN = 24201, + NPC_FROST_TOMB = 23965, + GO_BELLOW_1 = 186688, GO_BELLOW_2 = 186689, GO_BELLOW_3 = 186690, GO_FORGEFIRE_1 = 186692, GO_FORGEFIRE_2 = 186693, - GO_FORGEFIRE_3 = 186691 + GO_FORGEFIRE_3 = 186691, + + ACHIEV_CRIT_ON_THE_ROCKS = 7231, +}; + +class MANGOS_DLL_DECL instance_utgarde_keep : public ScriptedInstance +{ + public: + instance_utgarde_keep(Map* pMap); + ~instance_utgarde_keep() {} + + void Initialize(); + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + + void OnCreatureDeath(Creature* pCreature); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + bool CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/); + + protected: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiKelesethGUID; + uint64 m_uiSkarvaldGUID; + uint64 m_uiDalronnGUID; + + uint64 m_uiBellow1GUID; + uint64 m_uiBellow2GUID; + uint64 m_uiBellow3GUID; + uint64 m_uiForgeFire1GUID; + uint64 m_uiForgeFire2GUID; + uint64 m_uiForgeFire3GUID; + + bool m_bKelesethAchievFailed; }; #endif diff --git a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_gortok.cpp b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_gortok.cpp index 178782a3b..62207d62e 100644 --- a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_gortok.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_gortok.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp index 1d084c55d..9fe4c3ebb 100644 --- a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp index 6354f732c..4f9b1f6cc 100644 --- a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp index 30613e2b9..d2576d39c 100644 --- a/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_utgarde_pinnacle.cpp b/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_utgarde_pinnacle.cpp index 937d472d1..60dd9145a 100644 --- a/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_utgarde_pinnacle.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_utgarde_pinnacle.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h b/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h index 5ab6aa410..0b544bfb1 100644 --- a/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h +++ b/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/northrend/vault_of_archavon/boss_archavon.cpp b/scripts/northrend/vault_of_archavon/boss_archavon.cpp new file mode 100644 index 000000000..e5400f46a --- /dev/null +++ b/scripts/northrend/vault_of_archavon/boss_archavon.cpp @@ -0,0 +1,274 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Boss_Archavon_The_Stone_Watcher +SD%Complete: 0% +SDComment: +SDCategory: Vault of Archavon +EndScriptData */ + +#include "precompiled.h" +#include "vault_of_archavon.h" + +enum +{ + SPELL_ROCK_SHARDS_LEFT_N = 58695, + SPELL_ROCK_SHARDS_LEFT_H = 60883, + SPELL_ROCK_SHARDS_RIGHT_N = 58696, + SPELL_ROCK_SHARDS_RIGHT_H = 60884, + SPELL_CRUSHING_LEAP_N = 58963, + SPELL_CRUSHING_LEAP_H = 60895, + SPELL_STOMP_N = 58663, + SPELL_STOMP_H = 60880, + SPELL_IMPALE_DMG_N = 58666, + SPELL_IMPALE_DMG_H = 60882, + SPELL_IMPALE_STUN = 50839, + SPELL_BERSERK = 47008 +}; + +struct MANGOS_DLL_DECL boss_archavonAI : public ScriptedAI +{ + boss_archavonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_fDefaultMoveSpeed = pCreature->GetSpeedRate(MOVE_RUN); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + float m_fDefaultMoveSpeed; + uint32 m_uiEvadeCheckCooldown; + + uint32 m_uiBerserkTimer; + uint32 m_uiRockShardsTimer; + bool m_bRockShardsInProgress; + uint32 m_uiRockShardsProgressTimer; + uint32 m_uiRockShardTimer; + bool m_bRLRockShard; + Unit* m_pRockShardsTarget; + uint32 m_uiCrushingLeapTimer; + Unit* m_pCrushingLeapTarget; + bool m_bCrushingLeapInProgress; + uint32 m_uiCrushingLeapSecureTimer; + uint32 m_uiStompTimer; + uint32 m_uiImpaleAfterStompTimer; + bool m_bImpaleInProgress; + + void Reset() + { + m_uiEvadeCheckCooldown = 2000; + m_creature->SetSpeedRate(MOVE_RUN, m_fDefaultMoveSpeed); + m_uiBerserkTimer = 300000; + m_uiRockShardsTimer = 15000; + m_bRockShardsInProgress = false; + m_uiRockShardsProgressTimer = 3000; + m_uiRockShardTimer = 0; + m_bRLRockShard = true; + m_pRockShardsTarget = NULL; + m_uiCrushingLeapTimer = 30000; + m_pCrushingLeapTarget = NULL; + m_bCrushingLeapInProgress = false; + m_uiCrushingLeapSecureTimer = 2000; + m_uiStompTimer = 45000; + m_uiImpaleAfterStompTimer = 1000; + m_bImpaleInProgress = false; + + if(m_pInstance) + m_pInstance->SetData(TYPE_ARCHAVON, NOT_STARTED); + } + + void Aggro(Unit *pWho) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_ARCHAVON, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if(m_pInstance) + m_pInstance->SetData(TYPE_ARCHAVON, DONE); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEvadeCheckCooldown < uiDiff) + { + if (m_creature->GetDistance2d(140.34f, -102.34f) > 80.0f) + EnterEvadeMode(); + m_uiEvadeCheckCooldown = 2000; + } + else + m_uiEvadeCheckCooldown -= uiDiff; + + if (m_bImpaleInProgress) + { + if (m_uiImpaleAfterStompTimer < uiDiff) + { + if (Unit* pTarget = m_creature->getVictim()) + { + DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_IMPALE_DMG_N : SPELL_IMPALE_DMG_H); + pTarget->CastSpell(pTarget, SPELL_IMPALE_STUN, true); + } + m_bImpaleInProgress = false; + } + else + { + m_uiImpaleAfterStompTimer -= uiDiff; + return; + } + } + + if (m_bCrushingLeapInProgress) + { + if (m_pCrushingLeapTarget) + { + if (m_pCrushingLeapTarget->isDead() || !m_pCrushingLeapTarget->IsInWorld() && !m_pCrushingLeapTarget->IsInMap(m_creature)) + { + m_bCrushingLeapInProgress = false; + return; + } + } + else + { + m_bCrushingLeapInProgress = false; + return; + } + if ((m_uiCrushingLeapSecureTimer < uiDiff) || (m_pCrushingLeapTarget && m_creature->IsWithinDist(m_pCrushingLeapTarget, 5.0f))) + { + m_creature->getThreatManager().addThreat(m_pCrushingLeapTarget, -100000000.0f); + m_creature->SetSpeedRate(MOVE_RUN, m_fDefaultMoveSpeed); + DoCastSpellIfCan(m_pCrushingLeapTarget, m_bIsRegularMode ? SPELL_CRUSHING_LEAP_N : SPELL_CRUSHING_LEAP_H, true); + m_bCrushingLeapInProgress = false; + } + else + m_uiCrushingLeapSecureTimer -= uiDiff; + + return; + } + + if (m_bRockShardsInProgress) + { + if (m_uiRockShardsProgressTimer < uiDiff) + { + m_bRockShardsInProgress = false; + if (m_pRockShardsTarget) + m_creature->getThreatManager().addThreat(m_pRockShardsTarget, -100000000.0f); + return; + } + else + m_uiRockShardsProgressTimer -= uiDiff; + + if (m_uiRockShardTimer < uiDiff) + { + if (m_pRockShardsTarget && m_pRockShardsTarget->isAlive()) + { + DoCast(m_pRockShardsTarget, m_bIsRegularMode ? (m_bRLRockShard ? SPELL_ROCK_SHARDS_LEFT_N : SPELL_ROCK_SHARDS_RIGHT_N) : (m_bRLRockShard ? SPELL_ROCK_SHARDS_LEFT_H : SPELL_ROCK_SHARDS_RIGHT_H)); + m_bRLRockShard = !m_bRLRockShard; + } + m_uiRockShardTimer = 100; + } + else + m_uiRockShardsTimer -= uiDiff; + + return; + } + + if (m_uiRockShardsTimer < uiDiff) + { + m_bRockShardsInProgress = true; + m_uiRockShardsProgressTimer = 3000; + m_bRLRockShard = true; + m_pRockShardsTarget = NULL; + if (m_pRockShardsTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_creature->getThreatManager().addThreat(m_pRockShardsTarget, 100000000.0f); + m_uiRockShardsTimer = 15000+rand()%15000; + return; + } + else + m_uiRockShardsTimer -= uiDiff; + + if (m_uiCrushingLeapTimer < uiDiff) + { + ThreatList const& tList = m_creature->getThreatManager().getThreatList(); + std::list lTargets; + for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) + { + Unit *pTemp = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && !m_creature->IsWithinDist(pTemp, 10.0f) && m_creature->IsWithinDist(pTemp, 80.0f)) + lTargets.push_back(pTemp); + } + m_pCrushingLeapTarget = NULL; + if (!lTargets.empty()) + { + std::list::iterator pTarget = lTargets.begin(); + advance(pTarget, (rand() % lTargets.size())); + m_pCrushingLeapTarget = *pTarget; + if (m_pCrushingLeapTarget) + { + m_creature->MonsterSay(m_pCrushingLeapTarget->GetName(), LANG_UNIVERSAL); + m_creature->getThreatManager().addThreat(m_pCrushingLeapTarget, 100000000.0f); + m_creature->SetSpeedRate(MOVE_RUN, m_fDefaultMoveSpeed*10.0f); + m_bCrushingLeapInProgress = true; + m_uiCrushingLeapSecureTimer = 2000; + } + } + m_uiCrushingLeapTimer = 30000+rand()%15000; + return; + } + else + m_uiCrushingLeapTimer -= uiDiff; + + if (m_uiStompTimer < uiDiff) + { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_STOMP_N : SPELL_STOMP_H); + m_uiImpaleAfterStompTimer = 1000; + m_bImpaleInProgress = true; + m_uiStompTimer = 45000+rand()%15000; + } + else + m_uiStompTimer -= uiDiff; + + if (m_uiBerserkTimer < uiDiff) + { + DoCastSpellIfCan(m_creature, SPELL_BERSERK); + m_uiBerserkTimer = 60000; + } + else + m_uiBerserkTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_archavon(Creature *pCreature) +{ + return new boss_archavonAI (pCreature); +}; + +void AddSC_boss_archavon() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_archavon"; + newscript->GetAI = &GetAI_boss_archavon; + newscript->RegisterSelf(); +}; diff --git a/scripts/northrend/vault_of_archavon/boss_emalon.cpp b/scripts/northrend/vault_of_archavon/boss_emalon.cpp new file mode 100644 index 000000000..ce354d8b1 --- /dev/null +++ b/scripts/northrend/vault_of_archavon/boss_emalon.cpp @@ -0,0 +1,445 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Boss_Emalon_The_Storm_Watcher +SD%Complete: 0% +SDComment: +SDCategory: Vault of Archavon +EndScriptData */ + +#include "precompiled.h" +#include "vault_of_archavon.h" + +enum +{ + // Emalon spells + SPELL_CHAIN_LIGHTNING_N = 64213, + SPELL_CHAIN_LIGHTNING_H = 64215, + SPELL_LIGHTNING_NOVA_N = 64216, + SPELL_LIGHTNING_NOVA_H = 65279, + SPELL_OVERCHARGE = 64379, //This spell is used by Time Warder, and temporary by Emalon, because 64218 is bugged + SPELL_BERSERK = 26662, + + // Tempest Minion spells + SPELL_SHOCK = 64363, + SPELL_OVERCHARGED_BLAST = 64219, + SPELL_OVERCHARGED = 64217 +}; + +/*###### +## npc_tempest_minion +######*/ + +struct MANGOS_DLL_DECL npc_tempest_minionAI : public ScriptedAI +{ + npc_tempest_minionAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_fDefaultX = m_creature->GetPositionX(); + m_fDefaultY = m_creature->GetPositionY(); + m_fDefaultZ = m_creature->GetPositionZ(); + m_fDefaultO = m_creature->GetOrientation(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_uiEvadeCheckCooldown; + + uint32 m_uiShockTimer; + uint32 m_uiRespawnTimer; + uint32 m_uiOverchargedStacksCheckTimer; + bool m_bDead; + bool m_bTimeToDie; + float m_fDefaultX; + float m_fDefaultY; + float m_fDefaultZ; + float m_fDefaultO; + + void Init() + { + m_uiEvadeCheckCooldown = 2000; + m_uiShockTimer = 8000+rand()%4000; + m_bDead = false; + m_bTimeToDie = false; + m_uiRespawnTimer = 4000; + m_uiOverchargedStacksCheckTimer = 2000; + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->SetVisibility(VISIBILITY_ON); + } + + void Reset() + { + Init(); + } + + void Aggro(Unit* pWho) + { + m_creature->CallForHelp(80.0f); + } + + void FakeDeath() + { + m_bDead = true; + m_bTimeToDie = false; + m_uiRespawnTimer = 4000; + m_creature->InterruptNonMeleeSpells(false); + m_creature->SetHealth(0); + 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->SetUInt64Value(UNIT_FIELD_TARGET,0); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->SetStandState(UNIT_STAND_STATE_DEAD); + m_creature->GetMap()->CreatureRelocation(m_creature, m_fDefaultX, m_fDefaultY, m_fDefaultZ, m_fDefaultO); + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if (uiDamage < m_creature->GetHealth()) + return; + + if (m_pInstance && (m_pInstance->GetData(TYPE_EMALON) != DONE)) + { + uiDamage = 0; + FakeDeath(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEvadeCheckCooldown < uiDiff) + { + Creature* pEmalon = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_EMALON)); + if ((pEmalon && pEmalon->IsInEvadeMode()) || (m_creature->GetDistance2d(-219.119f, -289.037f) > 80.0f)) + { + EnterEvadeMode(); + return; + } + m_uiEvadeCheckCooldown = 2000; + } + else + m_uiEvadeCheckCooldown -= uiDiff; + + if (m_bTimeToDie) + { + FakeDeath(); + return; + } + + if (m_bDead) + { + if (m_uiRespawnTimer < uiDiff) + { + m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetVisibility(VISIBILITY_OFF); + Init(); + m_creature->MonsterTextEmote("%s appears to defend Emalon!", NULL, true); + m_creature->SetInCombatWithZone(); + DoResetThreat(); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_creature->GetMotionMaster()->MoveChase(pTarget); + } + else + m_uiRespawnTimer -= uiDiff; + + return; + } + + if (m_uiOverchargedStacksCheckTimer < uiDiff) + { + m_uiOverchargedStacksCheckTimer = 2000; + Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, EFFECT_INDEX_0); + if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10) + { + DoCastSpellIfCan(m_creature, SPELL_OVERCHARGED_BLAST); + m_bTimeToDie = true; + return; + } + } + else + m_uiOverchargedStacksCheckTimer -= uiDiff; + + if (m_uiShockTimer < uiDiff) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK); + m_uiShockTimer = 8000+rand()%4000; + } + else + m_uiShockTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## boss_emalon +######*/ + +struct MANGOS_DLL_DECL boss_emalonAI : public ScriptedAI +{ + boss_emalonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + uint32 m_uiEvadeCheckCooldown; + + uint64 m_auiTempestMinionGUID[4]; + uint32 m_uiChainLightningTimer; + uint32 m_uiChainLightningCount; + uint32 m_uiLightningNovaTimer; + uint32 m_uiOverchargeTimer; + uint32 m_uiEnrageTimer; + + void Reset() + { + m_uiEvadeCheckCooldown = 2000; + memset(&m_auiTempestMinionGUID, 0, sizeof(m_auiTempestMinionGUID)); + m_uiChainLightningTimer = 15000; + m_uiChainLightningCount = 0; + m_uiLightningNovaTimer = 20000; + m_uiOverchargeTimer = 45000; + m_uiEnrageTimer = 360000; + + if (m_pInstance) + { + m_auiTempestMinionGUID[0] = m_pInstance->GetData64(DATA_TEMPEST_MINION_1); + m_auiTempestMinionGUID[1] = m_pInstance->GetData64(DATA_TEMPEST_MINION_2); + m_auiTempestMinionGUID[2] = m_pInstance->GetData64(DATA_TEMPEST_MINION_3); + m_auiTempestMinionGUID[3] = m_pInstance->GetData64(DATA_TEMPEST_MINION_4); + } + + for (uint8 i=0; i<4; ++i) + { + Creature* pMinion = m_creature->GetMap()->GetCreature( m_auiTempestMinionGUID[i]); + if (pMinion && pMinion->isDead()) + pMinion->Respawn(); + } + + if (m_pInstance) + m_pInstance->SetData(TYPE_EMALON, NOT_STARTED); + } + + void Aggro(Unit* pWho) + { + if (m_pInstance) + { + m_auiTempestMinionGUID[0] = m_pInstance->GetData64(DATA_TEMPEST_MINION_1); + m_auiTempestMinionGUID[1] = m_pInstance->GetData64(DATA_TEMPEST_MINION_2); + m_auiTempestMinionGUID[2] = m_pInstance->GetData64(DATA_TEMPEST_MINION_3); + m_auiTempestMinionGUID[3] = m_pInstance->GetData64(DATA_TEMPEST_MINION_4); + } + + m_creature->CallForHelp(80.0f); + + if (m_pInstance) + m_pInstance->SetData(TYPE_EMALON, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_EMALON, DONE); + for (uint8 i=0; i<4; ++i) + { + Creature *pMinion = m_creature->GetMap()->GetCreature( m_auiTempestMinionGUID[i]); + if (pMinion) + pMinion->DealDamage(pMinion, pMinion->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEvadeCheckCooldown < uiDiff) + { + if (m_creature->GetDistance2d(-219.119f, -289.037f) > 80.0f) + EnterEvadeMode(); + m_creature->CallForHelp(80.0f); + m_uiEvadeCheckCooldown = 2000; + } + else + m_uiEvadeCheckCooldown -= uiDiff; + + if (m_uiOverchargeTimer < uiDiff) + { + Creature* pMinion = m_creature->GetMap()->GetCreature( m_auiTempestMinionGUID[rand()%4]); + if(pMinion && pMinion->isAlive()) + { + m_creature->MonsterTextEmote("%s overcharges Tempest Minion!",NULL, true); + pMinion->SetHealth(pMinion->GetMaxHealth()); + pMinion->CastSpell(pMinion, SPELL_OVERCHARGE, false); + } + m_uiOverchargeTimer = 45000; + } + else + m_uiOverchargeTimer -= uiDiff; + + if (m_uiChainLightningTimer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING_N : SPELL_CHAIN_LIGHTNING_H); + m_uiChainLightningTimer = 10000 + rand()%15000; + } + else + m_uiChainLightningTimer -= uiDiff; + + if (m_uiLightningNovaTimer < uiDiff) + { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_NOVA_N : SPELL_LIGHTNING_NOVA_H); + m_uiLightningNovaTimer = 45000; + } + else + m_uiLightningNovaTimer -= uiDiff; + + if (m_uiEnrageTimer < uiDiff) + { + DoCastSpellIfCan(m_creature, SPELL_BERSERK); + m_uiEnrageTimer = 30000; + } + else + m_uiEnrageTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## npc_tempest_warder +######*/ + +struct MANGOS_DLL_DECL npc_tempest_warderAI : public ScriptedAI +{ + npc_tempest_warderAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiShockTimer; + bool m_bOvercharged; + uint32 m_uiOverchargedStacksCheckTimer; + bool m_bTimeToDie; + + void Reset() + { + m_uiShockTimer = 8000+rand()%4000; + m_bOvercharged = false; + uint32 m_uiOverchargedStacksCheckTimer = 2000; + m_bTimeToDie = false; + } + + void Aggro(Unit* pWho) {} + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_bTimeToDie) + { + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + return; + } + + if (!m_bOvercharged && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 37)) + { + DoCastSpellIfCan(m_creature, SPELL_OVERCHARGE); + m_bOvercharged = true; + } + + if (m_bOvercharged) + { + if (m_uiOverchargedStacksCheckTimer < uiDiff) + { + m_uiOverchargedStacksCheckTimer = 2000; + Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, EFFECT_INDEX_0); + if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10) + { + DoCastSpellIfCan(m_creature, SPELL_OVERCHARGED_BLAST); + m_bTimeToDie = true; + return; + } + } + else + m_uiOverchargedStacksCheckTimer -= uiDiff; + } + + if (m_uiShockTimer < uiDiff) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK); + m_uiShockTimer = 8000+rand()%4000; + } + else + m_uiShockTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_emalonAI(Creature* pCreature) +{ + return new boss_emalonAI(pCreature); +} + +CreatureAI* GetAI_npc_tempest_minionAI(Creature* pCreature) +{ + return new npc_tempest_minionAI(pCreature); +} + +CreatureAI* GetAI_npc_tempest_warderAI(Creature* pCreature) +{ + return new npc_tempest_warderAI(pCreature); +} + +void AddSC_boss_emalon() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_emalon"; + newscript->GetAI = &GetAI_boss_emalonAI; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_tempest_minion"; + newscript->GetAI = &GetAI_npc_tempest_minionAI; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_tempest_warder"; + newscript->GetAI = &GetAI_npc_tempest_warderAI; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/vault_of_archavon/boss_koralon.cpp b/scripts/northrend/vault_of_archavon/boss_koralon.cpp new file mode 100644 index 000000000..b49ca7821 --- /dev/null +++ b/scripts/northrend/vault_of_archavon/boss_koralon.cpp @@ -0,0 +1,140 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_koralon +SD%Complete: 50% +SDComment: +SDCategory: Vault of Archavon +EndScriptData */ + +#include "precompiled.h" +#include "vault_of_archavon.h" + +#define SP_BURNING_FURY_AURA 66895 +#define SP_BURNING_FURY_AURA2 68168 +#define SP_BURNING_FURY_EFFECT 66721 + +#define SP_BURNING_BREATH 66665 +#define H_SP_BURNING_BREATH 67328 //DBM +#define SP_BB_EFFECT 66670 +#define H_SP_BB_EFFECT 67329 + +#define SP_METEOR_FISTS 66725 //DBM +#define H_SP_METEOR_FISTS 68161 +#define SP_METEOR_FISTS_EFF 66765 +#define H_SP_METEOR_FISTS_EFF 67333 + +#define SP_CINDER 66684 +#define H_SP_CINDER 67332 + +struct MANGOS_DLL_DECL boss_koralonAI : public ScriptedAI +{ + boss_koralonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Regular = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* pInstance; + bool Regular; + uint32 BurningBreathTimer; + uint32 MeteorFistsTimer; + uint32 FlamesTimer; + + uint32 BBTickTimer; + uint32 BBTicks; + bool BB; + + void Reset() + { + BurningBreathTimer = 25000; + MeteorFistsTimer = 47000; + FlamesTimer = 15000; + + BB = false; + + if(pInstance) pInstance->SetData(TYPE_KORALON, NOT_STARTED); + } + + void Aggro(Unit *who) + { + DoCastSpellIfCan(m_creature, SP_BURNING_FURY_AURA); + + if(pInstance) pInstance->SetData(TYPE_KORALON, IN_PROGRESS); + }; + + void JustDied(Unit *killer) + { + if(pInstance) pInstance->SetData(TYPE_KORALON, DONE); + }; + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(BurningBreathTimer < diff) + { + DoCastSpellIfCan(m_creature, Regular ? SP_BURNING_BREATH : H_SP_BURNING_BREATH); + BurningBreathTimer = 45000; + + BB = true; + BBTickTimer = 1000; + BBTicks = 0; + } + else BurningBreathTimer -= diff; + + + if(FlamesTimer < diff) + { + int flames = Regular ? 3 : 5; + int i; + for(i=0; i< flames; ++i) + { + Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); + if(target) DoCastSpellIfCan(target, Regular ? SP_CINDER : H_SP_CINDER); + } + FlamesTimer = 20000; + } + else FlamesTimer -= diff; + + if(MeteorFistsTimer < diff) + { + DoCastSpellIfCan(m_creature->getVictim(), SP_METEOR_FISTS_EFF); + MeteorFistsTimer = 45000; + } + else MeteorFistsTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_koralonAI(Creature* pCreature) +{ + return new boss_koralonAI(pCreature); +} + +void AddSC_boss_koralon() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_koralon"; + newscript->GetAI = &GetAI_boss_koralonAI; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/vault_of_archavon/boss_toravon.cpp b/scripts/northrend/vault_of_archavon/boss_toravon.cpp new file mode 100644 index 000000000..afe614f46 --- /dev/null +++ b/scripts/northrend/vault_of_archavon/boss_toravon.cpp @@ -0,0 +1,138 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Toravon the Ice Watcher +SDAuthor: Lutik +SD%Complete: 0% +SDComment: +SDCategory: Vault of Archavon +EndScriptData */ + +#include "precompiled.h" +#include "vault_of_archavon.h" + +enum +{ + SP_WHITEOUT = 72034, + H_SP_WHITEOUT = 72096, + SP_FREEZING_GROUND = 72090, + H_SP_FREEZING_GROUND = 72104, + SP_FROZEN_MALLET = 71993, + FROZEN_ORB_AURA = 72081, + + CR_FROZEN_ORB = 38456 +}; + + +struct MANGOS_DLL_DECL boss_toravonAI : public ScriptedAI +{ + boss_toravonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + orbsNum = m_bIsRegularMode ? 1 : 3; + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + bool m_bIsRegularMode; + ScriptedInstance *pInstance; + + int orbsNum; + uint32 WhiteoutTimer; + uint32 OrbsTimer; + uint32 FreezeTimer; + + void Reset() + { + WhiteoutTimer = 40000; + OrbsTimer = 15000; + FreezeTimer = 20000 + rand()%5000; + + if(pInstance) + pInstance->SetData(TYPE_TORAVON, NOT_STARTED); + } + + void Aggro(Unit *who) + { + DoCastSpellIfCan(m_creature, SP_FROZEN_MALLET); + + if(pInstance) + pInstance->SetData(TYPE_TORAVON, IN_PROGRESS); + } + + void JustDied(Unit *killer) + { + if(pInstance) + pInstance->SetData(TYPE_TORAVON, DONE); + } + + void JustSummoned(Creature *orb) + { + orb->CastSpell(orb, FROZEN_ORB_AURA, false); + orb->SetInCombatWithZone(); + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(WhiteoutTimer < diff) + { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SP_WHITEOUT : H_SP_WHITEOUT); + WhiteoutTimer = 40000; + } + else + WhiteoutTimer -= diff; + + if(OrbsTimer < diff) + { + for(int i=0; iSelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + m_creature->SummonCreature(CR_FROZEN_ORB, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000); + } + OrbsTimer = 40000; + } + else + OrbsTimer -= diff; + + if(FreezeTimer < diff) + { + DoCastSpellIfCan(m_creature, SP_FREEZING_GROUND); + FreezeTimer = 20000 + rand()%5000; + } + else + FreezeTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_toravon(Creature *pCreature) +{ + return new boss_toravonAI (pCreature); +}; + +void AddSC_boss_toravon() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_toravon"; + newscript->GetAI = &GetAI_boss_toravon; + newscript->RegisterSelf(); +}; diff --git a/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp b/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp new file mode 100644 index 000000000..eff9989bf --- /dev/null +++ b/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp @@ -0,0 +1,210 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Instance_Vault_of_Archavon +SD%Complete: 0 +SDComment: +SDCategory: Vault of Archavon +EndScriptData */ + +#include "precompiled.h" +#include "vault_of_archavon.h" + +struct MANGOS_DLL_DECL instance_vault_of_archavon : public ScriptedInstance +{ + instance_vault_of_archavon(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string strInstData; + + uint64 m_uiArchavonGUID; + uint64 m_uiEmalonGUID; + uint64 m_uiKoralonGUID; + uint64 m_uiTempestMinion1GUID; + uint64 m_uiTempestMinion2GUID; + uint64 m_uiTempestMinion3GUID; + uint64 m_uiTempestMinion4GUID; + uint8 m_uiMinion; + + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + m_uiArchavonGUID = 0; + m_uiEmalonGUID = 0; + m_uiKoralonGUID = 0; + m_uiTempestMinion1GUID = 0; + m_uiTempestMinion2GUID = 0; + m_uiTempestMinion3GUID = 0; + m_uiTempestMinion4GUID = 0; + m_uiMinion = 0; + } + + void OnCreatureCreate(Creature* pCreature) + { + switch (pCreature->GetEntry()) + { + case NPC_ARCHAVON: + m_uiArchavonGUID = pCreature->GetGUID(); + break; + case NPC_EMALON: + m_uiEmalonGUID = pCreature->GetGUID(); + break; + case NPC_KORALON: + m_uiKoralonGUID = pCreature->GetGUID(); + break; + case NPC_TEMPEST_MINION: + ++m_uiMinion; + switch (m_uiMinion) + { + case 1: + m_uiTempestMinion1GUID = pCreature->GetGUID(); + break; + case 2: + m_uiTempestMinion2GUID = pCreature->GetGUID(); + break; + case 3: + m_uiTempestMinion3GUID = pCreature->GetGUID(); + break; + case 4: + m_uiTempestMinion4GUID = pCreature->GetGUID(); + break; + case 5: + m_uiMinion = 0; + break; + } + break; + } + } + + void SetData(uint32 uiType, uint32 uiData) + { + switch (uiType) + { + case TYPE_ARCHAVON: + m_auiEncounter[0] = uiData; + break; + case TYPE_EMALON: + m_auiEncounter[1] = uiData; + break; + case TYPE_KORALON: + m_auiEncounter[2] = uiData; + break; + case TYPE_TORAVON: + m_auiEncounter[3] = 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]; + + strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + uint32 GetData(uint32 uiType) + { + switch (uiType) + { + case TYPE_ARCHAVON: + return m_auiEncounter[0]; + case TYPE_EMALON: + return m_auiEncounter[1]; + case TYPE_KORALON: + return m_auiEncounter[2]; + case TYPE_TORAVON: + return m_auiEncounter[3]; + } + return 0; + } + + uint64 GetData64(uint32 uiData) + { + switch (uiData) + { + case DATA_ARCHAVON: + return m_uiArchavonGUID; + case DATA_EMALON: + return m_uiEmalonGUID; + case DATA_KORALON: + return m_uiKoralonGUID; + case DATA_TEMPEST_MINION_1: + return m_uiTempestMinion1GUID; + case DATA_TEMPEST_MINION_2: + return m_uiTempestMinion2GUID; + case DATA_TEMPEST_MINION_3: + return m_uiTempestMinion3GUID; + case DATA_TEMPEST_MINION_4: + return m_uiTempestMinion4GUID; + } + return 0; + } + const char* Save() + { + return strInstData.c_str(); + } + + void Load(const char* in) + { + if (!in) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(in); + + std::istringstream loadStream(in); + 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; + } + + bool IsEncounterInProgress() const + { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) + return true; + return false; + } +}; + +InstanceData* GetInstanceData_instance_vault_of_archavon(Map* pMap) +{ + return new instance_vault_of_archavon(pMap); +} + +void AddSC_instance_vault_of_archavon() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_vault_of_archavon"; + newscript->GetInstanceData = &GetInstanceData_instance_vault_of_archavon; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/vault_of_archavon/vault_of_archavon.h b/scripts/northrend/vault_of_archavon/vault_of_archavon.h new file mode 100644 index 000000000..5becbc2db --- /dev/null +++ b/scripts/northrend/vault_of_archavon/vault_of_archavon.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_VAULT_OF_ARCHAVON_H +#define DEF_VAULT_OF_ARCHAVON_H + +enum +{ + MAX_ENCOUNTER = 4, + + DATA_ARCHAVON = 1, + DATA_EMALON = 2, + DATA_KORALON = 3, + DATA_TEMPEST_MINION_1 = 4, + DATA_TEMPEST_MINION_2 = 5, + DATA_TEMPEST_MINION_3 = 6, + DATA_TEMPEST_MINION_4 = 7, + + TYPE_ARCHAVON = 8, + TYPE_EMALON = 9, + TYPE_KORALON = 10, + TYPE_TORAVON = 11, + + NPC_ARCHAVON = 31125, + NPC_EMALON = 33993, + NPC_KORALON = 35013, + NPC_TEMPEST_MINION = 33998 +}; + +#endif diff --git a/scripts/northrend/violet_hold/boss_cyanigosa.cpp b/scripts/northrend/violet_hold/boss_cyanigosa.cpp new file mode 100644 index 000000000..3498f253f --- /dev/null +++ b/scripts/northrend/violet_hold/boss_cyanigosa.cpp @@ -0,0 +1,196 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_cyanigosa +SDAuthor: ckegg +SD%Complete: 0 +SDComment: +SDCategory: The Violet Hold +EndScriptData */ + +#include "precompiled.h" +#include "violet_hold.h" + +enum +{ + SAY_AGGRO = -1608046, + SAY_SLAY_1 = -1608051, + SAY_SLAY_2 = -1608052, + SAY_SLAY_3 = -1608053, + SAY_DEATH = -1608054, + SAY_SPAWN = -1608045, + SAY_DISRUPTION = -1608050, + SAY_BREATH_ATTACK = -1608047, + SAY_SPECIAL_ATTACK_1 = -1608048, + SAY_SPECIAL_ATTACK_2 = -1608049, + + SPELL_ARCANE_VACUM = 58694, + SPELL_BLIZZARD = 58693, + SPELL_BLIZZARD_H = 59369, + SPELL_MANA_DESTRUCTION = 59374, + SPELL_TAIL_SWEEP = 58690, + SPELL_TAIL_SWEEP_H = 59283, + SPELL_UNCONTROLLABLE_ENERGY = 58688, + SPELL_UNCONTROLLABLE_ENERGY_H = 59281, + SPELL_CYANIGOSA_TRANSFORM = 58668, +}; + +struct MANGOS_DLL_DECL boss_cyanigosaAI : public ScriptedAI +{ + boss_cyanigosaAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + + bool m_bIsRegularMode; + + uint32 m_uiTailSweep_Timer; + uint32 m_uiManaDestruction_Timer; + uint32 m_uiBlizzard_Timer; + uint32 m_uiUncontrollableEnergy_Timer; + uint32 m_uiArcaneVacuum_Timer; + bool MovementStarted; + + void Reset() + { + m_uiUncontrollableEnergy_Timer = urand(15000, 16000); + m_uiManaDestruction_Timer = urand(5000, 6000); + m_uiBlizzard_Timer = urand(20000, 25000); + m_uiTailSweep_Timer = urand(10000, 11000); + m_uiArcaneVacuum_Timer = urand(28000, 33000); + MovementStarted = false; + m_creature->SetInCombatWithZone(); + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_CYANIGOSA, FAIL); + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + } + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_AGGRO, m_creature); + DoCast(m_creature, SPELL_CYANIGOSA_TRANSFORM); + m_pInstance->SetData(TYPE_CYANIGOSA, IN_PROGRESS); + } + + void UpdateAI(const uint32 uiDiff) + { + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiUncontrollableEnergy_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_UNCONTROLLABLE_ENERGY : SPELL_UNCONTROLLABLE_ENERGY_H); + m_uiUncontrollableEnergy_Timer = urand(15000, 16000); + } + else + m_uiUncontrollableEnergy_Timer -= uiDiff; + + if (m_uiManaDestruction_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_MANA_DESTRUCTION); + m_uiManaDestruction_Timer = urand(8000, 13000); + } + else + m_uiManaDestruction_Timer -= uiDiff; + + if (m_uiBlizzard_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_BLIZZARD: SPELL_BLIZZARD_H ); + m_uiBlizzard_Timer = urand(20000, 25000); + } + else + m_uiBlizzard_Timer -= uiDiff; + + if (m_uiArcaneVacuum_Timer < uiDiff) + { + DoCast(m_creature, SPELL_ARCANE_VACUM); + Map* pMap = m_creature->GetMap(); + if (pMap && pMap->IsDungeon()) + { + Map::PlayerList const &PlayerList = pMap->GetPlayers(); + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (i->getSource()->isAlive()) + DoTeleportPlayer(i->getSource(), m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), i->getSource()->GetOrientation()); + } + DoResetThreat(); + m_uiArcaneVacuum_Timer = urand(28000, 33000); + } + else + m_uiArcaneVacuum_Timer -= uiDiff; + + if (m_uiTailSweep_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_SWEEP : SPELL_TAIL_SWEEP_H); + m_uiTailSweep_Timer = urand(10000, 11000); + } + else + m_uiTailSweep_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + { + m_pInstance->SetData(TYPE_RIFT, DONE); + m_pInstance->SetData(TYPE_EVENT, DONE); + m_pInstance->SetData(TYPE_CYANIGOSA, DONE); + } + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0, 2)) + { + case 0: DoScriptText(SAY_SLAY_1, m_creature);break; + case 1: DoScriptText(SAY_SLAY_2, m_creature);break; + case 2: DoScriptText(SAY_SLAY_3, m_creature);break; + } + } +}; + +CreatureAI* GetAI_boss_cyanigosa(Creature* pCreature) +{ + return new boss_cyanigosaAI (pCreature); +} + +void AddSC_boss_cyanigosa() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_cyanigosa"; + newscript->GetAI = &GetAI_boss_cyanigosa; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/violet_hold/boss_erekem.cpp b/scripts/northrend/violet_hold/boss_erekem.cpp new file mode 100644 index 000000000..365621ec5 --- /dev/null +++ b/scripts/northrend/violet_hold/boss_erekem.cpp @@ -0,0 +1,429 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_erekem +SDAuthor: ckegg +SD%Complete: 50% +SDComment: +SDCategory: The Violet Hold +EndScriptData */ + +#include "precompiled.h" +#include "violet_hold.h" + +enum +{ + SAY_AGGRO = -1608010, + SAY_SLAY_1 = -1608011, + SAY_SLAY_2 = -1608012, + SAY_SLAY_3 = -1608013, + SAY_DEATH = -1608014, + SAY_SPAWN = -1608015, + SAY_ADD_KILED = -1608016, + SAY_BOTH_ADDS_KILED = -1608017, + + SPELL_BLOODLUST = 54516, + SPELL_BREAK_BONDS = 59463, + SPELL_CHAIN_HEAL = 54481, + SPELL_CHAIN_HEAL_H = 59473, + SPELL_EARTH_SHIELD = 54479, + SPELL_EARTH_SHIELD_H = 59471, + SPELL_EARTH_SHOCK = 54511, + SPELL_LIGHTNING_BOLT = 53044, + SPELL_STORMSTRIKE = 51876, + + SPELL_GUSHING_WOUND = 39215, + SPELL_HOWLING_SCREECH = 54462, + SPELL_STRIKE = 14516, +}; + +struct MANGOS_DLL_DECL boss_erekemAI : public ScriptedAI +{ + boss_erekemAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + + bool m_bIsRegularMode; + bool m_bIsAddDead; + bool MovementStarted; + + uint32 m_uiBloodlust_Timer; + uint32 m_uiBreakBonds_Timer; + uint32 m_uiChainHeal_Timer; + uint32 m_uiEarthShield_Timer; + uint32 m_uiEarthShock_Timer; + uint32 m_uiLightningBolt_Timer; + uint32 m_uiStormstrike_Timer; + + void Reset() + { + if (!m_pInstance) return; + + m_bIsAddDead = false; + MovementStarted = false; + m_uiLightningBolt_Timer = 2000; + m_uiEarthShield_Timer = urand(10000, 15000); + m_uiEarthShock_Timer = urand(12000, 17000); + m_uiChainHeal_Timer = urand(5000, 25000); + m_uiBreakBonds_Timer = urand(25000, 30000); + m_uiBloodlust_Timer = urand(60000, 65000); + m_uiStormstrike_Timer = urand(1000, 2000); + + std::list lUnitList; + GetCreatureListWithEntryInGrid(lUnitList, m_creature, NPC_EREKEM_GUARD, 100.0f); + if (!lUnitList.empty()) + for(std::list::iterator iter = lUnitList.begin(); iter != lUnitList.end(); ++iter) + if ((*iter)) + if ((*iter)->isDead()) + (*iter)->Respawn(); + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_EREKEM, FAIL); + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, NOT_STARTED);} + else {m_pInstance->SetData(TYPE_PORTAL12, NOT_STARTED);} + } + } + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + DoScriptText(SAY_AGGRO, m_creature); + m_pInstance->SetData(TYPE_EREKEM, IN_PROGRESS); + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + } + + void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_EREKEM) != SPECIAL && m_pInstance->GetData(TYPE_EREKEM) != IN_PROGRESS) + return; + + if (!pWho || pWho == m_creature) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho, 0.0f); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + + std::list lUnitList; + GetCreatureListWithEntryInGrid(lUnitList, m_creature, NPC_EREKEM_GUARD, 100.0f); + if (!lUnitList.empty()) + for(std::list::iterator iter = lUnitList.begin(); iter != lUnitList.end(); ++iter) + if (*iter) + if ((*iter)->isAlive()) + { + (*iter)->AddThreat(pWho, 0.0f); + /* (*iter)->AI()->AttackStart(pWho);*/ + } + } + } + + void StartMovement(uint32 id) + { + m_creature->GetMotionMaster()->MovePoint(id, PortalLoc[id].x, PortalLoc[id].y, PortalLoc[id].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetInCombatWithZone(); + MovementStarted = true; + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + if (id == 0) + { + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_EREKEM) == SPECIAL && !MovementStarted) + StartMovement(0); + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEarthShield_Timer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature, m_bIsRegularMode ? SPELL_EARTH_SHIELD : SPELL_EARTH_SHIELD_H); + m_uiEarthShield_Timer = urand(25000, 30000); + } + else m_uiEarthShield_Timer -= uiDiff; + + if (m_uiEarthShock_Timer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(false); + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_EARTH_SHOCK); + m_uiEarthShock_Timer = urand(12000, 17000); + } + else m_uiEarthShock_Timer -= uiDiff; + + if (m_uiChainHeal_Timer < uiDiff) + { + //m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature, m_bIsRegularMode ? SPELL_CHAIN_HEAL : SPELL_CHAIN_HEAL_H); + m_uiChainHeal_Timer = urand(5000, 25000); + } + else m_uiChainHeal_Timer -= uiDiff; + + if (m_uiBreakBonds_Timer < uiDiff) + { + m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature, SPELL_BREAK_BONDS); + m_uiBreakBonds_Timer = urand(25000, 30000); + } + else m_uiBreakBonds_Timer -= uiDiff; + + if (!m_bIsAddDead) + { + if (m_uiLightningBolt_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_LIGHTNING_BOLT); + m_uiLightningBolt_Timer = 2000; + } + else m_uiLightningBolt_Timer -= uiDiff; + } + else + { + if (m_uiStormstrike_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_STORMSTRIKE); + m_uiStormstrike_Timer = 1000; + } + else m_uiStormstrike_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) { + m_pInstance->SetData(TYPE_EREKEM, DONE); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, DONE);} + else {m_pInstance->SetData(TYPE_PORTAL12, DONE);} + + } + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0, 2)) + { + case 0: DoScriptText(SAY_SLAY_1, m_creature);break; + case 1: DoScriptText(SAY_SLAY_2, m_creature);break; + case 2: DoScriptText(SAY_SLAY_3, m_creature);break; + } + } +}; + +struct MANGOS_DLL_DECL mob_erekem_guardAI : public ScriptedAI +{ + mob_erekem_guardAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + ScriptedInstance *m_pInstance; + + uint32 m_uiGushingWound_Timer; + uint32 m_uiHowlingScreech_Timer; + uint32 m_uiStrike_Timer; + uint32 m_uiBloodlust_Timer; + bool MovementStarted; + + void Reset() + { + m_uiGushingWound_Timer = urand(5000, 10000); + m_uiBloodlust_Timer = urand(25000, 30000); + m_uiHowlingScreech_Timer = urand(12000, 15000); + m_uiStrike_Timer = urand(10000, 11000); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = false; + + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + } + + /* void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_EREKEM) != SPECIAL && m_pInstance->GetData(TYPE_EREKEM) != IN_PROGRESS) + return; + + + if (!pWho || pWho == m_creature) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho, 0.0f); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + } + }*/ + + void StartMovement(uint32 id) + { + m_creature->GetMotionMaster()->MovePoint(id, PortalLoc[id].x, PortalLoc[id].y, PortalLoc[id].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = true; + m_creature->SetInCombatWithZone(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + if (id == 0) + { + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_pInstance) return; + + if (m_pInstance->GetData(TYPE_EREKEM) == IN_PROGRESS && !MovementStarted && !m_creature->getVictim()) + StartMovement(0); + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiGushingWound_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_GUSHING_WOUND); + m_uiGushingWound_Timer = urand(30000, 32000); + } + else m_uiGushingWound_Timer -= uiDiff; + + if (m_uiBloodlust_Timer < uiDiff) + { + if (m_pInstance) + if (Creature* pErekem = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_EREKEM)))) + if (pErekem->isAlive()) + { + pErekem->InterruptNonMeleeSpells(false); + pErekem->CastSpell(pErekem, SPELL_BLOODLUST, false); + m_uiBloodlust_Timer = urand(25000, 30000); + } + } + else m_uiBloodlust_Timer -= uiDiff; + + if (m_uiHowlingScreech_Timer < uiDiff) + { + DoCast(m_creature, SPELL_HOWLING_SCREECH); + m_uiHowlingScreech_Timer = urand(24000, 30000); + } + else m_uiHowlingScreech_Timer -= uiDiff; + + if (m_uiStrike_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_STRIKE); + m_uiStrike_Timer = urand(15000, 16000); + } + else m_uiStrike_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance) + if (Creature* pErekem = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_EREKEM)))) + if (pErekem->isAlive()) + { + DoScriptText(SAY_ADD_KILED, pErekem); + // pErekem->InterruptNonMeleeSpells(false); + // pErekem->CastSpell(pErekem, SPELL_BLOODLUST, false); + ((boss_erekemAI*)pErekem->AI())->m_bIsAddDead = true; + } + } +}; + +CreatureAI* GetAI_boss_erekem(Creature* pCreature) +{ + return new boss_erekemAI (pCreature); +} + +CreatureAI* GetAI_mob_erekem_guard(Creature* pCreature) +{ + return new mob_erekem_guardAI (pCreature); +} + +void AddSC_boss_erekem() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_erekem"; + newscript->GetAI = &GetAI_boss_erekem; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_erekem_guard"; + newscript->GetAI = &GetAI_mob_erekem_guard; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/violet_hold/boss_ichoron.cpp b/scripts/northrend/violet_hold/boss_ichoron.cpp new file mode 100644 index 000000000..8f462c539 --- /dev/null +++ b/scripts/northrend/violet_hold/boss_ichoron.cpp @@ -0,0 +1,387 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_ichoron +SDAuthor: ckegg +SD%Complete: 30% +SDComment: +SDCategory: The Violet Hold +EndScriptData */ + +#include "precompiled.h" +#include "violet_hold.h" + + +enum +{ + SAY_AGGRO = -1608018, + SAY_SLAY_1 = -1608019, + SAY_SLAY_2 = -1608020, + SAY_SLAY_3 = -1608021, + SAY_DEATH = -1608022, + SAY_SPAWN = -1608023, + SAY_ENRAGE = -1608024, + SAY_SHATTER = -1608025, + SAY_BUBBLE = -1608026, + EMOTE_ICHORON_PROTECTIVE_BUBBLE = -1608008, + + SPELL_DRAINED = 59820, + SPELL_FRENZY = 54312, + SPELL_FRENZY_H = 59522, + SPELL_PROTECTIVE_BUBBLE = 54306, + SPELL_WATER_BLAST = 54237, + SPELL_WATER_BLAST_H = 59520, + SPELL_WATER_BOLT_VOLLEY = 54241, + SPELL_WATER_BOLT_VOLLEY_H = 59521, + + NPC_ICHOR_GLOBULE = 29321, + SPELL_SPLASH = 59516, + SPELL_WATER_GLOBULE = 54268, + SPELL_WATER_GLOBULE_2 = 54260, + GLOBULE_HEAL_H = 9000, + GLOBULE_HEAL = 5000 +}; + +struct MANGOS_DLL_DECL boss_ichoronAI : public ScriptedAI +{ + boss_ichoronAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + std::list m_lWaterElementsGUIDList; + + bool m_bIsRegularMode; + bool m_bIsExploded; + bool m_bIsFrenzy; + bool MovementStarted; + + uint32 m_uiBuubleChecker_Timer; + uint32 m_uiWaterBoltVolley_Timer; + uint32 m_uiShowup_Counter; + uint32 m_uiVisible_Timer; + uint32 m_uiHealth; + + void Reset() + { + if (!m_pInstance) return; + DoCastSpellIfCan(m_creature, SPELL_PROTECTIVE_BUBBLE); + m_bIsExploded = false; + m_bIsFrenzy = false; + MovementStarted = false; + m_uiBuubleChecker_Timer = 1000; + // m_uiDrained_Timer = 1000; + m_uiVisible_Timer = 0; + m_uiWaterBoltVolley_Timer = urand(5000, 10000); + // m_uiShowup_Counter = 0; + + m_creature->SetVisibility(VISIBILITY_ON); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DespawnWaterElements(); + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_ICHORON, FAIL); + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, NOT_STARTED);} + else {m_pInstance->SetData(TYPE_PORTAL12, NOT_STARTED);} + } + } + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + + DoScriptText(SAY_AGGRO, m_creature); + m_pInstance->SetData(TYPE_ICHORON, IN_PROGRESS); + SetCombatMovement(true); + } + + void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_ICHORON) != SPECIAL && m_pInstance->GetData(TYPE_ICHORON) != IN_PROGRESS) + return; + + + if (!pWho || pWho == m_creature) + return; + + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } + } + + void WaterElementHit() + { + if (Creature* pIchoron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ICHORON))) + { + if(pIchoron->isAlive()) + { + pIchoron->ModifyHealth( m_bIsRegularMode ? GLOBULE_HEAL : GLOBULE_HEAL_H); + if (m_bIsExploded) + { + if(m_creature->HasAura(SPELL_DRAINED)) + { + m_creature->RemoveAurasByCasterSpell(SPELL_DRAINED,m_creature->GetGUID()); + } + m_creature->SetVisibility(VISIBILITY_ON); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + } + } + } + + void JustSummoned(Creature* pSummoned) + { + pSummoned->SetSpeedRate(MOVE_RUN, 0.2f); + pSummoned->GetMotionMaster()->MoveFollow(m_creature, 0, 0); + pSummoned->CastSpell(pSummoned, SPELL_WATER_GLOBULE, false); + m_lWaterElementsGUIDList.push_back(pSummoned->GetGUID()); + } + void DespawnWaterElements() + { + if (m_lWaterElementsGUIDList.empty()) + return; + + for(std::list::iterator itr = m_lWaterElementsGUIDList.begin(); itr != m_lWaterElementsGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + { + if (pTemp->isAlive()) + //pTemp->ForcedDespawn(); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + m_lWaterElementsGUIDList.clear(); + } + + void StartMovement(uint32 id) + { + m_creature->GetMotionMaster()->MovePoint(id, PortalLoc[id].x, PortalLoc[id].y, PortalLoc[id].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = true; + m_creature->SetInCombatWithZone(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !MovementStarted || m_creature->GetVisibility() == VISIBILITY_OFF ) return; + if (id == 0) + { + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_ICHORON) == SPECIAL && !MovementStarted) + StartMovement(0); + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (!m_bIsFrenzy) + { + if (m_uiBuubleChecker_Timer < uiDiff) + { + if(!m_creature->HasAura(SPELL_PROTECTIVE_BUBBLE) && m_creature->GetVisibility() == VISIBILITY_ON && m_bIsExploded) + { + DoCastSpellIfCan(m_creature, SPELL_PROTECTIVE_BUBBLE); + DoScriptText(SAY_BUBBLE, m_creature); + m_bIsExploded = false; + m_uiBuubleChecker_Timer = 3000; + } + if(!m_creature->HasAura(SPELL_PROTECTIVE_BUBBLE) && m_creature->GetVisibility() == VISIBILITY_ON && !m_bIsExploded) + { + DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_WATER_BLAST : SPELL_WATER_BLAST_H); + + for(uint8 i = 0; i < 10; i++) + { + int tmp = urand(0, 5); + m_creature->SummonCreature(NPC_ICHOR_GLOBULE, PortalLoc[tmp].x, PortalLoc[tmp].y, PortalLoc[tmp].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + } + DoScriptText(EMOTE_ICHORON_PROTECTIVE_BUBBLE, m_creature); + //DoScriptText(SAY_SHATTER, m_creature); + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth()*0.25, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_creature->SetVisibility(VISIBILITY_OFF); + m_bIsExploded = true; + m_uiVisible_Timer = 15000; + } + + } + else m_uiBuubleChecker_Timer -= uiDiff; + + if(m_creature->GetVisibility() == VISIBILITY_OFF && m_uiVisible_Timer < uiDiff) + { + m_creature->SetVisibility(VISIBILITY_ON); + m_uiVisible_Timer = 3000; + } + else m_uiVisible_Timer -= uiDiff; + + } + if (m_creature->GetVisibility() == VISIBILITY_OFF && !m_creature->HasAura(SPELL_DRAINED) ) + { + DoCastSpellIfCan(m_creature, SPELL_DRAINED); + } + + if (m_creature->GetVisibility() == VISIBILITY_ON ) + { + if (m_uiWaterBoltVolley_Timer < uiDiff) + { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_WATER_BOLT_VOLLEY : SPELL_WATER_BOLT_VOLLEY_H); + m_uiWaterBoltVolley_Timer = urand(15000, 20000); + } + else m_uiWaterBoltVolley_Timer -= uiDiff; + + } + if (!m_bIsFrenzy && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25) + { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_FRENZY : SPELL_FRENZY_H); + DoScriptText(SAY_ENRAGE, m_creature); + if(m_creature->HasAura(SPELL_DRAINED)) + { + m_creature->RemoveAurasByCasterSpell(SPELL_DRAINED,m_creature->GetGUID()); + } + if(m_creature->GetVisibility() == VISIBILITY_OFF){m_creature->SetVisibility(VISIBILITY_ON);} + m_bIsFrenzy = true; + } + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + DespawnWaterElements(); + + if (m_pInstance){ + m_pInstance->SetData(TYPE_ICHORON, DONE); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, DONE);} + else {m_pInstance->SetData(TYPE_PORTAL12, DONE);} + } + + if(m_creature->GetVisibility() == VISIBILITY_OFF) + m_creature->SetVisibility(VISIBILITY_ON); + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0, 2)) + { + case 0: DoScriptText(SAY_SLAY_1, m_creature);break; + case 1: DoScriptText(SAY_SLAY_2, m_creature);break; + case 2: DoScriptText(SAY_SLAY_3, m_creature);break; + } + } +}; + + +struct MANGOS_DLL_DECL mob_ichor_globuleAI : public ScriptedAI +{ + mob_ichor_globuleAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + ScriptedInstance *m_pInstance; + + uint32 m_uiRangeCheck_Timer; + + void Reset() + { + m_uiRangeCheck_Timer = 1000; + } + + void AttackStart(Unit* pWho) + { + return; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiRangeCheck_Timer < uiDiff) + { + if (m_pInstance) + { + if (Creature* pIchoron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ICHORON))) + { + float fDistance = m_creature->GetDistance2d(pIchoron); + if (fDistance <= 2) + { + ((boss_ichoronAI*)pIchoron->AI())->WaterElementHit(); + + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + } + m_uiRangeCheck_Timer = 1000; + } + else m_uiRangeCheck_Timer -= uiDiff; + } + + void JustDied(Unit* pKiller) + { + DoCast(m_creature, SPELL_SPLASH); + DoCast(m_creature, SPELL_WATER_GLOBULE_2); + + } +}; + +CreatureAI* GetAI_boss_ichoron(Creature* pCreature) +{ + return new boss_ichoronAI (pCreature); +} + +CreatureAI* GetAI_mob_ichor_globule(Creature* pCreature) +{ + return new mob_ichor_globuleAI (pCreature); +} + +void AddSC_boss_ichoron() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_ichoron"; + newscript->GetAI = &GetAI_boss_ichoron; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ichor_globule"; + newscript->GetAI = &GetAI_mob_ichor_globule; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/violet_hold/boss_lavanthor.cpp b/scripts/northrend/violet_hold/boss_lavanthor.cpp new file mode 100644 index 000000000..4e9e13599 --- /dev/null +++ b/scripts/northrend/violet_hold/boss_lavanthor.cpp @@ -0,0 +1,193 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_lavanthor +SDAuthor: ckegg +SD%Complete: 0 +SDComment: +SDCategory: The Violet Hold +EndScriptData */ + +#include "precompiled.h" +#include "violet_hold.h" + +enum +{ + SPELL_CAUTERIZING_FLAMES = 59466, + SPELL_FIREBOLT = 54235, + SPELL_FIREBOLT_H = 59468, + SPELL_FLAME_BREATH = 54282, + SPELL_FLAME_BREATH_H = 59469, + SPELL_LAVA_BURN = 54249, + SPELL_LAVA_BURN_H = 59594, +}; + +struct MANGOS_DLL_DECL boss_lavanthorAI : public ScriptedAI +{ + boss_lavanthorAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + + bool m_bIsRegularMode; + bool MovementStarted; + + uint32 m_uiCauterizingFlames_Timer; + uint32 m_uiFlameBreath_Timer; + uint32 m_uiFirebolt_Timer; + + void Reset() + { + if (!m_pInstance) return; + m_uiCauterizingFlames_Timer = urand(40000, 41000); + m_uiFlameBreath_Timer = urand(15000, 16000); + m_uiFirebolt_Timer = urand(10000, 11000); + MovementStarted = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_LAVANTHOR, FAIL); + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, NOT_STARTED);} + else {m_pInstance->SetData(TYPE_PORTAL12, NOT_STARTED);} + } + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_LAVANTHOR, IN_PROGRESS); + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + } + + void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_LAVANTHOR) != SPECIAL && m_pInstance->GetData(TYPE_LAVANTHOR) != IN_PROGRESS) + return; + + if (!pWho || pWho == m_creature) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } + } + + void StartMovement(uint32 id) + { + m_creature->GetMotionMaster()->MovePoint(id, PortalLoc[id].x, PortalLoc[id].y, PortalLoc[id].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = true; + m_creature->SetInCombatWithZone(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + if (id == 0 ) + { + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_LAVANTHOR) == SPECIAL && !MovementStarted) + StartMovement(0); + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiCauterizingFlames_Timer < uiDiff) + { + DoCast(m_creature, SPELL_CAUTERIZING_FLAMES); + m_uiCauterizingFlames_Timer = urand(40000, 41000); + } + else m_uiCauterizingFlames_Timer -= uiDiff; + + if (m_uiFirebolt_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FIREBOLT: SPELL_FIREBOLT_H ); + m_uiFirebolt_Timer = urand(10000, 11000); + } + else m_uiFirebolt_Timer -= uiDiff; + + if (m_uiFlameBreath_Timer < uiDiff) + { + switch (urand(0, 1)) + { + case 0: + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H); + break; + case 1: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, m_bIsRegularMode ? SPELL_LAVA_BURN : SPELL_LAVA_BURN_H); + break; + } + m_uiFlameBreath_Timer = urand(15000, 16000); + } + else m_uiFlameBreath_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance){ + m_pInstance->SetData(TYPE_LAVANTHOR, DONE); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, DONE);} + else {m_pInstance->SetData(TYPE_PORTAL12, DONE);} + } + } +}; + +CreatureAI* GetAI_boss_lavanthor(Creature* pCreature) +{ + return new boss_lavanthorAI (pCreature); +} + +void AddSC_boss_lavanthor() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_lavanthor"; + newscript->GetAI = &GetAI_boss_lavanthor; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/violet_hold/boss_moragg.cpp b/scripts/northrend/violet_hold/boss_moragg.cpp new file mode 100644 index 000000000..a0800fb27 --- /dev/null +++ b/scripts/northrend/violet_hold/boss_moragg.cpp @@ -0,0 +1,183 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_moragg +SDAuthor: ckegg +SD%Complete: 50% +SDComment: +SDCategory: The Violet Hold +EndScriptData */ + +#include "precompiled.h" +#include "violet_hold.h" + +enum +{ + SPELL_CORROSICE_SALIVA = 54527, + SPELL_OPTIC_LINK = 54396, + SPELL_RAY_PAIN = 59525, + SPELL_RAY_SUFFERING = 54417, +}; + +struct MANGOS_DLL_DECL boss_moraggAI : public ScriptedAI +{ + boss_moraggAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + + bool m_bIsRegularMode; + uint32 m_uiCorrosiveSaliva_Timer; + uint32 m_uiOpticLink_Timer; + uint32 m_uiRay_Timer; + + bool MovementStarted; + + void Reset() + { + MovementStarted = false; + m_uiCorrosiveSaliva_Timer = urand(10000, 11000); + m_uiOpticLink_Timer = urand(25000, 30000); + m_uiRay_Timer = urand(2000, 7000); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + } + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_MORAGG, FAIL); + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, NOT_STARTED);} + else {m_pInstance->SetData(TYPE_PORTAL12, NOT_STARTED);} + } + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + m_pInstance->SetData(TYPE_MORAGG, IN_PROGRESS); + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + } + + void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_MORAGG) != SPECIAL && m_pInstance->GetData(TYPE_MORAGG) != IN_PROGRESS) + return; + + if (!pWho || pWho == m_creature) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } + } + + void StartMovement(uint32 id) + { + m_creature->GetMotionMaster()->MovePoint(id, PortalLoc[id].x, PortalLoc[id].y, PortalLoc[id].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = true; + m_creature->SetInCombatWithZone(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + if (id == 0) + { + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_MORAGG) == SPECIAL && !MovementStarted) + StartMovement(0); + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiCorrosiveSaliva_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_CORROSICE_SALIVA); + m_uiCorrosiveSaliva_Timer = urand(10000, 11000); + } + else m_uiCorrosiveSaliva_Timer -= uiDiff; + + if (m_uiOpticLink_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_OPTIC_LINK); + m_uiOpticLink_Timer = urand(25000, 30000); + } + else m_uiOpticLink_Timer -= uiDiff; + + if (m_uiRay_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(pTarget, urand(0, 1) ? SPELL_RAY_PAIN : SPELL_RAY_SUFFERING); + m_uiRay_Timer = urand(2000, 7000); + } + else m_uiRay_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* pKiller) + { + if (m_pInstance){ + m_pInstance->SetData(TYPE_MORAGG, DONE); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, DONE);} + else {m_pInstance->SetData(TYPE_PORTAL12, DONE);} + } + } +}; + +CreatureAI* GetAI_boss_moragg(Creature* pCreature) +{ + return new boss_moraggAI (pCreature); +} + +void AddSC_boss_moragg() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_moragg"; + newscript->GetAI = &GetAI_boss_moragg; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/violet_hold/boss_xevozz.cpp b/scripts/northrend/violet_hold/boss_xevozz.cpp new file mode 100644 index 000000000..e2ed3f3f4 --- /dev/null +++ b/scripts/northrend/violet_hold/boss_xevozz.cpp @@ -0,0 +1,358 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_xevozz +SDAuthor: ckegg +SD%Complete: 60% +SDComment: +SDCategory: The Violet Hold +EndScriptData */ + +#include "precompiled.h" +#include "violet_hold.h" + +enum +{ + SAY_AGGRO = -1608027, + SAY_SLAY_1 = -1608028, + SAY_SLAY_2 = -1608029, + SAY_SLAY_3 = -1608030, + SAY_DEATH = -1608031, + SAY_SPAWN = -1608032, + SAY_CHARGED = -1608033, + SAY_REPEAT_SUMMON_1 = -1608034, + SAY_REPEAT_SUMMON_2 = -1608035, + SAY_SUMMON_ENERGY = -1608036, + + SPELL_ARCANE_BARRAGE_VOLLEY = 54202, + SPELL_ARCANE_BARRAGE_VOLLEY_H = 59483, + SPELL_ARCANE_BUFFET = 54226, + SPELL_ARCANE_BUFFET_H = 59485, + SPELL_SUMMON_ETHEREAL_SPHERE_1 = 54102, + SPELL_SUMMON_ETHEREAL_SPHERE_2 = 54137, + SPELL_SUMMON_ETHEREAL_SPHERE_3 = 54138, + + NPC_ETHEREAL_SPHERE = 29271, + //NPC_ETHEREAL_SPHERE2 = 32582, // heroic only? + SPELL_ARCANE_POWER = 54160, + SPELL_ARCANE_POWER_H = 59474, + SPELL_SUMMON_PLAYERS = 54164, + SPELL_ARCANE_TEMPEST = 35845, + SPELL_ARCANE_TEMPEST_H = 49366, + SPELL_ETHEREAL_BEACON_VISUAL = 32368 +}; + +struct MANGOS_DLL_DECL boss_xevozzAI : public ScriptedAI +{ + boss_xevozzAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + + bool m_bIsRegularMode; + bool MovementStarted; + + uint32 m_uiSummonEtherealSphere_Timer; + uint32 m_uiArcaneBarrageVolley_Timer; + uint32 m_uiArcaneBuffet_Timer; + uint32 m_uiDespawn_Timer; + + void Reset() + { + m_uiSummonEtherealSphere_Timer = 10000; + m_uiDespawn_Timer = 35000; + m_uiArcaneBarrageVolley_Timer = urand(20000, 22000); + m_uiArcaneBuffet_Timer = m_uiSummonEtherealSphere_Timer + urand(5000, 6000); + DespawnSphere(); + MovementStarted = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + + DoScriptText(SAY_AGGRO, m_creature); + m_pInstance->SetData(TYPE_XEVOZZ, IN_PROGRESS); + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_XEVOZZ, FAIL); + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, NOT_STARTED);} + else {m_pInstance->SetData(TYPE_PORTAL12, NOT_STARTED);} + } + } + + void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_XEVOZZ) != SPECIAL && m_pInstance->GetData(TYPE_XEVOZZ) != IN_PROGRESS) + return; + + if (!pWho || pWho == m_creature) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } + } + + void DespawnSphere() + { + std::list assistList; + GetCreatureListWithEntryInGrid(assistList,m_creature, NPC_ETHEREAL_SPHERE ,150.0f); + + if (assistList.empty()) + return; + + for(std::list::iterator iter = assistList.begin(); iter != assistList.end(); ++iter) + (*iter)->DealDamage((*iter), (*iter)->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + void JustSummoned(Creature* pSummoned) + { + pSummoned->SetSpeedRate(MOVE_RUN, 0.5f); + pSummoned->StopMoving(); + pSummoned->CastSpell(pSummoned, SPELL_ETHEREAL_BEACON_VISUAL, false); + } + + void StartMovement(uint32 id) + { + m_creature->GetMotionMaster()->MovePoint(id, PortalLoc[id].x, PortalLoc[id].y, PortalLoc[id].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = true; + m_creature->SetInCombatWithZone(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + if (id == 0) + { + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_XEVOZZ) == SPECIAL && !MovementStarted) + StartMovement(0); + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiArcaneBarrageVolley_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_ARCANE_BARRAGE_VOLLEY : SPELL_ARCANE_BARRAGE_VOLLEY_H); + m_uiArcaneBarrageVolley_Timer = urand(20000, 22000); + } + else m_uiArcaneBarrageVolley_Timer -= uiDiff; + + if (m_uiArcaneBuffet_Timer) + if (m_uiArcaneBuffet_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ARCANE_BUFFET : SPELL_ARCANE_BUFFET_H); + m_uiArcaneBuffet_Timer = 0; + } + else m_uiArcaneBuffet_Timer -= uiDiff; + + if (m_uiSummonEtherealSphere_Timer < uiDiff) + { + DoScriptText(SAY_SPAWN, m_creature); + DoCast(m_creature, SPELL_SUMMON_ETHEREAL_SPHERE_1); + if (!m_bIsRegularMode) // extra one for heroic + m_creature->SummonCreature(NPC_ETHEREAL_SPHERE, m_creature->GetPositionX()-5+rand()%10, m_creature->GetPositionY()-5+rand()%10, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 40000); + + m_uiSummonEtherealSphere_Timer = 30000; + m_uiArcaneBuffet_Timer = urand(5000, 6000); + m_uiDespawn_Timer= 30000; + } + else m_uiSummonEtherealSphere_Timer -= uiDiff; + + if (m_uiDespawn_Timer < uiDiff) + { + DespawnSphere(); + } + else m_uiDespawn_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + DespawnSphere(); + + if (m_pInstance){ + m_pInstance->SetData(TYPE_XEVOZZ, DONE); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, DONE);} + else {m_pInstance->SetData(TYPE_PORTAL12, DONE);} + } + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0, 2)) + { + case 0: DoScriptText(SAY_SLAY_1, m_creature);break; + case 1: DoScriptText(SAY_SLAY_2, m_creature);break; + case 2: DoScriptText(SAY_SLAY_3, m_creature);break; + } + } +}; + +struct MANGOS_DLL_DECL mob_ethereal_sphereAI : public ScriptedAI +{ + mob_ethereal_sphereAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiSummonPlayers_Timer; + uint32 m_uiRangeCheck_Timer; + uint32 m_uiPhaseCheck_Timer; + bool bNormalPhase; + + + void Reset() + { + m_uiSummonPlayers_Timer = 5000; + m_uiRangeCheck_Timer = 1000; + m_uiPhaseCheck_Timer = 10000; + bNormalPhase = false; + } + + void UpdateAI(const uint32 uiDiff) + { + //Return since we have no target + /* if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return;*/ + if(!bNormalPhase) + { + if (m_uiPhaseCheck_Timer < uiDiff ) + { + bNormalPhase = true; + m_uiPhaseCheck_Timer=3000000; + Creature* pXevozz = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_XEVOZZ)); + m_creature->GetMotionMaster()->MoveFollow(pXevozz, 0, 0); + } + else m_uiPhaseCheck_Timer -= uiDiff; + } + if(bNormalPhase) + { + + if (m_uiRangeCheck_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_ARCANE_TEMPEST: SPELL_ARCANE_TEMPEST_H); + if (m_pInstance) + { + if (Creature* pXevozz = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_XEVOZZ))) + { + float fDistance = m_creature->GetDistance2d(pXevozz); + if (fDistance <= 3) + { + m_creature->CastSpell(pXevozz, SPELL_ARCANE_POWER_H, false); + // DoCast(pXevozz,SPELL_ARCANE_POWER_H); + } + } + } + m_uiRangeCheck_Timer = 1000; + } + else m_uiRangeCheck_Timer -= uiDiff; + + if (m_uiSummonPlayers_Timer < uiDiff) + { + if(Creature* pXevozz = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_XEVOZZ)))) + { + float fDistance = m_creature->GetDistance2d(pXevozz); + + if(fDistance<=20 && fDistance >6) + { + DoCast(m_creature, SPELL_SUMMON_PLAYERS); // not working right + + Map* pMap = m_creature->GetMap(); + if (pMap && pMap->IsDungeon()) + { + Map::PlayerList const &PlayerList = pMap->GetPlayers(); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (i->getSource()->isAlive()) + DoTeleportPlayer(i->getSource(), m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), i->getSource()->GetOrientation()); + } + + m_uiSummonPlayers_Timer = 15000; + } + } + } + else m_uiSummonPlayers_Timer -= uiDiff; + } + } +}; + +CreatureAI* GetAI_boss_xevozz(Creature* pCreature) +{ + return new boss_xevozzAI (pCreature); +} + +CreatureAI* GetAI_mob_ethereal_sphere(Creature* pCreature) +{ + return new mob_ethereal_sphereAI (pCreature); +} + +void AddSC_boss_xevozz() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_xevozz"; + newscript->GetAI = &GetAI_boss_xevozz; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ethereal_sphere"; + newscript->GetAI = &GetAI_mob_ethereal_sphere; + newscript->RegisterSelf(); +} diff --git a/scripts/northrend/violet_hold/boss_zuramat.cpp b/scripts/northrend/violet_hold/boss_zuramat.cpp new file mode 100644 index 000000000..6d15b659f --- /dev/null +++ b/scripts/northrend/violet_hold/boss_zuramat.cpp @@ -0,0 +1,296 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_zuramat +SDAuthor: ckegg +SD%Complete: 60% +SDComment: +SDCategory: The Violet Hold +EndScriptData */ + +#include "precompiled.h" +#include "violet_hold.h" + +enum +{ + SAY_AGGRO = -1608037, + SAY_SLAY_1 = -1608038, + SAY_SLAY_2 = -1608039, + SAY_SLAY_3 = -1608040, + SAY_DEATH = -1608041, + SAY_SPAWN = -1608042, + SAY_SHIELD = -1608043, + SAY_WHISPER = -1608044, + + SPELL_SHROUD_OF_DARKNESS = 54524, + SPELL_SHROUD_OF_DARKNESS_H = 59745, + SPELL_SUMMON_VOID_SENTRY = 54369, + SPELL_VOID_SHIFT = 54361, + SPELL_VOID_SHIFT_H = 59743, + + NPC_VOID_SENTRY = 29364, + SPELL_VOID_SENTRY_AURA = 54341, + SPELL_VOID_SENTRY_AURA_H = 54351, + SPELL_SHADOW_BOLT_VOLLEY = 54358, // 54342? 54358? + SPELL_SHADOW_BOLT_VOLLEY_H = 59747, + SPELL_VOID_SHIFTED = 54343 +}; + +struct MANGOS_DLL_DECL boss_zuramatAI : public ScriptedAI +{ + boss_zuramatAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + ScriptedInstance *m_pInstance; + + bool m_bIsRegularMode; + bool MovementStarted; + std::list m_lSentryGUIDList; + + uint32 m_uiShroudDarkness_Timer; + uint32 m_uiVoidShift_Timer; + uint32 m_uiSummonVoidSentry_Timer; + + void Reset() + { + m_uiShroudDarkness_Timer = urand(8000, 9000); + m_uiSummonVoidSentry_Timer = 10000; + m_uiVoidShift_Timer = 10000; + MovementStarted = false; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + } + + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_ZURAMAT, FAIL); + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) + m_pInstance->SetData(TYPE_PORTAL6, NOT_STARTED); + else + m_pInstance->SetData(TYPE_PORTAL12, NOT_STARTED); + } + } + + void Aggro(Unit* pWho) + { + if (!m_pInstance) return; + DoScriptText(SAY_AGGRO, m_creature); + m_pInstance->SetData(TYPE_ZURAMAT, IN_PROGRESS); + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + } + + void AttackStart(Unit* pWho) + { + if (!m_pInstance) + return; + + if (m_pInstance->GetData(TYPE_ZURAMAT) != SPECIAL && m_pInstance->GetData(TYPE_ZURAMAT) != IN_PROGRESS) + return; + + if (!pWho || pWho == m_creature) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho); + } + } + + void JustSummoned(Creature* pSummoned) + { + m_lSentryGUIDList.push_back(pSummoned->GetGUID()); + //pSummoned->AddThreat(m_creature); + //pSummoned->AI()->AttackStart(m_creature); + } + + void DespawnSentry() + { + if (m_lSentryGUIDList.empty()) + return; + + for(std::list::iterator itr = m_lSentryGUIDList.begin(); itr != m_lSentryGUIDList.end(); ++itr) + { + if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) + { + if (pTemp->isAlive()) + //pTemp->ForcedDespawn(); + pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + m_lSentryGUIDList.clear(); + } + + void StartMovement(uint32 id) + { + m_creature->GetMotionMaster()->MovePoint(id, PortalLoc[id].x, PortalLoc[id].y, PortalLoc[id].z); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + MovementStarted = true; + m_creature->SetInCombatWithZone(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || !MovementStarted) return; + if (id == 0) + { + MovementStarted = false; + m_creature->GetMotionMaster()->MovementExpired(); + SetCombatMovement(true); + m_creature->SetInCombatWithZone(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_pInstance->GetData(TYPE_ZURAMAT) == SPECIAL && !MovementStarted) + StartMovement(0); + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiShroudDarkness_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHROUD_OF_DARKNESS : SPELL_SHROUD_OF_DARKNESS_H); + m_uiShroudDarkness_Timer = urand(7000, 8000); + } + else m_uiShroudDarkness_Timer -= uiDiff; + + if (m_uiVoidShift_Timer < uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + DoCast(pTarget, m_bIsRegularMode ? SPELL_VOID_SHIFT : SPELL_VOID_SHIFT_H); + pTarget->CastSpell(pTarget, SPELL_VOID_SHIFTED, true); + } + m_uiVoidShift_Timer = urand(10000, 11000); + } + else m_uiVoidShift_Timer -= uiDiff; + + if (m_uiSummonVoidSentry_Timer < uiDiff) + { + m_creature->SummonCreature(NPC_VOID_SENTRY, m_creature->GetPositionX()-10+rand()%20, m_creature->GetPositionY()-10+rand()%20, m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + m_uiSummonVoidSentry_Timer = urand(10000, 10000); + } + else m_uiSummonVoidSentry_Timer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + DespawnSentry(); + + if (m_pInstance){ + m_pInstance->SetData(TYPE_ZURAMAT, DONE); + if(m_pInstance->GetData(TYPE_PORTAL6) == IN_PROGRESS) {m_pInstance->SetData(TYPE_PORTAL6, DONE);} + else {m_pInstance->SetData(TYPE_PORTAL12, DONE);} + } + } + + void KilledUnit(Unit* pVictim) + { + switch(urand(0, 2)) + { + case 0: DoScriptText(SAY_SLAY_1, m_creature);break; + case 1: DoScriptText(SAY_SLAY_2, m_creature);break; + case 2: DoScriptText(SAY_SLAY_3, m_creature);break; + } + } +}; + +struct MANGOS_DLL_DECL mob_zuramat_sentryAI : public ScriptedAI +{ + mob_zuramat_sentryAI(Creature *pCreature) : ScriptedAI(pCreature) + { + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + SetCombatMovement(false); + Reset(); + } + ScriptedInstance *m_pInstance; + bool m_bIsRegularMode; + uint32 m_uiShadowBoltVolley_Timer; + + void Reset() + { + m_uiShadowBoltVolley_Timer = 3000; +// DoCast(m_creature, m_bIsRegularMode ? SPELL_VOID_SENTRY_AURA_H : SPELL_VOID_SENTRY_AURA); +// m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);*/ + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHADOW_BOLT_VOLLEY : SPELL_SHADOW_BOLT_VOLLEY_H); + } + + void DamageTaken(Unit *killer, uint32 &damage) + { + if(!killer->HasAura(SPELL_VOID_SHIFTED)) + damage=0; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiShadowBoltVolley_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_SHADOW_BOLT_VOLLEY : SPELL_SHADOW_BOLT_VOLLEY_H); + m_uiShadowBoltVolley_Timer = 3000; + } + else m_uiShadowBoltVolley_Timer -= uiDiff; + } + +}; + +CreatureAI* GetAI_boss_zuramat(Creature* pCreature) +{ + return new boss_zuramatAI (pCreature); +} + +CreatureAI* GetAI_mob_zuramat_sentry(Creature* pCreature) +{ + return new mob_zuramat_sentryAI (pCreature); +} + +void AddSC_boss_zuramat() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_zuramat"; + newscript->GetAI = &GetAI_boss_zuramat; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_zuramat_sentry"; + newscript->GetAI = &GetAI_mob_zuramat_sentry; + newscript->RegisterSelf(); + +} diff --git a/scripts/northrend/violet_hold/instance_violet_hold.cpp b/scripts/northrend/violet_hold/instance_violet_hold.cpp index 10b637b53..64cd48bec 100644 --- a/scripts/northrend/violet_hold/instance_violet_hold.cpp +++ b/scripts/northrend/violet_hold/instance_violet_hold.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,384 +15,413 @@ */ /* ScriptData -SDName: Instance_Violet_Hold -SD%Complete: 50 -SDComment: "experimental" use of header/source object -SDCategory: Violet Hold +SDName: Instance The Violet Hold +SD%Complete: 60% +SDComment: +SDCategory: The Violet Hold EndScriptData */ #include "precompiled.h" #include "violet_hold.h" -instance_violet_hold::instance_violet_hold(Map* pMap) : ScriptedInstance(pMap), - m_uiSinclariGUID(0), - m_uiSinclariAltGUID(0), - m_uiErekemGUID(0), - m_uiMoraggGUID(0), - m_uiIchoronGUID(0), - m_uiXevozzGUID(0), - m_uiLavanthorGUID(0), - m_uiZuramatGUID(0), - - m_uiCellErekemGuard_LGUID(0), - m_uiCellErekemGuard_RGUID(0), - m_uiIntroCrystalGUID(0), - - m_uiWorldState(0), - m_uiWorldStateSealCount(100), - m_uiWorldStatePortalCount(0), - - m_uiPortalId(0), - m_uiPortalTimer(0), - m_uiMaxCountPortalLoc(0) +/* The Violet Hold encounters: +0 Whole Event +1 Rift +2 Erekem +3 Moragg +4 Ichoron +5 Xevozz +6 Lavanthor +7 Zuramat +*/ +//inline uint32 RandRiftBoss() { return ((rand()%2) ? NPC_GUARDIAN : NPC_KEEPER); } + +struct MANGOS_DLL_DECL instance_violet_hold : public ScriptedInstance { - Initialize(); -} - -void instance_violet_hold::Initialize() -{ - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - m_uiMaxCountPortalLoc = (sizeof(afPortalLocation)/sizeof(sPortalData)) - 1; -} - -void instance_violet_hold::ResetVariables() -{ - m_uiWorldStateSealCount = 100; - m_uiWorldStatePortalCount = 0; -} - -void instance_violet_hold::ResetAll() -{ - ResetVariables(); - UpdateWorldState(false); - CallGuards(true); - SetIntroPortals(false); -} - -void instance_violet_hold::OnCreatureCreate(Creature* pCreature) -{ - switch(pCreature->GetEntry()) + instance_violet_hold(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint32 m_auiEncounter[MAX_ENCOUNTER+1]; + std::string m_strInstData; + + bool bIsInBoss; + + uint8 m_uiLastBossID; + uint8 m_uiLastBossIDConst; + uint8 m_uiRiftPortalCount; + uint32 m_uiShieldPercent; + uint32 m_uiDisruptions; + int8 m_uiPortalTime; + + uint64 m_uiSinclariGUID; + uint64 m_uiNPCSealDoorGUID; + + uint64 m_uiErekemGUID; + uint64 m_uiMoraggGUID; + uint64 m_uiIchoronGUID; + uint64 m_uiXevozzGUID; + uint64 m_uiLavanthorGUID; + uint64 m_uiZuramatGUID; + + uint64 m_uiSealDoorGUID; + uint64 m_uiErekemDoorGUID; + uint64 m_uiErekemDoorLeftGUID; + uint64 m_uiErekemDoorRightGUID; + uint64 m_uiMoraggDoorGUID; + uint64 m_uiIchoronDoorGUID; + uint64 m_uiXevozzDoorGUID; + uint64 m_uiLavanthorDoorGUID; + uint64 m_uiZuramatDoorGUID; + + void Initialize() { - case NPC_SINCLARI: m_uiSinclariGUID = pCreature->GetGUID(); break; - case NPC_SINCLARI_ALT: m_uiSinclariAltGUID = pCreature->GetGUID(); break; - case NPC_DOOR_SEAL: m_uiDoorSealGUID = pCreature->GetGUID(); break; + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + m_auiEncounter[i] = NOT_STARTED; + + m_uiSinclariGUID = 0; + m_uiNPCSealDoorGUID = 0; + m_uiLastBossIDConst = 0; + + m_uiErekemGUID = 0; + m_uiMoraggGUID = 0; + m_uiIchoronGUID = 0; + m_uiXevozzGUID = 0; + m_uiLavanthorGUID = 0; + m_uiZuramatGUID = 0; + + m_uiDisruptions = 0; + + m_uiSealDoorGUID = 0; + m_uiErekemDoorGUID = 0; + m_uiErekemDoorLeftGUID = 0; + m_uiErekemDoorRightGUID = 0; + m_uiMoraggDoorGUID = 0; + m_uiIchoronDoorGUID = 0; + m_uiXevozzDoorGUID = 0; + m_uiLavanthorDoorGUID = 0; + m_uiZuramatDoorGUID = 0; + Clear(); + } - case NPC_EREKEM: - m_lRandomBossList.push_back(pCreature->GetEntry()); - m_uiErekemGUID = pCreature->GetGUID(); - break; - case NPC_MORAGG: - m_lRandomBossList.push_back(pCreature->GetEntry()); - m_uiMoraggGUID = pCreature->GetGUID(); - break; - case NPC_ICHORON: - m_lRandomBossList.push_back(pCreature->GetEntry()); - m_uiIchoronGUID = pCreature->GetGUID(); - break; - case NPC_XEVOZZ: - m_lRandomBossList.push_back(pCreature->GetEntry()); - m_uiXevozzGUID = pCreature->GetGUID(); - break; - case NPC_LAVANTHOR: - m_lRandomBossList.push_back(pCreature->GetEntry()); - m_uiLavanthorGUID = pCreature->GetGUID(); - break; - case NPC_ZURAMAT: - m_lRandomBossList.push_back(pCreature->GetEntry()); - m_uiZuramatGUID = pCreature->GetGUID(); - break; + void Clear(){ + bIsInBoss = false; - case NPC_PORTAL_INTRO: - m_lIntroPortalList.push_back(pCreature->GetGUID()); - break; - case NPC_HOLD_GUARD: - m_lGuardsList.push_back(pCreature->GetGUID()); - break; + m_uiLastBossID = 0; + m_uiRiftPortalCount = 0; + m_uiPortalTime = 0; + m_uiShieldPercent = 100; } -} -void instance_violet_hold::OnObjectCreate(GameObject* pGo) -{ - switch(pGo->GetEntry()) + void InitWorldState(bool Enable = true) { - case GO_CELL_LAVANTHOR: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_LAVANTHOR, pGo->GetGUID())); - break; - case GO_CELL_MORAGG: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_MORAGG, pGo->GetGUID())); - break; - case GO_CELL_ZURAMAT: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_ZURAMAT, pGo->GetGUID())); - break; - case GO_CELL_XEVOZZ: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_XEVOZZ, pGo->GetGUID())); - break; - case GO_CELL_ICHORON: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_ICHORON, pGo->GetGUID())); - break; - case GO_CELL_EREKEM: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_EREKEM, pGo->GetGUID())); - break; - case GO_CELL_EREKEM_GUARD_L: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_EREKEM, pGo->GetGUID())); - break; - case GO_CELL_EREKEM_GUARD_R: - m_mBossToCellMap.insert(BossToCellMap::value_type(NPC_EREKEM, pGo->GetGUID())); - break; - - case GO_INTRO_CRYSTAL: - m_uiIntroCrystalGUID = pGo->GetGUID(); - break; - case GO_PRISON_SEAL_DOOR: - m_uiDoorSealGUID = pGo->GetGUID(); - break; + DoUpdateWorldState(WORLD_STATE_VH,Enable ? 1 : 0); + DoUpdateWorldState(WORLD_STATE_VH_PRISON,100); + DoUpdateWorldState(WORLD_STATE_VH_PORTALS,0); } -} - -void instance_violet_hold::UpdateCellForBoss(uint32 uiBossEntry) -{ - BossToCellMap::const_iterator itrCellLower = m_mBossToCellMap.lower_bound(uiBossEntry); - BossToCellMap::const_iterator itrCellUpper = m_mBossToCellMap.upper_bound(uiBossEntry); - - if (itrCellLower == itrCellUpper) - return; - for(BossToCellMap::const_iterator itr = itrCellLower; itr != itrCellUpper; ++itr) - DoUseDoorOrButton(itr->second); -} - -void instance_violet_hold::UpdateWorldState(bool bEnable) -{ - if (bEnable) - m_uiWorldState = 1; - else - m_uiWorldState = 0; - - DoUpdateWorldState(WORLD_STATE_ID, m_uiWorldState); - DoUpdateWorldState(WORLD_STATE_SEAL, m_uiWorldStateSealCount); - DoUpdateWorldState(WORLD_STATE_PORTALS, m_uiWorldStatePortalCount); -} + void OnPlayerEnter(Player* pPlayer) + { + if(m_auiEncounter[0] != NOT_STARTED) + pPlayer->SendUpdateWorldState(WORLD_STATE_VH,1); + } -void instance_violet_hold::OnPlayerEnter(Player* pPlayer) -{ - UpdateWorldState(m_auiEncounter[0] == IN_PROGRESS ? true : false); -} + bool IsEncounterInProgress() const + { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) + return true; -void instance_violet_hold::SetData(uint32 uiType, uint32 uiData) -{ - debug_log("SD2: instance_violet_hold: SetData got type % u, data %u.", uiType, uiData); + return false; + } - switch(uiType) + void OnCreatureCreate(Creature* pCreature) { - case TYPE_MAIN: - { - if (uiData == m_auiEncounter[0]) - return; - - switch(uiData) - { - case NOT_STARTED: - ResetAll(); - break; - case IN_PROGRESS: - DoUseDoorOrButton(m_uiDoorSealGUID); - SetRandomBosses(); - UpdateWorldState(); - m_uiPortalId = urand(0, 2); - m_uiPortalTimer = 15000; - break; - case FAIL: - if (Creature* pSinclari = instance->GetCreature(m_uiSinclariGUID)) - pSinclari->Respawn(); - - break; - case DONE: - break; - case SPECIAL: - break; - } - m_auiEncounter[0] = uiData; - break; - } - case TYPE_SEAL: - m_auiEncounter[1] = uiData; - break; - case TYPE_PORTAL: + switch(pCreature->GetEntry()) { - switch(uiData) - { - case SPECIAL: // timer to next - m_uiPortalTimer = 90000; - break; - case DONE: // portal done, set timer to 5 secs - m_uiPortalTimer = 5000; - break; - } - m_auiEncounter[2] = uiData; - break; + case NPC_SINCLARI: + m_uiSinclariGUID = pCreature->GetGUID(); + break; + case NPC_DOOR_SEAL: + m_uiNPCSealDoorGUID = pCreature->GetGUID(); + break; + case NPC_EREKEM: + m_uiErekemGUID = pCreature->GetGUID(); + break; + case NPC_MORAGG: + m_uiMoraggGUID = pCreature->GetGUID(); + break; + case NPC_ICHORON: + m_uiIchoronGUID = pCreature->GetGUID(); + break; + case NPC_XEVOZZ: + m_uiXevozzGUID = pCreature->GetGUID(); + break; + case NPC_LAVANTHOR: + m_uiLavanthorGUID = pCreature->GetGUID(); + break; + case NPC_ZURAMAT: + m_uiZuramatGUID = pCreature->GetGUID(); + break; } } -} -void instance_violet_hold::SetIntroPortals(bool bDeactivate) -{ - for(std::list::iterator i = m_lIntroPortalList.begin(); i != m_lIntroPortalList.end(); ++i) + void OnObjectCreate(GameObject* pGo) { - if (Creature* pPortal = instance->GetCreature(*i)) + switch(pGo->GetEntry()) { - if (bDeactivate) - pPortal->ForcedDespawn(); - else - pPortal->Respawn(); + case GO_DOOR_SEAL: + m_uiSealDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_EREKEM: + m_uiErekemDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_EREKEM_LEFT: + m_uiErekemDoorLeftGUID = pGo->GetGUID(); + break; + case GO_DOOR_EREKEM_RIGHT: + m_uiErekemDoorRightGUID = pGo->GetGUID(); + break; + case GO_DOOR_MORAGG: + m_uiMoraggDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_ICHORON: + m_uiIchoronDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_XEVOZZ: + m_uiXevozzDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_LAVANTHOR: + m_uiLavanthorDoorGUID = pGo->GetGUID(); + break; + case GO_DOOR_ZURAMAT: + m_uiZuramatDoorGUID = pGo->GetGUID(); + break; } } -} -void instance_violet_hold::SpawnPortal() -{ - if (const sPortalData* pData = GetPortalData()) + void SetData(uint32 uiType, uint32 uiData) { - if (Creature* pController = instance->GetCreature(m_uiSinclariAltGUID)) + switch(uiType) { - uint32 uiPortalEntry; - - switch(pData->pPortalType) - { - case PORTAL_TYPE_NORM: uiPortalEntry = NPC_PORTAL; break; - case PORTAL_TYPE_SQUAD: - case PORTAL_TYPE_BOSS: uiPortalEntry = NPC_PORTAL_ELITE; break; - } + case TYPE_EVENT: + if (uiData == IN_PROGRESS) + { + Clear(); + InitWorldState(); + } + else if (uiData == FAIL || uiData == DONE) + { + DoUpdateWorldState(WORLD_STATE_VH, 0); + DoUseDoorOrButton(m_uiSealDoorGUID); + if (Creature* pSinclari = instance->GetCreature(m_uiSinclariGUID)) + {pSinclari->ForcedDespawn(1000);}} + m_auiEncounter[0] = uiData; + break; + case TYPE_EREKEM: + m_auiEncounter[2] = uiData; + if (uiData == IN_PROGRESS) bIsInBoss = true; + break; + case TYPE_MORAGG: + m_auiEncounter[3] = uiData; + if (uiData == IN_PROGRESS) bIsInBoss = true; + break; + case TYPE_ICHORON: + m_auiEncounter[4] = uiData; + if (uiData == IN_PROGRESS) bIsInBoss = true; + break; + case TYPE_XEVOZZ: + m_auiEncounter[5] = uiData; + if (uiData == IN_PROGRESS) bIsInBoss = true; + break; + case TYPE_LAVANTHOR: + m_auiEncounter[6] = uiData; + if (uiData == IN_PROGRESS) bIsInBoss = true; + break; + case TYPE_ZURAMAT: + m_auiEncounter[7] = uiData; + if (uiData == IN_PROGRESS) bIsInBoss = true; + break; + case TYPE_CYANIGOSA: + m_auiEncounter[8] = uiData; + if (uiData == IN_PROGRESS) bIsInBoss = true; + break; + case TYPE_PORTAL6: + m_auiEncounter[9] = uiData; + break; + case TYPE_PORTAL12: + m_auiEncounter[10] = uiData; + break; + case TYPE_RIFT: + if (uiData == FAIL) DoUseDoorOrButton(m_uiSealDoorGUID); + m_auiEncounter[1] = uiData; + break; + case TYPE_DOOR: + if (uiData == SPECIAL) + { + m_uiShieldPercent = m_uiShieldPercent - 5; + if(m_uiShieldPercent > 0) + DoUpdateWorldState(WORLD_STATE_VH_PRISON, m_uiShieldPercent); + else + { DoUpdateWorldState(WORLD_STATE_VH, 0); + DoUseDoorOrButton(m_uiSealDoorGUID); + m_auiEncounter[0] = FAIL; + } + } + break; + case TYPE_DISRUPTIONS: + m_uiDisruptions = uiData; +// DoUpdateWorldState(WORLD_STATE_VH_PRISON, 100-m_uiDisruptions*5); + break; + case TYPE_LASTBOSS_ID: + m_uiLastBossIDConst = uiData; + break; - pController->SummonCreature(uiPortalEntry, pData->fX, pData->fY, pData->fZ, pData->fOrient, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 1800*IN_MILLISECONDS); } - } -} + if (uiData == DONE) + { + bIsInBoss = false; + OUT_SAVE_INST_DATA; -void instance_violet_hold::SetPortalId() -{ - if (IsCurrentPortalForTrash()) - { - int iTemp = rand()%(m_uiMaxCountPortalLoc - 1); + std::ostringstream saveStream; - if (iTemp >= m_uiPortalId) - ++iTemp; + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + saveStream << m_auiEncounter[i] << " "; - debug_log("SD2: instance_violet_hold: SetPortalId %i, old was id %u.", iTemp, m_uiPortalId); + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } - m_uiPortalId = iTemp; - } - else - { - debug_log("SD2: instance_violet_hold: SetPortalId %u (is boss), old was id %u.", m_uiMaxCountPortalLoc, m_uiPortalId); - m_uiPortalId = m_uiMaxCountPortalLoc; } -} -void instance_violet_hold::SetRandomBosses() -{ - while (m_lRandomBossList.size() > 2) + uint32 GetData(uint32 uiType) { - uint32 uiPosition = urand(0, m_lRandomBossList.size()-1); - - for(std::list::iterator itr = m_lRandomBossList.begin(); itr != m_lRandomBossList.end(); ++itr, --uiPosition) + switch(uiType) { - if (!*itr) - continue; - - if (!uiPosition) + case TYPE_EVENT: + return m_auiEncounter[0]; + case TYPE_EREKEM: + return m_auiEncounter[2]; + case TYPE_MORAGG: + return m_auiEncounter[3]; + case TYPE_ICHORON: + return m_auiEncounter[4]; + case TYPE_XEVOZZ: + return m_auiEncounter[5]; + case TYPE_LAVANTHOR: + return m_auiEncounter[6]; + case TYPE_ZURAMAT: + return m_auiEncounter[7]; + case TYPE_CYANIGOSA: + return m_auiEncounter[8]; + case TYPE_PORTAL6: + return m_auiEncounter[9]; + case TYPE_PORTAL12: + return m_auiEncounter[10]; + case TYPE_RIFT: + return m_uiRiftPortalCount; + case TYPE_LASTBOSS_ID: + return m_uiLastBossIDConst; + case TYPE_LASTBOSS: { - m_lRandomBossList.erase(itr); - break; + if (m_uiLastBossID == 0) + m_uiLastBossID = urand(2, 7); + else + { + m_uiLastBossID = urand(2, 7); + if ( m_auiEncounter[2] == DONE && + m_auiEncounter[3] == DONE && + m_auiEncounter[4] == DONE && + m_auiEncounter[5] == DONE && + m_auiEncounter[6] == DONE && + m_auiEncounter[7] == DONE) return 0; + while ( m_auiEncounter[m_uiLastBossID] == DONE + || m_auiEncounter[m_uiLastBossID] == IN_PROGRESS + || m_auiEncounter[m_uiLastBossID] == SPECIAL ) + { + m_uiLastBossID = urand(2, 7); + } + } + return m_uiLastBossID; } + case DATA_BOSSTIME: + return bIsInBoss; + case TYPE_DISRUPTIONS: + return m_uiDisruptions; } + return 0; } - for(std::list::iterator itr = m_lRandomBossList.begin(); itr != m_lRandomBossList.end(); ++itr) - debug_log("SD2: instance_violet_hold random boss is entry %u", *itr); -} - -void instance_violet_hold::CallGuards(bool bRespawn) -{ - for(std::list::iterator i = m_lGuardsList.begin(); i != m_lGuardsList.end(); ++i) + uint64 GetData64(uint32 uiData) { - if (Creature* pGuard = instance->GetCreature(*i)) + switch(uiData) { - if (bRespawn) - { - pGuard->Respawn(); - } - else if (pGuard->isAlive()) - { - pGuard->AI()->EnterEvadeMode(); - - if (Creature* pSinclari = instance->GetCreature(m_uiSinclariGUID)) - pGuard->GetMotionMaster()->MoveFollow(pSinclari, 0.0f, 0.0f); - - pGuard->ForcedDespawn(20000); - } + case DATA_EREKEM: + return m_uiErekemGUID; + case DATA_MORAGG: + return m_uiMoraggGUID; + case DATA_ICHORON: + return m_uiIchoronGUID; + case DATA_XEVOZZ: + return m_uiXevozzGUID; + case DATA_LAVANTHOR: + return m_uiLavanthorGUID; + case DATA_ZURAMAT: + return m_uiZuramatGUID; + case DATA_SINCLARI: + return m_uiSinclariGUID; + case DATA_NPC_SEAL_DOOR: + return m_uiNPCSealDoorGUID; + case DATA_SEAL_DOOR: + return m_uiSealDoorGUID; + case DATA_EREKEM_DOOR: + return m_uiErekemDoorGUID; + case DATA_EREKEM_DOOR_L: + return m_uiErekemDoorLeftGUID; + case DATA_EREKEM_DOOR_R: + return m_uiErekemDoorRightGUID; + case DATA_MORAGG_DOOR: + return m_uiMoraggDoorGUID; + case DATA_ICHORON_DOOR: + return m_uiIchoronDoorGUID; + case DATA_XEVOZZ_DOOR: + return m_uiXevozzDoorGUID; + case DATA_LAVANTHOR_DOOR: + return m_uiLavanthorDoorGUID; + case DATA_ZURAMAT_DOOR: + return m_uiZuramatDoorGUID; } + return 0; } -} -void instance_violet_hold::ProcessActivationCrystal(Unit* pUser, bool bIsIntro) -{ - if (Creature* pSummon = pUser->SummonCreature(NPC_DEFENSE_SYSTEM, fDefenseSystemLoc[0], fDefenseSystemLoc[1], fDefenseSystemLoc[2], fDefenseSystemLoc[3], TEMPSUMMON_TIMED_DESPAWN, 10000)) +const char* Save() { - pSummon->CastSpell(pSummon, SPELL_DEFENSE_SYSTEM_VISUAL, true); - - // TODO: figure out how the rest work - // NPC's NPC_DEFENSE_DUMMY_TARGET are probably channeling some spell to the defense system + return m_strInstData.c_str(); } - if (bIsIntro) - DoUseDoorOrButton(m_uiIntroCrystalGUID); - - // else, kill (and despawn?) certain trash mobs. Also boss affected, but not killed. -} - -uint32 instance_violet_hold::GetRandomPortalEliteEntry() -{ - return (urand(0, 1) ? NPC_PORTAL_GUARDIAN : NPC_PORTAL_KEEPER); -} - -uint32 instance_violet_hold::GetRandomMobForNormalPortal() -{ - switch(urand(1, 4)) +void Load(const char* strIn) { - case 1: return NPC_AZURE_INVADER; - case 2: return NPC_MAGE_HUNTER; - case 3: return NPC_AZURE_SPELLBREAKER; - case 4: return NPC_AZURE_BINDER; - } - - return 0; -} + if (!strIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } -uint64 instance_violet_hold::GetData64(uint32 uiData) -{ - return 0; -} + OUT_LOAD_INST_DATA(strIn); -void instance_violet_hold::Update(uint32 uiDiff) -{ - if (m_auiEncounter[0] != IN_PROGRESS) - return; + std::istringstream loadStream(strIn); - if (m_uiPortalTimer) - { - if (m_uiPortalTimer <= uiDiff) + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) { - DoUpdateWorldState(WORLD_STATE_PORTALS, ++m_uiWorldStatePortalCount); - - SetPortalId(); - SpawnPortal(); + loadStream >> m_auiEncounter[i]; - m_uiPortalTimer = 0; + if (m_auiEncounter[i] == IN_PROGRESS && i != 1) + m_auiEncounter[i] = NOT_STARTED; } - else - m_uiPortalTimer -= uiDiff; + + OUT_LOAD_INST_DATA_COMPLETE; } -} +}; InstanceData* GetInstanceData_instance_violet_hold(Map* pMap) { @@ -404,6 +433,6 @@ void AddSC_instance_violet_hold() Script *newscript; newscript = new Script; newscript->Name = "instance_violet_hold"; - newscript->GetInstanceData = GetInstanceData_instance_violet_hold; + newscript->GetInstanceData = &GetInstanceData_instance_violet_hold; newscript->RegisterSelf(); } diff --git a/scripts/northrend/violet_hold/violet_hold.cpp b/scripts/northrend/violet_hold/violet_hold.cpp index 3832167bc..3a63b78a8 100644 --- a/scripts/northrend/violet_hold/violet_hold.cpp +++ b/scripts/northrend/violet_hold/violet_hold.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -15,58 +15,581 @@ */ /* ScriptData -SDName: Violet_Hold -SD%Complete: 40 -SDComment: -SDCategory: Violet Hold +SDName: violet_hold +SDAuthor: ckegg, modified by rsa +SD%Complete: 60 +SDComment: +SDCategory: The Violet Hold EndScriptData */ -/* ContentData -go_activation_crystal -npc_door_seal -npc_sinclari -npc_teleportation_portal -EndContentData */ - #include "precompiled.h" #include "violet_hold.h" #include "escort_ai.h" +enum +{ + SPELL_TELEPORT_INSIDE = 62139, + SPELL_SHIELD_DISRUPTION = 58291, + + //DRAGONS SPELLS + //Azure Captain + SPELL_MORTAL_STRIKE = 32736, + SPELL_WHIRLWIND = 41057, + + //Azure Raider + SPELL_CONCUSSION_BLOW = 52719, + SPELL_MAGIC_REFLECTION = 60158, + + //Azure Sorceror + SPELL_ARCANE_STREAM = 60181, + SPELL_ARCANE_STREAM_H = 60204, + SPELL_MANA_DETONATION = 60182, + SPELL_MANA_DETONATION_H = 60205, + + //Azure stalker + SPELL_BACKSTAB = 58471, + SPELL_TACTICAL_BLINK = 58470, + AZURE_SAY_AGGRO_1 = -1608055, + AZURE_SAY_AGGRO_2 = -1608056, + AZURE_SAY_AGGRO_3 = -1608057, + AZURE_SAY_AGGRO_4 = -1608058, + PORTAL_KEEPER_GUARDIAN_AGGRO_1 = -1608059, + PORTAL_KEEPER_GUARDIAN_AGGRO_2 = -1608060, + PORTAL_KEEPER_GUARDIAN_AGGRO_3 = -1608061, + PORTAL_KEEPER_GUARDIAN_DEATH_1 = -1608062, + PORTAL_KEEPER_GUARDIAN_DEATH_2 = -1608063, + PORTAL_KEEPER_GUARDIAN_DEATH_3 = -1608064, + AZURE_CAPTAIN_AGGRO_1 = -1608065 + +}; + +uint32 m_uiNextPortal_Timer; /*###### -## go_activation_crystal +## mob_vh_dragons +## This script is for ALL mobs which are spawned from portals, +## they have to be scripted in SD2 because in EventAI you cant +## check for distance from door seal :/ +## (Intro not implented yet) ######*/ - -bool GOHello_go_activation_crystal(Player* pPlayer, GameObject* pGo) +struct MANGOS_DLL_DECL mob_vh_dragonsAI : public ScriptedAI { - if (instance_violet_hold* pInstance = (instance_violet_hold*)pGo->GetInstanceData()) - pInstance->ProcessActivationCrystal(pPlayer); + mob_vh_dragonsAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegular = pCreature->GetMap()->IsRegularDifficulty(); + WayPointList.clear(); + Reset(); + } - return false; -} + ScriptedInstance* m_pInstance; + bool m_bIsRegular; + uint32 creatureEntry; + uint32 motherPortalID; + uint32 WalkTimer; + int8 portalLoc; + bool IsWalking; + bool IsInCombat; + bool MovementStarted; + Creature* pDoorSeal; + + std::list WayPointList; + std::list::iterator WayPoint; + + //Azure Captain + uint32 m_uiMortalStrike_Timer; + uint32 m_uiWhirlwind_Timer; + + //Azure Raider + uint32 m_uiConcussionBlow_Timer; + uint32 m_uiMagicReflection_Timer; + + //Azure Sorceror + uint32 m_uiArcaneStream_Timer; + uint32 m_uiManaDetonation_Timer; + + //Azure Stalker + uint32 m_uiBackstab_Timer; + uint32 m_uiBlink_Timer; + + void Reset(){ + creatureEntry = m_creature->GetEntry(); + motherPortalID = 0; + WalkTimer = 200; + portalLoc = -1; + IsWalking = false; + IsInCombat = false; + MovementStarted = false; + pDoorSeal = GetClosestCreatureWithEntry(m_creature, NPC_DOOR_SEAL, 150.0f); + + //Azure Captain + m_uiMortalStrike_Timer = 3000; + m_uiWhirlwind_Timer = 5000; + + //Azure Raider + m_uiConcussionBlow_Timer = 3000; + m_uiMagicReflection_Timer = 10000; + + //Azure Sorceror + m_uiArcaneStream_Timer = 5000; + m_uiManaDetonation_Timer = 3000; + + //Azure Stalker + m_uiBackstab_Timer = 7100; + m_uiBlink_Timer = 7000; + + if (creatureEntry == NPC_KEEPER + || creatureEntry == NPC_GUARDIAN) + { + SetCombatMovement(false); + m_creature->GetMotionMaster()->MoveRandom(); + }; + + } + + void StartMovement() + { + if(!WayPointList.empty() || MovementStarted) + return; + + uint8 start = 0; + uint8 end = 0; + switch(portalLoc) + { + case -1: + return; + //center & ichoron + case 0: + case 5: + start = 0; + end = 2; + break; + //From lavanthor + case 1: + start = 3; + end = 5; + break; + // From Zuramat + case 2: + start = 6; + end = 11; + break; + //From Moragg + case 3: + start = 12; + end = 16; + break; + //From Erekem + case 4: + start = 17; + end = 21; + break; + //From highest platform + case 6: + start = 22; + end = 26; + break; + } + uint8 wpId = 0; + for(uint8 i = start; i <= end; ++i){ + debug_log("AddWP: %u", i); + AddWaypoint(wpId, DragonsWP[i].x, DragonsWP[i].y, DragonsWP[i].z); + wpId++; + } + + WayPoint = WayPointList.begin(); + m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); + IsWalking = true; + MovementStarted = true; + } + void JustReachedHome() + { + if (m_pInstance) + { + m_pInstance->SetData(TYPE_EVENT, FAIL); + m_pInstance->SetData(TYPE_RIFT, FAIL); + } + } + void AddWaypoint(uint32 id, float x, float y, float z) + { + WayPoints DWP(id, x, y, z); + WayPointList.push_back(DWP); + } + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if(uiType != POINT_MOTION_TYPE || creatureEntry == NPC_GUARDIAN || creatureEntry == NPC_KEEPER) + return; + + if(WayPoint->id != uiPointId) + return; + + ++WayPoint; + WalkTimer = 200; + } + void JustDied(Unit* pKiller) + { + switch(creatureEntry) + { + case NPC_GUARDIAN: + case NPC_KEEPER: + switch(urand(0,2)) + { + case 0: DoScriptText(PORTAL_KEEPER_GUARDIAN_DEATH_1, m_creature); break; + case 1: DoScriptText(PORTAL_KEEPER_GUARDIAN_DEATH_2, m_creature); break; + case 2: DoScriptText(PORTAL_KEEPER_GUARDIAN_DEATH_3, m_creature); break; + } + break; + } + } + void Aggro(Unit* pWho) + { + switch(creatureEntry) + { + case NPC_AZURE_CAPTAIN: + DoScriptText(AZURE_CAPTAIN_AGGRO_1, m_creature); + break; + case NPC_AZURE_RAIDER: + case NPC_AZURE_SORCEROR: + case NPC_AZURE_STALKER: + case NPC_AZURE_BINDER: + case NPC_AZURE_INVADER: + case NPC_AZURE_MAGE_SLAYER: + case NPC_AZURE_SPELLBREAKER: + switch(urand(0,3)) + { + case 0: DoScriptText(AZURE_SAY_AGGRO_1, m_creature); break; + case 1: DoScriptText(AZURE_SAY_AGGRO_2, m_creature); break; + case 2: DoScriptText(AZURE_SAY_AGGRO_3, m_creature); break; + case 3: DoScriptText(AZURE_SAY_AGGRO_4, m_creature); break; + } + break; + case NPC_GUARDIAN: + case NPC_KEEPER: + switch(urand(0,2)) + { + case 0: DoScriptText(PORTAL_KEEPER_GUARDIAN_AGGRO_1, m_creature); break; + case 1: DoScriptText(PORTAL_KEEPER_GUARDIAN_AGGRO_2, m_creature); break; + case 2: DoScriptText(PORTAL_KEEPER_GUARDIAN_AGGRO_3, m_creature); break; + } + break; + default: + debug_log("SD2: The Violet Hold: Unhandled dragon entry %u!", m_creature->GetEntry()); + break; + } + } + void UpdateAI(const uint32 uiDiff){ + if(portalLoc != -1) + StartMovement(); + + if (IsWalking && WalkTimer) + { + if (WalkTimer <= uiDiff) + { + if (WayPoint != WayPointList.end()) + { + m_creature->GetMotionMaster()->MovePoint(WayPoint->id, WayPoint->x, WayPoint->y,WayPoint->z); + WalkTimer = 0; + } + }else WalkTimer -= uiDiff; + } + + //Corrupt Seal + + if(Creature *pDoorSeal2 = GetClosestCreatureWithEntry(m_creature, NPC_DOOR_SEAL, 150.0f)){ + if(m_creature->IsWithinDist(pDoorSeal2, 27.0f, false) && !IsInCombat) + { + IsWalking = false; + WayPointList.clear(); + m_creature->GetMotionMaster()->Clear(false); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + DoCast(pDoorSeal2, SPELL_CORRUPT); + m_pInstance->SetData(TYPE_DOOR,SPECIAL); + } + } + if(!IsWalking && !IsInCombat) { + if (Unit* m_uEmbraceTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + m_creature->GetMotionMaster()->MoveChase(m_uEmbraceTarget); + m_creature->SetInCombatWithZone(); + IsInCombat = true; + } + + + //Return since we have no target + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if(m_creature->getVictim()) + if(m_creature->getVictim()->GetEntry() == NPC_DOOR_SEAL) + return; + switch(creatureEntry) + { + case NPC_AZURE_CAPTAIN: + AzureCaptain_UpdateAI(uiDiff); + break; + case NPC_AZURE_RAIDER: + AzureRaider_UpdateAI(uiDiff); + break; + case NPC_AZURE_SORCEROR: + AzureSorceror_UpdateAI(uiDiff); + break; + case NPC_AZURE_STALKER: + AzureStalker_UpdateAI(uiDiff); + break; + case NPC_GUARDIAN: + case NPC_KEEPER: + case NPC_AZURE_BINDER: + case NPC_AZURE_INVADER: + case NPC_AZURE_MAGE_SLAYER: + case NPC_AZURE_SPELLBREAKER: + break; + default: + debug_log("SD2: The Violet Hold: Unhandled dragon entry %u!", m_creature->GetEntry()); + break; + } + DoMeleeAttackIfReady(); + } + //Azure Captain + void AzureCaptain_UpdateAI(const uint32 uiDiff) + { + //Mortal Strike + if (m_uiMortalStrike_Timer <= uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE); + m_uiMortalStrike_Timer = 6000; + }else m_uiMortalStrike_Timer -= uiDiff; + + //Whirlwind + if (m_uiWhirlwind_Timer <= uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_WHIRLWIND); + m_uiWhirlwind_Timer = 15000; + }else m_uiWhirlwind_Timer -= uiDiff; + } + //Azure Raider + void AzureRaider_UpdateAI(const uint32 uiDiff) + { + //Concusion Blow + if (m_uiConcussionBlow_Timer <= uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_CONCUSSION_BLOW); + m_uiMortalStrike_Timer = 7000; + }else m_uiConcussionBlow_Timer -= uiDiff; + + //Magic reflection + if (m_uiMagicReflection_Timer <= uiDiff) + { + DoCast(m_creature, SPELL_MAGIC_REFLECTION); + m_uiMagicReflection_Timer = 30000; + }else m_uiMagicReflection_Timer -= uiDiff; + } + //Azure Sorceror + void AzureSorceror_UpdateAI(const uint32 uiDiff) + { + //Arcane Stream + if (m_uiArcaneStream_Timer <= uiDiff) + { + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + DoCast(pTarget, m_bIsRegular ? SPELL_ARCANE_STREAM : SPELL_ARCANE_STREAM_H); + m_uiArcaneStream_Timer = 7000; + }else m_uiArcaneStream_Timer -= uiDiff; + + //Mana Detonation + if (m_uiManaDetonation_Timer <= uiDiff) + { + DoCast(m_creature, m_bIsRegular ? SPELL_MANA_DETONATION : SPELL_MANA_DETONATION_H); + m_uiManaDetonation_Timer = 18000; + }else m_uiManaDetonation_Timer -= uiDiff; + } + //Azure Stalker + void AzureStalker_UpdateAI(const uint32 uiDiff) + { + //Backstab + if (m_uiBackstab_Timer <= uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_BACKSTAB); + m_uiBackstab_Timer = 15100; + }else m_uiBackstab_Timer -= uiDiff; + + //Tactical blink + if (m_uiBlink_Timer <= uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_TACTICAL_BLINK); + m_uiBlink_Timer = 15000; + }else m_uiBlink_Timer -= uiDiff; + } +}; /*###### -## npc_door_seal +## npc_violet_portal ######*/ - -bool EffectDummyCreature_npc_door_seal(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +struct MANGOS_DLL_DECL npc_violet_portalAI : public ScriptedAI { - //always check spellid and effectindex - if (uiSpellId == SPELL_DESTROY_DOOR_SEAL && uiEffIndex == EFFECT_INDEX_0) + npc_violet_portalAI(Creature* pCreature) : ScriptedAI(pCreature) { - if (instance_violet_hold* pInstance = (instance_violet_hold*)pCreatureTarget->GetInstanceData()) - pInstance->SetData(TYPE_SEAL, SPECIAL); + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + bool m_uiGroupSpawned; + uint8 portalType; // 0 = nothing, 1 = Guard & spawns, 2 = Group of elites + uint32 portalID; // To identify portal... + int8 portalLoc; - //always return true when we are handling this spell and effect - return true; + uint32 TimeRiftWave_Timer; + uint32 Check_Timer; + + void Reset() + { + m_uiGroupSpawned = false; + portalType = 0; + portalID = 0; + portalLoc = -1; + TimeRiftWave_Timer = 15000; + Check_Timer = 5000; + + m_creature->SetRespawnDelay(DAY); } - return false; -} + void JustSummoned(Creature* pSummoned) + { + switch(pSummoned->GetEntry()) + { + case NPC_GUARDIAN: + DoScriptText(EMOTE_GUARDIAN_PORTAL, pSummoned); + break; + case NPC_KEEPER: + DoScriptText(EMOTE_KEEPER_PORTAL, pSummoned); + break; + case NPC_AZURE_CAPTAIN: + DoScriptText(EMOTE_DRAGONFLIGHT_PORTAL, pSummoned); + break; + default: + return; + } + } + + uint32 SelectRandSummon() + { + uint32 entry = 0; + if(portalType == 1) + { + switch (urand(0, 3)) + { + case 0: entry = NPC_AZURE_BINDER; break; + case 1: entry = NPC_AZURE_INVADER; break; + case 2: entry = NPC_AZURE_MAGE_SLAYER; break; + case 3: entry = NPC_AZURE_SPELLBREAKER; break; + } + }else{ + switch (urand(0, 3)) + { + case 0: entry = NPC_AZURE_CAPTAIN; break; + case 1: entry = NPC_AZURE_RAIDER; break; + case 2: entry = NPC_AZURE_SORCEROR; break; + case 3: entry = NPC_AZURE_STALKER; break; + } + } + return entry; + } + void SpawnGroup() + { + if(portalType == 0) + return; + + uint8 uiSpawnCount = (m_pInstance->GetData(TYPE_RIFT) < 12) ? 3 : 4; + for(uint8 i = 0; i < uiSpawnCount; i++) + { + uint32 uiSpawnEntry = SelectRandSummon(); + if(Creature* pSummoned = m_creature->SummonCreature(uiSpawnEntry, m_creature->GetPositionX()-5+rand()%10, m_creature->GetPositionY()-5+rand()%10, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + debug_log("Spawn NPC %u, motherPortalID %u, portalLoc %u", uiSpawnEntry, portalID, portalLoc); + ((mob_vh_dragonsAI*)pSummoned->AI())->motherPortalID = portalID; + ((mob_vh_dragonsAI*)pSummoned->AI())->portalLoc = portalLoc; + } + } + } + bool IsThereNearElite(float range) + { + //Azure captain + if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, NPC_AZURE_CAPTAIN, range)) + { + if(((mob_vh_dragonsAI*)pTemp->AI())->motherPortalID == portalID) + return true; + } + //Azure raider + else if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, NPC_AZURE_RAIDER, range)) + { + if(((mob_vh_dragonsAI*)pTemp->AI())->motherPortalID == portalID) + return true; + } + //Azure sorceror + else if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, NPC_AZURE_SORCEROR, range)) + { + if(((mob_vh_dragonsAI*)pTemp->AI())->motherPortalID == portalID) + return true; + } + //Azure Stalker + else if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, NPC_AZURE_STALKER, range)) + { + if(((mob_vh_dragonsAI*)pTemp->AI())->motherPortalID == portalID) + return true; + } + return false; + } + + void UpdateAI(const uint32 diff) + { + if (!m_pInstance) + return; + + if(m_pInstance->GetData(TYPE_EVENT) != IN_PROGRESS) + return; + + switch(portalType) + { + case 0: + return; + case 1: + if (TimeRiftWave_Timer < diff) + { + debug_log("SpawnGroup()"); + SpawnGroup(); + TimeRiftWave_Timer = 15000; + }else TimeRiftWave_Timer -= diff; + + if (!m_creature->IsNonMeleeSpellCasted(false)) + { + m_uiNextPortal_Timer = 5000; + debug_log("SD2: npc_time_rift: not casting anylonger, i need to die."); + m_creature->ForcedDespawn(); + } + break; + case 2: + if(!m_uiGroupSpawned) + { + SpawnGroup(); + m_uiGroupSpawned = true; + } + if (Check_Timer < diff) + { + if(!IsThereNearElite(150.0f)) + { + m_uiNextPortal_Timer = 5000; + debug_log("SD2: npc_time_rift: No elite, i need to die."); + m_creature->ForcedDespawn(); + } + Check_Timer = 1000; + }else Check_Timer -= diff; + break; + } + } +}; /*###### ## npc_sinclari ######*/ - enum { SAY_BEGIN = -1608000, @@ -77,60 +600,251 @@ enum GOSSIP_TEXT_ID_INTRO = 13853, GOSSIP_TEXT_ID_START = 13854, + SAY_END = -1608009, }; -struct MANGOS_DLL_DECL npc_sinclariAI : public npc_escortAI +struct MANGOS_DLL_DECL npc_sinclariAI : public ScriptedAI { - npc_sinclariAI(Creature* pCreature) : npc_escortAI(pCreature) + npc_sinclariAI(Creature *pCreature) : ScriptedAI(pCreature) { - m_pInstance = (instance_violet_hold*)pCreature->GetInstanceData(); + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); Reset(); } + ScriptedInstance *m_pInstance; - instance_violet_hold* m_pInstance; + uint8 m_uiRiftPortalCount; + uint8 m_bIsRegular; + uint32 m_uiBossCheck_Timer; + uint32 m_uiPortalCheck_Timer; + std::list m_lGuardsList; + uint32 m_uiWaypoint; + bool start; + uint32 m_uiWalkTimer; void Reset() { + m_uiRiftPortalCount = 0; + m_uiWalkTimer = 0; + m_uiNextPortal_Timer = 0; + m_uiBossCheck_Timer = 0; + m_uiPortalCheck_Timer = 1000; + m_bIsRegular = m_creature->GetMap()->IsRegularDifficulty(); + m_uiWaypoint = 0; + start = false; + } + + void CallGuards(bool bRespawn) + { + GetCreatureListWithEntryInGrid(m_lGuardsList, m_creature, NPC_GUARD, 50.0f); + for(std::list::iterator i = m_lGuardsList.begin(); i != m_lGuardsList.end(); ++i) + { + if (Creature* pGuard = *i) + { + if (bRespawn) + { + pGuard->Respawn(); + } + else if (pGuard->isAlive()) + { + pGuard->AI()->EnterEvadeMode(); + + if (Creature* pSinclari = GetClosestCreatureWithEntry(pGuard,NPC_SINCLARI,50.0f)) + pGuard->GetMotionMaster()->MoveFollow(pSinclari, 0.0f, 0.0f); + + pGuard->ForcedDespawn(20000); + } + } } +} - void WaypointReached(uint32 uiPointId) + + void SetEvent() { - if (!m_pInstance) - return; + + m_uiNextPortal_Timer = 5000; + + if (m_pInstance){ + m_pInstance->SetData(TYPE_EVENT, IN_PROGRESS); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_SEAL_DOOR)); + } + } + void EventEscort() + { + start=true; + m_uiWalkTimer = 1000; - switch(uiPointId) + + } + + void DoSpawnPortal() + { + int tmp = urand(1, 6); + if (Creature* pTemp = m_creature->SummonCreature(NPC_PORTAL, PortalLoc[tmp].x, PortalLoc[tmp].y, PortalLoc[tmp].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) { - case 0: - m_pInstance->ProcessActivationCrystal(m_creature, true); - break; - case 1: - DoScriptText(SAY_BEGIN, m_creature); - m_pInstance->SetIntroPortals(true); - m_pInstance->CallGuards(false); - break; - case 2: - DoScriptText(SAY_LOCK_DOOR, m_creature); - m_pInstance->SetData(TYPE_MAIN, IN_PROGRESS); - break; + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + //set portal type + uint8 portalType = rand()%2+1; + uint32 portalID = rand()%50000; + ((npc_violet_portalAI*)pTemp->AI())->portalType = portalType; + ((npc_violet_portalAI*)pTemp->AI())->portalID = portalID; + ((npc_violet_portalAI*)pTemp->AI())->portalLoc = tmp; + + if(portalType == 1) + { + uint32 entry = urand(0, 1) ? NPC_GUARDIAN : NPC_KEEPER; + if (Creature* pSummoned = pTemp->SummonCreature(entry, PortalLoc[tmp].x, PortalLoc[tmp].y, PortalLoc[tmp].z, pTemp->GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) + { + pSummoned->AddThreat(pTemp); + pTemp->CastSpell(pSummoned, SPELL_PORTAL_CHANNEL,false); + ((mob_vh_dragonsAI*)pSummoned->AI())->motherPortalID = portalID; + } + } } } - void JustRespawned() + void UpdateAI(const uint32 uiDiff) { - if (m_pInstance) - m_pInstance->SetData(TYPE_MAIN, NOT_STARTED); + if(start) + { + if (m_uiWalkTimer <= uiDiff) + { + switch(m_uiWaypoint) + { + case 0: m_creature->GetMotionMaster()->MovePoint(m_uiWaypoint, SinclariWP[m_uiWaypoint].x, SinclariWP[m_uiWaypoint].y, SinclariWP[m_uiWaypoint].z); + m_uiWalkTimer = 1000; + m_uiWaypoint++; + break; + case 1: m_creature->GetMotionMaster()->MovePoint(m_uiWaypoint, SinclariWP[m_uiWaypoint].x, SinclariWP[m_uiWaypoint].y, SinclariWP[m_uiWaypoint].z); + DoScriptText(SAY_BEGIN, m_creature); + CallGuards(false); + m_uiWalkTimer = 2000; + m_uiWaypoint++; + break; + case 2: + m_creature->GetMotionMaster()->MovePoint(m_uiWaypoint, SinclariWP[m_uiWaypoint].x, SinclariWP[m_uiWaypoint].y, SinclariWP[m_uiWaypoint].z); + m_uiWalkTimer = 3000; + m_uiWaypoint++; + break; + case 3: m_creature->GetMotionMaster()->MovePoint(m_uiWaypoint, SinclariWP[m_uiWaypoint].x, SinclariWP[m_uiWaypoint].y, SinclariWP[m_uiWaypoint].z); + DoScriptText(SAY_LOCK_DOOR, m_creature); + m_uiWalkTimer = 3000; + m_uiWaypoint++; + break; + case 4: + m_creature->GetMotionMaster()->MovePoint(4, 1815.571f, 800.112f, 44.364f); + SetEvent(); + m_uiWalkTimer = 3000; + m_uiWaypoint++; + break; + case 5: + m_creature->GetMotionMaster()->Clear(); + start = false; + m_uiWalkTimer = 0; + break; + + } + } + else m_uiWalkTimer -= uiDiff; + } + + if(m_pInstance->GetData(TYPE_EVENT) != IN_PROGRESS || m_pInstance->GetData(TYPE_CYANIGOSA) == IN_PROGRESS) + return; + + if (m_uiNextPortal_Timer && m_pInstance->GetData(TYPE_RIFT) != DONE ) + { + if (m_uiNextPortal_Timer <= uiDiff) + { + ++m_uiRiftPortalCount; + if (m_pInstance && m_uiRiftPortalCount < 19) + { + m_pInstance->DoUpdateWorldState(WORLD_STATE_VH_PORTALS, m_uiRiftPortalCount); + m_pInstance->SetData(TYPE_RIFT, SPECIAL); + } + + if ( m_uiRiftPortalCount != 6 + && m_uiRiftPortalCount != 12 + && m_uiRiftPortalCount != 18 + && m_uiRiftPortalCount < 18 + ) + { + DoSpawnPortal(); + if (m_uiRiftPortalCount < 12) + m_uiNextPortal_Timer = 120000; + else + m_uiNextPortal_Timer = 90000; + } + else if ( m_uiRiftPortalCount == 6 + || m_uiRiftPortalCount == 12) + { + if(m_uiRiftPortalCount == 6 && m_pInstance->GetData(TYPE_PORTAL6) != DONE || m_uiRiftPortalCount == 12 && m_pInstance->GetData(TYPE_PORTAL12) != DONE) + { + if (Creature* pTemp = m_creature->SummonCreature(NPC_PORTAL, PortalLoc[0].x, PortalLoc[0].y, PortalLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000)) + { + pTemp->SetRespawnDelay(7*DAY*IN_MILLISECONDS); + Creature* pSummoned = m_creature->SummonCreature(NPC_AZURE_SABOTEUR, PortalLoc[0].x, PortalLoc[0].y, PortalLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); +// pSummoned->AddThreat(pTemp); + pTemp->CastSpell(pSummoned, SPELL_PORTAL_CHANNEL, false); + if(m_uiRiftPortalCount == 6) {m_pInstance->SetData(TYPE_PORTAL6, IN_PROGRESS);} + else m_pInstance->SetData(TYPE_PORTAL12, IN_PROGRESS); + } + m_uiNextPortal_Timer = m_bIsRegular ? 180000 : 120000; + } + else m_uiNextPortal_Timer = 4000; + m_pInstance->SetData(TYPE_RIFT, IN_PROGRESS); + m_uiBossCheck_Timer = 1000; + } + else if (m_uiRiftPortalCount == 18 && m_pInstance->GetData(TYPE_RIFT) != DONE) + { + Creature* pCyanigossa = GetClosestCreatureWithEntry(m_creature, NPC_CYANIGOSA, 300.0f); + + if (!pCyanigossa) + { + m_creature->SummonCreature(NPC_CYANIGOSA, 1922.420f, 803.240f, 52.40f, 3.022f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN , 99999999);} + m_pInstance->SetData(TYPE_RIFT, DONE); + m_pInstance->SetData(TYPE_DISRUPTIONS, 20); + m_uiNextPortal_Timer = 1*DAY; + } + } + else + m_uiNextPortal_Timer -= uiDiff; + + return; + } + + if (m_uiBossCheck_Timer) + { + if (m_uiBossCheck_Timer <= uiDiff) + { + if (!m_pInstance->GetData(DATA_BOSSTIME)) + m_uiNextPortal_Timer = 10000; + m_uiBossCheck_Timer = 1000; + } + else + m_uiBossCheck_Timer -= uiDiff; + + return; + } + + } }; -CreatureAI* GetAI_npc_sinclari(Creature* pCreature) -{ - return new npc_sinclariAI(pCreature); -} +#define GOSSIP_ITEM_START_EVENT "Activate the crystals when we get in trouble, right." +#define GOSSIP_ITEM_TELE_IN "I need to go in!" + bool GossipHello_npc_sinclari(Player* pPlayer, Creature* pCreature) { - pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INTRO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_ID_INTRO, pCreature->GetGUID()); + if (ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData()) + { + if (m_pInstance->GetData(TYPE_EVENT) == NOT_STARTED || m_pInstance->GetData(TYPE_EVENT) == FAIL) + { + pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INTRO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_ID_INTRO, pCreature->GetGUID()); + } + } return true; } @@ -138,10 +852,11 @@ bool GossipSelect_npc_sinclari(Player* pPlayer, Creature* pCreature, uint32 uiSe { if (uiAction == GOSSIP_ACTION_INFO_DEF+1) { - if (instance_violet_hold* pInstance = (instance_violet_hold*)pCreature->GetInstanceData()) + if (ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData()) { - if (pInstance->GetData(TYPE_MAIN) == NOT_STARTED) + if (m_pInstance->GetData(TYPE_EVENT) == NOT_STARTED || m_pInstance->GetData(TYPE_EVENT) == FAIL) { + pPlayer->PlayerTalkClass->ClearMenus(); pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXT_ID_START, pCreature->GetGUID()); } @@ -152,16 +867,16 @@ bool GossipSelect_npc_sinclari(Player* pPlayer, Creature* pCreature, uint32 uiSe if (uiAction == GOSSIP_ACTION_INFO_DEF+2) { - if (instance_violet_hold* pInstance = (instance_violet_hold*)pCreature->GetInstanceData()) + if (ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData()) { pPlayer->CLOSE_GOSSIP_MENU(); - if (pInstance->GetData(TYPE_MAIN) == NOT_STARTED) + if (m_pInstance->GetData(TYPE_EVENT) == NOT_STARTED || m_pInstance->GetData(TYPE_EVENT) == FAIL) { - pInstance->SetData(TYPE_MAIN, SPECIAL); - if (npc_sinclariAI* pEscortAI = dynamic_cast(pCreature->AI())) - pEscortAI->Start(); + if (Creature* pSinclari = (pCreature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_SINCLARI)))) + + ((npc_sinclariAI*)pSinclari->AI())->EventEscort(); } } else @@ -170,193 +885,208 @@ bool GossipSelect_npc_sinclari(Player* pPlayer, Creature* pCreature, uint32 uiSe return true; } - /*###### -## npc_teleportation_portal +## npc_door_seal_vh ######*/ - -struct MANGOS_DLL_DECL npc_teleportation_portalAI : public ScriptedAI +struct MANGOS_DLL_DECL npc_door_sealAI : public ScriptedAI { - npc_teleportation_portalAI(Creature* pCreature) : ScriptedAI(pCreature) + npc_door_sealAI(Creature* pCreature) : ScriptedAI(pCreature) { - m_pInstance = (instance_violet_hold*)pCreature->GetInstanceData(); - m_uiMyPortalNumber = 0; + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); Reset(); } - instance_violet_hold* m_pInstance; - - std::set m_lMobSet; + ScriptedInstance* m_pInstance; - bool m_bNeedInvisible; - bool m_bIntro; - uint32 m_uiIntroTimer; - uint32 m_uiMyPortalNumber; + uint32 CheckTimer; + uint32 SpellCorrupt_Timer; + uint8 lastPortal; void Reset() { - m_bNeedInvisible = false; - m_bIntro = false; - m_uiIntroTimer = 10000; - - if (m_pInstance) - m_uiMyPortalNumber = m_pInstance->GetCurrentPortalNumber(); - } - - void DoSummon() + CheckTimer = 0; + SpellCorrupt_Timer = 0; + lastPortal = 0; +} + void SpellHit(Unit* caster, const SpellEntry* spell) { - if (m_creature->GetEntry() == NPC_PORTAL_INTRO) - { - //not made yet + if (SpellCorrupt_Timer) return; - } - else if (m_creature->GetEntry() == NPC_PORTAL) - { - m_creature->SummonCreature(m_pInstance->GetRandomPortalEliteEntry(), 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600*IN_MILLISECONDS); - m_creature->CastSpell(m_creature, SPELL_PORTAL_PERIODIC, true); - } - else if (m_pInstance->IsCurrentPortalForTrash()) - { - for(uint8 i = 0; i < 4; ++i) - { - uint32 uiSummonId; - switch(i) - { - case 0: uiSummonId = NPC_AZURE_CAPTAIN; break; - case 1: uiSummonId = NPC_AZURE_RAIDER; break; - case 2: uiSummonId = NPC_AZURE_SORCEROR; break; - case 3: uiSummonId = NPC_AZURE_STALKER; break; - } - - m_creature->SummonCreature(uiSummonId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600*IN_MILLISECONDS); + if (spell->Id == SPELL_CORRUPT) { + SpellCorrupt_Timer = 1000; } + } + void JustDied(Unit* pKiller) + { + m_creature->Respawn(); + } - m_bNeedInvisible = true; - } - else + void UpdateAI(const uint32 diff){ + if (SpellCorrupt_Timer) { - m_creature->SummonCreature(NPC_AZURE_SABOTEUR, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600*IN_MILLISECONDS); - m_bNeedInvisible = true; + if (SpellCorrupt_Timer <= diff) + { + if (m_creature->HasAura(SPELL_CORRUPT,EFFECT_INDEX_0)) + SpellCorrupt_Timer = 1500; + else + SpellCorrupt_Timer = 0; + }else SpellCorrupt_Timer -= diff; } } +}; - void JustSummoned(Creature* pSummoned) +/*###### +## npc_azure_saboteur +######*/ +struct MANGOS_DLL_DECL npc_azure_saboteurAI : public ScriptedAI +{ + npc_azure_saboteurAI(Creature *pCreature) : ScriptedAI(pCreature) { - switch(pSummoned->GetEntry()) - { - case NPC_PORTAL_GUARDIAN: - DoScriptText(EMOTE_GUARDIAN_PORTAL, pSummoned); - m_creature->CastSpell(pSummoned, SPELL_PORTAL_CHANNEL, false); - break; - case NPC_PORTAL_KEEPER: - DoScriptText(EMOTE_KEEPER_PORTAL, pSummoned); - m_creature->CastSpell(pSummoned, SPELL_PORTAL_CHANNEL, false); - break; - case NPC_AZURE_CAPTAIN: - DoScriptText(EMOTE_DRAGONFLIGHT_PORTAL, pSummoned); - m_lMobSet.insert(pSummoned->GetGUID()); - break; - case NPC_AZURE_RAIDER: - case NPC_AZURE_SORCEROR: - case NPC_AZURE_STALKER: - m_lMobSet.insert(pSummoned->GetGUID()); - return; - default: - return; - } + m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + Reset(); + } + ScriptedInstance *m_pInstance; - if (m_pInstance) - m_pInstance->SetData(TYPE_PORTAL, SPECIAL); + bool m_bIsActiving; + + uint32 m_uiDisruption_Timer; + uint32 m_uiDisruptionCounter; + uint32 m_uiDisruptionsCount; + + uint8 m_uiBossID; + uint8 m_bIsRegular; + uint32 m_uiBossType; + uint64 m_uiBossGUID; + uint64 m_uiDoorGUID; + + void AttackStart(Unit* pWho) + { + return; } - void SummonedCreatureJustDied(Creature* pSummoned) + void Reset() { - switch(pSummoned->GetEntry()) - { - case NPC_PORTAL_GUARDIAN: - case NPC_PORTAL_KEEPER: - break; - case NPC_AZURE_CAPTAIN: - case NPC_AZURE_RAIDER: - case NPC_AZURE_SORCEROR: - case NPC_AZURE_STALKER: - { - m_lMobSet.erase(pSummoned->GetGUID()); + m_bIsActiving = false; - if (!m_lMobSet.empty()) - return; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_uiDisruptionCounter = 0; + m_uiDisruptionsCount = 0; + m_uiDisruption_Timer = 1000; +// m_bIsRegular = m_creature->GetMap()->IsRegularDifficulty(); - break; + if (m_pInstance) + { + m_uiBossID = m_pInstance->GetData(TYPE_LASTBOSS); + m_uiDisruptionsCount = m_pInstance->GetData(TYPE_DISRUPTIONS); + switch (m_uiBossID) + { + case 6: // Lavanthor + m_uiBossType = TYPE_LAVANTHOR; + m_uiBossGUID = m_pInstance->GetData64(DATA_LAVANTHOR); + m_uiDoorGUID = m_pInstance->GetData64(DATA_LAVANTHOR_DOOR); + break; + case 7: // Zuramat + m_uiBossType = TYPE_ZURAMAT; + m_uiBossGUID = m_pInstance->GetData64(DATA_ZURAMAT); + m_uiDoorGUID = m_pInstance->GetData64(DATA_ZURAMAT_DOOR); + break; + case 3: // Moragg + m_uiBossType = TYPE_MORAGG; + m_uiBossGUID = m_pInstance->GetData64(DATA_MORAGG); + m_uiDoorGUID = m_pInstance->GetData64(DATA_MORAGG_DOOR); + break; + case 2: // Erekem + m_uiBossType = TYPE_EREKEM; + m_uiBossGUID = m_pInstance->GetData64(DATA_EREKEM); + m_uiDoorGUID = m_pInstance->GetData64(DATA_EREKEM_DOOR); + break; + case 4: // Ichoron + m_uiBossType = TYPE_ICHORON; + m_uiBossGUID = m_pInstance->GetData64(DATA_ICHORON); + m_uiDoorGUID = m_pInstance->GetData64(DATA_ICHORON_DOOR); + break; + case 5: // Xevozz + m_uiBossType = TYPE_XEVOZZ; + m_uiBossGUID = m_pInstance->GetData64(DATA_XEVOZZ); + m_uiDoorGUID = m_pInstance->GetData64(DATA_XEVOZZ_DOOR); + break; + case 0: // No boss + m_uiBossType = 0; + break; } - default: - return; + m_pInstance->SetData(TYPE_LASTBOSS_ID, m_uiBossType); + if (m_uiBossType != 0) m_creature->GetMotionMaster()->MovePoint(0, BossLoc[m_uiBossID].x, BossLoc[m_uiBossID].y, BossLoc[m_uiBossID].z); + else m_creature->GetMotionMaster()->MovePoint(0, 1827.960f, 804.208f, 44.364f); } + } - if (m_pInstance) + void MovementInform(uint32 uiType, uint32 uiPointId) + { + if(uiType != POINT_MOTION_TYPE) + return; + + switch(uiPointId) { - // no need if a new portal was made while this was in progress - if (m_uiMyPortalNumber == m_pInstance->GetCurrentPortalNumber()) - m_pInstance->SetData(TYPE_PORTAL, DONE); + case 0: + m_bIsActiving = true; + break; } - - m_creature->ForcedDespawn(); } void UpdateAI(const uint32 uiDiff) { - if (m_uiIntroTimer) - { - if (m_uiIntroTimer <= uiDiff) + if (m_bIsActiving) + if (m_uiDisruption_Timer < uiDiff) { - if (!m_pInstance) + if (m_uiDisruptionCounter < 3) { + DoCast(m_creature, SPELL_SHIELD_DISRUPTION); + ++m_uiDisruptionsCount; + m_pInstance->SetData(TYPE_DISRUPTIONS, m_uiDisruptionsCount);} + else if (m_uiDisruptionCounter == 3) { - m_creature->ForcedDespawn(); - return; + m_pInstance->DoUseDoorOrButton(m_uiDoorGUID); + if (m_uiBossType == TYPE_EREKEM) { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_EREKEM_DOOR_L)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_EREKEM_DOOR_R)); + } } + else { + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + if (m_pInstance->GetData(TYPE_LASTBOSS_ID) != 0) m_pInstance->SetData(m_pInstance->GetData(TYPE_LASTBOSS_ID), SPECIAL); + m_bIsActiving = false; + } - m_uiIntroTimer = 0; - } - else - { - m_uiIntroTimer -= uiDiff; - return; + ++m_uiDisruptionCounter; + m_uiDisruption_Timer = 1000; } - } - - if (!m_bIntro) - { - DoSummon(); - m_bIntro = true; - } - - if (m_bNeedInvisible) - { - // hack; find a better way - m_creature->SetVisibility(VISIBILITY_OFF); - m_bNeedInvisible = false; - } + else m_uiDisruption_Timer -= uiDiff; } }; -CreatureAI* GetAI_npc_teleportation_portal(Creature* pCreature) + + +CreatureAI* GetAI_npc_azure_saboteur(Creature* pCreature) { - return new npc_teleportation_portalAI(pCreature); + return new npc_azure_saboteurAI (pCreature); } -bool EffectDummyCreature_npc_teleportation_portal(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +CreatureAI* GetAI_mob_vh_dragons(Creature* pCreature) { - //always check spellid and effectindex - if (uiSpellId == SPELL_PORTAL_PERIODIC && uiEffIndex == EFFECT_INDEX_0) - { - if (instance_violet_hold* pInstance = (instance_violet_hold*)pCreatureTarget->GetInstanceData()) - pCreatureTarget->SummonCreature(pInstance->GetRandomMobForNormalPortal(), 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600*IN_MILLISECONDS); - - //always return true when we are handling this spell and effect - return true; - } - - return false; + return new mob_vh_dragonsAI(pCreature); +} +CreatureAI* GetAI_npc_sinclari(Creature* pCreature) +{ + return new npc_sinclariAI (pCreature); +} +CreatureAI* GetAI_npc_violet_portal(Creature* pCreature) +{ + return new npc_violet_portalAI (pCreature); +} +CreatureAI* GetAI_npc_door_seal(Creature* pCreature) +{ + return new npc_door_sealAI(pCreature); } void AddSC_violet_hold() @@ -364,25 +1094,30 @@ void AddSC_violet_hold() Script *newscript; newscript = new Script; - newscript->Name = "go_activation_crystal"; - newscript->pGOHello = &GOHello_go_activation_crystal; + newscript->Name = "npc_sinclari"; + newscript->GetAI = &GetAI_npc_sinclari; + newscript->pGossipHello = &GossipHello_npc_sinclari; + newscript->pGossipSelect = &GossipSelect_npc_sinclari; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "npc_door_seal"; - newscript->pEffectDummyCreature = &EffectDummyCreature_npc_door_seal; + newscript->Name = "npc_violet_portal"; + newscript->GetAI = &GetAI_npc_violet_portal; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "npc_sinclari"; - newscript->GetAI = &GetAI_npc_sinclari; - newscript->pGossipHello = &GossipHello_npc_sinclari; - newscript->pGossipSelect = &GossipSelect_npc_sinclari; + newscript->Name = "npc_door_seal_vh"; + newscript->GetAI = &GetAI_npc_door_seal; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_azure_saboteur"; + newscript->GetAI = &GetAI_npc_azure_saboteur; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "npc_teleportation_portal"; - newscript->GetAI = &GetAI_npc_teleportation_portal; - newscript->pEffectDummyCreature = &EffectDummyCreature_npc_teleportation_portal; + newscript->Name = "mob_vh_dragons"; + newscript->GetAI = &GetAI_mob_vh_dragons; newscript->RegisterSelf(); + } diff --git a/scripts/northrend/violet_hold/violet_hold.h b/scripts/northrend/violet_hold/violet_hold.h index b8f4a8b17..d81c32240 100644 --- a/scripts/northrend/violet_hold/violet_hold.h +++ b/scripts/northrend/violet_hold/violet_hold.h @@ -1,229 +1,195 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ -#ifndef DEF_VIOLET_H -#define DEF_VIOLET_H +#ifndef DEF_VIOLET_HOLD_H +#define DEF_VIOLET_HOLD_H enum { - MAX_ENCOUNTER = 3, - - TYPE_MAIN = 1, - TYPE_SEAL = 2, - TYPE_PORTAL = 3, - - WORLD_STATE_ID = 3816, - WORLD_STATE_SEAL = 3815, - WORLD_STATE_PORTALS = 3810, - - GO_INTRO_CRYSTAL = 193615, - GO_PRISON_SEAL_DOOR = 191723, - - GO_CELL_LAVANTHOR = 191566, - GO_CELL_MORAGG = 191606, - GO_CELL_ZURAMAT = 191565, - GO_CELL_EREKEM = 191564, - GO_CELL_EREKEM_GUARD_L = 191563, - GO_CELL_EREKEM_GUARD_R = 191562, - GO_CELL_XEVOZZ = 191556, - GO_CELL_ICHORON = 191722, - - NPC_EVENT_CONTROLLER = 30883, - NPC_PORTAL_INTRO = 31011, - NPC_PORTAL = 30679, - NPC_PORTAL_ELITE = 32174, - NPC_DOOR_SEAL = 30896, - - NPC_SINCLARI = 30658, - NPC_SINCLARI_ALT = 32204, // yeller for seal weakening and summoner for portals - NPC_HOLD_GUARD = 30659, - - NPC_EREKEM = 29315, - NPC_EREKEM_GUARD = 29395, - NPC_MORAGG = 29316, - NPC_ICHORON = 29313, - NPC_XEVOZZ = 29266, - NPC_LAVANTHOR = 29312, - NPC_ZURAMAT = 29314, - NPC_CYANIGOSA = 31134, - - NPC_PORTAL_GUARDIAN = 30660, - NPC_PORTAL_KEEPER = 30695, - - NPC_AZURE_INVADER = 30661, - NPC_AZURE_SPELLBREAKER = 30662, - NPC_AZURE_BINDER = 30663, - NPC_AZURE_MAGE_SLAYER = 30664, - NPC_MAGE_HUNTER = 30665, - NPC_AZURE_CAPTAIN = 30666, - NPC_AZURE_SORCEROR = 30667, - NPC_AZURE_RAIDER = 30668, - NPC_AZURE_STALKER = 32191, - - // used for intro - NPC_AZURE_BINDER_INTRO = 31007, - NPC_AZURE_INVADER_INTRO = 31008, - NPC_AZURE_SPELLBREAKER_INTRO= 31009, - NPC_AZURE_MAGE_SLAYER_INTRO = 31010, - - NPC_AZURE_SABOTEUR = 31079, - - NPC_DEFENSE_SYSTEM = 30837, - NPC_DEFENSE_DUMMY_TARGET = 30857, - - NPC_ARAKKOA = 32226, - NPC_VOID_LORD = 32230, - NPC_ETHERAL = 32231, - NPC_SWIRLING = 32234, - NPC_WATCHER = 32235, - NPC_LAVA_HOUND = 32237, - - SPELL_DEFENSE_SYSTEM_VISUAL = 57887, - SPELL_DEFENSE_SYSTEM_SPAWN = 57886, - - SPELL_DESTROY_DOOR_SEAL = 58040, // spell periodic cast by misc - SPELL_TELEPORTATION_PORTAL = 57687, // visual aura, but possibly not used? creature_template model for portals are same - - SPELL_SHIELD_DISRUPTION = 58291, // dummy when opening a cell - - SPELL_PORTAL_PERIODIC = 58008, // most likely the tick for each summon (tick each 15 seconds) - SPELL_PORTAL_CHANNEL = 58012, // the blue "stream" between portal and guardian/keeper - SPELL_PORTAL_BEAM = 56046, // large beam, unsure if really used here (or possible for something different) - - SPELL_PORTAL_VISUAL_1 = 57872, // no idea, but is possibly related based on it's visual appearence - SPELL_PORTAL_VISUAL_2 = 57630, - - SAY_SEAL_75 = -1608002, - SAY_SEAL_50 = -1608003, - SAY_SEAL_5 = -1608004, + MAX_ENCOUNTER = 11, + + TYPE_EVENT = 0, + TYPE_RIFT = 1, + TYPE_EREKEM = 2, + TYPE_MORAGG = 3, + TYPE_ICHORON = 4, + TYPE_XEVOZZ = 5, + TYPE_LAVANTHOR = 6, + TYPE_ZURAMAT = 7, + TYPE_CYANIGOSA = 8, + TYPE_PORTAL6 = 9, + TYPE_PORTAL12 = 10, + + + WORLD_STATE_VH = 3816, + WORLD_STATE_VH_PRISON = 3815, + WORLD_STATE_VH_PORTALS = 3810, + + TYPE_LASTBOSS = 19, + TYPE_DOOR = 21, + TYPE_PORTAL_TIME = 22, + + TYPE_DISRUPTIONS = 101, + TYPE_LASTBOSS_ID = 102, + + DATA_EREKEM = 23, + DATA_MORAGG = 24, + DATA_ICHORON = 25, + DATA_XEVOZZ = 26, + DATA_LAVANTHOR = 27, + DATA_ZURAMAT = 28, + DATA_SINCLARI = 29, + DATA_BOSSTIME = 30, + DATA_NPC_SEAL_DOOR = 31, + + DATA_SEAL_DOOR = 32, + DATA_EREKEM_DOOR = 33, + DATA_MORAGG_DOOR = 34, + DATA_ICHORON_DOOR = 35, + DATA_XEVOZZ_DOOR = 36, + DATA_LAVANTHOR_DOOR = 37, + DATA_ZURAMAT_DOOR = 38, + DATA_EREKEM_DOOR_L = 39, + DATA_EREKEM_DOOR_R = 40, + + NPC_EREKEM = 29315, + NPC_EREKEM_GUARD = 29395, + NPC_MORAGG = 29316, + NPC_ICHORON = 29313, + NPC_XEVOZZ = 29266, + NPC_LAVANTHOR = 29312, + NPC_ZURAMAT = 29314, + NPC_CYANIGOSA = 31134, + + NPC_AZURE_SABOTEUR = 31079, // Open boss's cell + + NPC_AZURE_CAPTAIN = 30666, //Melee, 40k - 60k hp, 3 for 1-11, 4 for 13-17 + NPC_AZURE_RAIDER = 30668, //Melee, 40k - 60k hp + NPC_AZURE_SORCEROR = 30667, //Caster, 40k - 60k hp + NPC_AZURE_STALKER = 32191, //Melee, 40k - 60k hp + NPC_GUARDIAN = 30660, + NPC_KEEPER = 30695, + NPC_AZURE_BINDER = 30663, //Caster, 7k - 10k hp + NPC_AZURE_INVADER = 30661, //Melee, 8k - 12k hp + NPC_AZURE_MAGE_SLAYER = 30664, //Melee, 10k - 15k hp + NPC_AZURE_SPELLBREAKER = 30662, //Caster, 10k - 15k hp + + NPC_SINCLARI = 30658, + NPC_GUARD = 30659, + NPC_PORTAL = 31011, + NPC_DOOR_SEAL = 30896, + + GO_DOOR_SEAL = 191723, + GO_DOOR_EREKEM = 191564, + GO_DOOR_EREKEM_RIGHT = 191563, + GO_DOOR_EREKEM_LEFT = 191562, + GO_DOOR_MORAGG = 191606, + GO_DOOR_ICHORON = 191722, + GO_DOOR_XEVOZZ = 191556, + GO_DOOR_LAVANTHOR = 191566, + GO_DOOR_ZURAMAT = 191565, + + SPELL_PORTAL_CHANNEL = 58012, + SPELL_CORRUPT = 58040, EMOTE_GUARDIAN_PORTAL = -1608005, EMOTE_DRAGONFLIGHT_PORTAL = -1608006, - EMOTE_KEEPER_PORTAL = -1608007, - - MAX_NORMAL_PORTAL = 8 + EMOTE_KEEPER_PORTAL = -1608007 }; -static float fDefenseSystemLoc[4] = {1888.146f, 803.382f, 58.604f, 3.072f}; - -enum ePortalType +struct Locations { - PORTAL_TYPE_NORM = 0, - PORTAL_TYPE_SQUAD, - PORTAL_TYPE_BOSS, + float x, y, z; + uint32 id; }; -struct sPortalData +struct WayPoints { - ePortalType pPortalType; - float fX, fY, fZ, fOrient; + WayPoints(uint32 _id, float _x, float _y, float _z) + { + id = _id; + x = _x; + y = _y; + z = _z; + } + uint32 id; + float x, y, z; }; -static sPortalData afPortalLocation[]= +static Locations SinclariWP[]= { - {PORTAL_TYPE_NORM, 1936.07f, 803.198f, 53.3749f, 3.1241f}, //balcony - {PORTAL_TYPE_NORM, 1877.51f, 850.104f, 44.6599f, 4.7822f}, //erekem - {PORTAL_TYPE_NORM, 1890.64f, 753.471f, 48.7224f, 1.7104f}, //moragg - {PORTAL_TYPE_SQUAD, 1911.06f, 802.103f, 38.6465f, 2.8908f}, //below balcony - {PORTAL_TYPE_SQUAD, 1928.06f, 763.256f, 51.3167f, 2.3905f}, //bridge - {PORTAL_TYPE_SQUAD, 1924.26f, 847.661f, 47.1591f, 4.0202f}, //zuramat - {PORTAL_TYPE_NORM, 1914.16f, 832.527f, 38.6441f, 3.5160f}, //xevozz - {PORTAL_TYPE_NORM, 1857.30f, 764.145f, 38.6543f, 0.8339f}, //lavanthor - {PORTAL_TYPE_BOSS, 1890.73f, 803.309f, 38.4001f, 2.4139f}, //center + {1830.5f, 799.357f, 44.3418f}, // 0 use activation + {1832.46f, 800.431f, 44.3117f}, // 1 SAY_BEGIN call back guards + {1824.79f, 803.828f, 44.3634f}, // 2 SAY_LOCK_DOOR close door + {1807.25f, 803.904f, 44.3634f}, // 3 + {1808.07f, 804.259f, 44.3641f}, // 4 + }; -class MANGOS_DLL_DECL instance_violet_hold : public ScriptedInstance +static Locations PortalLoc[]= { - public: - instance_violet_hold(Map* pMap); - ~instance_violet_hold() {} - - void Initialize(); - void ResetAll(); - void ResetVariables(); - - void OnCreatureCreate(Creature* pCreature); - void OnObjectCreate(GameObject* pGo); - - void UpdateCellForBoss(uint32 uiBossEntry); - void UpdateWorldState(bool bEnable = true); - - void SetIntroPortals(bool bDeactivate); - void SpawnPortal(); - - void SetPortalId(); - - void CallGuards(bool bRespawn); - - uint32 GetRandomPortalEliteEntry(); - uint32 GetRandomMobForNormalPortal(); - - uint32 GetCurrentPortalNumber() { return m_uiWorldStatePortalCount; } - - sPortalData const* GetPortalData() { return &afPortalLocation[m_uiPortalId]; } - - bool IsCurrentPortalForTrash() - { - if (m_uiWorldStatePortalCount % 6) - return true; - - return false; - } - - bool IsNextPortalForTrash() - { - if ((m_uiWorldStatePortalCount+1) % 6) - return true; - - return false; - } - - void ProcessActivationCrystal(Unit* pUser, bool bIsIntro = false); - - void SetRandomBosses(); - - void OnPlayerEnter(Player* pPlayer); - - void SetData(uint32 uiType, uint32 uiData); - uint64 GetData64(uint32 uiData); - - void Update(uint32 uiDiff); - - typedef std::multimap BossToCellMap; - - protected: - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - uint64 m_uiSinclariGUID; - uint64 m_uiSinclariAltGUID; - uint64 m_uiErekemGUID; - uint64 m_uiMoraggGUID; - uint64 m_uiIchoronGUID; - uint64 m_uiXevozzGUID; - uint64 m_uiLavanthorGUID; - uint64 m_uiZuramatGUID; - - uint64 m_uiCellErekemGuard_LGUID; - uint64 m_uiCellErekemGuard_RGUID; - uint64 m_uiIntroCrystalGUID; - uint64 m_uiDoorSealGUID; - - uint32 m_uiWorldState; - uint32 m_uiWorldStateSealCount; - uint32 m_uiWorldStatePortalCount; - - uint8 m_uiPortalId; - uint32 m_uiPortalTimer; - uint32 m_uiMaxCountPortalLoc; + {1888.271f, 810.781f, 38.441f}, // 0 center + {1857.125f, 763.295f, 38.654f}, // 1 Lavanthor + {1925.480f, 849.981f, 47.174f}, // 2 Zuramat + {1892.737f, 744.589f, 47.666f}, // 3 Moragg + {1878.198f, 850.005f, 43.333f}, // 4 Portal in front of Erekem + {1909.381f, 806.796f, 38.645f}, // 5 Portal outside of Ichoron + {1936.101f, 802.950f, 52.417f}, // 6 at the highest platform +}; - BossToCellMap m_mBossToCellMap; +static Locations BossLoc[]= +{ + {0,0,0}, + {0,0,0}, + {1876.100f, 857.079f, 43.333f}, // Erekem + {1892.737f, 744.589f, 47.666f}, // Moragg + {1908.863f, 785.647f, 37.435f}, // Ichoron + {1905.364f, 840.607f, 38.670f}, // Xevozz + {1857.125f, 763.295f, 38.654f}, // Lavanthor + {1925.480f, 849.981f, 47.174f}, // Zuramat +}; - std::list m_lIntroPortalList; - std::list m_lGuardsList; - std::list m_lRandomBossList; +static Locations DragonsWP[]= +{ + //center, ichoron + {1869.393f, 803.902f, 38.768f}, // 0 + {1859.843f, 804.222f, 44.008f}, // 1 + {1829.64f, 804.194f, 44.355f}, // 2 + + //From left side (lavanthor) + {1861.016f, 789.717f, 38.908f}, // 3 + {1856.217f, 796.705f, 44.008f}, // 4 + {1829.64f, 804.194f, 44.355f}, // 5 + + //From Zuramat + {1931.446f, 826.734f, 47.556f}, // 6 + {1913.049f, 823.930f, 38.792f}, // 7 + {1827.960f, 804.208f, 44.364f}, // 8 + {1869.393f, 803.902f, 38.768f}, // 9 + {1859.843f, 804.222f, 44.008f}, // 10 + {1829.64f, 804.194f, 44.355f}, // 11 + + //From Morag + {1887.500f, 763.096f, 47.666f}, // 12 + {1880.837f, 775.769f, 38.796f}, // 13 + {1861.016f, 789.717f, 38.908f}, // 14 + {1856.217f, 796.705f, 44.008f}, // 15 + {1829.64f, 804.194f, 44.355f}, // 16 + + //From erekem + {1878.280f, 843.267f, 43.333f}, // 17 + {1872.311f, 835.531f, 38.780f}, // 18 + {1861.997f, 818.766f, 38.650f}, // 19 + {1857.348f, 811.230f, 44.008f}, // 20 + {1829.64f, 804.194f, 44.355f}, // 21 + + //From Highest platform + {1937.298f, 824.557f, 52.332f}, // 22 + {1913.049f, 823.930f, 38.792f}, // 23 + {1869.393f, 803.902f, 38.768f}, // 24 + {1859.843f, 804.222f, 44.008f}, // 25 + {1829.64f, 804.194f, 44.355f}, // 26 }; #endif diff --git a/scripts/northrend/zuldrak.cpp b/scripts/northrend/zuldrak.cpp index d0c526ea6..3f4f20f09 100644 --- a/scripts/northrend/zuldrak.cpp +++ b/scripts/northrend/zuldrak.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -98,6 +98,6 @@ void AddSC_zuldrak() pNewScript = new Script; pNewScript->Name = "npc_gurgthock"; pNewScript->GetAI = &GetAI_npc_gurgthock; - pNewScript->pQuestAccept = &QuestAccept_npc_gurgthock; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_gurgthock; pNewScript->RegisterSelf(); } diff --git a/scripts/outdoor_pvp/eastern_kingdoms/outdoor_pvp_eastern_plaguelands.cpp b/scripts/outdoor_pvp/eastern_kingdoms/outdoor_pvp_eastern_plaguelands.cpp new file mode 100644 index 000000000..100ba0b68 --- /dev/null +++ b/scripts/outdoor_pvp/eastern_kingdoms/outdoor_pvp_eastern_plaguelands.cpp @@ -0,0 +1,891 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: outdoor_pvp_eastern_plaguelands +SD%Complete: +SDComment: +SDCategory: Outdoor PvP +EndScriptData */ + +#include "precompiled.h" +#include "outdoor_pvp_eastern_plaguelands.h" + +outdoor_pvp_eastern_plaguelands::outdoor_pvp_eastern_plaguelands(Map* pMap) : OutdoorPvP(pMap), + m_uiPlaguewoodController(0), + m_uiEastwallController(0), + m_uiNorthpassController(0), + m_uiCrownguardController(0), + m_uiTowersAly(0), + m_uiTowersHorde(0) { } + +void outdoor_pvp_eastern_plaguelands::OnPlayerEnterZone(Player* pPlayer, uint32 uiZoneId, uint32 uiAreaId) +{ + //if(pPlayer->GetTeam() == m_uiLastControllerFaction) + // pPlayer->CastSpell(pPlayer, SPELL_CENARION_FAVOR, false); + + // add to the player set + sPlaguelandsPlayers.insert(pPlayer->GetGUID()); + + // send actual world states + SendPlayerWorldState(pPlayer); +} + +void outdoor_pvp_eastern_plaguelands::OnPlayerLeaveZone(Player* pPlayer, uint32 uiZoneId) +{ + // remove from the player set + if (sPlaguelandsPlayers.find(pPlayer->GetGUID()) != sPlaguelandsPlayers.end()) + sPlaguelandsPlayers.erase(pPlayer->GetGUID()); +} + +void outdoor_pvp_eastern_plaguelands::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) + { + case TYPE_CROWNGUARD_CONTROLLER: + m_uiCrownguardController = uiData; + break; + case TYPE_EASTWALL_CONTROLLER: + m_uiEastwallController = uiData; + break; + case TYPE_NORTHPASS_CONTROLLER: + m_uiNorthpassController = uiData; + break; + case TYPE_PLAGUEWOOD_CONTROLLER: + m_uiPlaguewoodController = uiData; + break; + } + + // update states + UpdateZoneWorldState(); + + if (uiData) + { + OUT_SAVE_PVP_DATA; + + std::ostringstream saveStream; + saveStream << m_uiCrownguardController << " " << m_uiEastwallController << " " << m_uiNorthpassController << " " << m_uiPlaguewoodController; + + strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_PVP_DATA_COMPLETE; + } +} + +uint32 outdoor_pvp_eastern_plaguelands::GetData(uint32 uiType) +{ + switch(uiType) + { + case TYPE_CROWNGUARD_CONTROLLER: + return m_uiCrownguardController; + case TYPE_EASTWALL_CONTROLLER: + return m_uiEastwallController; + case TYPE_NORTHPASS_CONTROLLER: + return m_uiNorthpassController; + case TYPE_PLAGUEWOOD_CONTROLLER: + return m_uiPlaguewoodController; + } + return 0; +} + +void outdoor_pvp_eastern_plaguelands::Load(const char* chrIn) +{ + if (!chrIn) + { + OUT_LOAD_PVP_DATA_FAIL; + return; + } + + OUT_LOAD_PVP_DATA(chrIn); + + std::istringstream loadStream(chrIn); + loadStream >> m_uiCrownguardController >> m_uiEastwallController >> m_uiNorthpassController >> m_uiPlaguewoodController; + + OUT_LOAD_PVP_DATA_COMPLETE; +} + +void outdoor_pvp_eastern_plaguelands::UpdateZoneWorldState() +{ + //DoUpdateWorldState(sSilithusPlayers, WORLD_STATE_SI_GATHERED_A, m_uiResourcesdAly); + //DoUpdateWorldState(sSilithusPlayers, WORLD_STATE_SI_GATHERED_H, m_uiResourcesHorde); +} + +void outdoor_pvp_eastern_plaguelands::SendPlayerWorldState(Player* pPlayer) +{ + //pPlayer->SendUpdateWorldState(WORLD_STATE_SI_GATHERED_A, m_uiResourcesdAly); + //pPlayer->SendUpdateWorldState(WORLD_STATE_SI_GATHERED_H, m_uiResourcesHorde); + //pPlayer->SendUpdateWorldState(WORLD_STATE_SI_SILITHYST_MAX, MAX_SILITHYST); +} + +InstanceData* GetInstanceData_outdoor_pvp_eastern_plaguelands(Map* pMap) +{ + return new outdoor_pvp_eastern_plaguelands(pMap); +} + +void AddSC_outdoor_pvp_eastern_plaguelands() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "outdoor_pvp_eastern_plaguelands"; + pNewScript->GetInstanceData = &GetInstanceData_outdoor_pvp_eastern_plaguelands; + pNewScript->RegisterSelf(); +} + + + + + + + +/* + +OPvPCapturePointEP_EWT::OPvPCapturePointEP_EWT(OutdoorPvP *pvp) +: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_UnitsSummonedSide(0) +{ + SetCapturePointData(EPCapturePoints[EP_EWT].entry,EPCapturePoints[EP_EWT].map,EPCapturePoints[EP_EWT].x,EPCapturePoints[EP_EWT].y,EPCapturePoints[EP_EWT].z,EPCapturePoints[EP_EWT].o,EPCapturePoints[EP_EWT].rot0,EPCapturePoints[EP_EWT].rot1,EPCapturePoints[EP_EWT].rot2,EPCapturePoints[EP_EWT].rot3); + AddObject(EP_EWT_FLAGS,EPTowerFlags[EP_EWT].entry,EPTowerFlags[EP_EWT].map,EPTowerFlags[EP_EWT].x,EPTowerFlags[EP_EWT].y,EPTowerFlags[EP_EWT].z,EPTowerFlags[EP_EWT].o,EPTowerFlags[EP_EWT].rot0,EPTowerFlags[EP_EWT].rot1,EPTowerFlags[EP_EWT].rot2,EPTowerFlags[EP_EWT].rot3); +} + +void OPvPCapturePointEP_EWT::ChangeState() +{ + if(fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out! + { + // if changing from controlling alliance to horde or vice versa + if( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_EWT_A)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = 0; + } + else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_EWT_H)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = 0; + } + + uint32 artkit = 21; + + switch(m_State) + { + case OBJECTIVESTATE_ALLIANCE: + if(m_value == m_maxValue) + m_TowerState = EP_TS_A; + else + m_TowerState = EP_TS_A_P; + artkit = 2; + SummonSupportUnitAtNorthpassTower(ALLIANCE); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = ALLIANCE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_A)); + break; + case OBJECTIVESTATE_HORDE: + if(m_value == -m_maxValue) + m_TowerState = EP_TS_H; + else + m_TowerState = EP_TS_H_P; + artkit = 1; + SummonSupportUnitAtNorthpassTower(HORDE); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = HORDE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_H)); + break; + case OBJECTIVESTATE_NEUTRAL: + m_TowerState = EP_TS_N; + break; + case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: + case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: + m_TowerState = EP_TS_N_A; + break; + case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: + case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: + m_TowerState = EP_TS_N_H; + break; + } + + GameObject* flag = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, m_capturePointGUID)); + GameObject * flag2 = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, m_Objects[EP_EWT_FLAGS])); + if(flag) + { + flag->SetGoArtKit(artkit); + } + if(flag2) + { + flag2->SetGoArtKit(artkit); + } + + UpdateTowerState(); + + // complete quest objective + if(m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) + SendObjectiveComplete(EP_EWT_CM, 0); + } +} + +void OPvPCapturePointEP_EWT::SendChangePhase() +{ + // send this too, sometimes the slider disappears, dunno why :( + SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + // send these updates to only the ones in this objective + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + // send this too, sometimes it resets :S + SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); +} + +void OPvPCapturePointEP_EWT::FillInitialWorldStates(WorldPacket& data, uint32& count) +{ + FillInitialWorldState(data, count, EP_EWT_A, bool(m_TowerState & EP_TS_A)); + FillInitialWorldState(data, count, EP_EWT_H, bool(m_TowerState & EP_TS_H)); + FillInitialWorldState(data, count, EP_EWT_A_P, bool(m_TowerState & EP_TS_A_P)); + FillInitialWorldState(data, count, EP_EWT_H_P, bool(m_TowerState & EP_TS_H_P)); + FillInitialWorldState(data, count, EP_EWT_N_A, bool(m_TowerState & EP_TS_N_A)); + FillInitialWorldState(data, count, EP_EWT_N_H, bool(m_TowerState & EP_TS_N_H)); + FillInitialWorldState(data, count, EP_EWT_N, bool(m_TowerState & EP_TS_N)); +} + +void OPvPCapturePointEP_EWT::UpdateTowerState() +{ + m_PvP->SendUpdateWorldState(EP_EWT_A , bool(m_TowerState & EP_TS_A)); + m_PvP->SendUpdateWorldState(EP_EWT_H , bool(m_TowerState & EP_TS_H)); + m_PvP->SendUpdateWorldState(EP_EWT_A_P , bool(m_TowerState & EP_TS_A_P)); + m_PvP->SendUpdateWorldState(EP_EWT_H_P , bool(m_TowerState & EP_TS_H_P)); + m_PvP->SendUpdateWorldState(EP_EWT_N_A , bool(m_TowerState & EP_TS_N_A)); + m_PvP->SendUpdateWorldState(EP_EWT_N_H , bool(m_TowerState & EP_TS_N_H)); + m_PvP->SendUpdateWorldState(EP_EWT_N , bool(m_TowerState & EP_TS_N)); +} + +bool OPvPCapturePointEP_EWT::HandlePlayerEnter(Player *plr) +{ + if(OPvPCapturePoint::HandlePlayerEnter(plr)) + { + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); + return true; + } + return false; +} + +void OPvPCapturePointEP_EWT::HandlePlayerLeave(Player *plr) +{ + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); + OPvPCapturePoint::HandlePlayerLeave(plr); +} + +void OPvPCapturePointEP_EWT::SummonSupportUnitAtNorthpassTower(uint32 team) +{ + if(m_UnitsSummonedSide != team) + { + m_UnitsSummonedSide = team; + const creature_type * ct = NULL; + if(team == ALLIANCE) + ct=EP_EWT_Summons_A; + else + ct=EP_EWT_Summons_H; + + for (int i = 0; i < EP_EWT_NUM_CREATURES; ++i) + { + DelCreature(i); + AddCreature(i,ct[i].entry,ct[i].teamval,ct[i].map,ct[i].x,ct[i].y,ct[i].z,ct[i].o,1000000); + } + } +} + +// NPT +OPvPCapturePointEP_NPT::OPvPCapturePointEP_NPT(OutdoorPvP *pvp) +: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_SummonedGOSide(0) +{ + SetCapturePointData(EPCapturePoints[EP_NPT].entry,EPCapturePoints[EP_NPT].map,EPCapturePoints[EP_NPT].x,EPCapturePoints[EP_NPT].y,EPCapturePoints[EP_NPT].z,EPCapturePoints[EP_NPT].o,EPCapturePoints[EP_NPT].rot0,EPCapturePoints[EP_NPT].rot1,EPCapturePoints[EP_NPT].rot2,EPCapturePoints[EP_NPT].rot3); + AddObject(EP_NPT_FLAGS,EPTowerFlags[EP_NPT].entry,EPTowerFlags[EP_NPT].map,EPTowerFlags[EP_NPT].x,EPTowerFlags[EP_NPT].y,EPTowerFlags[EP_NPT].z,EPTowerFlags[EP_NPT].o,EPTowerFlags[EP_NPT].rot0,EPTowerFlags[EP_NPT].rot1,EPTowerFlags[EP_NPT].rot2,EPTowerFlags[EP_NPT].rot3); +} + +void OPvPCapturePointEP_NPT::ChangeState() +{ + if(fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out! + { + // if changing from controlling alliance to horde or vice versa + if( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_NPT_A)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = 0; + } + else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_NPT_H)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = 0; + } + + uint32 artkit = 21; + + switch(m_State) + { + case OBJECTIVESTATE_ALLIANCE: + if(m_value == m_maxValue) + m_TowerState = EP_TS_A; + else + m_TowerState = EP_TS_A_P; + artkit = 2; + SummonGO(ALLIANCE); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = ALLIANCE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_A)); + break; + case OBJECTIVESTATE_HORDE: + if(m_value == -m_maxValue) + m_TowerState = EP_TS_H; + else + m_TowerState = EP_TS_H_P; + artkit = 1; + SummonGO(HORDE); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = HORDE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_H)); + break; + case OBJECTIVESTATE_NEUTRAL: + m_TowerState = EP_TS_N; + m_SummonedGOSide = 0; + DelObject(EP_NPT_BUFF); + break; + case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: + case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: + m_TowerState = EP_TS_N_A; + break; + case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: + case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: + m_TowerState = EP_TS_N_H; + break; + } + + GameObject * flag = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, m_capturePointGUID)); + GameObject * flag2 = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, m_Objects[EP_NPT_FLAGS])); + if(flag) + { + flag->SetGoArtKit(artkit); + } + if(flag2) + { + flag2->SetGoArtKit(artkit); + } + + UpdateTowerState(); + + // complete quest objective + if(m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) + SendObjectiveComplete(EP_NPT_CM, 0); + } +} + +void OPvPCapturePointEP_NPT::SendChangePhase() +{ + // send this too, sometimes the slider disappears, dunno why :( + SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + // send these updates to only the ones in this objective + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + // send this too, sometimes it resets :S + SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); +} + +void OPvPCapturePointEP_NPT::FillInitialWorldStates(WorldPacket& data, uint32& count) +{ + FillInitialWorldState(data, count, EP_NPT_A, bool(m_TowerState & EP_TS_A)); + FillInitialWorldState(data, count, EP_NPT_H, bool(m_TowerState & EP_TS_H)); + FillInitialWorldState(data, count, EP_NPT_A_P, bool(m_TowerState & EP_TS_A_P)); + FillInitialWorldState(data, count, EP_NPT_H_P, bool(m_TowerState & EP_TS_H_P)); + FillInitialWorldState(data, count, EP_NPT_N_A, bool(m_TowerState & EP_TS_N_A)); + FillInitialWorldState(data, count, EP_NPT_N_H, bool(m_TowerState & EP_TS_N_H)); + FillInitialWorldState(data, count, EP_NPT_N, bool(m_TowerState & EP_TS_N)); +} + +void OPvPCapturePointEP_NPT::UpdateTowerState() +{ + m_PvP->SendUpdateWorldState(EP_NPT_A , bool(m_TowerState & EP_TS_A)); + m_PvP->SendUpdateWorldState(EP_NPT_H , bool(m_TowerState & EP_TS_H)); + m_PvP->SendUpdateWorldState(EP_NPT_A_P , bool(m_TowerState & EP_TS_A_P)); + m_PvP->SendUpdateWorldState(EP_NPT_H_P , bool(m_TowerState & EP_TS_H_P)); + m_PvP->SendUpdateWorldState(EP_NPT_N_A , bool(m_TowerState & EP_TS_N_A)); + m_PvP->SendUpdateWorldState(EP_NPT_N_H , bool(m_TowerState & EP_TS_N_H)); + m_PvP->SendUpdateWorldState(EP_NPT_N , bool(m_TowerState & EP_TS_N)); +} + +bool OPvPCapturePointEP_NPT::HandlePlayerEnter(Player *plr) +{ + if(OPvPCapturePoint::HandlePlayerEnter(plr)) + { + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); + return true; + } + return false; +} + +void OPvPCapturePointEP_NPT::HandlePlayerLeave(Player *plr) +{ + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); + OPvPCapturePoint::HandlePlayerLeave(plr); +} + +void OPvPCapturePointEP_NPT::SummonGO(uint32 team) +{ + if(m_SummonedGOSide != team) + { + m_SummonedGOSide = team; + DelObject(EP_NPT_BUFF); + AddObject(EP_NPT_BUFF,EP_NPT_LordaeronShrine.entry,EP_NPT_LordaeronShrine.map,EP_NPT_LordaeronShrine.x,EP_NPT_LordaeronShrine.y,EP_NPT_LordaeronShrine.z,EP_NPT_LordaeronShrine.o,EP_NPT_LordaeronShrine.rot0,EP_NPT_LordaeronShrine.rot1,EP_NPT_LordaeronShrine.rot2,EP_NPT_LordaeronShrine.rot3); + GameObject * go = ObjectAccessor::GetGameObjectInWorld(m_Objects[EP_NPT_BUFF]); + if(go) + go->SetUInt32Value(GAMEOBJECT_FACTION,(team == ALLIANCE ? 84 : 83)); + } +} + +// CGT +OPvPCapturePointEP_CGT::OPvPCapturePointEP_CGT(OutdoorPvP *pvp) +: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_GraveyardSide(0) +{ + SetCapturePointData(EPCapturePoints[EP_CGT].entry,EPCapturePoints[EP_CGT].map,EPCapturePoints[EP_CGT].x,EPCapturePoints[EP_CGT].y,EPCapturePoints[EP_CGT].z,EPCapturePoints[EP_CGT].o,EPCapturePoints[EP_CGT].rot0,EPCapturePoints[EP_CGT].rot1,EPCapturePoints[EP_CGT].rot2,EPCapturePoints[EP_CGT].rot3); + AddObject(EP_CGT_FLAGS,EPTowerFlags[EP_CGT].entry,EPTowerFlags[EP_CGT].map,EPTowerFlags[EP_CGT].x,EPTowerFlags[EP_CGT].y,EPTowerFlags[EP_CGT].z,EPTowerFlags[EP_CGT].o,EPTowerFlags[EP_CGT].rot0,EPTowerFlags[EP_CGT].rot1,EPTowerFlags[EP_CGT].rot2,EPTowerFlags[EP_CGT].rot3); +} + +void OPvPCapturePointEP_CGT::ChangeState() +{ + if(fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out! + { + // if changing from controlling alliance to horde or vice versa + if( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_CGT_A)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = 0; + } + else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_CGT_H)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = 0; + } + + uint32 artkit = 21; + + switch(m_State) + { + case OBJECTIVESTATE_ALLIANCE: + if(m_value == m_maxValue) + m_TowerState = EP_TS_A; + else + m_TowerState = EP_TS_A_P; + artkit = 2; + LinkGraveYard(ALLIANCE); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = ALLIANCE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_A)); + break; + case OBJECTIVESTATE_HORDE: + if(m_value == -m_maxValue) + m_TowerState = EP_TS_H; + else + m_TowerState = EP_TS_H_P; + artkit = 1; + LinkGraveYard(HORDE); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = HORDE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_H)); + break; + case OBJECTIVESTATE_NEUTRAL: + m_TowerState = EP_TS_N; + break; + case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: + case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: + m_TowerState = EP_TS_N_A; + break; + case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: + case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: + m_TowerState = EP_TS_N_H; + break; + } + + GameObject* flag = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, m_capturePointGUID)); + GameObject* flag2 = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT,m_Objects[EP_CGT_FLAGS])); + if(flag) + { + flag->SetGoArtKit(artkit); + } + if(flag2) + { + flag2->SetGoArtKit(artkit); + } + + UpdateTowerState(); + + // complete quest objective + if(m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) + SendObjectiveComplete(EP_CGT_CM, 0); + } +} + +void OPvPCapturePointEP_CGT::SendChangePhase() +{ + // send this too, sometimes the slider disappears, dunno why :( + SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + // send these updates to only the ones in this objective + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + // send this too, sometimes it resets :S + SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); +} + +void OPvPCapturePointEP_CGT::FillInitialWorldStates(WorldPacket& data, uint32& count) +{ + FillInitialWorldState(data, count, EP_CGT_A, bool(m_TowerState & EP_TS_A)); + FillInitialWorldState(data, count, EP_CGT_H, bool(m_TowerState & EP_TS_H)); + FillInitialWorldState(data, count, EP_CGT_A_P, bool(m_TowerState & EP_TS_A_P)); + FillInitialWorldState(data, count, EP_CGT_H_P, bool(m_TowerState & EP_TS_H_P)); + FillInitialWorldState(data, count, EP_CGT_N_A, bool(m_TowerState & EP_TS_N_A)); + FillInitialWorldState(data, count, EP_CGT_N_H, bool(m_TowerState & EP_TS_N_H)); + FillInitialWorldState(data, count, EP_CGT_N, bool(m_TowerState & EP_TS_N)); +} + +void OPvPCapturePointEP_CGT::UpdateTowerState() +{ + m_PvP->SendUpdateWorldState(EP_CGT_A , bool(m_TowerState & EP_TS_A)); + m_PvP->SendUpdateWorldState(EP_CGT_H , bool(m_TowerState & EP_TS_H)); + m_PvP->SendUpdateWorldState(EP_CGT_A_P , bool(m_TowerState & EP_TS_A_P)); + m_PvP->SendUpdateWorldState(EP_CGT_H_P , bool(m_TowerState & EP_TS_H_P)); + m_PvP->SendUpdateWorldState(EP_CGT_N_A , bool(m_TowerState & EP_TS_N_A)); + m_PvP->SendUpdateWorldState(EP_CGT_N_H , bool(m_TowerState & EP_TS_N_H)); + m_PvP->SendUpdateWorldState(EP_CGT_N , bool(m_TowerState & EP_TS_N)); +} + +bool OPvPCapturePointEP_CGT::HandlePlayerEnter(Player *plr) +{ + if(OPvPCapturePoint::HandlePlayerEnter(plr)) + { + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); + return true; + } + return false; +} + +void OPvPCapturePointEP_CGT::HandlePlayerLeave(Player *plr) +{ + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); + OPvPCapturePoint::HandlePlayerLeave(plr); +} + +void OPvPCapturePointEP_CGT::LinkGraveYard(Team team) +{ + if(m_GraveyardSide != team) + { + m_GraveyardSide = team; + sObjectMgr.RemoveGraveYardLink(EP_GraveYardId,EP_GraveYardZone,team,false); + sObjectMgr.AddGraveYardLink(EP_GraveYardId,EP_GraveYardZone,team,false); + } +} + +// PWT +OPvPCapturePointEP_PWT::OPvPCapturePointEP_PWT(OutdoorPvP *pvp) +: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_FlightMasterSpawned(0) +{ + SetCapturePointData(EPCapturePoints[EP_PWT].entry,EPCapturePoints[EP_PWT].map,EPCapturePoints[EP_PWT].x,EPCapturePoints[EP_PWT].y,EPCapturePoints[EP_PWT].z,EPCapturePoints[EP_PWT].o,EPCapturePoints[EP_PWT].rot0,EPCapturePoints[EP_PWT].rot1,EPCapturePoints[EP_PWT].rot2,EPCapturePoints[EP_PWT].rot3); + AddObject(EP_PWT_FLAGS,EPTowerFlags[EP_PWT].entry,EPTowerFlags[EP_PWT].map,EPTowerFlags[EP_PWT].x,EPTowerFlags[EP_PWT].y,EPTowerFlags[EP_PWT].z,EPTowerFlags[EP_PWT].o,EPTowerFlags[EP_PWT].rot0,EPTowerFlags[EP_PWT].rot1,EPTowerFlags[EP_PWT].rot2,EPTowerFlags[EP_PWT].rot3); +} + +void OPvPCapturePointEP_PWT::ChangeState() +{ + if(fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out! + { + // if changing from controlling alliance to horde or vice versa + if( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_PWT_A)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = 0; + } + else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) + { + sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_LOOSE_PWT_H)); + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = 0; + } + + uint32 artkit = 21; + + switch(m_State) + { + case OBJECTIVESTATE_ALLIANCE: + if(m_value == m_maxValue) + m_TowerState = EP_TS_A; + else + m_TowerState = EP_TS_A_P; + SummonFlightMaster(ALLIANCE); + artkit = 2; + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = ALLIANCE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_A)); + break; + case OBJECTIVESTATE_HORDE: + if(m_value == -m_maxValue) + m_TowerState = EP_TS_H; + else + m_TowerState = EP_TS_H_P; + SummonFlightMaster(HORDE); + artkit = 1; + ((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = HORDE; + if(m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,sObjectMgr.GetMangosStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_H)); + break; + case OBJECTIVESTATE_NEUTRAL: + m_TowerState = EP_TS_N; + DelCreature(EP_PWT_FLIGHTMASTER); + m_FlightMasterSpawned = 0; + break; + case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: + case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: + m_TowerState = EP_TS_N_A; + break; + case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: + case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: + m_TowerState = EP_TS_N_H; + break; + } + + GameObject * flag = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, m_capturePointGUID)); + GameObject * flag2 = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, m_Objects[EP_PWT_FLAGS])); + if(flag) + { + flag->SetGoArtKit(artkit); + } + if(flag2) + { + flag2->SetGoArtKit(artkit); + } + + UpdateTowerState(); + + // complete quest objective + if(m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) + SendObjectiveComplete(EP_PWT_CM, 0); + } +} + +void OPvPCapturePointEP_PWT::SendChangePhase() +{ + // send this too, sometimes the slider disappears, dunno why :( + SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + // send these updates to only the ones in this objective + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + // send this too, sometimes it resets :S + SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); +} + +void OPvPCapturePointEP_PWT::FillInitialWorldStates(WorldPacket& data, uint32& count) +{ + FillInitialWorldState(data, count, EP_PWT_A, bool(m_TowerState & EP_TS_A)); + FillInitialWorldState(data, count, EP_PWT_H, bool(m_TowerState & EP_TS_H)); + FillInitialWorldState(data, count, EP_PWT_A_P, bool(m_TowerState & EP_TS_A_P)); + FillInitialWorldState(data, count, EP_PWT_H_P, bool(m_TowerState & EP_TS_H_P)); + FillInitialWorldState(data, count, EP_PWT_N_A, bool(m_TowerState & EP_TS_N_A)); + FillInitialWorldState(data, count, EP_PWT_N_H, bool(m_TowerState & EP_TS_N_H)); + FillInitialWorldState(data, count, EP_PWT_N, bool(m_TowerState & EP_TS_N)); +} + +void OPvPCapturePointEP_PWT::UpdateTowerState() +{ + m_PvP->SendUpdateWorldState(EP_PWT_A , bool(m_TowerState & EP_TS_A)); + m_PvP->SendUpdateWorldState(EP_PWT_H , bool(m_TowerState & EP_TS_H)); + m_PvP->SendUpdateWorldState(EP_PWT_A_P , bool(m_TowerState & EP_TS_A_P)); + m_PvP->SendUpdateWorldState(EP_PWT_H_P , bool(m_TowerState & EP_TS_H_P)); + m_PvP->SendUpdateWorldState(EP_PWT_N_A , bool(m_TowerState & EP_TS_N_A)); + m_PvP->SendUpdateWorldState(EP_PWT_N_H , bool(m_TowerState & EP_TS_N_H)); + m_PvP->SendUpdateWorldState(EP_PWT_N , bool(m_TowerState & EP_TS_N)); +} + +bool OPvPCapturePointEP_PWT::HandlePlayerEnter(Player *plr) +{ + if(OPvPCapturePoint::HandlePlayerEnter(plr)) + { + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); + uint32 phase = (uint32)ceil(( m_value + m_maxValue) / ( 2 * m_maxValue ) * 100.0f); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); + return true; + } + return false; +} + +void OPvPCapturePointEP_PWT::HandlePlayerLeave(Player *plr) +{ + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); + OPvPCapturePoint::HandlePlayerLeave(plr); +} + +void OPvPCapturePointEP_PWT::SummonFlightMaster(uint32 team) +{ + if(m_FlightMasterSpawned != team) + { + m_FlightMasterSpawned = team; + DelCreature(EP_PWT_FLIGHTMASTER); + AddCreature(EP_PWT_FLIGHTMASTER,EP_PWT_FlightMaster.entry,team,EP_PWT_FlightMaster.map,EP_PWT_FlightMaster.x,EP_PWT_FlightMaster.y,EP_PWT_FlightMaster.z,EP_PWT_FlightMaster.o); + } +} + +// ep +OutdoorPvPEP::OutdoorPvPEP() +{ + m_TypeId = OUTDOOR_PVP_EP; + memset(EP_Controls,0,sizeof(EP_Controls)); + m_AllianceTowersControlled = 0; + m_HordeTowersControlled = 0; +} + +bool OutdoorPvPEP::SetupOutdoorPvP() +{ + for (int i = 0; i < EPBuffZonesNum; ++i) + RegisterZone(EPBuffZones[i]); + + AddCapturePoint(new OPvPCapturePointEP_EWT(this)); + AddCapturePoint(new OPvPCapturePointEP_PWT(this)); + AddCapturePoint(new OPvPCapturePointEP_CGT(this)); + AddCapturePoint(new OPvPCapturePointEP_NPT(this)); + return true; +} + +bool OutdoorPvPEP::Update(uint32 diff) +{ + if(OutdoorPvP::Update(diff)) + { + m_AllianceTowersControlled = 0; + m_HordeTowersControlled = 0; + for (int i = 0; i < EP_TOWER_NUM; ++i) + { + if(EP_Controls[i] == ALLIANCE) + ++m_AllianceTowersControlled; + else if(EP_Controls[i] == HORDE) + ++m_HordeTowersControlled; + SendUpdateWorldState(EP_UI_TOWER_COUNT_A,m_AllianceTowersControlled); + SendUpdateWorldState(EP_UI_TOWER_COUNT_H,m_HordeTowersControlled); + BuffTeams(); + } + return true; + } + return false; +} + +void OutdoorPvPEP::HandlePlayerEnterZone(Player * plr, uint32 zone) +{ + // add buffs + if(plr->GetTeam() == ALLIANCE) + { + if(m_AllianceTowersControlled && m_AllianceTowersControlled < 5) + plr->CastSpell(plr,EP_AllianceBuffs[m_AllianceTowersControlled-1],true); + } + else + { + if(m_HordeTowersControlled && m_HordeTowersControlled < 5) + plr->CastSpell(plr,EP_HordeBuffs[m_HordeTowersControlled-1],true); + } + OutdoorPvP::HandlePlayerEnterZone(plr,zone); +} + +void OutdoorPvPEP::HandlePlayerLeaveZone(Player * plr, uint32 zone) +{ + // remove buffs + if(plr->GetTeam() == ALLIANCE) + { + for (int i = 0; i < 4; ++i) + plr->RemoveAurasDueToSpell(EP_AllianceBuffs[i]); + } + else + { + for (int i = 0; i < 4; ++i) + plr->RemoveAurasDueToSpell(EP_HordeBuffs[i]); + } + OutdoorPvP::HandlePlayerLeaveZone(plr, zone); +} + +void OutdoorPvPEP::BuffTeams() +{ + for (PlayerSet::iterator itr = m_players[0].begin(); itr != m_players[0].end(); ++itr) + { + Player * plr = *itr; + { + for (int i = 0; i < 4; ++i) + plr->RemoveAurasDueToSpell(EP_AllianceBuffs[i]); + if(m_AllianceTowersControlled && m_AllianceTowersControlled < 5) + plr->CastSpell(plr,EP_AllianceBuffs[m_AllianceTowersControlled-1],true); + } + } + for (PlayerSet::iterator itr = m_players[1].begin(); itr != m_players[1].end(); ++itr) + { + Player * plr = *itr; + { + for (int i = 0; i < 4; ++i) + plr->RemoveAurasDueToSpell(EP_HordeBuffs[i]); + if(m_HordeTowersControlled && m_HordeTowersControlled < 5) + plr->CastSpell(plr,EP_HordeBuffs[m_HordeTowersControlled-1],true); + } + } +} + +void OutdoorPvPEP::FillInitialWorldStates(WorldPacket& data, uint32& count) +{ + FillInitialWorldState(data, count, EP_UI_TOWER_COUNT_A, m_AllianceTowersControlled); + FillInitialWorldState(data, count, EP_UI_TOWER_COUNT_H, m_HordeTowersControlled); + FillInitialWorldState(data, count, EP_UI_TOWER_SLIDER_DISPLAY, 0); + FillInitialWorldState(data, count, EP_UI_TOWER_SLIDER_POS, 50); + FillInitialWorldState(data, count, EP_UI_TOWER_SLIDER_N, 100); + for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) + { + itr->second->FillInitialWorldStates(data, count); + } +} + +void OutdoorPvPEP::SendRemoveWorldStates(Player *plr) +{ + plr->SendUpdateWorldState(EP_UI_TOWER_COUNT_A,0); + plr->SendUpdateWorldState(EP_UI_TOWER_COUNT_H,0); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY,0); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS,0); + plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N,0); + + plr->SendUpdateWorldState(EP_EWT_A,0); + plr->SendUpdateWorldState(EP_EWT_H,0); + plr->SendUpdateWorldState(EP_EWT_N,0); + plr->SendUpdateWorldState(EP_EWT_A_P,0); + plr->SendUpdateWorldState(EP_EWT_H_P,0); + plr->SendUpdateWorldState(EP_EWT_N_A,0); + plr->SendUpdateWorldState(EP_EWT_N_H,0); + + plr->SendUpdateWorldState(EP_PWT_A,0); + plr->SendUpdateWorldState(EP_PWT_H,0); + plr->SendUpdateWorldState(EP_PWT_N,0); + plr->SendUpdateWorldState(EP_PWT_A_P,0); + plr->SendUpdateWorldState(EP_PWT_H_P,0); + plr->SendUpdateWorldState(EP_PWT_N_A,0); + plr->SendUpdateWorldState(EP_PWT_N_H,0); + + plr->SendUpdateWorldState(EP_NPT_A,0); + plr->SendUpdateWorldState(EP_NPT_H,0); + plr->SendUpdateWorldState(EP_NPT_N,0); + plr->SendUpdateWorldState(EP_NPT_A_P,0); + plr->SendUpdateWorldState(EP_NPT_H_P,0); + plr->SendUpdateWorldState(EP_NPT_N_A,0); + plr->SendUpdateWorldState(EP_NPT_N_H,0); + + plr->SendUpdateWorldState(EP_CGT_A,0); + plr->SendUpdateWorldState(EP_CGT_H,0); + plr->SendUpdateWorldState(EP_CGT_N,0); + plr->SendUpdateWorldState(EP_CGT_A_P,0); + plr->SendUpdateWorldState(EP_CGT_H_P,0); + plr->SendUpdateWorldState(EP_CGT_N_A,0); + plr->SendUpdateWorldState(EP_CGT_N_H,0); +} +*/ \ No newline at end of file diff --git a/scripts/outdoor_pvp/eastern_kingdoms/outdoor_pvp_eastern_plaguelands.h b/scripts/outdoor_pvp/eastern_kingdoms/outdoor_pvp_eastern_plaguelands.h new file mode 100644 index 000000000..237b2e5da --- /dev/null +++ b/scripts/outdoor_pvp/eastern_kingdoms/outdoor_pvp_eastern_plaguelands.h @@ -0,0 +1,330 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef OUTDOOR_PVP_EASTERN_PLAGUELANDS_H +#define OUTDOOR_PVP_EASTERN_PLAGUELANDS_H +#include "precompiled.h" + +enum +{ + MAX_VARIABLES = 4, + + TYPE_CROWNGUARD_CONTROLLER = 1, + TYPE_EASTWALL_CONTROLLER = 2, + TYPE_NORTHPASS_CONTROLLER = 3, + TYPE_PLAGUEWOOD_CONTROLLER = 4, + + // spells + // aly + SPELL_ECOES_OF_LORDAERON_ALY_1 = 11413, + SPELL_ECOES_OF_LORDAERON_ALY_2 = 11414, + SPELL_ECOES_OF_LORDAERON_ALY_3 = 11415, + SPELL_ECOES_OF_LORDAERON_ALY_4 = 1386, + + // horde + SPELL_ECOES_OF_LORDAERON_HORDE_1 = 30880, + SPELL_ECOES_OF_LORDAERON_HORDE_2 = 30683, + SPELL_ECOES_OF_LORDAERON_HORDE_3 = 30682, + SPELL_ECOES_OF_LORDAERON_HORDE_4 = 29520, + + // zone ids + ZONE_ID_EASTERN_PLAGUELANDS = 139, + ZONE_ID_STRATHOLME = 2017, + ZONE_ID_SCHOLOMANCE = 2057, + + // graveyards + GRAVEYARD_ZONE_EASTERN_PLAGUE = 139, + GRAVEYARD_ID_EASTERN_PLAGUE = 927, + + // taxi nodes + TAXI_NODE_PLAGUEWOOD_TOWER = 84, + TAXI_NODE_NORTHPASS_TOWER = 85, + TAXI_NODE_EASTWALL_TOWER = 86, + TAXI_NODE_CROWNGUARD_TOWER = 87, + + // npcs + NPC_SPECTRAL_FLIGHTMASTER = 17209, + + // quest + NPC_CROWNGUARD_TOWER_QUEST_DOODAD = 17689, + NPC_EASTWALL_TOWER_QUEST_DOODAD = 17690, + NPC_NORTHPASS_TOWER_QUEST_DOODAD = 17696, + NPC_PLAGUEWOOD_TOWER_QUEST_DOODAD = 17698, + + // aly + NPC_LORDAERON_COMMANDER = 17635, + NPC_LORDAERON_SOLDIER = 17647, + + // horde + NPC_LORDAERON_VETERAN = 17995, + NPC_LORDAERON_FIGHTER = 17996, + + // gameobjects + GO_LORDAERON_SHRINE = 181682, + GO_TOWER_FLAG = 182106, + + // capture points + GO_BATTLEFIELD_BANNER_PLAGUELANDS_1 = 181899, + GO_BATTLEFIELD_BANNER_PLAGUELANDS_2 = 182096, + GO_BATTLEFIELD_BANNER_PLAGUELANDS_3 = 182097, + GO_BATTLEFIELD_BANNER_PLAGUELANDS_4 = 182098, + + // world states + WORLD_STATE_TOWER_COUNT_ALY = 2327, + WORLD_STATE_TOWER_COUNT_HORDE = 2328, + WORLD_STATE_TOWER_SLIDER_DISPLAY = 2426, + WORLD_STATE_TOWER_SLIDER_POS = 2427, + WORLD_STATE_TOWER_SLIDER_NEUTRAL = 2428, + + // plaguewood tower + WORLD_STATE_PLAGUEWOOD_CONQ_ALY = 2366, + WORLD_STATE_PLAGUEWOOD_CONQ_HORDE = 2367, + WORLD_STATE_PLAGUEWOOD_PROG_ALY = 2368, + WORLD_STATE_PLAGUEWOOD_PROG_HORDE = 2369, + WORLD_STATE_PLAGUEWOOD_ALY = 2370, + WORLD_STATE_PLAGUEWOOD_HORDE = 2371, + WORLD_STATE_PLAGUEWOOD_NEUTRAL = 2353, + + // northpass tower + WORLD_STATE_NORTHPASS_CONQ_ALY = 2362, + WORLD_STATE_NORTHPASS_CONQ_HORDE = 2363, + WORLD_STATE_NORTHPASS_PROG_ALY = 2364, + WORLD_STATE_NORTHPASS_PROG_HORDE = 2365, + WORLD_STATE_NORTHPASS_ALY = 2372, + WORLD_STATE_NORTHPASS_HORDE = 2373, + WORLD_STATE_NORTHPASS_NEUTRAL = 2352, + + // eastwall tower + WORLD_STATE_EASTWALL_CONQ_ALY = 2359, + WORLD_STATE_EASTWALL_CONQ_HORDE = 2360, + WORLD_STATE_EASTWALL_PROG_ALY = 2357, + WORLD_STATE_EASTWALL_PROG_HORDE = 2358, + WORLD_STATE_EASTWALL_ALY = 2354, + WORLD_STATE_EASTWALL_HORDE = 2356, + WORLD_STATE_EASTWALL_NEUTRAL = 2361, + + // crownguard tower + WORLD_STATE_CROWNGUARD_CONQ_ALY = 2374, + WORLD_STATE_CROWNGUARD_CONQ_HORDE = 2375, + WORLD_STATE_CROWNGUARD_PROG_ALY = 2376, + WORLD_STATE_CROWNGUARD_PROG_HORDE = 2377, + WORLD_STATE_CROWNGUARD_ALY = 2378, + WORLD_STATE_CROWNGUARD_HORDE = 2379, + WORLD_STATE_CROWNGUARD_NEUTRAL = 2355, +}; + +/* +const uint32 EPTowerPlayerEnterEvents[EP_TOWER_NUM] = {10691,10699,10701,10705}; + +const uint32 EPTowerPlayerLeaveEvents[EP_TOWER_NUM] = {10692,10698,10700,10704}; + +/* +enum EP_Summons { + EP_EWT_COMMANDER = 0, + EP_EWT_SOLDIER1, + EP_EWT_SOLDIER2, + EP_EWT_SOLDIER3, + EP_EWT_SOLDIER4, + EP_PWT_FLIGHTMASTER, +}; + +enum EP_GoSummons { + EP_NPT_BUFF = 0, + EP_NPT_FLAGS, + EP_EWT_FLAGS, + EP_CGT_FLAGS, + EP_PWT_FLAGS +}; + +enum EP_Towers { + EP_EWT = 0, // plaguelands 03 + EP_NPT,// plaguelands 01 + EP_PWT,// plaguelands 04 + EP_CGT,// plaguelands 02 + EP_TOWER_NUM +}; + +const go_type EPCapturePoints[EP_TOWER_NUM] = { + {182097,0,2574.51f,-4794.89f,144.704f,-1.45003f,-0.097056f,0.095578f,-0.656229f,0.742165f}, + {181899,0,3181.08f,-4379.36f,174.123f,-2.03472f,-0.065392f,0.119494f,-0.842275f,0.521553f}, + {182098,0,2962.71f,-3042.31f,154.789f,2.08426f,-0.074807f,-0.113837f,0.855928f,0.49883f}, + {182096,0,1860.85f,-3731.23f,196.716f,-2.53214f,0.033967f,-0.131914f,0.944741f,-0.298177f} +}; + +const go_type EPTowerFlags[EP_TOWER_NUM] = { + {182106,0,2569.60f,-4772.93f,115.399f,2.72271f,0,0,0.978148f,0.207912f}, + {182106,0,3148.17f,-4365.51f,145.029f,1.53589f,0,0,0.694658f,0.71934f}, + {182106,0,2992.63f,-3022.95f,125.593f,3.03687f,0,0,0.99863f,0.052336f}, + {182106,0,1838.42f,-3703.56f,167.713f,0.890118f,0,0,0.430511f,0.902585f} +}; + +const uint32 EP_NUM_CREATURES = 6; +const uint32 EP_EWT_NUM_CREATURES = 5; + +// one lordaeron commander, 4 soldiers +// should be spawned at EWT and follow a path, but trans-grid pathing isn't safe, so summon them directly at NPT +const creature_type EP_EWT_Summons_A[EP_EWT_NUM_CREATURES] = { + {17635,469,0, 3167.61f,-4352.09f,138.20f,4.5811f}, + {17647,469,0, 3172.74f,-4352.99f,139.14f,4.9873f}, + {17647,469,0, 3165.89f,-4354.46f,138.67f,3.7244f}, + {17647,469,0, 3164.65f,-4350.26f,138.22f,2.4794f}, + {17647,469,0, 3169.91f,-4349.68f,138.37f,0.7444f} +}; + +const creature_type EP_EWT_Summons_H[EP_EWT_NUM_CREATURES] = { + {17995,67,0, 3167.61f,-4352.09f,138.20f,4.5811f}, + {17996,67,0, 3172.74f,-4352.99f,139.14f,4.9873f}, + {17996,67,0, 3165.89f,-4354.46f,138.67f,3.7244f}, + {17996,67,0, 3164.65f,-4350.26f,138.22f,2.4794f}, + {17996,67,0, 3169.91f,-4349.68f,138.37f,0.7444f} +}; + +enum EP_TowerStates { + EP_TS_N = 1, + EP_TS_N_A = 2, + EP_TS_N_H = 4, + EP_TS_A_P = 8, + EP_TS_H_P = 16, + EP_TS_A = 32, + EP_TS_H = 64 +}; + +// when spawning, pay attention at setting the faction manually! +const creature_type EP_PWT_FlightMaster = {17209,0,0,2987.5f,-3049.11f,120.126f,5.75959f}; + +// after spawning, modify the faction so that only the controller will be able to use it with SetUInt32Value(GAMEOBJECT_FACTION, faction_id); +const go_type EP_NPT_LordaeronShrine = {181682,0,3167.72f,-4355.91f,138.785f,1.69297f,0,0,0.748956f,0.66262f}; +*/ + +class MANGOS_DLL_DECL outdoor_pvp_eastern_plaguelands : public OutdoorPvP +{ + public: + outdoor_pvp_eastern_plaguelands(Map* pMap); + ~outdoor_pvp_eastern_plaguelands() {} + + void OnPlayerEnterZone(Player* pPlayer, uint32 uiZoneId, uint32 uiAreaId); + void OnPlayerLeaveZone(Player* pPlayer, uint32 uiZoneId); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + + const char* Save() { return strInstData.c_str(); } + void Load(const char* chrIn); + + protected: + void UpdateZoneWorldState(); + void SendPlayerWorldState(Player* pPlayer); + + std::string strInstData; + + uint32 m_uiPlaguewoodController; + uint32 m_uiEastwallController; + uint32 m_uiNorthpassController; + uint32 m_uiCrownguardController; + uint32 m_uiTowersAly; + uint32 m_uiTowersHorde; + + PlayerSet sPlaguelandsPlayers; +}; + +/* +class OPvPCapturePointEP_EWT : public OPvPCapturePoint +{ +friend class OutdoorPvPEP; +public: + OPvPCapturePointEP_EWT(OutdoorPvP * pvp); + void ChangeState(); + void SendChangePhase(); + void FillInitialWorldStates(WorldPacket& data, uint32& count); + // used when player is activated/inactivated in the area + bool HandlePlayerEnter(Player * plr); + void HandlePlayerLeave(Player * plr); +protected: + void SummonSupportUnitAtNorthpassTower(uint32 team); + void UpdateTowerState(); +protected: + uint32 m_TowerState; + uint32 m_UnitsSummonedSide; +}; + +class OPvPCapturePointEP_NPT : public OPvPCapturePoint +{ +friend class OutdoorPvPEP; +public: + OPvPCapturePointEP_NPT(OutdoorPvP * pvp); + void ChangeState(); + void SendChangePhase(); + void FillInitialWorldStates(WorldPacket& data, uint32& count); + // used when player is activated/inactivated in the area + bool HandlePlayerEnter(Player * plr); + void HandlePlayerLeave(Player * plr); +protected: + void SummonGO(uint32 team); + void UpdateTowerState(); +protected: + uint32 m_TowerState; + uint32 m_SummonedGOSide; +}; + +class OPvPCapturePointEP_CGT : public OPvPCapturePoint +{ +friend class OutdoorPvPEP; +public: + OPvPCapturePointEP_CGT(OutdoorPvP * pvp); + void ChangeState(); + void SendChangePhase(); + void FillInitialWorldStates(WorldPacket& data, uint32& count); + // used when player is activated/inactivated in the area + bool HandlePlayerEnter(Player * plr); + void HandlePlayerLeave(Player * plr); +protected: + void LinkGraveYard(Team team); + void UpdateTowerState(); +protected: + uint32 m_TowerState; + uint32 m_GraveyardSide; +}; + +class OPvPCapturePointEP_PWT : public OPvPCapturePoint +{ +friend class OutdoorPvPEP; +public: + OPvPCapturePointEP_PWT(OutdoorPvP * pvp); + void ChangeState(); + void SendChangePhase(); + void FillInitialWorldStates(WorldPacket& data, uint32& count); + // used when player is activated/inactivated in the area + bool HandlePlayerEnter(Player * plr); + void HandlePlayerLeave(Player * plr); +protected: + void SummonFlightMaster(uint32 team); + void UpdateTowerState(); +protected: + uint32 m_FlightMasterSpawned; + uint32 m_TowerState; +}; + +class OutdoorPvPEP : public OutdoorPvP +{ +friend class OPvPCapturePointEP_EWT; +friend class OPvPCapturePointEP_NPT; +friend class OPvPCapturePointEP_PWT; +friend class OPvPCapturePointEP_CGT; +public: + OutdoorPvPEP(); + bool SetupOutdoorPvP(); + void HandlePlayerEnterZone(Player *plr, uint32 zone); + void HandlePlayerLeaveZone(Player *plr, uint32 zone); + bool Update(uint32 diff); + void FillInitialWorldStates(WorldPacket& data, uint32& count); + void SendRemoveWorldStates(Player * plr); + void BuffTeams(); +private: + // how many towers are controlled + uint32 EP_Controls[EP_TOWER_NUM]; + uint32 m_AllianceTowersControlled; + uint32 m_HordeTowersControlled; +}; +*/ +#endif \ No newline at end of file diff --git a/scripts/outdoor_pvp/kalimdor/outdoor_pvp_silithus.cpp b/scripts/outdoor_pvp/kalimdor/outdoor_pvp_silithus.cpp new file mode 100644 index 000000000..6521db47b --- /dev/null +++ b/scripts/outdoor_pvp/kalimdor/outdoor_pvp_silithus.cpp @@ -0,0 +1,278 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: outdoor_pvp_silithus +SD%Complete: +SDComment: +SDCategory: Outdoor PvP +EndScriptData */ + +#include "precompiled.h" +#include "outdoor_pvp_silithus.h" + +outdoor_pvp_silithus::outdoor_pvp_silithus(Map* pMap) : OutdoorPvP(pMap), + m_uiResourcesAly(0), + m_uiResourcesHorde(0), + m_uiLastControllerFaction(0){ } + +void outdoor_pvp_silithus::OnPlayerEnterZone(Player* pPlayer, uint32 uiZoneId) +{ + if (uiZoneId == ZONE_ID_SILITHUS) + { + if(pPlayer->GetTeam() == m_uiLastControllerFaction) + pPlayer->CastSpell(pPlayer, SPELL_CENARION_FAVOR, false); + + // add to the player set + sSilithusPlayers.insert(pPlayer->GetGUID()); + + // send actual world states + SendPlayerWorldState(pPlayer); + } + else + { + if (pPlayer->HasAura(SPELL_CENARION_FAVOR)) + pPlayer->RemoveAurasDueToSpell(SPELL_CENARION_FAVOR); + + // remove from the player set + if (sSilithusPlayers.find(pPlayer->GetGUID()) != sSilithusPlayers.end()) + sSilithusPlayers.erase(pPlayer->GetGUID()); + } +} + +void outdoor_pvp_silithus::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) + { + case TYPE_ALLIANCE_SILITHYSTS: + if (uiData) + m_uiResourcesAly += uiData; + else + m_uiResourcesAly = uiData; + + if (GetData(TYPE_ALLIANCE_SILITHYSTS) == MAX_SILITHYST) + { + SetData(TYPE_CONTROLLER_FACTION, ALLIANCE); + DoApplyTeamBuff(sSilithusPlayers, ALLIANCE, SPELL_CENARION_FAVOR); + + // send zone emote + //sWorld.SendZoneText(ZONE_ID_SILITHUS, ZONE_EMOTE_ALY_CAPTURE); + + // reset counters + SetData(TYPE_ALLIANCE_SILITHYSTS, 0); + SetData(TYPE_HORDE_SILITHYSTS, 0); + } + break; + case TYPE_HORDE_SILITHYSTS: + if (uiData) + m_uiResourcesHorde += uiData; + else + m_uiResourcesHorde = uiData; + + if (GetData(TYPE_HORDE_SILITHYSTS) == MAX_SILITHYST) + { + SetData(TYPE_CONTROLLER_FACTION, HORDE); + DoApplyTeamBuff(sSilithusPlayers, HORDE, SPELL_CENARION_FAVOR); + + // send zone emote + //sWorld.SendZoneText(ZONE_ID_SILITHUS, ZONE_EMOTE_HORDE_CAPTURE); + + // reset counters + SetData(TYPE_ALLIANCE_SILITHYSTS, 0); + SetData(TYPE_HORDE_SILITHYSTS, 0); + } + break; + case TYPE_CONTROLLER_FACTION: + m_uiLastControllerFaction = uiData; + break; + } + + // update states + UpdateZoneWorldState(); + + if (uiData) + { + OUT_SAVE_PVP_DATA; + + std::ostringstream saveStream; + saveStream << m_uiResourcesAly << " " << m_uiResourcesHorde << " " << m_uiLastControllerFaction; + + strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_PVP_DATA_COMPLETE; + } +} + +uint32 outdoor_pvp_silithus::GetData(uint32 uiType) +{ + switch(uiType) + { + case TYPE_ALLIANCE_SILITHYSTS: + return m_uiResourcesAly; + case TYPE_HORDE_SILITHYSTS: + return m_uiResourcesHorde; + case TYPE_CONTROLLER_FACTION: + return m_uiLastControllerFaction; + } + return 0; +} + +void outdoor_pvp_silithus::Load(const char* chrIn) +{ + if (!chrIn) + { + OUT_LOAD_PVP_DATA_FAIL; + return; + } + + OUT_LOAD_PVP_DATA(chrIn); + + std::istringstream loadStream(chrIn); + loadStream >> m_uiResourcesAly >> m_uiResourcesHorde >> m_uiLastControllerFaction; + + OUT_LOAD_PVP_DATA_COMPLETE; +} + +void outdoor_pvp_silithus::UpdateZoneWorldState() +{ + DoUpdateWorldState(sSilithusPlayers, WORLD_STATE_SI_GATHERED_A, m_uiResourcesAly); + DoUpdateWorldState(sSilithusPlayers, WORLD_STATE_SI_GATHERED_H, m_uiResourcesHorde); +} + +void outdoor_pvp_silithus::SendPlayerWorldState(Player* pPlayer) +{ + pPlayer->SendUpdateWorldState(WORLD_STATE_SI_GATHERED_A, m_uiResourcesAly); + pPlayer->SendUpdateWorldState(WORLD_STATE_SI_GATHERED_H, m_uiResourcesHorde); + pPlayer->SendUpdateWorldState(WORLD_STATE_SI_SILITHYST_MAX, MAX_SILITHYST); +} + +void outdoor_pvp_silithus::OnPlayerDroppedFlag(Player* pPlayer, uint32 uiSpellId) +{ + if (uiSpellId != SPELL_SILITHYST) + return; + + // ToDo + // * make it drop by damage - core issue + // * exclude the case when it's dropped near the area trigger + + //switch(pPlayer->GetTeam()) + //{ + // case ALLIANCE: + // if (AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(AREATRIGGER_SILITHUS_ALY)) + // { + // // 5.0f is safe-distance; else drop the flag + // if (pPlayer->GetDistance(atEntry->x, atEntry->y, atEntry->z) < 5.0f + atEntry->radius) + // return; + // } + // break; + // case HORDE: + // if (AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(AREATRIGGER_SILITHUS_HORDE)) + // { + // // 5.0f is safe-distance; else drop the flag + // if (pPlayer->GetDistance(atEntry->x, atEntry->y, atEntry->z) < 5.0f + atEntry->radius) + // return; + // } + // break; + //} + + // drop the flag if conditions are ok + pPlayer->CastSpell(pPlayer, SPELL_SILITHYST_FLAG_DROP, true); +} + +bool AreaTrigger_at_silithus(Player* pPlayer, AreaTriggerEntry const* pAt) +{ + if (pPlayer->isGameMaster() || pPlayer->isDead()) + return false; + + outdoor_pvp_silithus* pOutdoorPvp = (outdoor_pvp_silithus*)pPlayer->GetInstanceData(); + + if (!pOutdoorPvp) + return false; + + if (pAt->id == AREATRIGGER_SILITHUS_ALY) + { + if(pPlayer->GetTeam() == ALLIANCE && pPlayer->HasAura(SPELL_SILITHYST)) + { + // remove aura + pPlayer->RemoveAurasDueToSpell(SPELL_SILITHYST); + pOutdoorPvp->SetData(TYPE_ALLIANCE_SILITHYSTS, 1); + + // reward the player + pPlayer->CastSpell(pPlayer, SPELL_TRACES_OF_SILITHYST, false); + pPlayer->RewardHonor(NULL, 1, HONOR_REWARD_SILITHYST); + //pPlayer->GetReputationMgr().ModifyReputation(sFactionStore.LookupEntry(FACTION_CENARION_CIRCLE), REPUTATION_REWARD_SILITHYST); + + // complete quest + if (pPlayer->GetQuestStatus(QUEST_SCOURING_DESERT_ALY) == QUEST_STATUS_INCOMPLETE) + pPlayer->KilledMonsterCredit(NPC_SILITHUS_DUST_QUEST_ALY); + } + } + else if (pAt->id == AREATRIGGER_SILITHUS_HORDE) + { + if(pPlayer->GetTeam() == HORDE && pPlayer->HasAura(SPELL_SILITHYST)) + { + // remove aura + pPlayer->RemoveAurasDueToSpell(SPELL_SILITHYST); + pOutdoorPvp->SetData(TYPE_HORDE_SILITHYSTS, 1); + + // reward the player + pPlayer->CastSpell(pPlayer, SPELL_TRACES_OF_SILITHYST, false); + pPlayer->RewardHonor(NULL, 1, HONOR_REWARD_SILITHYST); + //pPlayer->GetReputationMgr().ModifyReputation(sFactionStore.LookupEntry(FACTION_CENARION_CIRCLE), REPUTATION_REWARD_SILITHYST); + + // complete quest + if (pPlayer->GetQuestStatus(QUEST_SCOURING_DESERT_HORDE) == QUEST_STATUS_INCOMPLETE) + pPlayer->KilledMonsterCredit(NPC_SILITHUS_DUST_QUEST_HORDE); + } + } + + return false; +} + +bool GOUse_go_silithyst(Player* pPlayer, GameObject* pGo) +{ + // ToDo - in the old DBCs this GO has a spell, so it doesn't need script + pPlayer->CastSpell(pPlayer, SPELL_SILITHYST, false); + pGo->Delete(); + + return true; +} + +InstanceData* GetInstanceData_outdoor_pvp_silithus(Map* pMap) +{ + return new outdoor_pvp_silithus(pMap); +} + +void AddSC_outdoor_pvp_silithus() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "at_silithus"; + pNewScript->pAreaTrigger = &AreaTrigger_at_silithus; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "go_silithyst"; + pNewScript->pGOUse = &GOUse_go_silithyst; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "outdoor_pvp_silithus"; + pNewScript->GetInstanceData = &GetInstanceData_outdoor_pvp_silithus; + pNewScript->RegisterSelf(); +} \ No newline at end of file diff --git a/scripts/outdoor_pvp/kalimdor/outdoor_pvp_silithus.h b/scripts/outdoor_pvp/kalimdor/outdoor_pvp_silithus.h new file mode 100644 index 000000000..5729e79da --- /dev/null +++ b/scripts/outdoor_pvp/kalimdor/outdoor_pvp_silithus.h @@ -0,0 +1,85 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef OUTDOOR_PVP_SILITHUS_H +#define OUTDOOR_PVP_SILITHUS_H + +enum +{ + TYPE_ALLIANCE_SILITHYSTS = 1, + TYPE_HORDE_SILITHYSTS = 2, + TYPE_CONTROLLER_FACTION = 3, + + // npcs + NPC_SILITHUS_DUST_QUEST_ALY = 17090, // dummy npcs for quest credit + NPC_SILITHUS_DUST_QUEST_HORDE = 18199, + + // game objects + GO_SILITHYST_MOUND = 181597, // created when a player drops the flag + GO_SILITHYST_GEYSER = 181598, // spawn on the map by default + + // spells + SPELL_SILITHYST_OBJECT = 29518, // unk, related to the GO + SPELL_SILITHYST = 29519, // buff recieved when you are carrying a silithyst + SPELL_TRACES_OF_SILITHYST = 29534, // individual buff recieved when succesfully delivered a silithyst + SPELL_CENARION_FAVOR = 30754, // zone buff recieved when a faction gathers 200 silithysts + SPELL_SILITHYST_FLAG_DROP = 29533, + + // quests + QUEST_SCOURING_DESERT_ALY = 9419, + QUEST_SCOURING_DESERT_HORDE = 9422, + + // zone ids + ZONE_ID_SILITHUS = 1377, + ZONE_ID_TEMPLE_OF_AQ = 3428, // ToDo - research + ZONE_ID_RUINS_OF_AQ = 3429, // don't know yet how to handle the buff inside the instances + + // area triggers + AREATRIGGER_SILITHUS_ALY = 4162, // areatriggers ids + AREATRIGGER_SILITHUS_HORDE = 4168, + + // zone emotes + ZONE_EMOTE_HORDE_CAPTURE = -1001000, + ZONE_EMOTE_ALY_CAPTURE = -1001001, + + FACTION_CENARION_CIRCLE = 609, + HONOR_REWARD_SILITHYST = 19, + REPUTATION_REWARD_SILITHYST = 20, + MAX_SILITHYST = 200, + + // world states + WORLD_STATE_SI_GATHERED_A = 2313, // world state ids + WORLD_STATE_SI_GATHERED_H = 2314, + WORLD_STATE_SI_SILITHYST_MAX = 2317, +}; + +class MANGOS_DLL_DECL outdoor_pvp_silithus : public OutdoorPvP +{ + public: + outdoor_pvp_silithus(Map* pMap); + ~outdoor_pvp_silithus() {} + + void OnPlayerEnterZone(Player* pPlayer, uint32 uiZoneId); + void OnPlayerDroppedFlag(Player* pPlayer, uint32 uiSpellId); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + + const char* Save() { return strInstData.c_str(); } + void Load(const char* chrIn); + + protected: + void UpdateZoneWorldState(); + void SendPlayerWorldState(Player* pPlayer); + + std::string strInstData; + + uint32 m_uiResourcesAly; + uint32 m_uiResourcesHorde; + uint32 m_uiLastControllerFaction; + + PlayerSet sSilithusPlayers; +}; + +#endif \ No newline at end of file diff --git a/scripts/outdoor_pvp/northrend/.gitignore b/scripts/outdoor_pvp/northrend/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/outdoor_pvp/outdoor_pvp_eastern_kingdoms.cpp b/scripts/outdoor_pvp/outdoor_pvp_eastern_kingdoms.cpp new file mode 100644 index 000000000..84505c86d --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_eastern_kingdoms.cpp @@ -0,0 +1,49 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for 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 + */ + +/* ScriptData +SDName: outdoor_pvp_eastern_kingdoms +SD%Complete: who know? +SDComment: map script selector by /dev/rsa +SDCategory: Outdoor PvP +EndScriptData */ + +#include "precompiled.h" +#include "outdoor_pvp_eastern_kingdoms.h" + +struct MANGOS_DLL_DECL outdoor_pvp_eastern_kingdoms : public OutdoorPvP_ZoneSelector +{ + outdoor_pvp_eastern_kingdoms(Map* pMap) : OutdoorPvP_ZoneSelector(pMap) + { + LoadZoneScripts(pMap, ZoneScriptList); + }; +}; + + +InstanceData* GetInstanceData_outdoor_pvp_eastern_kingdoms(Map* pMap) +{ + return new outdoor_pvp_eastern_kingdoms(pMap); +} + +void AddSC_outdoor_pvp_eastern_kingdoms() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "outdoor_pvp_eastern_kingdoms"; + newscript->GetInstanceData = &GetInstanceData_outdoor_pvp_eastern_kingdoms; + newscript->RegisterSelf(); +} + diff --git a/scripts/outdoor_pvp/outdoor_pvp_eastern_kingdoms.h b/scripts/outdoor_pvp/outdoor_pvp_eastern_kingdoms.h new file mode 100644 index 000000000..9636fd4fb --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_eastern_kingdoms.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef OUTDOOR_PVP_EASTERN_KINGDOMS_H +#define OUTDOOR_PVP_EASTERN_KINGDOMS_H + +#include "precompiled.h" +#include "outdoor_pvp_zone_selector.h" + +enum Zones +{ + ZONE_ID_EASTERN_PLAGUELANDS = 139, + ZONE_ID_STRATHOLME = 2017, + ZONE_ID_SCHOLOMANCE = 2057 +}; + +static ZoneScriptEntry ZoneScriptList[] = +{ + { true, ZONE_ID_EASTERN_PLAGUELANDS, "outdoor_pvp_eastern_plaguelands" }, + { true, ZONE_ID_STRATHOLME, "outdoor_pvp_eastern_plaguelands" }, + { true, ZONE_ID_SCHOLOMANCE, "outdoor_pvp_eastern_plaguelands" }, + { false, 0, "" } +}; + +#endif diff --git a/scripts/outdoor_pvp/outdoor_pvp_kalimdor.cpp b/scripts/outdoor_pvp/outdoor_pvp_kalimdor.cpp new file mode 100644 index 000000000..5ce9f0a38 --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_kalimdor.cpp @@ -0,0 +1,49 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for 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 + */ + +/* ScriptData +SDName: outdoor_pvp_kalimdor +SD%Complete: who know? +SDComment: map script selector by /dev/rsa +SDCategory: Outdoor PvP +EndScriptData */ + +#include "precompiled.h" +#include "outdoor_pvp_kalimdor.h" + +struct MANGOS_DLL_DECL outdoor_pvp_kalimdor : public OutdoorPvP_ZoneSelector +{ + outdoor_pvp_kalimdor(Map* pMap) : OutdoorPvP_ZoneSelector(pMap) + { + LoadZoneScripts(pMap, ZoneScriptList); + }; +}; + + +InstanceData* GetInstanceData_outdoor_pvp_kalimdor(Map* pMap) +{ + return new outdoor_pvp_kalimdor(pMap); +} + +void AddSC_outdoor_pvp_kalimdor() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "outdoor_pvp_kalimdor"; + newscript->GetInstanceData = &GetInstanceData_outdoor_pvp_kalimdor; + newscript->RegisterSelf(); +} + diff --git a/scripts/outdoor_pvp/outdoor_pvp_kalimdor.h b/scripts/outdoor_pvp/outdoor_pvp_kalimdor.h new file mode 100644 index 000000000..509fa6423 --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_kalimdor.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef OUTDOOR_PVP_KALIMDOR_H +#define OUTDOOR_PVP_KALIMDOR_H + +#include "precompiled.h" +#include "outdoor_pvp_zone_selector.h" + +enum Zones +{ + // zone ids + ZONE_ID_SILITHUS = 1377, + ZONE_ID_TEMPLE_OF_AQ = 3428, + ZONE_ID_RUINS_OF_AQ = 3429, +}; + +static ZoneScriptEntry ZoneScriptList[] = +{ + { true, ZONE_ID_SILITHUS, "outdoor_pvp_silithus" }, + { true, ZONE_ID_TEMPLE_OF_AQ, "outdoor_pvp_silithus" }, + { true, ZONE_ID_RUINS_OF_AQ, "outdoor_pvp_silithus" }, + { false, 0, "" } +}; + +#endif diff --git a/scripts/outdoor_pvp/outdoor_pvp_northrend.cpp b/scripts/outdoor_pvp/outdoor_pvp_northrend.cpp new file mode 100644 index 000000000..3104754db --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_northrend.cpp @@ -0,0 +1,49 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for 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 + */ + +/* ScriptData +SDName: outdoor_pvp_northrend +SD%Complete: who know? +SDComment: map script selector by /dev/rsa +SDCategory: Outdoor PvP +EndScriptData */ + +#include "precompiled.h" +#include "outdoor_pvp_northrend.h" + +struct MANGOS_DLL_DECL outdoor_pvp_northrend : public OutdoorPvP_ZoneSelector +{ + outdoor_pvp_northrend(Map* pMap) : OutdoorPvP_ZoneSelector(pMap) + { + LoadZoneScripts(pMap, ZoneScriptList); + }; +}; + + +InstanceData* GetInstanceData_outdoor_pvp_northrend(Map* pMap) +{ + return new outdoor_pvp_northrend(pMap); +} + +void AddSC_outdoor_pvp_northrend() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "outdoor_pvp_northrend"; + newscript->GetInstanceData = &GetInstanceData_outdoor_pvp_northrend; + newscript->RegisterSelf(); +} + diff --git a/scripts/outdoor_pvp/outdoor_pvp_northrend.h b/scripts/outdoor_pvp/outdoor_pvp_northrend.h new file mode 100644 index 000000000..0918d22a0 --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_northrend.h @@ -0,0 +1,22 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef OUTDOOR_PVP_NORTHREND_H +#define OUTDOOR_PVP_NORTHREND_H + +#include "precompiled.h" +#include "outdoor_pvp_zone_selector.h" + +enum Zones +{ + // zone ids + ZONE_ID_WINTERGRASP = 9999, +}; + +static ZoneScriptEntry ZoneScriptList[] = +{ + { false, 0, "" } +}; + +#endif diff --git a/scripts/outdoor_pvp/outdoor_pvp_outland.cpp b/scripts/outdoor_pvp/outdoor_pvp_outland.cpp new file mode 100644 index 000000000..2ead09e4f --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_outland.cpp @@ -0,0 +1,49 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for 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 + */ + +/* ScriptData +SDName: outdoor_pvp_outland +SD%Complete: who know? +SDComment: map script selector by /dev/rsa +SDCategory: Outdoor PvP +EndScriptData */ + +#include "precompiled.h" +#include "outdoor_pvp_outland.h" + +struct MANGOS_DLL_DECL outdoor_pvp_outland : public OutdoorPvP_ZoneSelector +{ + outdoor_pvp_outland(Map* pMap) : OutdoorPvP_ZoneSelector(pMap) + { + LoadZoneScripts(pMap, ZoneScriptList); + }; +}; + + +InstanceData* GetInstanceData_outdoor_pvp_outland(Map* pMap) +{ + return new outdoor_pvp_outland(pMap); +} + +void AddSC_outdoor_pvp_outland() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "outdoor_pvp_outland"; + newscript->GetInstanceData = &GetInstanceData_outdoor_pvp_outland; + newscript->RegisterSelf(); +} + diff --git a/scripts/outdoor_pvp/outdoor_pvp_outland.h b/scripts/outdoor_pvp/outdoor_pvp_outland.h new file mode 100644 index 000000000..db7007b3d --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_outland.h @@ -0,0 +1,21 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef OUTDOOR_PVP_OUTLAND_H +#define OUTDOOR_PVP_OUTLAND_H + +#include "precompiled.h" +#include "outdoor_pvp_zone_selector.h" + +enum Zones +{ + ZONE_ID_1 = 9999, +}; + +static ZoneScriptEntry ZoneScriptList[] = +{ + { false, 0, "" } +}; + +#endif diff --git a/scripts/outdoor_pvp/outdoor_pvp_zone_selector.h b/scripts/outdoor_pvp/outdoor_pvp_zone_selector.h new file mode 100644 index 000000000..7e6ff6cf1 --- /dev/null +++ b/scripts/outdoor_pvp/outdoor_pvp_zone_selector.h @@ -0,0 +1,209 @@ +/* Copyright (C) 2006 - 2011 /dev/rsa for ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +/* +Usage: + - write and register script as always, but not assign scriptname in mangos DB; + - put script name in ZoneScriptList structure in map header file + - enjoy + + TODO: make save/load expression for map +*/ +#ifndef OUTDOOR_PVP_ZONE_SELECTOR_H +#define OUTDOOR_PVP_ZONE_SELECTOR_H +#include "precompiled.h" + +struct ZoneScriptEntry +{ + public: + bool active; + int zone; + std::string scriptName; +}; + +typedef UNORDERED_MAP ZoneScriptsMap; +typedef std::set< InstanceData* > ZoneScriptsSet; + +class OutdoorPvP_ZoneSelector : public OutdoorPvP +{ + public: + OutdoorPvP_ZoneSelector(Map* pMap) : OutdoorPvP(pMap) + {}; + + ~OutdoorPvP_ZoneSelector() + { + for (ZoneScriptsSet::iterator itr = m_scriptsSet.begin(); itr != m_scriptsSet.end();) + delete (*itr); + } + + ZoneScriptsMap m_scriptsMap; + ZoneScriptsSet m_scriptsSet; + std::string saveData; + + void LoadZoneScripts(Map* pMap, ZoneScriptEntry ZoneScriptList[]) + { + m_scriptsMap.clear(); + m_scriptsSet.clear(); + + for(uint16 i = 0; ZoneScriptList[i].zone != 0; ++i) + { + if (!ZoneScriptList[i].active) + continue; + + Script* pScript = GetScriptByName(ZoneScriptList[i].scriptName); + + if (!pScript || !pScript->GetInstanceData) + continue; + + InstanceData* pData = pScript->GetInstanceData(pMap); + + if (!pData) + continue; + + m_scriptsMap.insert(std::make_pair(ZoneScriptList[i].zone, pData)); + m_scriptsSet.insert(pData); + } + }; + + void Initialize() + { + for(ZoneScriptsSet::const_iterator itr = m_scriptsSet.begin(); itr != m_scriptsSet.end(); ++itr ) + (*itr)->Initialize(); + }; + + void Load(const char* data) + { + // need parser for data + for(ZoneScriptsSet::const_iterator itr = m_scriptsSet.begin(); itr != m_scriptsSet.end(); ++itr ) + (*itr)->Load(data); + }; + + void Update(uint32 diff) + { + for(ZoneScriptsSet::const_iterator itr = m_scriptsSet.begin(); itr != m_scriptsSet.end(); ++itr ) + (*itr)->Update(diff); + }; + + bool IsEncounterInProgress() const { return false; }; + + void OnPlayerEnter(Player* player) + { + if (!player) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(player->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnPlayerEnter(player); + }; + + void OnPlayerDeath(Player* player) + { + if (!player) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(player->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnPlayerDeath(player); + }; + + void OnPlayerLeave(Player* player) + { + if (!player) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(player->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnPlayerLeave(player); + }; + + void OnPlayerEnterZone(Player* player, uint32 uiNewZoneId, uint32 uiNewAreaId) + { + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(uiNewZoneId); + if (itr != m_scriptsMap.end()) + itr->second->OnPlayerEnterZone(player, uiNewZoneId, uiNewAreaId); + }; + + void OnPlayerLeaveZone(Player* player, uint32 uiOldZoneId) + { + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(uiOldZoneId); + if (itr != m_scriptsMap.end()) + itr->second->OnPlayerLeaveZone(player, uiOldZoneId); + }; + + void OnPlayerDroppedFlag(Player* player, uint32 uiSpellId) + { + if (!player) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(player->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnPlayerDroppedFlag(player, uiSpellId); + }; + + void OnObjectCreate(GameObject* pGO) + { + if (!pGO) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(pGO->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnObjectCreate(pGO); + }; + + void OnCreatureCreate(Creature* creature) + { + if (!creature) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(creature->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnCreatureCreate(creature); + }; + + void OnCreatureEnterCombat(Creature* creature) + { + if (!creature) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(creature->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnCreatureCreate(creature); + }; + + void OnCreatureEvade(Creature* creature) + { + if (!creature) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(creature->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnCreatureEvade(creature); + }; + + void OnCreatureDeath(Creature* creature) + { + if (!creature) + return; + + ZoneScriptsMap::const_iterator itr = m_scriptsMap.find(creature->GetZoneId()); + + if (itr != m_scriptsMap.end()) + itr->second->OnCreatureDeath(creature); + }; + + bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0) { return false; }; + + bool CheckConditionCriteriaMeet(Player const* source, uint32 map_id, uint32 instance_condition_id) { return false; }; + +}; + +#endif diff --git a/scripts/outdoor_pvp/outland/.gitignore b/scripts/outdoor_pvp/outland/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp b/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp index 943b36d8a..621649f5b 100644 --- a/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp +++ b/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -317,7 +317,7 @@ struct MANGOS_DLL_DECL mob_avatar_of_martyredAI : public ScriptedAI } uint32 m_uiMortalStrikeTimer; - + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) diff --git a/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak.cpp b/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak.cpp new file mode 100644 index 000000000..9f1c9242d --- /dev/null +++ b/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_shirrak +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Auchindoun, Auchenai Crypts +EndScriptData */ + +#include "precompiled.h" + +void AddSC_boss_shirrak() +{ +} \ No newline at end of file diff --git a/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp b/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp index 39cae8b15..6d997c5cb 100644 --- a/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp +++ b/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp b/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp index 8be002a7a..f953705ea 100644 --- a/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp +++ b/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp b/scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp new file mode 100644 index 000000000..617218506 --- /dev/null +++ b/scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_anzu +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Auchindoun, Sethekk Halls +EndScriptData */ + +#include "precompiled.h" + +void AddSC_boss_anzu() +{ +} diff --git a/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp b/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp index d5dd136c1..25d124eaf 100644 --- a/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp +++ b/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -207,7 +207,7 @@ struct MANGOS_DLL_DECL mob_syth_fireAI : public ScriptedAI { mob_syth_fireAI(Creature* pCreature) : ScriptedAI(pCreature) { - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); Reset(); } diff --git a/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp b/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp deleted file mode 100644 index 293e1a03a..000000000 --- a/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright (C) 2006 - 2010 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 - */ - -/* ScriptData -SDName: Boss_Talon_King_Ikiss -SD%Complete: 80 -SDComment: Heroic supported. Some details missing, but most are spell related. -SDCategory: Auchindoun, Sethekk Halls -EndScriptData */ - -#include "precompiled.h" -#include "sethekk_halls.h" - -#define SAY_INTRO -1556007 -#define SAY_AGGRO_1 -1556008 -#define SAY_AGGRO_2 -1556009 -#define SAY_AGGRO_3 -1556010 -#define SAY_SLAY_1 -1556011 -#define SAY_SLAY_2 -1556012 -#define SAY_DEATH -1556013 -#define EMOTE_ARCANE_EXP -1556015 - -#define SPELL_BLINK 38194 -#define SPELL_BLINK_TELEPORT 38203 -#define SPELL_MANA_SHIELD 38151 -#define SPELL_ARCANE_BUBBLE 9438 -#define H_SPELL_SLOW 35032 - -#define SPELL_POLYMORPH 38245 -#define H_SPELL_POLYMORPH 43309 - -#define SPELL_ARCANE_VOLLEY 35059 -#define H_SPELL_ARCANE_VOLLEY 40424 - -#define SPELL_ARCANE_EXPLOSION 38197 -#define H_SPELL_ARCANE_EXPLOSION 40425 - -struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI -{ - boss_talon_king_ikissAI(Creature* pCreature) : ScriptedAI(pCreature) - { - m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); - m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); - Reset(); - } - - ScriptedInstance* m_pInstance; - bool m_bIsRegularMode; - - uint32 ArcaneVolley_Timer; - uint32 Sheep_Timer; - uint32 Blink_Timer; - uint32 Slow_Timer; - - bool ManaShield; - bool Blink; - bool Intro; - - void Reset() - { - ArcaneVolley_Timer = 5000; - Sheep_Timer = 8000; - Blink_Timer = 35000; - Slow_Timer = urand(15000, 30000); - Blink = false; - Intro = false; - ManaShield = false; - } - - void MoveInLineOfSight(Unit *who) - { - if (!m_creature->getVictim() && who->isTargetableForAttack() && (m_creature->IsHostileTo(who)) && who->isInAccessablePlaceFor(m_creature)) - { - if (!Intro && m_creature->IsWithinDistInMap(who, 100)) - { - Intro = true; - DoScriptText(SAY_INTRO, 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); - } - } - } - - void Aggro(Unit *who) - { - switch(urand(0, 2)) - { - case 0: DoScriptText(SAY_AGGRO_1, m_creature); break; - case 1: DoScriptText(SAY_AGGRO_2, m_creature); break; - case 2: DoScriptText(SAY_AGGRO_3, m_creature); break; - } - } - - void JustDied(Unit* Killer) - { - DoScriptText(SAY_DEATH, m_creature); - - if (m_pInstance) - m_pInstance->SetData(DATA_IKISSDOOREVENT, DONE); - } - - void KilledUnit(Unit* victim) - { - DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - if (Blink) - { - DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_EXPLOSION : H_SPELL_ARCANE_EXPLOSION); - m_creature->CastSpell(m_creature,SPELL_ARCANE_BUBBLE,true); - Blink = false; - } - - if (ArcaneVolley_Timer < diff) - { - DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_VOLLEY : H_SPELL_ARCANE_VOLLEY); - ArcaneVolley_Timer = urand(7000, 12000); - }else ArcaneVolley_Timer -= diff; - - if (Sheep_Timer < diff) - { - //second top aggro target in normal, random target in heroic correct? - Unit *target = NULL; - if (m_bIsRegularMode ? target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1) : target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCastSpellIfCan(target, m_bIsRegularMode ? SPELL_POLYMORPH : H_SPELL_POLYMORPH); - Sheep_Timer = urand(15000, 17500); - }else Sheep_Timer -= diff; - - //may not be correct time to cast - if (!ManaShield && m_creature->GetHealthPercent() < 20.0f) - { - DoCastSpellIfCan(m_creature,SPELL_MANA_SHIELD); - ManaShield = true; - } - - if (!m_bIsRegularMode) - { - if (Slow_Timer < diff) - { - DoCastSpellIfCan(m_creature,H_SPELL_SLOW); - Slow_Timer = urand(15000, 40000); - }else Slow_Timer -= diff; - } - - if (Blink_Timer < diff) - { - DoScriptText(EMOTE_ARCANE_EXP, m_creature); - - if (Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) - { - if (m_creature->IsNonMeleeSpellCasted(false)) - m_creature->InterruptNonMeleeSpells(false); - - //Spell doesn't work, but we use for visual effect at least - DoCastSpellIfCan(target,SPELL_BLINK); - - float X = target->GetPositionX(); - float Y = target->GetPositionY(); - float Z = target->GetPositionZ(); - - m_creature->GetMap()->CreatureRelocation(m_creature,X,Y,Z,0.0f); - m_creature->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, 1); - - DoCastSpellIfCan(target,SPELL_BLINK_TELEPORT); - Blink = true; - } - Blink_Timer = urand(35000, 40000); - }else Blink_Timer -= diff; - - if (!Blink) - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_talon_king_ikiss(Creature* pCreature) -{ - return new boss_talon_king_ikissAI(pCreature); -} - -void AddSC_boss_talon_king_ikiss() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_talon_king_ikiss"; - newscript->GetAI = &GetAI_boss_talon_king_ikiss; - newscript->RegisterSelf(); -} diff --git a/scripts/outland/auchindoun/sethekk_halls/boss_talon_king_ikiss.cpp b/scripts/outland/auchindoun/sethekk_halls/boss_talon_king_ikiss.cpp new file mode 100644 index 000000000..952b71434 --- /dev/null +++ b/scripts/outland/auchindoun/sethekk_halls/boss_talon_king_ikiss.cpp @@ -0,0 +1,214 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: Boss_Talon_King_Ikiss +SD%Complete: 100 +SDComment: +SDCategory: Auchindoun, Sethekk Halls +EndScriptData */ + +#include "precompiled.h" +#include "sethekk_halls.h" + +enum +{ + SAY_INTRO = -1556007, + SAY_AGGRO_1 = -1556008, + SAY_AGGRO_2 = -1556009, + SAY_AGGRO_3 = -1556010, + SAY_SLAY_1 = -1556011, + SAY_SLAY_2 = -1556012, + SAY_DEATH = -1556013, + EMOTE_ARCANE_EXP = -1556015, + + SPELL_BLINK = 38194, + SPELL_MANA_SHIELD = 38151, + SPELL_ARCANE_BUBBLE = 9438, + SPELL_SLOW_H = 35032, + + SPELL_POLYMORPH = 38245, + SPELL_POLYMORPH_H = 43309, + + SPELL_ARCANE_VOLLEY = 35059, + SPELL_ARCANE_VOLLEY_H = 40424, + + SPELL_ARCANE_EXPLOSION = 38197, + SPELL_ARCANE_EXPLOSION_H = 40425, +}; + +struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI +{ + boss_talon_king_ikissAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_bIntro = false; + Reset(); + } + + ScriptedInstance* m_pInstance; + bool m_bIsRegularMode; + + uint32 m_uiArcaneVolleyTimer; + uint32 m_uiSheepTimer; + uint32 m_uiBlinkTimer; + uint32 m_uiSlowTimer; + + bool m_bManaShield; + bool m_bBlink; + bool m_bIntro; + + void Reset() + { + m_uiArcaneVolleyTimer = 5000; + m_uiSheepTimer = 8000; + m_uiBlinkTimer = 35000; + m_uiSlowTimer = urand(15000, 30000); + + m_bBlink = false; + m_bManaShield = false; + } + + void MoveInLineOfSight(Unit* pWho) + { + if (!m_creature->getVictim() && pWho->isTargetableForAttack() && (m_creature->IsHostileTo(pWho)) && pWho->isInAccessablePlaceFor(m_creature)) + { + if (!m_bIntro && m_creature->IsWithinDistInMap(pWho, 100.0f)) + { + m_bIntro = true; + DoScriptText(SAY_INTRO, m_creature); + } + } + + ScriptedAI::MoveInLineOfSight(pWho); + } + + void Aggro(Unit* pWho) + { + switch(urand(0, 2)) + { + case 0: DoScriptText(SAY_AGGRO_1, m_creature); break; + case 1: DoScriptText(SAY_AGGRO_2, m_creature); break; + case 2: DoScriptText(SAY_AGGRO_3, m_creature); break; + } + + if (m_pInstance) + m_pInstance->SetData(TYPE_IKISS, IN_PROGRESS); + } + + void JustDied(Unit* pKiller) + { + DoScriptText(SAY_DEATH, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_IKISS, DONE); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_IKISS, FAIL); + } + + void KilledUnit(Unit* pVctim) + { + DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (EnterEvadeIfOutOfCombatArea(uiDiff)) + return; + + if (m_bBlink) + { + DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_EXPLOSION : SPELL_ARCANE_EXPLOSION_H); + DoCastSpellIfCan(m_creature, SPELL_ARCANE_BUBBLE, CAST_TRIGGERED); + DoResetThreat(); + m_bBlink = false; + } + + if (m_uiArcaneVolleyTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_VOLLEY : SPELL_ARCANE_VOLLEY_H) == CAST_OK) + m_uiArcaneVolleyTimer = urand(7000, 12000); + } + else + m_uiArcaneVolleyTimer -= uiDiff; + + if (m_uiSheepTimer < uiDiff) + { + // second top aggro target in normal, random target in heroic + if (Unit* pTarget = m_bIsRegularMode ? m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1) : m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_POLYMORPH : SPELL_POLYMORPH_H); + m_uiSheepTimer = urand(15000, 17500); + } + else + m_uiSheepTimer -= uiDiff; + + if (!m_bManaShield && m_creature->GetHealthPercent() < 20.0f) + { + if (DoCastSpellIfCan(m_creature, SPELL_MANA_SHIELD) == CAST_OK) + m_bManaShield = true; + } + + if (!m_bIsRegularMode) + { + if (m_uiSlowTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_SLOW_H) == CAST_OK) + m_uiSlowTimer = urand(15000, 30000); + } + else + m_uiSlowTimer -= uiDiff; + } + + if (m_uiBlinkTimer < uiDiff) + { + DoScriptText(EMOTE_ARCANE_EXP, m_creature); + + if (DoCastSpellIfCan(m_creature, SPELL_BLINK, CAST_INTERRUPT_PREVIOUS) == CAST_OK) + { + m_bBlink = true; + m_uiBlinkTimer = urand(35000, 40000); + } + } + else + m_uiBlinkTimer -= uiDiff; + + if (!m_bBlink) + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_talon_king_ikiss(Creature* pCreature) +{ + return new boss_talon_king_ikissAI(pCreature); +} + +void AddSC_boss_talon_king_ikiss() +{ + Script* pNewscript; + + pNewscript = new Script; + pNewscript->Name = "boss_talon_king_ikiss"; + pNewscript->GetAI = &GetAI_boss_talon_king_ikiss; + pNewscript->RegisterSelf(); +} diff --git a/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp b/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp index 6bd4bd43b..46e0bf0b7 100644 --- a/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp +++ b/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,36 +24,98 @@ EndScriptData */ #include "precompiled.h" #include "sethekk_halls.h" -#define IKISS_DOOR 177203 +instance_sethekk_halls::instance_sethekk_halls(Map* pMap) : ScriptedInstance(pMap), + m_uiIkissDoorGUID(0) +{ + Initialize(); +} +void instance_sethekk_halls::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} -struct MANGOS_DLL_DECL instance_sethekk_halls : public ScriptedInstance +void instance_sethekk_halls::OnObjectCreate(GameObject* pGo) { - instance_sethekk_halls(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + if (pGo->GetEntry() == GO_IKISS_DOOR) + { + m_uiIkissDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_IKISS] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + } +} - uint64 m_uiIkissDoorGUID; +void instance_sethekk_halls::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) + { + case TYPE_SYTH: + case TYPE_ANZU: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_IKISS: + if (uiData == DONE) + DoUseDoorOrButton(m_uiIkissDoorGUID, DAY*IN_MILLISECONDS); + m_auiEncounter[uiType] = uiData; + break; + default: + return; + } - void Initialize() + if (uiData == DONE) { - m_uiIkissDoorGUID = 0; + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2]; + + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - void OnObjectCreate(GameObject* pGo) +uint32 instance_sethekk_halls::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + + return 0; +} + +void instance_sethekk_halls::Load(const char* chrIn) +{ + if (!chrIn) { - if (pGo->GetEntry() == IKISS_DOOR) - m_uiIkissDoorGUID = pGo->GetGUID(); + OUT_LOAD_INST_DATA_FAIL; + return; } - void SetData(uint32 uiType, uint32 uiData) + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) { - switch(uiType) - { - case DATA_IKISSDOOREVENT: - if (uiData == DONE) - DoUseDoorOrButton(m_uiIkissDoorGUID,DAY*IN_MILLISECONDS); - break; - } + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; } -}; + + OUT_LOAD_INST_DATA_COMPLETE; +} + +bool instance_sethekk_halls::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/) +{ + if (uiCriteriaId != ACHIEV_CRITA_TURKEY_TIME) + return false; + + if (!pSource) + return false; + + return pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_HAT, 1) && (pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_DRESS, 1) + || pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_ROBE, 1) || pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_ATTIRE, 1)); +} InstanceData* GetInstanceData_instance_sethekk_halls(Map* pMap) { @@ -62,9 +124,10 @@ InstanceData* GetInstanceData_instance_sethekk_halls(Map* pMap) void AddSC_instance_sethekk_halls() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_sethekk_halls"; - newscript->GetInstanceData = &GetInstanceData_instance_sethekk_halls; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_sethekk_halls"; + pNewScript->GetInstanceData = &GetInstanceData_instance_sethekk_halls; + pNewScript->RegisterSelf(); } diff --git a/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h b/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h index c6034a9d3..6b2caa1fd 100644 --- a/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h +++ b/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h @@ -1,9 +1,49 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ #ifndef DEF_SETHEKK_HALLS_H #define DEF_SETHEKK_HALLS_H -#define DATA_IKISSDOOREVENT 1 +enum +{ + MAX_ENCOUNTER = 3, + + TYPE_SYTH = 0, + TYPE_ANZU = 1, + TYPE_IKISS = 2, + + GO_IKISS_DOOR = 177203, + + ACHIEV_CRITA_TURKEY_TIME = 11142, + ITEM_PILGRIMS_HAT = 46723, + ITEM_PILGRIMS_DRESS = 44785, + ITEM_PILGRIMS_ROBE = 46824, + ITEM_PILGRIMS_ATTIRE = 46800, +}; + +class MANGOS_DLL_DECL instance_sethekk_halls : public ScriptedInstance +{ + public: + instance_sethekk_halls(Map* pMap); + ~instance_sethekk_halls() {} + + void Initialize(); + void OnObjectCreate(GameObject* pGo); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + + bool CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + private: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiIkissDoorGUID; +}; + #endif diff --git a/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp b/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp index 7e48175c5..55f34033f 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp b/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp index 257ae653b..806ce787e 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -126,10 +126,11 @@ struct MANGOS_DLL_DECL boss_blackheart_the_inciterAI : public ScriptedAI { DoCastSpellIfCan(m_creature, SPELL_INCITE_CHAOS); - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator itr = vGuids.begin();itr != vGuids.end(); ++itr) { - Unit* target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + Unit* target = m_creature->GetMap()->GetUnit(*itr); if (target && target->GetTypeId() == TYPEID_PLAYER) target->CastSpell(target,SPELL_INCITE_CHAOS_B,true); diff --git a/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp b/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp index 01fb70149..6e430df0f 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -156,10 +156,11 @@ struct MANGOS_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI float ranY = LOCY; float ranZ = LOCZ; - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator itr = vGuids.begin();itr != vGuids.end(); ++itr) { - Unit* target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + Unit* target = m_creature->GetMap()->GetUnit(*itr); if (target && target->GetTypeId() == TYPEID_PLAYER) { diff --git a/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp b/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp index 697362765..0de40677b 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -79,10 +79,11 @@ struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI void SonicBoomEffect() { - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator itr = vGuids.begin();itr != vGuids.end(); ++itr) { - Unit* target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + Unit* target = m_creature->GetMap()->GetUnit(*itr); if (target && target->GetTypeId() == TYPEID_PLAYER) { @@ -134,7 +135,7 @@ struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI }else MurmursTouch_Timer -= diff; //Resonance_Timer - if (!CanSonicBoom && !m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (!CanSonicBoom && !m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { if (Resonance_Timer < diff) { @@ -191,6 +192,7 @@ struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_murmur(Creature* pCreature) { return new boss_murmurAI(pCreature); diff --git a/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp b/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp index f229f688f..5e1573a11 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h b/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h index 30f5a3b40..b09e29ac2 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h +++ b/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/black_temple/black_temple.cpp b/scripts/outland/black_temple/black_temple.cpp index 96fdb6d1f..3fd733912 100644 --- a/scripts/outland/black_temple/black_temple.cpp +++ b/scripts/outland/black_temple/black_temple.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/black_temple/black_temple.h b/scripts/outland/black_temple/black_temple.h index 439c9eb9f..aba7fe543 100644 --- a/scripts/outland/black_temple/black_temple.h +++ b/scripts/outland/black_temple/black_temple.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,39 +7,90 @@ enum { - MAX_ENCOUNTER = 9, - - TYPE_NAJENTUS = 1, - TYPE_SUPREMUS = 2, - TYPE_SHADE = 3, - TYPE_GOREFIEND = 4, - TYPE_BLOODBOIL = 5, - TYPE_RELIQUIARY = 6, - TYPE_SHAHRAZ = 7, - TYPE_COUNCIL = 8, - TYPE_ILLIDAN = 9, - - DATA_HIGHWARLORDNAJENTUS = 10, - DATA_SUPREMUS = 11, - DATA_SHADEOFAKAMA = 12, - DATA_AKAMA_SHADE = 13, - DATA_ILLIDARICOUNCIL = 14, - DATA_BLOOD_ELF_COUNCIL_VOICE = 15, - DATA_LADYMALANDE = 16, - DATA_HIGHNETHERMANCERZEREVOR = 17, - DATA_GATHIOSTHESHATTERER = 18, - DATA_VERASDARKSHADOW = 19, - DATA_AKAMA = 20, - DATA_ILLIDANSTORMRAGE = 21, - - DATA_GAMEOBJECT_NAJENTUS_GATE = 22, - DATA_GAMEOBJECT_SUPREMUS_DOORS = 23, - DATA_GO_PRE_SHAHRAZ_DOOR = 24, - DATA_GO_POST_SHAHRAZ_DOOR = 25, - DATA_GO_COUNCIL_DOOR = 26, - DATA_GAMEOBJECT_ILLIDAN_GATE = 27, - DATA_GAMEOBJECT_ILLIDAN_DOOR_R = 28, - DATA_GAMEOBJECT_ILLIDAN_DOOR_L = 29 + MAX_ENCOUNTER = 9, + + TYPE_NAJENTUS = 0, + TYPE_SUPREMUS = 1, + TYPE_SHADE = 2, + TYPE_GOREFIEND = 3, + TYPE_BLOODBOIL = 4, + TYPE_RELIQUIARY = 5, + TYPE_SHAHRAZ = 6, + TYPE_COUNCIL = 7, + TYPE_ILLIDAN = 8, + + NPC_WARLORD_NAJENTUS = 22887, + NPC_SUPREMUS = 22898, + NPC_SHADE_OF_AKAMA = 22841, + NPC_AKAMA_SHADE = 22990, + NPC_ILLIDARI_COUNCIL = 23426, + NPC_COUNCIL_VOICE = 23499, + NPC_LADY_MALANDE = 22951, + NPC_ZEREVOR = 22950, + NPC_GATHIOS = 22949, + NPC_VERAS = 22952, + NPC_AKAMA = 23089, + NPC_ILLIDAN_STORMRAGE = 22917, + + GO_NAJENTUS_GATE = 185483, + GO_SUPREMUS_DOORS = 185882, + GO_SHADE_OF_AKAMA = 185478, + GO_PRE_SHAHRAZ_DOOR = 185479, + GO_POST_SHAHRAZ_DOOR = 185482, + GO_PRE_COUNCIL_DOOR = 185481, + GO_COUNCIL_DOOR = 186152, + GO_ILLIDAN_GATE = 185905, + GO_ILLIDAN_DOOR_R = 186261, + GO_ILLIDAN_DOOR_L = 186262, +}; + +class MANGOS_DLL_DECL instance_black_temple : public ScriptedInstance +{ + public: + instance_black_temple(Map* pMap); + + void Initialize(); + + bool IsEncounterInProgress() const; + + void OnCreatureCreate(Creature* pCreature); + void OnObjectCreate(GameObject* pGo); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + private: + bool CanPreMotherDoorOpen(); + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiNajentusGUID; + uint64 m_uiAkamaGUID; // This is the Akama that starts the Illidan encounter. + uint64 m_uiAkama_ShadeGUID; // This is the Akama that starts the Shade of Akama encounter. + uint64 m_uiShadeOfAkamaGUID; + uint64 m_uiSupremusGUID; + uint64 m_uiLadyMalandeGUID; + uint64 m_uiGathiosTheShattererGUID; + uint64 m_uiHighNethermancerZerevorGUID; + uint64 m_uiVerasDarkshadowGUID; + uint64 m_uiIllidariCouncilGUID; + uint64 m_uiBloodElfCouncilVoiceGUID; + uint64 m_uiIllidanStormrageGUID; + + uint64 m_uiNajentusGateGUID; + uint64 m_uiMainTempleDoorsGUID; + uint64 m_uiShadeAkamaDoorGUID; + uint64 m_uiIllidanGateGUID; + uint64 m_uiIllidanDoorGUID[2]; + uint64 m_uiShahrazPreDoorGUID; + uint64 m_uiShahrazPostDoorGUID; + uint64 m_uiPreCouncilDoorGUID; + uint64 m_uiCouncilDoorGUID; }; #endif diff --git a/scripts/outland/black_temple/boss_bloodboil.cpp b/scripts/outland/black_temple/boss_bloodboil.cpp index 9ded2ef11..6e8da16f8 100644 --- a/scripts/outland/black_temple/boss_bloodboil.cpp +++ b/scripts/outland/black_temple/boss_bloodboil.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -109,8 +109,6 @@ struct MANGOS_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI void Aggro(Unit *who) { - m_creature->SetInCombatWithZone(); - DoScriptText(SAY_AGGRO, m_creature); if (m_pInstance) @@ -320,7 +318,7 @@ struct MANGOS_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI PhaseChangeTimer = 60000; } }else PhaseChangeTimer -= diff; - + //Enrage if (m_uiEnrageTimer < diff) { diff --git a/scripts/outland/black_temple/boss_illidan.cpp b/scripts/outland/black_temple/boss_illidan.cpp index 1d1f396b8..87306209e 100644 --- a/scripts/outland/black_temple/boss_illidan.cpp +++ b/scripts/outland/black_temple/boss_illidan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -342,9 +342,9 @@ struct MANGOS_DLL_DECL demonfireAI : public ScriptedAI { if (!IllidanGUID && m_pInstance) { - if (Creature* pIllidan = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_ILLIDANSTORMRAGE))) + if (Creature* pIllidan = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ILLIDAN_STORMRAGE))) { - IllidanGUID = m_pInstance->GetData64(DATA_ILLIDANSTORMRAGE); + IllidanGUID = m_pInstance->GetData64(NPC_ILLIDAN_STORMRAGE); if (!pIllidan->HasSplineFlag(SPLINEFLAG_NO_SPLINE)) m_creature->SetDeathState(JUST_DIED); @@ -411,13 +411,13 @@ struct MANGOS_DLL_DECL npc_akama_illidanAI : public ScriptedAI if (m_pInstance) { m_pInstance->SetData(TYPE_ILLIDAN, NOT_STARTED); - GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE)); + GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_ILLIDAN_GATE)); // close door if already open (when raid wipes or something) if (pGate && !pGate->GetGoState()) pGate->SetGoState(GO_STATE_READY); - for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i) + for(uint32 i = GO_ILLIDAN_DOOR_R; i < GO_ILLIDAN_DOOR_L + 1; ++i) { if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(i))) pDoor->SetGoState(GO_STATE_ACTIVE); @@ -464,10 +464,11 @@ struct MANGOS_DLL_DECL npc_akama_illidanAI : public ScriptedAI void KillAllElites() { - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator itr = vGuids.begin();itr != vGuids.end(); ++itr) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*itr); if (pUnit && pUnit->GetTypeId() == TYPEID_UNIT && pUnit->GetEntry() == ILLIDARI_ELITE) pUnit->SetDeathState(JUST_DIED); @@ -502,13 +503,14 @@ struct MANGOS_DLL_DECL npc_akama_illidanAI : public ScriptedAI void BeginDoorEvent(Player* pPlayer) { - if (!m_pInstance) + // Requires Instance and this additional check to prevent exploits + if (!m_pInstance || m_pInstance->GetData(TYPE_COUNCIL) != DONE) return; debug_log("SD2: Akama - Door event initiated by player %s", pPlayer->GetName()); PlayerGUID = pPlayer->GetGUID(); - if (GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE))) + if (GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_ILLIDAN_GATE))) { float x,y,z; pGate->GetPosition(x, y, z); @@ -555,7 +557,7 @@ struct MANGOS_DLL_DECL npc_akama_illidanAI : public ScriptedAI if (!IsReturningToIllidan) { // open the doors that close the summit - for(uint32 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L+1; ++i) + for(uint32 i = GO_ILLIDAN_DOOR_R; i < GO_ILLIDAN_DOOR_L+1; ++i) { if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(i))) pDoor->SetGoState(GO_STATE_ACTIVE); @@ -677,7 +679,7 @@ struct MANGOS_DLL_DECL npc_akama_illidanAI : public ScriptedAI }else { if (m_pInstance) - IllidanGUID = m_pInstance->GetData64(DATA_ILLIDANSTORMRAGE); + IllidanGUID = m_pInstance->GetData64(NPC_ILLIDAN_STORMRAGE); } if (IsWalking && WalkTimer) @@ -713,7 +715,7 @@ struct MANGOS_DLL_DECL npc_akama_illidanAI : public ScriptedAI } } - if (GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE))) + if (GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_ILLIDAN_GATE))) pGate->SetGoState(GO_STATE_ACTIVE); ++ChannelCount; @@ -987,11 +989,6 @@ struct MANGOS_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI m_pInstance->SetData(TYPE_ILLIDAN, NOT_STARTED); } - void Aggro(Unit* pWho) - { - m_creature->SetInCombatWithZone(); - } - void AttackStart(Unit *who) { if (!who || IsTalking || Phase == 2 || Phase == 4 || Phase == 6 || m_creature->HasAura(SPELL_KNEEL, EFFECT_INDEX_0)) @@ -1043,7 +1040,7 @@ struct MANGOS_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI // Completed m_pInstance->SetData(TYPE_ILLIDAN, DONE); - for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i) + for(uint32 i = GO_ILLIDAN_DOOR_R; i < GO_ILLIDAN_DOOR_L + 1; ++i) { // Open Doors if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(i))) @@ -1158,7 +1155,7 @@ struct MANGOS_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI { if (m_pInstance) { - AkamaGUID = m_pInstance->GetData64(DATA_AKAMA); + AkamaGUID = m_pInstance->GetData64(NPC_AKAMA); if (!AkamaGUID) return; GUID = AkamaGUID; @@ -1904,13 +1901,13 @@ void npc_akama_illidanAI::BeginEvent(uint64 PlayerGUID) debug_log("SD2: Akama - Illidan Introduction started. Illidan event properly begun."); if (m_pInstance) { - IllidanGUID = m_pInstance->GetData64(DATA_ILLIDANSTORMRAGE); + IllidanGUID = m_pInstance->GetData64(NPC_ILLIDAN_STORMRAGE); m_pInstance->SetData(TYPE_ILLIDAN, IN_PROGRESS); } if (m_pInstance) { - for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L+1; ++i) + for(uint32 i = GO_ILLIDAN_DOOR_R; i < GO_ILLIDAN_DOOR_L+1; ++i) { if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(i))) pDoor->SetGoState(GO_STATE_READY); @@ -1965,6 +1962,7 @@ void npc_akama_illidanAI::BeginEvent(uint64 PlayerGUID) bool GossipHello_npc_akama_at_illidan(Player* pPlayer, Creature* pCreature) { + // TODO: Add gossip item only when Council is done? pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); pPlayer->SEND_GOSSIP_MENU(10465, pCreature->GetGUID()); @@ -2007,7 +2005,7 @@ struct MANGOS_DLL_DECL boss_maievAI : public ScriptedAI if (!IllidanGUID) { if (m_pInstance) - IllidanGUID = m_pInstance->GetData64(DATA_ILLIDANSTORMRAGE); + IllidanGUID = m_pInstance->GetData64(NPC_ILLIDAN_STORMRAGE); }else { Creature* Illidan = m_creature->GetMap()->GetCreature(IllidanGUID); @@ -2109,7 +2107,7 @@ struct MANGOS_DLL_DECL cage_trap_triggerAI : public ScriptedAI } }; -bool GOHello_cage_trap(Player* pPlayer, GameObject* pGo) +bool GOUse_go_cage_trap(Player* pPlayer, GameObject* pGo) { float x, y, z; pPlayer->GetPosition(x, y, z); @@ -2278,6 +2276,9 @@ struct MANGOS_DLL_DECL flamecrashAI : public ScriptedAI } }; +/* ** TODO This code was unused for long time (not used in DB and pointless) + * ** Keep it temporarily as reference + // Shadowfiends interact with Illidan, setting more targets in Illidan's hashmap struct MANGOS_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI { @@ -2291,7 +2292,7 @@ struct MANGOS_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI void DoMeleeAttackIfReady() { //If we are within range melee the target - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { //Make sure our attack is ready and we aren't currently casting if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) @@ -2305,6 +2306,7 @@ struct MANGOS_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI } } }; +*/ struct MANGOS_DLL_DECL blazeAI : public ScriptedAI { @@ -2406,10 +2408,12 @@ CreatureAI* GetAI_blade_of_azzinoth(Creature* pCreature) return new blade_of_azzinothAI(pCreature); } +/* ** TODO dead code CreatureAI* GetAI_parasitic_shadowfiend(Creature* pCreature) { return new mob_parasitic_shadowfiendAI(pCreature); } +*/ void AddSC_boss_illidan() { @@ -2444,7 +2448,7 @@ void AddSC_boss_illidan() newscript = new Script; newscript->Name = "gameobject_cage_trap"; - newscript->pGOHello = &GOHello_cage_trap; + newscript->pGOUse = &GOUse_go_cage_trap; newscript->RegisterSelf(); newscript = new Script; @@ -2472,8 +2476,10 @@ void AddSC_boss_illidan() newscript->GetAI = &GetAI_blaze; newscript->RegisterSelf(); + /* ** TODO dead code newscript = new Script; newscript->Name = "mob_parasitic_shadowfiend"; newscript->GetAI = &GetAI_parasitic_shadowfiend; newscript->RegisterSelf(); + */ } diff --git a/scripts/outland/black_temple/boss_mother_shahraz.cpp b/scripts/outland/black_temple/boss_mother_shahraz.cpp index ec1eaac7d..b5234993d 100644 --- a/scripts/outland/black_temple/boss_mother_shahraz.cpp +++ b/scripts/outland/black_temple/boss_mother_shahraz.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -124,8 +124,6 @@ struct MANGOS_DLL_DECL boss_shahrazAI : public ScriptedAI if (m_pInstance) m_pInstance->SetData(TYPE_SHAHRAZ, IN_PROGRESS); - m_creature->SetInCombatWithZone(); - DoScriptText(SAY_AGGRO, m_creature); } diff --git a/scripts/outland/black_temple/boss_reliquary_of_souls.cpp b/scripts/outland/black_temple/boss_reliquary_of_souls.cpp index bde3a38b5..5145a5e8a 100644 --- a/scripts/outland/black_temple/boss_reliquary_of_souls.cpp +++ b/scripts/outland/black_temple/boss_reliquary_of_souls.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -174,7 +174,7 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); + m_creature->HandleEmote(EMOTE_ONESHOT_NONE); m_creature->GetMotionMaster()->Clear(false); } @@ -218,7 +218,7 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI Phase = 1; // I R ANNNGRRRY! - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,375); + m_creature->HandleEmote(EMOTE_STATE_READY2H); SummonEssenceTimer = 8000; AnimationTimer = 5100; m_creature->AddThreat(who); @@ -288,14 +288,14 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI if (AnimationTimer < diff) { // Release the cube - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); + m_creature->HandleEmote(EMOTE_ONESHOT_SUBMERGE); AnimationTimer = 8300; }else AnimationTimer -= diff; if (SummonEssenceTimer < diff) { // Ribs: open - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); + m_creature->HandleEmote(EMOTE_STATE_SUBMERGED); Creature* EssenceSuffering = m_creature->SummonCreature(23418, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); @@ -350,7 +350,7 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI if (AnimationTimer < diff) { // Return - EssenceSuffering->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); + EssenceSuffering->HandleEmote(EMOTE_ONESHOT_SUBMERGE); AnimationTimer = 10000; }else AnimationTimer -= diff; @@ -361,7 +361,7 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI EssenceSuffering->DeleteThreatList(); EssenceSuffering->SetDisplayId(11686); EssenceSuffering->setFaction(35); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); + m_creature->HandleEmote(EMOTE_ONESHOT_NONE); SummonEssenceTimer = 20000; //60000; AnimationTimer = 18200; //58100; SoulDeathCount = 0; @@ -391,14 +391,14 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI if (AnimationTimer < diff) { // Release the cube - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); + m_creature->HandleEmote(EMOTE_ONESHOT_SUBMERGE); AnimationTimer = 10000; }else AnimationTimer -= diff; if (SummonEssenceTimer < diff) { // Ribs: open - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); + m_creature->HandleEmote(EMOTE_STATE_SUBMERGED); Creature* EssenceDesire = m_creature->SummonCreature(23419, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); @@ -455,7 +455,7 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI if (AnimationTimer < diff) { // Return - EssenceDesire->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); + EssenceDesire->HandleEmote(EMOTE_ONESHOT_SUBMERGE); AnimationTimer = 10000; }else AnimationTimer -= diff; @@ -467,7 +467,7 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI DoScriptText(DESI_SAY_AFTER, EssenceDesire); EssenceDesire->SetDisplayId(11686); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); + m_creature->HandleEmote(EMOTE_ONESHOT_NONE); SummonEssenceTimer = 20000; AnimationTimer = 18200; SoulDeathCount = 0; @@ -498,14 +498,14 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI if (AnimationTimer < diff) { // Release the cube - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); + m_creature->HandleEmote(EMOTE_ONESHOT_SUBMERGE); AnimationTimer = 10000; }else AnimationTimer -= diff; if (SummonEssenceTimer < diff) { // Ribs: open - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); + m_creature->HandleEmote(EMOTE_STATE_SUBMERGED); Creature* EssenceAnger = m_creature->SummonCreature(23420, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000); @@ -587,7 +587,6 @@ struct MANGOS_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); DoCastSpellIfCan(pWho, AURA_OF_SUFFERING, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, ESSENCE_OF_SUFFERING_PASSIVE, CAST_TRIGGERED); } @@ -724,11 +723,6 @@ struct MANGOS_DLL_DECL boss_essence_of_desireAI : public ScriptedAI } } - void Aggro(Unit* pWho) - { - m_creature->SetInCombatWithZone(); - } - void KilledUnit(Unit *victim) { switch(urand(0, 2)) @@ -826,7 +820,6 @@ struct MANGOS_DLL_DECL boss_essence_of_angerAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); DoCastSpellIfCan(m_creature->getVictim(), AURA_OF_ANGER, CAST_TRIGGERED); } diff --git a/scripts/outland/black_temple/boss_shade_of_akama.cpp b/scripts/outland/black_temple/boss_shade_of_akama.cpp index 25c64d1bc..4e0d01652 100644 --- a/scripts/outland/black_temple/boss_shade_of_akama.cpp +++ b/scripts/outland/black_temple/boss_shade_of_akama.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -52,7 +52,6 @@ enum SPELL_AKAMA_SOUL_CHANNEL = 40447, SPELL_AKAMA_SOUL_RETRIEVE = 40902, - NPC_AKAMA = 22990, NPC_ASH_CHANNELER = 23421, NPC_ASH_SORCERER = 23215, NPC_ASH_DEFENDER = 23216, @@ -158,7 +157,7 @@ struct MANGOS_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); + m_creature->HandleEmote(EMOTE_STATE_STUN); } void AttackStart(Unit* pWho) @@ -324,7 +323,7 @@ struct MANGOS_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI m_afSpawnLoc[uiRand].m_fX, m_afSpawnLoc[uiRand].m_fY, m_afSpawnLoc[uiRand].m_fZ, m_afSpawnLoc[uiRand].m_fO, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000)) { - if (Creature* pAkama = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_AKAMA_SHADE))) + if (Creature* pAkama = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_AKAMA_SHADE))) pDefender->AI()->AttackStart(pAkama); } @@ -343,7 +342,7 @@ struct MANGOS_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI if (m_uiDeathCount >= 6) { - if (Creature* pAkama = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_AKAMA_SHADE))) + if (Creature* pAkama = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_AKAMA_SHADE))) { if (pAkama && pAkama->isAlive()) { @@ -365,7 +364,7 @@ struct MANGOS_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI { if (m_uiReduceHealthTimer < uiDiff) { - if (Creature* pAkama = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_AKAMA_SHADE))) + if (Creature* pAkama = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_AKAMA_SHADE))) { if (pAkama->isAlive()) { @@ -456,7 +455,7 @@ struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI if (!m_pInstance) return; - if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) { if (boss_shade_of_akamaAI* pShadeAI = dynamic_cast(pShade->AI())) pShadeAI->PrepareChannelers(); @@ -470,7 +469,7 @@ struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI pShade->SetInCombatWith(m_creature); m_creature->SetInCombatWith(pShade); - pShade->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + pShade->HandleEmote(EMOTE_STATE_NONE); pShade->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); pShade->SetInCombatWithZone(); @@ -490,7 +489,7 @@ struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI ++m_uiWayPointId; break; case 1: - if (Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) { DoCastSpellIfCan(pShade, SPELL_AKAMA_SOUL_RETRIEVE); m_uiEndingTalkCount = 0; @@ -512,7 +511,7 @@ struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI if (!m_bCanStartCombat) { - if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) { if (!pShade->isAlive()) { @@ -551,7 +550,7 @@ struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI { if (m_uiCheckTimer < uiDiff) { - if (Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) { if (!pShade->isAlive()) { @@ -678,7 +677,7 @@ struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI if (m_uiDestructivePoisonTimer < uiDiff) { - if (Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) { if (pShade->isAlive()) DoCastSpellIfCan(pShade, SPELL_DESTRUCTIVE_POISON); @@ -756,7 +755,7 @@ struct MANGOS_DLL_DECL mob_ashtongue_channelerAI : public ScriptedAI if (!m_pInstance) return; - if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) { if (pShade->isAlive()) { @@ -776,7 +775,7 @@ struct MANGOS_DLL_DECL mob_ashtongue_channelerAI : public ScriptedAI //start channel (not nice way to start channeling) if (!m_creature->IsNonMeleeSpellCasted(false) && !m_creature->getVictim() && m_pInstance) { - if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) m_creature->CastSpell(pShade, SPELL_SHADE_SOUL_CHANNEL, false); } } @@ -809,7 +808,7 @@ struct MANGOS_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI if (!m_pInstance) return; - if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA))) + if (Creature* pShade = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA))) { if (pShade->isAlive()) { @@ -828,7 +827,7 @@ struct MANGOS_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI if (m_uiCheckTimer < uiDiff) { - Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SHADEOFAKAMA)); + Creature* pShade = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADE_OF_AKAMA)); if (pShade && pShade->isAlive() && m_creature->isAlive()) { diff --git a/scripts/outland/black_temple/boss_supremus.cpp b/scripts/outland/black_temple/boss_supremus.cpp index 5f05a156d..4e0bff084 100644 --- a/scripts/outland/black_temple/boss_supremus.cpp +++ b/scripts/outland/black_temple/boss_supremus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -16,136 +16,69 @@ /* ScriptData SDName: Boss_Supremus -SD%Complete: 95 -SDComment: Need to implement molten punch +SD%Complete: 90 +SDComment: Fixating the target is hacky, unknown if other speed-changes happen, remove AI for trigger mobs in next step SDCategory: Black Temple EndScriptData */ #include "precompiled.h" #include "black_temple.h" -#define EMOTE_NEW_TARGET -1564010 -#define EMOTE_PUNCH_GROUND -1564011 //DoScriptText(EMOTE_PUNCH_GROUND, m_creature); -#define EMOTE_GROUND_CRACK -1564012 - -//Spells -#define SPELL_HURTFUL_STRIKE 41926 -#define SPELL_DEMON_FIRE 40029 -#define SPELL_MOLTEN_FLAME 40253 -#define SPELL_VOLCANIC_ERUPTION 40276 -#define SPELL_VOLCANIC_FIREBALL 40118 -#define SPELL_VOLCANIC_GEYSER 42055 -#define SPELL_MOLTEN_PUNCH 40126 -#define SPELL_BERSERK 45078 - -#define CREATURE_VOLCANO 23085 -#define CREATURE_STALKER 23095 - -struct MANGOS_DLL_DECL molten_flameAI : public ScriptedAI +enum { - molten_flameAI(Creature* pCreature) : ScriptedAI(pCreature) - { - Reset(); - } - - uint64 SupremusGUID; - bool TargetLocked; - uint32 CheckTimer; - - void Reset() - { - SupremusGUID = 0; - TargetLocked = false; - - CheckTimer = 1000; - } - - void AttackStart(Unit* who) {} - void MoveInLineOfSight(Unit *who) - { - if (TargetLocked) - return; - - // stop it from aggroing players who move in LOS if we have a target. - if (who && (who != m_creature) && (m_creature->IsWithinDistInMap(who, 10))) - StalkTarget(who); - } + EMOTE_NEW_TARGET = -1564010, + EMOTE_PUNCH_GROUND = -1564011, + EMOTE_GROUND_CRACK = -1564012, + + // Spells + SPELL_HATEFUL_STRIKE = 41926, + SPELL_CHARGE = 41581, + SPELL_MOLTEN_FLAME = 40980, + SPELL_VOLCANIC_ERUPTION_BOSS = 40276, + SPELL_VOLCANIC_ERUPTION_VOLCANO = 40117, + SPELL_MOLTEN_PUNCH = 40126, + SPELL_BERSERK = 45078, + SPELL_SLOW_SELF = 41922, + + NPC_VOLCANO = 23085, + NPC_STALKER = 23095, +}; - void SetSupremusGUID(uint64 GUID) { SupremusGUID = GUID; } +/* Non existed spells that were used in 3.2 + * Stalker: 40257 41930 + * Supremus: 33420 41582 41925 41951 + */ - void StalkTarget(Unit* target) - { - if (!target) - return; +const float RANGE_MOLTEN_PUNCH = 40.0; - m_creature->AddThreat(target, 50000000.0f); - m_creature->GetMotionMaster()->MoveChase(target); - DoCastSpellIfCan(m_creature, SPELL_DEMON_FIRE, CAST_TRIGGERED); - // DoCastSpellIfCan(m_creature, SPELL_MOLTEN_FLAME, CAST_TRIGGERED); // This spell damages self, so disabled for now - TargetLocked = true; - } +/* These floats are related to the speed-hack near end of script; + * Statet at wowwiki: "If the gaze target is further away than 40 yards, he dashes at about five times the normal run speed until the range is about 20 yards." + * TODO But this is currently not confirmed otherwise to be actually happening + * const float RANGE_MIN_DASHING = 20.0; + * const float SPEED_DASHING = 5.0; + * const float SPEED_CHASE = 0.9f; + */ - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget()) - return; +// TODO Remove this 'script' when combat movement can be proper prevented from core-side +struct MANGOS_DLL_DECL molten_flameAI : public Scripted_NoMovementAI +{ + molten_flameAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) { Reset(); } - if (m_creature->getVictim() && m_creature->isAlive()) - { - if (CheckTimer < diff) - { - if (SupremusGUID) - { - Unit* Supremus = m_creature->GetMap()->GetCreature(SupremusGUID); - if (Supremus && (!Supremus->isAlive())) - m_creature->DealDamage(m_creature, m_creature->GetHealth(), 0, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - CheckTimer = 2000; - }else CheckTimer -= diff; - } - } + void Reset() {} + void AttackStart(Unit* pWho) {} + void MoveInLineOfSight(Unit* pWho) {} + void UpdateAI(const uint32 uiDiff) {} }; -struct MANGOS_DLL_DECL npc_volcanoAI : public ScriptedAI +// TODO Remove this 'script' when combat movement can be proper prevented from core-side +struct MANGOS_DLL_DECL npc_volcanoAI : public Scripted_NoMovementAI { - npc_volcanoAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - uint32 CheckTimer; - uint64 SupremusGUID; - uint32 FireballTimer; - uint32 GeyserTimer; - - void Reset() - { - CheckTimer = 1000; - SupremusGUID = 0; - FireballTimer = 500; - GeyserTimer = 0; - } + npc_volcanoAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) { Reset(); } - void AttackStart(Unit* who) {} - void MoveInLineOfSight(Unit* who) {} - void SetSupremusGUID(uint64 guid) { SupremusGUID = guid; } - - void UpdateAI(const uint32 diff) - { - if (CheckTimer < diff) - { - if (SupremusGUID) - { - Unit* Supremus = m_creature->GetMap()->GetCreature(SupremusGUID); - if (Supremus && (!Supremus->isAlive())) - m_creature->DealDamage(m_creature, m_creature->GetHealth(), 0, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - CheckTimer = 2000; - }else CheckTimer -= diff; - - if (GeyserTimer < diff) - { - DoCastSpellIfCan(m_creature, SPELL_VOLCANIC_GEYSER); - GeyserTimer = 18000; - }else GeyserTimer -= diff; - } + void Reset() {} + void AttackStart(Unit* pWho) {} + void MoveInLineOfSight(Unit* pWho) {} + void UpdateAI(const uint32 uiDiff) {} }; struct MANGOS_DLL_DECL boss_supremusAI : public ScriptedAI @@ -158,25 +91,31 @@ struct MANGOS_DLL_DECL boss_supremusAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 SummonFlameTimer; - uint32 SwitchTargetTimer; - uint32 PhaseSwitchTimer; - uint32 SummonVolcanoTimer; - uint32 HurtfulStrikeTimer; - uint32 BerserkTimer; + uint32 m_uiSummonFlameTimer; + uint32 m_uiSwitchTargetTimer; + uint32 m_uiPhaseSwitchTimer; + uint32 m_uiSummonVolcanoTimer; + uint32 m_uiHatefulStrikeTimer; + uint32 m_uiBerserkTimer; + uint32 m_uiMoltenPunchTimer; - bool Phase1; + uint64 m_uiLastGazeTargetGUID; + + bool m_bTankPhase; + + std::list m_lSummonedGUIDs; void Reset() { - HurtfulStrikeTimer = 5000; - SummonFlameTimer = 20000; - SwitchTargetTimer = 90000; - PhaseSwitchTimer = 60000; - SummonVolcanoTimer = 5000; - BerserkTimer = 900000; // 15 minute enrage - - Phase1 = true; + m_uiHatefulStrikeTimer = 5000; + m_uiSummonFlameTimer = 20000; + m_uiPhaseSwitchTimer = 60000; + m_uiMoltenPunchTimer = 8000; + m_uiBerserkTimer = 15*MINUTE*IN_MILLISECONDS; + + m_uiLastGazeTargetGUID = 0; + + m_bTankPhase = true; } void JustReachedHome() @@ -187,175 +126,180 @@ struct MANGOS_DLL_DECL boss_supremusAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); - if (m_pInstance) m_pInstance->SetData(TYPE_SUPREMUS, IN_PROGRESS); } - void JustDied(Unit *killer) + void JustDied(Unit* pKiller) { if (m_pInstance) m_pInstance->SetData(TYPE_SUPREMUS, DONE); - } - float CalculateRandomCoord(float initial) - { - float coord = 0; - - switch(urand(0, 1)) + for (std::list::const_iterator itr = m_lSummonedGUIDs.begin(); itr != m_lSummonedGUIDs.end(); ++itr) { - case 0: coord = initial + 20 + rand()%20; break; - case 1: coord = initial - 20 - rand()%20; break; + if (Creature* pSummoned = m_creature->GetMap()->GetCreature(*itr)) + pSummoned->ForcedDespawn(); } - - return coord; } - Creature* SummonCreature(uint32 entry, Unit* target) + void JustSummoned(Creature* pSummoned) { - if (target && entry) + if (pSummoned->GetEntry() == NPC_STALKER) { - Creature* Summon = m_creature->SummonCreature(entry, CalculateRandomCoord(target->GetPositionX()), CalculateRandomCoord(target->GetPositionY()), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000); - if (Summon) + Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); + if (!pTarget) + pTarget = m_creature->getVictim(); + + if (pTarget) { - Summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Summon->setFaction(m_creature->getFaction()); - return Summon; + pSummoned->GetMotionMaster()->Clear(); + pSummoned->GetMotionMaster()->MoveFollow(pTarget, 0.0f, 0.0f); + pSummoned->CastSpell(pSummoned, SPELL_MOLTEN_FLAME, false, NULL, NULL, m_creature->GetObjectGuid()); } } - return NULL; + + else if (pSummoned->GetEntry() == NPC_VOLCANO) + pSummoned->CastSpell(pSummoned, SPELL_VOLCANIC_ERUPTION_VOLCANO, false, NULL, NULL, m_creature->GetObjectGuid()); } - Unit* CalculateHurtfulStrikeTarget() + Unit* GetHatefulStrikeTarget() { - uint32 health = 0; - Unit* target = NULL; + uint32 uiHealth = 0; + Unit* pTarget = NULL; ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + for (ThreatList::const_iterator iter = tList.begin(); iter != tList.end(); ++iter) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid()); - if (pUnit && m_creature->IsWithinDistInMap(pUnit, ATTACK_DISTANCE)) + if (pUnit && m_creature->CanReachWithMeleeAttack(pUnit)) { - if (pUnit->GetHealth() > health) + if (pUnit->GetHealth() > uiHealth) { - health = pUnit->GetHealth(); - target = pUnit; + uiHealth = pUnit->GetHealth(); + pTarget = pUnit; } } } - return target; + return pTarget; } - void UpdateAI(const uint32 diff) + void KilledUnit(Unit* pKilled) + { + if (!m_bTankPhase && pKilled->GetGUID() == m_uiLastGazeTargetGUID) + m_uiSwitchTargetTimer = 0; + } + + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (!m_creature->HasAura(SPELL_BERSERK, EFFECT_INDEX_0)) + if (m_uiBerserkTimer) { - if (BerserkTimer < diff) - DoCastSpellIfCan(m_creature, SPELL_BERSERK); - else BerserkTimer -= diff; + if (m_uiBerserkTimer <= uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) + m_uiBerserkTimer = 0; + } + else + m_uiBerserkTimer -= uiDiff; } - if (SummonFlameTimer < diff) + if (m_uiSummonFlameTimer < uiDiff) { - Unit* target = NULL; - target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); - - if (!target) // someone is trying to solo, set target as current victim. - target = m_creature->getVictim(); + // This currently is entirely screwed, because the npc is summoned somewhere far away as of big bounding box of supremus + if (DoCastSpellIfCan(m_creature, SPELL_MOLTEN_PUNCH) == CAST_OK) + m_uiSummonFlameTimer = 20000; + } + else + m_uiSummonFlameTimer -= uiDiff; - if (target) + if (m_uiPhaseSwitchTimer < uiDiff) + { + if (!m_bTankPhase) { - if (Creature* pMoltenFlame = SummonCreature(CREATURE_STALKER, target)) - { - // Invisible model - pMoltenFlame->SetDisplayId(11686); - - if (molten_flameAI* pMoltenAI = dynamic_cast(pMoltenFlame->AI())) - { - pMoltenAI->SetSupremusGUID(m_creature->GetGUID()); - pMoltenAI->StalkTarget(target); - } + m_bTankPhase = true; + m_creature->RemoveAurasDueToSpell(SPELL_SLOW_SELF); + } + else + { + m_bTankPhase = false; + m_uiSwitchTargetTimer = 0; + m_uiSummonVolcanoTimer = 2000; - SummonFlameTimer = 20000; - } + DoCastSpellIfCan(m_creature, SPELL_SLOW_SELF, CAST_INTERRUPT_PREVIOUS); } - }else SummonFlameTimer -= diff; - if (Phase1) + m_uiPhaseSwitchTimer = MINUTE*IN_MILLISECONDS; + DoResetThreat(); + } + else + m_uiPhaseSwitchTimer -= uiDiff; + + if (m_bTankPhase) { - if (HurtfulStrikeTimer < diff) + if (m_uiHatefulStrikeTimer < uiDiff) { - Unit* target = CalculateHurtfulStrikeTarget(); - if (target) + if (Unit* pTarget = GetHatefulStrikeTarget()) { - DoCastSpellIfCan(target, SPELL_HURTFUL_STRIKE); - HurtfulStrikeTimer = 5000; + if (DoCastSpellIfCan(pTarget, SPELL_HATEFUL_STRIKE) == CAST_OK) + m_uiHatefulStrikeTimer = 5000; } - }else HurtfulStrikeTimer -= diff; + } + else + m_uiHatefulStrikeTimer -= uiDiff; } - - if (!Phase1) + else // !m_bTankPhase { - if (SwitchTargetTimer < diff) + if (m_uiSwitchTargetTimer < uiDiff) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { DoResetThreat(); - m_creature->AddThreat(target, 5000000.0f); + // This way to simulate some fixating is to be considered a hack + m_creature->AddThreat(pTarget, 5000000.0f); DoScriptText(EMOTE_NEW_TARGET, m_creature); - SwitchTargetTimer = 10000; + m_uiSwitchTargetTimer = 10000; + m_uiLastGazeTargetGUID = pTarget->GetGUID(); } - }else SwitchTargetTimer -= diff; + } + else + m_uiSwitchTargetTimer -= uiDiff; - if (SummonVolcanoTimer < diff) + if (m_uiSummonVolcanoTimer < uiDiff) { - Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); - - if (!target) - target = m_creature->getVictim(); + Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); - if (target) + if (DoCastSpellIfCan(pTarget ? pTarget : m_creature->getVictim(), SPELL_VOLCANIC_ERUPTION_BOSS) == CAST_OK) { - if (Creature* pVolcano = SummonCreature(CREATURE_VOLCANO, target)) - { - DoCastSpellIfCan(target, SPELL_VOLCANIC_ERUPTION); - - if (npc_volcanoAI* pVolcanoAI = dynamic_cast(pVolcano->AI())) - pVolcanoAI->SetSupremusGUID(m_creature->GetGUID()); - } - DoScriptText(EMOTE_GROUND_CRACK, m_creature); - SummonVolcanoTimer = 10000; + m_uiSummonVolcanoTimer = 10000; } - }else SummonVolcanoTimer -= diff; - } - - if (PhaseSwitchTimer < diff) - { - if (!Phase1) - { - Phase1 = true; - DoResetThreat(); - PhaseSwitchTimer = 60000; - m_creature->SetSpeedRate(MOVE_RUN, 1.0f); } else + m_uiSummonVolcanoTimer -= uiDiff; + + if (m_uiMoltenPunchTimer < uiDiff) { - Phase1 = false; - DoResetThreat(); - SwitchTargetTimer = 10000; - SummonVolcanoTimer = 2000; - PhaseSwitchTimer = 60000; - m_creature->SetSpeedRate(MOVE_RUN, 0.9f); + if (m_creature->GetCombatDistance(m_creature->getVictim()) < RANGE_MOLTEN_PUNCH) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHARGE); + DoScriptText(EMOTE_PUNCH_GROUND, m_creature); + } + m_uiMoltenPunchTimer = 8000; // might be better with small timer and some sort of cast-chance } - }else PhaseSwitchTimer -= diff; + else + m_uiMoltenPunchTimer -= uiDiff; + + /* Not understood how this really must work + * if (m_creature->GetSpeedRate(MOVE_RUN) > SPEED_CHASE && m_creature->GetCombatDistance(m_creature->getVictim()) < RANGE_MIN_DASHING) + * m_creature->SetSpeedRate(MOVE_RUN, SPEED_CHASE); + * else if (m_creature->GetCombatDistance(m_creature->getVictim()) > RANGE_MOLTEN_PUNCH) + * m_creature->SetSpeedRate(MOVE_RUN, SPEED_DASHING); + */ + } DoMeleeAttackIfReady(); } @@ -378,19 +322,20 @@ CreatureAI* GetAI_npc_volcano(Creature* pCreature) void AddSC_boss_supremus() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_supremus"; - newscript->GetAI = &GetAI_boss_supremus; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "molten_flame"; - newscript->GetAI = &GetAI_molten_flame; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_volcano"; - newscript->GetAI = &GetAI_npc_volcano; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_supremus"; + pNewScript->GetAI = &GetAI_boss_supremus; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "molten_flame"; + pNewScript->GetAI = &GetAI_molten_flame; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_volcano"; + pNewScript->GetAI = &GetAI_npc_volcano; + pNewScript->RegisterSelf(); } diff --git a/scripts/outland/black_temple/boss_teron_gorefiend.cpp b/scripts/outland/black_temple/boss_teron_gorefiend.cpp index 6a9043a78..79e55f832 100644 --- a/scripts/outland/black_temple/boss_teron_gorefiend.cpp +++ b/scripts/outland/black_temple/boss_teron_gorefiend.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -258,7 +258,7 @@ struct MANGOS_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI DoScriptText(SAY_INTRO, m_creature); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK); + m_creature->HandleEmote(EMOTE_STATE_TALK); m_uiAggroTargetGUID = pWho->GetGUID(); m_bIntro = true; } @@ -279,7 +279,7 @@ struct MANGOS_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI DoScriptText(SAY_DEATH, m_creature); } - + float CalculateRandomLocation(float fLoc, uint32 uiRadius) { return fLoc + urand(0, 1) ? -rand()%uiRadius : rand()%uiRadius; @@ -315,7 +315,7 @@ struct MANGOS_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI Player* pGhost = NULL; if (m_uiGhostGUID) pGhost = m_creature->GetMap()->GetPlayer(m_uiGhostGUID); - + if (pGhost && pGhost->isAlive() && pGhost->HasAura(SPELL_SHADOW_OF_DEATH, EFFECT_INDEX_0)) { /*float x,y,z; @@ -358,7 +358,7 @@ struct MANGOS_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + m_creature->HandleEmote(EMOTE_STATE_NONE); m_bIntro = false; if (m_uiAggroTargetGUID) { diff --git a/scripts/outland/black_temple/boss_warlord_najentus.cpp b/scripts/outland/black_temple/boss_warlord_najentus.cpp index e7dbf6229..ab701130a 100644 --- a/scripts/outland/black_temple/boss_warlord_najentus.cpp +++ b/scripts/outland/black_temple/boss_warlord_najentus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: Boss_Warlord_Najentus SD%Complete: 90 -SDComment: Does the GO need script? Uncomment code to test. +SDComment: Core spell support for Needle Spine (spells 39992, 39835) missing, no change from SD2 needed SDCategory: Black Temple EndScriptData */ @@ -38,10 +38,9 @@ enum SAY_DEATH = -1564009, SPELL_CRASHINGWAVE = 40100, - SPELL_NEEDLE_SPINE = 39835, - SPELL_NEEDLE_AOE = 39968, + SPELL_NEEDLE_SPINE = 39992, SPELL_TIDAL_BURST = 39878, - SPELL_TIDAL_SHIELD = 39872, // Not going to use this since Hurl Spine doesn't dispel it. + SPELL_TIDAL_SHIELD = 39872, SPELL_IMPALING_SPINE = 39837, SPELL_CREATE_NAJENTUS_SPINE = 39956, SPELL_HURL_SPINE = 39948, @@ -75,6 +74,8 @@ struct MANGOS_DLL_DECL boss_najentusAI : public ScriptedAI m_uiSpecialYellTimer = urand(45000, 120000); m_uiTidalShieldTimer = 60000; m_uiImpalingSpineTimer = 20000; + + SetCombatMovement(true); } void JustReachedHome() @@ -83,12 +84,12 @@ struct MANGOS_DLL_DECL boss_najentusAI : public ScriptedAI m_pInstance->SetData(TYPE_NAJENTUS, NOT_STARTED); } - void KilledUnit(Unit *victim) + void KilledUnit(Unit* pVictim) { DoScriptText(urand(0, 1) ? SAY_SLAY1 : SAY_SLAY2, m_creature); } - void JustDied(Unit *victim) + void JustDied(Unit* pKiller) { if (m_pInstance) m_pInstance->SetData(TYPE_NAJENTUS, DONE); @@ -96,18 +97,19 @@ struct MANGOS_DLL_DECL boss_najentusAI : public ScriptedAI DoScriptText(SAY_DEATH, m_creature); } - void SpellHit(Unit *caster, const SpellEntry *spell) + void SpellHit(Unit* pCaster, const SpellEntry* pSpell) { - if (m_bIsShielded) + if (m_bIsShielded && pSpell->Id == SPELL_HURL_SPINE) { - if (spell->Id == SPELL_HURL_SPINE) - { - if (m_creature->HasAura(SPELL_TIDAL_SHIELD, EFFECT_INDEX_0)) - m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); + if (m_creature->HasAura(SPELL_TIDAL_SHIELD)) + m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); - DoCastSpellIfCan(m_creature->getVictim(), SPELL_TIDAL_BURST); - m_bIsShielded = false; - } + DoCastSpellIfCan(m_creature, SPELL_TIDAL_BURST); + m_bIsShielded = false; + + SetCombatMovement(true); + if (m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } } @@ -117,83 +119,85 @@ struct MANGOS_DLL_DECL boss_najentusAI : public ScriptedAI m_pInstance->SetData(TYPE_NAJENTUS, IN_PROGRESS); DoScriptText(SAY_AGGRO, m_creature); - - m_creature->SetInCombatWithZone(); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (m_uiEnrageTimer < diff) - { - if (m_creature->IsNonMeleeSpellCasted(false)) - m_creature->InterruptNonMeleeSpells(false); - - DoScriptText(SAY_ENRAGE2, m_creature); - DoCastSpellIfCan(m_creature, SPELL_BERSERK); - m_uiEnrageTimer = MINUTE*8*IN_MILLISECONDS; - }else m_uiEnrageTimer -= diff; - - if (m_bIsShielded) + // If shield expired after 45s, attack again + if (m_bIsShielded && m_uiTidalShieldTimer < 16000 && !m_creature->HasAura(SPELL_TIDAL_SHIELD)) { - m_creature->GetMotionMaster()->Clear(false); - m_creature->GetMotionMaster()->MoveIdle(); + m_bIsShielded = false; - return; // Don't cast or do anything while Shielded + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } - // Needle - if (m_uiNeedleSpineTimer < diff) + if (m_uiEnrageTimer < uiDiff) { - for(uint8 i = 0; i < 3; ++i) + if (DoCastSpellIfCan(m_creature, SPELL_BERSERK, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { - Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); - - if (!target) - target = m_creature->getVictim(); - - DoCastSpellIfCan(target, SPELL_NEEDLE_SPINE); - target->CastSpell(target, SPELL_NEEDLE_AOE, false); + m_uiEnrageTimer = MINUTE*8*IN_MILLISECONDS; + DoScriptText(SAY_ENRAGE2, m_creature); } + } + else + m_uiEnrageTimer -= uiDiff; - m_uiNeedleSpineTimer = 3000; - }else m_uiNeedleSpineTimer -= diff; - - if (m_uiSpecialYellTimer < diff) + if (m_uiSpecialYellTimer < uiDiff) { DoScriptText(urand(0, 1) ? SAY_SPECIAL1 : SAY_SPECIAL2, m_creature); m_uiSpecialYellTimer = urand(25000, 100000); - }else m_uiSpecialYellTimer -= diff; + } + else + m_uiSpecialYellTimer -= uiDiff; - if (m_uiImpalingSpineTimer < diff) + if (m_uiImpalingSpineTimer < uiDiff) { - Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); + Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); - if (!target) - target = m_creature->getVictim(); + if (!pTarget) + pTarget = m_creature->getVictim(); - if (target && (target->GetTypeId() == TYPEID_PLAYER)) + if (pTarget && (pTarget->GetTypeId() == TYPEID_PLAYER)) { - DoCastSpellIfCan(target, SPELL_IMPALING_SPINE); + DoCastSpellIfCan(pTarget, SPELL_IMPALING_SPINE); m_uiImpalingSpineTimer = 20000; DoScriptText(urand(0, 1) ? SAY_NEEDLE1 : SAY_NEEDLE2, m_creature); } - }else m_uiImpalingSpineTimer -= diff; + } + else + m_uiImpalingSpineTimer -= uiDiff; - if (m_uiTidalShieldTimer < diff) + if (m_uiTidalShieldTimer < uiDiff) { - m_creature->InterruptNonMeleeSpells(false); - DoCastSpellIfCan(m_creature, SPELL_TIDAL_SHIELD, CAST_TRIGGERED); + DoCastSpellIfCan(m_creature, SPELL_TIDAL_SHIELD, CAST_INTERRUPT_PREVIOUS | CAST_TRIGGERED); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MoveIdle(); + SetCombatMovement(false); m_bIsShielded = true; m_uiTidalShieldTimer = 60000; - }else m_uiTidalShieldTimer -= diff; + + // Skip needle splines for 10s + m_uiNeedleSpineTimer += 10000; + } + else + m_uiTidalShieldTimer -= uiDiff; + + // Needle + if (m_uiNeedleSpineTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_NEEDLE_SPINE) == CAST_OK) + m_uiNeedleSpineTimer = 3000; + } + else + m_uiNeedleSpineTimer -= uiDiff; + DoMeleeAttackIfReady(); } @@ -206,9 +210,10 @@ CreatureAI* GetAI_boss_najentus(Creature* pCreature) void AddSC_boss_najentus() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_najentus"; - newscript->GetAI = &GetAI_boss_najentus; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_najentus"; + pNewScript->GetAI = &GetAI_boss_najentus; + pNewScript->RegisterSelf(); } diff --git a/scripts/outland/black_temple/illidari_council.cpp b/scripts/outland/black_temple/illidari_council.cpp index 0aa9fd571..d4340357a 100644 --- a/scripts/outland/black_temple/illidari_council.cpp +++ b/scripts/outland/black_temple/illidari_council.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -137,10 +137,10 @@ struct MANGOS_DLL_DECL mob_blood_elf_council_voice_triggerAI : public ScriptedAI { if (ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData()) { - Council[0] = pInstance->GetData64(DATA_GATHIOSTHESHATTERER); - Council[1] = pInstance->GetData64(DATA_VERASDARKSHADOW); - Council[2] = pInstance->GetData64(DATA_LADYMALANDE); - Council[3] = pInstance->GetData64(DATA_HIGHNETHERMANCERZEREVOR); + Council[0] = pInstance->GetData64(NPC_GATHIOS); + Council[1] = pInstance->GetData64(NPC_VERAS); + Council[2] = pInstance->GetData64(NPC_LADY_MALANDE); + Council[3] = pInstance->GetData64(NPC_ZEREVOR); }else error_log(ERROR_INST_DATA); } @@ -242,7 +242,7 @@ struct MANGOS_DLL_DECL mob_illidari_councilAI : public ScriptedAI if (m_pInstance->GetData(TYPE_COUNCIL) == DONE) return; - if (Creature* VoiceTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE))) + if (Creature* VoiceTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_COUNCIL_VOICE))) VoiceTrigger->AI()->EnterEvadeMode(); m_pInstance->SetData(TYPE_COUNCIL, NOT_STARTED); @@ -259,13 +259,16 @@ struct MANGOS_DLL_DECL mob_illidari_councilAI : public ScriptedAI if (target && target->isAlive() && !EventBegun) { - Council[0] = m_pInstance->GetData64(DATA_GATHIOSTHESHATTERER); - Council[1] = m_pInstance->GetData64(DATA_HIGHNETHERMANCERZEREVOR); - Council[2] = m_pInstance->GetData64(DATA_LADYMALANDE); - Council[3] = m_pInstance->GetData64(DATA_VERASDARKSHADOW); + // Prevent further handling for next council member aggroing + EventBegun = true; + + Council[0] = m_pInstance->GetData64(NPC_GATHIOS); + Council[1] = m_pInstance->GetData64(NPC_ZEREVOR); + Council[2] = m_pInstance->GetData64(NPC_LADY_MALANDE); + Council[3] = m_pInstance->GetData64(NPC_VERAS); // Start the event for the Voice Trigger - if (Creature* pVoiceTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE))) + if (Creature* pVoiceTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_COUNCIL_VOICE))) { if (mob_blood_elf_council_voice_triggerAI* pVoiceAI = dynamic_cast(pVoiceTrigger->AI())) { @@ -279,14 +282,13 @@ struct MANGOS_DLL_DECL mob_illidari_councilAI : public ScriptedAI if (Council[i]) { Creature* pMember = m_creature->GetMap()->GetCreature(Council[i]); - if (pMember && pMember->isAlive()) + if (pMember && pMember->isAlive() && !pMember->isInCombat()) pMember->AI()->AttackStart(target); } } + // All are set into combat now, Set Instance Data m_pInstance->SetData(TYPE_COUNCIL, IN_PROGRESS); - - EventBegun = true; } } @@ -303,7 +305,7 @@ struct MANGOS_DLL_DECL mob_illidari_councilAI : public ScriptedAI { if (m_pInstance) { - if (Creature* VoiceTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE))) + if (Creature* VoiceTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_COUNCIL_VOICE))) VoiceTrigger->DealDamage(VoiceTrigger, VoiceTrigger->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); m_pInstance->SetData(TYPE_COUNCIL, DONE); @@ -346,7 +348,11 @@ struct MANGOS_DLL_DECL mob_illidari_councilAI : public ScriptedAI } if (EvadeCheck > 3) + { + if (m_pInstance) + m_pInstance->SetData(TYPE_COUNCIL, FAIL); Reset(); + } CheckTimer = 2000; }else CheckTimer -= diff; @@ -376,7 +382,7 @@ struct MANGOS_DLL_DECL boss_illidari_councilAI : public ScriptedAI { if (m_pInstance) { - if (Creature* pController = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ILLIDARICOUNCIL))) + if (Creature* pController = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ILLIDARI_COUNCIL))) { if (mob_illidari_councilAI* pControlAI = dynamic_cast(pController->AI())) pControlAI->StartEvent(pWho); @@ -388,8 +394,6 @@ struct MANGOS_DLL_DECL boss_illidari_councilAI : public ScriptedAI EnterEvadeMode(); } - m_creature->SetInCombatWithZone(); - // Load GUIDs on first aggro because the creature guids are only set as the creatures are created in world- // this means that for each creature, it will attempt to LoadGUIDs even though some of the other creatures are // not in world, and thus have no GUID set in the instance data system. Putting it in aggro ensures that all the creatures @@ -422,10 +426,10 @@ struct MANGOS_DLL_DECL boss_illidari_councilAI : public ScriptedAI return; } - Council[0] = m_pInstance->GetData64(DATA_LADYMALANDE); - Council[1] = m_pInstance->GetData64(DATA_HIGHNETHERMANCERZEREVOR); - Council[2] = m_pInstance->GetData64(DATA_GATHIOSTHESHATTERER); - Council[3] = m_pInstance->GetData64(DATA_VERASDARKSHADOW); + Council[0] = m_pInstance->GetData64(NPC_LADY_MALANDE); + Council[1] = m_pInstance->GetData64(NPC_ZEREVOR); + Council[2] = m_pInstance->GetData64(NPC_GATHIOS); + Council[3] = m_pInstance->GetData64(NPC_VERAS); LoadedGUIDs = true; } diff --git a/scripts/outland/black_temple/instance_black_temple.cpp b/scripts/outland/black_temple/instance_black_temple.cpp index 7d101ef14..4b1a75b9c 100644 --- a/scripts/outland/black_temple/instance_black_temple.cpp +++ b/scripts/outland/black_temple/instance_black_temple.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -36,286 +36,260 @@ EndScriptData */ 8 - Illidan Stormrage Event */ -struct MANGOS_DLL_DECL instance_black_temple : public ScriptedInstance +instance_black_temple::instance_black_temple(Map* pMap) : ScriptedInstance(pMap), + m_uiNajentusGUID(0), + m_uiAkamaGUID(0), + m_uiAkama_ShadeGUID(0), + m_uiShadeOfAkamaGUID(0), + m_uiSupremusGUID(0), + m_uiLadyMalandeGUID(0), + m_uiGathiosTheShattererGUID(0), + m_uiHighNethermancerZerevorGUID(0), + m_uiVerasDarkshadowGUID(0), + m_uiIllidariCouncilGUID(0), + m_uiBloodElfCouncilVoiceGUID(0), + m_uiIllidanStormrageGUID(0), + + m_uiNajentusGateGUID(0), + m_uiMainTempleDoorsGUID(0), + m_uiShadeAkamaDoorGUID(0), + m_uiIllidanGateGUID(0), + m_uiShahrazPreDoorGUID(0), + m_uiShahrazPostDoorGUID(0), + m_uiPreCouncilDoorGUID(0), + m_uiCouncilDoorGUID(0) { - instance_black_temple(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strInstData; - - uint64 m_uiNajentusGUID; - uint64 m_uiAkamaGUID; // This is the Akama that starts the Illidan encounter. - uint64 m_uiAkama_ShadeGUID; // This is the Akama that starts the Shade of Akama encounter. - uint64 m_uiShadeOfAkamaGUID; - uint64 m_uiSupremusGUID; - uint64 m_uiLadyMalandeGUID; - uint64 m_uiGathiosTheShattererGUID; - uint64 m_uiHighNethermancerZerevorGUID; - uint64 m_uiVerasDarkshadowGUID; - uint64 m_uiIllidariCouncilGUID; - uint64 m_uiBloodElfCouncilVoiceGUID; - uint64 m_uiIllidanStormrageGUID; + Initialize(); +}; - uint64 m_uiNajentusGateGUID; - uint64 m_uiMainTempleDoorsGUID; - uint64 m_uiShadeAkamaDoorGUID; - uint64 m_uiIllidanGateGUID; - uint64 m_uiIllidanDoorGUID[2]; - uint64 m_uiShahrazPreDoorGUID; - uint64 m_uiShahrazPostDoorGUID; - uint64 m_uiCouncilDoorGUID; +void instance_black_temple::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + m_uiIllidanDoorGUID[0] = 0; + m_uiIllidanDoorGUID[1] = 0; +} - m_uiNajentusGUID = 0; - m_uiAkamaGUID = 0; - m_uiAkama_ShadeGUID = 0; - m_uiShadeOfAkamaGUID = 0; - m_uiSupremusGUID = 0; - m_uiLadyMalandeGUID = 0; - m_uiGathiosTheShattererGUID = 0; - m_uiHighNethermancerZerevorGUID = 0; - m_uiVerasDarkshadowGUID = 0; - m_uiIllidariCouncilGUID = 0; - m_uiBloodElfCouncilVoiceGUID = 0; - m_uiIllidanStormrageGUID = 0; +bool instance_black_temple::IsEncounterInProgress() const +{ + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) return true; - m_uiNajentusGateGUID = 0; - m_uiMainTempleDoorsGUID = 0; - m_uiShadeAkamaDoorGUID = 0; - m_uiIllidanGateGUID = 0; - m_uiIllidanDoorGUID[0] = 0; - m_uiIllidanDoorGUID[1] = 0; - m_uiShahrazPreDoorGUID = 0; - m_uiShahrazPostDoorGUID = 0; - m_uiCouncilDoorGUID = 0; - } + return false; +} - bool IsEncounterInProgress() const +void instance_black_temple::OnCreatureCreate(Creature* pCreature) +{ + switch(pCreature->GetEntry()) { - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) return true; - - return false; + case NPC_WARLORD_NAJENTUS: m_uiNajentusGUID = pCreature->GetGUID(); break; + case NPC_AKAMA: m_uiAkamaGUID = pCreature->GetGUID(); break; + case NPC_AKAMA_SHADE: m_uiAkama_ShadeGUID = pCreature->GetGUID(); break; + case NPC_SHADE_OF_AKAMA: m_uiShadeOfAkamaGUID = pCreature->GetGUID(); break; + case NPC_SUPREMUS: m_uiSupremusGUID = pCreature->GetGUID(); break; + case NPC_ILLIDAN_STORMRAGE: m_uiIllidanStormrageGUID = pCreature->GetGUID(); break; + case NPC_GATHIOS: m_uiGathiosTheShattererGUID = pCreature->GetGUID(); break; + case NPC_ZEREVOR: m_uiHighNethermancerZerevorGUID = pCreature->GetGUID(); break; + case NPC_LADY_MALANDE: m_uiLadyMalandeGUID = pCreature->GetGUID(); break; + case NPC_VERAS: m_uiVerasDarkshadowGUID = pCreature->GetGUID(); break; + case NPC_ILLIDARI_COUNCIL: m_uiIllidariCouncilGUID = pCreature->GetGUID(); break; + case NPC_COUNCIL_VOICE: m_uiBloodElfCouncilVoiceGUID = pCreature->GetGUID(); break; } +} - void OnCreatureCreate(Creature* pCreature) +void instance_black_temple::OnObjectCreate(GameObject* pGo) +{ + switch(pGo->GetEntry()) { - switch(pCreature->GetEntry()) - { - case 22887: m_uiNajentusGUID = pCreature->GetGUID(); break; - case 23089: m_uiAkamaGUID = pCreature->GetGUID(); break; - case 22990: m_uiAkama_ShadeGUID = pCreature->GetGUID(); break; - case 22841: m_uiShadeOfAkamaGUID = pCreature->GetGUID(); break; - case 22898: m_uiSupremusGUID = pCreature->GetGUID(); break; - case 22917: m_uiIllidanStormrageGUID = pCreature->GetGUID(); break; - case 22949: m_uiGathiosTheShattererGUID = pCreature->GetGUID(); break; - case 22950: m_uiHighNethermancerZerevorGUID = pCreature->GetGUID(); break; - case 22951: m_uiLadyMalandeGUID = pCreature->GetGUID(); break; - case 22952: m_uiVerasDarkshadowGUID = pCreature->GetGUID(); break; - case 23426: m_uiIllidariCouncilGUID = pCreature->GetGUID(); break; - case 23499: m_uiBloodElfCouncilVoiceGUID = pCreature->GetGUID(); break; - } + case GO_NAJENTUS_GATE: // Gate past Naj'entus (at the entrance to Supermoose's courtyards) + m_uiNajentusGateGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_NAJENTUS] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_SUPREMUS_DOORS: // Main Temple Doors - right past Supermoose (Supremus) + m_uiMainTempleDoorsGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_SUPREMUS] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_SHADE_OF_AKAMA: // Door close during encounter + m_uiShadeAkamaDoorGUID = pGo->GetGUID(); + break; + case GO_PRE_SHAHRAZ_DOOR: // Door leading to Mother Shahraz + m_uiShahrazPreDoorGUID = pGo->GetGUID(); + if (CanPreMotherDoorOpen()) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_POST_SHAHRAZ_DOOR: // Door after shahraz + m_uiShahrazPostDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[6] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_PRE_COUNCIL_DOOR: // Door leading to the Council (grand promenade) + m_uiPreCouncilDoorGUID = pGo->GetGUID(); + break; + case GO_COUNCIL_DOOR: // Door leading to the Council (inside) + m_uiCouncilDoorGUID = pGo->GetGUID(); + break; + case GO_ILLIDAN_GATE: // Gate leading to Temple Summit + m_uiIllidanGateGUID = pGo->GetGUID(); + // TODO - dependend on council state + break; + case GO_ILLIDAN_DOOR_R: // Right door at Temple Summit + m_uiIllidanDoorGUID[0] = pGo->GetGUID(); + break; + case GO_ILLIDAN_DOOR_L: // Left door at Temple Summit + m_uiIllidanDoorGUID[1] = pGo->GetGUID(); + break; } +} - void OnObjectCreate(GameObject* pGo) +bool instance_black_temple::CanPreMotherDoorOpen() +{ + if (m_auiEncounter[TYPE_SHADE] == DONE && m_auiEncounter[TYPE_GOREFIEND] == DONE && m_auiEncounter[TYPE_BLOODBOIL] == DONE && m_auiEncounter[TYPE_RELIQUIARY] == DONE) { - switch(pGo->GetEntry()) - { - case 185483: // Gate past Naj'entus (at the entrance to Supermoose's courtyards) - m_uiNajentusGateGUID = pGo->GetGUID(); - if (m_auiEncounter[0] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 185882: // Main Temple Doors - right past Supermoose (Supremus) - m_uiMainTempleDoorsGUID = pGo->GetGUID(); - if (m_auiEncounter[1] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 185478: - m_uiShadeAkamaDoorGUID = pGo->GetGUID(); // Door close during encounter - break; - case 185479: // Door leading to Mother Shahraz - m_uiShahrazPreDoorGUID = pGo->GetGUID(); - if (CanPreMotherDoorOpen()) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 185481: // Door leading to the Council (grand promenade) - m_uiCouncilDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[6] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 185482: // Door after shahraz - m_uiShahrazPostDoorGUID = pGo->GetGUID(); - if (m_auiEncounter[6] == DONE) - pGo->SetGoState(GO_STATE_ACTIVE); - break; - case 185905: // Gate leading to Temple Summit - m_uiIllidanGateGUID = pGo->GetGUID(); - break; - case 186261: // Right door at Temple Summit - m_uiIllidanDoorGUID[0] = pGo->GetGUID(); - break; - case 186262: // Left door at Temple Summit - m_uiIllidanDoorGUID[1] = pGo->GetGUID(); - break; - } + debug_log("SD2: Black Temple: door to Mother Shahraz can open"); + return true; } - bool CanPreMotherDoorOpen() - { - if (m_auiEncounter[2] == DONE && m_auiEncounter[3] == DONE && m_auiEncounter[4] == DONE && m_auiEncounter[5] == DONE) - { - debug_log("SD2: Black Temple: door to Mother Shahraz can open"); - return true; - } + debug_log("SD2: Black Temple: Door data to Mother Shahraz requested, cannot open yet (Encounter data: %u %u %u %u)",m_auiEncounter[2],m_auiEncounter[3],m_auiEncounter[4],m_auiEncounter[5]); + return false; +} - debug_log("SD2: Black Temple: Door data to Mother Shahraz requested, cannot open yet (Encounter data: %u %u %u %u)",m_auiEncounter[2],m_auiEncounter[3],m_auiEncounter[4],m_auiEncounter[5]); - return false; - } +void instance_black_temple::SetData(uint32 uiType, uint32 uiData) +{ + debug_log("SD2: Instance Black Temple: SetData received for type %u with data %u",uiType,uiData); - void SetData(uint32 uiType, uint32 uiData) + switch(uiType) { - debug_log("SD2: Instance Black Temple: SetData received for type %u with data %u",uiType,uiData); - - switch(uiType) - { - case TYPE_NAJENTUS: - m_auiEncounter[0] = uiData; - if (uiData == DONE) - DoUseDoorOrButton(m_uiNajentusGateGUID); - break; - case TYPE_SUPREMUS: - m_auiEncounter[1] = uiData; - if (uiData == DONE) - DoUseDoorOrButton(m_uiMainTempleDoorsGUID); - break; - case TYPE_SHADE: - m_auiEncounter[2] = uiData; - if (uiData == DONE && CanPreMotherDoorOpen()) - DoUseDoorOrButton(m_uiShahrazPreDoorGUID); - break; - case TYPE_GOREFIEND: - m_auiEncounter[3] = uiData; - if (uiData == DONE && CanPreMotherDoorOpen()) - DoUseDoorOrButton(m_uiShahrazPreDoorGUID); - break; - case TYPE_BLOODBOIL: - m_auiEncounter[4] = uiData; - if (uiData == DONE && CanPreMotherDoorOpen()) - DoUseDoorOrButton(m_uiShahrazPreDoorGUID); - break; - case TYPE_RELIQUIARY: - m_auiEncounter[5] = uiData; - if (uiData == DONE && CanPreMotherDoorOpen()) - DoUseDoorOrButton(m_uiShahrazPreDoorGUID); - break; - case TYPE_SHAHRAZ: - if (uiData == DONE) - { - DoUseDoorOrButton(m_uiCouncilDoorGUID); - DoUseDoorOrButton(m_uiShahrazPostDoorGUID); - } - m_auiEncounter[6] = uiData; - break; - case TYPE_COUNCIL: m_auiEncounter[7] = uiData; break; - case TYPE_ILLIDAN: m_auiEncounter[8] = uiData; break; - default: - error_log("SD2: Instance Black Temple: ERROR SetData = %u for type %u does not exist/not implemented.",uiType,uiData); - break; - } + case TYPE_NAJENTUS: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiNajentusGateGUID); + break; + case TYPE_SUPREMUS: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiMainTempleDoorsGUID); + break; + case TYPE_SHADE: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE && CanPreMotherDoorOpen()) + DoUseDoorOrButton(m_uiShahrazPreDoorGUID); + break; + case TYPE_GOREFIEND: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE && CanPreMotherDoorOpen()) + DoUseDoorOrButton(m_uiShahrazPreDoorGUID); + break; + case TYPE_BLOODBOIL: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE && CanPreMotherDoorOpen()) + DoUseDoorOrButton(m_uiShahrazPreDoorGUID); + break; + case TYPE_RELIQUIARY: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE && CanPreMotherDoorOpen()) + DoUseDoorOrButton(m_uiShahrazPreDoorGUID); + break; + case TYPE_SHAHRAZ: + if (uiData == DONE) + DoUseDoorOrButton(m_uiShahrazPostDoorGUID); + m_auiEncounter[uiType] = uiData; + break; + case TYPE_COUNCIL: + DoUseDoorOrButton(m_uiCouncilDoorGUID); + m_auiEncounter[uiType] = uiData; + break; + case TYPE_ILLIDAN: m_auiEncounter[uiType] = uiData; break; + default: + error_log("SD2: Instance Black Temple: ERROR SetData = %u for type %u does not exist/not implemented.", uiType, uiData); + break; + } - if (uiData == DONE) - { - OUT_SAVE_INST_DATA; + 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]; + 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]; - strInstData = saveStream.str(); + m_strInstData = saveStream.str(); - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - uint32 GetData(uint32 uiType) +uint32 instance_black_temple::GetData(uint32 uiType) +{ + switch(uiType) { - switch(uiType) - { - case TYPE_NAJENTUS: return m_auiEncounter[0]; - case TYPE_SUPREMUS: return m_auiEncounter[1]; - case TYPE_SHADE: return m_auiEncounter[2]; - case TYPE_GOREFIEND: return m_auiEncounter[3]; - case TYPE_BLOODBOIL: return m_auiEncounter[4]; - case TYPE_RELIQUIARY: return m_auiEncounter[5]; - case TYPE_SHAHRAZ: return m_auiEncounter[6]; - case TYPE_COUNCIL: return m_auiEncounter[7]; - case TYPE_ILLIDAN: return m_auiEncounter[8]; - } - - return 0; + case TYPE_NAJENTUS: return m_auiEncounter[0]; + case TYPE_SUPREMUS: return m_auiEncounter[1]; + case TYPE_SHADE: return m_auiEncounter[2]; + case TYPE_GOREFIEND: return m_auiEncounter[3]; + case TYPE_BLOODBOIL: return m_auiEncounter[4]; + case TYPE_RELIQUIARY: return m_auiEncounter[5]; + case TYPE_SHAHRAZ: return m_auiEncounter[6]; + case TYPE_COUNCIL: return m_auiEncounter[7]; + case TYPE_ILLIDAN: return m_auiEncounter[8]; + default: + return 0; } +} - uint64 GetData64(uint32 uiData) +uint64 instance_black_temple::GetData64(uint32 uiData) +{ + switch(uiData) { - switch(uiData) - { - case DATA_HIGHWARLORDNAJENTUS: return m_uiNajentusGUID; - case DATA_AKAMA: return m_uiAkamaGUID; - case DATA_AKAMA_SHADE: return m_uiAkama_ShadeGUID; - case DATA_SHADEOFAKAMA: return m_uiShadeOfAkamaGUID; - case DATA_SUPREMUS: return m_uiSupremusGUID; - case DATA_ILLIDANSTORMRAGE: return m_uiIllidanStormrageGUID; - case DATA_GATHIOSTHESHATTERER: return m_uiGathiosTheShattererGUID; - case DATA_HIGHNETHERMANCERZEREVOR: return m_uiHighNethermancerZerevorGUID; - case DATA_LADYMALANDE: return m_uiLadyMalandeGUID; - case DATA_VERASDARKSHADOW: return m_uiVerasDarkshadowGUID; - case DATA_ILLIDARICOUNCIL: return m_uiIllidariCouncilGUID; - case DATA_GAMEOBJECT_NAJENTUS_GATE: return m_uiNajentusGateGUID; - case DATA_GAMEOBJECT_ILLIDAN_GATE: return m_uiIllidanGateGUID; - case DATA_GAMEOBJECT_ILLIDAN_DOOR_R: return m_uiIllidanDoorGUID[0]; - case DATA_GAMEOBJECT_ILLIDAN_DOOR_L: return m_uiIllidanDoorGUID[1]; - case DATA_GAMEOBJECT_SUPREMUS_DOORS: return m_uiMainTempleDoorsGUID; - case DATA_BLOOD_ELF_COUNCIL_VOICE: return m_uiBloodElfCouncilVoiceGUID; - case DATA_GO_PRE_SHAHRAZ_DOOR: return m_uiShahrazPreDoorGUID; - case DATA_GO_POST_SHAHRAZ_DOOR: return m_uiShahrazPostDoorGUID; - case DATA_GO_COUNCIL_DOOR: return m_uiCouncilDoorGUID; - } - - return 0; + case NPC_WARLORD_NAJENTUS: return m_uiNajentusGUID; + case NPC_AKAMA: return m_uiAkamaGUID; + case NPC_AKAMA_SHADE: return m_uiAkama_ShadeGUID; + case NPC_SHADE_OF_AKAMA: return m_uiShadeOfAkamaGUID; + case NPC_SUPREMUS: return m_uiSupremusGUID; + case NPC_ILLIDAN_STORMRAGE: return m_uiIllidanStormrageGUID; + case NPC_GATHIOS: return m_uiGathiosTheShattererGUID; + case NPC_ZEREVOR: return m_uiHighNethermancerZerevorGUID; + case NPC_LADY_MALANDE: return m_uiLadyMalandeGUID; + case NPC_VERAS: return m_uiVerasDarkshadowGUID; + case NPC_ILLIDARI_COUNCIL: return m_uiIllidariCouncilGUID; + case GO_NAJENTUS_GATE: return m_uiNajentusGateGUID; + case GO_ILLIDAN_GATE: return m_uiIllidanGateGUID; + case GO_ILLIDAN_DOOR_R: return m_uiIllidanDoorGUID[0]; + case GO_ILLIDAN_DOOR_L: return m_uiIllidanDoorGUID[1]; + case GO_SUPREMUS_DOORS: return m_uiMainTempleDoorsGUID; + case NPC_COUNCIL_VOICE: return m_uiBloodElfCouncilVoiceGUID; + case GO_PRE_SHAHRAZ_DOOR: return m_uiShahrazPreDoorGUID; + case GO_POST_SHAHRAZ_DOOR: return m_uiShahrazPostDoorGUID; + case GO_PRE_COUNCIL_DOOR: return m_uiPreCouncilDoorGUID; + case GO_COUNCIL_DOOR: return m_uiCouncilDoorGUID; + default: + return 0; } +} - const char* Save() +void instance_black_temple::Load(const char* chrIn) +{ + if (!chrIn) { - return strInstData.c_str(); + OUT_LOAD_INST_DATA_FAIL; + return; } - void Load(const char* chrIn) - { - if (!chrIn) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(chrIn); + 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]; + 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]; - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. - m_auiEncounter[i] = NOT_STARTED; + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. + m_auiEncounter[i] = NOT_STARTED; - OUT_LOAD_INST_DATA_COMPLETE; - } -}; + OUT_LOAD_INST_DATA_COMPLETE; +} InstanceData* GetInstanceData_instance_black_temple(Map* pMap) { @@ -324,9 +298,10 @@ InstanceData* GetInstanceData_instance_black_temple(Map* pMap) void AddSC_instance_black_temple() { - Script* newscript; - newscript = new Script; - newscript->Name = "instance_black_temple"; - newscript->GetInstanceData = &GetInstanceData_instance_black_temple; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_black_temple"; + pNewScript->GetInstanceData = &GetInstanceData_instance_black_temple; + pNewScript->RegisterSelf(); } diff --git a/scripts/outland/blades_edge_mountains.cpp b/scripts/outland/blades_edge_mountains.cpp index bad14bd43..38bff665e 100644 --- a/scripts/outland/blades_edge_mountains.cpp +++ b/scripts/outland/blades_edge_mountains.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -251,7 +251,7 @@ struct MANGOS_DLL_DECL npc_daranelleAI : public ScriptedAI DoScriptText(SAY_SPELL_INFLUENCE, m_creature, pWho); //TODO: Move the below to updateAI and run if this statement == true - ((Player*)pWho)->KilledMonsterCredit(NPC_KALIRI_AURA_DISPEL, m_creature->GetGUID()); + ((Player*)pWho)->KilledMonsterCredit(NPC_KALIRI_AURA_DISPEL, m_creature->GetObjectGuid()); pWho->RemoveAurasDueToSpell(SPELL_LASHHAN_CHANNEL); } } diff --git a/scripts/outland/boss_doomlord_kazzak.cpp b/scripts/outland/boss_doomlord_kazzak.cpp index eae350ae7..abd22e0ba 100644 --- a/scripts/outland/boss_doomlord_kazzak.cpp +++ b/scripts/outland/boss_doomlord_kazzak.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -140,11 +140,12 @@ struct MANGOS_DLL_DECL boss_doomlordkazzakAI : public ScriptedAI if (MarkOfKazzak_Timer < diff) { Unit* victim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); - if (victim->GetPower(POWER_MANA)) - { - DoCastSpellIfCan(victim, SPELL_MARKOFKAZZAK); - MarkOfKazzak_Timer = 20000; - } + if (victim) + if (victim->GetPower(POWER_MANA)) + { + DoCastSpellIfCan(victim, SPELL_MARKOFKAZZAK); + MarkOfKazzak_Timer = 20000; + } }else MarkOfKazzak_Timer -= diff; //Enrage_Timer diff --git a/scripts/outland/boss_doomwalker.cpp b/scripts/outland/boss_doomwalker.cpp index f98a4e85e..a1ba497f5 100644 --- a/scripts/outland/boss_doomwalker.cpp +++ b/scripts/outland/boss_doomwalker.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -67,7 +67,7 @@ struct MANGOS_DLL_DECL boss_doomwalkerAI : public ScriptedAI void KilledUnit(Unit* Victim) { - Victim->CastSpell(Victim,SPELL_MARK_DEATH,0); + Victim->CastSpell(Victim, SPELL_MARK_DEATH, true); if (urand(0, 4)) return; diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp index 933e9307c..44bdb9fc0 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -62,7 +62,7 @@ enum //Caribdis Spells SPELL_WATER_BOLT_VOLLEY = 38335, - SPELL_TIDAL_SURGE = 38353, // triggers 38357 + SPELL_TIDAL_SURGE = 38358, // triggers 38353 which then triggers 38357 SPELL_HEAL = 38330, SPELL_SUMMON_CYCLONE = 38337, // summons creature 22104 which uses spell 29538 @@ -87,8 +87,8 @@ struct MANGOS_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI ScriptedInstance* m_pInstance; // timers - uint32 m_uiCataclysmicBolt_Timer; - uint32 m_uiEnrage_Timer; + uint32 m_uiCataclysmicBoltTimer; + uint32 m_uiEnrageTimer; bool m_bBlessingOfTides_MobsChecked; @@ -96,8 +96,8 @@ struct MANGOS_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI void Reset() { - m_uiCataclysmicBolt_Timer = 10000; - m_uiEnrage_Timer = 600000; + m_uiCataclysmicBoltTimer = 10000; + m_uiEnrageTimer = 600000; m_bBlessingOfTides_MobsChecked = false; for(uint8 i = 0; i < MAX_ADVISORS; ++i) @@ -115,6 +115,7 @@ struct MANGOS_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI m_pInstance->SetData(TYPE_KARATHRESS_EVENT, NOT_STARTED); } + // TODO - unneeded workaround - the spell should be cast by adviser onto karathress; text can also be handled in their AI // select the spell and the text based on the advisor which died void EventAdvisorDeath(uint8 uiAdvisor) { @@ -140,7 +141,7 @@ struct MANGOS_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI break; default: error_log("SD2: invalid advisor (id %u) for karathress!", uiAdvisor); - break; + return; } DoScriptText(iSayGainAbility, m_creature); @@ -218,8 +219,8 @@ struct MANGOS_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI return; } - //m_uiCataclysmicBolt_Timer - if (m_uiCataclysmicBolt_Timer < uiDiff) + //m_uiCataclysmicBoltTimer + if (m_uiCataclysmicBoltTimer < uiDiff) { //select a random unit other than the main tank Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); @@ -228,10 +229,11 @@ struct MANGOS_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI if (!pTarget) pTarget = m_creature->getVictim(); - m_creature->CastSpell(pTarget, SPELL_CATACLYSMIC_BOLT, false); - - m_uiCataclysmicBolt_Timer = 10000; - }else m_uiCataclysmicBolt_Timer -= uiDiff; + if (DoCastSpellIfCan(pTarget, SPELL_CATACLYSMIC_BOLT) == CAST_OK) + m_uiCataclysmicBoltTimer = 10000; + } + else + m_uiCataclysmicBoltTimer -= uiDiff; //hp under 75% if (!m_bBlessingOfTides_MobsChecked && m_creature->GetHealthPercent() < 75.0f) @@ -256,12 +258,14 @@ struct MANGOS_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI m_bBlessingOfTides_MobsChecked = true; } - //m_uiEnrage_Timer - if (m_uiEnrage_Timer < uiDiff) + //m_uiEnrageTimer + if (m_uiEnrageTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_ENRAGE); - m_uiEnrage_Timer = 90000; - }else m_uiEnrage_Timer -= uiDiff; + if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) + m_uiEnrageTimer = 90000; + } + else + m_uiEnrageTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -274,11 +278,12 @@ struct MANGOS_DLL_DECL Advisor_Base_AI : public ScriptedAI { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); } + protected: - uint8 m_uiAdvisor; + uint8 m_uiAdvisor; public: - ScriptedInstance* m_pInstance; + ScriptedInstance* m_pInstance; void JustReachedHome() { @@ -321,21 +326,21 @@ struct MANGOS_DLL_DECL boss_fathomguard_sharkkisAI : public Advisor_Base_AI } // timers - uint32 m_uiHurlTrident_Timer; - uint32 m_uiLeechingThrow_Timer; - uint32 m_uiTheBeastWithin_Timer; - uint32 m_uiPet_Timer; + uint32 m_uiHurlTridentTimer; + uint32 m_uiLeechingThrowTimer; + uint32 m_uiTheBeastWithinTimer; + uint32 m_uiPetTimer; bool m_bIsPetCheckNeeded; void Reset() { - m_uiHurlTrident_Timer = 2500; - m_uiLeechingThrow_Timer = 20000; - m_uiTheBeastWithin_Timer = 30000; - m_uiPet_Timer = 10000; + m_uiHurlTridentTimer = 2500; + m_uiLeechingThrowTimer = 20000; + m_uiTheBeastWithinTimer = 30000; + m_uiPetTimer = 10000; - m_bIsPetCheckNeeded = true; + m_bIsPetCheckNeeded = true; } void AttackStart(Unit* pWho) @@ -358,7 +363,7 @@ struct MANGOS_DLL_DECL boss_fathomguard_sharkkisAI : public Advisor_Base_AI { if (pSummoned->IsPet()) { - m_uiPet_Timer = 10000; + m_uiPetTimer = 10000; m_bIsPetCheckNeeded = false; } } @@ -393,40 +398,46 @@ struct MANGOS_DLL_DECL boss_fathomguard_sharkkisAI : public Advisor_Base_AI //after 10 seconds: spawn pet if not exist if (m_bIsPetCheckNeeded) { - if (m_uiPet_Timer < uiDiff) + if (m_uiPetTimer < uiDiff) { if (!m_creature->GetPet()) DoCastSpellIfCan(m_creature, urand(0,1) ? SPELL_SUMMON_FATHOM_LURKER : SPELL_SUMMON_FATHOM_SPOREBAT); } else - m_uiPet_Timer -= uiDiff; + m_uiPetTimer -= uiDiff; } - //m_uiHurlTrident_Timer - if (m_uiHurlTrident_Timer < uiDiff) + //m_uiHurlTridentTimer + if (m_uiHurlTridentTimer < uiDiff) { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - if (!m_creature->IsWithinDist(pTarget,ATTACK_DISTANCE)) + if (!m_creature->CanReachWithMeleeAttack(pTarget)) DoCastSpellIfCan(pTarget, SPELL_HURL_TRIDENT); } - m_uiHurlTrident_Timer = 5000; - }else m_uiHurlTrident_Timer -= uiDiff; + m_uiHurlTridentTimer = 5000; + } + else + m_uiHurlTridentTimer -= uiDiff; - //m_uiLeechingThrow_Timer - if (m_uiLeechingThrow_Timer < uiDiff) + //m_uiLeechingThrowTimer + if (m_uiLeechingThrowTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_LEECHING_THROW); - m_uiLeechingThrow_Timer = 20000; - }else m_uiLeechingThrow_Timer -= uiDiff; + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_LEECHING_THROW) == CAST_OK) + m_uiLeechingThrowTimer = 20000; + } + else + m_uiLeechingThrowTimer -= uiDiff; - //m_uiTheBeastWithin_Timer - if (m_uiTheBeastWithin_Timer < uiDiff) + //m_uiTheBeastWithinTimer + if (m_uiTheBeastWithinTimer < uiDiff) { - DoCastSpellIfCan(m_creature, SPELL_THE_BEAST_WITHIN); - m_uiTheBeastWithin_Timer = 30000; - }else m_uiTheBeastWithin_Timer -= uiDiff; + if (DoCastSpellIfCan(m_creature, SPELL_THE_BEAST_WITHIN) == CAST_OK) + m_uiTheBeastWithinTimer = 30000; + } + else + m_uiTheBeastWithinTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -442,11 +453,11 @@ struct MANGOS_DLL_DECL boss_fathomguard_tidalvessAI : public Advisor_Base_AI } // timers - uint32 m_uiFrostShock_Timer; + uint32 m_uiFrostShockTimer; void Reset() { - m_uiFrostShock_Timer = 25000; + m_uiFrostShockTimer = 25000; } void UpdateAI(const uint32 uiDiff) @@ -470,12 +481,14 @@ struct MANGOS_DLL_DECL boss_fathomguard_tidalvessAI : public Advisor_Base_AI return; } - //m_uiFrostShock_Timer - if (m_uiFrostShock_Timer < uiDiff) + //m_uiFrostShockTimer + if (m_uiFrostShockTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_FROST_SHOCK); - m_uiFrostShock_Timer = urand(25000, 30000); - }else m_uiFrostShock_Timer -= uiDiff; + m_uiFrostShockTimer = urand(25000, 30000); + } + else + m_uiFrostShockTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -491,15 +504,15 @@ struct MANGOS_DLL_DECL boss_fathomguard_caribdisAI : public Advisor_Base_AI } // timers - uint32 m_uiWaterBoltVolley_Timer; - uint32 m_uiTidalSurge_Timer; - uint32 m_uiHeal_Timer; + uint32 m_uiWaterBoltVolleyTimer; + uint32 m_uiTidalSurgeTimer; + uint32 m_uiHealTimer; void Reset() { - m_uiWaterBoltVolley_Timer = 35000; - m_uiTidalSurge_Timer = urand(15000, 20000); - m_uiHeal_Timer = 55000; + m_uiWaterBoltVolleyTimer = 35000; + m_uiTidalSurgeTimer = urand(15000, 20000); + m_uiHealTimer = 55000; } void UpdateAI(const uint32 uiDiff) @@ -523,23 +536,26 @@ struct MANGOS_DLL_DECL boss_fathomguard_caribdisAI : public Advisor_Base_AI return; } - //m_uiWaterBoltVolley_Timer - if (m_uiWaterBoltVolley_Timer < uiDiff) + //m_uiWaterBoltVolleyTimer + if (m_uiWaterBoltVolleyTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_WATER_BOLT_VOLLEY); - m_uiWaterBoltVolley_Timer = 30000; - }else m_uiWaterBoltVolley_Timer -= uiDiff; + if (DoCastSpellIfCan(m_creature, SPELL_WATER_BOLT_VOLLEY) == CAST_OK) + m_uiWaterBoltVolleyTimer = 30000; + } + else + m_uiWaterBoltVolleyTimer -= uiDiff; - //m_uiTidalSurge_Timer - if (m_uiTidalSurge_Timer < uiDiff) + //m_uiTidalSurgeTimer + if (m_uiTidalSurgeTimer < uiDiff) { - // the victim has to cast it on himself because in the spell.dbc the EffectImplicitTargetA1 is 1 (TARGET_SELF) - m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_TIDAL_SURGE, true); - m_uiTidalSurge_Timer = urand(15000, 20000); - }else m_uiTidalSurge_Timer -= uiDiff; + if (DoCastSpellIfCan(m_creature, SPELL_TIDAL_SURGE) == CAST_OK) + m_uiTidalSurgeTimer = urand(15000, 20000); + } + else + m_uiTidalSurgeTimer -= uiDiff; - //m_uiHeal_Timer - if (m_uiHeal_Timer < uiDiff) + //m_uiHealTimer + if (m_uiHealTimer < uiDiff) { // It can be cast on any of the mobs Unit* pUnit = NULL; @@ -554,14 +570,18 @@ struct MANGOS_DLL_DECL boss_fathomguard_caribdisAI : public Advisor_Base_AI case 3: pUnit = m_creature; break; } } - else - pUnit = m_creature; - if (pUnit && pUnit->isAlive()) - DoCastSpellIfCan(pUnit, SPELL_HEAL); + if (!pUnit) + pUnit = m_creature; - m_uiHeal_Timer = 60000; - }else m_uiHeal_Timer -= uiDiff; + if (pUnit->isAlive()) + { + if (DoCastSpellIfCan(pUnit, SPELL_HEAL) == CAST_OK) + m_uiHealTimer = 60000; + } + } + else + m_uiHealTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -589,24 +609,25 @@ CreatureAI* GetAI_boss_fathomguard_caribdis(Creature* pCreature) void AddSC_boss_fathomlord_karathress() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_fathomlord_karathress"; - newscript->GetAI = &GetAI_boss_fathomlord_karathress; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_fathomguard_sharkkis"; - newscript->GetAI = &GetAI_boss_fathomguard_sharkkis; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_fathomguard_tidalvess"; - newscript->GetAI = &GetAI_boss_fathomguard_tidalvess; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_fathomguard_caribdis"; - newscript->GetAI = &GetAI_boss_fathomguard_caribdis; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_fathomlord_karathress"; + pNewScript->GetAI = &GetAI_boss_fathomlord_karathress; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "boss_fathomguard_sharkkis"; + pNewScript->GetAI = &GetAI_boss_fathomguard_sharkkis; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "boss_fathomguard_tidalvess"; + pNewScript->GetAI = &GetAI_boss_fathomguard_tidalvess; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "boss_fathomguard_caribdis"; + pNewScript->GetAI = &GetAI_boss_fathomguard_caribdis; + pNewScript->RegisterSelf(); } diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_hydross_the_unstable.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_hydross_the_unstable.cpp index 87be6e175..07631c2b5 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_hydross_the_unstable.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_hydross_the_unstable.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp index f528de791..5b82dd4be 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -378,7 +378,7 @@ struct MANGOS_DLL_DECL boss_lady_vashjAI : public ScriptedAI Unit* pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); //if in melee range - if (pTarget && pTarget->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) + if (pTarget && m_creature->CanReachWithMeleeAttack(pTarget)) { bInMeleeRange = true; break; @@ -509,7 +509,7 @@ struct MANGOS_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI { if (Creature* pVashj = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_LADYVASHJ))) { - if (pVashj->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) + if (pVashj->IsWithinDistInMap(m_creature, INTERACTION_DISTANCE)) { //increase lady vashj damage if (pVashj->isAlive() && pVashj->isInCombat()) diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_leotheras_the_blind.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_leotheras_the_blind.cpp index 426a34155..75da7509a 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_leotheras_the_blind.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_leotheras_the_blind.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp index 6a46a7687..8d47d3eea 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -277,7 +277,7 @@ struct MANGOS_DLL_DECL mob_water_globuleAI : public ScriptedAI if (m_uiCheck_Timer < uiDiff) { - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { m_creature->DealDamage(m_creature->getVictim(), 4000+rand()%2000, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FROST, NULL, false); diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp index 24a05a16a..e166a92d9 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -31,6 +31,7 @@ enum SPELL_GEYSER = 37478, SPELL_SPOUT = 37433, // TODO should sweep the room 360degrees, related spells 37429 37430 37431 SPELL_WATERBOLT = 37138, // TODO is used when no enemy in melee range (unknown if on random or top-most aggro holder in this case + ACHIEVEMENT_LURKER = 144, }; enum Phases @@ -42,6 +43,7 @@ enum Phases }; // TODO This boss should infact be a Scripted_NoMovementAI, but selecting only melee targets is not supported yet, change when implemented + struct MANGOS_DLL_DECL boss_the_lurker_belowAI : public ScriptedAI { boss_the_lurker_belowAI(Creature* pCreature) : ScriptedAI(pCreature) @@ -118,7 +120,7 @@ CreatureAI* GetAI_boss_the_lurker_below(Creature* pCreature) } // Cast the spell that should summon the Lurker-Below -bool GOHello_go_strange_pool(Player* pPlayer, GameObject* pGo) +bool GOUse_go_strange_pool(Player* pPlayer, GameObject* pGo) { // There is some chance to fish The Lurker Below, sources are from 20s to 10minutes, average 5min => 20 tries, hence 5% if (urand(0,99) < 5) @@ -128,6 +130,7 @@ bool GOHello_go_strange_pool(Player* pPlayer, GameObject* pGo) if (pInstance->GetData(TYPE_THELURKER_EVENT) == NOT_STARTED) { pPlayer->CastSpell(pPlayer, SPELL_LURKER_SPAWN_TRIGGER, true); + pPlayer->CompletedAchievement(ACHIEVEMENT_LURKER); pInstance->SetData(TYPE_THELURKER_EVENT, IN_PROGRESS); return true; } @@ -147,6 +150,6 @@ void AddSC_boss_the_lurker_below() pNewScript = new Script; pNewScript->Name = "go_strange_pool"; - pNewScript->pGOHello = &GOHello_go_strange_pool; + pNewScript->pGOUse = &GOUse_go_strange_pool; pNewScript->RegisterSelf(); } diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/instance_serpent_shrine.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/instance_serpent_shrine.cpp index 73c21d218..3e999f336 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/instance_serpent_shrine.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/instance_serpent_shrine.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/serpent_shrine.h b/scripts/outland/coilfang_reservoir/serpent_shrine/serpent_shrine.h index 6d2b9f48e..b7bde5fa3 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/serpent_shrine.h +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/serpent_shrine.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/coilfang_reservoir/slave_pens/boss_ahune.cpp b/scripts/outland/coilfang_reservoir/slave_pens/boss_ahune.cpp new file mode 100644 index 000000000..a69e79396 --- /dev/null +++ b/scripts/outland/coilfang_reservoir/slave_pens/boss_ahune.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2011 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 + */ + +/* ScriptData +SDName: boss_ahune +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Slave Pens +EndScriptData */ + +#include "precompiled.h" + +void AddSC_boss_ahune() +{ +} diff --git a/scripts/outland/coilfang_reservoir/steam_vault/boss_hydromancer_thespia.cpp b/scripts/outland/coilfang_reservoir/steam_vault/boss_hydromancer_thespia.cpp index 829e674eb..96f086f42 100644 --- a/scripts/outland/coilfang_reservoir/steam_vault/boss_hydromancer_thespia.cpp +++ b/scripts/outland/coilfang_reservoir/steam_vault/boss_hydromancer_thespia.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/coilfang_reservoir/steam_vault/boss_mekgineer_steamrigger.cpp b/scripts/outland/coilfang_reservoir/steam_vault/boss_mekgineer_steamrigger.cpp index 138052a31..efc6e6789 100644 --- a/scripts/outland/coilfang_reservoir/steam_vault/boss_mekgineer_steamrigger.cpp +++ b/scripts/outland/coilfang_reservoir/steam_vault/boss_mekgineer_steamrigger.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/coilfang_reservoir/steam_vault/boss_warlord_kalithresh.cpp b/scripts/outland/coilfang_reservoir/steam_vault/boss_warlord_kalithresh.cpp index fad04fa8a..6e1ffe336 100644 --- a/scripts/outland/coilfang_reservoir/steam_vault/boss_warlord_kalithresh.cpp +++ b/scripts/outland/coilfang_reservoir/steam_vault/boss_warlord_kalithresh.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/coilfang_reservoir/steam_vault/instance_steam_vault.cpp b/scripts/outland/coilfang_reservoir/steam_vault/instance_steam_vault.cpp index db2492543..b43b484b7 100644 --- a/scripts/outland/coilfang_reservoir/steam_vault/instance_steam_vault.cpp +++ b/scripts/outland/coilfang_reservoir/steam_vault/instance_steam_vault.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -36,7 +36,7 @@ EndScriptData */ 3 - Warlord Kalithresh Event */ -bool GOHello_go_main_chambers_access_panel(Player* pPlayer, GameObject* pGo) +bool GOUse_go_main_chambers_access_panel(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -194,7 +194,7 @@ void AddSC_instance_steam_vault() newscript = new Script; newscript->Name = "go_main_chambers_access_panel"; - newscript->pGOHello = &GOHello_go_main_chambers_access_panel; + newscript->pGOUse = &GOUse_go_main_chambers_access_panel; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/outland/coilfang_reservoir/steam_vault/steam_vault.h b/scripts/outland/coilfang_reservoir/steam_vault/steam_vault.h index fea0b997e..12deaa010 100644 --- a/scripts/outland/coilfang_reservoir/steam_vault/steam_vault.h +++ b/scripts/outland/coilfang_reservoir/steam_vault/steam_vault.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/coilfang_reservoir/underbog/boss_hungarfen.cpp b/scripts/outland/coilfang_reservoir/underbog/boss_hungarfen.cpp index b4c747685..38d1d4367 100644 --- a/scripts/outland/coilfang_reservoir/underbog/boss_hungarfen.cpp +++ b/scripts/outland/coilfang_reservoir/underbog/boss_hungarfen.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/gruuls_lair/boss_gruul.cpp b/scripts/outland/gruuls_lair/boss_gruul.cpp index 75181490b..3242fc264 100644 --- a/scripts/outland/gruuls_lair/boss_gruul.cpp +++ b/scripts/outland/gruuls_lair/boss_gruul.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -197,7 +197,7 @@ struct MANGOS_DLL_DECL boss_gruulAI : public ScriptedAI if (m_uiHurtfulStrike_Timer < uiDiff) { // Find 2nd-aggro target within melee range. - Unit *pTarget = NULL; + Unit* pTarget = NULL; ThreatList const& tList = m_creature->getThreatManager().getThreatList(); ThreatList::const_iterator itr = tList.begin(); std::advance(itr, 1); @@ -206,7 +206,7 @@ struct MANGOS_DLL_DECL boss_gruulAI : public ScriptedAI pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); // exclude pets, totems & player out of melee range - if (pTarget->GetTypeId() != TYPEID_PLAYER || !pTarget->IsWithinDist(m_creature, ATTACK_DISTANCE, false)) + if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER || !m_creature->CanReachWithMeleeAttack(pTarget)) { pTarget = NULL; continue; diff --git a/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp b/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp index 1ecdeeed2..4c10bf661 100644 --- a/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp +++ b/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -580,10 +580,11 @@ struct MANGOS_DLL_DECL boss_krosh_firehandAI : public Council_Base_AI //BlastWave_Timer if (m_uiBlastWave_Timer < uiDiff) { - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin(); i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin(); i != vGuids.end(); ++i) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit && pUnit->IsWithinDistInMap(m_creature, 15.0f)) { diff --git a/scripts/outland/gruuls_lair/gruuls_lair.h b/scripts/outland/gruuls_lair/gruuls_lair.h index 34cdf2675..eeb02d5f7 100644 --- a/scripts/outland/gruuls_lair/gruuls_lair.h +++ b/scripts/outland/gruuls_lair/gruuls_lair.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -13,6 +13,9 @@ enum TYPE_MAULGAR_EVENT = 1, TYPE_GRUUL_EVENT = 2, + GO_PORT_GRONN_1 = 183817, // 184468 not in use + GO_PORT_GRONN_2 = 184662, + // NPC GUIDs DATA_MAULGAR = 3, DATA_BLINDEYE = 4, diff --git a/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp b/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp index 449a186de..ddc614e1c 100644 --- a/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp +++ b/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -83,12 +83,12 @@ struct MANGOS_DLL_DECL instance_gruuls_lair : public ScriptedInstance { switch (pGo->GetEntry()) { - case 184468: + case GO_PORT_GRONN_1: m_uiMaulgarDoorGUID = pGo->GetGUID(); if (m_auiEncounter[0] == DONE) pGo->SetGoState(GO_STATE_ACTIVE); break; - case 184662: + case GO_PORT_GRONN_2: m_uiGruulEncounterDoorGUID = pGo->GetGUID(); break; } diff --git a/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h b/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h index 2041214b5..2a4122119 100644 --- a/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h +++ b/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp b/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp index fc9bb71e7..4e5d4ec97 100644 --- a/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp +++ b/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp b/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp index 5c7216d29..c76bc3103 100644 --- a/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp +++ b/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp b/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp index 6b13dcac2..0ca5742cc 100644 --- a/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp +++ b/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp b/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp index 70f36a38d..06d7f6fb2 100644 --- a/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp +++ b/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_nazan_and_vazruden.cpp b/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_nazan_and_vazruden.cpp index 52d682c48..79bef1908 100644 --- a/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_nazan_and_vazruden.cpp +++ b/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_nazan_and_vazruden.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -40,8 +40,8 @@ enum SPELL_REVENGE = 40392, //nazan - SPELL_FIREBALL = 30691, - SPELL_H_FIREBALL = 36920, + SPELL_FIREBALL = 30691, // TODO: IDs not verified + SPELL_FIREBALL_H = 36920, SPELL_CONE_OF_FIRE = 30926, SPELL_H_CONE_OF_FIRE = 36921, @@ -50,7 +50,7 @@ enum //misc POINT_ID_CENTER = 100, - POINT_ID_WAITING = 101, + POINT_ID_FLYING = 101, POINT_ID_COMBAT = 102, NPC_VAZRUDEN_HERALD = 17307, @@ -58,7 +58,7 @@ enum NPC_VAZRUDEN = 17537 }; -const float afCenterPos[3] = {-1399.401f, 1736.365f, 86.008f}; //moves here to drop off nazan +const float afCenterPos[3] = {-1399.401f, 1736.365f, 87.008f}; //moves here to drop off nazan const float afCombatPos[3] = {-1413.848f, 1754.019f, 83.146f}; //moves here when decending struct MANGOS_DLL_DECL boss_vazrudenAI : public ScriptedAI @@ -154,7 +154,12 @@ struct MANGOS_DLL_DECL boss_vazruden_heraldAI : public ScriptedAI ScriptedInstance* m_pInstance; bool m_bIsRegularMode; + bool m_bIsEventInProgress; uint32 m_uiMovementTimer; + uint32 m_uiFireballTimer; + + uint64 m_uiLastSeenPlayerGUID; + uint64 m_uiVazrudenGUID; void Reset() { @@ -164,10 +169,25 @@ struct MANGOS_DLL_DECL boss_vazruden_heraldAI : public ScriptedAI m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_uiMovementTimer = 0; + m_bIsEventInProgress = false; + m_uiLastSeenPlayerGUID = 0; + m_uiVazrudenGUID = 0; + m_uiFireballTimer = 0; + + // see boss_onyxia + // sort of a hack, it is unclear how this really work but the values appear to be valid + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); } void MoveInLineOfSight(Unit* pWho) { + if (m_bIsEventInProgress && !m_uiLastSeenPlayerGUID && pWho->GetTypeId() == TYPEID_PLAYER && pWho->isAlive() && !((Player*)pWho)->isGameMaster()) + { + if (m_creature->IsWithinDistInMap(pWho, 40.0f)) + m_uiLastSeenPlayerGUID = pWho->GetGUID(); + } + if (m_pInstance && m_pInstance->GetData(TYPE_NAZAN) != IN_PROGRESS) return; @@ -181,24 +201,43 @@ struct MANGOS_DLL_DECL boss_vazruden_heraldAI : public ScriptedAI if (uiType == WAYPOINT_MOTION_TYPE) { - if (m_uiMovementTimer) + if (m_uiMovementTimer || m_bIsEventInProgress) return; if (m_pInstance->GetData(TYPE_NAZAN) == SPECIAL) { m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); m_uiMovementTimer = 1000; + m_bIsEventInProgress = true; } } if (uiType == POINT_MOTION_TYPE) { - if (uiPointId == POINT_ID_CENTER) - DoSplit(); - else if (uiPointId == POINT_ID_COMBAT) + switch (uiPointId) { - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - m_pInstance->SetData(TYPE_NAZAN, IN_PROGRESS); + case POINT_ID_CENTER: + DoSplit(); + break; + case POINT_ID_COMBAT: + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_pInstance->SetData(TYPE_NAZAN, IN_PROGRESS); + + // Landing + // undo flying + m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); + m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING); + + Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiLastSeenPlayerGUID); + if (pPlayer && pPlayer->isAlive()) + AttackStart(pPlayer); + + break; + } + case POINT_ID_FLYING: + m_uiFireballTimer = 3000; + break; } } } @@ -206,22 +245,19 @@ struct MANGOS_DLL_DECL boss_vazruden_heraldAI : public ScriptedAI void DoMoveToCenter() { DoScriptText(SAY_INTRO, m_creature); - - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - { - m_creature->GetMotionMaster()->MovementExpired(); - m_creature->GetMotionMaster()->MoveIdle(); - } - m_creature->GetMotionMaster()->MovePoint(POINT_ID_CENTER, afCenterPos[0], afCenterPos[1], afCenterPos[2]); } - void DoMoveToHold() + void DoMoveToAir() { float fX, fY, fZ; m_creature->GetCombatStartPosition(fX, fY, fZ); - m_creature->GetMotionMaster()->MovePoint(POINT_ID_WAITING, fX, fY, fZ); + // Remove Idle MMGen + if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE) + m_creature->GetMotionMaster()->MovementExpired(false); + + m_creature->GetMotionMaster()->MovePoint(POINT_ID_FLYING, fX, fY, fZ); } void DoSplit() @@ -231,10 +267,21 @@ struct MANGOS_DLL_DECL boss_vazruden_heraldAI : public ScriptedAI m_creature->SummonCreature(NPC_VAZRUDEN, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0); m_uiMovementTimer = 3000; + + // Let him idle for now + m_creature->GetMotionMaster()->MoveIdle(); } void JustSummoned(Creature* pSummoned) { + if (pSummoned->GetEntry() != NPC_VAZRUDEN) + return; + + if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiLastSeenPlayerGUID)) + pSummoned->AI()->AttackStart(pPlayer); + + m_uiVazrudenGUID = pSummoned->GetGUID(); + if (m_pInstance) m_pInstance->SetData(TYPE_VAZRUDEN, IN_PROGRESS); } @@ -247,23 +294,42 @@ struct MANGOS_DLL_DECL boss_vazruden_heraldAI : public ScriptedAI void UpdateAI(const uint32 uiDiff) { - if (!m_creature->getVictim() && m_uiMovementTimer) + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { - if (m_uiMovementTimer <= uiDiff) + if (m_uiMovementTimer) { - if (m_pInstance) + if (m_uiMovementTimer <= uiDiff) { - if (m_pInstance->GetData(TYPE_VAZRUDEN) == IN_PROGRESS) - DoMoveToHold(); - else - DoMoveToCenter(); + if (m_pInstance) + { + if (m_pInstance->GetData(TYPE_VAZRUDEN) == IN_PROGRESS) + DoMoveToAir(); + else + DoMoveToCenter(); + } + m_uiMovementTimer = 0; } - m_uiMovementTimer = 0; - } else m_uiMovementTimer -= uiDiff; - } + else + m_uiMovementTimer -= uiDiff; + } + + if (m_uiVazrudenGUID && m_uiFireballTimer) + { + if (m_uiFireballTimer <= uiDiff) + { + if (Creature* pVazruden = m_creature->GetMap()->GetCreature(m_uiVazrudenGUID)) + { + if (Unit* pEnemy = pVazruden->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCastSpellIfCan(pEnemy, m_bIsRegularMode ? SPELL_FIREBALL : SPELL_FIREBALL_H, 0, pVazruden->GetGUID()); + } + m_uiFireballTimer = urand(4000, 8000); + } + else + m_uiFireballTimer -= uiDiff; + } - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + } DoMeleeAttackIfReady(); } diff --git a/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp b/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp index 299bec47c..6c1e5f988 100644 --- a/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp +++ b/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -147,7 +147,7 @@ struct MANGOS_DLL_DECL boss_omor_the_unscarredAI : public ScriptedAI else if (OrbitalStrike_Timer < diff) { Unit* temp = NULL; - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) temp = m_creature->getVictim(); else temp = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); diff --git a/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp b/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp index f38953d7d..a9170ec29 100644 --- a/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp +++ b/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h b/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h index 5c5638f95..af236f020 100644 --- a/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h +++ b/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp b/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp index 579182439..95962a883 100644 --- a/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp +++ b/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp b/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp index 2fb590c6b..28d4ef095 100644 --- a/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp +++ b/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -331,7 +331,6 @@ struct MANGOS_DLL_DECL boss_magtheridonAI : public ScriptedAI void Aggro(Unit* pWho) { - m_creature->SetInCombatWithZone(); DoScriptText(SAY_AGGRO, m_creature); } @@ -548,8 +547,6 @@ struct MANGOS_DLL_DECL mob_hellfire_channelerAI : public ScriptedAI } m_pInstance->SetData(TYPE_CHANNELER_EVENT, IN_PROGRESS); - - m_creature->SetInCombatWithZone(); } void JustSummoned(Creature* pSummoned) @@ -639,7 +636,7 @@ struct MANGOS_DLL_DECL mob_hellfire_channelerAI : public ScriptedAI }; //Manticron Cube -bool GOHello_go_manticron_cube(Player* pPlayer, GameObject* pGo) +bool GOUse_go_manticron_cube(Player* pPlayer, GameObject* pGo) { if (ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData()) { @@ -697,7 +694,7 @@ void AddSC_boss_magtheridon() newscript = new Script; newscript->Name = "go_manticron_cube"; - newscript->pGOHello = &GOHello_go_manticron_cube; + newscript->pGOUse = &GOUse_go_manticron_cube; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp b/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp index c52acfacf..d6b46c013 100644 --- a/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp +++ b/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h b/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h index 51bd7289d..385e1f8c6 100644 --- a/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h +++ b/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp b/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp index 0114c6cbb..d25edca25 100644 --- a/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp +++ b/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -74,7 +74,9 @@ enum SPELL_HEMORRHAGE = 30478, SPELL_CONSUMPTION = 30497, - SPELL_TEMPORARY_VISUAL = 39312 // this is wrong, a temporary solution. spell consumption already has the purple visual, but doesn't display as it should + SPELL_TEMPORARY_VISUAL = 39312, // this is wrong, a temporary solution. spell consumption already has the purple visual, but doesn't display as it should + + NPC_FEL_ORC_CONVERT = 17083, }; struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI @@ -83,6 +85,7 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty(); + m_bIntroOnce = false; Reset(); } @@ -104,12 +107,13 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI uint32 m_uiShadowFissureTimer; uint32 m_uiCleaveTimer; + uint64 m_uiLastEventInvokerGUID; + void Reset() { m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_bIsIntroEvent = false; - m_bIntroOnce = false; m_bIsMainEvent = false; //m_bHasTaunted = false; m_bSpinOnce = false; @@ -122,18 +126,23 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI m_uiDeathCoilTimer = 20000; m_uiShadowFissureTimer = 8000; m_uiCleaveTimer = 5000; + + m_uiLastEventInvokerGUID = 0; } - void DoYellForPeonAggro() + void DoYellForPeonAggro(Unit* pWho) { if (m_uiPeonEngagedCount >= 4) return; DoScriptText(PeonAttacked[m_uiPeonEngagedCount].id, m_creature); ++m_uiPeonEngagedCount; + + if (pWho) + m_uiLastEventInvokerGUID = pWho->GetGUID(); } - void DoYellForPeonDeath() + void DoYellForPeonDeath(Unit* pKiller) { if (m_uiPeonKilledCount >= 4) return; @@ -146,6 +155,10 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI m_bIsIntroEvent = false; m_bIsMainEvent = true; m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if (pKiller) + AttackStart(pKiller); + } } @@ -158,12 +171,19 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI case 2: DoScriptText(SAY_TAUNT_3, m_creature); break; } - // TODO: kill the peons first + std::list lFelConverts; + GetCreatureListWithEntryInGrid(lFelConverts, m_creature, NPC_FEL_ORC_CONVERT, 40.0f); + for (std::list::iterator itr = lFelConverts.begin(); itr != lFelConverts.end(); ++itr) + (*itr)->DealDamage(*itr, (*itr)->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_bIsIntroEvent = false; m_uiPeonEngagedCount = 4; m_uiPeonKilledCount = 4; m_bIsMainEvent = true; m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if (Unit* pEnemy = m_creature->GetMap()->GetUnit(m_uiLastEventInvokerGUID)) + AttackStart(pEnemy); } void AttackStart(Unit* pWho) @@ -195,6 +215,8 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI m_bIntroOnce = true; m_bIsIntroEvent = true; + m_uiLastEventInvokerGUID = pWho->GetGUID(); + if (m_pInstance) m_pInstance->SetData(TYPE_NETHEKURSE, IN_PROGRESS); } @@ -241,6 +263,20 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI m_pInstance->SetData(TYPE_NETHEKURSE, DONE); } + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->SetData(TYPE_NETHEKURSE, FAIL); + + std::list lFelConverts; + GetCreatureListWithEntryInGrid(lFelConverts, m_creature, NPC_FEL_ORC_CONVERT, 40.0f); + for (std::list::iterator itr = lFelConverts.begin(); itr != lFelConverts.end(); ++itr) + { + if (!(*itr)->isAlive()) + (*itr)->Respawn(); + } + } + void UpdateAI(const uint32 uiDiff) { if (m_bIsIntroEvent) @@ -337,7 +373,7 @@ struct MANGOS_DLL_DECL mob_fel_orc_convertAI : public ScriptedAI if (pKurse && m_creature->IsWithinDist(pKurse, 45.0f)) { if (boss_grand_warlock_nethekurseAI* pKurseAI = dynamic_cast(pKurse->AI())) - pKurseAI->DoYellForPeonAggro(); + pKurseAI->DoYellForPeonAggro(pWho); if (m_pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) return; @@ -357,7 +393,7 @@ struct MANGOS_DLL_DECL mob_fel_orc_convertAI : public ScriptedAI if (Creature* pKurse = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_NETHEKURSE))) { if (boss_grand_warlock_nethekurseAI* pKurseAI = dynamic_cast(pKurse->AI())) - pKurseAI->DoYellForPeonAggro(); + pKurseAI->DoYellForPeonDeath(pKiller); } } } diff --git a/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp b/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp index 7182fb159..1804cfe2e 100644 --- a/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp +++ b/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp b/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp index 1b202abd4..03e870173 100644 --- a/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp +++ b/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp b/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp index ed3bd7bda..9e1991b70 100644 --- a/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp +++ b/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -24,81 +24,112 @@ EndScriptData */ #include "precompiled.h" #include "shattered_halls.h" -struct MANGOS_DLL_DECL instance_shattered_halls : public ScriptedInstance +instance_shattered_halls::instance_shattered_halls(Map* pMap) : ScriptedInstance(pMap), + m_uiNethekurseGUID(0), + m_uiNethekurseDoorGUID(0), + m_uiNethekurseEnterDoorGUID(0) { - instance_shattered_halls(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + Initialize(); +} - uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint64 m_uiNethekurseGUID; - uint64 m_uiNethekurseDoorGUID; +void instance_shattered_halls::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} - void Initialize() +void instance_shattered_halls::OnObjectCreate(GameObject* pGo) +{ + switch (pGo->GetEntry()) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiNethekurseGUID = 0; - m_uiNethekurseDoorGUID = 0; + case GO_NETHEKURSE_DOOR: + m_uiNethekurseDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_NETHEKURSE] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; + case GO_NETHERKURSE_ENTER_DOOR: + m_uiNethekurseEnterDoorGUID = pGo->GetGUID(); + if (m_auiEncounter[TYPE_NETHEKURSE] == DONE) + pGo->SetGoState(GO_STATE_ACTIVE); + break; } +} - bool IsEncounterInProgress() const - { - for(uint8 i = 0; i < MAX_ENCOUNTER; i++) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; - return false; - } +void instance_shattered_halls::OnCreatureCreate(Creature* pCreature) +{ + if (pCreature->GetEntry() == NPC_NETHEKURSE) + m_uiNethekurseGUID = pCreature->GetGUID(); +} - void OnObjectCreate(GameObject* pGo) +void instance_shattered_halls::SetData(uint32 uiType, uint32 uiData) +{ + switch(uiType) { - if (pGo->GetEntry() == GO_NETHEKURSE_DOOR) - m_uiNethekurseDoorGUID = pGo->GetGUID(); + case TYPE_NETHEKURSE: + m_auiEncounter[uiType] = uiData; + if (uiData == DONE) + DoUseDoorOrButton(m_uiNethekurseDoorGUID); + break; + case TYPE_OMROGG: + m_auiEncounter[uiType] = uiData; + break; + case TYPE_BLADEFIST: + m_auiEncounter[uiType] = uiData; + break; } - void OnCreatureCreate(Creature* pCreature) + if (uiData == DONE) { - if (pCreature->GetEntry() == NPC_NETHEKURSE) - m_uiNethekurseGUID = pCreature->GetGUID(); - } + OUT_SAVE_INST_DATA; - void SetData(uint32 uiType, uint32 uiData) - { - switch(uiType) - { - case TYPE_NETHEKURSE: - m_auiEncounter[0] = uiData; - if (uiData == DONE) - DoUseDoorOrButton(m_uiNethekurseDoorGUID); - break; - case TYPE_OMROGG: - m_auiEncounter[1] = uiData; - break; - } + std::ostringstream saveStream; + + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2]; + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; } +} - uint32 GetData(uint32 uiType) +void instance_shattered_halls::Load(const char* chrIn) +{ + if (!chrIn) { - switch(uiType) - { - case TYPE_NETHEKURSE: - return m_auiEncounter[0]; - case TYPE_OMROGG: - return m_auiEncounter[1]; - } - return 0; + OUT_LOAD_INST_DATA_FAIL; + return; } - uint64 GetData64(uint32 uiData) + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; + + 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_shattered_halls::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + + return 0; +} + +uint64 instance_shattered_halls::GetData64(uint32 uiData) +{ + switch(uiData) { - switch(uiData) - { - case NPC_NETHEKURSE: - return m_uiNethekurseGUID; - case GO_NETHEKURSE_DOOR: - return m_uiNethekurseDoorGUID; - } - return 0; + case NPC_NETHEKURSE: return m_uiNethekurseGUID; + case GO_NETHEKURSE_DOOR: return m_uiNethekurseDoorGUID; + case GO_NETHERKURSE_ENTER_DOOR: return m_uiNethekurseEnterDoorGUID; + default: + return 0; } -}; +} InstanceData* GetInstanceData_instance_shattered_halls(Map* pMap) { diff --git a/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h b/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h index 7dba5b848..826f3f233 100644 --- a/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h +++ b/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -7,12 +7,43 @@ enum { - MAX_ENCOUNTER = 2, + MAX_ENCOUNTER = 3, - TYPE_NETHEKURSE = 0, - TYPE_OMROGG = 1, + TYPE_NETHEKURSE = 0, + TYPE_OMROGG = 1, + TYPE_BLADEFIST = 2, // TODO Currently unhandled - GO_NETHEKURSE_DOOR = 182540, - NPC_NETHEKURSE = 16807 + NPC_NETHEKURSE = 16807, + + GO_NETHEKURSE_DOOR = 182540, + GO_NETHERKURSE_ENTER_DOOR = 182539, // TODO Currently unhandled +}; + +class MANGOS_DLL_DECL instance_shattered_halls : public ScriptedInstance +{ + public: + instance_shattered_halls(Map* pMap); + + void Initialize(); + + void OnObjectCreate(GameObject* pGo); + void OnCreatureCreate(Creature* pCreature); + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + uint64 GetData64(uint32 uiData); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + private: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; + + uint64 m_uiNethekurseGUID; + + uint64 m_uiNethekurseDoorGUID; + uint64 m_uiNethekurseEnterDoorGUID; }; + #endif diff --git a/scripts/outland/hellfire_peninsula.cpp b/scripts/outland/hellfire_peninsula.cpp index e9fcf978f..e13cbdfff 100644 --- a/scripts/outland/hellfire_peninsula.cpp +++ b/scripts/outland/hellfire_peninsula.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -123,7 +123,7 @@ CreatureAI* GetAI_npc_aeranas(Creature* pCreature) ## go_haaleshi_altar ######*/ -bool GOHello_go_haaleshi_altar(Player* pPlayer, GameObject* pGo) +bool GOUse_go_haaleshi_altar(Player* pPlayer, GameObject* pGo) { pGo->SummonCreature(C_AERANAS, -1321.79f, 4043.80f, 116.24f, 1.25f, TEMPSUMMON_TIMED_DESPAWN, 180000); return false; @@ -754,7 +754,7 @@ void AddSC_hellfire_peninsula() newscript = new Script; newscript->Name = "go_haaleshi_altar"; - newscript->pGOHello = &GOHello_go_haaleshi_altar; + newscript->pGOUse = &GOUse_go_haaleshi_altar; newscript->RegisterSelf(); newscript = new Script; @@ -808,6 +808,6 @@ void AddSC_hellfire_peninsula() newscript = new Script; newscript->Name = "npc_wounded_blood_elf"; newscript->GetAI = &GetAI_npc_wounded_blood_elf; - newscript->pQuestAccept = &QuestAccept_npc_wounded_blood_elf; + newscript->pQuestAcceptNPC = &QuestAccept_npc_wounded_blood_elf; newscript->RegisterSelf(); } diff --git a/scripts/outland/nagrand.cpp b/scripts/outland/nagrand.cpp index e7e6dd87e..853e8f19b 100644 --- a/scripts/outland/nagrand.cpp +++ b/scripts/outland/nagrand.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,14 +17,12 @@ /* ScriptData SDName: Nagrand SD%Complete: 90 -SDComment: Quest support: 9849, 9868, 9874, 9918, 9991, 10044, 10085, 10107, 10108, 10172, 10646. TextId's unknown for altruis_the_sufferer and greatmother_geyah (npc_text) +SDComment: Quest support: 9868, 9918, 9991, 10044, 10085, 10107, 10108, 10172, 10646. TextId's unknown for altruis_the_sufferer and greatmother_geyah (npc_text) SDCategory: Nagrand EndScriptData */ /* ContentData -mob_shattered_rumbler mob_lump -mob_sunspring_villager npc_altruis_the_sufferer npc_greatmother_geyah npc_lantresor_of_the_blade @@ -35,43 +33,6 @@ EndContentData */ #include "precompiled.h" #include "escort_ai.h" -/*###### -## mob_shattered_rumbler - this should be done with ACID -######*/ - -struct MANGOS_DLL_DECL mob_shattered_rumblerAI : public ScriptedAI -{ - bool Spawn; - - mob_shattered_rumblerAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - void Reset() - { - Spawn = false; - } - - void SpellHit(Unit *Hitter, const SpellEntry *Spellkind) - { - if (Spellkind->Id == 32001 && !Spawn) - { - float x = m_creature->GetPositionX(); - float y = m_creature->GetPositionY(); - float z = m_creature->GetPositionZ(); - - Hitter->SummonCreature(18181,x+(0.7 * (rand()%30)),y+(rand()%5),z,0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,60000); - Hitter->SummonCreature(18181,x+(rand()%5),y-(rand()%5),z,0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,60000); - Hitter->SummonCreature(18181,x-(rand()%5),y+(0.5 *(rand()%60)),z,0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,60000); - m_creature->SetDeathState(CORPSE); - Spawn = true; - } - return; - } -}; -CreatureAI* GetAI_mob_shattered_rumbler(Creature* pCreature) -{ - return new mob_shattered_rumblerAI(pCreature); -} - /*###### ## mob_lump - TODO: remove gossip, can be done in database ######*/ @@ -234,34 +195,6 @@ bool GossipSelect_mob_lump(Player* pPlayer, Creature* pCreature, uint32 uiSender return true; } -/*#### -# mob_sunspring_villager - should be done with ACID -####*/ - -struct MANGOS_DLL_DECL mob_sunspring_villagerAI : public ScriptedAI -{ - mob_sunspring_villagerAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} - - void Reset() - { - m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); - m_creature->SetStandState(UNIT_STAND_STATE_DEAD); - } - - void SpellHit(Unit *caster, const SpellEntry *spell) - { - if (spell->Id == 32146) - { - m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - m_creature->RemoveCorpse(); - } - } -}; -CreatureAI* GetAI_mob_sunspring_villager(Creature* pCreature) -{ - return new mob_sunspring_villagerAI(pCreature); -} - /*###### ## npc_altruis_the_sufferer ######*/ @@ -685,7 +618,7 @@ struct MANGOS_DLL_DECL npc_creditmarker_visit_with_ancestorsAI : public Scripted { // 18840: Sunspring, 18841: Laughing, 18842: Garadar, 18843: Bleeding if (!((Player*)pWho)->GetReqKillOrCastCurrentCount(QUEST_VISIT_WITH_ANCESTORS, creditMarkerId)) - ((Player*)pWho)->KilledMonsterCredit(creditMarkerId, m_creature->GetGUID()); + ((Player*)pWho)->KilledMonsterCredit(creditMarkerId, m_creature->GetObjectGuid()); } } } @@ -705,11 +638,6 @@ void AddSC_nagrand() { Script* pNewScript; - pNewScript = new Script; - pNewScript->Name = "mob_shattered_rumbler"; - pNewScript->GetAI = &GetAI_mob_shattered_rumbler; - pNewScript->RegisterSelf(); - pNewScript = new Script; pNewScript->Name = "mob_lump"; pNewScript->GetAI = &GetAI_mob_lump; @@ -717,16 +645,11 @@ void AddSC_nagrand() pNewScript->pGossipSelect = &GossipSelect_mob_lump; pNewScript->RegisterSelf(); - pNewScript = new Script; - pNewScript->Name = "mob_sunspring_villager"; - pNewScript->GetAI = &GetAI_mob_sunspring_villager; - pNewScript->RegisterSelf(); - pNewScript = new Script; pNewScript->Name = "npc_altruis_the_sufferer"; pNewScript->pGossipHello = &GossipHello_npc_altruis_the_sufferer; pNewScript->pGossipSelect = &GossipSelect_npc_altruis_the_sufferer; - pNewScript->pQuestAccept = &QuestAccept_npc_altruis_the_sufferer; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_altruis_the_sufferer; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -744,7 +667,7 @@ void AddSC_nagrand() pNewScript = new Script; pNewScript->Name = "npc_maghar_captive"; pNewScript->GetAI = &GetAI_npc_maghar_captive; - pNewScript->pQuestAccept = &QuestAccept_npc_maghar_captive; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_maghar_captive; pNewScript->RegisterSelf(); pNewScript = new Script; diff --git a/scripts/outland/netherstorm.cpp b/scripts/outland/netherstorm.cpp index f9ec68092..8b86470a0 100644 --- a/scripts/outland/netherstorm.cpp +++ b/scripts/outland/netherstorm.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: Netherstorm SD%Complete: 80 -SDComment: Quest support: 10438, 10652 (special flight paths), 10299, 10321, 10322, 10323, 10329, 10330, 10337, 10338, 10365(Shutting Down Manaforge), 10198, 10191 +SDComment: Quest support: 10438, 10652 (special flight paths), 10299, 10321, 10322, 10323, 10329, 10330, 10337, 10338, 10365(Shutting Down Manaforge), 10198, 10191, 10924 SDCategory: Netherstorm EndScriptData */ @@ -33,6 +33,7 @@ EndContentData */ #include "precompiled.h" #include "escort_ai.h" +#include "pet_ai.h" /*###### ## npc_manaforge_control_console @@ -276,7 +277,7 @@ struct MANGOS_DLL_DECL npc_manaforge_control_consoleAI : public ScriptedAI break; case 5: DoScriptText(EMOTE_COMPLETE, m_creature, pPlayer); - pPlayer->KilledMonsterCredit(m_creature->GetEntry(), m_creature->GetGUID()); + pPlayer->KilledMonsterCredit(m_creature->GetEntry(), m_creature->GetObjectGuid()); DoCastSpellIfCan(m_creature, SPELL_DISABLE_VISUAL); if (m_uiConsoleGUID) { @@ -311,7 +312,7 @@ CreatureAI* GetAI_npc_manaforge_control_console(Creature* pCreature) ######*/ // TODO: clean up this workaround when mangos adds support to do it properly (with gossip selections instead of instant summon) -bool GOHello_go_manaforge_control_console(Player* pPlayer, GameObject* pGo) +bool GOUse_go_manaforge_control_console(Player* pPlayer, GameObject* pGo) { if (pGo->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) { @@ -919,13 +920,49 @@ bool QuestAccept_npc_maxx_a_million(Player* pPlayer, Creature* pCreature, const return true; } +/*###### +## npc_zeppit +######*/ + +enum +{ + EMOTE_GATHER_BLOOD = -1000625, + NPC_WARP_CHASER = 18884, + SPELL_GATHER_WARP_BLOOD = 39244, // for quest 10924 +}; + +struct MANGOS_DLL_DECL npc_zeppitAI : public ScriptedPetAI +{ + npc_zeppitAI(Creature* pCreature) : ScriptedPetAI(pCreature) { Reset(); } + + void Reset() { } + + void OwnerKilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() == TYPEID_UNIT && pVictim->GetEntry() == NPC_WARP_CHASER) + { + // Distance not known, be assumed to be ~10 yards, possibly a bit less. + if (m_creature->IsWithinDistInMap(pVictim, 10.0f)) + { + DoScriptText(EMOTE_GATHER_BLOOD, m_creature); + m_creature->CastSpell(m_creature, SPELL_GATHER_WARP_BLOOD, false); + } + } + } +}; + +CreatureAI* GetAI_npc_zeppit(Creature* pCreature) +{ + return new npc_zeppitAI(pCreature); +} + void AddSC_netherstorm() { Script* pNewScript; pNewScript = new Script; pNewScript->Name = "go_manaforge_control_console"; - pNewScript->pGOHello = &GOHello_go_manaforge_control_console; + pNewScript->pGOUse = &GOUse_go_manaforge_control_console; pNewScript->RegisterSelf(); pNewScript = new Script; @@ -958,12 +995,17 @@ void AddSC_netherstorm() pNewScript = new Script; pNewScript->Name = "npc_bessy"; pNewScript->GetAI = &GetAI_npc_bessy; - pNewScript->pQuestAccept = &QuestAccept_npc_bessy; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_bessy; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "npc_maxx_a_million"; pNewScript->GetAI = &GetAI_npc_maxx_a_million; - pNewScript->pQuestAccept = &QuestAccept_npc_maxx_a_million; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_maxx_a_million; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_zeppit"; + pNewScript->GetAI = &GetAI_npc_zeppit; pNewScript->RegisterSelf(); } diff --git a/scripts/outland/shadowmoon_valley.cpp b/scripts/outland/shadowmoon_valley.cpp index 1c8d60e6a..4ab733944 100644 --- a/scripts/outland/shadowmoon_valley.cpp +++ b/scripts/outland/shadowmoon_valley.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,13 +17,14 @@ /* ScriptData SDName: Shadowmoon_Valley SD%Complete: 100 -SDComment: Quest support: 10519, 10583, 10601, 10781, 10814, 10804, 10854, 11082. Vendor Drake Dealer Hurlunk. +SDComment: Quest support: 10519, 10583, 10601, 10781, 10814, 10804, 10854, 11082, 10458, 10480, 10481. Vendor Drake Dealer Hurlunk. SDCategory: Shadowmoon Valley EndScriptData */ /* ContentData mob_mature_netherwing_drake mob_enslaved_netherwing_drake +npc_dragonmaw_peon npc_drake_dealer_hurlunk npcs_flanis_swiftwing_and_kagrosh npc_murkblood_overseer @@ -32,12 +33,15 @@ npc_karynaku npc_oronok_tornheart npc_wilda mob_torloth +npc_totem_of_spirits +event_spell_soul_captured_credit npc_lord_illidan_stormrage go_crystal_prison EndContentData */ #include "precompiled.h" #include "escort_ai.h" +#include "pet_ai.h" /*##### # mob_mature_netherwing_drake @@ -114,7 +118,19 @@ struct MANGOS_DLL_DECL mob_mature_netherwing_drakeAI : public ScriptedAI { if (Player* pPlayer = m_creature->GetMap()->GetPlayer(uiPlayerGUID)) { - if (GameObject* pGo = pPlayer->GetGameObject(SPELL_PLACE_CARCASS)) + GameObject* pGo = pPlayer->GetGameObject(SPELL_PLACE_CARCASS); + + // Workaround for broken function GetGameObject + if (!pGo) + { + const SpellEntry* pSpell = GetSpellStore()->LookupEntry(SPELL_PLACE_CARCASS); + + uint32 uiGameobjectEntry = pSpell->EffectMiscValue[EFFECT_INDEX_0]; + + pGo = GetClosestGameObjectWithEntry(pPlayer, uiGameobjectEntry, 2*INTERACTION_DISTANCE); + } + + if (pGo) { if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) m_creature->GetMotionMaster()->MovementExpired(); @@ -122,7 +138,10 @@ struct MANGOS_DLL_DECL mob_mature_netherwing_drakeAI : public ScriptedAI m_creature->GetMotionMaster()->MoveIdle(); m_creature->StopMoving(); - m_creature->GetMotionMaster()->MovePoint(POINT_ID, pGo->GetPositionX(), pGo->GetPositionY(), pGo->GetPositionZ()); + float fX, fY, fZ; + pGo->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); + + m_creature->GetMotionMaster()->MovePoint(POINT_ID, fX, fY, fZ); } } bCanEat = false; @@ -133,7 +152,7 @@ struct MANGOS_DLL_DECL mob_mature_netherwing_drakeAI : public ScriptedAI DoScriptText(SAY_JUST_EATEN, m_creature); if (Player* pPlayer = m_creature->GetMap()->GetPlayer(uiPlayerGUID)) - pPlayer->KilledMonsterCredit(NPC_EVENT_PINGER, m_creature->GetGUID()); + pPlayer->KilledMonsterCredit(NPC_EVENT_PINGER, m_creature->GetObjectGuid()); Reset(); m_creature->GetMotionMaster()->Clear(); @@ -274,49 +293,50 @@ CreatureAI* GetAI_mob_enslaved_netherwing_drake(Creature* pCreature) } /*##### -# mob_dragonmaw_peon +# npc_dragonmaw_peon #####*/ enum { + SAY_PEON_1 = -1000652, + SAY_PEON_2 = -1000653, + SAY_PEON_3 = -1000654, + SAY_PEON_4 = -1000655, + SAY_PEON_5 = -1000656, + SPELL_SERVING_MUTTON = 40468, NPC_DRAGONMAW_KILL_CREDIT = 23209, - QUEST_SLOW_DEATH = 11020, + EQUIP_ID_MUTTON = 2202, POINT_DEST = 1 }; -struct MANGOS_DLL_DECL mob_dragonmaw_peonAI : public ScriptedAI +struct MANGOS_DLL_DECL npc_dragonmaw_peonAI : public ScriptedAI { - mob_dragonmaw_peonAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + npc_dragonmaw_peonAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } uint64 m_uiPlayerGUID; - bool m_bIsTapped; uint32 m_uiPoisonTimer; + uint32 m_uiMoveTimer; + uint32 m_uiEatTimer; void Reset() { m_uiPlayerGUID = 0; - m_bIsTapped = false; m_uiPoisonTimer = 0; + m_uiMoveTimer = 0; + m_uiEatTimer = 0; + + SetEquipmentSlots(true); } - void SpellHit(Unit* pCaster, const SpellEntry* pSpell) + bool SetPlayerTarget(uint64 uiPlayerGUID) { - if (!pCaster) - return; - - if (pCaster->GetTypeId() == TYPEID_PLAYER && pSpell->Id == SPELL_SERVING_MUTTON && !m_bIsTapped) - { - m_uiPlayerGUID = pCaster->GetGUID(); + if (m_uiPlayerGUID) + return false; - m_bIsTapped = true; - - float fX, fY, fZ; - pCaster->GetClosePoint(fX, fY, fZ, m_creature->GetObjectBoundingRadius()); - - m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); - m_creature->GetMotionMaster()->MovePoint(POINT_DEST, fX, fY, fZ); - } + m_uiPlayerGUID = uiPlayerGUID; + m_uiMoveTimer = 500; + return true; } void MovementInform(uint32 uiType, uint32 uiPointId) @@ -326,25 +346,82 @@ struct MANGOS_DLL_DECL mob_dragonmaw_peonAI : public ScriptedAI if (uiPointId == POINT_DEST) { - m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_EAT); - m_uiPoisonTimer = 15000; + m_uiEatTimer = 2000; + m_uiPoisonTimer = 3000; + + switch(urand(0, 4)) + { + case 0: DoScriptText(SAY_PEON_1, m_creature); break; + case 1: DoScriptText(SAY_PEON_2, m_creature); break; + case 2: DoScriptText(SAY_PEON_3, m_creature); break; + case 3: DoScriptText(SAY_PEON_4, m_creature); break; + case 4: DoScriptText(SAY_PEON_5, m_creature); break; + } } } void UpdateAI(const uint32 uiDiff) { - if (m_uiPoisonTimer) + if (!m_creature->isAlive()) + return; + + if (m_uiMoveTimer) { - if (m_uiPoisonTimer <= uiDiff) + if (m_uiMoveTimer <= uiDiff) { if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) { - if (pPlayer->GetQuestStatus(QUEST_SLOW_DEATH) == QUEST_STATUS_INCOMPLETE) - pPlayer->KilledMonsterCredit(NPC_DRAGONMAW_KILL_CREDIT, m_creature->GetGUID()); + GameObject* pMutton = pPlayer->GetGameObject(SPELL_SERVING_MUTTON); + + // Workaround for broken function GetGameObject + if (!pMutton) + { + const SpellEntry* pSpell = GetSpellStore()->LookupEntry(SPELL_SERVING_MUTTON); + + uint32 uiGameobjectEntry = pSpell->EffectMiscValue[EFFECT_INDEX_0]; + + // this can fail, but very low chance + pMutton = GetClosestGameObjectWithEntry(pPlayer, uiGameobjectEntry, 2*INTERACTION_DISTANCE); + } + + if (pMutton) + { + float fX, fY, fZ; + pMutton->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); + + m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); + m_creature->GetMotionMaster()->MovePoint(POINT_DEST, fX, fY, fZ); + } } + m_uiMoveTimer = 0; + } + else + m_uiMoveTimer -= uiDiff; + } + else if (m_uiEatTimer) + { + if (m_uiEatTimer <= uiDiff) + { + SetEquipmentSlots(false, EQUIP_ID_MUTTON, EQUIP_UNEQUIP); + m_creature->HandleEmote(EMOTE_ONESHOT_EAT_NOSHEATHE); + m_uiEatTimer = 0; + } + else + m_uiEatTimer -= uiDiff; + } + else if (m_uiPoisonTimer) + { + if (m_uiPoisonTimer <= uiDiff) + { + if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID)) + pPlayer->KilledMonsterCredit(NPC_DRAGONMAW_KILL_CREDIT, m_creature->GetObjectGuid()); + m_uiPoisonTimer = 0; - m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + // dies + m_creature->SetDeathState(JUST_DIED); + m_creature->SetHealth(0); } else m_uiPoisonTimer -= uiDiff; @@ -352,6 +429,30 @@ struct MANGOS_DLL_DECL mob_dragonmaw_peonAI : public ScriptedAI } }; +CreatureAI* GetAI_npc_dragonmaw_peon(Creature* pCreature) +{ + return new npc_dragonmaw_peonAI(pCreature); +} + +bool EffectDummyCreature_npc_dragonmaw_peon(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +{ + if (uiEffIndex != EFFECT_INDEX_1 || uiSpellId != SPELL_SERVING_MUTTON || pCaster->GetTypeId() != TYPEID_PLAYER) + return false; + + npc_dragonmaw_peonAI* pPeonAI = dynamic_cast(pCreatureTarget->AI()); + + if (!pPeonAI) + return false; + + if (pPeonAI->SetPlayerTarget(pCaster->GetGUID())) + { + pCreatureTarget->HandleEmote(EMOTE_ONESHOT_NONE); + return true; + } + + return false; +} + /*###### ## npc_drake_dealer_hurlunk ######*/ @@ -782,7 +883,7 @@ enum EVENT_COOLDOWN = 30000, SAY_TORLOTH_DIALOGUE1 = -1000532, - SAY_TORLOTH_DIALOGUE2 = -1000533, + SAY_TORLOTH_DIALOGUE2 = -1000533, SAY_TORLOTH_DIALOGUE3 = -1000534, SAY_ILLIDAN_DIALOGUE = -1000535, SAY_ILLIDAN_SUMMON1 = -1000536, @@ -822,7 +923,7 @@ static TorlothCinematic TorlothAnim[]= {SAY_ILLIDAN_DIALOGUE, LORD_ILLIDAN, 7000}, {SAY_TORLOTH_DIALOGUE2, TORLOTH, 3000}, {0, TORLOTH, 2000}, // Torloth stand - {SAY_TORLOTH_DIALOGUE3, TORLOTH, 1000}, + {SAY_TORLOTH_DIALOGUE3, TORLOTH, 1000}, {0, TORLOTH, 3000}, {0, TORLOTH, 0} }; @@ -859,7 +960,7 @@ struct WaveData { uint8 uiSpawnCount; uint8 uiUsedSpawnPoint; - uint32 uiCreatureId; + uint32 uiCreatureId; uint32 uiSpawnTimer; uint32 uiYellTimer; int32 iTextId; @@ -946,7 +1047,7 @@ struct MANGOS_DLL_DECL mob_torlothAI : public ScriptedAI { case 0: m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); - break; + break; case 3: m_creature->SetStandState(UNIT_STAND_STATE_STAND); break; @@ -980,7 +1081,7 @@ struct MANGOS_DLL_DECL mob_torlothAI : public ScriptedAI if (Player* pPlayer = pKiller->GetCharmerOrOwnerPlayerOrPlayerItself()) { pPlayer->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, m_creature); - + if (Creature* pLordIllidan = m_creature->GetMap()->GetCreature(m_uiLordIllidanGUID)) { DoScriptText(SAY_EVENT_COMPLETED, pLordIllidan, pPlayer); @@ -1037,6 +1138,170 @@ CreatureAI* GetAI_mob_torloth(Creature* pCreature) return new mob_torlothAI(pCreature); } +/*###### +## npc_totem_of_spirits +######*/ + +enum +{ + QUEST_SPIRITS_FIRE_AND_EARTH = 10458, + QUEST_SPIRITS_WATER = 10480, + QUEST_SPIRITS_AIR = 10481, + + // quest 10458, 10480, 10481 + SPELL_ELEMENTAL_SIEVE = 36035, + NPC_TOTEM_OF_SPIRITS = 21071, + NPC_EARTH_SPIRIT = 21050, // to be killed + NPC_FIERY_SPIRIT = 21061, + NPC_WATER_SPIRIT = 21059, + NPC_AIR_SPIRIT = 21060, + SPELL_EARTH_CAPTURED = 36025, // dummies (having visual effects) + SPELL_FIERY_CAPTURED = 36115, + SPELL_WATER_CAPTURED = 36170, + SPELL_AIR_CAPTURED = 36181, + SPELL_EARTH_CAPTURED_CREDIT = 36108, // event 13513 + SPELL_FIERY_CAPTURED_CREDIT = 36117, // event 13514 + SPELL_WATER_CAPTURED_CREDIT = 36171, // event 13515 + SPELL_AIR_CAPTURED_CREDIT = 36182, // event 13516 + EVENT_EARTH = 13513, + EVENT_FIERY = 13514, + EVENT_WATER = 13515, + EVENT_AIR = 13516, + NPC_CREDIT_MARKER_EARTH = 21092, // quest objective npc's + NPC_CREDIT_MARKER_FIERY = 21094, + NPC_CREDIT_MARKER_WATER = 21095, + NPC_CREDIT_MARKER_AIR = 21096, +}; + +struct MANGOS_DLL_DECL npc_totem_of_spiritsAI : public ScriptedPetAI +{ + npc_totem_of_spiritsAI(Creature* pCreature) : ScriptedPetAI(pCreature) { Reset(); } + + void Reset() {} + + void MoveInLineOfSight(Unit* pWho) {} + void UpdateAI(const uint32 uiDiff) {} + void AttackedBy(Unit* pAttacker) {} + + void OwnerKilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() != TYPEID_UNIT) + return; + + uint32 uiEntry = pVictim->GetEntry(); + + // make elementals cast the sieve is only way to make it work properly, due to the spell target modes 22/7 + if (uiEntry == NPC_EARTH_SPIRIT || uiEntry == NPC_FIERY_SPIRIT || uiEntry == NPC_WATER_SPIRIT || uiEntry == NPC_AIR_SPIRIT) + pVictim->CastSpell(pVictim, SPELL_ELEMENTAL_SIEVE, true); + } +}; + +CreatureAI* GetAI_npc_totem_of_spirits(Creature* pCreature) +{ + return new npc_totem_of_spiritsAI(pCreature); +} + +bool EffectDummyCreature_npc_totem_of_spirits(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget) +{ + if (uiEffIndex != EFFECT_INDEX_0) + return false; + + switch(uiSpellId) + { + case SPELL_EARTH_CAPTURED: + { + pCaster->CastSpell(pCaster, SPELL_EARTH_CAPTURED_CREDIT, true); + return true; + } + case SPELL_FIERY_CAPTURED: + { + pCaster->CastSpell(pCaster, SPELL_FIERY_CAPTURED_CREDIT, true); + return true; + } + case SPELL_WATER_CAPTURED: + { + pCaster->CastSpell(pCaster, SPELL_WATER_CAPTURED_CREDIT, true); + return true; + } + case SPELL_AIR_CAPTURED: + { + pCaster->CastSpell(pCaster, SPELL_AIR_CAPTURED_CREDIT, true); + return true; + } + } + + return false; +} + +bool EffectAuraDummy_npc_totem_of_spirits(const Aura* pAura, bool bApply) +{ + if (pAura->GetId() != SPELL_ELEMENTAL_SIEVE) + return true; + + if (pAura->GetEffIndex() != EFFECT_INDEX_0) + return true; + + if (bApply) // possible it should be some visual effects, using "enraged soul" npc and "Cosmetic: ... soul" spell + return true; + + Creature* pCreature = (Creature*)pAura->GetTarget(); + Unit* pCaster = pAura->GetCaster(); + + // aura only affect the spirit totem, since this is the one that need to be in range. + // It is possible though, that player is the one who should actually have the aura + // and check for presense of spirit totem, but then we can't script the dummy. + if (!pCreature || !pCreature->IsPet() || !pCaster) + return true; + + // Need to expect the enraged elementals to be caster of aura + switch(pCaster->GetEntry()) + { + case NPC_EARTH_SPIRIT: + pCreature->CastSpell(pCreature, SPELL_EARTH_CAPTURED, true); + break; + case NPC_FIERY_SPIRIT: + pCreature->CastSpell(pCreature, SPELL_FIERY_CAPTURED, true); + break; + case NPC_WATER_SPIRIT: + pCreature->CastSpell(pCreature, SPELL_WATER_CAPTURED, true); + break; + case NPC_AIR_SPIRIT: + pCreature->CastSpell(pCreature, SPELL_AIR_CAPTURED, true); + break; + } + + return true; +} + +bool ProcessEventId_event_spell_soul_captured_credit(uint32 uiEventId, Object* pSource, Object* pTarget, bool bIsStart) +{ + if (bIsStart && pSource->GetTypeId() == TYPEID_UNIT) + { + Player* pOwner = (Player*)((Creature*)pSource)->GetOwner(); + + if (!pOwner) + return true; + + switch(uiEventId) + { + case EVENT_EARTH: + pOwner->KilledMonsterCredit(NPC_CREDIT_MARKER_EARTH); + return true; + case EVENT_FIERY: + pOwner->KilledMonsterCredit(NPC_CREDIT_MARKER_FIERY); + return true; + case EVENT_WATER: + pOwner->KilledMonsterCredit(NPC_CREDIT_MARKER_WATER); + return true; + case EVENT_AIR: + pOwner->KilledMonsterCredit(NPC_CREDIT_MARKER_AIR); + return true; + } + } + + return false; +} + /*##### # npc_lord_illidan_stormrage #####*/ @@ -1149,7 +1414,7 @@ struct MANGOS_DLL_DECL npc_lord_illidan_stormrageAI : public Scripted_NoMovement } } - void SummonedCreatureDespawn(Creature* pCreature) + void SummonedCreatureDespawn(Creature* pCreature) { // decrement mob count --m_uiMobCount; @@ -1264,7 +1529,7 @@ CreatureAI* GetAI_npc_lord_illidan_stormrage(Creature* (pCreature)) ######*/ bool GOQuestAccept_GO_crystal_prison(Player* pPlayer, GameObject* pGo, Quest const* pQuest) { - if (pQuest->GetQuestId() == QUEST_BATTLE_OF_THE_CRIMSON_WATCH ) + if (pQuest->GetQuestId() == QUEST_BATTLE_OF_THE_CRIMSON_WATCH) if (Creature* pLordIllidan = GetClosestCreatureWithEntry(pPlayer, NPC_LORD_ILLIDAN, 50.0)) if (npc_lord_illidan_stormrageAI* pIllidanAI = dynamic_cast(pLordIllidan->AI())) if (!pIllidanAI->m_bEventStarted) @@ -1287,6 +1552,12 @@ void AddSC_shadowmoon_valley() newscript->GetAI = &GetAI_mob_enslaved_netherwing_drake; newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "npc_dragonmaw_peon"; + newscript->GetAI = &GetAI_npc_dragonmaw_peon; + newscript->pEffectDummyNPC = &EffectDummyCreature_npc_dragonmaw_peon; + newscript->RegisterSelf(); + newscript = new Script; newscript->Name = "npc_drake_dealer_hurlunk"; newscript->pGossipHello = &GossipHello_npc_drake_dealer_hurlunk; @@ -1313,7 +1584,7 @@ void AddSC_shadowmoon_valley() newscript = new Script; newscript->Name = "npc_karynaku"; - newscript->pQuestAccept = &QuestAccept_npc_karynaku; + newscript->pQuestAcceptNPC = &QuestAccept_npc_karynaku; newscript->RegisterSelf(); newscript = new Script; @@ -1325,7 +1596,7 @@ void AddSC_shadowmoon_valley() newscript = new Script; newscript->Name = "npc_wilda"; newscript->GetAI = &GetAI_npc_wilda; - newscript->pQuestAccept = &QuestAccept_npc_wilda; + newscript->pQuestAcceptNPC = &QuestAccept_npc_wilda; newscript->RegisterSelf(); newscript = new Script; @@ -1338,8 +1609,20 @@ void AddSC_shadowmoon_valley() newscript->GetAI = &GetAI_mob_torloth; newscript->RegisterSelf(); + newscript = new Script; + newscript->Name = "npc_totem_of_spirits"; + newscript->GetAI = &GetAI_npc_totem_of_spirits; + newscript->pEffectDummyNPC = &EffectDummyCreature_npc_totem_of_spirits; + newscript->pEffectAuraDummy = &EffectAuraDummy_npc_totem_of_spirits; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "event_spell_soul_captured_credit"; + newscript->pProcessEventId = &ProcessEventId_event_spell_soul_captured_credit; + newscript->RegisterSelf(); + newscript = new Script; newscript->Name = "go_crystal_prison"; - newscript->pGOQuestAccept = &GOQuestAccept_GO_crystal_prison; + newscript->pQuestAcceptGO = &GOQuestAccept_GO_crystal_prison; newscript->RegisterSelf(); } diff --git a/scripts/outland/shattrath_city.cpp b/scripts/outland/shattrath_city.cpp index a7aaa3e11..a9a7cb107 100644 --- a/scripts/outland/shattrath_city.cpp +++ b/scripts/outland/shattrath_city.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp b/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp index ac04e3a1e..d4cbad890 100644 --- a/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp +++ b/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/arcatraz/arcatraz.h b/scripts/outland/tempest_keep/arcatraz/arcatraz.h index c5b73afc4..775370441 100644 --- a/scripts/outland/tempest_keep/arcatraz/arcatraz.h +++ b/scripts/outland/tempest_keep/arcatraz/arcatraz.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp b/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp index ced7ad021..c018151fc 100644 --- a/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp +++ b/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp b/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp index d13b44927..ca413c247 100644 --- a/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp +++ b/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp b/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp index 68d535c26..3c72465dc 100644 --- a/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp +++ b/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/botanica/boss_laj.cpp b/scripts/outland/tempest_keep/botanica/boss_laj.cpp index 20cd4486a..67630c046 100644 --- a/scripts/outland/tempest_keep/botanica/boss_laj.cpp +++ b/scripts/outland/tempest_keep/botanica/boss_laj.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp b/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp index 0a3b733a3..940517ae5 100644 --- a/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp +++ b/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp b/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp index cf9ac7ba0..31b315b8d 100644 --- a/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp +++ b/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -66,63 +66,73 @@ const float SMALL_PORTAL_RADIUS = 12.6f; const float LARGE_PORTAL_RADIUS = 26.0f; const float PORTAL_Z = 17.005f; +enum Phases +{ + PHASE_NORMAL = 1, + PHASE_SUMMON_AGENTS = 2, + PHASE_SUMMON_PRIESTS = 3, + PHASE_VOID = 4, +}; + struct MANGOS_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI { boss_high_astromancer_solarianAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); - defaultarmor = m_creature->GetArmor(); - defaultsize = m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X); + m_uiDefaultArmor = m_creature->GetArmor(); + m_fDefaultSize = m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X); Reset(); } ScriptedInstance* m_pInstance; - uint32 ArcaneMissiles_Timer; - uint32 m_uiWrathOfTheAstromancer_Timer; - uint32 BlindingLight_Timer; - uint32 Fear_Timer; - uint32 VoidBolt_Timer; - uint32 Phase1_Timer; - uint32 Phase2_Timer; - uint32 Phase3_Timer; - uint32 AppearDelay_Timer; - uint32 defaultarmor; + uint32 m_uiArcaneMissilesTimer; + uint32 m_uiWrathOfTheAstromancerTimer; + uint32 m_uiBlindingLightTimer; + uint32 m_uiFearTimer; + uint32 m_uiVoidBoltTimer; + uint32 m_uiPhaseOneTimer; + uint32 m_uiPhaseTwoTimer; + uint32 m_uiPhaseThreeTimer; + uint32 m_uiAppearDelayTimer; + uint32 m_uiDefaultArmor; - float defaultsize; + float m_fDefaultSize; - bool AppearDelay; + bool m_bIsAppearDelay; - uint8 Phase; + Phases m_Phase; - float Portals[3][3]; + float m_aPortals[3][3]; void Reset() { - ArcaneMissiles_Timer = 2000; - m_uiWrathOfTheAstromancer_Timer = 15000; - BlindingLight_Timer = 41000; - Fear_Timer = 20000; - VoidBolt_Timer = 10000; - Phase1_Timer = 50000; - Phase2_Timer = 10000; - Phase3_Timer = 15000; - AppearDelay_Timer = 2000; - AppearDelay = false; - Phase = 1; + m_uiArcaneMissilesTimer = 2000; + m_uiWrathOfTheAstromancerTimer = 15000; + m_uiBlindingLightTimer = 41000; + m_uiFearTimer = 20000; + m_uiVoidBoltTimer = 10000; + m_uiPhaseOneTimer = 50000; + m_uiPhaseTwoTimer = 8000; + m_uiPhaseThreeTimer = 15000; + m_uiAppearDelayTimer = 2000; + m_bIsAppearDelay = false; + m_Phase = PHASE_NORMAL; if (m_pInstance) m_pInstance->SetData(TYPE_ASTROMANCER, NOT_STARTED); - m_creature->SetArmor(defaultarmor); + m_creature->SetArmor(m_uiDefaultArmor); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetVisibility(VISIBILITY_ON); - m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize); + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fDefaultSize); m_creature->SetDisplayId(MODEL_HUMAN); + + SetCombatMovement(true); } - void KilledUnit(Unit *victim) + void KilledUnit(Unit* pVictim) { switch(urand(0, 2)) { @@ -132,9 +142,9 @@ struct MANGOS_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI } } - void JustDied(Unit *victim) + void JustDied(Unit* pKiller) { - m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize); + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fDefaultSize); m_creature->SetDisplayId(MODEL_HUMAN); DoScriptText(SAY_DEATH, m_creature); @@ -143,245 +153,277 @@ struct MANGOS_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI m_pInstance->SetData(TYPE_ASTROMANCER, DONE); } - void Aggro(Unit *who) + void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); if (m_pInstance) m_pInstance->SetData(TYPE_ASTROMANCER, IN_PROGRESS); } - void SummonMinion(uint32 entry, float x, float y, float z) + void JustSummoned(Creature* pSummoned) { - Creature* Summoned = m_creature->SummonCreature(entry, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - if (Summoned) + switch (pSummoned->GetEntry()) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - Summoned->AI()->AttackStart(target); + case NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT: + pSummoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + pSummoned->CastSpell(pSummoned, SPELL_SPOTLIGHT, false); + break; + case NPC_SOLARIUM_AGENT: + case NPC_SOLARIUM_PRIEST: + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); + break; } } - float Portal_X(float radius) + float Portal_X(float fRadius) { if (urand(0, 1)) - radius = -radius; + fRadius = -fRadius; - return (radius * (float)(rand()%100)/100.0f + CENTER_X); + return (fRadius * (float)(rand()%100)/100.0f + CENTER_X); } - float Portal_Y(float x, float radius) + float Portal_Y(float fX, float fRadius) { - float z = 0.0f; + float fZ = urand(0, 1) ? 1.0f : -1.0f; - switch(urand(0, 1)) - { - case 0: z = 1; break; - case 1: z = -1; break; - } - return (z*sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y); + return (fZ * sqrt(fRadius*fRadius - (fX - CENTER_X)*(fX - CENTER_X)) + CENTER_Y); } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (AppearDelay) + // When Solarian reaches 20% she will transform into a huge void walker. + if (m_Phase != PHASE_VOID && m_creature->GetHealthPercent() < 20.0f) { - m_creature->StopMoving(); - m_creature->AttackStop(); + m_Phase = PHASE_VOID; - if (AppearDelay_Timer < diff) + // To make sure she behaves like expected + m_bIsAppearDelay = false; + if (!IsCombatMovement()) { - AppearDelay = false; + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + } + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetVisibility(VISIBILITY_ON); - if (Phase == 2) - { - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetVisibility(VISIBILITY_OFF); - } + DoScriptText(SAY_VOIDA, m_creature); + DoScriptText(SAY_VOIDB, m_creature); - AppearDelay_Timer = 2000; - }else AppearDelay_Timer -= diff; + m_creature->SetArmor(WV_ARMOR); + m_creature->SetDisplayId(MODEL_VOIDWALKER); + m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fDefaultSize*2.5f); } - if (Phase == 1) + if (m_bIsAppearDelay) { - //ArcaneMissiles_Timer - if (ArcaneMissiles_Timer < diff) + if (m_uiAppearDelayTimer < uiDiff) { - //Solarian casts Arcane Missiles on on random targets in the raid. - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - { - if (!m_creature->HasInArc(2.5f, target)) - target = m_creature->getVictim(); + m_bIsAppearDelay = false; - if (target) - DoCastSpellIfCan(target, SPELL_ARCANE_MISSILES); + if (m_Phase == PHASE_SUMMON_AGENTS) + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetVisibility(VISIBILITY_OFF); + } + // Let move and attack again + else if (!IsCombatMovement()) + { + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } - ArcaneMissiles_Timer = 3000; - }else ArcaneMissiles_Timer -= diff; + m_uiAppearDelayTimer = 2000; + } + else + m_uiAppearDelayTimer -= uiDiff; - //Wrath of the Astromancer targets a random player which will explode after 6 secondes - if (m_uiWrathOfTheAstromancer_Timer < diff) - { - m_creature->InterruptNonMeleeSpells(false); + // Combat is still on hold + return; + } - //Target the tank ? - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) + switch (m_Phase) + { + case PHASE_NORMAL: + // Wrath of the Astromancer targets a random player which will explode after 6 secondes + if (m_uiWrathOfTheAstromancerTimer < uiDiff) { - if (pTarget->GetTypeId() == TYPEID_PLAYER) + // Target the tank ? + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { - DoCastSpellIfCan(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER); - m_uiWrathOfTheAstromancer_Timer = 25000; + if (pTarget->GetTypeId() == TYPEID_PLAYER) + { + if (DoCastSpellIfCan(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER, CAST_INTERRUPT_PREVIOUS) == CAST_OK) + m_uiWrathOfTheAstromancerTimer = 25000; + } + else + m_uiWrathOfTheAstromancerTimer = 1000; } else - m_uiWrathOfTheAstromancer_Timer = 1000; + m_uiWrathOfTheAstromancerTimer = 10000; } - }else m_uiWrathOfTheAstromancer_Timer -= diff; + else + m_uiWrathOfTheAstromancerTimer -= uiDiff; - //BlindingLight_Timer - if (BlindingLight_Timer < diff) - { - //She casts this spell every 45 seconds. It is a kind of Moonfire spell, which she strikes down on the whole raid simultaneously. It hits everyone in the raid for 2280 to 2520 arcane damage. - DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLINDING_LIGHT); - BlindingLight_Timer = 45000; - }else BlindingLight_Timer -= diff; + // Blinding Light Timer + if (m_uiBlindingLightTimer < uiDiff) + { + // She casts this spell every 45 seconds. It is a kind of Moonfire spell, which she strikes down on the whole raid simultaneously. It hits everyone in the raid for 2280 to 2520 arcane damage. + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLINDING_LIGHT) == CAST_OK) + m_uiBlindingLightTimer = 45000; + } + else + m_uiBlindingLightTimer -= uiDiff; - //Phase1_Timer - if (Phase1_Timer < diff) - { - Phase = 2; - Phase1_Timer = 50000; + // Arcane Missiles Timer - TODO - check timer, if this spell is cast always, CombatMovement should be disabled here + if (m_uiArcaneMissilesTimer < uiDiff) + { + // Solarian casts Arcane Missiles on on random targets in the raid. + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + { + if (!m_creature->HasInArc(2.5f, pTarget)) + pTarget = m_creature->getVictim(); - //After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind. - m_creature->GetMotionMaster()->Clear(); - m_creature->GetMap()->CreatureRelocation(m_creature, CENTER_X, CENTER_Y, CENTER_Z, CENTER_O); + if (pTarget) + DoCastSpellIfCan(pTarget, SPELL_ARCANE_MISSILES); + } + + m_uiArcaneMissilesTimer = 5000; + } + else + m_uiArcaneMissilesTimer -= uiDiff; - for(int i = 0; i <= 2; ++i) + // Phase 1 Timer + if (m_uiPhaseOneTimer < uiDiff) { - if (!i) + m_Phase = PHASE_SUMMON_AGENTS; + + // After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind. + m_creature->GetMotionMaster()->Clear(); + m_creature->StopMoving(); + m_creature->AttackStop(); + + SetCombatMovement(false); + + m_creature->NearTeleportTo(CENTER_X, CENTER_Y, CENTER_Z, CENTER_O, true); + + for(int i = 0; i <= 2; ++i) { - Portals[i][0] = Portal_X(SMALL_PORTAL_RADIUS); - Portals[i][1] = Portal_Y(Portals[i][0], SMALL_PORTAL_RADIUS); - Portals[i][2] = CENTER_Z; + if (!i) + { + m_aPortals[i][0] = Portal_X(SMALL_PORTAL_RADIUS); + m_aPortals[i][1] = Portal_Y(m_aPortals[i][0], SMALL_PORTAL_RADIUS); + m_aPortals[i][2] = CENTER_Z; + } + else + { + m_aPortals[i][0] = Portal_X(LARGE_PORTAL_RADIUS); + m_aPortals[i][1] = Portal_Y(m_aPortals[i][0], LARGE_PORTAL_RADIUS); + m_aPortals[i][2] = PORTAL_Z; + } } - else + + if ((abs(int(m_aPortals[2][0]) - int(m_aPortals[1][0])) < 7) && (abs(int(m_aPortals[2][1]) - int(m_aPortals[1][1])) < 7)) { - Portals[i][0] = Portal_X(LARGE_PORTAL_RADIUS); - Portals[i][1] = Portal_Y(Portals[i][0], LARGE_PORTAL_RADIUS); - Portals[i][2] = PORTAL_Z; + int i = 1; + if (abs(int(CENTER_X) + int(26.0f) - int(m_aPortals[2][0])) < 7) + i = -1; + + m_aPortals[2][0] = m_aPortals[2][0]+7*i; + m_aPortals[2][1] = Portal_Y(m_aPortals[2][0], LARGE_PORTAL_RADIUS); } - } - if ((abs(int(Portals[2][0]) - int(Portals[1][0])) < 7) && (abs(int(Portals[2][1]) - int(Portals[1][1])) < 7)) - { - int i = 1; - if (abs(int(CENTER_X) + int(26.0f) - int(Portals[2][0])) < 7) - i = -1; + for (int i = 0; i <= 2; ++i) + m_creature->SummonCreature(NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT, m_aPortals[i][0], m_aPortals[i][1], m_aPortals[i][2], CENTER_O, TEMPSUMMON_TIMED_DESPAWN, m_uiPhaseTwoTimer+m_uiPhaseThreeTimer+m_uiAppearDelayTimer+1700); + + m_bIsAppearDelay = true; + m_uiPhaseOneTimer = 48000; // 2s for appearDelay - Portals[2][0] = Portals[2][0]+7*i; - Portals[2][1] = Portal_Y(Portals[2][0], LARGE_PORTAL_RADIUS); + // Do nothing more, if phase switched + return; } + else + m_uiPhaseOneTimer -= uiDiff; + + DoMeleeAttackIfReady(); + break; - for (int i = 0; i <= 2; ++i) + case PHASE_SUMMON_AGENTS: + // Check Phase 2 Timer + if (m_uiPhaseTwoTimer < uiDiff) { - if (Creature* Summoned = m_creature->SummonCreature(NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O, TEMPSUMMON_TIMED_DESPAWN, Phase2_Timer+Phase3_Timer+AppearDelay_Timer+1700)) + //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals. + m_Phase = PHASE_SUMMON_PRIESTS; + for (int i = 0; i <= 2; ++i) { - Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Summoned->CastSpell(Summoned, SPELL_SPOTLIGHT, false); + for (int j = 1; j <= 4; ++j) + m_creature->SummonCreature(NPC_SOLARIUM_AGENT, m_aPortals[i][0], m_aPortals[i][1], m_aPortals[i][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); } - } - AppearDelay = true; - }else Phase1_Timer -= diff; - } - else if (Phase == 2) - { - m_creature->AttackStop(); - m_creature->StopMoving(); + DoScriptText(SAY_SUMMON1, m_creature); - //Check Phase2_Timer - if (Phase2_Timer < diff) - { - //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals. - Phase = 3; - for (int i = 0; i <= 2; ++i) - { - for (int j = 1; j <= 4; ++j) - SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]); + m_uiPhaseTwoTimer = 8000; // 2s for appearDelay } + else + m_uiPhaseTwoTimer -= uiDiff; - DoScriptText(SAY_SUMMON1, m_creature); + break; - Phase2_Timer = 10000; - } else Phase2_Timer -= diff; - } - else if (Phase == 3) - { - m_creature->AttackStop(); - m_creature->StopMoving(); - - //Check Phase3_Timer - if (Phase3_Timer < diff) - { - Phase = 1; - - //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals. - int i = irand(0, 2); - m_creature->GetMotionMaster()->Clear(); - m_creature->GetMap()->CreatureRelocation(m_creature, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O); + case PHASE_SUMMON_PRIESTS: + // Check Phase 3 Timer + if (m_uiPhaseThreeTimer < uiDiff) + { + m_Phase = PHASE_NORMAL; - for (int j = 0; j <= 2; ++j) - if (j != i) - SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]); + // 15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals. + int i = irand(0, 2); + m_creature->GetMotionMaster()->Clear(); + m_creature->GetMap()->CreatureRelocation(m_creature, m_aPortals[i][0], m_aPortals[i][1], m_aPortals[i][2], CENTER_O); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetVisibility(VISIBILITY_ON); + for (int j = 0; j <= 2; ++j) + if (j != i) + m_creature->SummonCreature(NPC_SOLARIUM_PRIEST, m_aPortals[j][0], m_aPortals[j][1], m_aPortals[j][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - DoScriptText(SAY_SUMMON2, m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->SetVisibility(VISIBILITY_ON); - AppearDelay = true; - Phase3_Timer = 15000; - }else Phase3_Timer -= diff; - } - else if (Phase == 4) - { - //Fear_Timer - if (Fear_Timer < diff) - { - DoCastSpellIfCan(m_creature, SPELL_FEAR); - Fear_Timer = 20000; - }else Fear_Timer -= diff; + DoScriptText(SAY_SUMMON2, m_creature); - //VoidBolt_Timer - if (VoidBolt_Timer < diff) - { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOID_BOLT); - VoidBolt_Timer = 10000; - }else VoidBolt_Timer -= diff; - } + m_bIsAppearDelay = true; + m_uiPhaseThreeTimer = 15000; + } + else + m_uiPhaseThreeTimer -= uiDiff; - //When Solarian reaches 20% she will transform into a huge void walker. - if (Phase != 4 && m_creature->GetHealthPercent() < 20.0f) - { - Phase = 4; + break; - //To make sure she wont be invisible or not selecatble - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetVisibility(VISIBILITY_ON); + case PHASE_VOID: + // Fear Timer + if (m_uiFearTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature, SPELL_FEAR) == CAST_OK) + m_uiFearTimer = 20000; + } + else + m_uiFearTimer -= uiDiff; - DoScriptText(SAY_VOIDA, m_creature); - DoScriptText(SAY_VOIDB, m_creature); + // Void Bolt Timer + if (m_uiVoidBoltTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOID_BOLT) == CAST_OK) + m_uiVoidBoltTimer = 10000; + } + else + m_uiVoidBoltTimer -= uiDiff; - m_creature->SetArmor(WV_ARMOR); - m_creature->SetDisplayId(MODEL_VOIDWALKER); - m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize*2.5f); + DoMeleeAttackIfReady(); + break; } - - DoMeleeAttackIfReady(); } }; @@ -395,55 +437,61 @@ struct MANGOS_DLL_DECL mob_solarium_priestAI : public ScriptedAI ScriptedInstance* m_pInstance; - uint32 healTimer; - uint32 holysmiteTimer; - uint32 aoesilenceTimer; + uint32 m_uiHealTimer; + uint32 m_uiHolySmiteTimer; + uint32 m_uiAoESilenceTimer; void Reset() { - healTimer = 9000; - holysmiteTimer = 1; - aoesilenceTimer = 15000; + m_uiHealTimer = 9000; + m_uiHolySmiteTimer = 1; + m_uiAoESilenceTimer = 15000; } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (healTimer < diff) + if (m_uiHealTimer < uiDiff) { - Creature* target = NULL; + Creature* pTarget = NULL; switch(urand(0, 1)) { case 0: if (m_pInstance) - target = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ASTROMANCER)); + pTarget = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ASTROMANCER)); break; case 1: - target = m_creature; + pTarget = m_creature; break; } - if (target) + if (pTarget) { - DoCastSpellIfCan(target,SPELL_SOLARIUM_GREAT_HEAL); - healTimer = 9000; + DoCastSpellIfCan(pTarget, SPELL_SOLARIUM_GREAT_HEAL); + m_uiHealTimer = 9000; } - } else healTimer -= diff; + } + else + m_uiHealTimer -= uiDiff; - if (holysmiteTimer < diff) + if (m_uiHolySmiteTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SOLARIUM_HOLY_SMITE); - holysmiteTimer = 4000; - } else holysmiteTimer -= diff; + m_uiHolySmiteTimer = 4000; + } + else + m_uiHolySmiteTimer -= uiDiff; - if (aoesilenceTimer < diff) + if (m_uiAoESilenceTimer < uiDiff) { - DoCastSpellIfCan(m_creature->getVictim(), SPELL_SOLARIUM_ARCANE_TORRENT); - aoesilenceTimer = 13000; - } else aoesilenceTimer -= diff; + DoCastSpellIfCan(m_creature, SPELL_SOLARIUM_ARCANE_TORRENT); + m_uiAoESilenceTimer = 13000; + } + else + m_uiAoESilenceTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -461,14 +509,15 @@ CreatureAI* GetAI_boss_high_astromancer_solarian(Creature* pCreature) void AddSC_boss_high_astromancer_solarian() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_high_astromancer_solarian"; - newscript->GetAI = &GetAI_boss_high_astromancer_solarian; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_solarium_priest"; - newscript->GetAI = &GetAI_mob_solarium_priest; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_high_astromancer_solarian"; + pNewScript->GetAI = &GetAI_boss_high_astromancer_solarian; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_solarium_priest"; + pNewScript->GetAI = &GetAI_mob_solarium_priest; + pNewScript->RegisterSelf(); } diff --git a/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp b/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp index e46f38373..25bb72ab9 100644 --- a/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp +++ b/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -831,13 +831,11 @@ struct MANGOS_DLL_DECL boss_kaelthasAI : public ScriptedAI // Summon Phoenix if (m_uiPhoenix_Timer < uiDiff) { - if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + if (DoCastSpellIfCan(m_creature, SPELL_PHOENIX_ANIMATION) == CAST_OK) { - DoCastSpellIfCan(pTarget, SPELL_PHOENIX_ANIMATION); - DoScriptText(urand(0, 1) ? SAY_SUMMON_PHOENIX1 : SAY_SUMMON_PHOENIX2, pTarget); + DoScriptText(urand(0, 1) ? SAY_SUMMON_PHOENIX1 : SAY_SUMMON_PHOENIX2, m_creature); + m_uiPhoenix_Timer = 60000; } - - m_uiPhoenix_Timer = 60000; } else m_uiPhoenix_Timer -= uiDiff; @@ -928,10 +926,11 @@ struct MANGOS_DLL_DECL boss_kaelthasAI : public ScriptedAI m_creature->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], SPLINETYPE_NORMAL, SPLINEFLAG_NONE, 1); // 1) Kael'thas will portal the whole raid right into his body - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); + Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) { @@ -952,10 +951,11 @@ struct MANGOS_DLL_DECL boss_kaelthasAI : public ScriptedAI DoScriptText(urand(0, 1) ? SAY_GRAVITYLAPSE1 : SAY_GRAVITYLAPSE2, m_creature); // 2) At that point he will put a Gravity Lapse debuff on everyone - ThreatList const& tList = m_creature->getThreatManager().getThreatList(); - for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) + std::vector vGuids; + m_creature->FillGuidsListFromThreatList(vGuids); + for (std::vector::const_iterator i = vGuids.begin();i != vGuids.end(); ++i) { - if (Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid())) + if (Unit* pUnit = m_creature->GetMap()->GetUnit(*i)) { m_creature->CastSpell(pUnit, SPELL_KNOCKBACK, true); //Gravity lapse - needs an exception in Spell system to work @@ -1264,7 +1264,7 @@ struct MANGOS_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_a Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); //if in melee range - if (pUnit && pUnit->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) + if (pUnit && m_creature->CanReachWithMeleeAttack(pUnit)) { m_bInMeleeRange = true; pTarget = pUnit; diff --git a/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp b/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp index 8a9e582bd..4ec8ce6d6 100644 --- a/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp +++ b/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -87,7 +87,6 @@ struct MANGOS_DLL_DECL boss_void_reaverAI : public ScriptedAI void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); - m_creature->SetInCombatWithZone(); if (m_pInstance) m_pInstance->SetData(TYPE_VOIDREAVER, IN_PROGRESS); diff --git a/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp b/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp index 774bb6bc5..ab79be0e5 100644 --- a/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp +++ b/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_eye/the_eye.cpp b/scripts/outland/tempest_keep/the_eye/the_eye.cpp index ee0cc9874..d23e2279f 100644 --- a/scripts/outland/tempest_keep/the_eye/the_eye.cpp +++ b/scripts/outland/tempest_keep/the_eye/the_eye.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_eye/the_eye.h b/scripts/outland/tempest_keep/the_eye/the_eye.h index 879784122..347adfef1 100644 --- a/scripts/outland/tempest_keep/the_eye/the_eye.h +++ b/scripts/outland/tempest_keep/the_eye/the_eye.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp b/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp index 3d1ea8ca7..19ee13f08 100644 --- a/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp +++ b/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp b/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp index 66f1e17ff..c9a460ef8 100644 --- a/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp +++ b/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp b/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp index 72350069d..f490294c6 100644 --- a/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp +++ b/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp b/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp index 68228ee2c..3edeb1a2b 100644 --- a/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp +++ b/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/outland/tempest_keep/the_mechanar/mechanar.h b/scripts/outland/tempest_keep/the_mechanar/mechanar.h index 434b5bdfe..7752f871f 100644 --- a/scripts/outland/tempest_keep/the_mechanar/mechanar.h +++ b/scripts/outland/tempest_keep/the_mechanar/mechanar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/terokkar_forest.cpp b/scripts/outland/terokkar_forest.cpp index 9fbd15cb3..7e99beb25 100644 --- a/scripts/outland/terokkar_forest.cpp +++ b/scripts/outland/terokkar_forest.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,7 +17,7 @@ /* ScriptData SDName: Terokkar_Forest SD%Complete: 80 -SDComment: Quest support: 9889, 10009, 10873, 10896, 10446/10447, 10852, 10887, 10922, 11096. Skettis->Ogri'la Flight +SDComment: Quest support: 9889, 10009, 10873, 10896, 10446/10447, 10852, 10887, 10922, 11096, 11093, 10051, 10052. Skettis->Ogri'la Flight SDCategory: Terokkar Forest EndScriptData */ @@ -28,6 +28,7 @@ mob_rotting_forest_rager mob_netherweb_victim npc_akuno npc_floon +npc_hungry_nether_ray npc_letoll npc_mana_bomb_exp_trigger go_mana_bomb @@ -35,37 +36,42 @@ npc_skyguard_handler_deesak npc_slim go_veil_skith_cage npc_captive_child +npc_isla_starmane EndContentData */ #include "precompiled.h" #include "escort_ai.h" +#include "pet_ai.h" /*###### ## mob_unkor_the_ruthless ######*/ -#define SAY_SUBMIT -1000194 +enum +{ + SAY_SUBMIT = -1000194, -#define FACTION_HOSTILE 45 -#define FACTION_FRIENDLY 35 -#define QUEST_DONTKILLTHEFATONE 9889 + FACTION_HOSTILE = 45, + FACTION_FRIENDLY = 35, + QUEST_DONT_KILL_THE_FAT_ONE = 9889, -#define SPELL_PULVERIZE 2676 -//#define SPELL_QUID9889 32174 + SPELL_PULVERIZE = 2676, + // SPELL_QUID9889 = 32174, // TODO Make use of this quest-credit spell +}; struct MANGOS_DLL_DECL mob_unkor_the_ruthlessAI : public ScriptedAI { mob_unkor_the_ruthlessAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } - bool CanDoQuest; - uint32 UnkorUnfriendly_Timer; - uint32 Pulverize_Timer; + bool m_bCanDoQuest; + uint32 m_uiUnfriendlyTimer; + uint32 m_uiPulverizeTimer; void Reset() { - CanDoQuest = false; - UnkorUnfriendly_Timer = 0; - Pulverize_Timer = 3000; + m_bCanDoQuest = false; + m_uiUnfriendlyTimer = 0; + m_uiPulverizeTimer = 3000; m_creature->SetStandState(UNIT_STAND_STATE_STAND); m_creature->setFaction(FACTION_HOSTILE); } @@ -78,64 +84,68 @@ struct MANGOS_DLL_DECL mob_unkor_the_ruthlessAI : public ScriptedAI m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - UnkorUnfriendly_Timer = 60000; + m_uiUnfriendlyTimer = 60000; } - void DamageTaken(Unit *done_by, uint32 &damage) + void DamageTaken(Unit* pDealer, uint32 &uiDamage) { - if (done_by->GetTypeId() == TYPEID_PLAYER) - if ((m_creature->GetHealth()-damage)*100 / m_creature->GetMaxHealth() < 30) + if ((m_creature->GetHealth() - uiDamage)*100 / m_creature->GetMaxHealth() >= 30) + return; + + if (Player* pPlayer = pDealer->GetCharmerOrOwnerPlayerOrPlayerItself()) { - if (Group* pGroup = ((Player*)done_by)->GetGroup()) + if (Group* pGroup = pPlayer->GetGroup()) { - for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + for(GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { - Player *pGroupie = itr->getSource(); + Player* pGroupie = itr->getSource(); if (pGroupie && - pGroupie->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && - pGroupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) + pGroupie->GetQuestStatus(QUEST_DONT_KILL_THE_FAT_ONE) == QUEST_STATUS_INCOMPLETE && + pGroupie->GetReqKillOrCastCurrentCount(QUEST_DONT_KILL_THE_FAT_ONE, 18260) == 10) { - pGroupie->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); - if (!CanDoQuest) - CanDoQuest = true; + pGroupie->AreaExploredOrEventHappens(QUEST_DONT_KILL_THE_FAT_ONE); + if (!m_bCanDoQuest) + m_bCanDoQuest = true; } } - } else - if (((Player*)done_by)->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && - ((Player*)done_by)->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) + } + else if (pPlayer->GetQuestStatus(QUEST_DONT_KILL_THE_FAT_ONE) == QUEST_STATUS_INCOMPLETE && + pPlayer->GetReqKillOrCastCurrentCount(QUEST_DONT_KILL_THE_FAT_ONE, 18260) == 10) { - ((Player*)done_by)->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); - CanDoQuest = true; + pPlayer->AreaExploredOrEventHappens(QUEST_DONT_KILL_THE_FAT_ONE); + m_bCanDoQuest = true; } } } - void UpdateAI(const uint32 diff) + void UpdateAI(const uint32 uiDiff) { - if (CanDoQuest) + if (m_bCanDoQuest) { - if (!UnkorUnfriendly_Timer) + if (!m_uiUnfriendlyTimer) { //DoCastSpellIfCan(m_creature,SPELL_QUID9889); //not using spell for now DoNice(); } else { - if (UnkorUnfriendly_Timer <= diff) - { + if (m_uiUnfriendlyTimer <= uiDiff) EnterEvadeMode(); - }else UnkorUnfriendly_Timer -= diff; + else + m_uiUnfriendlyTimer -= uiDiff; } } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; - if (Pulverize_Timer < diff) + if (m_uiPulverizeTimer < uiDiff) { - DoCastSpellIfCan(m_creature,SPELL_PULVERIZE); - Pulverize_Timer = 9000; - }else Pulverize_Timer -= diff; + DoCastSpellIfCan(m_creature, SPELL_PULVERIZE); + m_uiPulverizeTimer = 9000; + } + else + m_uiPulverizeTimer -= uiDiff; DoMeleeAttackIfReady(); } @@ -150,21 +160,27 @@ CreatureAI* GetAI_mob_unkor_the_ruthless(Creature* pCreature) ## mob_infested_root_walker ######*/ +enum +{ + SPELL_SUMMON_WOOD_MITES = 39130, +}; + struct MANGOS_DLL_DECL mob_infested_root_walkerAI : public ScriptedAI { mob_infested_root_walkerAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} void Reset() { } - void DamageTaken(Unit *done_by, uint32 &damage) + void DamageTaken(Unit* pDealer, uint32 &uiDamage) { - if (done_by && done_by->GetTypeId() == TYPEID_PLAYER) - if (m_creature->GetHealth() <= damage) + if (m_creature->GetHealth() <= uiDamage) + if (pDealer->IsControlledByPlayer()) if (urand(0, 3)) //Summon Wood Mites - m_creature->CastSpell(m_creature,39130,true); + DoCastSpellIfCan(m_creature, SPELL_SUMMON_WOOD_MITES, CAST_TRIGGERED); } }; + CreatureAI* GetAI_mob_infested_root_walker(Creature* pCreature) { return new mob_infested_root_walkerAI(pCreature); @@ -174,19 +190,24 @@ CreatureAI* GetAI_mob_infested_root_walker(Creature* pCreature) ## mob_rotting_forest_rager ######*/ +enum +{ + SPELL_SUMMON_LOTS_OF_WOOD_MIGHTS = 39134, +}; + struct MANGOS_DLL_DECL mob_rotting_forest_ragerAI : public ScriptedAI { mob_rotting_forest_ragerAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} void Reset() { } - void DamageTaken(Unit *done_by, uint32 &damage) + void DamageTaken(Unit* pDealer, uint32 &uiDamage) { - if (done_by->GetTypeId() == TYPEID_PLAYER) - if (m_creature->GetHealth() <= damage) + if (m_creature->GetHealth() <= uiDamage) + if (pDealer->IsControlledByPlayer()) if (urand(0, 3)) //Summon Lots of Wood Mights - m_creature->CastSpell(m_creature,39134,true); + DoCastSpellIfCan(m_creature, SPELL_SUMMON_LOTS_OF_WOOD_MIGHTS, CAST_TRIGGERED); } }; CreatureAI* GetAI_mob_rotting_forest_rager(Creature* pCreature) @@ -222,17 +243,17 @@ struct MANGOS_DLL_DECL mob_netherweb_victimAI : public ScriptedAI void JustDied(Unit* pKiller) { - if (pKiller->GetTypeId() == TYPEID_PLAYER) + if (Player* pPlayer = pKiller->GetCharmerOrOwnerPlayerOrPlayerItself()) { - if (((Player*)pKiller)->GetQuestStatus(QUEST_TAKEN_IN_NIGHT) == QUEST_STATUS_INCOMPLETE) + if (pPlayer->GetQuestStatus(QUEST_TAKEN_IN_NIGHT) == QUEST_STATUS_INCOMPLETE) { if (!urand(0, 3)) { m_creature->SummonCreature(NPC_FREED_WARRIOR, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - ((Player*)pKiller)->KilledMonsterCredit(NPC_FREED_WARRIOR, m_creature->GetGUID()); + pPlayer->KilledMonsterCredit(NPC_FREED_WARRIOR, m_creature->GetObjectGuid()); } else - m_creature->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + m_creature->SummonCreature(netherwebVictims[urand(0, 5)], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); } } } @@ -348,7 +369,7 @@ CreatureAI* GetAI_npc_akuno(Creature* pCreature) } /*###### -## npc_floon +## npc_floon -- TODO move to EventAI and WorldDB (gossip) ######*/ enum @@ -448,7 +469,7 @@ bool GossipSelect_npc_floon(Player* pPlayer, Creature* pCreature, uint32 uiSende } /*###### -## npc_skyguard_handler_deesak +## npc_skyguard_handler_deesak -- TODO move to WorldDB (gossip) ######*/ #define GOSSIP_SKYGUARD "Fly me to Ogri'la please" @@ -476,6 +497,42 @@ bool GossipSelect_npc_skyguard_handler_deesak(Player* pPlayer, Creature* pCreatu return true; } +/*###### +## npc_hungry_nether_ray +######*/ + +enum +{ + EMOTE_FEED = -1000628, + NPC_BLACK_WARP_CHASER = 23219, + SPELL_FEED_CREDIT = 41427, // credit for quest 11093 +}; + +struct MANGOS_DLL_DECL npc_hungry_nether_rayAI : public ScriptedPetAI +{ + npc_hungry_nether_rayAI(Creature* pCreature) : ScriptedPetAI(pCreature) { Reset(); } + + void Reset() { } + + void OwnerKilledUnit(Unit* pVictim) + { + if (pVictim->GetTypeId() == TYPEID_UNIT && pVictim->GetEntry() == NPC_BLACK_WARP_CHASER) + { + // Distance expected? + if (m_creature->IsWithinDistInMap(pVictim, 10.0f)) + { + DoScriptText(EMOTE_FEED, m_creature); + m_creature->CastSpell(m_creature, SPELL_FEED_CREDIT, true); + } + } + } +}; + +CreatureAI* GetAI_npc_hungry_nether_ray(Creature* pCreature) +{ + return new npc_hungry_nether_rayAI(pCreature); +} + /*###### ## npc_letoll ######*/ @@ -834,7 +891,7 @@ CreatureAI* GetAI_npc_mana_bomb_exp_trigger(Creature* pCreature) ## go_mana_bomb ######*/ -bool GOHello_go_mana_bomb(Player* pPlayer, GameObject* pGo) +bool GOUse_go_mana_bomb(Player* pPlayer, GameObject* pGo) { if (Creature* pCreature = GetClosestCreatureWithEntry(pGo, NPC_MANA_BOMB_EXPL_TRIGGER, INTERACTION_DISTANCE)) { @@ -889,7 +946,7 @@ enum SAY_THANKS_4 = -1000593 }; -bool GOHello_veil_skith_cage(Player* pPlayer, GameObject* pGo) +bool GOUse_go_veil_skith_cage(Player* pPlayer, GameObject* pGo) { if (pPlayer->GetQuestStatus(QUEST_MISSING_FRIENDS) == QUEST_STATUS_INCOMPLETE) { @@ -897,7 +954,7 @@ bool GOHello_veil_skith_cage(Player* pPlayer, GameObject* pGo) GetCreatureListWithEntryInGrid(lChildrenList, pGo, NPC_CAPTIVE_CHILD, INTERACTION_DISTANCE); for(std::list::const_iterator itr = lChildrenList.begin(); itr != lChildrenList.end(); ++itr) { - pPlayer->KilledMonsterCredit(NPC_CAPTIVE_CHILD, (*itr)->GetGUID()); + pPlayer->KilledMonsterCredit(NPC_CAPTIVE_CHILD, (*itr)->GetObjectGuid()); switch(urand(0,3)) { case 0: DoScriptText(SAY_THANKS_1, *itr); break; @@ -931,78 +988,241 @@ CreatureAI* GetAI_npc_captive_child(Creature* pCreature) return new npc_captive_child(pCreature); } +/*##### +## npc_isla_starmane +## +## TODO: Verify SpellIDs, Research Timers, Finish Text? +#####*/ + +enum +{ + QUEST_ESCAPE_FROM_FIREWING_POINT_A = 10051, + QUEST_ESCAPE_FROM_FIREWING_POINT_H = 10052, + + SAY_ISLA_PERIODIC_1 = -1000629, + SAY_ISLA_PERIODIC_2 = -1000630, + SAY_ISLA_PERIODIC_3 = -1000631, + SAY_ISLA_START = -1000632, + SAY_ISLA_WAITING = -1000633, + SAY_ISLA_LEAVE_BUILDING = -1000634, + + GO_CAGE = 182794, + + SPELL_ENTANGLING_ROOTS = 33844, // these spell IDs seem to deal not enough dmg, but are linked + SPELL_MOONFIRE = 15798, + SPELL_WRATH = 9739, + SPELL_TRAVELFORM = 32447 // guesswork +}; + +struct MANGOS_DLL_DECL npc_isla_starmaneAI : public npc_escortAI +{ + npc_isla_starmaneAI(Creature* pCreature) : npc_escortAI(pCreature) + { + Reset(); + } + + uint32 m_uiPeriodicTalkTimer; + uint32 m_uiEntanglingRootsTimer; + uint32 m_uiMoonfireTimer; + uint32 m_uiWrathTimer; + + void Reset() + { + m_uiPeriodicTalkTimer = urand(20000, 40000); + m_uiEntanglingRootsTimer = 100; + m_uiMoonfireTimer = 1600; + m_uiWrathTimer = 2000; + + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + } + + void JustStartedEscort() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + DoScriptText(SAY_ISLA_START, m_creature); + if (GameObject* pCage = GetClosestGameObjectWithEntry(m_creature, GO_CAGE, 2*INTERACTION_DISTANCE)) + pCage->Use(m_creature); + } + + void WaypointStart(uint32 uiPointId) + { + switch (uiPointId) + { + case 7: DoScriptText(SAY_ISLA_LEAVE_BUILDING, m_creature); break; + case 68: DoCastSpellIfCan(m_creature, SPELL_TRAVELFORM); break; + } + } + + void WaypointReached(uint32 uiPointId) + { + switch(uiPointId) + { + case 6: + DoScriptText(SAY_ISLA_WAITING, m_creature); + break; + case 61: + if (Player* pPlayer = GetPlayerForEscort()) + pPlayer->GroupEventHappens(pPlayer->GetTeam() == ALLIANCE ? QUEST_ESCAPE_FROM_FIREWING_POINT_A : QUEST_ESCAPE_FROM_FIREWING_POINT_H, m_creature); + break; + case 67: + if (Player* pPlayer = GetPlayerForEscort()) + m_creature->SetFacingToObject(pPlayer); + m_creature->HandleEmote(EMOTE_ONESHOT_WAVE); + break; + } + } + + void UpdateEscortAI(const uint32 uiDiff) + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + if (m_uiPeriodicTalkTimer < uiDiff) + { + m_uiPeriodicTalkTimer = urand(30000, 60000); + switch (urand(0, 2)) + { + case 0: DoScriptText(SAY_ISLA_PERIODIC_1, m_creature); break; + case 1: DoScriptText(SAY_ISLA_PERIODIC_2, m_creature); break; + case 2: DoScriptText(SAY_ISLA_PERIODIC_3, m_creature); break; + } + } + else + m_uiPeriodicTalkTimer -= uiDiff; + } + + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiEntanglingRootsTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ENTANGLING_ROOTS) == CAST_OK) + m_uiEntanglingRootsTimer = urand(8000, 16000); + } + else + m_uiEntanglingRootsTimer -= uiDiff; + + if (m_uiMoonfireTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MOONFIRE) == CAST_OK) + m_uiMoonfireTimer = urand(6000, 12000); + } + else + m_uiMoonfireTimer -= uiDiff; + + if (m_uiWrathTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_WRATH) == CAST_OK) + m_uiWrathTimer = 2000; + } + else + m_uiWrathTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } +}; + +bool QuestAccept_npc_isla_starmane(Player* pPlayer, Creature* pCreature, const Quest* pQuest) +{ + if (pQuest->GetQuestId() == QUEST_ESCAPE_FROM_FIREWING_POINT_A || pQuest->GetQuestId() == QUEST_ESCAPE_FROM_FIREWING_POINT_H) + { + if (npc_isla_starmaneAI* pEscortAI = dynamic_cast(pCreature->AI())) + { + pCreature->setFaction(pPlayer->GetTeam() == ALLIANCE ? FACTION_ESCORT_A_NEUTRAL_ACTIVE : FACTION_ESCORT_H_NEUTRAL_ACTIVE); + pEscortAI->Start(false, pPlayer->GetGUID(), pQuest); + } + } + return true; +} + +CreatureAI* GetAI_npc_isla_starmane(Creature* pCreature) +{ + return new npc_isla_starmaneAI(pCreature); +} + void AddSC_terokkar_forest() { - Script *newscript; - - newscript = new Script; - newscript->Name = "mob_unkor_the_ruthless"; - newscript->GetAI = &GetAI_mob_unkor_the_ruthless; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_infested_root_walker"; - newscript->GetAI = &GetAI_mob_infested_root_walker; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_rotting_forest_rager"; - newscript->GetAI = &GetAI_mob_rotting_forest_rager; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_netherweb_victim"; - newscript->GetAI = &GetAI_mob_netherweb_victim; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_akuno"; - newscript->GetAI = &GetAI_npc_akuno; - newscript->pQuestAccept = &QuestAccept_npc_akuno; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_floon"; - newscript->GetAI = &GetAI_npc_floon; - newscript->pGossipHello = &GossipHello_npc_floon; - newscript->pGossipSelect = &GossipSelect_npc_floon; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_letoll"; - newscript->GetAI = &GetAI_npc_letoll; - newscript->pQuestAccept = &QuestAccept_npc_letoll; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_mana_bomb_exp_trigger"; - newscript->GetAI = &GetAI_npc_mana_bomb_exp_trigger; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "go_mana_bomb"; - newscript->pGOHello = &GOHello_go_mana_bomb; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_skyguard_handler_deesak"; - newscript->pGossipHello = &GossipHello_npc_skyguard_handler_deesak; - newscript->pGossipSelect = &GossipSelect_npc_skyguard_handler_deesak; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_slim"; - newscript->pGossipHello = &GossipHello_npc_slim; - newscript->pGossipSelect = &GossipSelect_npc_slim; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "go_veil_skith_cage"; - newscript->pGOHello = &GOHello_veil_skith_cage; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_captive_child"; - newscript->GetAI = &GetAI_npc_captive_child; - newscript->RegisterSelf(); + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "mob_unkor_the_ruthless"; + pNewScript->GetAI = &GetAI_mob_unkor_the_ruthless; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_infested_root_walker"; + pNewScript->GetAI = &GetAI_mob_infested_root_walker; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_rotting_forest_rager"; + pNewScript->GetAI = &GetAI_mob_rotting_forest_rager; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "mob_netherweb_victim"; + pNewScript->GetAI = &GetAI_mob_netherweb_victim; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_akuno"; + pNewScript->GetAI = &GetAI_npc_akuno; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_akuno; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_floon"; + pNewScript->GetAI = &GetAI_npc_floon; + pNewScript->pGossipHello = &GossipHello_npc_floon; + pNewScript->pGossipSelect = &GossipSelect_npc_floon; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_hungry_nether_ray"; + pNewScript->GetAI = &GetAI_npc_hungry_nether_ray; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_letoll"; + pNewScript->GetAI = &GetAI_npc_letoll; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_letoll; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_mana_bomb_exp_trigger"; + pNewScript->GetAI = &GetAI_npc_mana_bomb_exp_trigger; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "go_mana_bomb"; + pNewScript->pGOUse = &GOUse_go_mana_bomb; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_skyguard_handler_deesak"; + pNewScript->pGossipHello = &GossipHello_npc_skyguard_handler_deesak; + pNewScript->pGossipSelect = &GossipSelect_npc_skyguard_handler_deesak; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_slim"; + pNewScript->pGossipHello = &GossipHello_npc_slim; + pNewScript->pGossipSelect = &GossipSelect_npc_slim; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "go_veil_skith_cage"; + pNewScript->pGOUse = &GOUse_go_veil_skith_cage; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_captive_child"; + pNewScript->GetAI = &GetAI_npc_captive_child; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_isla_starmane"; + pNewScript->GetAI = &GetAI_npc_isla_starmane; + pNewScript->pQuestAcceptNPC = &QuestAccept_npc_isla_starmane; + pNewScript->RegisterSelf(); } diff --git a/scripts/outland/zangarmarsh.cpp b/scripts/outland/zangarmarsh.cpp index 9ef626cb5..c037ccc57 100644 --- a/scripts/outland/zangarmarsh.cpp +++ b/scripts/outland/zangarmarsh.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -409,7 +409,7 @@ void AddSC_zangarmarsh() newscript = new Script; newscript->Name = "npc_kayra_longmane"; newscript->GetAI = &GetAI_npc_kayra_longmane; - newscript->pQuestAccept = &QuestAccept_npc_kayra_longmane; + newscript->pQuestAcceptNPC = &QuestAccept_npc_kayra_longmane; newscript->RegisterSelf(); newscript = new Script; diff --git a/scripts/world/areatrigger_scripts.cpp b/scripts/world/areatrigger_scripts.cpp index 2babab81f..7ed772bfd 100644 --- a/scripts/world/areatrigger_scripts.cpp +++ b/scripts/world/areatrigger_scripts.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/world/boss_emeriss.cpp b/scripts/world/boss_emeriss.cpp index 44727b1c2..271f47308 100644 --- a/scripts/world/boss_emeriss.cpp +++ b/scripts/world/boss_emeriss.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/world/boss_lethon.cpp b/scripts/world/boss_lethon.cpp index a524dc877..4c82f642a 100644 --- a/scripts/world/boss_lethon.cpp +++ b/scripts/world/boss_lethon.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -22,3 +22,7 @@ SDCategory: Bosses EndScriptData */ #include "precompiled.h" + +void AddSC_boss_lethon() +{ +} diff --git a/scripts/world/boss_taerar.cpp b/scripts/world/boss_taerar.cpp index a41bc109b..1ec9db307 100644 --- a/scripts/world/boss_taerar.cpp +++ b/scripts/world/boss_taerar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/world/boss_ysondre.cpp b/scripts/world/boss_ysondre.cpp index 921ba38f2..b225649ba 100644 --- a/scripts/world/boss_ysondre.cpp +++ b/scripts/world/boss_ysondre.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/world/go_scripts.cpp b/scripts/world/go_scripts.cpp index e67af1f05..9fd81e944 100644 --- a/scripts/world/go_scripts.cpp +++ b/scripts/world/go_scripts.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -17,15 +17,12 @@ /* ScriptData SDName: GO_Scripts SD%Complete: 100 -SDComment: Quest support: 4285,4287,4288(crystal pylons), 4296, 5088, 5097, 5098, 6481, 10990, 10991, 10992, 14092/14076. Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089 +SDComment: Quest support: 4296, 5088, 5097, 5098, 5381, 6481, 10990, 10991, 10992, 12557, 14092/14076. Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089 SDCategory: Game Objects EndScriptData */ /* ContentData go_cat_figurine (the "trap" version of GO, two different exist) -go_northern_crystal_pylon -go_eastern_crystal_pylon -go_western_crystal_pylon go_barov_journal go_ethereum_prison go_ethereum_stasis @@ -41,6 +38,7 @@ go_tele_to_dalaran_crystal go_tele_to_violet_stand go_andorhal_tower go_scourge_enclosure +go_lab_work_reagents EndContentData */ #include "precompiled.h" @@ -54,65 +52,12 @@ enum SPELL_SUMMON_GHOST_SABER = 5968, }; -bool GOHello_go_cat_figurine(Player* pPlayer, GameObject* pGo) +bool GOUse_go_cat_figurine(Player* pPlayer, GameObject* pGo) { pPlayer->CastSpell(pPlayer, SPELL_SUMMON_GHOST_SABER, true); return false; } -/*###### -## go_crystal_pylons (3x) -######*/ - -enum -{ - QUEST_THE_NORTHERN_PYLON = 4285, - QUEST_THE_EASTERN_PYLON = 4287, - QUEST_THE_WESTERN_PYLON = 4288 -}; - -bool GOHello_go_northern_crystal_pylon(Player* pPlayer, GameObject* pGo) -{ - if (pGo->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - { - pPlayer->PrepareQuestMenu(pGo->GetGUID()); - pPlayer->SendPreparedQuest(pGo->GetGUID()); - } - - if (pPlayer->GetQuestStatus(QUEST_THE_NORTHERN_PYLON) == QUEST_STATUS_INCOMPLETE) - pPlayer->AreaExploredOrEventHappens(QUEST_THE_NORTHERN_PYLON); - - return true; -} - -bool GOHello_go_eastern_crystal_pylon(Player* pPlayer, GameObject* pGo) -{ - if (pGo->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - { - pPlayer->PrepareQuestMenu(pGo->GetGUID()); - pPlayer->SendPreparedQuest(pGo->GetGUID()); - } - - if (pPlayer->GetQuestStatus(QUEST_THE_EASTERN_PYLON) == QUEST_STATUS_INCOMPLETE) - pPlayer->AreaExploredOrEventHappens(QUEST_THE_EASTERN_PYLON); - - return true; -} - -bool GOHello_go_western_crystal_pylon(Player* pPlayer, GameObject* pGo) -{ - if (pGo->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - { - pPlayer->PrepareQuestMenu(pGo->GetGUID()); - pPlayer->SendPreparedQuest(pGo->GetGUID()); - } - - if (pPlayer->GetQuestStatus(QUEST_THE_WESTERN_PYLON) == QUEST_STATUS_INCOMPLETE) - pPlayer->AreaExploredOrEventHappens(QUEST_THE_WESTERN_PYLON); - - return true; -} - /*###### ## go_barov_journal ######*/ @@ -123,7 +68,7 @@ enum SPELL_LEARN_FELCLOTH_BAG = 26095 }; -bool GOHello_go_barov_journal(Player* pPlayer, GameObject* pGo) +bool GOUse_go_barov_journal(Player* pPlayer, GameObject* pGo) { if (pPlayer->HasSkill(SKILL_TAILORING) && pPlayer->GetBaseSkillValue(SKILL_TAILORING) >= 280 && !pPlayer->HasSpell(SPELL_TAILOR_FELCLOTH_BAG)) { @@ -159,7 +104,7 @@ const uint32 uiNpcPrisonEntry[] = 20783, 20784, 20785, 20786, 20788, 20789, 20790 //bad guys }; -bool GOHello_go_ethereum_prison(Player* pPlayer, GameObject* pGo) +bool GOUse_go_ethereum_prison(Player* pPlayer, GameObject* pGo) { uint8 uiRandom = urand(0, (sizeof(uiNpcPrisonEntry) / sizeof(uint32)) -1); @@ -203,7 +148,7 @@ const uint32 uiNpcStasisEntry[] = 22825, 20888, 22827, 22826, 22828 }; -bool GOHello_go_ethereum_stasis(Player* pPlayer, GameObject* pGo) +bool GOUse_go_ethereum_stasis(Player* pPlayer, GameObject* pGo) { uint8 uiRandom = urand(0, (sizeof(uiNpcStasisEntry) / sizeof(uint32)) -1); @@ -224,7 +169,7 @@ enum SPELL_LEARN_FIELD_REPAIR_BOT_74A = 22864 }; -bool GOHello_go_field_repair_bot_74A(Player* pPlayer, GameObject* pGo) +bool GOUse_go_field_repair_bot_74A(Player* pPlayer, GameObject* pGo) { if (pPlayer->HasSkill(SKILL_ENGINEERING) && pPlayer->GetBaseSkillValue(SKILL_ENGINEERING) >= 300 && !pPlayer->HasSpell(SPELL_ENGINEER_FIELD_REPAIR_BOT_74A)) pPlayer->CastSpell(pPlayer, SPELL_LEARN_FIELD_REPAIR_BOT_74A, false); @@ -241,7 +186,7 @@ enum NPC_STILLBLADE = 17716, }; -bool GOHello_go_gilded_brazier(Player* pPlayer, GameObject* pGO) +bool GOUse_go_gilded_brazier(Player* pPlayer, GameObject* pGO) { if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER) { @@ -262,7 +207,7 @@ enum NPC_JUMP_A_TRON = 19041 }; -bool GOHello_go_jump_a_tron(Player* pPlayer, GameObject* pGo) +bool GOUse_go_jump_a_tron(Player* pPlayer, GameObject* pGo) { if (Creature* pCreature = GetClosestCreatureWithEntry(pGo, NPC_JUMP_A_TRON, INTERACTION_DISTANCE)) pCreature->CastSpell(pPlayer, SPELL_JUMP_A_TRON, false); @@ -281,7 +226,7 @@ enum SPELL_SUMMON_MARAUDER = 66491, }; -bool GOHello_go_mysterious_snow_mound(Player* pPlayer, GameObject* pGo) +bool GOUse_go_mysterious_snow_mound(Player* pPlayer, GameObject* pGo) { if (urand(0,1)) { @@ -310,7 +255,7 @@ enum SPELL_TELEPORT_TO_BWL = 23460 }; -bool GOHello_go_orb_of_command(Player* pPlayer, GameObject* pGo) +bool GOUse_go_orb_of_command(Player* pPlayer, GameObject* pGo) { if (pPlayer->GetQuestRewardStatus(QUEST_BLACKHANDS_COMMAND)) pPlayer->CastSpell(pPlayer, SPELL_TELEPORT_TO_BWL, true); @@ -327,7 +272,7 @@ enum NPC_GOGGEROC = 11920 }; -bool GOHello_go_resonite_cask(Player* pPlayer, GameObject* pGO) +bool GOUse_go_resonite_cask(Player* pPlayer, GameObject* pGO) { if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER) pGO->SummonCreature(NPC_GOGGEROC, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000); @@ -344,7 +289,7 @@ enum NPC_ARIKARA = 10882, }; -bool GOHello_go_sacred_fire_of_life(Player* pPlayer, GameObject* pGO) +bool GOUse_go_sacred_fire_of_life(Player* pPlayer, GameObject* pGO) { if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER) pPlayer->SummonCreature(NPC_ARIKARA, -5008.338f, -2118.894f, 83.657f, 0.874f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); @@ -366,7 +311,7 @@ enum GO_SHRINE_FALCON = 185553 }; -bool GOHello_go_shrine_of_the_birds(Player* pPlayer, GameObject* pGo) +bool GOUse_go_shrine_of_the_birds(Player* pPlayer, GameObject* pGo) { uint32 uiBirdEntry = 0; @@ -402,7 +347,7 @@ enum SPELL_LEARN_GURUBASHI_MOJO_MADNESS = 24267 }; -bool GOHello_go_tablet_of_madness(Player* pPlayer, GameObject* pGo) +bool GOUse_go_tablet_of_madness(Player* pPlayer, GameObject* pGo) { if (pPlayer->HasSkill(SKILL_ALCHEMY) && pPlayer->GetSkillValue(SKILL_ALCHEMY) >= 300 && !pPlayer->HasSpell(SPELL_ALCHEMY_GURUBASHI_MOJO_MADNESS)) pPlayer->CastSpell(pPlayer, SPELL_LEARN_GURUBASHI_MOJO_MADNESS, false); @@ -415,7 +360,7 @@ bool GOHello_go_tablet_of_madness(Player* pPlayer, GameObject* pGo) ######*/ //TODO: use gossip option ("Transcript the Tablet") instead, if Mangos adds support. -bool GOHello_go_tablet_of_the_seven(Player* pPlayer, GameObject* pGo) +bool GOUse_go_tablet_of_the_seven(Player* pPlayer, GameObject* pGo) { if (pGo->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) return true; @@ -436,7 +381,7 @@ enum QUEST_TELE_CRYSTAL_FLAG = 12845 }; -bool GOHello_go_tele_to_dalaran_crystal(Player* pPlayer, GameObject* pGo) +bool GOUse_go_tele_to_dalaran_crystal(Player* pPlayer, GameObject* pGo) { if (pPlayer->GetQuestRewardStatus(QUEST_TELE_CRYSTAL_FLAG)) return false; @@ -449,7 +394,7 @@ bool GOHello_go_tele_to_dalaran_crystal(Player* pPlayer, GameObject* pGo) ## go_tele_to_violet_stand ######*/ -bool GOHello_go_tele_to_violet_stand(Player* pPlayer, GameObject* pGo) +bool GOUse_go_tele_to_violet_stand(Player* pPlayer, GameObject* pGo) { if (pPlayer->GetQuestRewardStatus(QUEST_LEARN_LEAVE_RETURN) || pPlayer->GetQuestStatus(QUEST_LEARN_LEAVE_RETURN) == QUEST_STATUS_INCOMPLETE) return false; @@ -465,7 +410,7 @@ enum float Position[4] = {-327.99f, 221.74f, -20.31f, 3.87f}; -bool GOHello_go_blood_filled_orb(Player* pPlayer, GameObject* pGo) +bool GOUse_go_blood_filled_orb(Player* pPlayer, GameObject* pGo) { if (Creature* pZelemar = pGo->SummonCreature(NPC_ZELEMAR_THE_WRATHFULL, Position[0], Position[1], Position[2], Position[3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) { @@ -493,7 +438,7 @@ enum GO_ANDORHAL_TOWER_4 = 176097 }; -bool GOHello_go_andorhal_tower(Player* pPlayer, GameObject* pGo) +bool GOUse_go_andorhal_tower(Player* pPlayer, GameObject* pGo) { if (pPlayer->GetQuestStatus(QUEST_ALL_ALONG_THE_WATCHTOWERS_ALLIANCE) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(QUEST_ALL_ALONG_THE_WATCHTOWERS_HORDE) == QUEST_STATUS_INCOMPLETE) { @@ -522,7 +467,7 @@ enum }; -bool GOHello_go_scourge_enclosure(Player* pPlayer, GameObject* pGo) +bool GOUse_go_scourge_enclosure(Player* pPlayer, GameObject* pGo) { std::list m_lResearchersList; GetCreatureListWithEntryInGrid(m_lResearchersList, pGo, NPC_GYMER_LOCK_DUMMY, 15.0f); @@ -537,117 +482,175 @@ bool GOHello_go_scourge_enclosure(Player* pPlayer, GameObject* pGo) return true; } -void AddSC_go_scripts() +/*###### +## go_lab_work_reagents +######*/ + +enum { - Script* pNewScript; + QUEST_LAB_WORK = 12557, - pNewScript = new Script; - pNewScript->Name = "go_cat_figurine"; - pNewScript->pGOHello = &GOHello_go_cat_figurine; - pNewScript->RegisterSelf(); + SPELL_WIRHERED_BATWING_KILL_CREDIT = 51226, + SPELL_MUDDY_MIRE_MAGGOT_KILL_CREDIT = 51227, + SPELL_AMBERSEED_KILL_CREDIT = 51228, + SPELL_CHILLED_SERPENT_MUCUS_KILL_CREDIT = 51229, - pNewScript = new Script; - pNewScript->Name = "go_northern_crystal_pylon"; - pNewScript->pGOHello = &GOHello_go_northern_crystal_pylon; - pNewScript->RegisterSelf(); + GO_AMBERSEED = 190459, + GO_CHILLED_SERPENT_MUCUS = 190462, + GO_WITHERED_BATWING = 190473, + GO_MUDDY_MIRE_MAGGOTS = 190478, +}; - pNewScript = new Script; - pNewScript->Name = "go_eastern_crystal_pylon"; - pNewScript->pGOHello = &GOHello_go_eastern_crystal_pylon; - pNewScript->RegisterSelf(); +bool GOUse_go_lab_work_reagents(Player* pPlayer, GameObject* pGo) +{ + if (pPlayer->GetQuestStatus(QUEST_LAB_WORK) == QUEST_STATUS_INCOMPLETE) + { + uint32 uiCreditSpellId = 0; + switch (pGo->GetEntry()) + { + case GO_AMBERSEED: uiCreditSpellId = SPELL_AMBERSEED_KILL_CREDIT; break; + case GO_CHILLED_SERPENT_MUCUS: uiCreditSpellId = SPELL_CHILLED_SERPENT_MUCUS_KILL_CREDIT; break; + case GO_WITHERED_BATWING: uiCreditSpellId = SPELL_WIRHERED_BATWING_KILL_CREDIT; break; + case GO_MUDDY_MIRE_MAGGOTS: uiCreditSpellId = SPELL_MUDDY_MIRE_MAGGOT_KILL_CREDIT; break; + } + + if (uiCreditSpellId) + pPlayer->CastSpell(pPlayer, uiCreditSpellId, true); + } + + return false; +} + +/*###### +## go_hand_of_iruxos_crystal +######*/ + +/* TODO + * Actually this script is extremely vague, but as long as there is no valid information + * hidden in some dark places, this will be the best we can do here :( + * Do not consider this a well proven script. + */ + +enum +{ + // QUEST_HAND_OF_IRUXOS = 5381, + NPC_IRUXOS = 11876, +}; + +bool GOUse_go_hand_of_iruxos_crystal(Player* pPlayer, GameObject* pGo) +{ + if (Creature* pIruxos = pGo->SummonCreature(NPC_IRUXOS, 0.0f, 0.0f, 0.0f, pPlayer->GetOrientation() + M_PI_F, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000)) + pIruxos->AI()->AttackStart(pPlayer); + + return false; +} + +void AddSC_go_scripts() +{ + Script* pNewScript; pNewScript = new Script; - pNewScript->Name = "go_western_crystal_pylon"; - pNewScript->pGOHello = &GOHello_go_western_crystal_pylon; + pNewScript->Name = "go_cat_figurine"; + pNewScript->pGOUse = &GOUse_go_cat_figurine; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_barov_journal"; - pNewScript->pGOHello = &GOHello_go_barov_journal; + pNewScript->pGOUse = &GOUse_go_barov_journal; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_ethereum_prison"; - pNewScript->pGOHello = &GOHello_go_ethereum_prison; + pNewScript->pGOUse = &GOUse_go_ethereum_prison; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_ethereum_stasis"; - pNewScript->pGOHello = &GOHello_go_ethereum_stasis; + pNewScript->pGOUse = &GOUse_go_ethereum_stasis; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_field_repair_bot_74A"; - pNewScript->pGOHello = &GOHello_go_field_repair_bot_74A; + pNewScript->pGOUse = &GOUse_go_field_repair_bot_74A; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_gilded_brazier"; - pNewScript->pGOHello = &GOHello_go_gilded_brazier; + pNewScript->pGOUse = &GOUse_go_gilded_brazier; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_jump_a_tron"; - pNewScript->pGOHello = &GOHello_go_jump_a_tron; + pNewScript->pGOUse = &GOUse_go_jump_a_tron; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_mysterious_snow_mound"; - pNewScript->pGOHello = &GOHello_go_mysterious_snow_mound; + pNewScript->pGOUse = &GOUse_go_mysterious_snow_mound; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_orb_of_command"; - pNewScript->pGOHello = &GOHello_go_orb_of_command; + pNewScript->pGOUse = &GOUse_go_orb_of_command; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_resonite_cask"; - pNewScript->pGOHello = &GOHello_go_resonite_cask; + pNewScript->pGOUse = &GOUse_go_resonite_cask; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_sacred_fire_of_life"; - pNewScript->pGOHello = &GOHello_go_sacred_fire_of_life; + pNewScript->pGOUse = &GOUse_go_sacred_fire_of_life; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_shrine_of_the_birds"; - pNewScript->pGOHello = &GOHello_go_shrine_of_the_birds; + pNewScript->pGOUse = &GOUse_go_shrine_of_the_birds; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_tablet_of_madness"; - pNewScript->pGOHello = &GOHello_go_tablet_of_madness; + pNewScript->pGOUse = &GOUse_go_tablet_of_madness; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_tablet_of_the_seven"; - pNewScript->pGOHello = &GOHello_go_tablet_of_the_seven; + pNewScript->pGOUse = &GOUse_go_tablet_of_the_seven; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_tele_to_dalaran_crystal"; - pNewScript->pGOHello = &GOHello_go_tele_to_dalaran_crystal; + pNewScript->pGOUse = &GOUse_go_tele_to_dalaran_crystal; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_tele_to_violet_stand"; - pNewScript->pGOHello = &GOHello_go_tele_to_violet_stand; + pNewScript->pGOUse = &GOUse_go_tele_to_violet_stand; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_blood_filled_orb"; - pNewScript->pGOHello = &GOHello_go_blood_filled_orb; + pNewScript->pGOUse = &GOUse_go_blood_filled_orb; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_andorhal_tower"; - pNewScript->pGOHello = &GOHello_go_andorhal_tower; + pNewScript->pGOUse = &GOUse_go_andorhal_tower; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "go_scourge_enclosure"; - pNewScript->pGOHello = &GOHello_go_scourge_enclosure; + pNewScript->pGOUse = &GOUse_go_scourge_enclosure; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "go_lab_work_reagents"; + pNewScript->pGOUse = &GOUse_go_lab_work_reagents; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "go_hand_of_iruxos_crystal"; + pNewScript->pGOUse = &GOUse_go_hand_of_iruxos_crystal; pNewScript->RegisterSelf(); } diff --git a/scripts/world/guards.cpp b/scripts/world/guards.cpp index e788be4e1..472d6bd9b 100644 --- a/scripts/world/guards.cpp +++ b/scripts/world/guards.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/world/item_scripts.cpp b/scripts/world/item_scripts.cpp index 277d80cf3..4474aa709 100644 --- a/scripts/world/item_scripts.cpp +++ b/scripts/world/item_scripts.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 diff --git a/scripts/world/mob_generic_creature.cpp b/scripts/world/mob_generic_creature.cpp index 531e36ecc..39f6d0e51 100644 --- a/scripts/world/mob_generic_creature.cpp +++ b/scripts/world/mob_generic_creature.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -42,7 +42,7 @@ struct MANGOS_DLL_DECL generic_creatureAI : public ScriptedAI void Aggro(Unit *who) { - if (!m_creature->IsWithinDistInMap(who, ATTACK_DISTANCE)) + if (!m_creature->CanReachWithMeleeAttack(who)) { IsSelfRooted = true; } @@ -80,11 +80,15 @@ struct MANGOS_DLL_DECL generic_creatureAI : public ScriptedAI if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; + // Return if we already cast a spell + if (m_creature->IsNonMeleeSpellCasted(false)) + return; + //If we are within range melee the target - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) { - //Make sure our attack is ready and we arn't currently casting - if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) + //Make sure our attack is ready + if (m_creature->isAttackReady()) { bool Healing = false; SpellEntry const *info = NULL; @@ -114,44 +118,40 @@ struct MANGOS_DLL_DECL generic_creatureAI : public ScriptedAI } else { - //Only run this code if we arn't already casting - if (!m_creature->IsNonMeleeSpellCasted(false)) - { - bool Healing = false; - SpellEntry const *info = NULL; + bool Healing = false; + SpellEntry const *info = NULL; - //Select a healing spell if less than 30% hp ONLY 33% of the time - if (m_creature->GetHealthPercent() < 30.0f && !urand(0, 2)) - info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING); + //Select a healing spell if less than 30% hp ONLY 33% of the time + if (m_creature->GetHealthPercent() < 30.0f && !urand(0, 2)) + info = 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 (info) Healing = true; - else info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, ATTACK_DISTANCE, 0, SELECT_EFFECT_DONTCARE); + if (info) Healing = true; + else info = 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 (info && !GlobalCooldown) + if (info && !GlobalCooldown) + { + //If we are currently moving stop us and set the movement generator + if (!IsSelfRooted) { - //If we are currently moving stop us and set the movement generator - if (!IsSelfRooted) - { - IsSelfRooted = true; - } + IsSelfRooted = true; + } - //Cast spell - if (Healing) DoCastSpell(m_creature,info); - else DoCastSpell(m_creature->getVictim(),info); + //Cast spell + if (Healing) DoCastSpell(m_creature,info); + else DoCastSpell(m_creature->getVictim(),info); - //Set our global cooldown - GlobalCooldown = GENERIC_CREATURE_COOLDOWN; + //Set our global cooldown + GlobalCooldown = GENERIC_CREATURE_COOLDOWN; - }//If no spells available and we arn't moving run to target - else if (IsSelfRooted) - { - //Cancel our current spell and then allow movement agian - m_creature->InterruptNonMeleeSpells(false); - IsSelfRooted = false; - } + }//If no spells available and we arn't moving run to target + else if (IsSelfRooted) + { + //Cancel our current spell and then allow movement agian + m_creature->InterruptNonMeleeSpells(false); + IsSelfRooted = false; } } } diff --git a/scripts/world/npc_professions.cpp b/scripts/world/npc_professions.cpp index 305005a78..c7f9325d4 100644 --- a/scripts/world/npc_professions.cpp +++ b/scripts/world/npc_professions.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -811,138 +811,6 @@ bool GossipSelect_npc_prof_blacksmith(Player* pPlayer, Creature* pCreature, uint return true; }*/ -/*### -# engineering trinkets -###*/ - -enum -{ - NPC_ZAP = 14742, - NPC_JHORDY = 14743, - NPC_KABLAM = 21493, - NPC_SMILES = 21494, - - SPELL_LEARN_TO_EVERLOOK = 23490, - SPELL_LEARN_TO_GADGET = 23491, - SPELL_LEARN_TO_AREA52 = 36956, - SPELL_LEARN_TO_TOSHLEY = 36957, - - SPELL_TO_EVERLOOK = 23486, - SPELL_TO_GADGET = 23489, - SPELL_TO_AREA52 = 36954, - SPELL_TO_TOSHLEY = 36955, - - ITEM_GNOMISH_CARD = 10790, - ITEM_GOBLIN_CARD = 10791 -}; - -#define GOSSIP_ITEM_ZAP "[PH] Unknown" -#define GOSSIP_ITEM_JHORDY "I must build a beacon for this marvelous device!" -#define GOSSIP_ITEM_KABLAM "[PH] Unknown" -#define GOSSIP_ITEM_SMILES "[PH] Unknown" - -bool GossipHello_npc_engineering_tele_trinket(Player* pPlayer, Creature* pCreature) -{ - uint32 uiNpcTextId = 0; - std::string strGossipItem; - bool bCanLearn = false; - - if (pPlayer->HasSkill(SKILL_ENGINEERING)) - { - switch(pCreature->GetEntry()) - { - case NPC_ZAP: - uiNpcTextId = 7249; - if (pPlayer->GetBaseSkillValue(SKILL_ENGINEERING) >= 260 && pPlayer->HasSpell(S_GOBLIN)) - { - if (!pPlayer->HasSpell(SPELL_TO_EVERLOOK)) - { - bCanLearn = true; - strGossipItem = GOSSIP_ITEM_ZAP; - } - else if (pPlayer->HasSpell(SPELL_TO_EVERLOOK)) - uiNpcTextId = 0; - } - break; - case NPC_JHORDY: - uiNpcTextId = 7251; - if (pPlayer->GetBaseSkillValue(SKILL_ENGINEERING) >= 260 && pPlayer->HasSpell(S_GNOMISH)) - { - if (!pPlayer->HasSpell(SPELL_TO_GADGET)) - { - bCanLearn = true; - strGossipItem = GOSSIP_ITEM_JHORDY; - } - else if (pPlayer->HasSpell(SPELL_TO_GADGET)) - uiNpcTextId = 7252; - } - break; - case NPC_KABLAM: - uiNpcTextId = 10365; - if (pPlayer->GetBaseSkillValue(SKILL_ENGINEERING) >= 350 && pPlayer->HasSpell(S_GOBLIN)) - { - if (!pPlayer->HasSpell(SPELL_TO_AREA52)) - { - bCanLearn = true; - strGossipItem = GOSSIP_ITEM_KABLAM; - } - else if (pPlayer->HasSpell(SPELL_TO_AREA52)) - uiNpcTextId = 0; - } - break; - case NPC_SMILES: - uiNpcTextId = 10363; - if (pPlayer->GetBaseSkillValue(SKILL_ENGINEERING) >= 350 && pPlayer->HasSpell(S_GNOMISH)) - { - if (!pPlayer->HasSpell(SPELL_TO_TOSHLEY)) - { - bCanLearn = true; - strGossipItem = GOSSIP_ITEM_SMILES; - } - else if (pPlayer->HasSpell(SPELL_TO_TOSHLEY)) - uiNpcTextId = 0; - } - break; - } - } - - if (bCanLearn) - { - if (pPlayer->HasItemCount(ITEM_GOBLIN_CARD,1) || pPlayer->HasItemCount(ITEM_GNOMISH_CARD,1)) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, strGossipItem, pCreature->GetEntry(), GOSSIP_ACTION_INFO_DEF+1); - } - - pPlayer->SEND_GOSSIP_MENU(uiNpcTextId ? uiNpcTextId : pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); - return true; -} - -bool GossipSelect_npc_engineering_tele_trinket(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) -{ - if (uiAction == GOSSIP_ACTION_INFO_DEF+1) - pPlayer->CLOSE_GOSSIP_MENU(); - - if (uiSender != pCreature->GetEntry()) - return true; - - switch(uiSender) - { - case NPC_ZAP: - pPlayer->CastSpell(pPlayer,SPELL_LEARN_TO_EVERLOOK,false); - break; - case NPC_JHORDY: - pPlayer->CastSpell(pPlayer,SPELL_LEARN_TO_GADGET,false); - break; - case NPC_KABLAM: - pPlayer->CastSpell(pPlayer,SPELL_LEARN_TO_AREA52,false); - break; - case NPC_SMILES: - pPlayer->CastSpell(pPlayer,SPELL_LEARN_TO_TOSHLEY,false); - break; - } - - return true; -} - /*### # start menues leatherworking ###*/ @@ -1286,7 +1154,7 @@ bool GossipSelect_npc_prof_tailor(Player* pPlayer, Creature* pCreature, uint32 u # start menues for GO (engineering and leatherworking) ###*/ -/*bool GOHello_go_soothsaying_for_dummies(Player* pPlayer, GameObject* pGo) +/*bool GOUse_go_soothsaying_for_dummies(Player* pPlayer, GameObject* pGo) { pPlayer->PlayerTalkClass->GetGossipMenu()->AddMenuItem(0,GOSSIP_LEARN_DRAGON, GOSSIP_SENDER_INFO, GOSSIP_ACTION_INFO_DEF, "", 0); @@ -1315,12 +1183,6 @@ void AddSC_npc_professions() newscript->pGossipSelect = &GossipSelect_npc_prof_blacksmith; newscript->RegisterSelf(); - newscript = new Script; - newscript->Name = "npc_engineering_tele_trinket"; - newscript->pGossipHello = &GossipHello_npc_engineering_tele_trinket; - newscript->pGossipSelect = &GossipSelect_npc_engineering_tele_trinket; - newscript->RegisterSelf(); - newscript = new Script; newscript->Name = "npc_prof_leather"; newscript->pGossipHello = &GossipHello_npc_prof_leather; @@ -1335,7 +1197,7 @@ void AddSC_npc_professions() /*newscript = new Script; newscript->Name = "go_soothsaying_for_dummies"; - newscript->pGOHello = &GOHello_go_soothsaying_for_dummies; + newscript->pGOUse = &GOUse_go_soothsaying_for_dummies; //newscript->pGossipSelect = &GossipSelect_go_soothsaying_for_dummies; newscript->RegisterSelf();*/ } diff --git a/scripts/world/npcs_special.cpp b/scripts/world/npcs_special.cpp index 78e69c22c..b4a886b2b 100644 --- a/scripts/world/npcs_special.cpp +++ b/scripts/world/npcs_special.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -35,7 +35,7 @@ npc_guardian 100% guardianAI used to prevent players from accessin npc_garments_of_quests 80% NPC's related to all Garments of-quests 5621, 5624, 5625, 5648, 5650 npc_injured_patient 100% patients for triage-quests (6622 and 6624) npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622 and 6624 (Triage) -npc_innkeeper 25% Innkeepers in general. A lot do be done here (misc options for events) +npc_innkeeper 25% ScriptName not assigned. Innkeepers in general. npc_kingdom_of_dalaran_quests Misc NPC's gossip option related to quests 12791, 12794 and 12796 npc_lunaclaw_spirit 100% Appears at two different locations, quest 6001/6002 npc_mount_vendor 100% Regular mount vendors all over the world. Display gossip if player doesn't meet the requirements to buy @@ -43,6 +43,7 @@ npc_rogue_trainer 80% Scripted trainers, so they are able to offer ite npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given npc_tabard_vendor 50% allow recovering quest related tabards, achievement related ones need core support npc_locksmith 75% list of keys needs to be confirmed +npc_death_knight_gargoyle AI for summoned gargoyle of deathknights EndContentData */ /*######## @@ -346,7 +347,7 @@ bool QuestAccept_npc_chicken_cluck(Player* pPlayer, Creature* pCreature, const Q return true; } -bool QuestComplete_npc_chicken_cluck(Player* pPlayer, Creature* pCreature, const Quest* pQuest) +bool QuestRewarded_npc_chicken_cluck(Player* pPlayer, Creature* pCreature, const Quest* pQuest) { if (pQuest->GetQuestId() == QUEST_CLUCK) { @@ -1060,17 +1061,6 @@ enum SPELL_TRICK_OR_TREAT = 24751, // create item or random buff SPELL_TRICK_OR_TREATED = 24755, // buff player get when tricked or treated - SPELL_TREAT = 24715, - SPELL_TRICK_NO_ATTACK = 24753, - SPELL_TRICK_GNOME = 24713, - SPELL_TRICK_GHOST_MALE = 24735, - SPELL_TRICK_GHOST_FEMALE = 24736, - SPELL_TRICK_NINJA_MALE = 24710, - SPELL_TRICK_NINJA_FEMALE = 24711, - SPELL_TRICK_PIRATE_MALE = 24708, - SPELL_TRICK_PIRATE_FEMALE = 24709, - SPELL_TRICK_SKELETON = 24723, - SPELL_TRICK_BAT = 24732 }; #define GOSSIP_ITEM_TRICK_OR_TREAT "Trick or Treat!" @@ -1078,7 +1068,7 @@ enum bool GossipHello_npc_innkeeper(Player* pPlayer, Creature* pCreature) { - pPlayer->PrepareGossipMenu(pCreature); + pPlayer->PrepareGossipMenu(pCreature, pPlayer->GetDefaultGossipMenuForSource(pCreature)); if (IsHolidayActive(HOLIDAY_HALLOWS_END) && !pPlayer->HasAura(SPELL_TRICK_OR_TREATED, EFFECT_INDEX_0)) pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TRICK_OR_TREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); @@ -1102,41 +1092,10 @@ bool GossipSelect_npc_innkeeper(Player* pPlayer, Creature* pCreature, uint32 uiS case GOSSIP_ACTION_INFO_DEF+1: pPlayer->SEND_GOSSIP_MENU(TEXT_ID_WHAT_TO_DO, pCreature->GetGUID()); break; - case GOSSIP_ACTION_INFO_DEF+2: - { pPlayer->CLOSE_GOSSIP_MENU(); - - // either trick or treat, 50% chance - if (urand(0, 1)) - { - pPlayer->CastSpell(pPlayer, SPELL_TREAT, true); - } - else - { - uint32 uiTrickSpell = 0; - - switch(urand(0, 9)) // note that female characters can get male costumes and vice versa - { - case 0: uiTrickSpell = SPELL_TRICK_NO_ATTACK; break; - case 1: uiTrickSpell = SPELL_TRICK_GNOME; break; - case 2: uiTrickSpell = SPELL_TRICK_GHOST_MALE; break; - case 3: uiTrickSpell = SPELL_TRICK_GHOST_FEMALE; break; - case 4: uiTrickSpell = SPELL_TRICK_NINJA_MALE; break; - case 5: uiTrickSpell = SPELL_TRICK_NINJA_FEMALE; break; - case 6: uiTrickSpell = SPELL_TRICK_PIRATE_MALE; break; - case 7: uiTrickSpell = SPELL_TRICK_PIRATE_FEMALE; break; - case 8: uiTrickSpell = SPELL_TRICK_SKELETON; break; - case 9: uiTrickSpell = SPELL_TRICK_BAT; break; - } - - pPlayer->CastSpell(pPlayer, uiTrickSpell, true); - } - - pPlayer->CastSpell(pPlayer, SPELL_TRICK_OR_TREATED, true); + pCreature->CastSpell(pPlayer, SPELL_TRICK_OR_TREAT, true); break; - } - case GOSSIP_OPTION_VENDOR: pPlayer->SEND_VENDORLIST(pCreature->GetGUID()); break; @@ -1266,7 +1225,7 @@ bool GossipHello_npc_mount_vendor(Player* pPlayer, Creature* pCreature) else canBuy = true; break; case 4731: //Zachariah Post - if (pPlayer->GetReputationRank(68) != REP_EXALTED && race != RACE_UNDEAD_PLAYER) + if (pPlayer->GetReputationRank(68) != REP_EXALTED && race != RACE_UNDEAD) pPlayer->SEND_GOSSIP_MENU(5840, pCreature->GetGUID()); else canBuy = true; break; @@ -1315,42 +1274,27 @@ bool GossipSelect_npc_mount_vendor(Player* pPlayer, Creature* pCreature, uint32 bool GossipHello_npc_rogue_trainer(Player* pPlayer, Creature* pCreature) { - if (pCreature->isQuestGiver()) - pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - - if (pCreature->isTrainer()) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); - - if (pCreature->CanTrainAndResetTalentsOf(pPlayer)) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, "I wish to unlearn my talents", GOSSIP_SENDER_MAIN, GOSSIP_OPTION_UNLEARNTALENTS); - - if (pPlayer->getClass() == CLASS_ROGUE && pPlayer->getLevel() >= 24 && !pPlayer->HasItemCount(17126,1) && !pPlayer->GetQuestRewardStatus(6681)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(5996, pCreature->GetGUID()); - } else - pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID()); - - return true; + if (pPlayer->getClass() != CLASS_ROGUE) return false; + + if (pPlayer->getLevel() >= 24 && !pPlayer->HasItemCount(17126,1) && !pPlayer->GetQuestRewardStatus(6681)) + if (pCreature->isQuestGiver()) + { + pPlayer->PrepareGossipMenu(pCreature,50195); + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + pPlayer->SEND_GOSSIP_MENU(5996, pCreature->GetGUID()); + return true; + } + return false; } bool GossipSelect_npc_rogue_trainer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { - switch(uiAction) - { - case GOSSIP_ACTION_INFO_DEF+1: - pPlayer->CLOSE_GOSSIP_MENU(); + if (uiAction == GOSSIP_ACTION_INFO_DEF) + { pPlayer->CastSpell(pPlayer,21100,false); - break; - case GOSSIP_ACTION_TRAIN: - pPlayer->SEND_TRAINERLIST(pCreature->GetGUID()); - break; - case GOSSIP_OPTION_UNLEARNTALENTS: pPlayer->CLOSE_GOSSIP_MENU(); - pPlayer->SendTalentWipeConfirm(pCreature->GetGUID()); - break; - } - return true; + return true; + } else return false; } /*###### @@ -1750,6 +1694,609 @@ bool GossipSelect_npc_locksmith(Player* pPlayer, Creature* pCreature, uint32 uiS return true; } +/*###### +## npc_mirror_image +######*/ + +enum MirrorImageSpells +{ + SPELL_CLONE_CASTER = 45204, + SPELL_CLONE_CASTER_1 = 69837, +// SPELL_CLONE_CASTER_1 = 58836, + SPELL_CLONE_THREAT = 58838, + SPELL_FIREBLAST = 59637, + SPELL_FROSTBOLT = 59638, + SPELL_FROSTSHIELD = 43008, + SPELL_FIRESHIELD = 43046, + SPELL_ICEBLOCK = 65802, + SPELL_ICERING = 42917, +}; + +struct MANGOS_DLL_DECL npc_mirror_imageAI : public ScriptedAI +{ + npc_mirror_imageAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + uint32 m_uiFrostboltTimer; + uint32 m_uiFrostringTimer; + uint32 m_uiFireblastTimer; + bool inCombat; + Unit *owner; + float angle; + bool blocked; + bool movement; + + void Reset() + { + owner = m_creature->GetOwner(); + if (!owner) + return; + + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_2,owner->GetUInt32Value(UNIT_FIELD_BYTES_2)); + m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); + m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); + + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, owner->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID)); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, owner->GetUInt32Value(PLAYER_VISIBLE_ITEM_17_ENTRYID)); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+2, owner->GetUInt32Value(PLAYER_VISIBLE_ITEM_18_ENTRYID)); + m_creature->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN), true); + + m_uiFrostboltTimer = urand(0,3000); + m_uiFrostringTimer = urand(2000,6000); + m_uiFireblastTimer = urand(0,3000); + inCombat = false; + blocked = false; + movement = false; + + + if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW)) + { + angle = m_creature->GetAngle(owner); + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f, angle); + } + + if(owner->IsPvP()) + m_creature->SetPvP(true); + if(owner->IsFFAPvP()) + m_creature->SetFFAPvP(true); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) return; + + if (m_creature->Attack(pWho, true)) + { + if (owner) + m_creature->CastSpell(m_creature, SPELL_CLONE_THREAT, true, NULL, NULL, owner->GetGUID()); + m_creature->clearUnitState(UNIT_STAT_FOLLOW); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 100.0f); + DoStartMovement(pWho, 30.0f); + SetCombatMovement(true); + inCombat = true; + } + } + + void EnterEvadeMode() + { + if (m_creature->IsInEvadeMode() || !m_creature->isAlive()) + return; + + inCombat = false; + + m_creature->AttackStop(); + m_creature->CombatStop(true); + if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW)) + { + angle = m_creature->GetAngle(owner); + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f,angle); + } + } + + void UpdateAI(const uint32 diff) + { + if (!owner || !owner->isAlive()) + m_creature->ForcedDespawn(); + + if (owner && !m_creature->HasAura(SPELL_CLONE_CASTER)) + m_creature->CastSpell(m_creature, SPELL_CLONE_CASTER, true, NULL, NULL, owner->GetGUID()); + + if (owner && !m_creature->HasAura(SPELL_CLONE_CASTER_1)) + m_creature->CastSpell(m_creature, SPELL_CLONE_CASTER_1, true, NULL, NULL, owner->GetGUID()); + + if (owner && owner->HasAura(SPELL_FROSTSHIELD) && !m_creature->HasAura(SPELL_FROSTSHIELD)) + m_creature->CastSpell(m_creature, SPELL_FROSTSHIELD, false); + + if (owner && owner->HasAura(SPELL_FIRESHIELD) && !m_creature->HasAura(SPELL_FIRESHIELD)) + m_creature->CastSpell(m_creature, SPELL_FIRESHIELD, false); + + if (!m_creature->getVictim()) + if (owner && owner->getVictim()) + AttackStart(owner->getVictim()); + + if (m_creature->getVictim() && m_creature->getVictim() != owner->getVictim()) + AttackStart(owner->getVictim()); + + if (inCombat && !m_creature->getVictim()) + { + EnterEvadeMode(); + return; + } + + if (!inCombat) + return; + + if (m_creature->IsWithinDistInMap(m_creature->getVictim(),30.0f)) + { + movement = false; + if (m_uiFrostboltTimer <= diff) + { + DoCastSpellIfCan(m_creature->getVictim(),SPELL_FROSTBOLT); + m_uiFrostboltTimer = urand(1000,6000); + } else m_uiFrostboltTimer -= diff; + + if (m_uiFireblastTimer <= diff) + { + DoCastSpellIfCan(m_creature->getVictim(),SPELL_FIREBLAST); + m_uiFireblastTimer = urand(1000,6000); + } else m_uiFireblastTimer -= diff; + + if (m_uiFrostringTimer <= diff && m_creature->IsWithinDistInMap(m_creature->getVictim(),5.0f)) + { + DoCastSpellIfCan(m_creature->getVictim(),SPELL_ICERING); + m_uiFrostringTimer = urand(4000,8000); + } else m_uiFrostringTimer -= diff; + + if (!blocked && m_creature->GetHealthPercent() < 10.0f) + { + DoCastSpellIfCan(m_creature,SPELL_ICEBLOCK); + blocked = true; + } + } + else + if (!movement) + { + DoStartMovement(m_creature->getVictim(), 20.0f); + movement = true; + } + +// DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_mirror_image(Creature* pCreature) +{ + return new npc_mirror_imageAI(pCreature); +}; + +/*#### + ## npc_snake_trap_serpents - Summonned snake id are 19921 and 19833 + ####*/ + +#define SPELL_MIND_NUMBING_POISON 25810 //Viper +#define SPELL_CRIPPLING_POISON 30981 //Viper +#define SPELL_DEADLY_POISON 34655 //Venomous Snake + +#define MOB_VIPER 19921 +#define MOB_VENOM_SNIKE 19833 + +struct MANGOS_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI +{ + npc_snake_trap_serpentsAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 SpellTimer; + Unit* Owner; + + void Reset() + { + SpellTimer = 500; + Owner = m_creature->GetCharmerOrOwner(); + if (!Owner) return; + + m_creature->SetLevel(Owner->getLevel()); + m_creature->setFaction(Owner->getFaction()); + } + + void AttackStart(Unit* pWho) + { + if (!pWho) return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->SetInCombatWith(pWho); + m_creature->AddThreat(pWho, 100.0f); + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(pWho); + } + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->getVictim()) + { + if (Owner && Owner->getVictim()) + AttackStart(Owner->getVictim()); + return; + } + + if (SpellTimer <= diff) + { + if (m_creature->GetEntry() == MOB_VIPER ) //Viper - 19921 + { + if (!urand(0,2)) //33% chance to cast + { + uint32 spell; + if (urand(0,1)) + spell = SPELL_MIND_NUMBING_POISON; + else + spell = SPELL_CRIPPLING_POISON; + DoCast(m_creature->getVictim(), spell); + } + + SpellTimer = urand(3000, 5000); + } + else if (m_creature->GetEntry() == MOB_VENOM_SNIKE ) //Venomous Snake - 19833 + { + if (urand(0,1) == 0) //80% chance to cast + DoCast(m_creature->getVictim(), SPELL_DEADLY_POISON); + SpellTimer = urand(2500, 4500); + } + } + else SpellTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_snake_trap_serpents(Creature* pCreature) +{ + return new npc_snake_trap_serpentsAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_rune_blade : public ScriptedAI +{ + npc_rune_blade(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + Unit* owner; + + void Reset() + { + owner = m_creature->GetOwner(); + if (!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + // Cannot be Selected or Attacked + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + m_creature->SetLevel(owner->getLevel()); + m_creature->setFaction(owner->getFaction()); + + // Add visible weapon + if (Item const * item = ((Player *)owner)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, item->GetProto()->ItemId); + + // Add stats scaling + int32 damageDone=owner->CalculateDamage(BASE_ATTACK, true); // might be average damage instead ? + int32 meleeSpeed=owner->m_modAttackSpeedPct[BASE_ATTACK]; + m_creature->CastCustomSpell(m_creature, 51906, &damageDone, &meleeSpeed, NULL, true); + + // Visual Glow + m_creature->CastSpell(m_creature, 53160, true); + + SetCombatMovement(true); + } + + void UpdateAI(const uint32 diff) + { + if (!owner) return; + + if (!m_creature->getVictim()) + { + if (owner->getVictim()) + AttackStart(owner->getVictim()); + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_rune_blade(Creature* pCreature) +{ + return new npc_rune_blade(pCreature); +} +/*######## +# mob_death_knight_gargoyle AI +#########*/ + +// UPDATE `creature_template` SET `ScriptName` = 'mob_death_knight_gargoyle' WHERE `entry` = '27829'; + +enum GargoyleSpells +{ + SPELL_GARGOYLE_STRIKE = 51963 // Don't know if this is the correct spell, it does about 700-800 damage points +}; + +struct MANGOS_DLL_DECL npc_death_knight_gargoyle : public ScriptedAI +{ + npc_death_knight_gargoyle(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + uint32 m_uiGargoyleStrikeTimer; + bool inCombat; + Unit *owner; + + + void Reset() + { + owner = m_creature->GetOwner(); + if (!owner) return; + + m_creature->SetLevel(owner->getLevel()); + m_creature->setFaction(owner->getFaction()); + + m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); + m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648); + m_creature->AddSplineFlag(SPLINEFLAG_FLYING); + + inCombat = false; + m_uiGargoyleStrikeTimer = urand(3000, 5000); + + float fPosX, fPosY, fPosZ; + owner->GetPosition(fPosX, fPosY, fPosZ); + + m_creature->NearTeleportTo(fPosX, fPosY, fPosZ+10.0f, m_creature->GetAngle(owner)); + + + if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW)) + { + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f, m_creature->GetAngle(owner)); + } + + if(owner->IsPvP()) + m_creature->SetPvP(true); + if(owner->IsFFAPvP()) + m_creature->SetFFAPvP(true); + } + + void EnterEvadeMode() + { + if (m_creature->IsInEvadeMode() || !m_creature->isAlive()) + return; + + inCombat = false; + + m_creature->AttackStop(); + m_creature->CombatStop(true); + if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW)) + { + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f, m_creature->GetAngle(owner)); + } + } + + void AttackStart(Unit* pWho) + { + if (!pWho) return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->clearUnitState(UNIT_STAT_FOLLOW); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + m_creature->AddThreat(pWho, 100.0f); + DoStartMovement(pWho, 10.0f); + SetCombatMovement(true); + inCombat = true; + } + } + + void UpdateAI(const uint32 uiDiff) + { + + if (!owner || !owner->IsInWorld()) + { + m_creature->ForcedDespawn(); + return; + } + + if (!m_creature->getVictim()) + if (owner && owner->getVictim()) + AttackStart(owner->getVictim()); + + if (m_creature->getVictim() && m_creature->getVictim() != owner->getVictim()) + AttackStart(owner->getVictim()); + + if (inCombat && !m_creature->getVictim()) + { + EnterEvadeMode(); + return; + } + + if (!inCombat) return; + + if (m_uiGargoyleStrikeTimer <= uiDiff) + { + DoCastSpellIfCan(m_creature->getVictim(), SPELL_GARGOYLE_STRIKE); + m_uiGargoyleStrikeTimer = urand(3000, 5000); + } + else m_uiGargoyleStrikeTimer -= uiDiff; + } +}; + +CreatureAI* GetAI_npc_death_knight_gargoyle(Creature* pCreature) +{ + return new npc_death_knight_gargoyle(pCreature); +} + +struct MANGOS_DLL_DECL npc_risen_allyAI : public ScriptedAI +{ + npc_risen_allyAI(Creature *pCreature) : ScriptedAI(pCreature) + { + } + + uint32 StartTimer; + + void Reset() + { + StartTimer = 2000; + m_creature->SetSheath(SHEATH_STATE_MELEE); + m_creature->SetByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_ABANDONED); + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048); + m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); + m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); + if (Player* creator = m_creature->GetMap()->GetPlayer(m_creature->GetCreatorGuid())) + { + m_creature->SetLevel(creator->getLevel()); + m_creature->setFaction(creator->getFaction()); + } + } + + void JustDied(Unit* killer) + { + if (!m_creature) + return; + + if (Player* creator = m_creature->GetMap()->GetPlayer(m_creature->GetCreatorGuid())) + { + creator->RemoveAurasDueToSpell(46619); + creator->RemoveAurasDueToSpell(62218); + } + } + + void AttackStart(Unit* pWho) + { + if (!pWho) return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + DoStartMovement(pWho, 10.0f); + SetCombatMovement(true); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if(StartTimer > uiDiff) + { + StartTimer -= uiDiff; + return; + } + + if(!m_creature->isCharmed()) + m_creature->ForcedDespawn(); + + if (m_creature->isInCombat()) + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_risen_ally(Creature* pCreature) +{ + return new npc_risen_allyAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_explosive_decoyAI : public ScriptedAI +{ + npc_explosive_decoyAI(Creature *pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + Player* p_owner; + + void Reset() + { + p_owner = NULL; + SetCombatMovement(false); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (!m_creature || !m_creature->isAlive()) + return; + + if (uiDamage > 0) + m_creature->CastSpell(m_creature, 53273, true); + } + + void JustDied(Unit* killer) + { + if (!m_creature || !p_owner) + return; + + SpellEntry const* createSpell = GetSpellStore()->LookupEntry(m_creature->GetUInt32Value(UNIT_CREATED_BY_SPELL)); + + if (createSpell) + p_owner->SendCooldownEvent(createSpell); + } + + void UpdateAI(const uint32 uiDiff) + { + if (p_owner) + return; + + p_owner = m_creature->GetMap()->GetPlayer(m_creature->GetCreatorGuid()); + + if (!p_owner) + return; + + m_creature->setFaction(p_owner->getFaction()); + m_creature->SetCreatorGuid(ObjectGuid()); + } +}; + +CreatureAI* GetAI_npc_explosive_decoy(Creature* pCreature) +{ + return new npc_explosive_decoyAI(pCreature); +} + +struct MANGOS_DLL_DECL npc_eye_of_kilrogg : public ScriptedAI +{ + npc_eye_of_kilrogg(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + Player* p_owner; + + void Reset() + { + p_owner = NULL; + } + + void UpdateAI(const uint32 diff) + { + if (p_owner) + return; + + p_owner = (Player*)m_creature->GetCharmerOrOwner(); + + if (!p_owner) + return; + + if (!m_creature->HasAura(2585)) + m_creature->CastSpell(m_creature, 2585, true); + + if (p_owner->HasAura(58081)) + m_creature->CastSpell(m_creature, 58083, true); + + } +}; + +CreatureAI* GetAI_npc_eye_of_kilrogg(Creature* pCreature) +{ + return new npc_eye_of_kilrogg(pCreature); +} + void AddSC_npcs_special() { Script* newscript; @@ -1762,8 +2309,8 @@ void AddSC_npcs_special() newscript = new Script; newscript->Name = "npc_chicken_cluck"; newscript->GetAI = &GetAI_npc_chicken_cluck; - newscript->pQuestAccept = &QuestAccept_npc_chicken_cluck; - newscript->pQuestComplete = &QuestComplete_npc_chicken_cluck; + newscript->pQuestAcceptNPC = &QuestAccept_npc_chicken_cluck; + newscript->pQuestRewardedNPC = &QuestRewarded_npc_chicken_cluck; newscript->RegisterSelf(); newscript = new Script; @@ -1779,7 +2326,7 @@ void AddSC_npcs_special() newscript = new Script; newscript->Name = "npc_doctor"; newscript->GetAI = &GetAI_npc_doctor; - newscript->pQuestAccept = &QuestAccept_npc_doctor; + newscript->pQuestAcceptNPC = &QuestAccept_npc_doctor; newscript->RegisterSelf(); newscript = new Script; @@ -1796,7 +2343,7 @@ void AddSC_npcs_special() newscript->Name = "npc_innkeeper"; newscript->pGossipHello = &GossipHello_npc_innkeeper; newscript->pGossipSelect = &GossipSelect_npc_innkeeper; - newscript->RegisterSelf(); + newscript->RegisterSelf(false); // script and error report disabled, but script can be used for custom needs, adding ScriptName newscript = new Script; newscript->Name = "npc_kingdom_of_dalaran_quests"; @@ -1839,4 +2386,39 @@ void AddSC_npcs_special() newscript->pGossipHello = &GossipHello_npc_locksmith; newscript->pGossipSelect = &GossipSelect_npc_locksmith; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_mirror_image"; + newscript->GetAI = &GetAI_npc_mirror_image; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_snake_trap_serpents"; + newscript->GetAI = &GetAI_npc_snake_trap_serpents; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_runeblade"; + newscript->GetAI = &GetAI_npc_rune_blade; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_death_knight_gargoyle"; + newscript->GetAI = &GetAI_npc_death_knight_gargoyle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_risen_ally"; + newscript->GetAI = &GetAI_npc_risen_ally; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_explosive_decoy"; + newscript->GetAI = &GetAI_npc_explosive_decoy; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_eye_of_kilrogg"; + newscript->GetAI = &GetAI_npc_eye_of_kilrogg; + newscript->RegisterSelf(); } diff --git a/scripts/world/spell_scripts.cpp b/scripts/world/spell_scripts.cpp index 2b7eca864..2361b3a74 100644 --- a/scripts/world/spell_scripts.cpp +++ b/scripts/world/spell_scripts.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 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 @@ -35,6 +35,10 @@ spell 50706 spell 45109 spell 45111 spell 39246 +spell 52090 +spell 51331 +spell 51332 +spell 51366 EndContentData */ #include "precompiled.h" @@ -264,6 +268,43 @@ enum SPELL_DARKMENDER_TINCTURE = 52741, SPELL_SUMMON_CORRUPTED_SCARLET = 54415, NPC_CORPSES_RISE_CREDIT_BUNNY = 29398, + + // quest 12659, item 38731 + SPELL_AHUNAES_KNIFE = 52090, + NPC_SCALPS_KILL_CREDIT_BUNNY = 28622, + + // quest 13549 + SPELL_TAILS_UP_GENDER_MASTER = 62110, + SPELL_TAILS_UP_AURA = 62109, + SPELL_FORCE_LEOPARD_SUMMON = 62117, + SPELL_FORCE_BEAR_SUMMON = 62118, + NPC_FROST_LEOPARD = 29327, + NPC_ICEPAW_BEAR = 29319, + NPC_LEOPARD_KILL_CREDIT = 33005, + NPC_BEAR_KILL_CREDIT = 33006, + SAY_ITS_FEMALE = -1000642, + SAY_ITS_MALE = -1000643, + + // quest 9849, item 24501 + SPELL_THROW_GORDAWG_BOULDER = 32001, + NPC_MINION_OF_GUROK = 18181, + + // quest 12589 + SPELL_HIT_APPLE = 51331, + SPELL_MISS_APPLE = 51332, + SPELL_MISS_APPLE_HIT_BIRD = 51366, + SPELL_APPLE_FALLS_TO_GROUND = 51371, + NPC_APPLE = 28053, + NPC_LUCKY_WILHELM = 28054, + NPC_DROSTAN = 28328, + SAY_LUCKY_HIT_1 = -1000644, + SAY_LUCKY_HIT_2 = -1000645, + SAY_LUCKY_HIT_3 = -1000646, + SAY_LUCKY_HIT_APPLE = -1000647, + SAY_DROSTAN_GOT_LUCKY_1 = -1000648, + SAY_DROSTAN_GOT_LUCKY_2 = -1000649, + SAY_DROSTAN_HIT_BIRD_1 = -1000650, + SAY_DROSTAN_HIT_BIRD_2 = -1000651, }; bool EffectAuraDummy_spell_aura_dummy_npc(const Aura* pAura, bool bApply) @@ -295,7 +336,7 @@ bool EffectAuraDummy_spell_aura_dummy_npc(const Aura* pAura, bool bApply) { if (Player* pPlayer = (Player*)pAura->GetCaster()) { - pPlayer->KilledMonsterCredit(NPC_FALLEN_HERO_SPIRIT_PROXY, pCreature->GetGUID()); + pPlayer->KilledMonsterCredit(NPC_FALLEN_HERO_SPIRIT_PROXY, pCreature->GetObjectGuid()); pCreature->ForcedDespawn(); } } @@ -374,7 +415,7 @@ bool EffectAuraDummy_spell_aura_dummy_npc(const Aura* pAura, bool bApply) { if (pAura->GetEffIndex() != EFFECT_INDEX_0) return true; - + if (Unit* pCaster = pAura->GetCaster()) DoScriptText(SAY_SPECIMEN, pCaster); @@ -393,18 +434,20 @@ bool EffectAuraDummy_spell_aura_dummy_npc(const Aura* pAura, bool bApply) } case SPELL_ENRAGE: { - if (pAura->GetTarget()->GetTypeId() != TYPEID_UNIT || !bApply) + if (!bApply || pAura->GetTarget()->GetTypeId() != TYPEID_UNIT) return false; - if (Creature* pCreature = GetClosestCreatureWithEntry(pAura->GetTarget(), NPC_DARKSPINE_MYRMIDON, 25.0f)) + Creature* pTarget = (Creature*)pAura->GetTarget(); + + if (Creature* pCreature = GetClosestCreatureWithEntry(pTarget, NPC_DARKSPINE_MYRMIDON, 25.0f)) { - dynamic_cast(pAura->GetTarget())->AI()->AttackStart(pCreature); + pTarget->AI()->AttackStart(pCreature); return true; } - if (Creature* pCreature = GetClosestCreatureWithEntry(pAura->GetTarget(), NPC_DARKSPINE_SIREN, 25.0f)) + if (Creature* pCreature = GetClosestCreatureWithEntry(pTarget, NPC_DARKSPINE_SIREN, 25.0f)) { - dynamic_cast(pAura->GetTarget())->AI()->AttackStart(pCreature); + pTarget->AI()->AttackStart(pCreature); return true; } @@ -500,7 +543,7 @@ bool EffectDummyCreature_spell_dummy_npc(Unit* pCaster, uint32 uiSpellId, SpellE } pCreatureTarget->SetStandState(UNIT_STAND_STATE_STAND); - pCreatureTarget->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_WORK); + pCreatureTarget->HandleEmote(EMOTE_STATE_WORK); break; } } @@ -663,7 +706,7 @@ bool EffectDummyCreature_spell_dummy_npc(Unit* pCaster, uint32 uiSpellId, SpellE { if (uiEffIndex == EFFECT_INDEX_0) { - if (pCreatureTarget->isDead()) + if (pCreatureTarget->IsCorpse()) { uint32 newSpellId = 0; @@ -694,8 +737,8 @@ bool EffectDummyCreature_spell_dummy_npc(Unit* pCaster, uint32 uiSpellId, SpellE { pCreatureTarget->CastSpell(pCaster, SPELL_GREENGILL_SLAVE_FREED, true); - if (pCreatureTarget->GetTypeId() == TYPEID_UNIT) - dynamic_cast(pCreatureTarget)->UpdateEntry(NPC_FREED_GREENGILL_SLAVE); // Freed Greengill Slave + // Freed Greengill Slave + pCreatureTarget->UpdateEntry(NPC_FREED_GREENGILL_SLAVE); pCreatureTarget->CastSpell(pCreatureTarget, SPELL_ENRAGE, true); @@ -735,6 +778,131 @@ bool EffectDummyCreature_spell_dummy_npc(Unit* pCaster, uint32 uiSpellId, SpellE } return true; } + case SPELL_AHUNAES_KNIFE: + { + if (uiEffIndex == EFFECT_INDEX_0) + { + if (pCaster->GetTypeId() != TYPEID_PLAYER) + return true; + + ((Player*)pCaster)->KilledMonsterCredit(NPC_SCALPS_KILL_CREDIT_BUNNY); + pCreatureTarget->ForcedDespawn(); + return true; + } + return true; + } + case SPELL_TAILS_UP_GENDER_MASTER: + { + if (uiEffIndex == EFFECT_INDEX_0) + { + bool isMale = urand(0,1); + Player* pPlayer = pCreatureTarget->GetLootRecipient(); + + if (!pPlayer) + return true; + + if (isMale) + DoScriptText(SAY_ITS_MALE, pCreatureTarget, pPlayer); + else + DoScriptText(SAY_ITS_FEMALE, pCreatureTarget, pPlayer); + + switch(pCreatureTarget->GetEntry()) + { + case NPC_FROST_LEOPARD: + { + if (isMale) + pCreatureTarget->CastSpell(pCreatureTarget, SPELL_TAILS_UP_AURA, true); + else + { + pPlayer->KilledMonsterCredit(NPC_LEOPARD_KILL_CREDIT, pCreatureTarget->GetObjectGuid()); + pCreatureTarget->CastSpell(pPlayer, SPELL_FORCE_LEOPARD_SUMMON, true); + pCreatureTarget->ForcedDespawn(); + } + + break; + } + case NPC_ICEPAW_BEAR: + { + if (isMale) + pCreatureTarget->CastSpell(pCreatureTarget, SPELL_TAILS_UP_AURA, true); + else + { + pPlayer->KilledMonsterCredit(NPC_BEAR_KILL_CREDIT, pCreatureTarget->GetObjectGuid()); + pCreatureTarget->CastSpell(pPlayer, SPELL_FORCE_BEAR_SUMMON, true); + pCreatureTarget->ForcedDespawn(); + } + + break; + } + } + return true; + } + return true; + } + case SPELL_THROW_GORDAWG_BOULDER: + { + if (uiEffIndex == EFFECT_INDEX_0) + { + for(int i = 0; i < 3; ++i) + { + if (irand(i, 2)) // 2-3 summons + pCreatureTarget->SummonCreature(NPC_MINION_OF_GUROK, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 5000); + } + + if (pCreatureTarget->getVictim()) + { + pCaster->DealDamage(pCreatureTarget, pCreatureTarget->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + return true; + } + + // If not in combat, no xp or loot + pCreatureTarget->SetDeathState(JUST_DIED); + pCreatureTarget->SetHealth(0); + return true; + } + return true; + } + case SPELL_HIT_APPLE: + { + if (uiEffIndex == EFFECT_INDEX_0) + { + if (pCaster->GetTypeId() == TYPEID_PLAYER) + ((Player*)pCaster)->KilledMonsterCredit(pCreatureTarget->GetEntry(), pCreatureTarget->GetObjectGuid()); + + pCreatureTarget->CastSpell(pCreatureTarget, SPELL_APPLE_FALLS_TO_GROUND, false); + + if (Creature* pLuckyWilhelm = GetClosestCreatureWithEntry(pCreatureTarget, NPC_LUCKY_WILHELM, 2*INTERACTION_DISTANCE)) + DoScriptText(SAY_LUCKY_HIT_APPLE, pLuckyWilhelm); + } + return true; + } + case SPELL_MISS_APPLE: + { + if (uiEffIndex == EFFECT_INDEX_0) + { + switch (urand(1, 3)) + { + case 1: DoScriptText(SAY_LUCKY_HIT_1, pCreatureTarget); break; + case 2: DoScriptText(SAY_LUCKY_HIT_2, pCreatureTarget); break; + case 3: DoScriptText(SAY_LUCKY_HIT_3, pCreatureTarget); break; + } + + if (Creature* pDrostan = GetClosestCreatureWithEntry(pCreatureTarget, NPC_DROSTAN, 4*INTERACTION_DISTANCE)) + DoScriptText(urand(0, 1) ? SAY_DROSTAN_GOT_LUCKY_1 : SAY_DROSTAN_GOT_LUCKY_2, pDrostan); + } + return true; + } + case SPELL_MISS_APPLE_HIT_BIRD: + { + if (uiEffIndex == EFFECT_INDEX_0) + { + if (Creature* pDrostan = GetClosestCreatureWithEntry(pCreatureTarget, NPC_DROSTAN, 5*INTERACTION_DISTANCE)) + DoScriptText(urand(0, 1) ? SAY_DROSTAN_HIT_BIRD_1 : SAY_DROSTAN_HIT_BIRD_2, pDrostan); + + pCreatureTarget->DealDamage(pCreatureTarget, pCreatureTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + return true; + } } return false; @@ -742,16 +910,16 @@ bool EffectDummyCreature_spell_dummy_npc(Unit* pCaster, uint32 uiSpellId, SpellE void AddSC_spell_scripts() { - Script* newscript; - - newscript = new Script; - newscript->Name = "spell_dummy_go"; - newscript->pEffectDummyGameObj = &EffectDummyGameObj_spell_dummy_go; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "spell_dummy_npc"; - newscript->pEffectDummyCreature = &EffectDummyCreature_spell_dummy_npc; - newscript->pEffectAuraDummy = &EffectAuraDummy_spell_aura_dummy_npc; - newscript->RegisterSelf(); + Script* pNewscript; + + pNewscript = new Script; + pNewscript->Name = "spell_dummy_go"; + pNewscript->pEffectDummyGO = &EffectDummyGameObj_spell_dummy_go; + pNewscript->RegisterSelf(); + + pNewscript = new Script; + pNewscript->Name = "spell_dummy_npc"; + pNewscript->pEffectDummyNPC = &EffectDummyCreature_spell_dummy_npc; + pNewscript->pEffectAuraDummy = &EffectAuraDummy_spell_aura_dummy_npc; + pNewscript->RegisterSelf(); } diff --git a/sd2_revision_nr.h b/sd2_revision_nr.h new file mode 100644 index 000000000..fe4ff178b --- /dev/null +++ b/sd2_revision_nr.h @@ -0,0 +1,4 @@ +#ifndef __SD2_REVISION_NR_H__ +#define __SD2_REVISION_NR_H__ + #define SD2_REVISION_NR "2067" +#endif // __SD2_REVISION_NR_H__ diff --git a/sd2_revision_sql.h b/sd2_revision_sql.h new file mode 100644 index 000000000..997c33355 --- /dev/null +++ b/sd2_revision_sql.h @@ -0,0 +1,5 @@ +#ifndef __SD2_REVISION_SQL_H__ +#define __SD2_REVISION_SQL_H__ + #define REVISION_DB_SCRIPTDEV2 "required__scriptdev2" + #define REVISION_DB_SD2_MANGOS "required__mangos" +#endif // __SD2_REVISION_SQL_H__ diff --git a/sql/Makefile.am b/sql/Makefile.am deleted file mode 100644 index 7a664de98..000000000 --- a/sql/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# 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 -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse -SUBDIRS = Updates - -## Change installation location -# datadir = scriptdev2/sql -pkgdatadir = $(datadir)/scriptdev2/sql - -## Files to be installed -# Install basic SQL files to datadir -pkgdata_DATA = \ - mangos_scriptname_full.sql \ - scriptdev2_create_database.sql \ - scriptdev2_create_structure_mysql.sql \ - scriptdev2_create_structure_pgsql.sql \ - scriptdev2_script_full.sql diff --git a/sql/Updates/0.0.1/Makefile.am b/sql/Updates/0.0.1/Makefile.am deleted file mode 100644 index eed44c8ff..000000000 --- a/sql/Updates/0.0.1/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# 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 -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse - -## Change installation location -# datadir = scriptdev2/sql/updates/0.0.1 -pkgdatadir = $(datadir)/scriptdev2/sql/updates/0.0.1 - -## Files to be installed -# Install basic SQL files to datadir -pkgdata_DATA = \ - 09_BraveWindfeather.sql \ - 11_SilvaFilnaveth.sql \ - 27_Vaelastraz.sql diff --git a/sql/Updates/0.0.2/Makefile.am b/sql/Updates/0.0.2/Makefile.am deleted file mode 100644 index 5e652b182..000000000 --- a/sql/Updates/0.0.2/Makefile.am +++ /dev/null @@ -1,270 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# 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 -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse - -## Change installation location -# datadir = scriptdev2/sql/updates/0.0.2 -pkgdatadir = $(datadir)/scriptdev2/sql/updates/0.0.2 - -## Files to be installed -# Install basic SQL files to datadir -pkgdata_DATA = \ - r56.sql \ - r59.sql \ - r63.sql \ - r65.sql \ - r72.sql \ - r78.sql \ - r81.sql \ - r91.sql \ - r92.sql \ - r97.sql \ - r108.sql \ - r110.sql \ - r121.sql \ - r123.sql \ - r124.sql \ - r125.sql \ - r128.sql \ - r131.sql \ - r134.sql \ - r136.sql \ - r139.sql \ - r142.sql \ - r144.sql \ - r145.sql \ - r149.sql \ - r150.sql \ - r152.sql \ - r153.sql \ - r157.sql \ - r161.sql \ - r163.sql \ - r169.sql \ - r170.sql \ - r171.sql \ - r172.sql \ - r174.sql \ - r176.sql \ - r177.sql \ - r178.sql \ - r181.sql \ - r182.sql \ - r183.sql \ - r184.sql \ - r186.sql \ - r187.sql \ - r189.sql \ - r191.sql \ - r192.sql \ - r197.sql \ - r204.sql \ - r206.sql \ - r211.sql \ - r213.sql \ - r214.sql \ - r215.sql \ - r218.sql \ - r219.sql \ - r221_scriptdev2.sql \ - r227_scriptdev2.sql \ - r230_mangos.sql \ - r234_mangos.sql \ - r237_mangos.sql \ - r238_mangos.sql \ - r239_mangos.sql \ - r240_scriptdev2.sql \ - r241_mangos.sql \ - r242_mangos.sql \ - r243_mangos.sql \ - r249_mangos.sql \ - r250_mangos.sql \ - r253_mangos.sql \ - r255_mangos.sql \ - r256_mangos.sql \ - r257_mangos.sql \ - r258_mangos.sql \ - r260_mangos.sql \ - r261_mangos.sql \ - r262_mangos.sql \ - r263_mangos.sql \ - r264_mangos.sql \ - r265_mangos.sql \ - r269_mangos.sql \ - r270_mangos.sql \ - r271_mangos.sql \ - r272_mangos.sql \ - r273_mangos.sql \ - r274_mangos.sql \ - r275_mangos.sql \ - r281_scriptdev2.sql \ - r282_mangos.sql \ - r286_mangos.sql \ - r289_mangos.sql \ - r291_mangos.sql \ - r295_mangos.sql \ - r297_mangos.sql \ - r298_scriptdev2.sql \ - r299_scriptdev2.sql \ - r304_mangos.sql \ - r306_scriptdev2.sql \ - r307_mangos.sql \ - r308_mangos.sql \ - r309_mangos.sql \ - r311_mangos.sql \ - r312_mangos.sql \ - r318_mangos.sql \ - r324_mangos.sql \ - r327_mangos.sql \ - r332_scriptdev2.sql \ - r333_mangos.sql \ - r334_mangos.sql \ - r336_mangos.sql \ - r352_mangos.sql \ - r355_mangos.sql \ - r358_mangos.sql \ - r364_mangos.sql \ - r367_mangos.sql \ - r368_mangos.sql \ - r369_mangos.sql \ - r374_mangos.sql \ - r386_mangos.sql \ - r417_mangos.sql \ - r428_mangos.sql \ - r431_mangos.sql \ - r444_mangos.sql \ - r445_mangos.sql \ - r446_mangos.sql \ - r448_scriptdev2.sql \ - r462_mangos.sql \ - r465_mangos.sql \ - r467_mangos.sql \ - r473_mangos.sql \ - r476_mangos.sql \ - r477_mangos.sql \ - r479_mangos.sql \ - r482_mangos.sql \ - r484_mangos.sql \ - r486_mangos.sql \ - r487_mangos.sql \ - r494_mangos.sql \ - r501_mangos.sql \ - r513_mangos.sql \ - r514_mangos.sql \ - r515_mangos.sql \ - r516_mangos.sql \ - r517_mangos.sql \ - r518_mangos.sql \ - r519_mangos.sql \ - r520_mangos.sql \ - r521_mangos.sql \ - r522_mangos.sql \ - r526_mangos.sql \ - r528_mangos.sql \ - r533_mangos.sql \ - r538_scriptdev2.sql \ - r547_mangos.sql \ - r554_mangos.sql \ - r555_mangos.sql \ - r575_mangos.sql \ - r576_mangos.sql \ - r578_mangos.sql \ - r584_mangos.sql \ - r590_mangos.sql \ - r591_mangos.sql \ - r593_mangos.sql \ - r594_mangos.sql \ - r596_mangos.sql \ - r610_mangos.sql \ - r615_scriptdev2.sql \ - r617_mangos.sql \ - r621_mangos.sql \ - r628_mangos.sql \ - r632_mangos.sql \ - r633_mangos.sql \ - r634_scriptdev2.sql \ - r636_mangos.sql \ - r637_mangos.sql \ - r638_mangos.sql \ - r639_mangos.sql \ - r642_mangos.sql \ - r643_mangos.sql \ - r646_mangos.sql \ - r647_scriptdev2.sql \ - r656_scriptdev2.sql \ - r658_mangos.sql \ - r659_mangos.sql \ - r681_scriptdev2.sql \ - r695_scriptdev2.sql \ - r699_scriptdev2_script_texts.sql \ - r700_scriptdev2_script_texts.sql \ - r701_scriptdev2_script_texts.sql \ - r702_scriptdev2_script_texts.sql \ - r703_scriptdev2_script_texts.sql \ - r704_scriptdev2_script_texts.sql \ - r705_scriptdev2_script_texts.sql \ - r706_mangos.sql \ - r707_scriptdev2_script_texts.sql \ - r709_scriptdev2_script_texts.sql \ - r710_scriptdev2_script_texts.sql \ - r713_scriptdev2_script_texts.sql \ - r715_scriptdev2_script_texts.sql \ - r725_scriptdev2_script_texts.sql \ - r726_scriptdev2_script_texts.sql \ - r727_scriptdev2_script_texts.sql \ - r728_scriptdev2_script_texts.sql \ - r729_scriptdev2_script_texts.sql \ - r730_scriptdev2_script_texts.sql \ - r732_scriptdev2_script_texts.sql \ - r735_mangos.sql \ - r735_scriptdev2_script_texts.sql \ - r740_mangos.sql \ - r740_scriptdev2_script_texts.sql \ - r743_mangos.sql \ - r743_scriptdev2_script_texts.sql \ - r745_scriptdev2_script_texts.sql \ - r747_scriptdev2_script_texts.sql \ - r751_scriptdev2_script_texts.sql \ - r755_scriptdev2_script_texts.sql \ - r757_mangos.sql \ - r757_scriptdev2_script_texts.sql \ - r764_mangos.sql \ - r764_scriptdev2_script_texts.sql \ - r766_mangos.sql \ - r766_scriptdev2_script_texts.sql \ - r767_mangos.sql \ - r768_scriptdev2_script_texts.sql \ - r769_mangos.sql \ - r771_scriptdev2_script_texts.sql \ - r772_mangos.sql \ - r777_mangos.sql \ - r778_mangos.sql \ - r779_scriptdev2_script_texts.sql \ - r779_mangos.sql \ - r782_mangos.sql \ - r783_mangos.sql \ - r783_scriptdev2_script_texts.sql \ - r790_mangos.sql \ - r794_mangos.sql \ - r796_scriptdev2_script_texts.sql \ - r802_mangos.sql \ - r804_mangos.sql \ - r804_scriptdev2_script_texts.sql \ - r809_mangos.sql \ - r809_scriptdev2_script_texts.sql \ - r810_mangos.sql diff --git a/sql/Updates/0.0.3/Makefile.am b/sql/Updates/0.0.3/Makefile.am deleted file mode 100644 index 876f4f993..000000000 --- a/sql/Updates/0.0.3/Makefile.am +++ /dev/null @@ -1,304 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# 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 -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse - -## Change installation location -# datadir = scriptdev2/sql/updates/0.0.3 -pkgdatadir = $(datadir)/scriptdev2/sql/updates/0.0.3 - -## Files to be installed -# Install basic SQL files to datadir -pkgdata_DATA = \ - r814_scriptdev2_eventai_scripts.sql \ - r820_scriptdev2_script_texts.sql \ - r822_mangos.sql \ - r822_scriptdev2_script_texts.sql \ - r823_scriptdev2_script_texts.sql \ - r824_mangos.sql \ - r824_scriptdev2_script_texts.sql \ - r825_scriptdev2_script_texts.sql \ - r826_scriptdev2.sql \ - r827_mangos.sql \ - r828_mangos.sql \ - r834_mangos.sql \ - r834_scriptdev2_script_texts.sql \ - r835_mangos.sql \ - r845_mangos.sql \ - r846_scriptdev2.sql \ - r847_scriptdev2_script_texts.sql \ - r848_scriptdev2_script_texts.sql \ - r849_scriptdev2_script_texts.sql \ - r850_mangos.sql \ - r851_scriptdev2_script_texts.sql \ - r852_scriptdev2_script_texts.sql \ - r854_scriptdev2_script_texts.sql \ - r855_scriptdev2_script_texts.sql \ - r856_scriptdev2_script_texts.sql \ - r860_scriptdev2_script_texts.sql \ - r862_scriptdev2_script_texts.sql \ - r863_mangos.sql \ - r872_mangos.sql \ - r883_mangos.sql \ - r895_mangos.sql \ - r900_mangos.sql \ - r903_mangos.sql \ - r903_scriptdev2_script_texts.sql \ - r907_mangos.sql \ - r907_scriptdev2_script_texts.sql \ - r909_mangos.sql \ - r910_scriptdev2_script_texts.sql \ - r912_mangos.sql \ - r912_scriptdev2_script_texts.sql \ - r916_mangos.sql \ - r916_scriptdev2_script_texts.sql \ - r919_mangos.sql \ - r922_scriptdev2_script_waypoint.sql \ - r924_scriptdev2_script_waypoint.sql \ - r936_scriptdev2_script_waypoint.sql \ - r937_mangos.sql \ - r937_scriptdev2_script_texts.sql \ - r937_scriptdev2_script_waypoint.sql \ - r939_scriptdev2_script_texts.sql \ - r940_mangos.sql \ - r941_mangos.sql \ - r945_mangos.sql \ - r945_scriptdev2_script_texts.sql \ - r945_scriptdev2_script_waypoint.sql \ - r947_mangos.sql \ - r949_scriptdev2_script_waypoint.sql \ - r951_scriptdev2_script_waypoint.sql \ - r953_scriptdev2_script_waypoint.sql \ - r956_scriptdev2.sql \ - r963_mangos.sql \ - r964_mangos.sql \ - r965_mangos.sql \ - r965_scriptdev2.sql \ - r972_mangos.sql \ - r972_scriptdev2.sql \ - r973_mangos.sql \ - r973_scriptdev2_script_waypoint.sql \ - r975_mangos.sql \ - r975_scriptdev2.sql \ - r976_mangos.sql \ - r976_scriptdev2.sql \ - r978_mangos.sql \ - r979_mangos.sql \ - r979_scriptdev2_script_texts.sql \ - r980_mangos.sql \ - r982_mangos.sql \ - r982_scriptdev2_script_texts.sql \ - r989_mangos.sql \ - r990_mangos.sql \ - r991_scriptdev2.sql \ - r992_mangos.sql \ - r993_mangos.sql \ - r993_scriptdev2_script_texts.sql \ - r995_mangos.sql \ - r995_scriptdev2.sql \ - r997_mangos.sql \ - r998_mangos.sql \ - r998_scriptdev2_script_texts.sql \ - r1002_scriptdev2.sql \ - r1006_scriptdev2.sql \ - r1008_mangos.sql \ - r1008_scriptdev2.sql \ - r1009_scriptdev2.sql \ - r1010_mangos.sql \ - r1010_scriptdev2.sql \ - r1012_mangos.sql \ - r1012_scriptdev2.sql \ - r1014_mangos.sql \ - r1014_scriptdev2.sql \ - r1016_scriptdev2.sql \ - r1023_scriptdev2.sql \ - r1025_mangos.sql \ - r1030_scriptdev2.sql \ - r1032_mangos.sql \ - r1032_scriptdev2.sql \ - r1039_mangos.sql \ - r1056_scriptdev2.sql \ - r1058_mangos.sql \ - r1058_scriptdev2.sql \ - r1062_mangos.sql \ - r1067_mangos.sql \ - r1068_mangos.sql \ - r1068_scriptdev2.sql \ - r1069_mangos.sql \ - r1073_mangos.sql \ - r1074_scriptdev2.sql \ - r1075_mangos.sql \ - r1080_scriptdev2.sql \ - r1082_mangos.sql \ - r1098_scriptdev2.sql \ - r1099_mangos.sql \ - r1100_mangos.sql \ - r1103_mangos.sql \ - r1104_scriptdev2.sql \ - r1106_mangos.sql \ - r1112_mangos.sql \ - r1116_mangos.sql \ - r1119_mangos.sql \ - r1119_scriptdev2.sql \ - r1120_scriptdev2.sql \ - r1121_mangos.sql \ - r1121_scriptdev2.sql \ - r1123_scriptdev2.sql \ - r1128_mangos.sql \ - r1129_mangos.sql \ - r1129_scriptdev2.sql \ - r1131_mangos.sql \ - r1136_mangos.sql \ - r1136_scriptdev2.sql \ - r1140_scriptdev2.sql \ - r1141_mangos.sql \ - r1145_scriptdev2.sql \ - r1146_scriptdev2.sql \ - r1149_scriptdev2.sql \ - r1152_scriptdev2.sql \ - r1154_mangos.sql \ - r1155_mangos.sql \ - r1169_mangos.sql \ - r1169_scriptdev2.sql \ - r1171_scriptdev2.sql \ - r1173_scriptdev2.sql \ - r1180_mangos.sql \ - r1184_mangos.sql \ - r1197_mangos.sql \ - r1199_mangos.sql \ - r1202_mangos.sql \ - r1202_scriptdev2.sql \ - r1207_mangos.sql \ - r1207_scriptdev2.sql \ - r1210_mangos.sql \ - r1212_mangos.sql \ - r1212_scriptdev2.sql \ - r1215_mangos.sql \ - r1215_scriptdev2.sql \ - r1218_scriptdev2.sql \ - r1221_mangos.sql \ - r1221_scriptdev2.sql \ - r1222_scriptdev2.sql \ - r1234_mangos.sql \ - r1241_scriptdev2.sql \ - r1242_mangos.sql \ - r1242_scriptdev2.sql \ - r1243_mangos.sql \ - r1243_scriptdev2.sql \ - r1249_mangos.sql \ - r1249_scriptdev2.sql \ - r1250_mangos.sql \ - r1250_scriptdev2.sql \ - r1251_scriptdev2.sql \ - r1257_scriptdev2.sql \ - r1258_mangos.sql \ - r1258_scriptdev2.sql \ - r1260_scriptdev2.sql \ - r1261_mangos.sql \ - r1263_mangos.sql \ - r1265_mangos.sql \ - r1265_scriptdev2.sql \ - r1266_mangos.sql \ - r1266_scriptdev2.sql \ - r1280_mangos.sql \ - r1280_scriptdev2.sql \ - r1281_mangos.sql \ - r1282_mangos.sql \ - r1283_mangos.sql \ - r1299_scriptdev2.sql \ - r1300_mangos.sql \ - r1307_mangos.sql \ - r1317_mangos.sql \ - r1317_scriptdev2.sql \ - r1321_mangos.sql \ - r1321_scriptdev2.sql \ - r1322_scriptdev2.sql \ - r1326_scriptdev2.sql \ - r1333_mangos.sql \ - r1334_mangos.sql \ - r1335_scriptdev2.sql \ - r1336_mangos.sql \ - r1336_scriptdev2.sql \ - r1341_scriptdev2.sql \ - r1351_mangos.sql \ - r1351_scriptdev2.sql \ - r1352_mangos.sql \ - r1352_scriptdev2.sql \ - r1354_scriptdev2.sql \ - r1358_mangos.sql \ - r1359_mangos.sql \ - r1359_scriptdev2.sql \ - r1367_mangos.sql \ - r1368_mangos.sql \ - r1369_mangos.sql \ - r1370_mangos.sql \ - r1371_scriptdev2.sql \ - r1374_mangos.sql \ - r1374_scriptdev2.sql \ - r1378_mangos.sql \ - r1378_scriptdev2.sql \ - r1379_mangos.sql \ - r1379_scriptdev2.sql \ - r1380_mangos.sql \ - r1380_scriptdev2.sql \ - r1382_mangos.sql \ - r1383_scriptdev2.sql \ - r1384_scriptdev2.sql \ - r1385_mangos.sql \ - r1385_scriptdev2.sql \ - r1386_mangos.sql \ - r1386_scriptdev2.sql \ - r1388_mangos.sql \ - r1388_scriptdev2.sql \ - r1391_mangos.sql \ - r1391_scriptdev2.sql \ - r1392_mangos.sql \ - r1392_scriptdev2.sql \ - r1394_mangos.sql \ - r1394_scriptdev2.sql \ - r1405_mangos.sql \ - r1405_scriptdev2.sql \ - r1406_mangos.sql \ - r1408_mangos.sql \ - r1408_scriptdev2.sql \ - r1409_mangos.sql \ - r1409_scriptdev2.sql \ - r1410_mangos.sql \ - r1410_scriptdev2.sql \ - r1411_mangos.sql \ - r1411_scriptdev2.sql \ - r1412_mangos.sql \ - r1412_scriptdev2.sql \ - r1413_mangos.sql \ - r1413_scriptdev2.sql \ - r1414_mangos.sql \ - r1414_scriptdev2.sql \ - r1415_mangos.sql \ - r1417_mangos.sql \ - r1418_scriptdev2.sql \ - r1419_mangos.sql \ - r1421_scriptdev2.sql \ - r1422_mangos.sql \ - r1422_scriptdev2.sql \ - r1428_scriptdev2.sql \ - r1430_mangos.sql \ - r1433_mangos.sql \ - r1435_mangos.sql \ - r1436_mangos.sql \ - r1437_scriptdev2.sql \ - r1439_scriptdev2.sql \ - r1441_mangos.sql diff --git a/sql/Updates/0.0.4/Makefile.am b/sql/Updates/0.0.4/Makefile.am deleted file mode 100644 index f9e7ebf10..000000000 --- a/sql/Updates/0.0.4/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# 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 -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse - -## Change installation location -# datadir = scriptdev2/sql/updates/0.0.4 -pkgdatadir = $(datadir)/scriptdev2/sql/updates/0.0.4 - -## Files to be installed -# Install basic SQL files to datadir -pkgdata_DATA = \ - r1453_scriptdev2.sql \ - r1457_scriptdev2.sql \ - r1459_mangos.sql \ - r1460_mangos.sql \ - r1461_mangos.sql \ - r1461_scriptdev2.sql \ - r1463_mangos.sql \ - r1465_scriptdev2.sql \ - r1466_scriptdev2.sql \ - r1470_scriptdev2.sql \ - r1473_scriptdev2.sql \ - r1474_scriptdev2.sql \ - r1476_mangos.sql \ - r1476_scriptdev2.sql \ - r1478_scriptdev2.sql \ - r1486_mangos.sql \ - r1490_scriptdev2.sql \ - r1492_mangos.sql \ - r1493_scriptdev2.sql \ - r1494_mangos.sql \ - r1496_mangos.sql \ - r1498_mangos.sql \ - r1500_mangos.sql \ - r1502_mangos.sql \ - r1503_scriptdev2.sql \ - r1504_scriptdev2.sql \ - r1506_scriptdev2.sql \ - r1508_mangos.sql \ - r1513_scriptdev2.sql \ - r1516_mangos.sql \ - r1516_scriptdev2.sql \ - r1517_scriptdev2.sql \ - r1519_mangos.sql \ - r1523_mangos.sql \ - r1524_scriptdev2.sql \ - r1525_mangos.sql \ - r1525_scriptdev2.sql \ - r1531_mangos.sql \ - r1536_mangos.sql \ - r1538_mangos.sql \ - r1540_mangos.sql \ - r1540_scriptdev2.sql \ - r1542_mangos.sql diff --git a/sql/Updates/Makefile.am b/sql/Updates/Makefile.am deleted file mode 100644 index a566f8618..000000000 --- a/sql/Updates/Makefile.am +++ /dev/null @@ -1,197 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# 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 -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse - -## Change installation location -# datadir = scriptdev2/sql/updates -pkgdatadir = $(datadir)/scriptdev2/sql/updates - -## Files to be installed -# Install basic SQL files to datadir -pkgdata_DATA = \ - r1543_scriptdev2.sql \ - r1544_mangos.sql \ - r1545_scriptdev2.sql \ - r1548_scriptdev2.sql \ - r1549_mangos.sql \ - r1549_scriptdev2.sql \ - r1551_mangos.sql \ - r1554_mangos.sql \ - r1554_scriptdev2.sql \ - r1555_scriptdev2.sql \ - r1556_mangos.sql \ - r1557_scriptdev2.sql \ - r1563_mangos.sql \ - r1567_mangos.sql \ - r1567_scriptdev2.sql \ - r1570_scriptdev2.sql \ - r1577_mangos.sql \ - r1577_scriptdev2.sql \ - r1583_scriptdev2.sql \ - r1584_scriptdev2.sql \ - r1587_scriptdev2.sql \ - r1589_mangos.sql \ - r1590_mangos.sql \ - r1591_mangos.sql \ - r1592_mangos.sql \ - r1593_mangos.sql \ - r1594_mangos.sql \ - r1595_mangos.sql \ - r1596_mangos.sql \ - r1599_mangos.sql \ - r1600_scriptdev2.sql \ - r1602_mangos.sql \ - r1604_mangos.sql \ - r1605_mangos.sql \ - r1607_mangos.sql \ - r1608_mangos.sql \ - r1615_mangos.sql \ - r1615_scriptdev2.sql \ - r1616_mangos.sql \ - r1617_mangos.sql \ - r1621_scriptdev2.sql \ - r1622_mangos.sql \ - r1622_scriptdev2.sql \ - r1624_mangos.sql \ - r1624_scriptdev2.sql \ - r1627_mangos.sql \ - r1627_scriptdev2.sql \ - r1629_mangos.sql \ - r1629_scriptdev2.sql \ - r1632_mangos.sql \ - r1636_mangos.sql \ - r1637_scriptdev2.sql \ - r1642_scriptdev2.sql \ - r1644_scriptdev2.sql \ - r1647_scriptdev2.sql \ - r1647_mangos.sql \ - r1650_mangos.sql \ - r1651_scriptdev2.sql \ - r1652_scriptdev2.sql \ - r1653_mangos.sql \ - r1658_scriptdev2.sql \ - r1660_scriptdev2.sql \ - r1661_mangos.sql \ - r1662_scriptdev2.sql \ - r1665_mangos.sql \ - r1667_mangos.sql \ - r1667_scriptdev2.sql \ - r1668_mangos.sql \ - r1671_mangos.sql \ - r1671_scriptdev2.sql \ - r1679_mangos.sql \ - r1680_mangos.sql \ - r1681_mangos.sql \ - r1683_scriptdev2.sql \ - r1685_mangos.sql \ - r1685_scriptdev2.sql \ - r1687_mangos.sql \ - r1691_mangos.sql \ - r1694_mangos.sql \ - r1698_mangos.sql \ - r1704_mangos.sql \ - r1705_mangos.sql \ - r1705_scriptdev2.sql \ - r1706_scriptdev2.sql \ - r1711_scriptdev2.sql \ - r1715_mangos.sql \ - r1715_scriptdev2.sql \ - r1720_mangos.sql \ - r1720_scriptdev2.sql \ - r1726_mangos.sql \ - r1727_scriptdev2.sql \ - r1728_mangos.sql \ - r1729_scriptdev2.sql \ - r1734_scriptdev2.sql \ - r1736_scriptdev2.sql \ - r1737_scriptdev2.sql \ - r1741_mangos.sql \ - r1750_scriptdev2.sql \ - r1751_scriptdev2.sql \ - r1752_mangos.sql \ - r1753_scriptdev2.sql \ - r1754_scriptdev2.sql \ - r1759_mangos.sql \ - r1763_mangos.sql \ - r1767_mangos.sql \ - r1771_scriptdev2.sql \ - r1777_scriptdev2.sql \ - r1780_scriptdev2.sql \ - r1782_scriptdev2.sql \ - r1783_scriptdev2.sql \ - r1784_scriptdev2.sql \ - r1785_scriptdev2.sql \ - r1786_scriptdev2.sql \ - r1789_scriptdev2.sql \ - r1791_scriptdev2.sql \ - r1797_mangos.sql \ - r1798_mangos.sql \ - r1800_mangos.sql \ - r1800_scriptdev2.sql \ - r1807_scriptdev2.sql \ - r1810_scriptdev2.sql \ - r1813_mangos.sql \ - r1816_scriptdev2.sql \ - r1818_mangos.sql \ - r1818_scriptdev2.sql \ - r1819_mangos.sql \ - r1822_scriptdev2.sql \ - r1824_mangos.sql \ - r1825_mangos.sql \ - r1825_scriptdev2.sql \ - r1826_mangos.sql \ - r1826_scriptdev2.sql \ - r1827_scriptdev2.sql \ - r1828_scriptdev2.sql \ - r1829_mangos.sql \ - r1830_scriptdev2.sql \ - r1831_scriptdev2.sql \ - r1836_mangos.sql \ - r1842_scriptdev2.sql \ - r1843_mangos.sql \ - r1843_scriptdev2.sql \ - r1844_mangos.sql \ - r1845_mangos.sql \ - r1845_scriptdev2.sql \ - r1850_mangos.sql \ - r1850_scriptdev2.sql \ - r1851_mangos.sql \ - r1852_scriptdev2.sql \ - r1853_mangos.sql \ - r1855_scriptdev2.sql \ - r1858_scriptdev2.sql \ - r1859_mangos.sql \ - r1860_scriptdev2.sql \ - r1862_mangos.sql \ - r1863_mangos.sql \ - r1864_mangos.sql \ - r1864_scriptdev2.sql \ - r1865_mangos.sql \ - r1865_scriptdev2.sql \ - r1866_scriptdev2.sql \ - r1868_scriptdev2.sql \ - r1869_mangos.sql \ - r1871_mangos.sql \ - r1875_mangos.sql \ - r1875_scriptdev2.sql \ - r1876_mangos.sql \ - r1876_scriptdev2.sql \ - r1878_mangos.sql \ - r1881_mangos.sql \ - r1882_scriptdev2.sql - diff --git a/sql/mangos_scriptname_full.sql b/sql/mangos_scriptname_full.sql index beb8e86e8..6558bc256 100644 --- a/sql/mangos_scriptname_full.sql +++ b/sql/mangos_scriptname_full.sql @@ -22,8 +22,10 @@ INSERT INTO scripted_areatrigger VALUES (5285,'at_aldurthar_gate'), (5286,'at_aldurthar_gate'), (5287,'at_aldurthar_gate'); -DELETE FROM scripted_areatrigger WHERE entry=4112; -INSERT INTO scripted_areatrigger VALUES (4112,'at_naxxramas'); +DELETE FROM scripted_areatrigger WHERE entry IN (4112, 4113); +INSERT INTO scripted_areatrigger VALUES +(4112,'at_naxxramas'), +(4113,'at_naxxramas'); DELETE FROM scripted_areatrigger WHERE entry=5108; INSERT INTO scripted_areatrigger VALUES (5108,'at_stormwright_shelf'); DELETE FROM scripted_areatrigger WHERE entry IN (3546, 3547, 3548, 3549, 3550, 3552); @@ -40,6 +42,11 @@ INSERT INTO scripted_areatrigger VALUES (2046, 'at_blackrock_spire'); DELETE FROM scripted_areatrigger WHERE entry=5030; INSERT INTO scripted_areatrigger VALUES (5030,'at_spearborn_encampment'); +DELETE FROM scripted_areatrigger WHERE entry IN (3958, 3960); +INSERT INTO scripted_areatrigger VALUES +(3958, 'at_zulgurub'), +(3960, 'at_zulgurub'); + /* BATTLEGROUNDS */ UPDATE creature_template SET ScriptName='npc_spirit_guide' WHERE entry IN (13116, 13117); @@ -55,9 +62,6 @@ UPDATE creature_template SET ScriptName='mob_dementeddruids' WHERE entry=15260; /* GO */ UPDATE gameobject_template SET ScriptName='go_cat_figurine' WHERE entry=13873; -UPDATE gameobject_template SET ScriptName='go_northern_crystal_pylon' WHERE entry=164955; -UPDATE gameobject_template SET ScriptName='go_western_crystal_pylon' WHERE entry=164956; -UPDATE gameobject_template SET ScriptName='go_eastern_crystal_pylon' WHERE entry=164957; UPDATE gameobject_template SET ScriptName='go_barov_journal' WHERE entry=180794; UPDATE gameobject_template SET ScriptName='go_ethereum_prison' WHERE entry BETWEEN 184418 AND 184431; UPDATE gameobject_template SET ScriptName='go_ethereum_stasis' WHERE entry BETWEEN 185465 AND 185467; @@ -79,6 +83,8 @@ UPDATE gameobject_template SET ScriptName='go_blood_filled_orb' WHERE entry=1820 UPDATE gameobject_template SET ScriptName='go_andorhal_tower' WHERE entry IN (176094,176095,176096,176097); UPDATE gameobject_template SET ScriptName='go_scourge_enclosure' WHERE entry=191548; UPDATE gameobject_template SET ScriptName='go_veil_skith_cage' WHERE entry IN (185202,185203,185204,185205); +UPDATE gameobject_template SET ScriptName='go_lab_work_reagents' WHERE entry IN (190462, 190473, 190478, 190459); +UPDATE gameobject_template SET ScriptName='go_hand_of_iruxos_crystal' WHERE entry=176581; /* GUARD */ UPDATE creature_template SET ScriptName='guard_azuremyst' WHERE entry=18038; @@ -121,20 +127,20 @@ UPDATE creature_template SET ScriptName='npc_lunaclaw_spirit' WHERE entry=12144; UPDATE creature_template SET ScriptName='npc_mount_vendor' WHERE entry IN (384,1261,1460,2357,3362,3685,4730,4731,4885,7952,7955,16264,17584); UPDATE creature_template SET ScriptName='npc_doctor' WHERE entry IN (12939,12920); UPDATE creature_template SET ScriptName='npc_injured_patient' WHERE entry IN (12936,12937,12938,12923,12924,12925); -UPDATE creature_template SET ScriptName='' WHERE npcflag!=npcflag|65536 AND ScriptName='npc_innkeeper'; -UPDATE creature_template SET ScriptName='npc_innkeeper' WHERE npcflag=npcflag|65536; UPDATE creature_template SET ScriptName='npc_prof_alchemy' WHERE entry IN (17909,19052,22427); UPDATE creature_template SET ScriptName='npc_prof_blacksmith' WHERE entry IN (5164,11145,11146,11176,11177,11178,11191,11192,11193); -UPDATE creature_template SET ScriptName='npc_engineering_tele_trinket' WHERE entry IN (14742,14743,21493,21494); UPDATE creature_template SET ScriptName='npc_prof_leather' WHERE entry IN (7866,7867,7868,7869,7870,7871); UPDATE creature_template SET ScriptName='npc_prof_tailor' WHERE entry IN (22208,22212,22213); UPDATE creature_template SET ScriptName='npc_rogue_trainer' WHERE entry IN (918,4163,3328,4583,5165,5167,13283,16684); UPDATE creature_template SET ScriptName='npc_sayge' WHERE entry=14822; UPDATE creature_template SET ScriptName='npc_tabard_vendor' WHERE entry=28776; UPDATE creature_template SET ScriptName='npc_locksmith' WHERE entry IN (29665,29725,29728); +-- disabled, but can be used for custom +-- UPDATE creature_template SET ScriptName='' WHERE npcflag!=npcflag|65536 AND ScriptName='npc_innkeeper'; +-- UPDATE creature_template SET ScriptName='npc_innkeeper' WHERE npcflag=npcflag|65536; /* SPELL */ -UPDATE creature_template SET ScriptName='spell_dummy_npc' WHERE entry IN (16880,1200,26616,26643,16518,25793,25758,25752,25792,25753,26421,26841,27808,27122,28068,12298,12296,24918,17326,17654,16847,18879,26270,26268,30146,25084,25085,32149,22105,29330,29338,29329); +UPDATE creature_template SET ScriptName='spell_dummy_npc' WHERE entry IN (16880,1200,26616,26643,16518,25793,25758,25752,25792,25753,26421,26841,27808,27122,28068,12298,12296,24918,17157,17326,17654,16847,18879,26270,26268,30146,25084,25085,32149,22105,29330,29338,29329,28465,28600,29327,29319,28053,28054,28093); UPDATE gameobject_template SET ScriptName='spell_dummy_go' WHERE entry IN (181616,186949); /* */ @@ -292,6 +298,7 @@ UPDATE creature_template SET ScriptName='boss_high_interrogator_gerstahn' WHERE UPDATE creature_template SET ScriptName='boss_magmus' WHERE entry=9938; UPDATE creature_template SET ScriptName='mob_phalanx' WHERE entry=9502; UPDATE creature_template SET ScriptName='npc_grimstone' WHERE entry=10096; +UPDATE creature_template SET ScriptName='npc_theldren_trigger' WHERE entry=16079; UPDATE creature_template SET ScriptName='npc_lokhtos_darkbargainer' WHERE entry=12944; UPDATE creature_template SET ScriptName='npc_kharan_mighthammer' WHERE entry=9021; UPDATE creature_template SET ScriptName='npc_rocknot' WHERE entry=9503; @@ -315,7 +322,7 @@ UPDATE creature_template SET ScriptName='boss_rend_blackhand' WHERE entry=10429; UPDATE creature_template SET ScriptName='boss_pyroguard_emberseer' WHERE entry=9816; /* BLACKWING LAIR */ --- UPDATE instance_template SET ScriptName='instance_blackwing_lair' WHERE map=469; +UPDATE instance_template SET ScriptName='instance_blackwing_lair' WHERE map=469; UPDATE creature_template SET ScriptName='boss_razorgore' WHERE entry=12435; UPDATE creature_template SET ScriptName='boss_vaelastrasz' WHERE entry=13020; UPDATE creature_template SET ScriptName='boss_broodlord' WHERE entry=12017; @@ -347,7 +354,9 @@ UPDATE creature_template SET ScriptName='npc_fizzcrank_fullthrottle' WHERE entry UPDATE creature_template SET ScriptName='npc_iruk' WHERE entry=26219; UPDATE creature_template SET ScriptName='npc_kara_thricestar' WHERE entry=26602; UPDATE creature_template SET ScriptName='npc_nesingwary_trapper' WHERE entry=25835; +UPDATE creature_template SET ScriptName='npc_oil_stained_wolf' WHERE entry=25791; UPDATE gameobject_template SET ScriptName='go_caribou_trap' WHERE entry IN (187982,187995,187996,187997,187998,187999,188000,188001,188002,188003,188004,188005,188006,188007,188008); +UPDATE creature_template SET ScriptName='npc_sinkhole_kill_credit' WHERE entry IN (26248,26249); UPDATE creature_template SET ScriptName='npc_surristrasz' WHERE entry=24795; UPDATE creature_template SET ScriptName='npc_tiare' WHERE entry=30051; UPDATE creature_template SET ScriptName='npc_lurgglbr' WHERE entry=25208; @@ -470,6 +479,7 @@ UPDATE creature_template SET ScriptName='npc_threshwackonator' WHERE entry=6669; /* DEADMINES */ +UPDATE creature_template SET ScriptName='boss_mr_smite' WHERE entry=646; UPDATE instance_template SET ScriptName='instance_deadmines' WHERE map=36; UPDATE gameobject_template SET ScriptName='go_defias_cannon' WHERE entry=16398; UPDATE gameobject_template SET ScriptName='go_door_lever_dm' WHERE entry=101833; @@ -479,9 +489,10 @@ UPDATE gameobject_template SET ScriptName='go_door_lever_dm' WHERE entry=101833; /* DESOLACE */ UPDATE creature_template SET ScriptName='npc_aged_dying_ancient_kodo' WHERE entry IN (4700, 4701, 4702, 11627); +UPDATE creature_template SET ScriptName='npc_dalinda_malem' WHERE entry=5644; /* DIRE MAUL */ - +UPDATE instance_template SET ScriptName='instance_dire_maul' WHERE map=429; /* DRAGONBLIGHT */ UPDATE creature_template SET ScriptName='npc_afrasastrasz' WHERE entry=27575; @@ -566,11 +577,11 @@ UPDATE creature_template SET ScriptName='npc_rathis_tomber' WHERE entry=16224; /* GNOMEREGAN */ UPDATE creature_template SET ScriptName='boss_thermaplugg' WHERE entry=7800; UPDATE gameobject_template SET ScriptName='go_gnomeface_button' WHERE entry BETWEEN 142214 AND 142219; --- UPDATE creature_template SET ScriptName='npc_blastmaster_emi_shortfuse' WHERE entry=7998; +UPDATE creature_template SET ScriptName='npc_blastmaster_emi_shortfuse' WHERE entry=7998; UPDATE instance_template SET ScriptName='instance_gnomeregan' WHERE map=90; /* GRIZZLY HILLS */ - +UPDATE creature_template SET ScriptName='npc_depleted_war_golem' WHERE entry=27017; /* GRUUL'S LAIR */ UPDATE instance_template SET ScriptName='instance_gruuls_lair' WHERE map =565; @@ -652,10 +663,13 @@ UPDATE creature_template SET ScriptName='npc_00x09hl' WHERE entry=7806; UPDATE creature_template SET ScriptName='npc_rinji' WHERE entry=7780; /* HOWLING FJORD */ +DELETE FROM scripted_areatrigger WHERE entry=4778; +INSERT INTO scripted_areatrigger VALUES (4778,'at_ancient_male_vrykul'); +UPDATE creature_template SET ScriptName='npc_ancient_male_vrykul' WHERE entry=24314; UPDATE creature_template SET ScriptName='npc_daegarn' WHERE entry=24151; UPDATE creature_template SET ScriptName='npc_deathstalker_razael' WHERE entry=23998; UPDATE creature_template SET ScriptName='npc_dark_ranger_lyana' WHERE entry=23778; -UPDATE creature_template SET ScriptName='npc_mcgoyver' WHERE entry=24040; +UPDATE creature_template SET ScriptName='npc_greer_orehammer' WHERE entry=23859; UPDATE creature_template SET ScriptName='npc_silvermoon_harry' WHERE entry=24539; /* */ @@ -671,9 +685,9 @@ UPDATE instance_template SET ScriptName='instance_forge_of_souls' WHERE map=632; /* PIT OF SARON */ UPDATE instance_template SET ScriptName='instance_pit_of_saron' WHERE map=658; +UPDATE creature_template SET ScriptName='boss_forgemaster_garfrost' WHERE entry=36494; /* ICECROWN */ -UPDATE creature_template SET ScriptName='npc_arete' WHERE entry=29344; UPDATE creature_template SET ScriptName='npc_dame_evniki_kapsalis' WHERE entry=34885; /* IRONFORGE */ @@ -778,8 +792,6 @@ UPDATE creature_template SET ScriptName='npc_skorn_whitecloud' WHERE entry=3052; /* NAGRAND */ UPDATE creature_template SET ScriptName='mob_lump' WHERE entry=18351; -UPDATE creature_template SET ScriptName='mob_shattered_rumbler' WHERE entry=17157; -UPDATE creature_template SET ScriptName='mob_sunspring_villager' WHERE entry=18240; UPDATE creature_template SET ScriptName='npc_altruis_the_sufferer' WHERE entry=18417; UPDATE creature_template SET ScriptName='npc_greatmother_geyah' WHERE entry=18141; UPDATE creature_template SET ScriptName='npc_lantresor_of_the_blade' WHERE entry=18261; @@ -803,11 +815,12 @@ UPDATE creature_template SET ScriptName='boss_sir_zeliek' WHERE entry=16063; UPDATE creature_template SET ScriptName='boss_lady_blaumeux' WHERE entry=16065; UPDATE creature_template SET ScriptName='boss_rivendare_naxx' WHERE entry=30549; UPDATE creature_template SET ScriptName='boss_patchwerk' WHERE entry=16028; --- UPDATE creature_template SET ScriptName='boss_grobbulus' WHERE entry=15931; +UPDATE creature_template SET ScriptName='boss_grobbulus' WHERE entry=15931; UPDATE creature_template SET ScriptName='boss_gluth' WHERE entry=15932; --- UPDATE creature_template SET ScriptName='boss_thaddius' WHERE entry=15928; --- UPDATE creature_template SET ScriptName='boss_stalagg' WHERE entry=15929; --- UPDATE creature_template SET ScriptName='boss_feugen' WHERE entry=15930; +UPDATE creature_template SET ScriptName='boss_thaddius' WHERE entry=15928; +UPDATE creature_template SET ScriptName='boss_stalagg' WHERE entry=15929; +UPDATE creature_template SET ScriptName='boss_feugen' WHERE entry=15930; +UPDATE creature_template SET ScriptName='npc_tesla_coil' WHERE entry=16218; UPDATE creature_template SET ScriptName='boss_sapphiron' WHERE entry=15989; UPDATE creature_template SET ScriptName='boss_kelthuzad' WHERE entry=15990; @@ -821,6 +834,7 @@ UPDATE creature_template SET ScriptName='npc_protectorate_nether_drake' WHERE en UPDATE creature_template SET ScriptName='npc_veronia' WHERE entry=20162; UPDATE creature_template SET ScriptName='npc_bessy' WHERE entry=20415; UPDATE creature_template SET ScriptName='npc_maxx_a_million' WHERE entry=19589; +UPDATE creature_template SET ScriptName='npc_zeppit' WHERE entry=22484; /* */ /* THE NEXUS */ @@ -899,15 +913,8 @@ UPDATE creature_template SET ScriptName='boss_headless_horseman' WHERE entry=236 UPDATE instance_template SET ScriptName='instance_scholomance' WHERE map=289; UPDATE creature_template SET ScriptName='boss_darkmaster_gandling' WHERE entry=1853; UPDATE creature_template SET ScriptName='boss_death_knight_darkreaver' WHERE entry=14516; -UPDATE creature_template SET ScriptName='boss_lord_alexei_barov' WHERE entry=10504; -UPDATE creature_template SET ScriptName='boss_instructor_malicia' WHERE entry=10505; -UPDATE creature_template SET ScriptName='boss_boss_ras_frostwhisper' WHERE entry=10508; -UPDATE creature_template SET ScriptName='boss_the_ravenian' WHERE entry=10507; UPDATE creature_template SET ScriptName='boss_vectus' WHERE entry=10432; -UPDATE creature_template SET ScriptName='boss_illucia_barov' WHERE entry=10502; -UPDATE creature_template SET ScriptName='boss_doctor_theolen_krastinov' WHERE entry=11261; UPDATE creature_template SET ScriptName='boss_jandice_barov' WHERE entry=10503; -UPDATE creature_template SET ScriptName='boss_lorekeeper_polkelt' WHERE entry=10901; UPDATE creature_template SET ScriptName='boss_kormok' WHERE entry=16118; UPDATE creature_template SET ScriptName='mob_illusionofjandicebarov' WHERE entry=11439; @@ -927,6 +934,7 @@ UPDATE creature_template SET ScriptName='boss_arugal' WHERE entry=4275; /* SHADOWMOON VALLEY */ UPDATE creature_template SET ScriptName='boss_doomwalker' WHERE entry=17711; UPDATE creature_template SET ScriptName='npc_drake_dealer_hurlunk' WHERE entry=23489; +UPDATE creature_template SET ScriptName='npc_dragonmaw_peon' WHERE entry=22252; UPDATE creature_template SET ScriptName='npcs_flanis_swiftwing_and_kagrosh' WHERE entry IN (21725,21727); UPDATE creature_template SET ScriptName='npc_murkblood_overseer' WHERE entry=23309; UPDATE creature_template SET ScriptName='npc_neltharaku' WHERE entry=21657; @@ -936,6 +944,13 @@ UPDATE creature_template SET ScriptName='mob_enslaved_netherwing_drake' WHERE en UPDATE creature_template SET ScriptName='npc_karynaku' WHERE entry=22112; UPDATE creature_template SET ScriptName='npc_wilda' WHERE entry=21027; UPDATE creature_template SET ScriptName='mob_torloth' WHERE entry=22076; +UPDATE creature_template SET ScriptName='npc_totem_of_spirits' WHERE entry=21071; +DELETE FROM scripted_event_id WHERE id IN (13513,13514,13515,13516); +INSERT INTO scripted_event_id VALUES +(13513,'event_spell_soul_captured_credit'), +(13514,'event_spell_soul_captured_credit'), +(13515,'event_spell_soul_captured_credit'), +(13516,'event_spell_soul_captured_credit'); UPDATE creature_template SET ScriptName='npc_lord_illidan_stormrage' WHERE entry=22083; UPDATE gameobject_template SET ScriptName='go_crystal_prison' WHERE entry=185126; @@ -950,6 +965,7 @@ UPDATE creature_template SET ScriptName='npc_shattrathflaskvendors' WHERE entry UPDATE creature_template SET ScriptName='npc_zephyr' WHERE entry=25967; /* SHOLAZAR BASIN */ +UPDATE creature_template SET ScriptName='npc_helice' WHERE entry=28787; UPDATE creature_template SET ScriptName='npc_injured_rainspeaker' WHERE entry=28217; UPDATE creature_template SET ScriptName='npc_mosswalker_victim' WHERE entry=28113; UPDATE creature_template SET ScriptName='npc_vekjik' WHERE entry=28315; @@ -962,7 +978,6 @@ UPDATE creature_template SET ScriptName='npcs_rutgar_and_frankal' WHERE entry IN UPDATE creature_template SET ScriptName='npc_blood_knight_stillblade' WHERE entry=17768; /* SILVERPINE FOREST */ -UPDATE creature_template SET ScriptName='npc_astor_hadren' WHERE entry=6497; UPDATE creature_template SET ScriptName='npc_deathstalker_erland' WHERE entry=1978; UPDATE creature_template SET ScriptName='npc_deathstalker_faerleia' WHERE entry=2058; @@ -1004,6 +1019,7 @@ UPDATE creature_template SET ScriptName='mobs_spectral_ghostly_citizen' WHERE en UPDATE creature_template SET ScriptName='mob_restless_soul' WHERE entry=11122; UPDATE creature_template SET ScriptName='mob_freed_soul' WHERE entry=11136; UPDATE gameobject_template SET ScriptName='go_gauntlet_gate' WHERE entry=175357; +UPDATE gameobject_template SET ScriptName='go_service_gate' WHERE entry=175368; /* SUNKEN TEMPLE */ UPDATE instance_template SET ScriptName='instance_sunken_temple' WHERE map=109; @@ -1111,12 +1127,14 @@ UPDATE creature_template SET ScriptName='mob_rotting_forest_rager' WHERE entry=2 UPDATE creature_template SET ScriptName='mob_unkor_the_ruthless' WHERE entry=18262; UPDATE creature_template SET ScriptName='npc_akuno' WHERE entry=22377; UPDATE creature_template SET ScriptName='npc_floon' WHERE entry=18588; +UPDATE creature_template SET ScriptName='npc_hungry_nether_ray' WHERE entry=23439; UPDATE creature_template SET ScriptName='npc_letoll' WHERE entry=22458; UPDATE creature_template SET ScriptName='npc_mana_bomb_exp_trigger' WHERE entry=20767; UPDATE gameobject_template SET ScriptName='go_mana_bomb' WHERE entry=184725; UPDATE creature_template SET ScriptName='npc_skyguard_handler_irena' WHERE entry=23413; UPDATE creature_template SET ScriptName='npc_slim' WHERE entry=19679; UPDATE creature_template SET ScriptName='npc_captive_child' WHERE entry=22314; +UPDATE creature_template SET ScriptName='npc_isla_starmane' WHERE entry=18760; /* THOUSAND NEEDLES */ UPDATE creature_template SET ScriptName='npc_kanati' WHERE entry=10638; @@ -1209,9 +1227,12 @@ UPDATE gameobject_template SET ScriptName='go_activation_crystal' WHERE entry=19 UPDATE creature_template SET ScriptName='npc_door_seal' WHERE entry=30896; UPDATE creature_template SET ScriptName='npc_sinclari' WHERE entry=30658; UPDATE creature_template SET ScriptName='npc_teleportation_portal' WHERE entry IN (31011,30679,32174); +UPDATE creature_template SET ScriptName='boss_ichoron' WHERE entry IN (29313,32234); +UPDATE creature_template SET ScriptName='boss_erekem' WHERE entry IN (29315,32226); /* WAILING CAVERNS */ UPDATE instance_template SET ScriptName='instance_wailing_caverns' WHERE map=43; +UPDATE creature_template SET ScriptName='npc_disciple_of_naralex' WHERE entry=3678; /* WESTERN PLAGUELANDS */ UPDATE creature_template SET ScriptName='npcs_dithers_and_arbington' WHERE entry IN (11056,11057); @@ -1261,9 +1282,9 @@ UPDATE creature_template SET ScriptName='mob_darkheart' WHERE entry=24246; UPDATE creature_template SET ScriptName='mob_koragg' WHERE entry=24247; UPDATE creature_template SET ScriptName='boss_nalorakk' WHERE entry=23576; UPDATE creature_template SET ScriptName='boss_zuljin' WHERE entry=23863; -UPDATE creature_template SET ScriptName='mob_jandalai_firebomb' WHERE entry=23920; -UPDATE creature_template SET ScriptName='mob_amanishi_hatcher' WHERE entry IN (23818,24504); -UPDATE creature_template SET ScriptName='mob_hatchling' WHERE entry=23598; +UPDATE creature_template SET ScriptName='npc_janalai_firebomb' WHERE entry=23920; +UPDATE creature_template SET ScriptName='npc_amanishi_hatcher' WHERE entry IN (23818,24504); +UPDATE creature_template SET ScriptName='npc_hatchling' WHERE entry=23598; UPDATE creature_template SET ScriptName='npc_forest_frog' WHERE entry=24396; /* ZUL'DRAK */ diff --git a/sql/scriptdev2_create_database.sql b/sql/scriptdev2_create_database.sql index 747dab2ac..2aa367fd5 100644 --- a/sql/scriptdev2_create_database.sql +++ b/sql/scriptdev2_create_database.sql @@ -1,4 +1,3 @@ CREATE DATABASE `scriptdev2` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; -GRANT ALL PRIVILEGES ON `scriptdev2` . * TO 'mangos'@'localhost' WITH GRANT OPTION; - +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, LOCK TABLES ON `scriptdev2`.* TO 'mangos'@'localhost'; diff --git a/sql/scriptdev2_script_full.sql b/sql/scriptdev2_script_full.sql index 3a78857a0..890952299 100644 --- a/sql/scriptdev2_script_full.sql +++ b/sql/scriptdev2_script_full.sql @@ -3,7 +3,7 @@ -- DELETE FROM sd2_db_version; -INSERT INTO sd2_db_version (version) VALUES ('ScriptDev2 (for MaNGOS 10610+) '); +INSERT INTO sd2_db_version (version) VALUES ('ScriptDev2 (for MaNGOS 11421+) '); -- -- Below contains data for table `script_texts` mainly used in C++ parts. @@ -584,9 +584,9 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1000559,'I\'d rather die fighting than live like a slave.',0,0,0,0,'exhausted vrykul SAY_RAND_ATTACK2'), (-1000560,'Enough! I will teach you some manners, wench!',0,0,0,0,'exhausted vrykul SAY_RAND_ATTACK3'), -(-1000561,'My wounds are grave. Forgive my slow pace but my injuries won''t allow me to walk any faster.',0,0,0,0,'SAY_CORPORAL_KEESHAN_1'), +(-1000561,'My wounds are grave. Forgive my slow pace but my injuries won\'t allow me to walk any faster.',0,0,0,0,'SAY_CORPORAL_KEESHAN_1'), (-1000562,'Ah, fresh air, at last! I need a moment to rest.',0,0,0,0,'SAY_CORPORAL_KEESHAN_2'), -(-1000563,'The Blackrock infestation is thick in these parts. I will do my best to keep the pace. Let''s go!',0,0,0,0,'SAY_CORPORAL_KEESHAN_3'), +(-1000563,'The Blackrock infestation is thick in these parts. I will do my best to keep the pace. Let\'s go!',0,0,0,0,'SAY_CORPORAL_KEESHAN_3'), (-1000564,'Marshal Marris, sir. Corporal Keeshan of the 12th Sabre Regiment returned from battle and reporting for duty!',0,0,0,0,'SAY_CORPORAL_KEESHAN_4'), (-1000565,'Brave adventurer, thank you for rescuing me! I am sure Marshal Marris will reward your kind deed.',0,0,0,0,'SAY_CORPORAL_KEESHAN_5'), @@ -663,7 +663,55 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1000621,'All systems on-line. Prepare yourself, we leave shortly.',0,0,0,0,'maxx SAY_START'), (-1000622,'Be careful in there and come back in one piece!',0,0,0,0,'maxx SAY_ALLEY_FAREWELL'), (-1000623,'Proceed.',0,0,0,0,'maxx SAY_CONTINUE'), -(-1000624,'You\'re back! Were you able to get all of the machines?',0,0,0,0,'maxx SAY_ALLEY_FINISH'); +(-1000624,'You\'re back! Were you able to get all of the machines?',0,0,0,0,'maxx SAY_ALLEY_FINISH'), + +(-1000625,'%s gathers the warp chaser\'s blood.',0,2,0,0,'zeppit EMOTE_GATHER_BLOOD'), + +(-1000626,'Intiating energy collection.',0,0,0,0,'depleted golem SAY_GOLEM_CHARGE'), +(-1000627,'Energy collection complete.',0,0,0,0,'depleted golem SAY_GOLEM_COMPLETE'), + +(-1000628,'%s feeds on the freshly-killed warp chaser.',0,2,0,0,'hungry ray EMOTE_FEED'), + +(-1000629,' Damsel in distress over here!',0,0,0,0,'isla starmane - SAY_ISLA_PERIODIC_1'), +(-1000630,'Hello? Help?',0,0,0,0,'isla starmane - SAY_ISLA_PERIODIC_2'), +(-1000631,'Don\'t leave me in here! Cause if you do I will find you!',0,0,0,0,'isla starmane - SAY_ISLA_PERIODIC_3'), +(-1000632,'Ok, let\'s get out of here!',0,0,0,0,'isla starmane - SAY_ISLA_START'), +(-1000633,'You sure you\'re ready? Take a moment.',0,0,0,0,'isla starmane - SAY_ISLA_WAITING'), +(-1000634,'Alright, let\'s do this!',0,0,0,0,'isla starmane - SAY_ISLA_LEAVE_BUILDING'), + +(-1000635,'So then we too are cursed?',0,0,0,0,'ancient vrykul SAY_VRYKUL_CURSED'), +(-1000636,'%s points to the infant.',0,2,0,0,'ancient vrykul EMOTE_VRYKUL_POINT'), +(-1000637,'%s sobs.',0,2,0,0,'ancient vrykul EMOTE_VRYKUL_SOB'), +(-1000638,'The gods have forsaken us! We must dispose of it before Ymiron is notified!',0,0,0,0,'ancient vrykul SAY_VRYKUL_DISPOSE'), +(-1000639,'NO! You cannot! I beg of you! It is our child!',0,0,0,0,'ancient vrykul SAY_VRYKUL_BEG'), +(-1000640,'Then what are we to do, wife? The others cannot find out. Should they learn of this aberration, we will all be executed.',0,0,0,0,'ancient vrykul SAY_VRYKUL_WHAT'), +(-1000641,'I... I will hide it. I will hide it until I find it a home, far away from here...',0,0,0,0,'ancient vrykul SAY_VRYKUL_HIDE'), + +(-1000642,'It\'s a female.',0,5,0,0,'leopard icepaw SAY_ITS_FEMALE'), +(-1000643,'It\'s an angry male!',0,5,0,0,'leopard icepaw SAY_ITS_MALE'), + +(-1000644,'Ouch! That\'s it, I quit the target business!',0,0,0,0,'SAY_LUCKY_HIT_1'), +(-1000645,'My ear! You grazed my ear!',0,0,0,0,'SAY_LUCKY_HIT_2'), +(-1000646,'Not the \'stache! Now I\'m asymmetrical!',0,0,0,5,'SAY_LUCKY_HIT_3'), +(-1000647,'Good shot!',0,0,0,4,'SAY_LUCKY_HIT_APPLE'), +(-1000648,'Stop whining. You\'ve still got your luck.',0,0,0,0,'SAY_DROSTAN_GOT_LUCKY_1'), +(-1000649,'Bah, it\'s an improvement.',0,0,0,11,'SAY_DROSTAN_GOT_LUCKY_2'), +(-1000650,'Calm down lad, it\'s just a birdshot!',0,0,0,0,'SAY_DROSTAN_HIT_BIRD_1'), +(-1000651,'The only thing hurt is your pride, lad! Buck up!',0,0,0,0,'SAY_DROSTAN_HIT_BIRD_2'), + +(-1000652,'Me so hungry! YUM!',0,0,0,71,'dragonmaw peon SAY_PEON_1'), +(-1000653,'Hey... me not feel so good.',0,0,0,0,'dragonmaw peon SAY_PEON_2'), +(-1000654,'You is bad orc... baaad... or... argh!',0,0,0,0,'dragonmaw peon SAY_PEON_3'), +(-1000655,'Time for eating!?',0,0,0,71,'dragonmaw peon SAY_PEON_4'), +(-1000656,'It put the mutton in the stomach!',0,0,0,71,'dragonmaw peon SAY_PEON_5'), + +(-1000657,'Let\'s get the hell out of here.',0,0,0,5,'helice SAY_HELICE_ACCEPT'), +(-1000658,'Listen up, Venture Company goons! Rule #1: Never keep the prisoner near the explosives.',0,0,0,25,'helice SAY_HELICE_EXPLOSIVES_1'), +(-1000659,'Or THIS is what you get.',0,0,0,0,'helice SAY_HELICE_EXPLODE_1'), +(-1000660,'It\'s getting a little hot over here. Shall we move on?',0,0,0,11,'helice SAY_HELICE_MOVE_ON'), +(-1000661,'Oh, look, it\'s another cartload of explosives! Let\'s help them dispose of it.',0,0,0,25,'helice SAY_HELICE_EXPLOSIVES_2'), +(-1000662,'You really shouldn\'t play with this stuff. Someone could get hurt.',0,0,0,5,'helice SAY_HELICE_EXPLODE_2'), +(-1000663,'We made it! Thank you for getting me out of that hell hole. Tell Hemet to expect me!',0,0,0,4,'helice SAY_HELICE_COMPLETE'); -- -1 033 000 SHADOWFANG KEEP INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -696,10 +744,33 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen -- -1 036 000 DEADMINES INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES -(-1036000,'You there, check out that noise!',5775,1,7,0,'smite INST_SAY_ALARM1'), -(-1036001,'We\'re under attack! A vast, ye swabs! Repel the invaders!',5777,1,7,0,'smite INST_SAY_ALARM2'); +(-1036000,'You there, check out that noise.',5775,1,7,0,'smite INST_SAY_ALARM1'), +(-1036001,'We\'re under attack! A vast, ye swabs! Repel the invaders!',5777,1,7,0,'smite INST_SAY_ALARM2'), +(-1036002,'You land lubbers are tougher than I thought! I\'ll have to improvise!',5778,0,0,21,'smite SAY_PHASE_2'), +(-1036003,'D\'ah! Now you\'re making me angry!',5779,0,0,15,'smite SAY_PHASE_3'); -- -1 043 000 WAILING CAVERNS +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1043000,'At last! Naralex can be awakened! Come aid me, brave adventurers!',0,6,0,0,'Disciple of Naralex - SAY_INTRO'), +(-1043001,'I must make the nescessary preparations before the awakening ritual can begin. You must protect me!',0,0,0,0,'SAY_PREPARE'), +(-1043002,'These caverns were once a temple of promise for regrowth in the Barrens. Now, they are the halls of nightmares.',0,0,0,0,'Disciple of Naralex - SAY_FIRST_CORNER'), +(-1043003,'Come. We must continue. There is much to be done before we can pull Naralex from his nightmare.',0,0,0,0,'Disciple of Naralex - SAY_CONTINUE'), +(-1043004,'Within this circle of fire I must cast the spell to banish the spirits of the slain Fanglords.',0,0,0,0,'Disciple of Naralex - SAY_CIRCLE_BANISH'), +(-1043005,'The caverns have been purified. To Naralex\'s chamber we go!',0,0,0,0,'Disciple of Naralex - SAY_PURIFIED'), +(-1043006,'Beyond this corridor, Naralex lies in fitful sleep. Let us go awaken him before it is too late.',0,0,0,0,'Disciple of Naralex - SAY_NARALEX_CHAMBER'), +(-1043007,'Protect me brave souls as I delve into the Emerald Dream to rescue Naralex and put an end to this corruption!',0,1,0,0,'Disciple of Naralex - SAY_BEGIN_RITUAL'), +(-1043008,'%s begins to perform the awakening ritual on Naralex.',0,2,0,0,'Disciple of Naralex - EMOTE_RITUAL_BEGIN'), +(-1043009,'%s tosses fitfully in troubled sleep.',0,2,0,0,'Naralex - EMOTE_NARALEX_AWAKE'), +(-1043010,'%s writhes in agony. The Disciple seems to be breaking through.',0,2,0,0,'Naralex - EMOTE_BREAK_THROUGH'), +(-1043011,'%s dreams up a horrendous vision. Something stirs beneath the murky waters.',0,2,0,0,'Naralex - EMOTE_VISION'), +(-1043012,'This $N is a minion from Naralex\'s nightmare no doubt!.',0,0,0,0,'Disciple of Naralex - SAY_MUTANUS'), +(-1043013,'I AM AWAKE, AT LAST!',5789,1,0,0,'Naralex - SAY_NARALEX_AWAKE'), +(-1043014,'At last! Naralex awakes from the nightmare.',0,0,0,0,'Disciple of Naralex - SAY_AWAKE'), +(-1043015,'Ah, to be pulled from the dreaded nightmare! I thank you, my loyal Disciple, along with your brave companions.',0,0,0,0,'Naralex - SAY_NARALEX_THANKYOU'), +(-1043016,'We must go and gather with the other Disciplies. There is much work to be done before I can make another attempt to restore the Barrens. Farewell, brave souls!',0,0,0,0,'Naralex - SAY_FAREWELL'), +(-1043017,'Attacked! Help get this $N off of me!',0,0,0,0,'Disciple of Naralex - SAY_AGGRO_1'), +(-1043018,'Help!',0,0,0,0,'Disciple of Naralex - SAY_AGGRO_2'), +(-1043019,'Deal with this $N! I need to prepare to awake Naralex!',0,0,0,0,'Disciple of Naralex - SAY_AGGRO_3'); -- -1 047 000 RAZORFEN KRAUL @@ -716,35 +787,37 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen -- -1 090 000 GNOMEREGAN INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES (-1090000,'With your help, I can evaluate these tunnels.',0,0,0,1,'emi shortfuse SAY_START'), -(-1090001,'Let\'s see if we can find out where these Troggs are coming from.... and put a stop to the invasion!',0,0,0,1,'emi shortfuse SAY_INTRO_1'), -- ' -(-1090002,'Such devastation... what a horrible mess....',0,0,0,5,'emi shortfuse SAY_INTRO_2'), -(-1090003,'It\'s quiet here....',0,0,0,1,'emi shortfuse SAY_INTRO_3'), -- ' +(-1090001,'Let\'s see if we can find out where these Troggs are coming from.... and put a stop to the invasion!',0,0,0,1,'emi shortfuse SAY_INTRO_1'), +(-1090002,'Such devastation... what a horrible mess...',0,0,0,5,'emi shortfuse SAY_INTRO_2'), +(-1090003,'It\'s quiet here....',0,0,0,1,'emi shortfuse SAY_INTRO_3'), (-1090004,'...too quiet.',0,0,0,1,'emi shortfuse SAY_INTRO_4'), (-1090005,'Look! Over there at the tunnel wall!',0,0,0,25,'emi shortfuse SAY_LOOK_1'), (-1090006,'Trogg incursion! Defend me while I blast the hole closed!',0,0,0,5,'emi shortfuse SAY_HEAR_1'), -(-1090007,'Get this, $n off of me!',0,0,0,0,'emi shortfuse SAY_AGGRO'), -(-1090008,'I don\'t think one charge is going to cut it. Keep fending them off!',0,0,0,0,'emi shortfuse SAY_CHARGE_1'), -- ' +(-1090007,'Get this, $n off of me!',0,0,0,0,'emi shortfuse SAY_AGGRO_1'), +(-1090008,'I don\'t think one charge is going to cut it. Keep fending them off!',0,0,0,0,'emi shortfuse SAY_CHARGE_1'), (-1090009,'The charges are set. Get back before they blow!',0,0,0,5,'emi shortfuse SAY_CHARGE_2'), (-1090010,'Incoming blast in 10 seconds!',0,1,0,5,'emi shortfuse SAY_BLOW_1_10'), -(-1090011,'Incoming blast in 5 seconds. Clear the tunnel!',0,1,0,5,'emi shortfuse SAY_BLOW_1_5'), +(-1090011,'Incoming blast in 5 seconds. Clear the tunnel! Stay back!',0,1,0,5,'emi shortfuse SAY_BLOW_1_5'), (-1090012,'FIRE IN THE HOLE!',0,1,0,25,'emi shortfuse SAY_BLOW_1'), -(-1090013,'Well done! without your help I would have never been able to thwart that wave of troggs.',0,0,0,4,'emi shortfuse SAY_FINISH_1'), +(-1090013,'Well done! Without your help I would have never been able to thwart that wave of troggs.',0,0,0,4,'emi shortfuse SAY_FINISH_1'), (-1090014,'Did you hear something?',0,0,0,6,'emi shortfuse SAY_LOOK_2'), (-1090015,'I heard something over there.',0,0,0,25,'emi shortfuse SAY_HEAR_2'), (-1090016,'More troggs! Ward them off as I prepare the explosives!',0,0,0,0,'emi shortfuse SAY_CHARGE_3'), -(-1090017,'The final charges are set. Stand back!',0,0,0,1,'emi shortfuse SAY_CHARGE_4'), -(-1090018,'10 seconds to blast! Stand back!',0,1,0,5,'emi shortfuse SAY_BLOW_2_10'), -(-1090019,'5 seconds until detonation!',0,1,0,5,'emi shortfuse SAY_BLOW_2_5'), -(-1090020,'Good work! I detonate the explosives that no more troggs can reach the surface.',0,0,0,1,'emi shortfuse SAY_BLOW_SOON'), +(-1090017,'The final charge is set. Stand back!',0,0,0,1,'emi shortfuse SAY_CHARGE_4'), +(-1090018,'10 seconds to blast! Stand back!!!',0,1,0,5,'emi shortfuse SAY_BLOW_2_10'), +(-1090019,'5 seconds until detonation!!!!!',0,1,0,5,'emi shortfuse SAY_BLOW_2_5'), +(-1090020,'Nice work! I\'ll set off the charges to prevent any more troggs from making it to the surface.',0,0,0,1,'emi shortfuse SAY_BLOW_SOON'), (-1090021,'FIRE IN THE HOLE!',0,1,0,0,'emi shortfuse SAY_BLOW_2'), -(-1090022,'Superb! Because of your help, my people stand a chance of re-taking our belowed city. Three cheers to you!',0,0,0,0,'emi shortfuse SAY_FINISH_2'), +(-1090022,'Superb! Because of your help, my people stand a chance of re-taking our beloved city. Three cheers to you!',0,0,0,0,'emi shortfuse SAY_FINISH_2'), (-1090023,'We come from below! You can never stop us!',0,1,0,1,'grubbis SAY_GRUBBIS_SPAWN'), (-1090024,'Usurpers! Gnomeregan is mine!',5807,1,0,0,'thermaplugg SAY_AGGRO'), (-1090025,'My machines are the future! They\'ll destroy you all!',5808,1,0,0,'thermaplugg SAY_PHASE'), (-1090026,'Explosions! MORE explosions! I\'ve got to have more explosions!',5809,1,0,0,'thermaplugg SAY_BOMB'), -(-1090027,'...and stay dead! He got served',5810,1,0,0,'thermaplugg SAY_SLAY'); +(-1090027,'...and stay dead! He got served',5810,1,0,0,'thermaplugg SAY_SLAY'), + +(-1090028,'$n attacking! Help!',0,0,0,0,'emi shortfuse SAY_AGGRO_2'); -- -1 109 000 SUNKEN TEMPLE INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -872,6 +945,8 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1269028,'Gul\'dan speaks the truth! We should return at once to tell our brothers of the news! Retreat back trought the portal!',0,1,0,0,'medivh SAY_ORCS_ANSWER'); -- -1 289 000 SCHOLOMANCE +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1289000,'School is in session!',0,1,0,0,'gandling SAY_GANDLING_SPAWN'); -- -1 309 000 ZUL'GURUB INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -904,8 +979,8 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1309020,'PRIDE HERALDS THE END OF YOUR WORLD. COME, MORTALS! FACE THE WRATH OF THE SOULFLAYER!',8414,1,0,0,'hakkar SAY_AGGRO'), (-1309021,'Fleeing will do you no good, mortals!',0,1,0,0,'hakkar SAY_FLEEING'), -(-1309022,'You dare set foot upon Hakkari holy ground? Minions of Hakkar, destroy the infidels!',0,1,0,0,'hakkar SAY_MINION_DESTROY'), -(-1309023,'Minions of Hakkar, hear your God. The sanctity of this temple has been compromised. Invaders encroach upon holy ground! The Altar of Blood must be protected. Kill them all!',0,1,0,0,'hakkar SAY_PROTECT_ALTAR'), +(-1309022,'You dare set foot upon Hakkari holy ground? Minions of Hakkar, destroy the infidels!',0,6,0,0,'hakkar SAY_MINION_DESTROY'), +(-1309023,'Minions of Hakkar, hear your God. The sanctity of this temple has been compromised. Invaders encroach upon holy ground! The Altar of Blood must be protected. Kill them all!',0,6,0,0,'hakkar SAY_PROTECT_ALTAR'), (-1309024,'%s goes into a rage after seeing his raptor fall in battle!',0,2,0,0,'mandokir EMOTE_RAGE'); @@ -919,7 +994,20 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1329004,'An Ash\'ari Crystal has fallen! Stay true to the Lich King, my brethren, and attempt to resummon it.',0,6,0,0,'thuzadin acolyte SAY_ANNOUNCE_ZIGGURAT_1'), (-1329005,'One of the Ash\'ari Crystals has been destroyed! Slay the intruders!',0,6,0,0,'thuzadin acolyte SAY_ANNOUNCE_ZIGGURAT_2'), (-1329006,'An Ash\'ari Crystal has been toppled! Restore the ziggurat before the Necropolis is vulnerable!',0,6,0,0,'thuzadin acolyte SAY_ANNOUNCE_ZIGGURAT_3'), -(-1329007,'The Ash\'ari Crystals have been destroyed! The Slaughterhouse is vulnerable!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RIVENDARE'); +(-1329007,'The Ash\'ari Crystals have been destroyed! The Slaughterhouse is vulnerable!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RIVENDARE'), + +(-1329008,'Intruders at the Service Gate! Lord Rivendare must be warned!',0,6,0,0,'barthilas SAY_WARN_BARON'), +(-1329009,'Intruders! More pawns of the Argent Dawn, no doubt. I already count one of their number among my prisoners. Withdraw from my domain before she is executed!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_START'), +(-1329010,'You\'re still here? Your foolishness is amusing! The Argent Dawn wench needn\'t suffer in vain. Leave at once and she shall be spared!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_10_MIN'), +(-1329011,'I shall take great pleasure in taking this poor wretch\'s life! It\'s not too late, she needn\'t suffer in vain. Turn back and her death shall be merciful!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_5_MIN'), +(-1329012,'May this prisoner\'s death serve as a warning. None shall defy the Scourge and live!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_FAIL'), +(-1329013,'So you see fit to toy with the Lich King\'s creations? Ramstein, be sure to give the intruders a proper greeting.',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RAMSTEIN'), +(-1329014,'Time to take matters into my own hands. Come. Enter my domain and challenge the might of the Scourge!',0,6,0,0,'baron rivendare SAY_UNDEAD_DEFEAT'), +(-1329015,'You did it... you\'ve slain Baron Rivendare! The Argent Dawn shall hear of your valiant deeds!',0,0,0,0,'ysida SAY_EPILOGUE'), + +(-1329016,'Today you have unmade what took me years to create! For this you shall all die by my hand!',0,1,0,0,'dathrohan SAY_AGGRO'), +(-1329017,'You fools think you can defeat me so easily? Face the true might of the Nathrezim!',0,1,0,0,'dathrohan SAY_TRANSFORM'), +(-1329018,'Damn you mortals! All my plans of revenge, all my hate... all burned to ash...',0,0,0,0,'dathrohan SAY_DEATH'); -- -1 349 000 MARAUDON @@ -932,10 +1020,10 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1409002,'%s refuses to die while its master is in trouble.',0,2,0,0,'core rager EMOTE_LOWHP'), (-1409003,'Reckless mortals, none may challenge the sons of the living flame!',8035,1,0,0,'majordomo SAY_AGGRO'), -(-1409004,'The runes of warding have been destroyed! Hunt down the infedels my bretheren.',8039,1,0,0,'majordomo SAY_SPAWN'), +(-1409004,'The runes of warding have been destroyed! Hunt down the infedels my bretheren.',8039,6,0,0,'majordomo SAY_SPAWN'), (-1409005,'Ashes to Ashes!',8037,1,0,0,'majordomo SAY_SLAY'), (-1409006,'Burn mortals! Burn for this transgression!',8036,1,0,0,'majordomo SAY_SPECIAL'), -(-1409007,'Impossible! Stay your attack mortals! I submitt! I submitt! Brashly you have come to rest the secrets of the living flame. You will soon regret the recklessness of your quest. I go now to summon the lord whos house this is. Should you seek an audiance with him your paltry lives will surly be forfit. Nevertheless seek out his lair if you dare!',8038,1,0,0,'majordomo SAY_DEFEAT'), +(-1409007,'Impossible! Stay your attack mortals! I submitt! I submitt!',8038,1,0,0,'majordomo SAY_DEFEAT_1'), (-1409008,'Behold Ragnaros, the Firelord! He who was ancient when this world was young! Bow before him, mortals! Bow before your ending!',8040,1,0,0,'ragnaros SAY_SUMMON_MAJ'), (-1409009,'TOO SOON! YOU HAVE AWAKENED ME TOO SOON, EXECUTUS! WHAT IS THE MEANING OF THIS INTRUSION?',8043,1,0,0,'ragnaros SAY_ARRIVAL1_RAG'), @@ -948,9 +1036,19 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1409015,'BY FIRE BE PURGED!',8046,1,0,0,'ragnaros SAY_HAND'), (-1409016,'TASTE THE FLAMES OF SULFURON!',8047,1,0,0,'ragnaros SAY_WRATH'), (-1409017,'DIE INSECT!',8051,1,0,0,'ragnaros SAY_KILL'), -(-1409018,'MY PATIENCE IS DWINDILING! COME NATS TO YOUR DEATH!',8048,1,0,0,'ragnaros SAY_MAGMABURST'); +(-1409018,'MY PATIENCE IS DWINDILING! COME NATS TO YOUR DEATH!',8048,1,0,0,'ragnaros SAY_MAGMABURST'), + +(-1409019,'You think you\'ve won already? Perhaps you\'ll need another lesson in pain!',0,1,0,0,'majordomo SAY_LAST_ADD'), +(-1409020,'Brashly you have come to rest the secrets of the living flame. You will soon regret the recklessness of your quest.',0,1,0,0,'majordomo SAY_DEFEAT_2'), +(-1409021,'I go now to summon the lord whos house this is. Should you seek an audiance with him your paltry lives will surly be forfit. Nevertheless seek out his lair if you dare!',0,1,0,0,'majordomo SAY_DEFEAT_3'), +(-1409022,'My flame! Please don\'t take away my flame... ',8042,1,0,0,'ragnaros SAY_ARRIVAL4_MAJ'), +(-1409023,'Very well, $N.',0,0,0,0,'majordomo SAY_SUMMON_0'), +(-1409024,'Impudent whelps! You''ve rushed headlong to your own deaths! See now, the master stirs!',0,1,0,0,'majordomo SAY_SUMMON_1'); -- -1 429 000 DIRE MAUL +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1429000,'The demon is loose! Quickly we must restrain him!',0,6,0,0,'highborne summoner SAY_FREE_IMMOLTHAR'), +(-1429001,'Who dares disrupt the sanctity of Eldre\'Thalas? Face me, cowards!',0,6,0,0,'prince tortheldrin SAY_KILL_IMMOLTHAR'); -- -1 469 000 BLACKWING LAIR INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -962,7 +1060,7 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1469004,'In this world where time is your enemy, it is my greatest ally. This grand game of life that you think you play in fact plays you. To that I say...',0,0,0,0,'victor_nefarius SAY_GAMESBEGIN_1'), (-1469005,'Let the games begin!',8280,1,0,0,'victor_nefarius SAY_GAMESBEGIN_2'), -(-1469006,'Ah, the heroes. You are persistent, aren\'t you. Your allied attempted to match his power against mine, and had to pay the price. Now he shall serve me, by slaughtering you. Get up little red wyrm and destroy them!',8279,1,0,0,'victor_nefarius SAY_VAEL_INTRO'), +(-1469006,'Ah, the heroes. You are persistent, aren\'t you. Your allied attempted to match his power against mine, and had to pay the price. Now he shall serve me, by slaughtering you. Get up little red wyrm and destroy them!',8279,1,0,0,'victor_nefarius SAY_NEFARIUS_CORRUPT'), (-1469007,'Well done, my minions. The mortals\' courage begins to wane! Now, let\'s see how they contend with the true Lord of Blackrock Spire!',8288,1,0,0,'nefarian SAY_AGGRO'), (-1469008,'Enough! Now you vermin shall feel the force of my birthright, the fury of the earth itself.',8289,1,0,0,'nefarian SAY_XHEALTH'), @@ -991,7 +1089,7 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1469029,'Nefarius\' hate has made me stronger than ever before. You should have fled, while you could, mortals! The fury of Blackrock courses through my veins!',8285,1,0,0,'vaelastrasz SAY_HALFLIFE'), (-1469030,'Forgive me $N, your death only adds to my failure.',8284,1,0,0,'vaelastrasz SAY_KILLTARGET'), -(-1469031,'REUSE ME',0,0,0,0,'REUSE ME'); +(-1469031,'Death Knights, get over here!',0,1,0,0,'nefarian SAY_DEATH_KNIGHT'); -- -1 509 000 RUINS OF AHN'QIRAJ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -1277,8 +1375,8 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1533080,'Breathe no more!',8850,1,0,0,'noth SAY_SLAY2'), (-1533081,'I will serve the master... in... death!',8848,1,0,0,'noth SAY_DEATH'), -(-1533082,'%s takes in a deep breath...',0,2,0,0,'sapphiron EMOTE_BREATH'), -(-1533083,'%s resumes his attacks!',0,2,0,0,'sapphiron EMOTE_GROUND'), +(-1533082,'%s takes in a deep breath...',0,3,0,0,'sapphiron EMOTE_BREATH'), +(-1533083,'%s resumes his attacks!',0,3,0,0,'sapphiron EMOTE_GROUND'), (-1533084,'Our preparations continue as planned, master.',14467,1,0,0,'kelthuzad SAY_SAPP_DIALOG1'), (-1533085,'It is good that you serve me so faithfully. Soon, all will serve the Lich King and in the end, you shall be rewarded...so long as you do not falter.',8881,1,0,0,'kelthuzad SAY_SAPP_DIALOG2_LICH'), @@ -1366,7 +1464,9 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1533155,'Corpse Scarabs appear from a Crypt Guard\'s corpse!',0,3,0,0,'anubrekhan EMOTE_CORPSE_SCARABS'), (-1533156,'%s casts Unyielding Pain on everyone!',0,3,0,0,'lady_blaumeux EMOTE_UNYIELDING_PAIN'), -(-1533157,'%s casts Condemation on everyone!',0,3,0,0,'sir_zeliek EMOTE_CONDEMATION'); +(-1533157,'%s casts Condemation on everyone!',0,3,0,0,'sir_zeliek EMOTE_CONDEMATION'), + +(-1533158,'%s injects you with a mutagen!',0,5,0,0,'grobbulus EMOTE_INJECTION'); -- -1 534 000 THE BATTLE OF MT. HYJAL INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -1732,12 +1832,12 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen -- -1 554 000 THE MECHANAR INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES -(-1554000,'I predict a painful death.',11101,1,0,0,'gyro SAY_AGGRO'), -(-1554001,'Measure twice; cut once!',11104,1,0,0,'gyro SAY_SAW_ATTACK1'), -(-1554002,'If my division is correct, you should be quite dead.',11105,1,0,0,'gyro SAY_SAW_ATTACK2'), -(-1554003,'Your strategy was flawed!',11102,1,0,0,'gyro SAY_SLAY1'), -(-1554004,'Yes, the only logical outcome.',11103,1,0,0,'gyro SAY_SLAY2'), -(-1554005,'An unforseen... contingency',11106,1,0,0,'gyro SAY_DEATH'), +(-1554000,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554001,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554002,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554003,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554004,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554005,'REUSE_ME',0,0,0,0,'REUSE_ME'), (-1554006,'You have approximately five seconds to live.',11109,1,0,0,'ironhand SAY_AGGRO_1'), (-1554007,'With the precise angle and velocity...',11112,1,0,0,'ironhand SAY_HAMMER_1'), @@ -2893,7 +2993,26 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1608005,'A Portal Guardian defends the new portal!',0,3,0,0,'EMOTE_GUARDIAN_PORTAL'), (-1608006,'An elite Blue Dragonflight squad appears from the portal!',0,3,0,0,'EMOTE_DRAGONFLIGHT_PORTAL'), -(-1608007,'A Guardian Keeper emerges from the portal!',0,3,0,0,'EMOTE_KEEPER_PORTAL'); +(-1608007,'A Guardian Keeper emerges from the portal!',0,3,0,0,'EMOTE_KEEPER_PORTAL'), + +(-1608008,'Free to--mm--fly now. Ra-aak... Not find us--ekh-ekh! Escape!',14218,1,0,0,'erekem SAY_RELEASE_EREKEM'), +(-1608009,'I... am fury... unrestrained!',14229,1,0,0,'ichoron SAY_RELEASE_ICHORON'), +(-1608010,'Back in business! Now to execute an exit strategy.',14498,1,0,0,'xevozz SAY_RELEASE_XEVOZZ'), +(-1608011,'I am... renewed.',13995,1,0,0,'zuramat SAY_RELEASE_ZURAMAT'), + +(-1608012,'Not--caww--get in way of--rrak-rrak--flee!',14219,1,0,0,'erekem SAY_AGGRO'), +(-1608013,'My---raaak--favorite! Awk awk awk! Raa-kaa!',14220,1,0,0,'erekem SAY_ADD_DIE_1'), +(-1608014,'Nasty little...A-ak,kaw! Kill! Yes,kill you!',14221,1,0,0,'erekem SAY_ADD_DIE_2'), +(-1608018,'No--kaw,kaw--flee...',14225,1,0,0,'erekem SAY_DEATH'), + +(-1608019,'Stand aside, mortals!',14230,1,0,0,'ichoron SAY_AGGRO'), +(-1608020,'I will not be contained! Ngyah!!',14233,1,0,0,'ichoron SAY_SHATTERING'), +(-1608021,'Water can hold any form, take any shape... overcome any obstacle.',14232,1,0,0,'ichoron SAY_SHIELD'), +(-1608022,'I am a force of nature!',14234,1,0,0,'ichoron SAY_SLAY_1'), +(-1608023,'I shall pass!',14235,1,0,0,'ichoron SAY_SLAY_2'), +(-1608024,'You can not stop the tide!',14236,1,0,0,'ichoron SAY_SLAY_3'), +(-1608025,'I shall consume,decimate, devastate,and destroy! Yield now to the wrath of the pounding sea!',14231,1,0,0,'ichoron SAY_ENRAGE'), +(-1608026,'I... recede.',14237,1,0,0,'ichoron SAY_DEATH'); -- -1 609 000 EBON HOLD (DK START) INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -3132,7 +3251,7 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen -- -1 649 000 TRIAL OF THE CRUSADER INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES -(-1649000,'Welcome champions, you have heard the call of the argent crusade and you have boldly answered. It is here in the crusaders coliseum that you will face your greatest challenges. Those of you who survive the rigors of the coliseum will join the Argent Crusade on it''s marsh to ice crown citadel.',16036,1,0,0,'tirion SAY_TIRION_RAID_INTRO_LONG'), +(-1649000,'Welcome champions, you have heard the call of the argent crusade and you have boldly answered. It is here in the crusaders coliseum that you will face your greatest challenges. Those of you who survive the rigors of the coliseum will join the Argent Crusade on it\'s marsh to ice crown citadel.',16036,1,0,0,'tirion SAY_TIRION_RAID_INTRO_LONG'), (-1649001,'Welcome to the trials of the crusader. Only the most powerful combatants of azeroth are allowed to undergo these trials. You are among the worthy few.',16053,1,0,0,'tirion SAY_RAID_TRIALS_INTRO'), (-1649002,'Hailing from the deepest, darkest carverns of the storm peaks, Gormok the Impaler! Battle on, heroes!',16038,1,0,0,'tirion SAY_TIRION_BEAST_1'), @@ -3148,26 +3267,26 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1649011,'Prepare for oblivion!',16269,1,0,0,'wilfred SAY_WILFRED_JARAXXUS_INTRO_2'), (-1649012,'Ah ha! Behold the absolute power of Wilfred Fizzlebang, master summoner! You are bound to ME, demon!',16270,1,0,0,'wilfred SAY_WILFRED_JARAXXUS_INTRO_3'), (-1649013,'Trifling gnome, your arrogance will be your undoing!',16143,1,0,0,'jaraxxus SAY_JARAXXUS_JARAXXAS_INTRO_1'), -(-1649014,'But I''m in charge her-',16271,1,0,0,'wilfred SAY_WILFRED_DEATH'), +(-1649014,'But I\'m in charge her-',16271,1,0,0,'wilfred SAY_WILFRED_DEATH'), (-1649015,'Quickly, heroes! Destroy the demon lord before it can open a portal to its twisted demonic realm!',16044,1,0,0,'tirion SAY_TIRION_JARAXXUS_INTRO_2'), (-1649016,'The loss of Wilfred Fizzlebang, while unfortunate, should be a lesson to those that dare dabble in dark magic. Alas, you are victorious and must now face the next challenge.',16045,1,0,0,'tirion SAY_TIRION_JARAXXUS_EXIT_1'), (-1649017,'Treacherous Alliance dogs! You summon a demon lord against warriors of the Horde!? Your deaths will be swift!',16021,1,0,0,'garrosh SAY_GARROSH_JARAXXUS_EXIT_1'), -(-1649018,'The Alliance doesn''t need the help of a demon lord to deal with Horde filth. Come, pig!',16064,1,0,0,'varian SAY_VARIAN_JARAXXUS_SLAY'), +(-1649018,'The Alliance doesn\'t need the help of a demon lord to deal with Horde filth. Come, pig!',16064,1,0,0,'varian SAY_VARIAN_JARAXXUS_SLAY'), (-1649019,'Everyone, calm down! Compose yourselves! There is no conspiracy at play here. The warlock acted on his own volition - outside of influences from the Alliance. The tournament must go on!',16046,1,0,0,'tirion SAY_TIRION_JARAXXUS_EXIT_2'), -(-1649020,'The next battle will be against the Argent Crusade''s most powerful knights! Only by defeating them will you be deemed worthy...',16047,1,0,0,'tirion SAY_TIRION_PVP_INTRO_1'), +(-1649020,'The next battle will be against the Argent Crusade\'s most powerful knights! Only by defeating them will you be deemed worthy...',16047,1,0,0,'tirion SAY_TIRION_PVP_INTRO_1'), (-1649021,'The Horde demands justice! We challenge the Alliance. Allow us to battle in place of your knights, paladin. We will show these dogs what it means to insult the Horde!',16023,1,0,0,'garrosh SAY_GARROSH_PVP_A_INTRO_1'), (-1649022,'Our honor has been besmirched! They make wild claims and false accusations against us. I demand justice! Allow my champions to fight in place of your knights, Tirion. We challenge the Horde!',16066,1,0,0,'varian SAY_VARIAN_PVP_H_INTRO_1'), (-1649023,'Very well, I will allow it. Fight with honor!',16048,1,0,0,'tirion SAY_TIRION_PVP_INTRO_2'), (-1649024,'Fight for the glory of the Alliance, heroes! Honor your king and your people!',16065,1,0,0,'varian SAY_VARIAN_PVP_A_INTRO_2'), -(-1649025,'Show them no mercy, Horde champions! LOK''TAR OGAR!',16022,1,0,0,'garrosh SAY_GARROSH_PVP_H_INTRO_2'), +(-1649025,'Show them no mercy, Horde champions! LOK\'TAR OGAR!',16022,1,0,0,'garrosh SAY_GARROSH_PVP_H_INTRO_2'), (-1649026,'Glory to the alliance.',16067,1,0,0,'varian SAY_VARIAN_PVP_A_WIN'), (-1649027,'That was just a taste of what the future brings. FOR THE HORDE!',16024,1,0,0,'garrosh SAY_GARROSH_PVP_H_WIN'), (-1649028,'A shallow and tragic victory. We are weaker as a whole from the losses suffered today. Who but the Lich King could benefit from such foolishness? Great warriors have lost their lives. And for what? The true threat looms ahead - the Lich King awaits us all in death.',16049,1,0,0,'tirion SAY_TIRION_PVP_WIN'), -(-1649029,'Only by working together will you overcome the final challenge. From the depths of Icecrown come two of the Scourge''s most powerful lieutenants: fearsome val''kyr, winged harbingers of the Lich King!',16050,1,0,0,'tirion SAY_TIRION_TWINS_INTRO'), +(-1649029,'Only by working together will you overcome the final challenge. From the depths of Icecrown come two of the Scourge\'s most powerful lieutenants: fearsome val\'kyr, winged harbingers of the Lich King!',16050,1,0,0,'tirion SAY_TIRION_TWINS_INTRO'), (-1649030,'Let the games begin!',16037,1,0,0,'tirion SAY_RAID_INTRO_SHORT'), -(-1649031,'Not even the lich king''s most powerful minions could stand against the alliance. All hail our victors.',16068,1,0,0,'varian SAY_VARIAN_TWINS_A_WIN'), +(-1649031,'Not even the lich king\'s most powerful minions could stand against the alliance. All hail our victors.',16068,1,0,0,'varian SAY_VARIAN_TWINS_A_WIN'), (-1649032,'Do you still question the might of the Horde, paladin? We will take on all comers!',16025,1,0,0,'garrosh SAY_GARROSH_TWINS_H_WIN'), (-1649033,'A mighty blow has been dealt to the Lich King! You have proven yourselves able bodied champions of the Argent Crusade. Together we will strike at Icecrown Citadel and destroy what remains of the Scourge! There is no challenge that we cannot face united!',16051,1,0,0,'tirion SAY_TIRION_TWINS_WIN'), @@ -3191,7 +3310,7 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1649048,'Weakling!',16017,1,0,0,'garrosh SAY_GARROSH_PVP_A_SLAY_1'), (-1649049,'Pathetic!',16018,1,0,0,'garrosh SAY_GARROSH_PVP_A_SLAY_2'), (-1649050,'Overpowered.',16019,1,0,0,'garrosh SAY_GARROSH_PVP_A_SLAY_3'), -(-1649051,'Lok''tar!',16020,1,0,0,'garrosh SAY_GARROSH_PVP_A_SLAY_4'), +(-1649051,'Lok\'tar!',16020,1,0,0,'garrosh SAY_GARROSH_PVP_A_SLAY_4'), (-1649052,'Hah!',16060,1,0,0,'varian SAY_VARIAN_PVP_H_SLAY_1'), (-1649053,'Hardly a challenge!',16061,1,0,0,'varian SAY_VARIAN_PVP_H_SLAY_2'), (-1649054,'Worthless scrub.',16062,1,0,0,'varian SAY_VARIAN_PVP_H_SLAY_3'), @@ -3347,15 +3466,34 @@ INSERT INTO gossip_texts (entry,content_default,comment) VALUES -- -3 000 100 GENERAL MAPS (not instance maps) INSERT INTO gossip_texts (entry,content_default,comment) VALUES (-3000101,'Taruk send me to collect what you owe.','silvermoon harry GOSSIP_ITEM_GAMBLING_DEBT'), -(-3000102,'Here\'s the money.','silvermoon harry GOSSIP_ITEM_PAYING'), +(-3000102,'Pay up, Harry!','silvermoon harry GOSSIP_ITEM_PAYING'), (-3000103,'I am ready to travel to you village now.','rainspeaker GOSSIP_ITEM_READY'), (-3000104,'','mosswalker victim GOSSIP_ITEM_PULSE'), -(-3000105,'Ezekiel said that you might have a certain book...','dirty larry GOSSIP_ITEM_BOOK'); +(-3000105,'Ezekiel said that you might have a certain book...','dirty larry GOSSIP_ITEM_BOOK'), +(-3000106,'Show me where I can fly.','greer orehammer GOSSIP_ITEM_TAXI'), +(-3000107,'[PH] Get Presicion Bombs','greer orehammer GOSSIP_ITEM_GET_BOMBS'), +(-3000108,'[PH] Start bombing mission','greer orehammer GOSSIP_ITEM_FLIGHT'); -- -3 090 000 GNOMEREGAN INSERT INTO gossip_texts (entry,content_default,comment) VALUES (-3090000,'I am ready to begin.','emi shortfuse GOSSIP_ITEM_START'); +-- -3 043 000 WAILING CAVERNS +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3043000,'Let the event begin!','Disciple of Naralex - GOSSIP_ITEM_BEGIN'); + +-- -3 409 000 MOLTEN CORE +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3409000,'Tell me more.','majordomo_executus GOSSIP_ITEM_SUMMON_1'), +(-3409001,'What else do you have to say?','majordomo_executus GOSSIP_ITEM_SUMMON_2'), +(-3409002,'You challenged us and we have come. Where is this master you speak of?','majordomo_executus GOSSIP_ITEM_SUMMON_3'); + +-- -3 469 000 BLACKWING LAIR +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3469000,'I\'ve made no mistakes.','victor_nefarius GOSSIP_ITEM_NEFARIUS_1'), +(-3469001,'You have lost your mind, Nefarius. You speak in riddles.','victor_nefarius GOSSIP_ITEM_NEFARIUS_2'), +(-3469002,'Please do.','victor_nefarius GOSSIP_ITEM_NEFARIUS_3'); + -- -3 560 000 ESCAPE FROM DURNHOLDE (OLD HILLSBRAD) INSERT INTO gossip_texts (entry,content_default,comment) VALUES (-3560000,'I am ready to go to Durnholde Keep.','brazen GOSSIP_ITEM_READY'), @@ -4780,7 +4918,7 @@ INSERT INTO script_waypoint VALUES (20129, 25, -8375.42,-4250.41, -205.14,5000, ''); DELETE FROM script_waypoint WHERE entry=20415; -INSERT INTO script_waypoint VALUES +INSERT INTO script_waypoint VALUES (20415, 0, 2488.77, 2184.89, 104.64, 0, ""), (20415, 1, 2478.72, 2184.77, 98.58, 0, ""), (20415, 2, 2473.52, 2184.71, 99.00, 0, ""), @@ -5091,6 +5229,31 @@ INSERT INTO script_waypoint VALUES (28217,23, 5638.541504, 4594.924805, -137.495117, 0, 'summon'), (28217,24, 5638.061523, 4579.945801, -138.029465, 0, ''); +DELETE FROM script_waypoint WHERE entry=28787; +INSERT INTO script_waypoint (entry, pointid, location_x, location_y, location_z, waittime, point_comment) VALUES +(28787, 1, 5913.516113, 5379.034668, -98.896118, 0, ''), +(28787, 2, 5917.750977, 5374.519043, -98.869781, 0, 'SAY_HELICE_EXPLOSIVES_1'), +(28787, 3, 5926.428711, 5372.145020, -98.884453, 0, ''), +(28787, 4, 5929.214844, 5377.803223, -99.020065, 0, ''), +(28787, 5, 5927.621582, 5378.564941, -99.047890, 0, ''), +(28787, 6, 5917.622070, 5383.494629, -106.310204, 0, ''), +(28787, 7, 5908.991211, 5387.655762, -106.310204, 0, ''), +(28787, 8, 5906.287109, 5390.496582, -106.041801, 0, ''), +(28787, 9, 5902.415039, 5399.741211, -99.306595, 0, ''), +(28787, 10, 5901.444336, 5404.593262, -96.759636, 0, ''), +(28787, 11, 5897.860352, 5406.656250, -96.029709, 0, ''), +(28787, 12, 5892.254395, 5401.291504, -95.848808, 0, ''), +(28787, 13, 5887.421875, 5386.701172, -95.400146, 0, 'SAY_HELICE_EXPLOSIVES_2'), +(28787, 14, 5883.308105, 5385.057617, -94.423698, 0, ''), +(28787, 15, 5879.180664, 5375.897461, -95.088066, 0, ''), +(28787, 16, 5872.613281, 5363.473633, -97.703575, 0, ''), +(28787, 17, 5857.971191, 5354.929688, -98.586090, 0, ''), +(28787, 18, 5848.729004, 5345.326660, -99.428978, 0, ''), +(28787, 19, 5842.330566, 5335.018555, -100.421455, 0, ''), +(28787, 20, 5832.164551, 5323.145020, -98.703285, 0, ''), +(28787, 21, 5824.738770, 5315.712891, -97.758018, 0, ''), +(28787, 22, 5819.650879, 5305.409668, -97.481796, 10000, 'SAY_HELICE_COMPLETE'); + DELETE FROM script_waypoint WHERE entry=28912; INSERT INTO script_waypoint VALUES (28912, 0, 1653.518, -6038.374, 127.585, 0, 'Jump off'), @@ -5226,28 +5389,164 @@ INSERT INTO script_waypoint VALUES (25208,24,4254.66,6205.16,-0.170,0,''), (25208,25,4270.07,6188.42,0.059,15000,'Lurgglbr - final point'); --- uncomment when it is implemented --- DELETE FROM script_waypoint WHERE entry=7998; --- INSERT INTO script_waypoint VALUES --- (7998, 01, -510.1305, -132.6899, -152.5, 0, ''), --- (7998, 02, -511.0994, -129.74, -153.8453, 0, ''), --- (7998, 03, -511.7897, -127.4764, -155.5505, 0, ''), --- (7998, 04, -512.9688, -124.926, -156.1146, 5000, ''), --- (7998, 05, -513.9719, -120.2358, -156.1161, 0, ''), --- (7998, 06, -514.3875, -115.1896, -156.1165, 0, ''), --- (7998, 07, -514.3039, -111.4777, -155.5205, 0, ''), --- (7998, 08, -514.8401, -107.6633, -154.8925, 0, ''), --- (7998, 09, -518.9943, -101.4161, -154.6482, 27000, ''), --- (7998, 10, -526.9984, -98.14884, -155.6253, 0, ''), --- (7998, 11, -534.5686, -105.4101, -155.989, 30000, ''), --- (7998, 12, -535.5336, -104.6947, -155.9713, 0, ''), --- (7998, 13, -541.6304, -98.6583, -155.8584, 25000, ''), --- (7998, 14, -535.0923, -99.91748, -155.9742, 0, ''), --- (7998, 15, -519.0099, -101.5097, -154.6766, 3000, ''), --- (7998, 16, -504.4659, -97.84802, -150.9554, 30000, ''), --- (7998, 17, -506.9069, -89.14736, -151.083, 23000, ''), --- (7998, 18, -512.7576, -101.9025, -153.198, 0, ''), --- (7998, 19, -519.9883, -124.8479, -156.128, 86400000, 'this npc should not reset on wp end'); +DELETE FROM script_waypoint WHERE entry=7998; +INSERT INTO script_waypoint VALUES +(7998, 01, -510.1305, -132.6899, -152.5, 0, ''), +(7998, 02, -511.0994, -129.74, -153.8453, 0, ''), +(7998, 03, -511.7897, -127.4764, -155.5505, 0, ''), +(7998, 04, -512.9688, -124.926, -156.1146, 5000, ''), +(7998, 05, -513.9719, -120.2358, -156.1161, 0, ''), +(7998, 06, -514.3875, -115.1896, -156.1165, 0, ''), +(7998, 07, -514.3039, -111.4777, -155.5205, 0, ''), +(7998, 08, -514.8401, -107.6633, -154.8925, 0, ''), +(7998, 09, -518.9943, -101.4161, -154.6482, 27000, ''), +(7998, 10, -526.9984, -98.14884, -155.6253, 0, ''), +(7998, 11, -534.5686, -105.4101, -155.989, 30000, ''), +(7998, 12, -535.5336, -104.6947, -155.9713, 0, ''), +(7998, 13, -541.6304, -98.6583, -155.8584, 25000, ''), +(7998, 14, -535.0923, -99.91748, -155.9742, 0, ''), +(7998, 15, -519.0099, -101.5097, -154.6766, 3000, ''), +(7998, 16, -504.4659, -97.84802, -150.9554, 30000, ''), +(7998, 17, -506.9069, -89.14736, -151.083, 23000, ''), +(7998, 18, -512.7576, -101.9025, -153.198, 0, ''), +(7998, 19, -519.9883, -124.8479, -156.128, 86400000, 'this npc should not reset on wp end'); + +DELETE FROM script_waypoint WHERE entry = 18760; +INSERT INTO script_waypoint (entry, pointid, location_x, location_y, location_z, waittime, point_comment) VALUES +(18760, 01, -2267.07, 3091.46, 13.8271, 0, ''), +(18760, 02, -2270.92, 3094.19, 13.8271, 0, ''), +(18760, 03, -2279.08, 3100.04, 13.8271, 0, ''), +(18760, 04, -2290.05, 3105.07, 13.8271, 0, ''), +(18760, 05, -2297.64, 3112.32, 13.8271, 0, ''), +(18760, 06, -2303.89, 3118.22, 13.8231, 10000, 'building exit'), +(18760, 07, -2307.77, 3123.47, 13.7257, 0, ''), +(18760, 08, -2310.67, 3126.2, 12.5841, 0, ''), +(18760, 09, -2311.48, 3126.98, 12.2769, 0, ''), +(18760, 10, -2316.91, 3132.13, 11.9261, 0, ''), +(18760, 11, -2320.43, 3135.54, 11.7436, 0, ''), +(18760, 12, -2327.38, 3139.36, 10.9431, 0, ''), +(18760, 13, -2332.02, 3142.05, 9.81277, 0, ''), +(18760, 14, -2338.21, 3145.32, 9.31001, 0, ''), +(18760, 15, -2343.1, 3148.91, 8.84879, 0, ''), +(18760, 16, -2347.76, 3153.15, 7.71049, 0, ''), +(18760, 17, -2351.04, 3156.12, 6.66476, 0, ''), +(18760, 18, -2355.15, 3163.18, 5.11997, 0, ''), +(18760, 19, -2359.01, 3169.83, 3.64343, 0, ''), +(18760, 20, -2364.85, 3176.81, 2.32802, 0, ''), +(18760, 21, -2368.77, 3181.69, 1.53285, 0, ''), +(18760, 22, -2371.76, 3185.11, 0.979932, 0, ''), +(18760, 23, -2371.85, 3191.89, -0.293048, 0, ''), +(18760, 24, -2370.99, 3199.6, -1.10504, 0, 'turn left 1'), +(18760, 25, -2376.24, 3205.54, -1.04152, 0, ''), +(18760, 26, -2380.99, 3211.61, -1.16891, 0, ''), +(18760, 27, -2384.04, 3218.4, -1.15279, 0, ''), +(18760, 28, -2385.41, 3226.22, -1.23403, 0, ''), +(18760, 29, -2386.02, 3233.89, -1.31723, 0, ''), +(18760, 30, -2384.7, 3239.82, -1.51903, 0, ''), +(18760, 31, -2382.98, 3247.94, -1.39163, 0, ''), +(18760, 32, -2379.68, 3254.22, -1.25927, 0, ''), +(18760, 33, -2375.27, 3259.69, -1.22925, 0, ''), +(18760, 34, -2369.62, 3264.55, -1.1879, 0, ''), +(18760, 35, -2364.01, 3268.32, -1.48348, 0, ''), +(18760, 36, -2356.61, 3272.31, -1.5505, 0, ''), +(18760, 37, -2352.3, 3274.63, -1.35693, 0, ''), +(18760, 38, -2348.54, 3278.04, -1.04161, 0, 'turn left 2'), +(18760, 39, -2347.56, 3282.41, -0.75979, 0, ''), +(18760, 40, -2348.29, 3288.91, -0.63215, 0, ''), +(18760, 41, -2349.68, 3298.84, -1.07864, 0, ''), +(18760, 42, -2351.15, 3308.52, -1.38864, 0, ''), +(18760, 43, -2352.2, 3317.14, -1.59873, 0, ''), +(18760, 44, -2351.59, 3325.51, -1.92624, 0, ''), +(18760, 45, -2350.88, 3333.38, -2.32506, 0, ''), +(18760, 46, -2350.05, 3342.68, -2.51886, 0, ''), +(18760, 47, -2350.12, 3347.32, -2.57528, 0, ''), +(18760, 48, -2348.72, 3353.7, -2.72689, 0, ''), +(18760, 49, -2346.53, 3360.85, -2.9756, 0, ''), +(18760, 50, -2344.83, 3365.46, -3.3311, 0, ''), +(18760, 51, -2342.68, 3368.91, -3.74526, 0, ''), +(18760, 52, -2340.25, 3371.44, -4.10499, 0, ''), +(18760, 53, -2337.4, 3373.47, -4.44362, 0, ''), +(18760, 54, -2332.68, 3376.02, -5.19648, 0, ''), +(18760, 55, -2326.69, 3379.64, -6.24757, 0, ''), +(18760, 56, -2321.2, 3383.98, -7.28247, 0, ''), +(18760, 57, -2317.81, 3387.78, -8.40093, 0, ''), +(18760, 58, -2315.3, 3392.47, -9.63431, 0, ''), +(18760, 59, -2314.69, 3396.6, -10.2031, 0, ''), +(18760, 60, -2315.48, 3402.35, -10.8211, 0, 'gate'), +(18760, 61, -2317.55, 3409.27, -11.3309, 5000, 'Firewing point exit'), +(18760, 62, -2320.69, 3412.99, -11.5207, 0, ''), +(18760, 63, -2326.88, 3417.89, -11.6105, 0, ''), +(18760, 64, -2332.73, 3421.74, -11.5659, 0, ''), +(18760, 65, -2337.23, 3424.89, -11.496, 0, ''), +(18760, 66, -2339.57, 3429.17, -11.3782, 0, ''), +(18760, 67, -2341.66, 3435.86, -11.3746, 5000, 'Wave and transform'), +(18760, 68, -2342.15, 3443.94, -11.2562, 2000, 'final destination'); + +DELETE FROM script_waypoint WHERE entry=3678; +INSERT INTO script_waypoint VALUES +(3678, 0, -134.925, 125.468, -78.16, 0, ''), +(3678, 1, -125.684, 132.937, -78.42, 0, ''), +(3678, 2, -113.812, 139.295, -80.98, 0, ''), +(3678, 3, -109.854, 157.538, -80.20, 0, ''), +(3678, 4, -108.640, 175.207, -79.74, 0, ''), +(3678, 5, -108.668, 195.457, -80.64, 0, ''), +(3678, 6, -111.007, 219.007, -86.58, 0, ''), +(3678, 7, -102.408, 232.821, -91.52, 0, 'first corner SAY_FIRST_CORNER'), +(3678, 8, -92.434, 227.742, -90.75, 0, ''), +(3678, 9, -82.456, 224.853, -93.57, 0, ''), +(3678, 10, -67.789, 208.073, -93.34, 0, ''), +(3678, 11, -43.343, 205.295, -96.37, 0, ''), +(3678, 12, -34.676, 221.394, -95.82, 0, ''), +(3678, 13, -32.582, 238.573, -93.51, 0, ''), +(3678, 14, -42.149, 258.672, -92.88, 0, ''), +(3678, 15, -55.257, 274.696, -92.83, 0, 'circle of flames SAY_CIRCLE_BANISH'), +(3678, 16, -48.604, 287.584, -92.46, 0, ''), +(3678, 17, -47.236, 296.093, -90.88, 0, ''), +(3678, 18, -35.618, 309.067, -89.73, 0, ''), +(3678, 19, -23.573, 311.376, -88.60, 0, ''), +(3678, 20, -8.692, 302.389, -87.43, 0, ''), +(3678, 21, -1.237, 293.268, -85.55, 0, ''), +(3678, 22, 10.398, 279.294, -85.86, 0, ''), +(3678, 23, 23.108, 264.693, -86.69, 0, ''), +(3678, 24, 31.996, 251.436, -87.62, 0, ''), +(3678, 25, 43.374, 233.073, -87.61, 0, ''), +(3678, 26, 54.438, 212.048, -89.50, 3000, 'chamber entrance SAY_NARALEX_CHAMBER'), +(3678, 27, 78.794, 208.895, -92.84, 0, ''), +(3678, 28, 88.392, 225.231, -94.46, 0, ''), +(3678, 29, 98.758, 233.938, -95.84, 0, ''), +(3678, 30, 107.248, 233.054, -95.98, 0, ''), +(3678, 31, 112.825, 233.907, -96.39, 0, ''), +(3678, 32, 114.634, 236.969, -96.04, 1000, 'naralex SAY_BEGIN_RITUAL'), +(3678, 33, 127.385, 252.279, -90.07, 0, ''), +(3678, 34, 121.595, 264.488, -91.55, 0, ''), +(3678, 35, 115.472, 264.253, -91.50, 0, ''), +(3678, 36, 99.988, 252.790, -91.51, 0, ''), +(3678, 37, 96.347, 245.038, -90.34, 0, ''), +(3678, 38, 82.201, 216.273, -86.10, 0, ''), +(3678, 39, 75.112, 206.494, -84.80, 0, ''), +(3678, 40, 27.174, 201.064, -72.31, 0, ''), +(3678, 41, -41.114, 204.149, -78.94, 0, ''); + +DELETE FROM script_waypoint WHERE entry=5644; +INSERT INTO script_waypoint (entry, pointid, location_x, location_y, location_z, waittime, point_comment) VALUES +(5644, 1, -339.679, 1752.04, 139.482, 0, ''), +(5644, 2, -328.957, 1734.95, 139.327, 0, ''), +(5644, 3, -338.29, 1731.36, 139.327, 0, ''), +(5644, 4, -350.747, 1731.12, 139.338, 0, ''), +(5644, 5, -365.064, 1739.04, 139.376, 0, ''), +(5644, 6, -371.105, 1746.03, 139.374, 0, ''), +(5644, 7, -383.141, 1738.62, 138.93, 0, ''), +(5644, 8, -390.445, 1733.98, 136.353, 0, ''), +(5644, 9, -401.368, 1726.77, 131.071, 0, ''), +(5644, 10, -416.016, 1721.19, 129.807, 0, ''), +(5644, 11, -437.139, 1709.82, 126.342, 0, ''), +(5644, 12, -455.83, 1695.61, 119.305, 0, ''), +(5644, 13, -459.862, 1687.92, 116.059, 0, ''), +(5644, 14, -463.565, 1679.1, 111.653, 0, ''), +(5644, 15, -461.485, 1670.94, 109.033, 0, ''), +(5644, 16, -471.786, 1647.34, 102.862, 0, ''), +(5644, 17, -477.146, 1625.69, 98.342, 0, ''), +(5644, 18, -475.815, 1615.815, 97.07, 0, ''), +(5644, 19, -474.329, 1590.01, 94.4982, 0, ''); -- EOF - diff --git a/sql/Updates/0.0.1/09_BraveWindfeather.sql b/sql/updates/0.0.1/09_BraveWindfeather.sql similarity index 100% rename from sql/Updates/0.0.1/09_BraveWindfeather.sql rename to sql/updates/0.0.1/09_BraveWindfeather.sql diff --git a/sql/Updates/0.0.1/11_SilvaFilnaveth.sql b/sql/updates/0.0.1/11_SilvaFilnaveth.sql similarity index 100% rename from sql/Updates/0.0.1/11_SilvaFilnaveth.sql rename to sql/updates/0.0.1/11_SilvaFilnaveth.sql diff --git a/sql/Updates/0.0.1/27_Vaelastraz.sql b/sql/updates/0.0.1/27_Vaelastraz.sql similarity index 100% rename from sql/Updates/0.0.1/27_Vaelastraz.sql rename to sql/updates/0.0.1/27_Vaelastraz.sql diff --git a/sql/Updates/0.0.2/r104.sql b/sql/updates/0.0.2/r104.sql similarity index 100% rename from sql/Updates/0.0.2/r104.sql rename to sql/updates/0.0.2/r104.sql diff --git a/sql/Updates/0.0.2/r108.sql b/sql/updates/0.0.2/r108.sql similarity index 100% rename from sql/Updates/0.0.2/r108.sql rename to sql/updates/0.0.2/r108.sql diff --git a/sql/Updates/0.0.2/r110.sql b/sql/updates/0.0.2/r110.sql similarity index 100% rename from sql/Updates/0.0.2/r110.sql rename to sql/updates/0.0.2/r110.sql diff --git a/sql/Updates/0.0.2/r121.sql b/sql/updates/0.0.2/r121.sql similarity index 100% rename from sql/Updates/0.0.2/r121.sql rename to sql/updates/0.0.2/r121.sql diff --git a/sql/Updates/0.0.2/r123.sql b/sql/updates/0.0.2/r123.sql similarity index 100% rename from sql/Updates/0.0.2/r123.sql rename to sql/updates/0.0.2/r123.sql diff --git a/sql/Updates/0.0.2/r124.sql b/sql/updates/0.0.2/r124.sql similarity index 100% rename from sql/Updates/0.0.2/r124.sql rename to sql/updates/0.0.2/r124.sql diff --git a/sql/Updates/0.0.2/r125.sql b/sql/updates/0.0.2/r125.sql similarity index 100% rename from sql/Updates/0.0.2/r125.sql rename to sql/updates/0.0.2/r125.sql diff --git a/sql/Updates/0.0.2/r128.sql b/sql/updates/0.0.2/r128.sql similarity index 100% rename from sql/Updates/0.0.2/r128.sql rename to sql/updates/0.0.2/r128.sql diff --git a/sql/Updates/0.0.2/r131.sql b/sql/updates/0.0.2/r131.sql similarity index 100% rename from sql/Updates/0.0.2/r131.sql rename to sql/updates/0.0.2/r131.sql diff --git a/sql/Updates/0.0.2/r134.sql b/sql/updates/0.0.2/r134.sql similarity index 100% rename from sql/Updates/0.0.2/r134.sql rename to sql/updates/0.0.2/r134.sql diff --git a/sql/Updates/0.0.2/r136.sql b/sql/updates/0.0.2/r136.sql similarity index 100% rename from sql/Updates/0.0.2/r136.sql rename to sql/updates/0.0.2/r136.sql diff --git a/sql/Updates/0.0.2/r139.sql b/sql/updates/0.0.2/r139.sql similarity index 100% rename from sql/Updates/0.0.2/r139.sql rename to sql/updates/0.0.2/r139.sql diff --git a/sql/Updates/0.0.2/r142.sql b/sql/updates/0.0.2/r142.sql similarity index 100% rename from sql/Updates/0.0.2/r142.sql rename to sql/updates/0.0.2/r142.sql diff --git a/sql/Updates/0.0.2/r144.sql b/sql/updates/0.0.2/r144.sql similarity index 100% rename from sql/Updates/0.0.2/r144.sql rename to sql/updates/0.0.2/r144.sql diff --git a/sql/Updates/0.0.2/r145.sql b/sql/updates/0.0.2/r145.sql similarity index 100% rename from sql/Updates/0.0.2/r145.sql rename to sql/updates/0.0.2/r145.sql diff --git a/sql/Updates/0.0.2/r149.sql b/sql/updates/0.0.2/r149.sql similarity index 100% rename from sql/Updates/0.0.2/r149.sql rename to sql/updates/0.0.2/r149.sql diff --git a/sql/Updates/0.0.2/r150.sql b/sql/updates/0.0.2/r150.sql similarity index 100% rename from sql/Updates/0.0.2/r150.sql rename to sql/updates/0.0.2/r150.sql diff --git a/sql/Updates/0.0.2/r152.sql b/sql/updates/0.0.2/r152.sql similarity index 100% rename from sql/Updates/0.0.2/r152.sql rename to sql/updates/0.0.2/r152.sql diff --git a/sql/Updates/0.0.2/r153.sql b/sql/updates/0.0.2/r153.sql similarity index 100% rename from sql/Updates/0.0.2/r153.sql rename to sql/updates/0.0.2/r153.sql diff --git a/sql/Updates/0.0.2/r157.sql b/sql/updates/0.0.2/r157.sql similarity index 100% rename from sql/Updates/0.0.2/r157.sql rename to sql/updates/0.0.2/r157.sql diff --git a/sql/Updates/0.0.2/r161.sql b/sql/updates/0.0.2/r161.sql similarity index 100% rename from sql/Updates/0.0.2/r161.sql rename to sql/updates/0.0.2/r161.sql diff --git a/sql/Updates/0.0.2/r163.sql b/sql/updates/0.0.2/r163.sql similarity index 100% rename from sql/Updates/0.0.2/r163.sql rename to sql/updates/0.0.2/r163.sql diff --git a/sql/Updates/0.0.2/r164.sql b/sql/updates/0.0.2/r164.sql similarity index 100% rename from sql/Updates/0.0.2/r164.sql rename to sql/updates/0.0.2/r164.sql diff --git a/sql/Updates/0.0.2/r165.sql b/sql/updates/0.0.2/r165.sql similarity index 100% rename from sql/Updates/0.0.2/r165.sql rename to sql/updates/0.0.2/r165.sql diff --git a/sql/Updates/0.0.2/r169.sql b/sql/updates/0.0.2/r169.sql similarity index 100% rename from sql/Updates/0.0.2/r169.sql rename to sql/updates/0.0.2/r169.sql diff --git a/sql/Updates/0.0.2/r170.sql b/sql/updates/0.0.2/r170.sql similarity index 100% rename from sql/Updates/0.0.2/r170.sql rename to sql/updates/0.0.2/r170.sql diff --git a/sql/Updates/0.0.2/r171.sql b/sql/updates/0.0.2/r171.sql similarity index 100% rename from sql/Updates/0.0.2/r171.sql rename to sql/updates/0.0.2/r171.sql diff --git a/sql/Updates/0.0.2/r172.sql b/sql/updates/0.0.2/r172.sql similarity index 100% rename from sql/Updates/0.0.2/r172.sql rename to sql/updates/0.0.2/r172.sql diff --git a/sql/Updates/0.0.2/r174.sql b/sql/updates/0.0.2/r174.sql similarity index 100% rename from sql/Updates/0.0.2/r174.sql rename to sql/updates/0.0.2/r174.sql diff --git a/sql/Updates/0.0.2/r176.sql b/sql/updates/0.0.2/r176.sql similarity index 100% rename from sql/Updates/0.0.2/r176.sql rename to sql/updates/0.0.2/r176.sql diff --git a/sql/Updates/0.0.2/r177.sql b/sql/updates/0.0.2/r177.sql similarity index 100% rename from sql/Updates/0.0.2/r177.sql rename to sql/updates/0.0.2/r177.sql diff --git a/sql/Updates/0.0.2/r178.sql b/sql/updates/0.0.2/r178.sql similarity index 100% rename from sql/Updates/0.0.2/r178.sql rename to sql/updates/0.0.2/r178.sql diff --git a/sql/Updates/0.0.2/r181.sql b/sql/updates/0.0.2/r181.sql similarity index 100% rename from sql/Updates/0.0.2/r181.sql rename to sql/updates/0.0.2/r181.sql diff --git a/sql/Updates/0.0.2/r182.sql b/sql/updates/0.0.2/r182.sql similarity index 100% rename from sql/Updates/0.0.2/r182.sql rename to sql/updates/0.0.2/r182.sql diff --git a/sql/Updates/0.0.2/r183.sql b/sql/updates/0.0.2/r183.sql similarity index 100% rename from sql/Updates/0.0.2/r183.sql rename to sql/updates/0.0.2/r183.sql diff --git a/sql/Updates/0.0.2/r184.sql b/sql/updates/0.0.2/r184.sql similarity index 100% rename from sql/Updates/0.0.2/r184.sql rename to sql/updates/0.0.2/r184.sql diff --git a/sql/Updates/0.0.2/r186.sql b/sql/updates/0.0.2/r186.sql similarity index 100% rename from sql/Updates/0.0.2/r186.sql rename to sql/updates/0.0.2/r186.sql diff --git a/sql/Updates/0.0.2/r187.sql b/sql/updates/0.0.2/r187.sql similarity index 100% rename from sql/Updates/0.0.2/r187.sql rename to sql/updates/0.0.2/r187.sql diff --git a/sql/Updates/0.0.2/r189.sql b/sql/updates/0.0.2/r189.sql similarity index 100% rename from sql/Updates/0.0.2/r189.sql rename to sql/updates/0.0.2/r189.sql diff --git a/sql/Updates/0.0.2/r191.sql b/sql/updates/0.0.2/r191.sql similarity index 100% rename from sql/Updates/0.0.2/r191.sql rename to sql/updates/0.0.2/r191.sql diff --git a/sql/Updates/0.0.2/r192.sql b/sql/updates/0.0.2/r192.sql similarity index 100% rename from sql/Updates/0.0.2/r192.sql rename to sql/updates/0.0.2/r192.sql diff --git a/sql/Updates/0.0.2/r197.sql b/sql/updates/0.0.2/r197.sql similarity index 100% rename from sql/Updates/0.0.2/r197.sql rename to sql/updates/0.0.2/r197.sql diff --git a/sql/Updates/0.0.2/r204.sql b/sql/updates/0.0.2/r204.sql similarity index 100% rename from sql/Updates/0.0.2/r204.sql rename to sql/updates/0.0.2/r204.sql diff --git a/sql/Updates/0.0.2/r206.sql b/sql/updates/0.0.2/r206.sql similarity index 100% rename from sql/Updates/0.0.2/r206.sql rename to sql/updates/0.0.2/r206.sql diff --git a/sql/Updates/0.0.2/r211.sql b/sql/updates/0.0.2/r211.sql similarity index 100% rename from sql/Updates/0.0.2/r211.sql rename to sql/updates/0.0.2/r211.sql diff --git a/sql/Updates/0.0.2/r213.sql b/sql/updates/0.0.2/r213.sql similarity index 100% rename from sql/Updates/0.0.2/r213.sql rename to sql/updates/0.0.2/r213.sql diff --git a/sql/Updates/0.0.2/r214.sql b/sql/updates/0.0.2/r214.sql similarity index 100% rename from sql/Updates/0.0.2/r214.sql rename to sql/updates/0.0.2/r214.sql diff --git a/sql/Updates/0.0.2/r215.sql b/sql/updates/0.0.2/r215.sql similarity index 100% rename from sql/Updates/0.0.2/r215.sql rename to sql/updates/0.0.2/r215.sql diff --git a/sql/Updates/0.0.2/r218.sql b/sql/updates/0.0.2/r218.sql similarity index 100% rename from sql/Updates/0.0.2/r218.sql rename to sql/updates/0.0.2/r218.sql diff --git a/sql/Updates/0.0.2/r219.sql b/sql/updates/0.0.2/r219.sql similarity index 100% rename from sql/Updates/0.0.2/r219.sql rename to sql/updates/0.0.2/r219.sql diff --git a/sql/Updates/0.0.2/r221_scriptdev2.sql b/sql/updates/0.0.2/r221_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r221_scriptdev2.sql rename to sql/updates/0.0.2/r221_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r227_scriptdev2.sql b/sql/updates/0.0.2/r227_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r227_scriptdev2.sql rename to sql/updates/0.0.2/r227_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r230_mangos.sql b/sql/updates/0.0.2/r230_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r230_mangos.sql rename to sql/updates/0.0.2/r230_mangos.sql diff --git a/sql/Updates/0.0.2/r234_mangos.sql b/sql/updates/0.0.2/r234_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r234_mangos.sql rename to sql/updates/0.0.2/r234_mangos.sql diff --git a/sql/Updates/0.0.2/r237_mangos.sql b/sql/updates/0.0.2/r237_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r237_mangos.sql rename to sql/updates/0.0.2/r237_mangos.sql diff --git a/sql/Updates/0.0.2/r238_mangos.sql b/sql/updates/0.0.2/r238_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r238_mangos.sql rename to sql/updates/0.0.2/r238_mangos.sql diff --git a/sql/Updates/0.0.2/r239_mangos.sql b/sql/updates/0.0.2/r239_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r239_mangos.sql rename to sql/updates/0.0.2/r239_mangos.sql diff --git a/sql/Updates/0.0.2/r240_scriptdev2.sql b/sql/updates/0.0.2/r240_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r240_scriptdev2.sql rename to sql/updates/0.0.2/r240_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r241_mangos.sql b/sql/updates/0.0.2/r241_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r241_mangos.sql rename to sql/updates/0.0.2/r241_mangos.sql diff --git a/sql/Updates/0.0.2/r242_mangos.sql b/sql/updates/0.0.2/r242_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r242_mangos.sql rename to sql/updates/0.0.2/r242_mangos.sql diff --git a/sql/Updates/0.0.2/r243_mangos.sql b/sql/updates/0.0.2/r243_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r243_mangos.sql rename to sql/updates/0.0.2/r243_mangos.sql diff --git a/sql/Updates/0.0.2/r249_mangos.sql b/sql/updates/0.0.2/r249_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r249_mangos.sql rename to sql/updates/0.0.2/r249_mangos.sql diff --git a/sql/Updates/0.0.2/r250_mangos.sql b/sql/updates/0.0.2/r250_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r250_mangos.sql rename to sql/updates/0.0.2/r250_mangos.sql diff --git a/sql/Updates/0.0.2/r253_mangos.sql b/sql/updates/0.0.2/r253_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r253_mangos.sql rename to sql/updates/0.0.2/r253_mangos.sql diff --git a/sql/Updates/0.0.2/r255_mangos.sql b/sql/updates/0.0.2/r255_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r255_mangos.sql rename to sql/updates/0.0.2/r255_mangos.sql diff --git a/sql/Updates/0.0.2/r256_mangos.sql b/sql/updates/0.0.2/r256_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r256_mangos.sql rename to sql/updates/0.0.2/r256_mangos.sql diff --git a/sql/Updates/0.0.2/r257_mangos.sql b/sql/updates/0.0.2/r257_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r257_mangos.sql rename to sql/updates/0.0.2/r257_mangos.sql diff --git a/sql/Updates/0.0.2/r258_mangos.sql b/sql/updates/0.0.2/r258_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r258_mangos.sql rename to sql/updates/0.0.2/r258_mangos.sql diff --git a/sql/Updates/0.0.2/r260_mangos.sql b/sql/updates/0.0.2/r260_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r260_mangos.sql rename to sql/updates/0.0.2/r260_mangos.sql diff --git a/sql/Updates/0.0.2/r261_mangos.sql b/sql/updates/0.0.2/r261_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r261_mangos.sql rename to sql/updates/0.0.2/r261_mangos.sql diff --git a/sql/Updates/0.0.2/r262_mangos.sql b/sql/updates/0.0.2/r262_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r262_mangos.sql rename to sql/updates/0.0.2/r262_mangos.sql diff --git a/sql/Updates/0.0.2/r263_mangos.sql b/sql/updates/0.0.2/r263_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r263_mangos.sql rename to sql/updates/0.0.2/r263_mangos.sql diff --git a/sql/Updates/0.0.2/r264_mangos.sql b/sql/updates/0.0.2/r264_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r264_mangos.sql rename to sql/updates/0.0.2/r264_mangos.sql diff --git a/sql/Updates/0.0.2/r265_mangos.sql b/sql/updates/0.0.2/r265_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r265_mangos.sql rename to sql/updates/0.0.2/r265_mangos.sql diff --git a/sql/Updates/0.0.2/r269_mangos.sql b/sql/updates/0.0.2/r269_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r269_mangos.sql rename to sql/updates/0.0.2/r269_mangos.sql diff --git a/sql/Updates/0.0.2/r270_mangos.sql b/sql/updates/0.0.2/r270_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r270_mangos.sql rename to sql/updates/0.0.2/r270_mangos.sql diff --git a/sql/Updates/0.0.2/r271_mangos.sql b/sql/updates/0.0.2/r271_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r271_mangos.sql rename to sql/updates/0.0.2/r271_mangos.sql diff --git a/sql/Updates/0.0.2/r272_mangos.sql b/sql/updates/0.0.2/r272_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r272_mangos.sql rename to sql/updates/0.0.2/r272_mangos.sql diff --git a/sql/Updates/0.0.2/r273_mangos.sql b/sql/updates/0.0.2/r273_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r273_mangos.sql rename to sql/updates/0.0.2/r273_mangos.sql diff --git a/sql/Updates/0.0.2/r274_mangos.sql b/sql/updates/0.0.2/r274_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r274_mangos.sql rename to sql/updates/0.0.2/r274_mangos.sql diff --git a/sql/Updates/0.0.2/r275_mangos.sql b/sql/updates/0.0.2/r275_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r275_mangos.sql rename to sql/updates/0.0.2/r275_mangos.sql diff --git a/sql/Updates/0.0.2/r281_scriptdev2.sql b/sql/updates/0.0.2/r281_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r281_scriptdev2.sql rename to sql/updates/0.0.2/r281_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r282_mangos.sql b/sql/updates/0.0.2/r282_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r282_mangos.sql rename to sql/updates/0.0.2/r282_mangos.sql diff --git a/sql/Updates/0.0.2/r286_mangos.sql b/sql/updates/0.0.2/r286_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r286_mangos.sql rename to sql/updates/0.0.2/r286_mangos.sql diff --git a/sql/Updates/0.0.2/r289_mangos.sql b/sql/updates/0.0.2/r289_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r289_mangos.sql rename to sql/updates/0.0.2/r289_mangos.sql diff --git a/sql/Updates/0.0.2/r291_mangos.sql b/sql/updates/0.0.2/r291_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r291_mangos.sql rename to sql/updates/0.0.2/r291_mangos.sql diff --git a/sql/Updates/0.0.2/r295_mangos.sql b/sql/updates/0.0.2/r295_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r295_mangos.sql rename to sql/updates/0.0.2/r295_mangos.sql diff --git a/sql/Updates/0.0.2/r297_mangos.sql b/sql/updates/0.0.2/r297_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r297_mangos.sql rename to sql/updates/0.0.2/r297_mangos.sql diff --git a/sql/Updates/0.0.2/r298_scriptdev2.sql b/sql/updates/0.0.2/r298_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r298_scriptdev2.sql rename to sql/updates/0.0.2/r298_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r299_scriptdev2.sql b/sql/updates/0.0.2/r299_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r299_scriptdev2.sql rename to sql/updates/0.0.2/r299_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r304_mangos.sql b/sql/updates/0.0.2/r304_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r304_mangos.sql rename to sql/updates/0.0.2/r304_mangos.sql diff --git a/sql/Updates/0.0.2/r306_scriptdev2.sql b/sql/updates/0.0.2/r306_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r306_scriptdev2.sql rename to sql/updates/0.0.2/r306_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r307_mangos.sql b/sql/updates/0.0.2/r307_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r307_mangos.sql rename to sql/updates/0.0.2/r307_mangos.sql diff --git a/sql/Updates/0.0.2/r308_mangos.sql b/sql/updates/0.0.2/r308_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r308_mangos.sql rename to sql/updates/0.0.2/r308_mangos.sql diff --git a/sql/Updates/0.0.2/r309_mangos.sql b/sql/updates/0.0.2/r309_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r309_mangos.sql rename to sql/updates/0.0.2/r309_mangos.sql diff --git a/sql/Updates/0.0.2/r311_mangos.sql b/sql/updates/0.0.2/r311_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r311_mangos.sql rename to sql/updates/0.0.2/r311_mangos.sql diff --git a/sql/Updates/0.0.2/r312_mangos.sql b/sql/updates/0.0.2/r312_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r312_mangos.sql rename to sql/updates/0.0.2/r312_mangos.sql diff --git a/sql/Updates/0.0.2/r318_mangos.sql b/sql/updates/0.0.2/r318_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r318_mangos.sql rename to sql/updates/0.0.2/r318_mangos.sql diff --git a/sql/Updates/0.0.2/r324_mangos.sql b/sql/updates/0.0.2/r324_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r324_mangos.sql rename to sql/updates/0.0.2/r324_mangos.sql diff --git a/sql/Updates/0.0.2/r327_mangos.sql b/sql/updates/0.0.2/r327_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r327_mangos.sql rename to sql/updates/0.0.2/r327_mangos.sql diff --git a/sql/Updates/0.0.2/r332_scriptdev2.sql b/sql/updates/0.0.2/r332_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r332_scriptdev2.sql rename to sql/updates/0.0.2/r332_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r333_mangos.sql b/sql/updates/0.0.2/r333_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r333_mangos.sql rename to sql/updates/0.0.2/r333_mangos.sql diff --git a/sql/Updates/0.0.2/r334_mangos.sql b/sql/updates/0.0.2/r334_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r334_mangos.sql rename to sql/updates/0.0.2/r334_mangos.sql diff --git a/sql/Updates/0.0.2/r336_mangos.sql b/sql/updates/0.0.2/r336_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r336_mangos.sql rename to sql/updates/0.0.2/r336_mangos.sql diff --git a/sql/Updates/0.0.2/r352_mangos.sql b/sql/updates/0.0.2/r352_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r352_mangos.sql rename to sql/updates/0.0.2/r352_mangos.sql diff --git a/sql/Updates/0.0.2/r355_mangos.sql b/sql/updates/0.0.2/r355_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r355_mangos.sql rename to sql/updates/0.0.2/r355_mangos.sql diff --git a/sql/Updates/0.0.2/r358_mangos.sql b/sql/updates/0.0.2/r358_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r358_mangos.sql rename to sql/updates/0.0.2/r358_mangos.sql diff --git a/sql/Updates/0.0.2/r364_mangos.sql b/sql/updates/0.0.2/r364_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r364_mangos.sql rename to sql/updates/0.0.2/r364_mangos.sql diff --git a/sql/Updates/0.0.2/r367_mangos.sql b/sql/updates/0.0.2/r367_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r367_mangos.sql rename to sql/updates/0.0.2/r367_mangos.sql diff --git a/sql/Updates/0.0.2/r368_mangos.sql b/sql/updates/0.0.2/r368_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r368_mangos.sql rename to sql/updates/0.0.2/r368_mangos.sql diff --git a/sql/Updates/0.0.2/r369_mangos.sql b/sql/updates/0.0.2/r369_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r369_mangos.sql rename to sql/updates/0.0.2/r369_mangos.sql diff --git a/sql/Updates/0.0.2/r374_mangos.sql b/sql/updates/0.0.2/r374_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r374_mangos.sql rename to sql/updates/0.0.2/r374_mangos.sql diff --git a/sql/Updates/0.0.2/r386_mangos.sql b/sql/updates/0.0.2/r386_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r386_mangos.sql rename to sql/updates/0.0.2/r386_mangos.sql diff --git a/sql/Updates/0.0.2/r417_mangos.sql b/sql/updates/0.0.2/r417_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r417_mangos.sql rename to sql/updates/0.0.2/r417_mangos.sql diff --git a/sql/Updates/0.0.2/r428_mangos.sql b/sql/updates/0.0.2/r428_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r428_mangos.sql rename to sql/updates/0.0.2/r428_mangos.sql diff --git a/sql/Updates/0.0.2/r431_mangos.sql b/sql/updates/0.0.2/r431_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r431_mangos.sql rename to sql/updates/0.0.2/r431_mangos.sql diff --git a/sql/Updates/0.0.2/r444_mangos.sql b/sql/updates/0.0.2/r444_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r444_mangos.sql rename to sql/updates/0.0.2/r444_mangos.sql diff --git a/sql/Updates/0.0.2/r445_mangos.sql b/sql/updates/0.0.2/r445_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r445_mangos.sql rename to sql/updates/0.0.2/r445_mangos.sql diff --git a/sql/Updates/0.0.2/r446_mangos.sql b/sql/updates/0.0.2/r446_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r446_mangos.sql rename to sql/updates/0.0.2/r446_mangos.sql diff --git a/sql/Updates/0.0.2/r448_scriptdev2.sql b/sql/updates/0.0.2/r448_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r448_scriptdev2.sql rename to sql/updates/0.0.2/r448_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r462_mangos.sql b/sql/updates/0.0.2/r462_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r462_mangos.sql rename to sql/updates/0.0.2/r462_mangos.sql diff --git a/sql/Updates/0.0.2/r465_mangos.sql b/sql/updates/0.0.2/r465_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r465_mangos.sql rename to sql/updates/0.0.2/r465_mangos.sql diff --git a/sql/Updates/0.0.2/r467_mangos.sql b/sql/updates/0.0.2/r467_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r467_mangos.sql rename to sql/updates/0.0.2/r467_mangos.sql diff --git a/sql/Updates/0.0.2/r473_mangos.sql b/sql/updates/0.0.2/r473_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r473_mangos.sql rename to sql/updates/0.0.2/r473_mangos.sql diff --git a/sql/Updates/0.0.2/r476_mangos.sql b/sql/updates/0.0.2/r476_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r476_mangos.sql rename to sql/updates/0.0.2/r476_mangos.sql diff --git a/sql/Updates/0.0.2/r477_mangos.sql b/sql/updates/0.0.2/r477_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r477_mangos.sql rename to sql/updates/0.0.2/r477_mangos.sql diff --git a/sql/Updates/0.0.2/r479_mangos.sql b/sql/updates/0.0.2/r479_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r479_mangos.sql rename to sql/updates/0.0.2/r479_mangos.sql diff --git a/sql/Updates/0.0.2/r482_mangos.sql b/sql/updates/0.0.2/r482_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r482_mangos.sql rename to sql/updates/0.0.2/r482_mangos.sql diff --git a/sql/Updates/0.0.2/r484_mangos.sql b/sql/updates/0.0.2/r484_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r484_mangos.sql rename to sql/updates/0.0.2/r484_mangos.sql diff --git a/sql/Updates/0.0.2/r486_mangos.sql b/sql/updates/0.0.2/r486_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r486_mangos.sql rename to sql/updates/0.0.2/r486_mangos.sql diff --git a/sql/Updates/0.0.2/r487_mangos.sql b/sql/updates/0.0.2/r487_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r487_mangos.sql rename to sql/updates/0.0.2/r487_mangos.sql diff --git a/sql/Updates/0.0.2/r494_mangos.sql b/sql/updates/0.0.2/r494_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r494_mangos.sql rename to sql/updates/0.0.2/r494_mangos.sql diff --git a/sql/Updates/0.0.2/r501_mangos.sql b/sql/updates/0.0.2/r501_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r501_mangos.sql rename to sql/updates/0.0.2/r501_mangos.sql diff --git a/sql/Updates/0.0.2/r513_mangos.sql b/sql/updates/0.0.2/r513_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r513_mangos.sql rename to sql/updates/0.0.2/r513_mangos.sql diff --git a/sql/Updates/0.0.2/r514_mangos.sql b/sql/updates/0.0.2/r514_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r514_mangos.sql rename to sql/updates/0.0.2/r514_mangos.sql diff --git a/sql/Updates/0.0.2/r515_mangos.sql b/sql/updates/0.0.2/r515_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r515_mangos.sql rename to sql/updates/0.0.2/r515_mangos.sql diff --git a/sql/Updates/0.0.2/r516_mangos.sql b/sql/updates/0.0.2/r516_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r516_mangos.sql rename to sql/updates/0.0.2/r516_mangos.sql diff --git a/sql/Updates/0.0.2/r517_mangos.sql b/sql/updates/0.0.2/r517_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r517_mangos.sql rename to sql/updates/0.0.2/r517_mangos.sql diff --git a/sql/Updates/0.0.2/r518_mangos.sql b/sql/updates/0.0.2/r518_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r518_mangos.sql rename to sql/updates/0.0.2/r518_mangos.sql diff --git a/sql/Updates/0.0.2/r519_mangos.sql b/sql/updates/0.0.2/r519_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r519_mangos.sql rename to sql/updates/0.0.2/r519_mangos.sql diff --git a/sql/Updates/0.0.2/r520_mangos.sql b/sql/updates/0.0.2/r520_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r520_mangos.sql rename to sql/updates/0.0.2/r520_mangos.sql diff --git a/sql/Updates/0.0.2/r521_mangos.sql b/sql/updates/0.0.2/r521_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r521_mangos.sql rename to sql/updates/0.0.2/r521_mangos.sql diff --git a/sql/Updates/0.0.2/r522_mangos.sql b/sql/updates/0.0.2/r522_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r522_mangos.sql rename to sql/updates/0.0.2/r522_mangos.sql diff --git a/sql/Updates/0.0.2/r526_mangos.sql b/sql/updates/0.0.2/r526_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r526_mangos.sql rename to sql/updates/0.0.2/r526_mangos.sql diff --git a/sql/Updates/0.0.2/r528_mangos.sql b/sql/updates/0.0.2/r528_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r528_mangos.sql rename to sql/updates/0.0.2/r528_mangos.sql diff --git a/sql/Updates/0.0.2/r533_mangos.sql b/sql/updates/0.0.2/r533_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r533_mangos.sql rename to sql/updates/0.0.2/r533_mangos.sql diff --git a/sql/Updates/0.0.2/r538_scriptdev2.sql b/sql/updates/0.0.2/r538_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r538_scriptdev2.sql rename to sql/updates/0.0.2/r538_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r547_mangos.sql b/sql/updates/0.0.2/r547_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r547_mangos.sql rename to sql/updates/0.0.2/r547_mangos.sql diff --git a/sql/Updates/0.0.2/r554_mangos.sql b/sql/updates/0.0.2/r554_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r554_mangos.sql rename to sql/updates/0.0.2/r554_mangos.sql diff --git a/sql/Updates/0.0.2/r555_mangos.sql b/sql/updates/0.0.2/r555_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r555_mangos.sql rename to sql/updates/0.0.2/r555_mangos.sql diff --git a/sql/Updates/0.0.2/r56.sql b/sql/updates/0.0.2/r56.sql similarity index 100% rename from sql/Updates/0.0.2/r56.sql rename to sql/updates/0.0.2/r56.sql diff --git a/sql/Updates/0.0.2/r575_mangos.sql b/sql/updates/0.0.2/r575_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r575_mangos.sql rename to sql/updates/0.0.2/r575_mangos.sql diff --git a/sql/Updates/0.0.2/r576_mangos.sql b/sql/updates/0.0.2/r576_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r576_mangos.sql rename to sql/updates/0.0.2/r576_mangos.sql diff --git a/sql/Updates/0.0.2/r578_mangos.sql b/sql/updates/0.0.2/r578_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r578_mangos.sql rename to sql/updates/0.0.2/r578_mangos.sql diff --git a/sql/Updates/0.0.2/r584_mangos.sql b/sql/updates/0.0.2/r584_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r584_mangos.sql rename to sql/updates/0.0.2/r584_mangos.sql diff --git a/sql/Updates/0.0.2/r59.sql b/sql/updates/0.0.2/r59.sql similarity index 100% rename from sql/Updates/0.0.2/r59.sql rename to sql/updates/0.0.2/r59.sql diff --git a/sql/Updates/0.0.2/r590_mangos.sql b/sql/updates/0.0.2/r590_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r590_mangos.sql rename to sql/updates/0.0.2/r590_mangos.sql diff --git a/sql/Updates/0.0.2/r591_mangos.sql b/sql/updates/0.0.2/r591_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r591_mangos.sql rename to sql/updates/0.0.2/r591_mangos.sql diff --git a/sql/Updates/0.0.2/r593_mangos.sql b/sql/updates/0.0.2/r593_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r593_mangos.sql rename to sql/updates/0.0.2/r593_mangos.sql diff --git a/sql/Updates/0.0.2/r594_mangos.sql b/sql/updates/0.0.2/r594_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r594_mangos.sql rename to sql/updates/0.0.2/r594_mangos.sql diff --git a/sql/Updates/0.0.2/r596_mangos.sql b/sql/updates/0.0.2/r596_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r596_mangos.sql rename to sql/updates/0.0.2/r596_mangos.sql diff --git a/sql/Updates/0.0.2/r610_mangos.sql b/sql/updates/0.0.2/r610_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r610_mangos.sql rename to sql/updates/0.0.2/r610_mangos.sql diff --git a/sql/Updates/0.0.2/r615_scriptdev2.sql b/sql/updates/0.0.2/r615_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r615_scriptdev2.sql rename to sql/updates/0.0.2/r615_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r617_mangos.sql b/sql/updates/0.0.2/r617_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r617_mangos.sql rename to sql/updates/0.0.2/r617_mangos.sql diff --git a/sql/Updates/0.0.2/r621_mangos.sql b/sql/updates/0.0.2/r621_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r621_mangos.sql rename to sql/updates/0.0.2/r621_mangos.sql diff --git a/sql/Updates/0.0.2/r628_mangos.sql b/sql/updates/0.0.2/r628_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r628_mangos.sql rename to sql/updates/0.0.2/r628_mangos.sql diff --git a/sql/Updates/0.0.2/r63.sql b/sql/updates/0.0.2/r63.sql similarity index 100% rename from sql/Updates/0.0.2/r63.sql rename to sql/updates/0.0.2/r63.sql diff --git a/sql/Updates/0.0.2/r632_mangos.sql b/sql/updates/0.0.2/r632_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r632_mangos.sql rename to sql/updates/0.0.2/r632_mangos.sql diff --git a/sql/Updates/0.0.2/r633_mangos.sql b/sql/updates/0.0.2/r633_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r633_mangos.sql rename to sql/updates/0.0.2/r633_mangos.sql diff --git a/sql/Updates/0.0.2/r634_scriptdev2.sql b/sql/updates/0.0.2/r634_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r634_scriptdev2.sql rename to sql/updates/0.0.2/r634_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r636_mangos.sql b/sql/updates/0.0.2/r636_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r636_mangos.sql rename to sql/updates/0.0.2/r636_mangos.sql diff --git a/sql/Updates/0.0.2/r637_mangos.sql b/sql/updates/0.0.2/r637_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r637_mangos.sql rename to sql/updates/0.0.2/r637_mangos.sql diff --git a/sql/Updates/0.0.2/r638_mangos.sql b/sql/updates/0.0.2/r638_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r638_mangos.sql rename to sql/updates/0.0.2/r638_mangos.sql diff --git a/sql/Updates/0.0.2/r639_mangos.sql b/sql/updates/0.0.2/r639_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r639_mangos.sql rename to sql/updates/0.0.2/r639_mangos.sql diff --git a/sql/Updates/0.0.2/r642_mangos.sql b/sql/updates/0.0.2/r642_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r642_mangos.sql rename to sql/updates/0.0.2/r642_mangos.sql diff --git a/sql/Updates/0.0.2/r643_mangos.sql b/sql/updates/0.0.2/r643_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r643_mangos.sql rename to sql/updates/0.0.2/r643_mangos.sql diff --git a/sql/Updates/0.0.2/r646_mangos.sql b/sql/updates/0.0.2/r646_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r646_mangos.sql rename to sql/updates/0.0.2/r646_mangos.sql diff --git a/sql/Updates/0.0.2/r647_scriptdev2.sql b/sql/updates/0.0.2/r647_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r647_scriptdev2.sql rename to sql/updates/0.0.2/r647_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r65.sql b/sql/updates/0.0.2/r65.sql similarity index 100% rename from sql/Updates/0.0.2/r65.sql rename to sql/updates/0.0.2/r65.sql diff --git a/sql/Updates/0.0.2/r656_scriptdev2.sql b/sql/updates/0.0.2/r656_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r656_scriptdev2.sql rename to sql/updates/0.0.2/r656_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r658_mangos.sql b/sql/updates/0.0.2/r658_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r658_mangos.sql rename to sql/updates/0.0.2/r658_mangos.sql diff --git a/sql/Updates/0.0.2/r659_mangos.sql b/sql/updates/0.0.2/r659_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r659_mangos.sql rename to sql/updates/0.0.2/r659_mangos.sql diff --git a/sql/Updates/0.0.2/r681_scriptdev2.sql b/sql/updates/0.0.2/r681_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r681_scriptdev2.sql rename to sql/updates/0.0.2/r681_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r695_scriptdev2.sql b/sql/updates/0.0.2/r695_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.2/r695_scriptdev2.sql rename to sql/updates/0.0.2/r695_scriptdev2.sql diff --git a/sql/Updates/0.0.2/r699_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r699_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r699_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r699_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r700_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r700_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r700_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r700_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r701_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r701_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r701_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r701_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r702_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r702_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r702_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r702_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r703_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r703_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r703_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r703_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r704_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r704_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r704_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r704_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r705_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r705_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r705_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r705_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r706_mangos.sql b/sql/updates/0.0.2/r706_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r706_mangos.sql rename to sql/updates/0.0.2/r706_mangos.sql diff --git a/sql/Updates/0.0.2/r707_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r707_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r707_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r707_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r709_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r709_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r709_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r709_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r710_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r710_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r710_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r710_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r713_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r713_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r713_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r713_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r715_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r715_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r715_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r715_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r72.sql b/sql/updates/0.0.2/r72.sql similarity index 100% rename from sql/Updates/0.0.2/r72.sql rename to sql/updates/0.0.2/r72.sql diff --git a/sql/Updates/0.0.2/r725_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r725_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r725_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r725_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r726_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r726_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r726_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r726_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r727_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r727_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r727_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r727_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r728_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r728_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r728_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r728_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r729_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r729_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r729_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r729_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r730_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r730_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r730_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r730_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r732_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r732_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r732_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r732_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r735_mangos.sql b/sql/updates/0.0.2/r735_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r735_mangos.sql rename to sql/updates/0.0.2/r735_mangos.sql diff --git a/sql/Updates/0.0.2/r735_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r735_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r735_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r735_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r740_mangos.sql b/sql/updates/0.0.2/r740_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r740_mangos.sql rename to sql/updates/0.0.2/r740_mangos.sql diff --git a/sql/Updates/0.0.2/r740_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r740_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r740_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r740_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r743_mangos.sql b/sql/updates/0.0.2/r743_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r743_mangos.sql rename to sql/updates/0.0.2/r743_mangos.sql diff --git a/sql/Updates/0.0.2/r743_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r743_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r743_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r743_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r745_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r745_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r745_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r745_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r747_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r747_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r747_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r747_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r751_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r751_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r751_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r751_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r755_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r755_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r755_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r755_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r757_mangos.sql b/sql/updates/0.0.2/r757_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r757_mangos.sql rename to sql/updates/0.0.2/r757_mangos.sql diff --git a/sql/Updates/0.0.2/r757_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r757_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r757_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r757_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r764_mangos.sql b/sql/updates/0.0.2/r764_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r764_mangos.sql rename to sql/updates/0.0.2/r764_mangos.sql diff --git a/sql/Updates/0.0.2/r764_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r764_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r764_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r764_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r766_mangos.sql b/sql/updates/0.0.2/r766_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r766_mangos.sql rename to sql/updates/0.0.2/r766_mangos.sql diff --git a/sql/Updates/0.0.2/r766_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r766_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r766_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r766_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r767_mangos.sql b/sql/updates/0.0.2/r767_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r767_mangos.sql rename to sql/updates/0.0.2/r767_mangos.sql diff --git a/sql/Updates/0.0.2/r768_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r768_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r768_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r768_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r769_mangos.sql b/sql/updates/0.0.2/r769_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r769_mangos.sql rename to sql/updates/0.0.2/r769_mangos.sql diff --git a/sql/Updates/0.0.2/r771_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r771_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r771_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r771_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r772_mangos.sql b/sql/updates/0.0.2/r772_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r772_mangos.sql rename to sql/updates/0.0.2/r772_mangos.sql diff --git a/sql/Updates/0.0.2/r777_mangos.sql b/sql/updates/0.0.2/r777_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r777_mangos.sql rename to sql/updates/0.0.2/r777_mangos.sql diff --git a/sql/Updates/0.0.2/r778_mangos.sql b/sql/updates/0.0.2/r778_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r778_mangos.sql rename to sql/updates/0.0.2/r778_mangos.sql diff --git a/sql/Updates/0.0.2/r779_mangos.sql b/sql/updates/0.0.2/r779_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r779_mangos.sql rename to sql/updates/0.0.2/r779_mangos.sql diff --git a/sql/Updates/0.0.2/r779_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r779_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r779_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r779_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r78.sql b/sql/updates/0.0.2/r78.sql similarity index 100% rename from sql/Updates/0.0.2/r78.sql rename to sql/updates/0.0.2/r78.sql diff --git a/sql/Updates/0.0.2/r782_mangos.sql b/sql/updates/0.0.2/r782_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r782_mangos.sql rename to sql/updates/0.0.2/r782_mangos.sql diff --git a/sql/Updates/0.0.2/r783_mangos.sql b/sql/updates/0.0.2/r783_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r783_mangos.sql rename to sql/updates/0.0.2/r783_mangos.sql diff --git a/sql/Updates/0.0.2/r783_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r783_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r783_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r783_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r790_mangos.sql b/sql/updates/0.0.2/r790_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r790_mangos.sql rename to sql/updates/0.0.2/r790_mangos.sql diff --git a/sql/Updates/0.0.2/r794_mangos.sql b/sql/updates/0.0.2/r794_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r794_mangos.sql rename to sql/updates/0.0.2/r794_mangos.sql diff --git a/sql/Updates/0.0.2/r796_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r796_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r796_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r796_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r802_mangos.sql b/sql/updates/0.0.2/r802_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r802_mangos.sql rename to sql/updates/0.0.2/r802_mangos.sql diff --git a/sql/Updates/0.0.2/r804_mangos.sql b/sql/updates/0.0.2/r804_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r804_mangos.sql rename to sql/updates/0.0.2/r804_mangos.sql diff --git a/sql/Updates/0.0.2/r804_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r804_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r804_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r804_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r809_mangos.sql b/sql/updates/0.0.2/r809_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r809_mangos.sql rename to sql/updates/0.0.2/r809_mangos.sql diff --git a/sql/Updates/0.0.2/r809_scriptdev2_script_texts.sql b/sql/updates/0.0.2/r809_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.2/r809_scriptdev2_script_texts.sql rename to sql/updates/0.0.2/r809_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.2/r81.sql b/sql/updates/0.0.2/r81.sql similarity index 100% rename from sql/Updates/0.0.2/r81.sql rename to sql/updates/0.0.2/r81.sql diff --git a/sql/Updates/0.0.2/r810_mangos.sql b/sql/updates/0.0.2/r810_mangos.sql similarity index 100% rename from sql/Updates/0.0.2/r810_mangos.sql rename to sql/updates/0.0.2/r810_mangos.sql diff --git a/sql/Updates/0.0.2/r91.sql b/sql/updates/0.0.2/r91.sql similarity index 100% rename from sql/Updates/0.0.2/r91.sql rename to sql/updates/0.0.2/r91.sql diff --git a/sql/Updates/0.0.2/r92.sql b/sql/updates/0.0.2/r92.sql similarity index 100% rename from sql/Updates/0.0.2/r92.sql rename to sql/updates/0.0.2/r92.sql diff --git a/sql/Updates/0.0.2/r97.sql b/sql/updates/0.0.2/r97.sql similarity index 100% rename from sql/Updates/0.0.2/r97.sql rename to sql/updates/0.0.2/r97.sql diff --git a/sql/Updates/0.0.3/r1002_scriptdev2.sql b/sql/updates/0.0.3/r1002_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1002_scriptdev2.sql rename to sql/updates/0.0.3/r1002_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1006_scriptdev2.sql b/sql/updates/0.0.3/r1006_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1006_scriptdev2.sql rename to sql/updates/0.0.3/r1006_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1008_mangos.sql b/sql/updates/0.0.3/r1008_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1008_mangos.sql rename to sql/updates/0.0.3/r1008_mangos.sql diff --git a/sql/Updates/0.0.3/r1008_scriptdev2.sql b/sql/updates/0.0.3/r1008_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1008_scriptdev2.sql rename to sql/updates/0.0.3/r1008_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1009_scriptdev2.sql b/sql/updates/0.0.3/r1009_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1009_scriptdev2.sql rename to sql/updates/0.0.3/r1009_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1010_mangos.sql b/sql/updates/0.0.3/r1010_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1010_mangos.sql rename to sql/updates/0.0.3/r1010_mangos.sql diff --git a/sql/Updates/0.0.3/r1010_scriptdev2.sql b/sql/updates/0.0.3/r1010_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1010_scriptdev2.sql rename to sql/updates/0.0.3/r1010_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1012_mangos.sql b/sql/updates/0.0.3/r1012_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1012_mangos.sql rename to sql/updates/0.0.3/r1012_mangos.sql diff --git a/sql/Updates/0.0.3/r1012_scriptdev2.sql b/sql/updates/0.0.3/r1012_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1012_scriptdev2.sql rename to sql/updates/0.0.3/r1012_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1014_mangos.sql b/sql/updates/0.0.3/r1014_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1014_mangos.sql rename to sql/updates/0.0.3/r1014_mangos.sql diff --git a/sql/Updates/0.0.3/r1014_scriptdev2.sql b/sql/updates/0.0.3/r1014_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1014_scriptdev2.sql rename to sql/updates/0.0.3/r1014_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1016_scriptdev2.sql b/sql/updates/0.0.3/r1016_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1016_scriptdev2.sql rename to sql/updates/0.0.3/r1016_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1023_scriptdev2.sql b/sql/updates/0.0.3/r1023_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1023_scriptdev2.sql rename to sql/updates/0.0.3/r1023_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1025_mangos.sql b/sql/updates/0.0.3/r1025_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1025_mangos.sql rename to sql/updates/0.0.3/r1025_mangos.sql diff --git a/sql/Updates/0.0.3/r1030_scriptdev2.sql b/sql/updates/0.0.3/r1030_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1030_scriptdev2.sql rename to sql/updates/0.0.3/r1030_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1032_mangos.sql b/sql/updates/0.0.3/r1032_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1032_mangos.sql rename to sql/updates/0.0.3/r1032_mangos.sql diff --git a/sql/Updates/0.0.3/r1032_scriptdev2.sql b/sql/updates/0.0.3/r1032_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1032_scriptdev2.sql rename to sql/updates/0.0.3/r1032_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1039_mangos.sql b/sql/updates/0.0.3/r1039_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1039_mangos.sql rename to sql/updates/0.0.3/r1039_mangos.sql diff --git a/sql/Updates/0.0.3/r1056_scriptdev2.sql b/sql/updates/0.0.3/r1056_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1056_scriptdev2.sql rename to sql/updates/0.0.3/r1056_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1058_mangos.sql b/sql/updates/0.0.3/r1058_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1058_mangos.sql rename to sql/updates/0.0.3/r1058_mangos.sql diff --git a/sql/Updates/0.0.3/r1058_scriptdev2.sql b/sql/updates/0.0.3/r1058_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1058_scriptdev2.sql rename to sql/updates/0.0.3/r1058_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1062_mangos.sql b/sql/updates/0.0.3/r1062_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1062_mangos.sql rename to sql/updates/0.0.3/r1062_mangos.sql diff --git a/sql/Updates/0.0.3/r1067_mangos.sql b/sql/updates/0.0.3/r1067_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1067_mangos.sql rename to sql/updates/0.0.3/r1067_mangos.sql diff --git a/sql/Updates/0.0.3/r1068_mangos.sql b/sql/updates/0.0.3/r1068_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1068_mangos.sql rename to sql/updates/0.0.3/r1068_mangos.sql diff --git a/sql/Updates/0.0.3/r1068_scriptdev2.sql b/sql/updates/0.0.3/r1068_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1068_scriptdev2.sql rename to sql/updates/0.0.3/r1068_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1069_mangos.sql b/sql/updates/0.0.3/r1069_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1069_mangos.sql rename to sql/updates/0.0.3/r1069_mangos.sql diff --git a/sql/Updates/0.0.3/r1073_mangos.sql b/sql/updates/0.0.3/r1073_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1073_mangos.sql rename to sql/updates/0.0.3/r1073_mangos.sql diff --git a/sql/Updates/0.0.3/r1074_scriptdev2.sql b/sql/updates/0.0.3/r1074_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1074_scriptdev2.sql rename to sql/updates/0.0.3/r1074_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1075_mangos.sql b/sql/updates/0.0.3/r1075_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1075_mangos.sql rename to sql/updates/0.0.3/r1075_mangos.sql diff --git a/sql/Updates/0.0.3/r1080_scriptdev2.sql b/sql/updates/0.0.3/r1080_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1080_scriptdev2.sql rename to sql/updates/0.0.3/r1080_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1082_mangos.sql b/sql/updates/0.0.3/r1082_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1082_mangos.sql rename to sql/updates/0.0.3/r1082_mangos.sql diff --git a/sql/Updates/0.0.3/r1098_scriptdev2.sql b/sql/updates/0.0.3/r1098_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1098_scriptdev2.sql rename to sql/updates/0.0.3/r1098_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1099_mangos.sql b/sql/updates/0.0.3/r1099_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1099_mangos.sql rename to sql/updates/0.0.3/r1099_mangos.sql diff --git a/sql/Updates/0.0.3/r1100_mangos.sql b/sql/updates/0.0.3/r1100_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1100_mangos.sql rename to sql/updates/0.0.3/r1100_mangos.sql diff --git a/sql/Updates/0.0.3/r1103_mangos.sql b/sql/updates/0.0.3/r1103_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1103_mangos.sql rename to sql/updates/0.0.3/r1103_mangos.sql diff --git a/sql/Updates/0.0.3/r1104_scriptdev2.sql b/sql/updates/0.0.3/r1104_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1104_scriptdev2.sql rename to sql/updates/0.0.3/r1104_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1106_mangos.sql b/sql/updates/0.0.3/r1106_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1106_mangos.sql rename to sql/updates/0.0.3/r1106_mangos.sql diff --git a/sql/Updates/0.0.3/r1112_mangos.sql b/sql/updates/0.0.3/r1112_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1112_mangos.sql rename to sql/updates/0.0.3/r1112_mangos.sql diff --git a/sql/Updates/0.0.3/r1116_mangos.sql b/sql/updates/0.0.3/r1116_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1116_mangos.sql rename to sql/updates/0.0.3/r1116_mangos.sql diff --git a/sql/Updates/0.0.3/r1119_mangos.sql b/sql/updates/0.0.3/r1119_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1119_mangos.sql rename to sql/updates/0.0.3/r1119_mangos.sql diff --git a/sql/Updates/0.0.3/r1119_scriptdev2.sql b/sql/updates/0.0.3/r1119_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1119_scriptdev2.sql rename to sql/updates/0.0.3/r1119_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1120_scriptdev2.sql b/sql/updates/0.0.3/r1120_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1120_scriptdev2.sql rename to sql/updates/0.0.3/r1120_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1121_mangos.sql b/sql/updates/0.0.3/r1121_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1121_mangos.sql rename to sql/updates/0.0.3/r1121_mangos.sql diff --git a/sql/Updates/0.0.3/r1121_scriptdev2.sql b/sql/updates/0.0.3/r1121_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1121_scriptdev2.sql rename to sql/updates/0.0.3/r1121_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1123_scriptdev2.sql b/sql/updates/0.0.3/r1123_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1123_scriptdev2.sql rename to sql/updates/0.0.3/r1123_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1128_mangos.sql b/sql/updates/0.0.3/r1128_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1128_mangos.sql rename to sql/updates/0.0.3/r1128_mangos.sql diff --git a/sql/Updates/0.0.3/r1129_mangos.sql b/sql/updates/0.0.3/r1129_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1129_mangos.sql rename to sql/updates/0.0.3/r1129_mangos.sql diff --git a/sql/Updates/0.0.3/r1129_scriptdev2.sql b/sql/updates/0.0.3/r1129_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1129_scriptdev2.sql rename to sql/updates/0.0.3/r1129_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1131_mangos.sql b/sql/updates/0.0.3/r1131_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1131_mangos.sql rename to sql/updates/0.0.3/r1131_mangos.sql diff --git a/sql/Updates/0.0.3/r1136_mangos.sql b/sql/updates/0.0.3/r1136_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1136_mangos.sql rename to sql/updates/0.0.3/r1136_mangos.sql diff --git a/sql/Updates/0.0.3/r1136_scriptdev2.sql b/sql/updates/0.0.3/r1136_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1136_scriptdev2.sql rename to sql/updates/0.0.3/r1136_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1140_scriptdev2.sql b/sql/updates/0.0.3/r1140_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1140_scriptdev2.sql rename to sql/updates/0.0.3/r1140_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1141_mangos.sql b/sql/updates/0.0.3/r1141_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1141_mangos.sql rename to sql/updates/0.0.3/r1141_mangos.sql diff --git a/sql/Updates/0.0.3/r1145_scriptdev2.sql b/sql/updates/0.0.3/r1145_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1145_scriptdev2.sql rename to sql/updates/0.0.3/r1145_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1146_scriptdev2.sql b/sql/updates/0.0.3/r1146_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1146_scriptdev2.sql rename to sql/updates/0.0.3/r1146_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1149_scriptdev2.sql b/sql/updates/0.0.3/r1149_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1149_scriptdev2.sql rename to sql/updates/0.0.3/r1149_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1152_scriptdev2.sql b/sql/updates/0.0.3/r1152_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1152_scriptdev2.sql rename to sql/updates/0.0.3/r1152_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1154_mangos.sql b/sql/updates/0.0.3/r1154_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1154_mangos.sql rename to sql/updates/0.0.3/r1154_mangos.sql diff --git a/sql/Updates/0.0.3/r1155_mangos.sql b/sql/updates/0.0.3/r1155_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1155_mangos.sql rename to sql/updates/0.0.3/r1155_mangos.sql diff --git a/sql/Updates/0.0.3/r1169_mangos.sql b/sql/updates/0.0.3/r1169_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1169_mangos.sql rename to sql/updates/0.0.3/r1169_mangos.sql diff --git a/sql/Updates/0.0.3/r1169_scriptdev2.sql b/sql/updates/0.0.3/r1169_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1169_scriptdev2.sql rename to sql/updates/0.0.3/r1169_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1171_scriptdev2.sql b/sql/updates/0.0.3/r1171_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1171_scriptdev2.sql rename to sql/updates/0.0.3/r1171_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1173_scriptdev2.sql b/sql/updates/0.0.3/r1173_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1173_scriptdev2.sql rename to sql/updates/0.0.3/r1173_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1180_mangos.sql b/sql/updates/0.0.3/r1180_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1180_mangos.sql rename to sql/updates/0.0.3/r1180_mangos.sql diff --git a/sql/Updates/0.0.3/r1184_mangos.sql b/sql/updates/0.0.3/r1184_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1184_mangos.sql rename to sql/updates/0.0.3/r1184_mangos.sql diff --git a/sql/Updates/0.0.3/r1197_mangos.sql b/sql/updates/0.0.3/r1197_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1197_mangos.sql rename to sql/updates/0.0.3/r1197_mangos.sql diff --git a/sql/Updates/0.0.3/r1199_mangos.sql b/sql/updates/0.0.3/r1199_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1199_mangos.sql rename to sql/updates/0.0.3/r1199_mangos.sql diff --git a/sql/Updates/0.0.3/r1202_mangos.sql b/sql/updates/0.0.3/r1202_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1202_mangos.sql rename to sql/updates/0.0.3/r1202_mangos.sql diff --git a/sql/Updates/0.0.3/r1202_scriptdev2.sql b/sql/updates/0.0.3/r1202_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1202_scriptdev2.sql rename to sql/updates/0.0.3/r1202_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1207_mangos.sql b/sql/updates/0.0.3/r1207_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1207_mangos.sql rename to sql/updates/0.0.3/r1207_mangos.sql diff --git a/sql/Updates/0.0.3/r1207_scriptdev2.sql b/sql/updates/0.0.3/r1207_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1207_scriptdev2.sql rename to sql/updates/0.0.3/r1207_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1210_mangos.sql b/sql/updates/0.0.3/r1210_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1210_mangos.sql rename to sql/updates/0.0.3/r1210_mangos.sql diff --git a/sql/Updates/0.0.3/r1212_mangos.sql b/sql/updates/0.0.3/r1212_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1212_mangos.sql rename to sql/updates/0.0.3/r1212_mangos.sql diff --git a/sql/Updates/0.0.3/r1212_scriptdev2.sql b/sql/updates/0.0.3/r1212_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1212_scriptdev2.sql rename to sql/updates/0.0.3/r1212_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1215_mangos.sql b/sql/updates/0.0.3/r1215_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1215_mangos.sql rename to sql/updates/0.0.3/r1215_mangos.sql diff --git a/sql/Updates/0.0.3/r1215_scriptdev2.sql b/sql/updates/0.0.3/r1215_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1215_scriptdev2.sql rename to sql/updates/0.0.3/r1215_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1218_scriptdev2.sql b/sql/updates/0.0.3/r1218_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1218_scriptdev2.sql rename to sql/updates/0.0.3/r1218_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1221_mangos.sql b/sql/updates/0.0.3/r1221_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1221_mangos.sql rename to sql/updates/0.0.3/r1221_mangos.sql diff --git a/sql/Updates/0.0.3/r1221_scriptdev2.sql b/sql/updates/0.0.3/r1221_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1221_scriptdev2.sql rename to sql/updates/0.0.3/r1221_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1222_scriptdev2.sql b/sql/updates/0.0.3/r1222_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1222_scriptdev2.sql rename to sql/updates/0.0.3/r1222_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1234_mangos.sql b/sql/updates/0.0.3/r1234_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1234_mangos.sql rename to sql/updates/0.0.3/r1234_mangos.sql diff --git a/sql/Updates/0.0.3/r1241_scriptdev2.sql b/sql/updates/0.0.3/r1241_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1241_scriptdev2.sql rename to sql/updates/0.0.3/r1241_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1242_mangos.sql b/sql/updates/0.0.3/r1242_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1242_mangos.sql rename to sql/updates/0.0.3/r1242_mangos.sql diff --git a/sql/Updates/0.0.3/r1242_scriptdev2.sql b/sql/updates/0.0.3/r1242_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1242_scriptdev2.sql rename to sql/updates/0.0.3/r1242_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1243_mangos.sql b/sql/updates/0.0.3/r1243_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1243_mangos.sql rename to sql/updates/0.0.3/r1243_mangos.sql diff --git a/sql/Updates/0.0.3/r1243_scriptdev2.sql b/sql/updates/0.0.3/r1243_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1243_scriptdev2.sql rename to sql/updates/0.0.3/r1243_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1249_mangos.sql b/sql/updates/0.0.3/r1249_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1249_mangos.sql rename to sql/updates/0.0.3/r1249_mangos.sql diff --git a/sql/Updates/0.0.3/r1249_scriptdev2.sql b/sql/updates/0.0.3/r1249_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1249_scriptdev2.sql rename to sql/updates/0.0.3/r1249_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1250_mangos.sql b/sql/updates/0.0.3/r1250_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1250_mangos.sql rename to sql/updates/0.0.3/r1250_mangos.sql diff --git a/sql/Updates/0.0.3/r1250_scriptdev2.sql b/sql/updates/0.0.3/r1250_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1250_scriptdev2.sql rename to sql/updates/0.0.3/r1250_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1251_scriptdev2.sql b/sql/updates/0.0.3/r1251_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1251_scriptdev2.sql rename to sql/updates/0.0.3/r1251_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1257_scriptdev2.sql b/sql/updates/0.0.3/r1257_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1257_scriptdev2.sql rename to sql/updates/0.0.3/r1257_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1258_mangos.sql b/sql/updates/0.0.3/r1258_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1258_mangos.sql rename to sql/updates/0.0.3/r1258_mangos.sql diff --git a/sql/Updates/0.0.3/r1258_scriptdev2.sql b/sql/updates/0.0.3/r1258_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1258_scriptdev2.sql rename to sql/updates/0.0.3/r1258_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1260_scriptdev2.sql b/sql/updates/0.0.3/r1260_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1260_scriptdev2.sql rename to sql/updates/0.0.3/r1260_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1261_mangos.sql b/sql/updates/0.0.3/r1261_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1261_mangos.sql rename to sql/updates/0.0.3/r1261_mangos.sql diff --git a/sql/Updates/0.0.3/r1263_mangos.sql b/sql/updates/0.0.3/r1263_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1263_mangos.sql rename to sql/updates/0.0.3/r1263_mangos.sql diff --git a/sql/Updates/0.0.3/r1265_mangos.sql b/sql/updates/0.0.3/r1265_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1265_mangos.sql rename to sql/updates/0.0.3/r1265_mangos.sql diff --git a/sql/Updates/0.0.3/r1265_scriptdev2.sql b/sql/updates/0.0.3/r1265_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1265_scriptdev2.sql rename to sql/updates/0.0.3/r1265_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1266_mangos.sql b/sql/updates/0.0.3/r1266_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1266_mangos.sql rename to sql/updates/0.0.3/r1266_mangos.sql diff --git a/sql/Updates/0.0.3/r1266_scriptdev2.sql b/sql/updates/0.0.3/r1266_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1266_scriptdev2.sql rename to sql/updates/0.0.3/r1266_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1280_mangos.sql b/sql/updates/0.0.3/r1280_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1280_mangos.sql rename to sql/updates/0.0.3/r1280_mangos.sql diff --git a/sql/Updates/0.0.3/r1280_scriptdev2.sql b/sql/updates/0.0.3/r1280_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1280_scriptdev2.sql rename to sql/updates/0.0.3/r1280_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1281_mangos.sql b/sql/updates/0.0.3/r1281_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1281_mangos.sql rename to sql/updates/0.0.3/r1281_mangos.sql diff --git a/sql/Updates/0.0.3/r1282_mangos.sql b/sql/updates/0.0.3/r1282_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1282_mangos.sql rename to sql/updates/0.0.3/r1282_mangos.sql diff --git a/sql/Updates/0.0.3/r1283_mangos.sql b/sql/updates/0.0.3/r1283_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1283_mangos.sql rename to sql/updates/0.0.3/r1283_mangos.sql diff --git a/sql/Updates/0.0.3/r1299_scriptdev2.sql b/sql/updates/0.0.3/r1299_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1299_scriptdev2.sql rename to sql/updates/0.0.3/r1299_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1300_mangos.sql b/sql/updates/0.0.3/r1300_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1300_mangos.sql rename to sql/updates/0.0.3/r1300_mangos.sql diff --git a/sql/Updates/0.0.3/r1307_mangos.sql b/sql/updates/0.0.3/r1307_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1307_mangos.sql rename to sql/updates/0.0.3/r1307_mangos.sql diff --git a/sql/Updates/0.0.3/r1317_mangos.sql b/sql/updates/0.0.3/r1317_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1317_mangos.sql rename to sql/updates/0.0.3/r1317_mangos.sql diff --git a/sql/Updates/0.0.3/r1317_scriptdev2.sql b/sql/updates/0.0.3/r1317_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1317_scriptdev2.sql rename to sql/updates/0.0.3/r1317_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1321_mangos.sql b/sql/updates/0.0.3/r1321_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1321_mangos.sql rename to sql/updates/0.0.3/r1321_mangos.sql diff --git a/sql/Updates/0.0.3/r1321_scriptdev2.sql b/sql/updates/0.0.3/r1321_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1321_scriptdev2.sql rename to sql/updates/0.0.3/r1321_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1322_scriptdev2.sql b/sql/updates/0.0.3/r1322_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1322_scriptdev2.sql rename to sql/updates/0.0.3/r1322_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1326_scriptdev2.sql b/sql/updates/0.0.3/r1326_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1326_scriptdev2.sql rename to sql/updates/0.0.3/r1326_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1333_mangos.sql b/sql/updates/0.0.3/r1333_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1333_mangos.sql rename to sql/updates/0.0.3/r1333_mangos.sql diff --git a/sql/Updates/0.0.3/r1334_mangos.sql b/sql/updates/0.0.3/r1334_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1334_mangos.sql rename to sql/updates/0.0.3/r1334_mangos.sql diff --git a/sql/Updates/0.0.3/r1335_scriptdev2.sql b/sql/updates/0.0.3/r1335_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1335_scriptdev2.sql rename to sql/updates/0.0.3/r1335_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1336_mangos.sql b/sql/updates/0.0.3/r1336_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1336_mangos.sql rename to sql/updates/0.0.3/r1336_mangos.sql diff --git a/sql/Updates/0.0.3/r1336_scriptdev2.sql b/sql/updates/0.0.3/r1336_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1336_scriptdev2.sql rename to sql/updates/0.0.3/r1336_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1341_scriptdev2.sql b/sql/updates/0.0.3/r1341_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1341_scriptdev2.sql rename to sql/updates/0.0.3/r1341_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1351_mangos.sql b/sql/updates/0.0.3/r1351_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1351_mangos.sql rename to sql/updates/0.0.3/r1351_mangos.sql diff --git a/sql/Updates/0.0.3/r1351_scriptdev2.sql b/sql/updates/0.0.3/r1351_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1351_scriptdev2.sql rename to sql/updates/0.0.3/r1351_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1352_mangos.sql b/sql/updates/0.0.3/r1352_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1352_mangos.sql rename to sql/updates/0.0.3/r1352_mangos.sql diff --git a/sql/Updates/0.0.3/r1352_scriptdev2.sql b/sql/updates/0.0.3/r1352_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1352_scriptdev2.sql rename to sql/updates/0.0.3/r1352_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1354_scriptdev2.sql b/sql/updates/0.0.3/r1354_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1354_scriptdev2.sql rename to sql/updates/0.0.3/r1354_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1358_mangos.sql b/sql/updates/0.0.3/r1358_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1358_mangos.sql rename to sql/updates/0.0.3/r1358_mangos.sql diff --git a/sql/Updates/0.0.3/r1359_mangos.sql b/sql/updates/0.0.3/r1359_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1359_mangos.sql rename to sql/updates/0.0.3/r1359_mangos.sql diff --git a/sql/Updates/0.0.3/r1359_scriptdev2.sql b/sql/updates/0.0.3/r1359_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1359_scriptdev2.sql rename to sql/updates/0.0.3/r1359_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1367_mangos.sql b/sql/updates/0.0.3/r1367_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1367_mangos.sql rename to sql/updates/0.0.3/r1367_mangos.sql diff --git a/sql/Updates/0.0.3/r1368_mangos.sql b/sql/updates/0.0.3/r1368_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1368_mangos.sql rename to sql/updates/0.0.3/r1368_mangos.sql diff --git a/sql/Updates/0.0.3/r1369_mangos.sql b/sql/updates/0.0.3/r1369_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1369_mangos.sql rename to sql/updates/0.0.3/r1369_mangos.sql diff --git a/sql/Updates/0.0.3/r1370_mangos.sql b/sql/updates/0.0.3/r1370_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1370_mangos.sql rename to sql/updates/0.0.3/r1370_mangos.sql diff --git a/sql/Updates/0.0.3/r1371_scriptdev2.sql b/sql/updates/0.0.3/r1371_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1371_scriptdev2.sql rename to sql/updates/0.0.3/r1371_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1374_mangos.sql b/sql/updates/0.0.3/r1374_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1374_mangos.sql rename to sql/updates/0.0.3/r1374_mangos.sql diff --git a/sql/Updates/0.0.3/r1374_scriptdev2.sql b/sql/updates/0.0.3/r1374_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1374_scriptdev2.sql rename to sql/updates/0.0.3/r1374_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1378_mangos.sql b/sql/updates/0.0.3/r1378_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1378_mangos.sql rename to sql/updates/0.0.3/r1378_mangos.sql diff --git a/sql/Updates/0.0.3/r1378_scriptdev2.sql b/sql/updates/0.0.3/r1378_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1378_scriptdev2.sql rename to sql/updates/0.0.3/r1378_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1379_mangos.sql b/sql/updates/0.0.3/r1379_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1379_mangos.sql rename to sql/updates/0.0.3/r1379_mangos.sql diff --git a/sql/Updates/0.0.3/r1379_scriptdev2.sql b/sql/updates/0.0.3/r1379_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1379_scriptdev2.sql rename to sql/updates/0.0.3/r1379_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1380_mangos.sql b/sql/updates/0.0.3/r1380_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1380_mangos.sql rename to sql/updates/0.0.3/r1380_mangos.sql diff --git a/sql/Updates/0.0.3/r1380_scriptdev2.sql b/sql/updates/0.0.3/r1380_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1380_scriptdev2.sql rename to sql/updates/0.0.3/r1380_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1382_mangos.sql b/sql/updates/0.0.3/r1382_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1382_mangos.sql rename to sql/updates/0.0.3/r1382_mangos.sql diff --git a/sql/Updates/0.0.3/r1383_scriptdev2.sql b/sql/updates/0.0.3/r1383_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1383_scriptdev2.sql rename to sql/updates/0.0.3/r1383_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1384_scriptdev2.sql b/sql/updates/0.0.3/r1384_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1384_scriptdev2.sql rename to sql/updates/0.0.3/r1384_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1385_mangos.sql b/sql/updates/0.0.3/r1385_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1385_mangos.sql rename to sql/updates/0.0.3/r1385_mangos.sql diff --git a/sql/Updates/0.0.3/r1385_scriptdev2.sql b/sql/updates/0.0.3/r1385_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1385_scriptdev2.sql rename to sql/updates/0.0.3/r1385_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1386_mangos.sql b/sql/updates/0.0.3/r1386_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1386_mangos.sql rename to sql/updates/0.0.3/r1386_mangos.sql diff --git a/sql/Updates/0.0.3/r1386_scriptdev2.sql b/sql/updates/0.0.3/r1386_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1386_scriptdev2.sql rename to sql/updates/0.0.3/r1386_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1388_mangos.sql b/sql/updates/0.0.3/r1388_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1388_mangos.sql rename to sql/updates/0.0.3/r1388_mangos.sql diff --git a/sql/Updates/0.0.3/r1388_scriptdev2.sql b/sql/updates/0.0.3/r1388_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1388_scriptdev2.sql rename to sql/updates/0.0.3/r1388_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1391_mangos.sql b/sql/updates/0.0.3/r1391_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1391_mangos.sql rename to sql/updates/0.0.3/r1391_mangos.sql diff --git a/sql/Updates/0.0.3/r1391_scriptdev2.sql b/sql/updates/0.0.3/r1391_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1391_scriptdev2.sql rename to sql/updates/0.0.3/r1391_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1392_mangos.sql b/sql/updates/0.0.3/r1392_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1392_mangos.sql rename to sql/updates/0.0.3/r1392_mangos.sql diff --git a/sql/Updates/0.0.3/r1392_scriptdev2.sql b/sql/updates/0.0.3/r1392_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1392_scriptdev2.sql rename to sql/updates/0.0.3/r1392_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1394_mangos.sql b/sql/updates/0.0.3/r1394_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1394_mangos.sql rename to sql/updates/0.0.3/r1394_mangos.sql diff --git a/sql/Updates/0.0.3/r1394_scriptdev2.sql b/sql/updates/0.0.3/r1394_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1394_scriptdev2.sql rename to sql/updates/0.0.3/r1394_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1405_mangos.sql b/sql/updates/0.0.3/r1405_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1405_mangos.sql rename to sql/updates/0.0.3/r1405_mangos.sql diff --git a/sql/Updates/0.0.3/r1405_scriptdev2.sql b/sql/updates/0.0.3/r1405_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1405_scriptdev2.sql rename to sql/updates/0.0.3/r1405_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1406_mangos.sql b/sql/updates/0.0.3/r1406_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1406_mangos.sql rename to sql/updates/0.0.3/r1406_mangos.sql diff --git a/sql/Updates/0.0.3/r1408_mangos.sql b/sql/updates/0.0.3/r1408_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1408_mangos.sql rename to sql/updates/0.0.3/r1408_mangos.sql diff --git a/sql/Updates/0.0.3/r1408_scriptdev2.sql b/sql/updates/0.0.3/r1408_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1408_scriptdev2.sql rename to sql/updates/0.0.3/r1408_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1409_mangos.sql b/sql/updates/0.0.3/r1409_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1409_mangos.sql rename to sql/updates/0.0.3/r1409_mangos.sql diff --git a/sql/Updates/0.0.3/r1409_scriptdev2.sql b/sql/updates/0.0.3/r1409_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1409_scriptdev2.sql rename to sql/updates/0.0.3/r1409_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1410_mangos.sql b/sql/updates/0.0.3/r1410_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1410_mangos.sql rename to sql/updates/0.0.3/r1410_mangos.sql diff --git a/sql/Updates/0.0.3/r1410_scriptdev2.sql b/sql/updates/0.0.3/r1410_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1410_scriptdev2.sql rename to sql/updates/0.0.3/r1410_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1411_mangos.sql b/sql/updates/0.0.3/r1411_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1411_mangos.sql rename to sql/updates/0.0.3/r1411_mangos.sql diff --git a/sql/Updates/0.0.3/r1411_scriptdev2.sql b/sql/updates/0.0.3/r1411_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1411_scriptdev2.sql rename to sql/updates/0.0.3/r1411_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1412_mangos.sql b/sql/updates/0.0.3/r1412_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1412_mangos.sql rename to sql/updates/0.0.3/r1412_mangos.sql diff --git a/sql/Updates/0.0.3/r1412_scriptdev2.sql b/sql/updates/0.0.3/r1412_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1412_scriptdev2.sql rename to sql/updates/0.0.3/r1412_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1413_mangos.sql b/sql/updates/0.0.3/r1413_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1413_mangos.sql rename to sql/updates/0.0.3/r1413_mangos.sql diff --git a/sql/Updates/0.0.3/r1413_scriptdev2.sql b/sql/updates/0.0.3/r1413_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1413_scriptdev2.sql rename to sql/updates/0.0.3/r1413_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1414_mangos.sql b/sql/updates/0.0.3/r1414_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1414_mangos.sql rename to sql/updates/0.0.3/r1414_mangos.sql diff --git a/sql/Updates/0.0.3/r1414_scriptdev2.sql b/sql/updates/0.0.3/r1414_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1414_scriptdev2.sql rename to sql/updates/0.0.3/r1414_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1415_mangos.sql b/sql/updates/0.0.3/r1415_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1415_mangos.sql rename to sql/updates/0.0.3/r1415_mangos.sql diff --git a/sql/Updates/0.0.3/r1417_mangos.sql b/sql/updates/0.0.3/r1417_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1417_mangos.sql rename to sql/updates/0.0.3/r1417_mangos.sql diff --git a/sql/Updates/0.0.3/r1418_scriptdev2.sql b/sql/updates/0.0.3/r1418_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1418_scriptdev2.sql rename to sql/updates/0.0.3/r1418_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1419_mangos.sql b/sql/updates/0.0.3/r1419_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1419_mangos.sql rename to sql/updates/0.0.3/r1419_mangos.sql diff --git a/sql/Updates/0.0.3/r1421_scriptdev2.sql b/sql/updates/0.0.3/r1421_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1421_scriptdev2.sql rename to sql/updates/0.0.3/r1421_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1422_mangos.sql b/sql/updates/0.0.3/r1422_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1422_mangos.sql rename to sql/updates/0.0.3/r1422_mangos.sql diff --git a/sql/Updates/0.0.3/r1422_scriptdev2.sql b/sql/updates/0.0.3/r1422_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1422_scriptdev2.sql rename to sql/updates/0.0.3/r1422_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1428_scriptdev2.sql b/sql/updates/0.0.3/r1428_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1428_scriptdev2.sql rename to sql/updates/0.0.3/r1428_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1430_mangos.sql b/sql/updates/0.0.3/r1430_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1430_mangos.sql rename to sql/updates/0.0.3/r1430_mangos.sql diff --git a/sql/Updates/0.0.3/r1433_mangos.sql b/sql/updates/0.0.3/r1433_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1433_mangos.sql rename to sql/updates/0.0.3/r1433_mangos.sql diff --git a/sql/Updates/0.0.3/r1435_mangos.sql b/sql/updates/0.0.3/r1435_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1435_mangos.sql rename to sql/updates/0.0.3/r1435_mangos.sql diff --git a/sql/Updates/0.0.3/r1436_mangos.sql b/sql/updates/0.0.3/r1436_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1436_mangos.sql rename to sql/updates/0.0.3/r1436_mangos.sql diff --git a/sql/Updates/0.0.3/r1437_scriptdev2.sql b/sql/updates/0.0.3/r1437_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1437_scriptdev2.sql rename to sql/updates/0.0.3/r1437_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1439_scriptdev2.sql b/sql/updates/0.0.3/r1439_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r1439_scriptdev2.sql rename to sql/updates/0.0.3/r1439_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r1441_mangos.sql b/sql/updates/0.0.3/r1441_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r1441_mangos.sql rename to sql/updates/0.0.3/r1441_mangos.sql diff --git a/sql/Updates/0.0.3/r814_scriptdev2_eventai_scripts.sql b/sql/updates/0.0.3/r814_scriptdev2_eventai_scripts.sql similarity index 100% rename from sql/Updates/0.0.3/r814_scriptdev2_eventai_scripts.sql rename to sql/updates/0.0.3/r814_scriptdev2_eventai_scripts.sql diff --git a/sql/Updates/0.0.3/r820_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r820_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r820_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r820_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r822_mangos.sql b/sql/updates/0.0.3/r822_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r822_mangos.sql rename to sql/updates/0.0.3/r822_mangos.sql diff --git a/sql/Updates/0.0.3/r822_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r822_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r822_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r822_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r823_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r823_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r823_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r823_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r824_mangos.sql b/sql/updates/0.0.3/r824_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r824_mangos.sql rename to sql/updates/0.0.3/r824_mangos.sql diff --git a/sql/Updates/0.0.3/r824_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r824_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r824_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r824_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r825_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r825_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r825_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r825_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r826_scriptdev2.sql b/sql/updates/0.0.3/r826_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r826_scriptdev2.sql rename to sql/updates/0.0.3/r826_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r827_mangos.sql b/sql/updates/0.0.3/r827_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r827_mangos.sql rename to sql/updates/0.0.3/r827_mangos.sql diff --git a/sql/Updates/0.0.3/r828_mangos.sql b/sql/updates/0.0.3/r828_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r828_mangos.sql rename to sql/updates/0.0.3/r828_mangos.sql diff --git a/sql/Updates/0.0.3/r834_mangos.sql b/sql/updates/0.0.3/r834_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r834_mangos.sql rename to sql/updates/0.0.3/r834_mangos.sql diff --git a/sql/Updates/0.0.3/r834_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r834_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r834_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r834_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r835_mangos.sql b/sql/updates/0.0.3/r835_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r835_mangos.sql rename to sql/updates/0.0.3/r835_mangos.sql diff --git a/sql/Updates/0.0.3/r845_mangos.sql b/sql/updates/0.0.3/r845_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r845_mangos.sql rename to sql/updates/0.0.3/r845_mangos.sql diff --git a/sql/Updates/0.0.3/r846_scriptdev2.sql b/sql/updates/0.0.3/r846_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r846_scriptdev2.sql rename to sql/updates/0.0.3/r846_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r847_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r847_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r847_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r847_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r848_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r848_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r848_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r848_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r849_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r849_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r849_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r849_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r850_mangos.sql b/sql/updates/0.0.3/r850_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r850_mangos.sql rename to sql/updates/0.0.3/r850_mangos.sql diff --git a/sql/Updates/0.0.3/r851_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r851_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r851_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r851_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r852_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r852_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r852_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r852_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r854_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r854_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r854_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r854_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r855_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r855_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r855_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r855_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r856_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r856_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r856_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r856_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r860_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r860_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r860_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r860_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r862_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r862_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r862_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r862_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r863_mangos.sql b/sql/updates/0.0.3/r863_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r863_mangos.sql rename to sql/updates/0.0.3/r863_mangos.sql diff --git a/sql/Updates/0.0.3/r872_mangos.sql b/sql/updates/0.0.3/r872_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r872_mangos.sql rename to sql/updates/0.0.3/r872_mangos.sql diff --git a/sql/Updates/0.0.3/r883_mangos.sql b/sql/updates/0.0.3/r883_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r883_mangos.sql rename to sql/updates/0.0.3/r883_mangos.sql diff --git a/sql/Updates/0.0.3/r895_mangos.sql b/sql/updates/0.0.3/r895_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r895_mangos.sql rename to sql/updates/0.0.3/r895_mangos.sql diff --git a/sql/Updates/0.0.3/r900_mangos.sql b/sql/updates/0.0.3/r900_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r900_mangos.sql rename to sql/updates/0.0.3/r900_mangos.sql diff --git a/sql/Updates/0.0.3/r903_mangos.sql b/sql/updates/0.0.3/r903_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r903_mangos.sql rename to sql/updates/0.0.3/r903_mangos.sql diff --git a/sql/Updates/0.0.3/r903_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r903_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r903_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r903_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r907_mangos.sql b/sql/updates/0.0.3/r907_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r907_mangos.sql rename to sql/updates/0.0.3/r907_mangos.sql diff --git a/sql/Updates/0.0.3/r907_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r907_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r907_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r907_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r909_mangos.sql b/sql/updates/0.0.3/r909_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r909_mangos.sql rename to sql/updates/0.0.3/r909_mangos.sql diff --git a/sql/Updates/0.0.3/r910_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r910_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r910_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r910_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r912_mangos.sql b/sql/updates/0.0.3/r912_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r912_mangos.sql rename to sql/updates/0.0.3/r912_mangos.sql diff --git a/sql/Updates/0.0.3/r912_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r912_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r912_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r912_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r916_mangos.sql b/sql/updates/0.0.3/r916_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r916_mangos.sql rename to sql/updates/0.0.3/r916_mangos.sql diff --git a/sql/Updates/0.0.3/r916_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r916_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r916_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r916_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r919_mangos.sql b/sql/updates/0.0.3/r919_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r919_mangos.sql rename to sql/updates/0.0.3/r919_mangos.sql diff --git a/sql/Updates/0.0.3/r922_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r922_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r922_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r922_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r924_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r924_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r924_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r924_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r936_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r936_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r936_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r936_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r937_mangos.sql b/sql/updates/0.0.3/r937_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r937_mangos.sql rename to sql/updates/0.0.3/r937_mangos.sql diff --git a/sql/Updates/0.0.3/r937_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r937_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r937_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r937_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r937_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r937_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r937_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r937_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r939_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r939_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r939_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r939_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r940_mangos.sql b/sql/updates/0.0.3/r940_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r940_mangos.sql rename to sql/updates/0.0.3/r940_mangos.sql diff --git a/sql/Updates/0.0.3/r941_mangos.sql b/sql/updates/0.0.3/r941_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r941_mangos.sql rename to sql/updates/0.0.3/r941_mangos.sql diff --git a/sql/Updates/0.0.3/r945_mangos.sql b/sql/updates/0.0.3/r945_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r945_mangos.sql rename to sql/updates/0.0.3/r945_mangos.sql diff --git a/sql/Updates/0.0.3/r945_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r945_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r945_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r945_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r945_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r945_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r945_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r945_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r947_mangos.sql b/sql/updates/0.0.3/r947_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r947_mangos.sql rename to sql/updates/0.0.3/r947_mangos.sql diff --git a/sql/Updates/0.0.3/r949_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r949_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r949_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r949_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r951_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r951_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r951_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r951_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r953_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r953_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r953_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r953_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r956_scriptdev2.sql b/sql/updates/0.0.3/r956_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r956_scriptdev2.sql rename to sql/updates/0.0.3/r956_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r963_mangos.sql b/sql/updates/0.0.3/r963_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r963_mangos.sql rename to sql/updates/0.0.3/r963_mangos.sql diff --git a/sql/Updates/0.0.3/r964_mangos.sql b/sql/updates/0.0.3/r964_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r964_mangos.sql rename to sql/updates/0.0.3/r964_mangos.sql diff --git a/sql/Updates/0.0.3/r965_mangos.sql b/sql/updates/0.0.3/r965_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r965_mangos.sql rename to sql/updates/0.0.3/r965_mangos.sql diff --git a/sql/Updates/0.0.3/r965_scriptdev2.sql b/sql/updates/0.0.3/r965_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r965_scriptdev2.sql rename to sql/updates/0.0.3/r965_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r972_mangos.sql b/sql/updates/0.0.3/r972_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r972_mangos.sql rename to sql/updates/0.0.3/r972_mangos.sql diff --git a/sql/Updates/0.0.3/r972_scriptdev2.sql b/sql/updates/0.0.3/r972_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r972_scriptdev2.sql rename to sql/updates/0.0.3/r972_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r973_mangos.sql b/sql/updates/0.0.3/r973_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r973_mangos.sql rename to sql/updates/0.0.3/r973_mangos.sql diff --git a/sql/Updates/0.0.3/r973_scriptdev2_script_waypoint.sql b/sql/updates/0.0.3/r973_scriptdev2_script_waypoint.sql similarity index 100% rename from sql/Updates/0.0.3/r973_scriptdev2_script_waypoint.sql rename to sql/updates/0.0.3/r973_scriptdev2_script_waypoint.sql diff --git a/sql/Updates/0.0.3/r975_mangos.sql b/sql/updates/0.0.3/r975_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r975_mangos.sql rename to sql/updates/0.0.3/r975_mangos.sql diff --git a/sql/Updates/0.0.3/r975_scriptdev2.sql b/sql/updates/0.0.3/r975_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r975_scriptdev2.sql rename to sql/updates/0.0.3/r975_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r976_mangos.sql b/sql/updates/0.0.3/r976_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r976_mangos.sql rename to sql/updates/0.0.3/r976_mangos.sql diff --git a/sql/Updates/0.0.3/r976_scriptdev2.sql b/sql/updates/0.0.3/r976_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r976_scriptdev2.sql rename to sql/updates/0.0.3/r976_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r978_mangos.sql b/sql/updates/0.0.3/r978_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r978_mangos.sql rename to sql/updates/0.0.3/r978_mangos.sql diff --git a/sql/Updates/0.0.3/r979_mangos.sql b/sql/updates/0.0.3/r979_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r979_mangos.sql rename to sql/updates/0.0.3/r979_mangos.sql diff --git a/sql/Updates/0.0.3/r979_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r979_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r979_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r979_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r980_mangos.sql b/sql/updates/0.0.3/r980_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r980_mangos.sql rename to sql/updates/0.0.3/r980_mangos.sql diff --git a/sql/Updates/0.0.3/r982_mangos.sql b/sql/updates/0.0.3/r982_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r982_mangos.sql rename to sql/updates/0.0.3/r982_mangos.sql diff --git a/sql/Updates/0.0.3/r982_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r982_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r982_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r982_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r989_mangos.sql b/sql/updates/0.0.3/r989_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r989_mangos.sql rename to sql/updates/0.0.3/r989_mangos.sql diff --git a/sql/Updates/0.0.3/r990_mangos.sql b/sql/updates/0.0.3/r990_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r990_mangos.sql rename to sql/updates/0.0.3/r990_mangos.sql diff --git a/sql/Updates/0.0.3/r991_scriptdev2.sql b/sql/updates/0.0.3/r991_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r991_scriptdev2.sql rename to sql/updates/0.0.3/r991_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r992_mangos.sql b/sql/updates/0.0.3/r992_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r992_mangos.sql rename to sql/updates/0.0.3/r992_mangos.sql diff --git a/sql/Updates/0.0.3/r993_mangos.sql b/sql/updates/0.0.3/r993_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r993_mangos.sql rename to sql/updates/0.0.3/r993_mangos.sql diff --git a/sql/Updates/0.0.3/r993_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r993_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r993_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r993_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.3/r995_mangos.sql b/sql/updates/0.0.3/r995_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r995_mangos.sql rename to sql/updates/0.0.3/r995_mangos.sql diff --git a/sql/Updates/0.0.3/r995_scriptdev2.sql b/sql/updates/0.0.3/r995_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.3/r995_scriptdev2.sql rename to sql/updates/0.0.3/r995_scriptdev2.sql diff --git a/sql/Updates/0.0.3/r997_mangos.sql b/sql/updates/0.0.3/r997_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r997_mangos.sql rename to sql/updates/0.0.3/r997_mangos.sql diff --git a/sql/Updates/0.0.3/r998_mangos.sql b/sql/updates/0.0.3/r998_mangos.sql similarity index 100% rename from sql/Updates/0.0.3/r998_mangos.sql rename to sql/updates/0.0.3/r998_mangos.sql diff --git a/sql/Updates/0.0.3/r998_scriptdev2_script_texts.sql b/sql/updates/0.0.3/r998_scriptdev2_script_texts.sql similarity index 100% rename from sql/Updates/0.0.3/r998_scriptdev2_script_texts.sql rename to sql/updates/0.0.3/r998_scriptdev2_script_texts.sql diff --git a/sql/Updates/0.0.4/r1453_scriptdev2.sql b/sql/updates/0.0.4/r1453_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1453_scriptdev2.sql rename to sql/updates/0.0.4/r1453_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1457_scriptdev2.sql b/sql/updates/0.0.4/r1457_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1457_scriptdev2.sql rename to sql/updates/0.0.4/r1457_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1459_mangos.sql b/sql/updates/0.0.4/r1459_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1459_mangos.sql rename to sql/updates/0.0.4/r1459_mangos.sql diff --git a/sql/Updates/0.0.4/r1460_mangos.sql b/sql/updates/0.0.4/r1460_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1460_mangos.sql rename to sql/updates/0.0.4/r1460_mangos.sql diff --git a/sql/Updates/0.0.4/r1461_mangos.sql b/sql/updates/0.0.4/r1461_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1461_mangos.sql rename to sql/updates/0.0.4/r1461_mangos.sql diff --git a/sql/Updates/0.0.4/r1461_scriptdev2.sql b/sql/updates/0.0.4/r1461_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1461_scriptdev2.sql rename to sql/updates/0.0.4/r1461_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1463_mangos.sql b/sql/updates/0.0.4/r1463_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1463_mangos.sql rename to sql/updates/0.0.4/r1463_mangos.sql diff --git a/sql/Updates/0.0.4/r1465_scriptdev2.sql b/sql/updates/0.0.4/r1465_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1465_scriptdev2.sql rename to sql/updates/0.0.4/r1465_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1466_scriptdev2.sql b/sql/updates/0.0.4/r1466_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1466_scriptdev2.sql rename to sql/updates/0.0.4/r1466_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1470_scriptdev2.sql b/sql/updates/0.0.4/r1470_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1470_scriptdev2.sql rename to sql/updates/0.0.4/r1470_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1473_scriptdev2.sql b/sql/updates/0.0.4/r1473_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1473_scriptdev2.sql rename to sql/updates/0.0.4/r1473_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1474_scriptdev2.sql b/sql/updates/0.0.4/r1474_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1474_scriptdev2.sql rename to sql/updates/0.0.4/r1474_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1476_mangos.sql b/sql/updates/0.0.4/r1476_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1476_mangos.sql rename to sql/updates/0.0.4/r1476_mangos.sql diff --git a/sql/Updates/0.0.4/r1476_scriptdev2.sql b/sql/updates/0.0.4/r1476_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1476_scriptdev2.sql rename to sql/updates/0.0.4/r1476_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1478_scriptdev2.sql b/sql/updates/0.0.4/r1478_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1478_scriptdev2.sql rename to sql/updates/0.0.4/r1478_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1481_scriptdev2.sql b/sql/updates/0.0.4/r1481_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1481_scriptdev2.sql rename to sql/updates/0.0.4/r1481_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1486_mangos.sql b/sql/updates/0.0.4/r1486_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1486_mangos.sql rename to sql/updates/0.0.4/r1486_mangos.sql diff --git a/sql/Updates/0.0.4/r1490_scriptdev2.sql b/sql/updates/0.0.4/r1490_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1490_scriptdev2.sql rename to sql/updates/0.0.4/r1490_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1492_mangos.sql b/sql/updates/0.0.4/r1492_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1492_mangos.sql rename to sql/updates/0.0.4/r1492_mangos.sql diff --git a/sql/Updates/0.0.4/r1493_scriptdev2.sql b/sql/updates/0.0.4/r1493_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1493_scriptdev2.sql rename to sql/updates/0.0.4/r1493_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1494_mangos.sql b/sql/updates/0.0.4/r1494_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1494_mangos.sql rename to sql/updates/0.0.4/r1494_mangos.sql diff --git a/sql/Updates/0.0.4/r1496_mangos.sql b/sql/updates/0.0.4/r1496_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1496_mangos.sql rename to sql/updates/0.0.4/r1496_mangos.sql diff --git a/sql/Updates/0.0.4/r1498_mangos.sql b/sql/updates/0.0.4/r1498_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1498_mangos.sql rename to sql/updates/0.0.4/r1498_mangos.sql diff --git a/sql/Updates/0.0.4/r1500_mangos.sql b/sql/updates/0.0.4/r1500_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1500_mangos.sql rename to sql/updates/0.0.4/r1500_mangos.sql diff --git a/sql/Updates/0.0.4/r1502_mangos.sql b/sql/updates/0.0.4/r1502_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1502_mangos.sql rename to sql/updates/0.0.4/r1502_mangos.sql diff --git a/sql/Updates/0.0.4/r1503_scriptdev2.sql b/sql/updates/0.0.4/r1503_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1503_scriptdev2.sql rename to sql/updates/0.0.4/r1503_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1504_scriptdev2.sql b/sql/updates/0.0.4/r1504_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1504_scriptdev2.sql rename to sql/updates/0.0.4/r1504_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1506_scriptdev2.sql b/sql/updates/0.0.4/r1506_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1506_scriptdev2.sql rename to sql/updates/0.0.4/r1506_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1508_mangos.sql b/sql/updates/0.0.4/r1508_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1508_mangos.sql rename to sql/updates/0.0.4/r1508_mangos.sql diff --git a/sql/Updates/0.0.4/r1513_scriptdev2.sql b/sql/updates/0.0.4/r1513_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1513_scriptdev2.sql rename to sql/updates/0.0.4/r1513_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1516_mangos.sql b/sql/updates/0.0.4/r1516_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1516_mangos.sql rename to sql/updates/0.0.4/r1516_mangos.sql diff --git a/sql/Updates/0.0.4/r1516_scriptdev2.sql b/sql/updates/0.0.4/r1516_scriptdev2.sql similarity index 98% rename from sql/Updates/0.0.4/r1516_scriptdev2.sql rename to sql/updates/0.0.4/r1516_scriptdev2.sql index 9ec1cf2ab..400b69304 100644 --- a/sql/Updates/0.0.4/r1516_scriptdev2.sql +++ b/sql/updates/0.0.4/r1516_scriptdev2.sql @@ -1,2 +1 @@ UPDATE script_texts SET comment='sladran SAY_SUMMON_CONSTRICTOR' WHERE entry=-1604002; - \ No newline at end of file diff --git a/sql/Updates/0.0.4/r1517_scriptdev2.sql b/sql/updates/0.0.4/r1517_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1517_scriptdev2.sql rename to sql/updates/0.0.4/r1517_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1519_mangos.sql b/sql/updates/0.0.4/r1519_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1519_mangos.sql rename to sql/updates/0.0.4/r1519_mangos.sql diff --git a/sql/Updates/0.0.4/r1523_mangos.sql b/sql/updates/0.0.4/r1523_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1523_mangos.sql rename to sql/updates/0.0.4/r1523_mangos.sql diff --git a/sql/Updates/0.0.4/r1524_scriptdev2.sql b/sql/updates/0.0.4/r1524_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1524_scriptdev2.sql rename to sql/updates/0.0.4/r1524_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1525_mangos.sql b/sql/updates/0.0.4/r1525_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1525_mangos.sql rename to sql/updates/0.0.4/r1525_mangos.sql diff --git a/sql/Updates/0.0.4/r1525_scriptdev2.sql b/sql/updates/0.0.4/r1525_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1525_scriptdev2.sql rename to sql/updates/0.0.4/r1525_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1531_mangos.sql b/sql/updates/0.0.4/r1531_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1531_mangos.sql rename to sql/updates/0.0.4/r1531_mangos.sql diff --git a/sql/Updates/0.0.4/r1536_mangos.sql b/sql/updates/0.0.4/r1536_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1536_mangos.sql rename to sql/updates/0.0.4/r1536_mangos.sql diff --git a/sql/Updates/0.0.4/r1538_mangos.sql b/sql/updates/0.0.4/r1538_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1538_mangos.sql rename to sql/updates/0.0.4/r1538_mangos.sql diff --git a/sql/Updates/0.0.4/r1540_mangos.sql b/sql/updates/0.0.4/r1540_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1540_mangos.sql rename to sql/updates/0.0.4/r1540_mangos.sql diff --git a/sql/Updates/0.0.4/r1540_scriptdev2.sql b/sql/updates/0.0.4/r1540_scriptdev2.sql similarity index 100% rename from sql/Updates/0.0.4/r1540_scriptdev2.sql rename to sql/updates/0.0.4/r1540_scriptdev2.sql diff --git a/sql/Updates/0.0.4/r1542_mangos.sql b/sql/updates/0.0.4/r1542_mangos.sql similarity index 100% rename from sql/Updates/0.0.4/r1542_mangos.sql rename to sql/updates/0.0.4/r1542_mangos.sql diff --git a/sql/Updates/r1543_scriptdev2.sql b/sql/updates/r1543_scriptdev2.sql similarity index 100% rename from sql/Updates/r1543_scriptdev2.sql rename to sql/updates/r1543_scriptdev2.sql diff --git a/sql/Updates/r1544_mangos.sql b/sql/updates/r1544_mangos.sql similarity index 100% rename from sql/Updates/r1544_mangos.sql rename to sql/updates/r1544_mangos.sql diff --git a/sql/Updates/r1545_scriptdev2.sql b/sql/updates/r1545_scriptdev2.sql similarity index 100% rename from sql/Updates/r1545_scriptdev2.sql rename to sql/updates/r1545_scriptdev2.sql diff --git a/sql/Updates/r1548_scriptdev2.sql b/sql/updates/r1548_scriptdev2.sql similarity index 100% rename from sql/Updates/r1548_scriptdev2.sql rename to sql/updates/r1548_scriptdev2.sql diff --git a/sql/Updates/r1549_mangos.sql b/sql/updates/r1549_mangos.sql similarity index 100% rename from sql/Updates/r1549_mangos.sql rename to sql/updates/r1549_mangos.sql diff --git a/sql/Updates/r1549_scriptdev2.sql b/sql/updates/r1549_scriptdev2.sql similarity index 100% rename from sql/Updates/r1549_scriptdev2.sql rename to sql/updates/r1549_scriptdev2.sql diff --git a/sql/Updates/r1551_mangos.sql b/sql/updates/r1551_mangos.sql similarity index 100% rename from sql/Updates/r1551_mangos.sql rename to sql/updates/r1551_mangos.sql diff --git a/sql/Updates/r1554_mangos.sql b/sql/updates/r1554_mangos.sql similarity index 100% rename from sql/Updates/r1554_mangos.sql rename to sql/updates/r1554_mangos.sql diff --git a/sql/Updates/r1554_scriptdev2.sql b/sql/updates/r1554_scriptdev2.sql similarity index 100% rename from sql/Updates/r1554_scriptdev2.sql rename to sql/updates/r1554_scriptdev2.sql diff --git a/sql/Updates/r1555_scriptdev2.sql b/sql/updates/r1555_scriptdev2.sql similarity index 100% rename from sql/Updates/r1555_scriptdev2.sql rename to sql/updates/r1555_scriptdev2.sql diff --git a/sql/Updates/r1556_mangos.sql b/sql/updates/r1556_mangos.sql similarity index 100% rename from sql/Updates/r1556_mangos.sql rename to sql/updates/r1556_mangos.sql diff --git a/sql/Updates/r1557_scriptdev2.sql b/sql/updates/r1557_scriptdev2.sql similarity index 100% rename from sql/Updates/r1557_scriptdev2.sql rename to sql/updates/r1557_scriptdev2.sql diff --git a/sql/Updates/r1563_mangos.sql b/sql/updates/r1563_mangos.sql similarity index 100% rename from sql/Updates/r1563_mangos.sql rename to sql/updates/r1563_mangos.sql diff --git a/sql/Updates/r1567_mangos.sql b/sql/updates/r1567_mangos.sql similarity index 100% rename from sql/Updates/r1567_mangos.sql rename to sql/updates/r1567_mangos.sql diff --git a/sql/Updates/r1567_scriptdev2.sql b/sql/updates/r1567_scriptdev2.sql similarity index 100% rename from sql/Updates/r1567_scriptdev2.sql rename to sql/updates/r1567_scriptdev2.sql diff --git a/sql/Updates/r1570_scriptdev2.sql b/sql/updates/r1570_scriptdev2.sql similarity index 100% rename from sql/Updates/r1570_scriptdev2.sql rename to sql/updates/r1570_scriptdev2.sql diff --git a/sql/Updates/r1577_mangos.sql b/sql/updates/r1577_mangos.sql similarity index 100% rename from sql/Updates/r1577_mangos.sql rename to sql/updates/r1577_mangos.sql diff --git a/sql/Updates/r1577_scriptdev2.sql b/sql/updates/r1577_scriptdev2.sql similarity index 100% rename from sql/Updates/r1577_scriptdev2.sql rename to sql/updates/r1577_scriptdev2.sql diff --git a/sql/Updates/r1583_scriptdev2.sql b/sql/updates/r1583_scriptdev2.sql similarity index 100% rename from sql/Updates/r1583_scriptdev2.sql rename to sql/updates/r1583_scriptdev2.sql diff --git a/sql/Updates/r1584_scriptdev2.sql b/sql/updates/r1584_scriptdev2.sql similarity index 100% rename from sql/Updates/r1584_scriptdev2.sql rename to sql/updates/r1584_scriptdev2.sql diff --git a/sql/Updates/r1587_scriptdev2.sql b/sql/updates/r1587_scriptdev2.sql similarity index 100% rename from sql/Updates/r1587_scriptdev2.sql rename to sql/updates/r1587_scriptdev2.sql diff --git a/sql/Updates/r1589_mangos.sql b/sql/updates/r1589_mangos.sql similarity index 100% rename from sql/Updates/r1589_mangos.sql rename to sql/updates/r1589_mangos.sql diff --git a/sql/Updates/r1590_mangos.sql b/sql/updates/r1590_mangos.sql similarity index 100% rename from sql/Updates/r1590_mangos.sql rename to sql/updates/r1590_mangos.sql diff --git a/sql/Updates/r1591_mangos.sql b/sql/updates/r1591_mangos.sql similarity index 100% rename from sql/Updates/r1591_mangos.sql rename to sql/updates/r1591_mangos.sql diff --git a/sql/Updates/r1592_mangos.sql b/sql/updates/r1592_mangos.sql similarity index 100% rename from sql/Updates/r1592_mangos.sql rename to sql/updates/r1592_mangos.sql diff --git a/sql/Updates/r1593_mangos.sql b/sql/updates/r1593_mangos.sql similarity index 100% rename from sql/Updates/r1593_mangos.sql rename to sql/updates/r1593_mangos.sql diff --git a/sql/Updates/r1594_mangos.sql b/sql/updates/r1594_mangos.sql similarity index 100% rename from sql/Updates/r1594_mangos.sql rename to sql/updates/r1594_mangos.sql diff --git a/sql/Updates/r1595_mangos.sql b/sql/updates/r1595_mangos.sql similarity index 100% rename from sql/Updates/r1595_mangos.sql rename to sql/updates/r1595_mangos.sql diff --git a/sql/Updates/r1596_mangos.sql b/sql/updates/r1596_mangos.sql similarity index 100% rename from sql/Updates/r1596_mangos.sql rename to sql/updates/r1596_mangos.sql diff --git a/sql/Updates/r1599_mangos.sql b/sql/updates/r1599_mangos.sql similarity index 100% rename from sql/Updates/r1599_mangos.sql rename to sql/updates/r1599_mangos.sql diff --git a/sql/Updates/r1600_scriptdev2.sql b/sql/updates/r1600_scriptdev2.sql similarity index 100% rename from sql/Updates/r1600_scriptdev2.sql rename to sql/updates/r1600_scriptdev2.sql diff --git a/sql/Updates/r1602_mangos.sql b/sql/updates/r1602_mangos.sql similarity index 100% rename from sql/Updates/r1602_mangos.sql rename to sql/updates/r1602_mangos.sql diff --git a/sql/Updates/r1604_mangos.sql b/sql/updates/r1604_mangos.sql similarity index 100% rename from sql/Updates/r1604_mangos.sql rename to sql/updates/r1604_mangos.sql diff --git a/sql/Updates/r1605_mangos.sql b/sql/updates/r1605_mangos.sql similarity index 100% rename from sql/Updates/r1605_mangos.sql rename to sql/updates/r1605_mangos.sql diff --git a/sql/Updates/r1607_mangos.sql b/sql/updates/r1607_mangos.sql similarity index 100% rename from sql/Updates/r1607_mangos.sql rename to sql/updates/r1607_mangos.sql diff --git a/sql/Updates/r1608_mangos.sql b/sql/updates/r1608_mangos.sql similarity index 100% rename from sql/Updates/r1608_mangos.sql rename to sql/updates/r1608_mangos.sql diff --git a/sql/Updates/r1615_mangos.sql b/sql/updates/r1615_mangos.sql similarity index 100% rename from sql/Updates/r1615_mangos.sql rename to sql/updates/r1615_mangos.sql diff --git a/sql/Updates/r1615_scriptdev2.sql b/sql/updates/r1615_scriptdev2.sql similarity index 100% rename from sql/Updates/r1615_scriptdev2.sql rename to sql/updates/r1615_scriptdev2.sql diff --git a/sql/Updates/r1616_mangos.sql b/sql/updates/r1616_mangos.sql similarity index 100% rename from sql/Updates/r1616_mangos.sql rename to sql/updates/r1616_mangos.sql diff --git a/sql/Updates/r1617_mangos.sql b/sql/updates/r1617_mangos.sql similarity index 100% rename from sql/Updates/r1617_mangos.sql rename to sql/updates/r1617_mangos.sql diff --git a/sql/Updates/r1621_scriptdev2.sql b/sql/updates/r1621_scriptdev2.sql similarity index 100% rename from sql/Updates/r1621_scriptdev2.sql rename to sql/updates/r1621_scriptdev2.sql diff --git a/sql/Updates/r1622_mangos.sql b/sql/updates/r1622_mangos.sql similarity index 100% rename from sql/Updates/r1622_mangos.sql rename to sql/updates/r1622_mangos.sql diff --git a/sql/Updates/r1622_scriptdev2.sql b/sql/updates/r1622_scriptdev2.sql similarity index 100% rename from sql/Updates/r1622_scriptdev2.sql rename to sql/updates/r1622_scriptdev2.sql diff --git a/sql/Updates/r1624_mangos.sql b/sql/updates/r1624_mangos.sql similarity index 100% rename from sql/Updates/r1624_mangos.sql rename to sql/updates/r1624_mangos.sql diff --git a/sql/Updates/r1624_scriptdev2.sql b/sql/updates/r1624_scriptdev2.sql similarity index 100% rename from sql/Updates/r1624_scriptdev2.sql rename to sql/updates/r1624_scriptdev2.sql diff --git a/sql/Updates/r1627_mangos.sql b/sql/updates/r1627_mangos.sql similarity index 100% rename from sql/Updates/r1627_mangos.sql rename to sql/updates/r1627_mangos.sql diff --git a/sql/Updates/r1627_scriptdev2.sql b/sql/updates/r1627_scriptdev2.sql similarity index 100% rename from sql/Updates/r1627_scriptdev2.sql rename to sql/updates/r1627_scriptdev2.sql diff --git a/sql/Updates/r1629_mangos.sql b/sql/updates/r1629_mangos.sql similarity index 100% rename from sql/Updates/r1629_mangos.sql rename to sql/updates/r1629_mangos.sql diff --git a/sql/Updates/r1629_scriptdev2.sql b/sql/updates/r1629_scriptdev2.sql similarity index 100% rename from sql/Updates/r1629_scriptdev2.sql rename to sql/updates/r1629_scriptdev2.sql diff --git a/sql/Updates/r1632_mangos.sql b/sql/updates/r1632_mangos.sql similarity index 90% rename from sql/Updates/r1632_mangos.sql rename to sql/updates/r1632_mangos.sql index 3fe6ca965..4818b1a28 100644 --- a/sql/Updates/r1632_mangos.sql +++ b/sql/updates/r1632_mangos.sql @@ -3,7 +3,7 @@ UPDATE creature_template SET ScriptName='boss_gormok' WHERE entry=34796; UPDATE creature_template SET ScriptName='boss_acidmaw' WHERE entry=35144; UPDATE creature_template SET ScriptName='boss_dreadscale' WHERE entry=34799; UPDATE creature_template SET ScriptName='boss_icehowl' WHERE entry=34797; -UPDATE creature_template SET ScriptName='boss_jaraxxis' WHERE entry=34780; +UPDATE creature_template SET ScriptName='boss_jaraxxus' WHERE entry=34780; UPDATE creature_template SET ScriptName='boss_anubarak_trial' WHERE entry=34564; UPDATE creature_template SET ScriptName='boss_fjola' WHERE entry=34497; UPDATE creature_template SET ScriptName='boss_eydis' WHERE entry=34496; diff --git a/sql/Updates/r1636_mangos.sql b/sql/updates/r1636_mangos.sql similarity index 100% rename from sql/Updates/r1636_mangos.sql rename to sql/updates/r1636_mangos.sql diff --git a/sql/Updates/r1637_scriptdev2.sql b/sql/updates/r1637_scriptdev2.sql similarity index 100% rename from sql/Updates/r1637_scriptdev2.sql rename to sql/updates/r1637_scriptdev2.sql diff --git a/sql/Updates/r1642_scriptdev2.sql b/sql/updates/r1642_scriptdev2.sql similarity index 100% rename from sql/Updates/r1642_scriptdev2.sql rename to sql/updates/r1642_scriptdev2.sql diff --git a/sql/Updates/r1644_scriptdev2.sql b/sql/updates/r1644_scriptdev2.sql similarity index 100% rename from sql/Updates/r1644_scriptdev2.sql rename to sql/updates/r1644_scriptdev2.sql diff --git a/sql/Updates/r1647_mangos.sql b/sql/updates/r1647_mangos.sql similarity index 100% rename from sql/Updates/r1647_mangos.sql rename to sql/updates/r1647_mangos.sql diff --git a/sql/Updates/r1647_scriptdev2.sql b/sql/updates/r1647_scriptdev2.sql similarity index 97% rename from sql/Updates/r1647_scriptdev2.sql rename to sql/updates/r1647_scriptdev2.sql index de5dc6b96..32164dbe7 100644 --- a/sql/Updates/r1647_scriptdev2.sql +++ b/sql/updates/r1647_scriptdev2.sql @@ -7,7 +7,7 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1000565,'Brave adventurer, thank you for rescuing me! I am sure Marshal Marris will reward your kind deed.',0,0,0,0,'SAY_CORPORAL_KEESHAN_5'); DELETE FROM script_waypoint WHERE entry = 349; -INSERT INTO script_waypoint VALUES +INSERT INTO script_waypoint VALUES (349, 01, -8769.591797, -2185.733643, 141.974564, 0, ''), (349, 02, -8776.540039, -2193.782959, 140.960159, 0, ''), (349, 03, -8783.289063, -2194.818604, 140.461731, 0, ''), @@ -26,7 +26,7 @@ INSERT INTO script_waypoint VALUES (349, 16, -8741.869141, -2250.997070, 154.485718, 0, ''), (349, 17, -8733.218750, -2251.010742, 154.360031, 0, ''), (349, 18, -8717.474609, -2245.044678, 154.68614, 0, ''), -(349, 19, -8712.240234, -2246.826172, 154.709473, 0, ''), +(349, 19, -8712.240234, -2246.826172, 154.709473, 0, ''), (349, 20, -8693.840820, -2240.410889, 152.909714, 0, ''), (349, 21, -8681.818359, -2245.332764, 155.517838, 0, ''), (349, 22, -8669.86, -2252.77, 154.854, 0, ''), diff --git a/sql/Updates/r1650_mangos.sql b/sql/updates/r1650_mangos.sql similarity index 100% rename from sql/Updates/r1650_mangos.sql rename to sql/updates/r1650_mangos.sql diff --git a/sql/Updates/r1651_scriptdev2.sql b/sql/updates/r1651_scriptdev2.sql similarity index 98% rename from sql/Updates/r1651_scriptdev2.sql rename to sql/updates/r1651_scriptdev2.sql index dcd8eccd8..3efb21efc 100644 --- a/sql/Updates/r1651_scriptdev2.sql +++ b/sql/updates/r1651_scriptdev2.sql @@ -1,2 +1 @@ UPDATE script_texts SET content_default='Ah, fresh air, at last! I need a moment to rest.' WHERE entry=-1000562; - diff --git a/sql/Updates/r1652_scriptdev2.sql b/sql/updates/r1652_scriptdev2.sql similarity index 98% rename from sql/Updates/r1652_scriptdev2.sql rename to sql/updates/r1652_scriptdev2.sql index 658774eaf..2eb23cd2e 100644 --- a/sql/Updates/r1652_scriptdev2.sql +++ b/sql/updates/r1652_scriptdev2.sql @@ -1,3 +1,2 @@ UPDATE script_texts SET content_default='%s raises more skeletons!' WHERE entry=-1533131; UPDATE script_texts SET content_default='%s teleports to the balcony above!' WHERE entry=-1533132; - diff --git a/sql/Updates/r1653_mangos.sql b/sql/updates/r1653_mangos.sql similarity index 100% rename from sql/Updates/r1653_mangos.sql rename to sql/updates/r1653_mangos.sql diff --git a/sql/Updates/r1658_scriptdev2.sql b/sql/updates/r1658_scriptdev2.sql similarity index 100% rename from sql/Updates/r1658_scriptdev2.sql rename to sql/updates/r1658_scriptdev2.sql diff --git a/sql/Updates/r1660_scriptdev2.sql b/sql/updates/r1660_scriptdev2.sql similarity index 100% rename from sql/Updates/r1660_scriptdev2.sql rename to sql/updates/r1660_scriptdev2.sql diff --git a/sql/Updates/r1661_mangos.sql b/sql/updates/r1661_mangos.sql similarity index 100% rename from sql/Updates/r1661_mangos.sql rename to sql/updates/r1661_mangos.sql diff --git a/sql/Updates/r1662_scriptdev2.sql b/sql/updates/r1662_scriptdev2.sql similarity index 100% rename from sql/Updates/r1662_scriptdev2.sql rename to sql/updates/r1662_scriptdev2.sql diff --git a/sql/Updates/r1665_mangos.sql b/sql/updates/r1665_mangos.sql similarity index 100% rename from sql/Updates/r1665_mangos.sql rename to sql/updates/r1665_mangos.sql diff --git a/sql/Updates/r1667_mangos.sql b/sql/updates/r1667_mangos.sql similarity index 100% rename from sql/Updates/r1667_mangos.sql rename to sql/updates/r1667_mangos.sql diff --git a/sql/Updates/r1667_scriptdev2.sql b/sql/updates/r1667_scriptdev2.sql similarity index 100% rename from sql/Updates/r1667_scriptdev2.sql rename to sql/updates/r1667_scriptdev2.sql diff --git a/sql/Updates/r1668_mangos.sql b/sql/updates/r1668_mangos.sql similarity index 100% rename from sql/Updates/r1668_mangos.sql rename to sql/updates/r1668_mangos.sql diff --git a/sql/Updates/r1671_mangos.sql b/sql/updates/r1671_mangos.sql similarity index 100% rename from sql/Updates/r1671_mangos.sql rename to sql/updates/r1671_mangos.sql diff --git a/sql/Updates/r1671_scriptdev2.sql b/sql/updates/r1671_scriptdev2.sql similarity index 100% rename from sql/Updates/r1671_scriptdev2.sql rename to sql/updates/r1671_scriptdev2.sql diff --git a/sql/Updates/r1679_mangos.sql b/sql/updates/r1679_mangos.sql similarity index 100% rename from sql/Updates/r1679_mangos.sql rename to sql/updates/r1679_mangos.sql diff --git a/sql/Updates/r1680_mangos.sql b/sql/updates/r1680_mangos.sql similarity index 100% rename from sql/Updates/r1680_mangos.sql rename to sql/updates/r1680_mangos.sql diff --git a/sql/Updates/r1681_mangos.sql b/sql/updates/r1681_mangos.sql similarity index 100% rename from sql/Updates/r1681_mangos.sql rename to sql/updates/r1681_mangos.sql diff --git a/sql/Updates/r1683_scriptdev2.sql b/sql/updates/r1683_scriptdev2.sql similarity index 100% rename from sql/Updates/r1683_scriptdev2.sql rename to sql/updates/r1683_scriptdev2.sql diff --git a/sql/Updates/r1685_mangos.sql b/sql/updates/r1685_mangos.sql similarity index 100% rename from sql/Updates/r1685_mangos.sql rename to sql/updates/r1685_mangos.sql diff --git a/sql/Updates/r1685_scriptdev2.sql b/sql/updates/r1685_scriptdev2.sql similarity index 100% rename from sql/Updates/r1685_scriptdev2.sql rename to sql/updates/r1685_scriptdev2.sql diff --git a/sql/Updates/r1687_mangos.sql b/sql/updates/r1687_mangos.sql similarity index 100% rename from sql/Updates/r1687_mangos.sql rename to sql/updates/r1687_mangos.sql diff --git a/sql/Updates/r1691_mangos.sql b/sql/updates/r1691_mangos.sql similarity index 100% rename from sql/Updates/r1691_mangos.sql rename to sql/updates/r1691_mangos.sql diff --git a/sql/Updates/r1694_mangos.sql b/sql/updates/r1694_mangos.sql similarity index 100% rename from sql/Updates/r1694_mangos.sql rename to sql/updates/r1694_mangos.sql diff --git a/sql/Updates/r1698_mangos.sql b/sql/updates/r1698_mangos.sql similarity index 100% rename from sql/Updates/r1698_mangos.sql rename to sql/updates/r1698_mangos.sql diff --git a/sql/Updates/r1704_mangos.sql b/sql/updates/r1704_mangos.sql similarity index 100% rename from sql/Updates/r1704_mangos.sql rename to sql/updates/r1704_mangos.sql diff --git a/sql/Updates/r1705_mangos.sql b/sql/updates/r1705_mangos.sql similarity index 100% rename from sql/Updates/r1705_mangos.sql rename to sql/updates/r1705_mangos.sql diff --git a/sql/Updates/r1705_scriptdev2.sql b/sql/updates/r1705_scriptdev2.sql similarity index 100% rename from sql/Updates/r1705_scriptdev2.sql rename to sql/updates/r1705_scriptdev2.sql diff --git a/sql/Updates/r1706_scriptdev2.sql b/sql/updates/r1706_scriptdev2.sql similarity index 100% rename from sql/Updates/r1706_scriptdev2.sql rename to sql/updates/r1706_scriptdev2.sql diff --git a/sql/Updates/r1711_scriptdev2.sql b/sql/updates/r1711_scriptdev2.sql similarity index 100% rename from sql/Updates/r1711_scriptdev2.sql rename to sql/updates/r1711_scriptdev2.sql diff --git a/sql/Updates/r1715_mangos.sql b/sql/updates/r1715_mangos.sql similarity index 100% rename from sql/Updates/r1715_mangos.sql rename to sql/updates/r1715_mangos.sql diff --git a/sql/Updates/r1715_scriptdev2.sql b/sql/updates/r1715_scriptdev2.sql similarity index 100% rename from sql/Updates/r1715_scriptdev2.sql rename to sql/updates/r1715_scriptdev2.sql diff --git a/sql/Updates/r1720_mangos.sql b/sql/updates/r1720_mangos.sql similarity index 100% rename from sql/Updates/r1720_mangos.sql rename to sql/updates/r1720_mangos.sql diff --git a/sql/Updates/r1720_scriptdev2.sql b/sql/updates/r1720_scriptdev2.sql similarity index 94% rename from sql/Updates/r1720_scriptdev2.sql rename to sql/updates/r1720_scriptdev2.sql index 77acd0c52..92dd0fe74 100644 --- a/sql/Updates/r1720_scriptdev2.sql +++ b/sql/updates/r1720_scriptdev2.sql @@ -1,5 +1,5 @@ DELETE FROM script_waypoint WHERE entry=20415; -INSERT INTO script_waypoint VALUES +INSERT INTO script_waypoint VALUES (20415, 0, 2488.77, 2184.89, 104.64, 0, ""), (20415, 1, 2478.72, 2184.77, 98.58, 0, ""), (20415, 2, 2473.52, 2184.71, 99.00, 0, ""), diff --git a/sql/Updates/r1726_mangos.sql b/sql/updates/r1726_mangos.sql similarity index 100% rename from sql/Updates/r1726_mangos.sql rename to sql/updates/r1726_mangos.sql diff --git a/sql/Updates/r1727_scriptdev2.sql b/sql/updates/r1727_scriptdev2.sql similarity index 100% rename from sql/Updates/r1727_scriptdev2.sql rename to sql/updates/r1727_scriptdev2.sql diff --git a/sql/Updates/r1728_mangos.sql b/sql/updates/r1728_mangos.sql similarity index 100% rename from sql/Updates/r1728_mangos.sql rename to sql/updates/r1728_mangos.sql diff --git a/sql/Updates/r1729_scriptdev2.sql b/sql/updates/r1729_scriptdev2.sql similarity index 100% rename from sql/Updates/r1729_scriptdev2.sql rename to sql/updates/r1729_scriptdev2.sql diff --git a/sql/Updates/r1734_scriptdev2.sql b/sql/updates/r1734_scriptdev2.sql similarity index 100% rename from sql/Updates/r1734_scriptdev2.sql rename to sql/updates/r1734_scriptdev2.sql diff --git a/sql/Updates/r1736_scriptdev2.sql b/sql/updates/r1736_scriptdev2.sql similarity index 100% rename from sql/Updates/r1736_scriptdev2.sql rename to sql/updates/r1736_scriptdev2.sql diff --git a/sql/Updates/r1737_scriptdev2.sql b/sql/updates/r1737_scriptdev2.sql similarity index 100% rename from sql/Updates/r1737_scriptdev2.sql rename to sql/updates/r1737_scriptdev2.sql diff --git a/sql/Updates/r1741_mangos.sql b/sql/updates/r1741_mangos.sql similarity index 100% rename from sql/Updates/r1741_mangos.sql rename to sql/updates/r1741_mangos.sql diff --git a/sql/Updates/r1750_scriptdev2.sql b/sql/updates/r1750_scriptdev2.sql similarity index 100% rename from sql/Updates/r1750_scriptdev2.sql rename to sql/updates/r1750_scriptdev2.sql diff --git a/sql/Updates/r1751_scriptdev2.sql b/sql/updates/r1751_scriptdev2.sql similarity index 100% rename from sql/Updates/r1751_scriptdev2.sql rename to sql/updates/r1751_scriptdev2.sql diff --git a/sql/Updates/r1752_mangos.sql b/sql/updates/r1752_mangos.sql similarity index 100% rename from sql/Updates/r1752_mangos.sql rename to sql/updates/r1752_mangos.sql diff --git a/sql/Updates/r1753_scriptdev2.sql b/sql/updates/r1753_scriptdev2.sql similarity index 100% rename from sql/Updates/r1753_scriptdev2.sql rename to sql/updates/r1753_scriptdev2.sql diff --git a/sql/Updates/r1754_scriptdev2.sql b/sql/updates/r1754_scriptdev2.sql similarity index 100% rename from sql/Updates/r1754_scriptdev2.sql rename to sql/updates/r1754_scriptdev2.sql diff --git a/sql/Updates/r1759_mangos.sql b/sql/updates/r1759_mangos.sql similarity index 100% rename from sql/Updates/r1759_mangos.sql rename to sql/updates/r1759_mangos.sql diff --git a/sql/Updates/r1763_mangos.sql b/sql/updates/r1763_mangos.sql similarity index 100% rename from sql/Updates/r1763_mangos.sql rename to sql/updates/r1763_mangos.sql diff --git a/sql/Updates/r1767_mangos.sql b/sql/updates/r1767_mangos.sql similarity index 100% rename from sql/Updates/r1767_mangos.sql rename to sql/updates/r1767_mangos.sql diff --git a/sql/Updates/r1771_scriptdev2.sql b/sql/updates/r1771_scriptdev2.sql similarity index 100% rename from sql/Updates/r1771_scriptdev2.sql rename to sql/updates/r1771_scriptdev2.sql diff --git a/sql/Updates/r1777_scriptdev2.sql b/sql/updates/r1777_scriptdev2.sql similarity index 100% rename from sql/Updates/r1777_scriptdev2.sql rename to sql/updates/r1777_scriptdev2.sql diff --git a/sql/Updates/r1780_scriptdev2.sql b/sql/updates/r1780_scriptdev2.sql similarity index 100% rename from sql/Updates/r1780_scriptdev2.sql rename to sql/updates/r1780_scriptdev2.sql diff --git a/sql/Updates/r1782_scriptdev2.sql b/sql/updates/r1782_scriptdev2.sql similarity index 100% rename from sql/Updates/r1782_scriptdev2.sql rename to sql/updates/r1782_scriptdev2.sql diff --git a/sql/Updates/r1783_scriptdev2.sql b/sql/updates/r1783_scriptdev2.sql similarity index 100% rename from sql/Updates/r1783_scriptdev2.sql rename to sql/updates/r1783_scriptdev2.sql diff --git a/sql/Updates/r1784_scriptdev2.sql b/sql/updates/r1784_scriptdev2.sql similarity index 100% rename from sql/Updates/r1784_scriptdev2.sql rename to sql/updates/r1784_scriptdev2.sql diff --git a/sql/Updates/r1785_scriptdev2.sql b/sql/updates/r1785_scriptdev2.sql similarity index 100% rename from sql/Updates/r1785_scriptdev2.sql rename to sql/updates/r1785_scriptdev2.sql diff --git a/sql/Updates/r1786_scriptdev2.sql b/sql/updates/r1786_scriptdev2.sql similarity index 100% rename from sql/Updates/r1786_scriptdev2.sql rename to sql/updates/r1786_scriptdev2.sql diff --git a/sql/Updates/r1789_scriptdev2.sql b/sql/updates/r1789_scriptdev2.sql similarity index 100% rename from sql/Updates/r1789_scriptdev2.sql rename to sql/updates/r1789_scriptdev2.sql diff --git a/sql/Updates/r1791_scriptdev2.sql b/sql/updates/r1791_scriptdev2.sql similarity index 100% rename from sql/Updates/r1791_scriptdev2.sql rename to sql/updates/r1791_scriptdev2.sql diff --git a/sql/Updates/r1797_mangos.sql b/sql/updates/r1797_mangos.sql similarity index 100% rename from sql/Updates/r1797_mangos.sql rename to sql/updates/r1797_mangos.sql diff --git a/sql/Updates/r1798_mangos.sql b/sql/updates/r1798_mangos.sql similarity index 100% rename from sql/Updates/r1798_mangos.sql rename to sql/updates/r1798_mangos.sql diff --git a/sql/Updates/r1800_mangos.sql b/sql/updates/r1800_mangos.sql similarity index 100% rename from sql/Updates/r1800_mangos.sql rename to sql/updates/r1800_mangos.sql diff --git a/sql/Updates/r1800_scriptdev2.sql b/sql/updates/r1800_scriptdev2.sql similarity index 100% rename from sql/Updates/r1800_scriptdev2.sql rename to sql/updates/r1800_scriptdev2.sql diff --git a/sql/Updates/r1807_scriptdev2.sql b/sql/updates/r1807_scriptdev2.sql similarity index 100% rename from sql/Updates/r1807_scriptdev2.sql rename to sql/updates/r1807_scriptdev2.sql diff --git a/sql/Updates/r1810_scriptdev2.sql b/sql/updates/r1810_scriptdev2.sql similarity index 100% rename from sql/Updates/r1810_scriptdev2.sql rename to sql/updates/r1810_scriptdev2.sql diff --git a/sql/Updates/r1813_mangos.sql b/sql/updates/r1813_mangos.sql similarity index 100% rename from sql/Updates/r1813_mangos.sql rename to sql/updates/r1813_mangos.sql diff --git a/sql/Updates/r1816_scriptdev2.sql b/sql/updates/r1816_scriptdev2.sql similarity index 100% rename from sql/Updates/r1816_scriptdev2.sql rename to sql/updates/r1816_scriptdev2.sql diff --git a/sql/Updates/r1818_mangos.sql b/sql/updates/r1818_mangos.sql similarity index 100% rename from sql/Updates/r1818_mangos.sql rename to sql/updates/r1818_mangos.sql diff --git a/sql/Updates/r1818_scriptdev2.sql b/sql/updates/r1818_scriptdev2.sql similarity index 100% rename from sql/Updates/r1818_scriptdev2.sql rename to sql/updates/r1818_scriptdev2.sql diff --git a/sql/Updates/r1819_mangos.sql b/sql/updates/r1819_mangos.sql similarity index 100% rename from sql/Updates/r1819_mangos.sql rename to sql/updates/r1819_mangos.sql diff --git a/sql/Updates/r1822_scriptdev2.sql b/sql/updates/r1822_scriptdev2.sql similarity index 100% rename from sql/Updates/r1822_scriptdev2.sql rename to sql/updates/r1822_scriptdev2.sql diff --git a/sql/Updates/r1824_mangos.sql b/sql/updates/r1824_mangos.sql similarity index 100% rename from sql/Updates/r1824_mangos.sql rename to sql/updates/r1824_mangos.sql diff --git a/sql/Updates/r1825_mangos.sql b/sql/updates/r1825_mangos.sql similarity index 100% rename from sql/Updates/r1825_mangos.sql rename to sql/updates/r1825_mangos.sql diff --git a/sql/Updates/r1825_scriptdev2.sql b/sql/updates/r1825_scriptdev2.sql similarity index 100% rename from sql/Updates/r1825_scriptdev2.sql rename to sql/updates/r1825_scriptdev2.sql diff --git a/sql/Updates/r1826_mangos.sql b/sql/updates/r1826_mangos.sql similarity index 100% rename from sql/Updates/r1826_mangos.sql rename to sql/updates/r1826_mangos.sql diff --git a/sql/Updates/r1826_scriptdev2.sql b/sql/updates/r1826_scriptdev2.sql similarity index 100% rename from sql/Updates/r1826_scriptdev2.sql rename to sql/updates/r1826_scriptdev2.sql diff --git a/sql/Updates/r1827_scriptdev2.sql b/sql/updates/r1827_scriptdev2.sql similarity index 100% rename from sql/Updates/r1827_scriptdev2.sql rename to sql/updates/r1827_scriptdev2.sql diff --git a/sql/Updates/r1828_scriptdev2.sql b/sql/updates/r1828_scriptdev2.sql similarity index 100% rename from sql/Updates/r1828_scriptdev2.sql rename to sql/updates/r1828_scriptdev2.sql diff --git a/sql/Updates/r1829_mangos.sql b/sql/updates/r1829_mangos.sql similarity index 100% rename from sql/Updates/r1829_mangos.sql rename to sql/updates/r1829_mangos.sql diff --git a/sql/Updates/r1830_scriptdev2.sql b/sql/updates/r1830_scriptdev2.sql similarity index 100% rename from sql/Updates/r1830_scriptdev2.sql rename to sql/updates/r1830_scriptdev2.sql diff --git a/sql/Updates/r1831_scriptdev2.sql b/sql/updates/r1831_scriptdev2.sql similarity index 100% rename from sql/Updates/r1831_scriptdev2.sql rename to sql/updates/r1831_scriptdev2.sql diff --git a/sql/Updates/r1836_mangos.sql b/sql/updates/r1836_mangos.sql similarity index 100% rename from sql/Updates/r1836_mangos.sql rename to sql/updates/r1836_mangos.sql diff --git a/sql/Updates/r1842_scriptdev2.sql b/sql/updates/r1842_scriptdev2.sql similarity index 100% rename from sql/Updates/r1842_scriptdev2.sql rename to sql/updates/r1842_scriptdev2.sql diff --git a/sql/Updates/r1843_mangos.sql b/sql/updates/r1843_mangos.sql similarity index 100% rename from sql/Updates/r1843_mangos.sql rename to sql/updates/r1843_mangos.sql diff --git a/sql/Updates/r1843_scriptdev2.sql b/sql/updates/r1843_scriptdev2.sql similarity index 100% rename from sql/Updates/r1843_scriptdev2.sql rename to sql/updates/r1843_scriptdev2.sql diff --git a/sql/Updates/r1844_mangos.sql b/sql/updates/r1844_mangos.sql similarity index 100% rename from sql/Updates/r1844_mangos.sql rename to sql/updates/r1844_mangos.sql diff --git a/sql/Updates/r1845_mangos.sql b/sql/updates/r1845_mangos.sql similarity index 100% rename from sql/Updates/r1845_mangos.sql rename to sql/updates/r1845_mangos.sql diff --git a/sql/Updates/r1845_scriptdev2.sql b/sql/updates/r1845_scriptdev2.sql similarity index 100% rename from sql/Updates/r1845_scriptdev2.sql rename to sql/updates/r1845_scriptdev2.sql diff --git a/sql/Updates/r1850_mangos.sql b/sql/updates/r1850_mangos.sql similarity index 100% rename from sql/Updates/r1850_mangos.sql rename to sql/updates/r1850_mangos.sql diff --git a/sql/Updates/r1850_scriptdev2.sql b/sql/updates/r1850_scriptdev2.sql similarity index 100% rename from sql/Updates/r1850_scriptdev2.sql rename to sql/updates/r1850_scriptdev2.sql diff --git a/sql/Updates/r1851_mangos.sql b/sql/updates/r1851_mangos.sql similarity index 100% rename from sql/Updates/r1851_mangos.sql rename to sql/updates/r1851_mangos.sql diff --git a/sql/Updates/r1852_scriptdev2.sql b/sql/updates/r1852_scriptdev2.sql similarity index 100% rename from sql/Updates/r1852_scriptdev2.sql rename to sql/updates/r1852_scriptdev2.sql diff --git a/sql/Updates/r1853_mangos.sql b/sql/updates/r1853_mangos.sql similarity index 100% rename from sql/Updates/r1853_mangos.sql rename to sql/updates/r1853_mangos.sql diff --git a/sql/Updates/r1855_scriptdev2.sql b/sql/updates/r1855_scriptdev2.sql similarity index 100% rename from sql/Updates/r1855_scriptdev2.sql rename to sql/updates/r1855_scriptdev2.sql diff --git a/sql/Updates/r1858_scriptdev2.sql b/sql/updates/r1858_scriptdev2.sql similarity index 100% rename from sql/Updates/r1858_scriptdev2.sql rename to sql/updates/r1858_scriptdev2.sql diff --git a/sql/Updates/r1859_mangos.sql b/sql/updates/r1859_mangos.sql similarity index 100% rename from sql/Updates/r1859_mangos.sql rename to sql/updates/r1859_mangos.sql diff --git a/sql/Updates/r1860_scriptdev2.sql b/sql/updates/r1860_scriptdev2.sql similarity index 100% rename from sql/Updates/r1860_scriptdev2.sql rename to sql/updates/r1860_scriptdev2.sql diff --git a/sql/Updates/r1862_mangos.sql b/sql/updates/r1862_mangos.sql similarity index 100% rename from sql/Updates/r1862_mangos.sql rename to sql/updates/r1862_mangos.sql diff --git a/sql/Updates/r1863_mangos.sql b/sql/updates/r1863_mangos.sql similarity index 100% rename from sql/Updates/r1863_mangos.sql rename to sql/updates/r1863_mangos.sql diff --git a/sql/Updates/r1864_mangos.sql b/sql/updates/r1864_mangos.sql similarity index 100% rename from sql/Updates/r1864_mangos.sql rename to sql/updates/r1864_mangos.sql diff --git a/sql/Updates/r1864_scriptdev2.sql b/sql/updates/r1864_scriptdev2.sql similarity index 100% rename from sql/Updates/r1864_scriptdev2.sql rename to sql/updates/r1864_scriptdev2.sql diff --git a/sql/Updates/r1865_mangos.sql b/sql/updates/r1865_mangos.sql similarity index 100% rename from sql/Updates/r1865_mangos.sql rename to sql/updates/r1865_mangos.sql diff --git a/sql/Updates/r1865_scriptdev2.sql b/sql/updates/r1865_scriptdev2.sql similarity index 100% rename from sql/Updates/r1865_scriptdev2.sql rename to sql/updates/r1865_scriptdev2.sql diff --git a/sql/Updates/r1866_scriptdev2.sql b/sql/updates/r1866_scriptdev2.sql similarity index 100% rename from sql/Updates/r1866_scriptdev2.sql rename to sql/updates/r1866_scriptdev2.sql diff --git a/sql/Updates/r1868_scriptdev2.sql b/sql/updates/r1868_scriptdev2.sql similarity index 100% rename from sql/Updates/r1868_scriptdev2.sql rename to sql/updates/r1868_scriptdev2.sql diff --git a/sql/Updates/r1869_mangos.sql b/sql/updates/r1869_mangos.sql similarity index 100% rename from sql/Updates/r1869_mangos.sql rename to sql/updates/r1869_mangos.sql diff --git a/sql/Updates/r1871_mangos.sql b/sql/updates/r1871_mangos.sql similarity index 100% rename from sql/Updates/r1871_mangos.sql rename to sql/updates/r1871_mangos.sql diff --git a/sql/Updates/r1875_mangos.sql b/sql/updates/r1875_mangos.sql similarity index 100% rename from sql/Updates/r1875_mangos.sql rename to sql/updates/r1875_mangos.sql diff --git a/sql/Updates/r1875_scriptdev2.sql b/sql/updates/r1875_scriptdev2.sql similarity index 100% rename from sql/Updates/r1875_scriptdev2.sql rename to sql/updates/r1875_scriptdev2.sql diff --git a/sql/Updates/r1876_mangos.sql b/sql/updates/r1876_mangos.sql similarity index 100% rename from sql/Updates/r1876_mangos.sql rename to sql/updates/r1876_mangos.sql diff --git a/sql/Updates/r1876_scriptdev2.sql b/sql/updates/r1876_scriptdev2.sql similarity index 100% rename from sql/Updates/r1876_scriptdev2.sql rename to sql/updates/r1876_scriptdev2.sql diff --git a/sql/Updates/r1878_mangos.sql b/sql/updates/r1878_mangos.sql similarity index 100% rename from sql/Updates/r1878_mangos.sql rename to sql/updates/r1878_mangos.sql diff --git a/sql/Updates/r1881_mangos.sql b/sql/updates/r1881_mangos.sql similarity index 100% rename from sql/Updates/r1881_mangos.sql rename to sql/updates/r1881_mangos.sql diff --git a/sql/Updates/r1882_scriptdev2.sql b/sql/updates/r1882_scriptdev2.sql similarity index 100% rename from sql/Updates/r1882_scriptdev2.sql rename to sql/updates/r1882_scriptdev2.sql diff --git a/sql/updates/r1886_scriptdev2.sql b/sql/updates/r1886_scriptdev2.sql new file mode 100644 index 000000000..20a4bba17 --- /dev/null +++ b/sql/updates/r1886_scriptdev2.sql @@ -0,0 +1,2 @@ +DELETE FROM sd2_db_version; +INSERT INTO sd2_db_version (version) VALUES ('ScriptDev2 (for MaNGOS 10761+) '); diff --git a/sql/updates/r1888_mangos.sql b/sql/updates/r1888_mangos.sql new file mode 100644 index 000000000..ec9325985 --- /dev/null +++ b/sql/updates/r1888_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_zeppit' WHERE entry=22484; diff --git a/sql/updates/r1888_scriptdev2.sql b/sql/updates/r1888_scriptdev2.sql new file mode 100644 index 000000000..e51dc0940 --- /dev/null +++ b/sql/updates/r1888_scriptdev2.sql @@ -0,0 +1,3 @@ +DELETE FROM script_texts WHERE entry=-1000625; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000625,'%s gathers the warp chaser\'s blood.',0,2,0,0,'zeppit EMOTE_GATHER_BLOOD'); diff --git a/sql/updates/r1889_mangos.sql b/sql/updates/r1889_mangos.sql new file mode 100644 index 000000000..ec06a37b0 --- /dev/null +++ b/sql/updates/r1889_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_depleted_war_golem' WHERE entry=27017; diff --git a/sql/updates/r1889_scriptdev2.sql b/sql/updates/r1889_scriptdev2.sql new file mode 100644 index 000000000..4bbccf052 --- /dev/null +++ b/sql/updates/r1889_scriptdev2.sql @@ -0,0 +1,4 @@ +DELETE FROM script_texts WHERE entry IN (-1000626,-1000627); +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000626,'Intiating energy collection.',0,0,0,0,'depleted golem SAY_GOLEM_CHARGE'), +(-1000627,'Energy collection complete.',0,0,0,0,'depleted golem SAY_GOLEM_COMPLETE'); diff --git a/sql/updates/r1890_mangos.sql b/sql/updates/r1890_mangos.sql new file mode 100644 index 000000000..234e7c45a --- /dev/null +++ b/sql/updates/r1890_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_hungry_nether_ray' WHERE entry=23439; diff --git a/sql/updates/r1890_scriptdev2.sql b/sql/updates/r1890_scriptdev2.sql new file mode 100644 index 000000000..beaab0918 --- /dev/null +++ b/sql/updates/r1890_scriptdev2.sql @@ -0,0 +1,3 @@ +DELETE FROM script_texts WHERE entry=-1000628; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000628,'%s feeds on the freshly-killed warp chaser.',0,2,0,0,'hungry ray EMOTE_FEED'); diff --git a/sql/updates/r1891_mangos.sql b/sql/updates/r1891_mangos.sql new file mode 100644 index 000000000..64d9d0825 --- /dev/null +++ b/sql/updates/r1891_mangos.sql @@ -0,0 +1,8 @@ +UPDATE creature_template SET ScriptName='npc_totem_of_spirits' WHERE entry=21071; + +DELETE FROM scripted_event_id WHERE id IN (13513,13514,13515,13516); +INSERT INTO scripted_event_id VALUES +(13513,'event_spell_soul_captured_credit'), +(13514,'event_spell_soul_captured_credit'), +(13515,'event_spell_soul_captured_credit'), +(13516,'event_spell_soul_captured_credit'); diff --git a/sql/updates/r1899_mangos.sql b/sql/updates/r1899_mangos.sql new file mode 100644 index 000000000..ac86c61ee --- /dev/null +++ b/sql/updates/r1899_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_greer_orehammer' WHERE entry=23859; diff --git a/sql/updates/r1899_scriptdev2.sql b/sql/updates/r1899_scriptdev2.sql new file mode 100644 index 000000000..01f1e22f8 --- /dev/null +++ b/sql/updates/r1899_scriptdev2.sql @@ -0,0 +1,5 @@ +DELETE FROM gossip_texts WHERE entry BETWEEN -3000108 AND -3000106; +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3000106,'Show me where I can fly.','greer orehammer GOSSIP_ITEM_TAXI'), +(-3000107,'[PH] Get Presicion Bombs','greer orehammer GOSSIP_ITEM_GET_BOMBS'), +(-3000108,'[PH] Start bombing mission','greer orehammer GOSSIP_ITEM_FLIGHT'); diff --git a/sql/updates/r1908_scriptdev2.sql b/sql/updates/r1908_scriptdev2.sql new file mode 100644 index 000000000..513dcf3f9 --- /dev/null +++ b/sql/updates/r1908_scriptdev2.sql @@ -0,0 +1,12 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1554005 AND -1554000; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1554000,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554001,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554002,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554003,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554004,'REUSE_ME',0,0,0,0,'REUSE_ME'), +(-1554005,'REUSE_ME',0,0,0,0,'REUSE_ME'); + +DELETE FROM gossip_texts WHERE entry=-3000102; +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3000102,'Pay up, Harry!','silvermoon harry GOSSIP_ITEM_PAYING'); diff --git a/sql/updates/r1913_mangos.sql b/sql/updates/r1913_mangos.sql new file mode 100644 index 000000000..2224fb8ed --- /dev/null +++ b/sql/updates/r1913_mangos.sql @@ -0,0 +1 @@ +UPDATE gameobject_template SET ScriptName='go_lab_work_reagents' WHERE entry IN (190462, 190473, 190478, 190459); diff --git a/sql/updates/r1914_scriptdev2.sql b/sql/updates/r1914_scriptdev2.sql new file mode 100644 index 000000000..93ec87b2a --- /dev/null +++ b/sql/updates/r1914_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 10928+) '; diff --git a/sql/updates/r1918_scriptdev2.sql b/sql/updates/r1918_scriptdev2.sql new file mode 100644 index 000000000..e91c9f248 --- /dev/null +++ b/sql/updates/r1918_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 10938+) '; diff --git a/sql/updates/r1921_scriptdev2.sql b/sql/updates/r1921_scriptdev2.sql new file mode 100644 index 000000000..385d49649 --- /dev/null +++ b/sql/updates/r1921_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 10950+) '; diff --git a/sql/updates/r1924_mangos.sql b/sql/updates/r1924_mangos.sql new file mode 100644 index 000000000..a2d143f36 --- /dev/null +++ b/sql/updates/r1924_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='boss_grobbulus' WHERE entry=15931; diff --git a/sql/updates/r1924_scriptdev2.sql b/sql/updates/r1924_scriptdev2.sql new file mode 100644 index 000000000..36d342010 --- /dev/null +++ b/sql/updates/r1924_scriptdev2.sql @@ -0,0 +1,3 @@ +DELETE FROM script_texts WHERE entry=-1533158; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1533158,'%s injects you with a mutagen!',0,5,0,0,'grobbulus EMOTE_INJECTION'); diff --git a/sql/updates/r1936_mangos.sql b/sql/updates/r1936_mangos.sql new file mode 100644 index 000000000..c336c9b5a --- /dev/null +++ b/sql/updates/r1936_mangos.sql @@ -0,0 +1 @@ +UPDATE instance_template SET ScriptName='instance_blackwing_lair' WHERE map=469; diff --git a/sql/updates/r1940_mangos.sql b/sql/updates/r1940_mangos.sql new file mode 100644 index 000000000..e3966d433 --- /dev/null +++ b/sql/updates/r1940_mangos.sql @@ -0,0 +1,3 @@ +UPDATE creature_template SET ScriptName='npc_janalai_firebomb' WHERE entry=23920; +UPDATE creature_template SET ScriptName='npc_amanishi_hatcher' WHERE entry IN (23818,24504); +UPDATE creature_template SET ScriptName='npc_hatchling' WHERE entry=23598; diff --git a/sql/updates/r1946_scriptdev2.sql b/sql/updates/r1946_scriptdev2.sql new file mode 100644 index 000000000..e7537c5f5 --- /dev/null +++ b/sql/updates/r1946_scriptdev2.sql @@ -0,0 +1,9 @@ +UPDATE script_texts SET type=6 WHERE entry=-1409004; + +DELETE FROM script_texts WHERE entry IN (-1409007, -1409019, -1409020, -1409021, -1409022); +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1409007,'Impossible! Stay your attack mortals! I submitt! I submitt!',8038,1,0,0,'majordomo SAY_DEFEAT_1'), +(-1409019,'You think you\'ve won already? Perhaps you\'ll need another lesson in pain!',0,1,0,0,'majordomo SAY_LAST_ADD'), +(-1409020,'Brashly you have come to rest the secrets of the living flame. You will soon regret the recklessness of your quest.',0,1,0,0,'majordomo SAY_DEFEAT_2'), +(-1409021,'I go now to summon the lord whos house this is. Should you seek an audiance with him your paltry lives will surly be forfit. Nevertheless seek out his lair if you dare!',0,1,0,0,'majordomo SAY_DEFEAT_3'), +(-1409022,'My flame! Please don\'t take away my flame... ',8042,1,0,0,'ragnaros SAY_ARRIVAL4_MAJ'); diff --git a/sql/updates/r1949_scriptdev2.sql b/sql/updates/r1949_scriptdev2.sql new file mode 100644 index 000000000..b6db02804 --- /dev/null +++ b/sql/updates/r1949_scriptdev2.sql @@ -0,0 +1,26 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1043019 AND -1043000; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1043000,'At last! Naralex can be awakened! Come aid me, brave adventurers!',0,6,0,0,'Disciple of Naralex - SAY_INTRO'), +(-1043001,'I must make the nescessary preparations before the awakening ritual can begin. You must protect me!',0,0,0,0,'SAY_PREPARE'), +(-1043002,'These caverns were once a temple of promise for regrowth in the Barrens. Now, they are the halls of nightmares.',0,0,0,0,'Disciple of Naralex - SAY_FIRST_CORNER'), +(-1043003,'Come. We must continue. There is much to be done before we can pull Naralex from his nightmare.',0,0,0,0,'Disciple of Naralex - SAY_CONTINUE'), +(-1043004,'Within this circle of fire I must cast the spell to banish the spirits of the slain Fanglords.',0,0,0,0,'Disciple of Naralex - SAY_CIRCLE_BANISH'), +(-1043005,'The caverns have been purified. To Naralex''s chamber we go!',0,0,0,0,'Disciple of Naralex - SAY_PURIFIED'), +(-1043006,'Beyond this corridor, Naralex lies in fitful sleep. Let us go awaken him before it is too late.',0,0,0,0,'Disciple of Naralex - SAY_NARALEX_CHAMBER'), +(-1043007,'Protect me brave souls as I delve into the Emerald Dream to rescue Naralex and put an end to this corruption!',0,1,0,0,'Disciple of Naralex - SAY_BEGIN_RITUAL'), +(-1043008,'%s begins to perform the awakening ritual on Naralex.',0,2,0,0,'Disciple of Naralex - EMOTE_RITUAL_BEGIN'), +(-1043009,'%s tosses fitfully in troubled sleep.',0,2,0,0,'Naralex - EMOTE_NARALEX_AWAKE'), +(-1043010,'%s writhes in agony. The Disciple seems to be breaking through.',0,2,0,0,'Naralex - EMOTE_BREAK_THROUGH'), +(-1043011,'%s dreams up a horrendous vision. Something stirs beneath the murky waters.',0,2,0,0,'Naralex - EMOTE_VISION'), +(-1043012,'This $N is a minin from Naralex\'s nightmare no doubt!.',0,0,0,0,'Disciple of Naralex - SAY_MUTANUS'), +(-1043013,'I AM AWAKE, AT LAST!',5789,1,0,0,'Naralex - SAY_NARALEX_AWAKE'), +(-1043014,'At last! Naralex awakes from the nightmare.',0,0,0,0,'Disciple of Naralex - SAY_AWAKE'), +(-1043015,'Ah, to be pulled from the dreaded nightmare! I thank you, my loyal Disciple, along with your brave companions.',0,0,0,0,'Naralex - SAY_NARALEX_THANKYOU'), +(-1043016,'We must go and gather with the other Disciplies. There is much work to be done before I can make another attempt to restore the Barrens. Farewell, brave souls!',0,0,0,0,'Naralex - SAY_FAREWELL'), +(-1043017,'Attacked! Help get this $N off of me!',0,0,0,0,'Disciple of Naralex - SAY_AGGRO_1'), +(-1043018,'Help!',0,0,0,0,'Disciple of Naralex - SAY_AGGRO_2'), +(-1043019,'Deal with this $N! I need to prepare to awake Naralex!',0,0,0,0,'Disciple of Naralex - SAY_AGGRO_3'); + +DELETE FROM gossip_texts WHERE entry=-3043000; +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3043000,'Let the event begin!','Disciple of Naralex - GOSSIP_ITEM_BEGIN'); diff --git a/sql/updates/r1951_scriptdev2.sql b/sql/updates/r1951_scriptdev2.sql new file mode 100644 index 000000000..ef8853e7e --- /dev/null +++ b/sql/updates/r1951_scriptdev2.sql @@ -0,0 +1,3 @@ +DELETE FROM script_texts WHERE entry=-1289000; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1289000,'School is in session!',0,1,0,0,'gandling SAY_GANDLING_SPAWN'); diff --git a/sql/updates/r1954_mangos.sql b/sql/updates/r1954_mangos.sql new file mode 100644 index 000000000..e4069a0e1 --- /dev/null +++ b/sql/updates/r1954_mangos.sql @@ -0,0 +1,7 @@ +UPDATE creature_template SET ScriptName='' WHERE entry=10504; +UPDATE creature_template SET ScriptName='' WHERE entry=10505; +UPDATE creature_template SET ScriptName='' WHERE entry=10508; +UPDATE creature_template SET ScriptName='' WHERE entry=10507; +UPDATE creature_template SET ScriptName='' WHERE entry=10502; +UPDATE creature_template SET ScriptName='' WHERE entry=11261; +UPDATE creature_template SET ScriptName='' WHERE entry=10901; diff --git a/sql/updates/r1962_mangos.sql b/sql/updates/r1962_mangos.sql new file mode 100644 index 000000000..7f2690d22 --- /dev/null +++ b/sql/updates/r1962_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_isla_starmane' WHERE entry=18760; diff --git a/sql/updates/r1962_scriptdev2.sql b/sql/updates/r1962_scriptdev2.sql new file mode 100644 index 000000000..f3e696827 --- /dev/null +++ b/sql/updates/r1962_scriptdev2.sql @@ -0,0 +1,79 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1000634 AND -1000629; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000629,' Damsel in distress over here!',0,0,0,0,'isla starmane - SAY_ISLA_PERIODIC_1'), +(-1000630,'Hello? Help?',0,0,0,0,'isla starmane - SAY_ISLA_PERIODIC_2'), +(-1000631,'Don''t leave me in here! Cause if you do I will find you!',0,0,0,0,'isla starmane - SAY_ISLA_PERIODIC_3'), +(-1000632,'Ok, let''s get out of here!',0,0,0,0,'isla starmane - SAY_ISLA_START'), +(-1000633,'You sure you''re ready? Take a moment.',0,0,0,0,'isla starmane - SAY_ISLA_WAITING'), +(-1000634,'Alright, let''s do this!',0,0,0,0,'isla starmane - SAY_ISLA_LEAVE_BUILDING'); + +DELETE FROM script_waypoint WHERE entry = 18760; +INSERT INTO script_waypoint (entry, pointid, location_x, location_y, location_z, waittime, point_comment) VALUES +(18760, 01, -2267.07, 3091.46, 13.8271, 0, ''), +(18760, 02, -2270.92, 3094.19, 13.8271, 0, ''), +(18760, 03, -2279.08, 3100.04, 13.8271, 0, ''), +(18760, 04, -2290.05, 3105.07, 13.8271, 0, ''), +(18760, 05, -2297.64, 3112.32, 13.8271, 0, ''), +(18760, 06, -2303.89, 3118.22, 13.8231, 10000, 'building exit'), +(18760, 07, -2307.77, 3123.47, 13.7257, 0, ''), +(18760, 08, -2310.67, 3126.2, 12.5841, 0, ''), +(18760, 09, -2311.48, 3126.98, 12.2769, 0, ''), +(18760, 10, -2316.91, 3132.13, 11.9261, 0, ''), +(18760, 11, -2320.43, 3135.54, 11.7436, 0, ''), +(18760, 12, -2327.38, 3139.36, 10.9431, 0, ''), +(18760, 13, -2332.02, 3142.05, 9.81277, 0, ''), +(18760, 14, -2338.21, 3145.32, 9.31001, 0, ''), +(18760, 15, -2343.1, 3148.91, 8.84879, 0, ''), +(18760, 16, -2347.76, 3153.15, 7.71049, 0, ''), +(18760, 17, -2351.04, 3156.12, 6.66476, 0, ''), +(18760, 18, -2355.15, 3163.18, 5.11997, 0, ''), +(18760, 19, -2359.01, 3169.83, 3.64343, 0, ''), +(18760, 20, -2364.85, 3176.81, 2.32802, 0, ''), +(18760, 21, -2368.77, 3181.69, 1.53285, 0, ''), +(18760, 22, -2371.76, 3185.11, 0.979932, 0, ''), +(18760, 23, -2371.85, 3191.89, -0.293048, 0, ''), +(18760, 24, -2370.99, 3199.6, -1.10504, 0, 'turn left 1'), +(18760, 25, -2376.24, 3205.54, -1.04152, 0, ''), +(18760, 26, -2380.99, 3211.61, -1.16891, 0, ''), +(18760, 27, -2384.04, 3218.4, -1.15279, 0, ''), +(18760, 28, -2385.41, 3226.22, -1.23403, 0, ''), +(18760, 29, -2386.02, 3233.89, -1.31723, 0, ''), +(18760, 30, -2384.7, 3239.82, -1.51903, 0, ''), +(18760, 31, -2382.98, 3247.94, -1.39163, 0, ''), +(18760, 32, -2379.68, 3254.22, -1.25927, 0, ''), +(18760, 33, -2375.27, 3259.69, -1.22925, 0, ''), +(18760, 34, -2369.62, 3264.55, -1.1879, 0, ''), +(18760, 35, -2364.01, 3268.32, -1.48348, 0, ''), +(18760, 36, -2356.61, 3272.31, -1.5505, 0, ''), +(18760, 37, -2352.3, 3274.63, -1.35693, 0, ''), +(18760, 38, -2348.54, 3278.04, -1.04161, 0, 'turn left 2'), +(18760, 39, -2347.56, 3282.41, -0.75979, 0, ''), +(18760, 40, -2348.29, 3288.91, -0.63215, 0, ''), +(18760, 41, -2349.68, 3298.84, -1.07864, 0, ''), +(18760, 42, -2351.15, 3308.52, -1.38864, 0, ''), +(18760, 43, -2352.2, 3317.14, -1.59873, 0, ''), +(18760, 44, -2351.59, 3325.51, -1.92624, 0, ''), +(18760, 45, -2350.88, 3333.38, -2.32506, 0, ''), +(18760, 46, -2350.05, 3342.68, -2.51886, 0, ''), +(18760, 47, -2350.12, 3347.32, -2.57528, 0, ''), +(18760, 48, -2348.72, 3353.7, -2.72689, 0, ''), +(18760, 49, -2346.53, 3360.85, -2.9756, 0, ''), +(18760, 50, -2344.83, 3365.46, -3.3311, 0, ''), +(18760, 51, -2342.68, 3368.91, -3.74526, 0, ''), +(18760, 52, -2340.25, 3371.44, -4.10499, 0, ''), +(18760, 53, -2337.4, 3373.47, -4.44362, 0, ''), +(18760, 54, -2332.68, 3376.02, -5.19648, 0, ''), +(18760, 55, -2326.69, 3379.64, -6.24757, 0, ''), +(18760, 56, -2321.2, 3383.98, -7.28247, 0, ''), +(18760, 57, -2317.81, 3387.78, -8.40093, 0, ''), +(18760, 58, -2315.3, 3392.47, -9.63431, 0, ''), +(18760, 59, -2314.69, 3396.6, -10.2031, 0, ''), +(18760, 60, -2315.48, 3402.35, -10.8211, 0, 'gate'), +(18760, 61, -2317.55, 3409.27, -11.3309, 5000, 'Firewing point exit'), +(18760, 62, -2320.69, 3412.99, -11.5207, 0, ''), +(18760, 63, -2326.88, 3417.89, -11.6105, 0, ''), +(18760, 64, -2332.73, 3421.74, -11.5659, 0, ''), +(18760, 65, -2337.23, 3424.89, -11.496, 0, ''), +(18760, 66, -2339.57, 3429.17, -11.3782, 0, ''), +(18760, 67, -2341.66, 3435.86, -11.3746, 5000, 'Wave and transform'), +(18760, 68, -2342.15, 3443.94, -11.2562, 2000, 'final destination'); diff --git a/sql/updates/r1963_scriptdev2.sql b/sql/updates/r1963_scriptdev2.sql new file mode 100644 index 000000000..aa133cc21 --- /dev/null +++ b/sql/updates/r1963_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 11105+) '; diff --git a/sql/updates/r1965_mangos.sql b/sql/updates/r1965_mangos.sql new file mode 100644 index 000000000..747fa1759 --- /dev/null +++ b/sql/updates/r1965_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_blastmaster_emi_shortfuse' WHERE entry=7998; diff --git a/sql/updates/r1965_scriptdev2.sql b/sql/updates/r1965_scriptdev2.sql new file mode 100644 index 000000000..43252b39c --- /dev/null +++ b/sql/updates/r1965_scriptdev2.sql @@ -0,0 +1,52 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1090023 AND -1090000 OR entry=-1090028; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1090000,'With your help, I can evaluate these tunnels.',0,0,0,1,'emi shortfuse SAY_START'), +(-1090001,'Let\'s see if we can find out where these Troggs are coming from.... and put a stop to the invasion!',0,0,0,1,'emi shortfuse SAY_INTRO_1'), +(-1090002,'Such devastation... what a horrible mess...',0,0,0,5,'emi shortfuse SAY_INTRO_2'), +(-1090003,'It\'s quiet here....',0,0,0,1,'emi shortfuse SAY_INTRO_3'), +(-1090004,'...too quiet.',0,0,0,1,'emi shortfuse SAY_INTRO_4'), +(-1090005,'Look! Over there at the tunnel wall!',0,0,0,25,'emi shortfuse SAY_LOOK_1'), +(-1090006,'Trogg incursion! Defend me while I blast the hole closed!',0,0,0,5,'emi shortfuse SAY_HEAR_1'), +(-1090007,'Get this, $n off of me!',0,0,0,0,'emi shortfuse SAY_AGGRO_1'), +(-1090008,'I don\'t think one charge is going to cut it. Keep fending them off!',0,0,0,0,'emi shortfuse SAY_CHARGE_1'), +(-1090009,'The charges are set. Get back before they blow!',0,0,0,5,'emi shortfuse SAY_CHARGE_2'), +(-1090010,'Incoming blast in 10 seconds!',0,1,0,5,'emi shortfuse SAY_BLOW_1_10'), +(-1090011,'Incoming blast in 5 seconds. Clear the tunnel! Stay back!',0,1,0,5,'emi shortfuse SAY_BLOW_1_5'), +(-1090012,'FIRE IN THE HOLE!',0,1,0,25,'emi shortfuse SAY_BLOW_1'), +(-1090013,'Well done! Without your help I would have never been able to thwart that wave of troggs.',0,0,0,4,'emi shortfuse SAY_FINISH_1'), +(-1090014,'Did you hear something?',0,0,0,6,'emi shortfuse SAY_LOOK_2'), +(-1090015,'I heard something over there.',0,0,0,25,'emi shortfuse SAY_HEAR_2'), +(-1090016,'More troggs! Ward them off as I prepare the explosives!',0,0,0,0,'emi shortfuse SAY_CHARGE_3'), +(-1090017,'The final charge is set. Stand back!',0,0,0,1,'emi shortfuse SAY_CHARGE_4'), +(-1090018,'10 seconds to blast! Stand back!!!',0,1,0,5,'emi shortfuse SAY_BLOW_2_10'), +(-1090019,'5 seconds until detonation!!!!!',0,1,0,5,'emi shortfuse SAY_BLOW_2_5'), +(-1090020,'Nice work! I\'ll set off the charges to prevent any more troggs from making it to the surface.',0,0,0,1,'emi shortfuse SAY_BLOW_SOON'), +(-1090021,'FIRE IN THE HOLE!',0,1,0,0,'emi shortfuse SAY_BLOW_2'), +(-1090022,'Superb! Because of your help, my people stand a chance of re-taking our beloved city. Three cheers to you!',0,0,0,0,'emi shortfuse SAY_FINISH_2'), + +(-1090023,'We come from below! You can never stop us!',0,1,0,1,'grubbis SAY_GRUBBIS_SPAWN'), + +(-1090028,'$n attacking! Help!',0,0,0,0,'emi shortfuse SAY_AGGRO_2'); + + +DELETE FROM script_waypoint WHERE entry=7998; +INSERT INTO script_waypoint VALUES +(7998, 01, -510.1305, -132.6899, -152.5, 0, ''), +(7998, 02, -511.0994, -129.74, -153.8453, 0, ''), +(7998, 03, -511.7897, -127.4764, -155.5505, 0, ''), +(7998, 04, -512.9688, -124.926, -156.1146, 5000, ''), +(7998, 05, -513.9719, -120.2358, -156.1161, 0, ''), +(7998, 06, -514.3875, -115.1896, -156.1165, 0, ''), +(7998, 07, -514.3039, -111.4777, -155.5205, 0, ''), +(7998, 08, -514.8401, -107.6633, -154.8925, 0, ''), +(7998, 09, -518.9943, -101.4161, -154.6482, 27000, ''), +(7998, 10, -526.9984, -98.14884, -155.6253, 0, ''), +(7998, 11, -534.5686, -105.4101, -155.989, 30000, ''), +(7998, 12, -535.5336, -104.6947, -155.9713, 0, ''), +(7998, 13, -541.6304, -98.6583, -155.8584, 25000, ''), +(7998, 14, -535.0923, -99.91748, -155.9742, 0, ''), +(7998, 15, -519.0099, -101.5097, -154.6766, 3000, ''), +(7998, 16, -504.4659, -97.84802, -150.9554, 30000, ''), +(7998, 17, -506.9069, -89.14736, -151.083, 23000, ''), +(7998, 18, -512.7576, -101.9025, -153.198, 0, ''), +(7998, 19, -519.9883, -124.8479, -156.128, 86400000, 'this npc should not reset on wp end'); diff --git a/sql/updates/r1968_scriptdev2.sql b/sql/updates/r1968_scriptdev2.sql new file mode 100644 index 000000000..59d70c7db --- /dev/null +++ b/sql/updates/r1968_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 11109+) '; diff --git a/sql/updates/r1972_scriptdev2.sql b/sql/updates/r1972_scriptdev2.sql new file mode 100644 index 000000000..7ce51a10c --- /dev/null +++ b/sql/updates/r1972_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 11126+) '; diff --git a/sql/updates/r1973_mangos.sql b/sql/updates/r1973_mangos.sql new file mode 100644 index 000000000..a39c3f4f5 --- /dev/null +++ b/sql/updates/r1973_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='spell_dummy_npc' WHERE entry IN (28465,28600); diff --git a/sql/updates/r1974_mangos.sql b/sql/updates/r1974_mangos.sql new file mode 100644 index 000000000..dad711887 --- /dev/null +++ b/sql/updates/r1974_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_theldren_trigger' WHERE entry=16079; diff --git a/sql/updates/r1975_scriptdev2.sql b/sql/updates/r1975_scriptdev2.sql new file mode 100644 index 000000000..d14055b97 --- /dev/null +++ b/sql/updates/r1975_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 11136+) '; diff --git a/sql/updates/r1979_scriptdev2.sql b/sql/updates/r1979_scriptdev2.sql new file mode 100644 index 000000000..db7417883 --- /dev/null +++ b/sql/updates/r1979_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 11167+) '; diff --git a/sql/updates/r1982_mangos.sql b/sql/updates/r1982_mangos.sql new file mode 100644 index 000000000..c096be814 --- /dev/null +++ b/sql/updates/r1982_mangos.sql @@ -0,0 +1,2 @@ +UPDATE creature_template SET ScriptName='boss_ichoron' WHERE entry IN (29313,32234); +UPDATE creature_template SET ScriptName='boss_erekem' WHERE entry IN (29315,32226); diff --git a/sql/updates/r1982_scriptdev2.sql b/sql/updates/r1982_scriptdev2.sql new file mode 100644 index 000000000..d6387b97e --- /dev/null +++ b/sql/updates/r1982_scriptdev2.sql @@ -0,0 +1,20 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1608026 AND -1608008; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1608008,'Free to--mm--fly now. Ra-aak... Not find us--ekh-ekh! Escape!',14218,1,0,0,'erekem SAY_RELEASE_EREKEM'), +(-1608009,'I... am fury... unrestrained!',14229,1,0,0,'ichoron SAY_RELEASE_ICHORON'), +(-1608010,'Back in business! Now to execute an exit strategy.',14498,1,0,0,'xevozz SAY_RELEASE_XEVOZZ'), +(-1608011,'I am... renewed.',13995,1,0,0,'zuramat SAY_RELEASE_ZURAMAT'), + +(-1608012,'Not--caww--get in way of--rrak-rrak--flee!',14219,1,0,0,'erekem SAY_AGGRO'), +(-1608013,'My---raaak--favorite! Awk awk awk! Raa-kaa!',14220,1,0,0,'erekem SAY_ADD_DIE_1'), +(-1608014,'Nasty little...A-ak,kaw! Kill! Yes,kill you!',14221,1,0,0,'erekem SAY_ADD_DIE_2'), +(-1608018,'No--kaw,kaw--flee...',14225,1,0,0,'erekem SAY_DEATH'), + +(-1608019,'Stand aside, mortals!',14230,1,0,0,'ichoron SAY_AGGRO'), +(-1608020,'I will not be contained! Ngyah!!',14233,1,0,0,'ichoron SAY_SHATTERING'), +(-1608021,'Water can hold any form, take any shape... overcome any obstacle.',14232,1,0,0,'ichoron SAY_SHIELD'), +(-1608022,'I am a force of nature!',14234,1,0,0,'ichoron SAY_SLAY_1'), +(-1608023,'I shall pass!',14235,1,0,0,'ichoron SAY_SLAY_2'), +(-1608024,'You can not stop the tide!',14236,1,0,0,'ichoron SAY_SLAY_3'), +(-1608025,'I shall consume, decimate,devastate,and destroy! Yield now to the wrath of the pounding sea!',14231,1,0,0,'ichoron SAY_ENRAGE'), +(-1608026,'I... recede.',14237,1,0,0,'ichoron SAY_DEATH'); diff --git a/sql/updates/r1984_mangos.sql b/sql/updates/r1984_mangos.sql new file mode 100644 index 000000000..642949622 --- /dev/null +++ b/sql/updates/r1984_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_disciple_of_naralex' WHERE entry=3678; diff --git a/sql/updates/r1984_scriptdev2.sql b/sql/updates/r1984_scriptdev2.sql new file mode 100644 index 000000000..000290adc --- /dev/null +++ b/sql/updates/r1984_scriptdev2.sql @@ -0,0 +1,48 @@ +DELETE FROM script_texts WHERE entry=-1043012; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1043012,'This $N is a minion from Naralex''s nightmare no doubt!.',0,0,0,0,'Disciple of Naralex - SAY_MUTANUS'); + +DELETE FROM script_waypoint WHERE entry=3678; +INSERT INTO script_waypoint VALUES +(3678, 0, -134.925, 125.468, -78.16, 0, ''), +(3678, 1, -125.684, 132.937, -78.42, 0, ''), +(3678, 2, -113.812, 139.295, -80.98, 0, ''), +(3678, 3, -109.854, 157.538, -80.20, 0, ''), +(3678, 4, -108.640, 175.207, -79.74, 0, ''), +(3678, 5, -108.668, 195.457, -80.64, 0, ''), +(3678, 6, -111.007, 219.007, -86.58, 0, ''), +(3678, 7, -102.408, 232.821, -91.52, 0, 'first corner SAY_FIRST_CORNER'), +(3678, 8, -92.434, 227.742, -90.75, 0, ''), +(3678, 9, -82.456, 224.853, -93.57, 0, ''), +(3678, 10, -67.789, 208.073, -93.34, 0, ''), +(3678, 11, -43.343, 205.295, -96.37, 0, ''), +(3678, 12, -34.676, 221.394, -95.82, 0, ''), +(3678, 13, -32.582, 238.573, -93.51, 0, ''), +(3678, 14, -42.149, 258.672, -92.88, 0, ''), +(3678, 15, -55.257, 274.696, -92.83, 0, 'circle of flames SAY_CIRCLE_BANISH'), +(3678, 16, -48.604, 287.584, -92.46, 0, ''), +(3678, 17, -47.236, 296.093, -90.88, 0, ''), +(3678, 18, -35.618, 309.067, -89.73, 0, ''), +(3678, 19, -23.573, 311.376, -88.60, 0, ''), +(3678, 20, -8.692, 302.389, -87.43, 0, ''), +(3678, 21, -1.237, 293.268, -85.55, 0, ''), +(3678, 22, 10.398, 279.294, -85.86, 0, ''), +(3678, 23, 23.108, 264.693, -86.69, 0, ''), +(3678, 24, 31.996, 251.436, -87.62, 0, ''), +(3678, 25, 43.374, 233.073, -87.61, 0, ''), +(3678, 26, 54.438, 212.048, -89.50, 3000, 'chamber entrance SAY_NARALEX_CHAMBER'), +(3678, 27, 78.794, 208.895, -92.84, 0, ''), +(3678, 28, 88.392, 225.231, -94.46, 0, ''), +(3678, 29, 98.758, 233.938, -95.84, 0, ''), +(3678, 30, 107.248, 233.054, -95.98, 0, ''), +(3678, 31, 112.825, 233.907, -96.39, 0, ''), +(3678, 32, 114.634, 236.969, -96.04, 1000, 'naralex SAY_BEGIN_RITUAL'), +(3678, 33, 127.385, 252.279, -90.07, 0, ''), +(3678, 34, 121.595, 264.488, -91.55, 0, ''), +(3678, 35, 115.472, 264.253, -91.50, 0, ''), +(3678, 36, 99.988, 252.790, -91.51, 0, ''), +(3678, 37, 96.347, 245.038, -90.34, 0, ''), +(3678, 38, 82.201, 216.273, -86.10, 0, ''), +(3678, 39, 75.112, 206.494, -84.80, 0, ''), +(3678, 40, 27.174, 201.064, -72.31, 0, ''), +(3678, 41, -41.114, 204.149, -78.94, 0, ''); diff --git a/sql/updates/r1987_mangos.sql b/sql/updates/r1987_mangos.sql new file mode 100644 index 000000000..730dbf767 --- /dev/null +++ b/sql/updates/r1987_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='' WHERE npcflag=npcflag|65536; diff --git a/sql/updates/r1990_mangos.sql b/sql/updates/r1990_mangos.sql new file mode 100644 index 000000000..3207052c5 --- /dev/null +++ b/sql/updates/r1990_mangos.sql @@ -0,0 +1,4 @@ +DELETE FROM scripted_areatrigger WHERE entry=4778; +INSERT INTO scripted_areatrigger VALUES (4778,'at_ancient_male_vrykul'); + +UPDATE creature_template SET ScriptName='npc_ancient_male_vrykul' WHERE entry=24314; diff --git a/sql/updates/r1990_scriptdev2.sql b/sql/updates/r1990_scriptdev2.sql new file mode 100644 index 000000000..bc0eaef2c --- /dev/null +++ b/sql/updates/r1990_scriptdev2.sql @@ -0,0 +1,9 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1000641 AND -1000635; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000635,'So then we too are cursed?',0,0,0,0,'ancient vrykul SAY_VRYKUL_CURSED'), +(-1000636,'%s points to the infant.',0,2,0,0,'ancient vrykul EMOTE_VRYKUL_POINT'), +(-1000637,'%s sobs.',0,2,0,0,'ancient vrykul EMOTE_VRYKUL_SOB'), +(-1000638,'The gods have forsaken us! We must dispose of it before Ymiron is notified!',0,0,0,0,'ancient vrykul SAY_VRYKUL_DISPOSE'), +(-1000639,'NO! You cannot! I beg of you! It is our child!',0,0,0,0,'ancient vrykul SAY_VRYKUL_BEG'), +(-1000640,'Then what are we to do, wife? The others cannot find out. Should they learn of this aberration, we will all be executed.',0,0,0,0,'ancient vrykul SAY_VRYKUL_WHAT'), +(-1000641,'I... I will hide it. I will hide it until I find it a home, far away from here...',0,0,0,0,'ancient vrykul SAY_VRYKUL_HIDE'); diff --git a/sql/updates/r1992_mangos.sql b/sql/updates/r1992_mangos.sql new file mode 100644 index 000000000..5a068993e --- /dev/null +++ b/sql/updates/r1992_mangos.sql @@ -0,0 +1 @@ +UPDATE gameobject_template SET ScriptName='go_service_gate' WHERE entry=175368; diff --git a/sql/updates/r1992_scriptdev2.sql b/sql/updates/r1992_scriptdev2.sql new file mode 100644 index 000000000..5a9bdfefc --- /dev/null +++ b/sql/updates/r1992_scriptdev2.sql @@ -0,0 +1,10 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1329015 AND -1329008; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1329008,'Intruders at the Service Gate! Lord Rivendare must be warned!',0,6,0,0,'barthilas SAY_WARN_BARON'), +(-1329009,'Intruders! More pawns of the Argent Dawn, no doubt. I already count one of their number among my prisoners. Withdraw from my domain before she is executed!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_START'), +(-1329010,'You\'re still here? Your foolishness is amusing! The Argent Dawn wench needn\'t suffer in vain. Leave at once and she shall be spared!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_10_MIN'), +(-1329011,'I shall take great pleasure in taking this poor wretch\'s life! It\'s not too late, she needn\'t suffer in vain. Turn back and her death shall be merciful!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_5_MIN'), +(-1329012,'May this prisoner\'s death serve as a warning. None shall defy the Scourge and live!',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RUN_FAIL'), +(-1329013,'So you see fit to toy with the Lich King\'s creations? Ramstein, be sure to give the intruders a proper greeting.',0,6,0,0,'baron rivendare SAY_ANNOUNCE_RAMSTEIN'), +(-1329014,'Time to take matters into my own hands. Come. Enter my domain and challenge the might of the Scourge!',0,6,0,0,'baron rivendare SAY_UNDEAD_DEFEAT'), +(-1329015,'You did it... you\'ve slain Baron Rivendare! The Argent Dawn shall hear of your valiant deeds!',0,0,0,0,'ysida SAY_EPILOGUE'); diff --git a/sql/updates/r1993_mangos.sql b/sql/updates/r1993_mangos.sql new file mode 100644 index 000000000..bd6bc356e --- /dev/null +++ b/sql/updates/r1993_mangos.sql @@ -0,0 +1 @@ +UPDATE instance_template SET ScriptName='instance_dire_maul' WHERE map=429; diff --git a/sql/updates/r1993_scriptdev2.sql b/sql/updates/r1993_scriptdev2.sql new file mode 100644 index 000000000..cbe8d234b --- /dev/null +++ b/sql/updates/r1993_scriptdev2.sql @@ -0,0 +1,4 @@ +DELETE FROM script_texts WHERE entry IN (-1429000, -1429001); +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1429000,'The demon is loose! Quickly we must restrain him!',0,6,0,0,'highborne summoner SAY_FREE_IMMOLTHAR'), +(-1429001,'Who dares disrupt the sanctity of Eldre\'Thalas? Face me, cowards!',0,6,0,0,'prince tortheldrin SAY_KILL_IMMOLTHAR'); diff --git a/sql/updates/r2004_mangos.sql b/sql/updates/r2004_mangos.sql new file mode 100644 index 000000000..63d094a87 --- /dev/null +++ b/sql/updates/r2004_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='boss_forgemaster_garfrost' WHERE entry=36494; diff --git a/sql/updates/r2008_mangos.sql b/sql/updates/r2008_mangos.sql new file mode 100644 index 000000000..b409b8253 --- /dev/null +++ b/sql/updates/r2008_mangos.sql @@ -0,0 +1,4 @@ +DELETE FROM scripted_areatrigger WHERE entry IN (3958, 3960); +INSERT INTO scripted_areatrigger VALUES +(3958, 'at_zulgurub'), +(3960, 'at_zulgurub'); diff --git a/sql/updates/r2008_scriptdev2.sql b/sql/updates/r2008_scriptdev2.sql new file mode 100644 index 000000000..81be1d728 --- /dev/null +++ b/sql/updates/r2008_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE script_texts SET type=6 WHERE entry IN (-1309022, -1309023); diff --git a/sql/updates/r2009_mangos.sql b/sql/updates/r2009_mangos.sql new file mode 100644 index 000000000..46ff7fd75 --- /dev/null +++ b/sql/updates/r2009_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_dalinda_malem' WHERE entry=5644; diff --git a/sql/updates/r2009_scriptdev2.sql b/sql/updates/r2009_scriptdev2.sql new file mode 100644 index 000000000..2ea71d9bb --- /dev/null +++ b/sql/updates/r2009_scriptdev2.sql @@ -0,0 +1,21 @@ +DELETE FROM script_waypoint WHERE entry=5644; +INSERT INTO script_waypoint (entry, pointid, location_x, location_y, location_z, waittime, point_comment) VALUES +(5644, 1, -339.679, 1752.04, 139.482, 0, ''), +(5644, 2, -328.957, 1734.95, 139.327, 0, ''), +(5644, 3, -338.29, 1731.36, 139.327, 0, ''), +(5644, 4, -350.747, 1731.12, 139.338, 0, ''), +(5644, 5, -365.064, 1739.04, 139.376, 0, ''), +(5644, 6, -371.105, 1746.03, 139.374, 0, ''), +(5644, 7, -383.141, 1738.62, 138.93, 0, ''), +(5644, 8, -390.445, 1733.98, 136.353, 0, ''), +(5644, 9, -401.368, 1726.77, 131.071, 0, ''), +(5644, 10, -416.016, 1721.19, 129.807, 0, ''), +(5644, 11, -437.139, 1709.82, 126.342, 0, ''), +(5644, 12, -455.83, 1695.61, 119.305, 0, ''), +(5644, 13, -459.862, 1687.92, 116.059, 0, ''), +(5644, 14, -463.565, 1679.1, 111.653, 0, ''), +(5644, 15, -461.485, 1670.94, 109.033, 0, ''), +(5644, 16, -471.786, 1647.34, 102.862, 0, ''), +(5644, 17, -477.146, 1625.69, 98.342, 0, ''), +(5644, 18, -475.815, 1615.815, 97.07, 0, ''), +(5644, 19, -474.329, 1590.01, 94.4982, 0, ''); diff --git a/sql/updates/r2010_mangos.sql b/sql/updates/r2010_mangos.sql new file mode 100644 index 000000000..ebcbec9f1 --- /dev/null +++ b/sql/updates/r2010_mangos.sql @@ -0,0 +1 @@ +UPDATE gameobject_template SET ScriptName='go_hand_of_iruxos_crystal' WHERE entry=176581; diff --git a/sql/updates/r2013_mangos.sql b/sql/updates/r2013_mangos.sql new file mode 100644 index 000000000..fafc022d4 --- /dev/null +++ b/sql/updates/r2013_mangos.sql @@ -0,0 +1,2 @@ +UPDATE creature_template SET ScriptName='spell_dummy_npc' WHERE entry=29327; +UPDATE creature_template SET ScriptName='spell_dummy_npc' WHERE entry=29319; diff --git a/sql/updates/r2013_scriptdev2.sql b/sql/updates/r2013_scriptdev2.sql new file mode 100644 index 000000000..a6bba7d33 --- /dev/null +++ b/sql/updates/r2013_scriptdev2.sql @@ -0,0 +1,4 @@ +DELETE FROM script_texts WHERE entry IN (-1000642, -1000643); +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000642,'It\'s a female.',0,5,0,0,'leopard icepaw SAY_ITS_FEMALE'), +(-1000643,'It\'s an angry male!',0,5,0,0,'leopard icepaw SAY_ITS_MALE'); diff --git a/sql/updates/r2015_mangos.sql b/sql/updates/r2015_mangos.sql new file mode 100644 index 000000000..50c0357b2 --- /dev/null +++ b/sql/updates/r2015_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='spell_dummy_npc' WHERE entry=17157; diff --git a/sql/updates/r2017_mangos.sql b/sql/updates/r2017_mangos.sql new file mode 100644 index 000000000..ccb71fb65 --- /dev/null +++ b/sql/updates/r2017_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='' WHERE entry=6497; diff --git a/sql/updates/r2018_scriptdev2.sql b/sql/updates/r2018_scriptdev2.sql new file mode 100644 index 000000000..a880c0288 --- /dev/null +++ b/sql/updates/r2018_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 11316+) '; diff --git a/sql/updates/r2020_scriptdev2.sql b/sql/updates/r2020_scriptdev2.sql new file mode 100644 index 000000000..aa05ff0ac --- /dev/null +++ b/sql/updates/r2020_scriptdev2.sql @@ -0,0 +1,10 @@ +DELETE FROM script_texts WHERE entry IN (-1409023, -1409024); +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1409023,'Very well, $N.',0,0,0,0,'majordomo SAY_SUMMON_0'), +(-1409024,'Impudent whelps! You''ve rushed headlong to your own deaths! See now, the master stirs!',0,1,0,0,'majordomo SAY_SUMMON_1'); + +DELETE FROM gossip_texts WHERE entry IN (-3409000, -3409001, -3409002); +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3409000,'Tell me more.','majordomo_executus GOSSIP_ITEM_SUMMON_1'), +(-3409001,'What else do you have to say?','majordomo_executus GOSSIP_ITEM_SUMMON_2'), +(-3409002,'You challenged us and we have come. Where is this master you speak of?','majordomo_executus GOSSIP_ITEM_SUMMON_3'); diff --git a/sql/updates/r2021_mangos.sql b/sql/updates/r2021_mangos.sql new file mode 100644 index 000000000..ba30ad964 --- /dev/null +++ b/sql/updates/r2021_mangos.sql @@ -0,0 +1,8 @@ +UPDATE creature_template SET ScriptName='boss_thaddius' WHERE entry=15928; +UPDATE creature_template SET ScriptName='boss_stalagg' WHERE entry=15929; +UPDATE creature_template SET ScriptName='boss_feugen' WHERE entry=15930; +UPDATE creature_template SET ScriptName='npc_tesla_coil' WHERE entry=16218; + +DELETE FROM scripted_areatrigger WHERE entry=4113; +INSERT INTO scripted_areatrigger VALUES +(4113,'at_naxxramas'); diff --git a/sql/updates/r2024_mangos.sql b/sql/updates/r2024_mangos.sql new file mode 100644 index 000000000..76919314a --- /dev/null +++ b/sql/updates/r2024_mangos.sql @@ -0,0 +1,3 @@ +UPDATE gameobject_template SET ScriptName='' WHERE entry=164955; +UPDATE gameobject_template SET ScriptName='' WHERE entry=164956; +UPDATE gameobject_template SET ScriptName='' WHERE entry=164957; diff --git a/sql/updates/r2025_mangos.sql b/sql/updates/r2025_mangos.sql new file mode 100644 index 000000000..b444b113d --- /dev/null +++ b/sql/updates/r2025_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='' WHERE entry=18240; diff --git a/sql/updates/r2028_scriptdev2.sql b/sql/updates/r2028_scriptdev2.sql new file mode 100644 index 000000000..3287576ed --- /dev/null +++ b/sql/updates/r2028_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE script_texts SET type=3 WHERE entry IN (-1533082,-1533083); diff --git a/sql/updates/r2031_mangos.sql b/sql/updates/r2031_mangos.sql new file mode 100644 index 000000000..95df14ff9 --- /dev/null +++ b/sql/updates/r2031_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='spell_dummy_npc' WHERE entry IN (28053, 28054, 28093); diff --git a/sql/updates/r2031_scriptdev2.sql b/sql/updates/r2031_scriptdev2.sql new file mode 100644 index 000000000..baef2250d --- /dev/null +++ b/sql/updates/r2031_scriptdev2.sql @@ -0,0 +1,10 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1000651 AND -1000644; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000644,'Ouch! That\'s it, I quit the target business!',0,0,0,0,'SAY_LUCKY_HIT_1'), +(-1000645,'My ear! You grazed my ear!',0,0,0,0,'SAY_LUCKY_HIT_2'), +(-1000646,'Not the \'stache! Now I\'m asymmetrical!',0,0,0,0,'SAY_LUCKY_HIT_3'), +(-1000647,'Good shot!',0,0,0,0,'SAY_LUCKY_HIT_APPLE'), +(-1000648,'Stop whining. You\'ve still got your luck.',0,0,0,0,'SAY_DROSTAN_GOT_LUCKY_1'), +(-1000649,'Bah, it\'s an improvement.',0,0,0,0,'SAY_DROSTAN_GOT_LUCKY_2'), +(-1000650,'Calm down lad, it\'s just a birdshot!',0,0,0,0,'SAY_DROSTAN_HIT_BIRD_1'), +(-1000651,'The only thing hurt is your pride, lad! Buck up!',0,0,0,0,'SAY_DROSTAN_HIT_BIRD_2'); diff --git a/sql/updates/r2033_scriptdev2.sql b/sql/updates/r2033_scriptdev2.sql new file mode 100644 index 000000000..736a7c4f5 --- /dev/null +++ b/sql/updates/r2033_scriptdev2.sql @@ -0,0 +1,11 @@ +DELETE FROM script_texts WHERE entry=-1469031; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1469031,'Death Knights, get over here!',0,1,0,0,'nefarian SAY_DEATH_KNIGHT'); + +DELETE FROM gossip_texts WHERE entry IN (-3469000, -3469001, -3469002); +INSERT INTO gossip_texts (entry,content_default,comment) VALUES +(-3469000,'I\'ve made no mistakes.','victor_nefarius GOSSIP_ITEM_NEFARIUS_1'), +(-3469001,'You have lost your mind, Nefarius. You speak in riddles.','victor_nefarius GOSSIP_ITEM_NEFARIUS_2'), +(-3469002,'Please do.','victor_nefarius GOSSIP_ITEM_NEFARIUS_3'); + +UPDATE script_texts SET comment='victor_nefarius SAY_NEFARIUS_CORRUPT' WHERE entry=-1469006; diff --git a/sql/updates/r2036_scriptdev2.sql b/sql/updates/r2036_scriptdev2.sql new file mode 100644 index 000000000..890db6725 --- /dev/null +++ b/sql/updates/r2036_scriptdev2.sql @@ -0,0 +1,3 @@ +UPDATE script_texts SET emote=5 WHERE entry=-1000646; +UPDATE script_texts SET emote=4 WHERE entry=-1000647; +UPDATE script_texts SET emote=11 WHERE entry=-1000649; diff --git a/sql/updates/r2037_mangos.sql b/sql/updates/r2037_mangos.sql new file mode 100644 index 000000000..4f67f0281 --- /dev/null +++ b/sql/updates/r2037_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='' WHERE entry=29344; diff --git a/sql/updates/r2038_mangos.sql b/sql/updates/r2038_mangos.sql new file mode 100644 index 000000000..c95ac91cb --- /dev/null +++ b/sql/updates/r2038_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='' WHERE entry IN (14742,14743,21493,21494); diff --git a/sql/updates/r2039_mangos.sql b/sql/updates/r2039_mangos.sql new file mode 100644 index 000000000..fa65242d0 --- /dev/null +++ b/sql/updates/r2039_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='' WHERE entry=24040; diff --git a/sql/updates/r2043_scriptdev2.sql b/sql/updates/r2043_scriptdev2.sql new file mode 100644 index 000000000..c5bb54f3e --- /dev/null +++ b/sql/updates/r2043_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE script_texts SET content_default='You there, check out that noise.' WHERE entry=-1036000; diff --git a/sql/updates/r2044_mangos.sql b/sql/updates/r2044_mangos.sql new file mode 100644 index 000000000..0771cad77 --- /dev/null +++ b/sql/updates/r2044_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='boss_mr_smite' WHERE entry=646; diff --git a/sql/updates/r2044_scriptdev2.sql b/sql/updates/r2044_scriptdev2.sql new file mode 100644 index 000000000..4c80d4f8a --- /dev/null +++ b/sql/updates/r2044_scriptdev2.sql @@ -0,0 +1,4 @@ +DELETE FROM script_texts WHERE entry IN (-1036002, -1036003); +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1036002,'You land lubbers are tougher than I thought! I\'ll have to improvise!',5778,0,0,21,'smite SAY_PHASE_2'), +(-1036003,'D\'ah! Now you\'re making me angry!',5779,0,0,15,'smite SAY_PHASE_3'); diff --git a/sql/updates/r2050_mangos.sql b/sql/updates/r2050_mangos.sql new file mode 100644 index 000000000..16bad37cf --- /dev/null +++ b/sql/updates/r2050_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_dragonmaw_peon' WHERE entry=22252; diff --git a/sql/updates/r2051_scriptdev2.sql b/sql/updates/r2051_scriptdev2.sql new file mode 100644 index 000000000..8a6c6ab5b --- /dev/null +++ b/sql/updates/r2051_scriptdev2.sql @@ -0,0 +1,7 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1000656 AND -1000652; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000652,'Me so hungry! YUM!',0,0,0,71,'dragonmaw peon SAY_PEON_1'), +(-1000653,'Hey... me not feel so good.',0,0,0,0,'dragonmaw peon SAY_PEON_2'), +(-1000654,'You is bad orc... baaad... or... argh!',0,0,0,0,'dragonmaw peon SAY_PEON_3'), +(-1000655,'Time for eating!?',0,0,0,71,'dragonmaw peon SAY_PEON_4'), +(-1000656,'It put the mutton in the stomach!',0,0,0,71,'dragonmaw peon SAY_PEON_5'); diff --git a/sql/updates/r2057_scriptdev2.sql b/sql/updates/r2057_scriptdev2.sql new file mode 100644 index 000000000..37712eefc --- /dev/null +++ b/sql/updates/r2057_scriptdev2.sql @@ -0,0 +1,5 @@ +DELETE FROM script_texts WHERE entry BETWEEN 1329018 AND 1329016; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1329016,'Today you have unmade what took me years to create! For this you shall all die by my hand!',0,1,0,0,'dathrohan SAY_AGGRO'), +(-1329017,'You fools think you can defeat me so easily? Face the true might of the Nathrezim!',0,1,0,0,'dathrohan SAY_TRANSFORM'), +(-1329018,'Damn you mortals! All my plans of revenge, all my hate... all burned to ash...',0,0,0,0,'dathrohan SAY_DEATH'); diff --git a/sql/updates/r2059_mangos.sql b/sql/updates/r2059_mangos.sql new file mode 100644 index 000000000..e723f5665 --- /dev/null +++ b/sql/updates/r2059_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_helice' WHERE entry=28787; diff --git a/sql/updates/r2059_scriptdev2.sql b/sql/updates/r2059_scriptdev2.sql new file mode 100644 index 000000000..43d91253b --- /dev/null +++ b/sql/updates/r2059_scriptdev2.sql @@ -0,0 +1,34 @@ +DELETE FROM script_texts WHERE entry BETWEEN -1000663 AND -1000657; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000657,'Let\'s get the hell out of here.',0,0,0,5,'helice SAY_HELICE_ACCEPT'), +(-1000658,'Listen up, Venture Company goons! Rule #1: Never keep the prisoner near the explosives.',0,0,0,25,'helice SAY_HELICE_EXPLOSIVES_1'), +(-1000659,'Or THIS is what you get.',0,0,0,0,'helice SAY_HELICE_EXPLODE_1'), +(-1000660,'It\'s getting a little hot over here. Shall we move on?',0,0,0,11,'helice SAY_HELICE_MOVE_ON'), +(-1000661,'Oh, look, it\'s another cartload of explosives! Let\'s help them dispose of it.',0,0,0,25,'helice SAY_HELICE_EXPLOSIVES_2'), +(-1000662,'You really shouldn\'t play with this stuff. Someone could get hurt.',0,0,0,5,'helice SAY_HELICE_EXPLODE_2'), +(-1000663,'We made it! Thank you for getting me out of that hell hole. Tell Hemet to expect me!',0,0,0,4,'helice SAY_HELICE_COMPLETE'); + +DELETE FROM script_waypoint WHERE entry=28787; +INSERT INTO script_waypoint (entry, pointid, location_x, location_y, location_z, waittime, point_comment) VALUES +(28787, 1, 5913.516113, 5379.034668, -98.896118, 0, ''), +(28787, 2, 5917.750977, 5374.519043, -98.869781, 0, 'SAY_HELICE_EXPLOSIVES_1'), +(28787, 3, 5926.428711, 5372.145020, -98.884453, 0, ''), +(28787, 4, 5929.214844, 5377.803223, -99.020065, 0, ''), +(28787, 5, 5927.621582, 5378.564941, -99.047890, 0, ''), +(28787, 6, 5917.622070, 5383.494629, -106.310204, 0, ''), +(28787, 7, 5908.991211, 5387.655762, -106.310204, 0, ''), +(28787, 8, 5906.287109, 5390.496582, -106.041801, 0, ''), +(28787, 9, 5902.415039, 5399.741211, -99.306595, 0, ''), +(28787, 10, 5901.444336, 5404.593262, -96.759636, 0, ''), +(28787, 11, 5897.860352, 5406.656250, -96.029709, 0, ''), +(28787, 12, 5892.254395, 5401.291504, -95.848808, 0, ''), +(28787, 13, 5887.421875, 5386.701172, -95.400146, 0, 'SAY_HELICE_EXPLOSIVES_2'), +(28787, 14, 5883.308105, 5385.057617, -94.423698, 0, ''), +(28787, 15, 5879.180664, 5375.897461, -95.088066, 0, ''), +(28787, 16, 5872.613281, 5363.473633, -97.703575, 0, ''), +(28787, 17, 5857.971191, 5354.929688, -98.586090, 0, ''), +(28787, 18, 5848.729004, 5345.326660, -99.428978, 0, ''), +(28787, 19, 5842.330566, 5335.018555, -100.421455, 0, ''), +(28787, 20, 5832.164551, 5323.145020, -98.703285, 0, ''), +(28787, 21, 5824.738770, 5315.712891, -97.758018, 0, ''), +(28787, 22, 5819.650879, 5305.409668, -97.481796, 10000, 'SAY_HELICE_COMPLETE'); diff --git a/sql/updates/r2061_mangos.sql b/sql/updates/r2061_mangos.sql new file mode 100644 index 000000000..2d518d85c --- /dev/null +++ b/sql/updates/r2061_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_oil_stained_wolf' WHERE entry=25791; diff --git a/sql/updates/r2064_mangos.sql b/sql/updates/r2064_mangos.sql new file mode 100644 index 000000000..9d4c04b99 --- /dev/null +++ b/sql/updates/r2064_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='npc_sinkhole_kill_credit' WHERE entry IN (26248,26249); diff --git a/sql/updates/r2064_scriptdev2.sql b/sql/updates/r2064_scriptdev2.sql new file mode 100644 index 000000000..4ba54cb48 --- /dev/null +++ b/sql/updates/r2064_scriptdev2.sql @@ -0,0 +1 @@ +UPDATE sd2_db_version SET version='ScriptDev2 (for MaNGOS 11421+) '; diff --git a/system/MangosdRev.cpp b/system/MangosdRev.cpp new file mode 100644 index 000000000..f47abb874 --- /dev/null +++ b/system/MangosdRev.cpp @@ -0,0 +1,20 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 +* This program is free software licensed under GPL version 2 +* Please see the included DOCS/LICENSE.TXT for more information */ + +#include "../../../shared/revision_nr.h" + +#ifdef WIN32 +# define MANGOS_DLL_EXPORT extern "C" __declspec(dllexport) +#elif defined( __GNUC__ ) +# define MANGOS_DLL_EXPORT extern "C" +#else +# define MANGOS_DLL_EXPORT extern "C" export +#endif + + +MANGOS_DLL_EXPORT +char const* GetMangosRevStr() +{ + return REVISION_NR; +} diff --git a/system/ScriptLoader.cpp b/system/ScriptLoader.cpp index 9e0cab6a3..dc79d0f8b 100644 --- a/system/ScriptLoader.cpp +++ b/system/ScriptLoader.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -8,6 +8,18 @@ extern void AddSC_battleground(); //custom +extern void AddSC_npc_arena_honor(); +extern void AddSC_mob_teleguy(); + +// OutdoorPvP +extern void AddSC_outdoor_pvp_eastern_kingdoms(); +extern void AddSC_outdoor_pvp_kalimdor(); +extern void AddSC_outdoor_pvp_northrend(); +extern void AddSC_outdoor_pvp_outland(); + +// OutdoorPvP zone scripts +extern void AddSC_outdoor_pvp_eastern_plaguelands(); +extern void AddSC_outdoor_pvp_silithus(); //examples extern void AddSC_example_creature(); @@ -53,8 +65,8 @@ extern void AddSC_boss_pyroguard_emberseer(); extern void AddSC_boss_gyth(); extern void AddSC_boss_rend_blackhand(); extern void AddSC_instance_blackrock_spire(); -extern void AddSC_boss_razorgore(); //blackwing_lair -extern void AddSC_boss_vael(); +extern void AddSC_boss_razorgore(); // blackwing_lair +extern void AddSC_boss_vaelastrasz(); extern void AddSC_boss_broodlord(); extern void AddSC_boss_firemaw(); extern void AddSC_boss_ebonroc(); @@ -111,15 +123,8 @@ extern void AddSC_boss_headless_horseman(); extern void AddSC_instance_scarlet_monastery(); extern void AddSC_boss_darkmaster_gandling(); //scholomance extern void AddSC_boss_death_knight_darkreaver(); -extern void AddSC_boss_theolenkrastinov(); -extern void AddSC_boss_illuciabarov(); -extern void AddSC_boss_instructormalicia(); extern void AddSC_boss_jandicebarov(); extern void AddSC_boss_kormok(); -extern void AddSC_boss_lordalexeibarov(); -extern void AddSC_boss_lorekeeperpolkelt(); -extern void AddSC_boss_rasfrost(); -extern void AddSC_boss_theravenian(); extern void AddSC_boss_vectus(); extern void AddSC_instance_scholomance(); extern void AddSC_shadowfang_keep(); //shadowfang_keep @@ -211,8 +216,6 @@ extern void AddSC_boss_epoch_hunter(); extern void AddSC_boss_lieutenant_drake(); extern void AddSC_instance_old_hillsbrad(); extern void AddSC_old_hillsbrad(); -extern void AddSC_culling_of_stratholme(); //Culling of Stratholme -extern void AddSC_instance_culling_of_stratholme(); extern void AddSC_boss_celebras_the_cursed(); //maraudon extern void AddSC_boss_landslide(); extern void AddSC_boss_noxxion(); @@ -235,10 +238,22 @@ extern void AddSC_boss_skeram(); extern void AddSC_boss_twinemperors(); extern void AddSC_mob_anubisath_sentinel(); extern void AddSC_instance_temple_of_ahnqiraj(); -extern void AddSC_instance_wailing_caverns(); // Wailing Caverns -extern void AddSC_zulfarrak(); //zulfarrak +extern void AddSC_instance_wailing_caverns(); // wailing_caverns +extern void AddSC_wailing_caverns(); +extern void AddSC_boss_zumrah(); // zulfarrak extern void AddSC_instance_zulfarrak(); +// culling of stratholme +extern void AddSC_boss_lord_epoch(); +extern void AddSC_boss_malganis(); +extern void AddSC_boss_meathook(); +extern void AddSC_boss_salramm(); +extern void AddSC_boss_infinite_corruptor(); +extern void AddSC_culling_of_stratholme(); +extern void AddSC_culling_of_stratholmeAI(); +extern void AddSC_instance_culling_of_stratholme(); +extern void AddSC_trash_culling_of_stratholme(); + extern void AddSC_ashenvale(); extern void AddSC_azshara(); extern void AddSC_azuremyst_isle(); @@ -263,7 +278,15 @@ extern void AddSC_ungoro_crater(); extern void AddSC_winterspring(); //northrend + +extern void AddSC_trial_of_the_champion(); //trial_of_the_champion +extern void AddSC_boss_argent_challenge(); +extern void AddSC_boss_black_knight(); +extern void AddSC_boss_grand_champions(); +extern void AddSC_instance_trial_of_the_champion(); + extern void AddSC_boss_jedoga(); //ahnkahet +extern void AddSC_boss_amanitar(); extern void AddSC_boss_nadox(); extern void AddSC_boss_taldaram(); extern void AddSC_boss_volazj(); @@ -272,13 +295,17 @@ extern void AddSC_boss_anubarak(); //azjol-nerub extern void AddSC_boss_hadronox(); extern void AddSC_boss_krikthir(); extern void AddSC_instance_azjol_nerub(); -extern void AddSC_boss_anubarak_trial(); //trial_of_the_crusader + +extern void AddSC_northrend_beasts(); //Crusaders' Coliseum, trial_of_the_crusader extern void AddSC_boss_jaraxxus(); +extern void AddSC_boss_anubarak_trial(); +extern void AddSC_boss_faction_champions(); +extern void AddSC_twin_valkyr(); extern void AddSC_instance_trial_of_the_crusader(); -extern void AddSC_northrend_beasts(); extern void AddSC_trial_of_the_crusader(); -extern void AddSC_twin_valkyr(); + extern void AddSC_boss_novos(); //draktharon_keep +extern void AddSC_boss_dred(); extern void AddSC_boss_tharonja(); extern void AddSC_boss_trollgore(); extern void AddSC_instance_draktharon_keep(); @@ -288,17 +315,18 @@ extern void AddSC_boss_galdarah(); extern void AddSC_boss_moorabi(); extern void AddSC_boss_sladran(); extern void AddSC_instance_gundrak(); -extern void AddSC_boss_bronjahm(); // ICC, forge_of_souls -extern void AddSC_boss_devourer_of_souls(); -extern void AddSC_instance_forge_of_souls(); -extern void AddSC_boss_gafrost(); // ICC, pit_of_saron + +extern void AddSC_boss_garfrost(); // ICC, pit_of_saron + extern void AddSC_boss_krick_and_ick(); extern void AddSC_boss_tyrannus(); extern void AddSC_instance_pit_of_saron(); extern void AddSC_pit_of_saron(); + extern void AddSC_boss_anubrekhan(); //naxxramas extern void AddSC_boss_four_horsemen(); extern void AddSC_boss_faerlina(); +extern void AddSC_boss_grobbulus(); extern void AddSC_boss_gluth(); extern void AddSC_boss_gothik(); extern void AddSC_boss_kelthuzad(); @@ -310,13 +338,30 @@ extern void AddSC_boss_patchwerk(); extern void AddSC_boss_razuvious(); extern void AddSC_boss_sapphiron(); extern void AddSC_instance_naxxramas(); + extern void AddSC_boss_anomalus(); //nexus extern void AddSC_boss_keristrasza(); extern void AddSC_boss_ormorok(); extern void AddSC_boss_telestra(); extern void AddSC_instance_nexus(); + +extern void AddSC_oculus(); //Oculus +extern void AddSC_instance_oculus(); +extern void AddSC_boss_drakos(); +extern void AddSC_boss_varos(); +extern void AddSC_boss_urom(); +extern void AddSC_boss_eregos(); + +extern void AddSC_boss_malygos(); //eye of eternity +extern void AddSC_instance_eye_of_eternity(); + extern void AddSC_boss_sartharion(); //obsidian_sanctum extern void AddSC_instance_obsidian_sanctum(); +extern void AddSC_instance_vault_of_archavon(); //vault_of_archavon +extern void AddSC_boss_toravon(); +extern void AddSC_boss_koralon(); +extern void AddSC_boss_emalon(); +extern void AddSC_boss_archavon(); extern void AddSC_boss_bjarngrim(); //Ulduar, halls_of_lightning extern void AddSC_boss_ionar(); extern void AddSC_boss_loken(); @@ -324,23 +369,26 @@ extern void AddSC_boss_volkhan(); extern void AddSC_instance_halls_of_lightning(); extern void AddSC_boss_maiden_of_grief(); //Ulduar, halls_of_stone extern void AddSC_boss_sjonnir(); +extern void AddSC_boss_krystallus(); extern void AddSC_halls_of_stone(); extern void AddSC_instance_halls_of_stone(); -extern void AddSC_boss_assembly_of_iron(); //ulduar -extern void AddSC_boss_algalon(); +extern void AddSC_boss_algalon(); //Ulduar raid extern void AddSC_boss_auriaya(); -extern void AddSC_boss_flame_leviathan(); extern void AddSC_boss_freya(); -extern void AddSC_boss_general_vezax(); extern void AddSC_boss_hodir(); extern void AddSC_boss_ignis(); +extern void AddSC_boss_iron_council(); extern void AddSC_boss_kologarn(); +extern void AddSC_boss_leviathan(); extern void AddSC_boss_mimiron(); extern void AddSC_boss_razorscale(); extern void AddSC_boss_thorim(); -extern void AddSC_boss_xt_002(); +extern void AddSC_boss_vezax(); +extern void AddSC_boss_xt002(); extern void AddSC_boss_yogg_saron(); extern void AddSC_instance_ulduar(); +extern void AddSC_ulduar(); +extern void AddSC_ulduar_teleport(); extern void AddSC_boss_ingvar(); //utgarde_keep extern void AddSC_boss_keleseth(); extern void AddSC_boss_skarvald_and_dalronn(); @@ -351,18 +399,60 @@ extern void AddSC_boss_skadi(); extern void AddSC_boss_svala(); extern void AddSC_boss_ymiron(); extern void AddSC_instance_pinnacle(); -extern void AddSC_instance_violet_hold(); //violet_hold -extern void AddSC_violet_hold(); extern void AddSC_borean_tundra(); extern void AddSC_dalaran(); extern void AddSC_dragonblight(); +extern void AddSC_grizzly_hills(); extern void AddSC_howling_fjord(); extern void AddSC_icecrown(); extern void AddSC_sholazar_basin(); extern void AddSC_storm_peaks(); extern void AddSC_zuldrak(); +extern void AddSC_instance_violet_hold(); +extern void AddSC_violet_hold(); +extern void AddSC_boss_cyanigosa(); +extern void AddSC_boss_moragg(); +extern void AddSC_boss_erekem(); +extern void AddSC_boss_xevozz(); +extern void AddSC_boss_ichoron(); +extern void AddSC_boss_zuramat(); +extern void AddSC_boss_lavanthor(); +//IceCrown Citadel +extern void AddSC_instance_icecrown_spire(); +extern void AddSC_icecrown_spire(); +extern void AddSC_icecrown_teleporter(); +extern void AddSC_boss_lord_marrowgar(); +extern void AddSC_boss_lady_deathwhisper(); +extern void AddSC_boss_deathbringer_saurfang(); +extern void AddSC_boss_rotface(); +extern void AddSC_boss_festergut(); +extern void AddSC_boss_proffesor_putricide(); +extern void AddSC_blood_prince_council(); +extern void AddSC_boss_blood_queen_lanathel(); +extern void AddSC_boss_valithria_dreamwalker(); +extern void AddSC_boss_sindragosa(); +extern void AddSC_boss_lich_king_icc(); + +extern void AddSC_instance_forge_of_souls(); +extern void AddSC_boss_devourer_of_souls(); +extern void AddSC_boss_bronjahm(); +extern void AddSC_forge_of_souls(); + +extern void AddSC_instance_halls_of_reflection(); +extern void AddSC_halls_of_reflection(); +extern void AddSC_boss_falric(); +extern void AddSC_boss_marwyn(); +extern void AddSC_boss_lich_king_hr(); + +extern void AddSC_instance_ruby_sanctum(); // Ruby Sanctum +extern void AddSC_ruby_sanctum(); +extern void AddSC_boss_halion(); +extern void AddSC_boss_ragefire(); +extern void AddSC_boss_zarithian(); +extern void AddSC_boss_baltharus(); + //outland extern void AddSC_boss_exarch_maladaar(); //auchindoun, auchenai_crypts extern void AddSC_boss_nexusprince_shaffar(); //auchindoun, mana_tombs @@ -448,6 +538,19 @@ void AddScripts() AddSC_battleground(); //custom + AddSC_npc_arena_honor(); + AddSC_mob_teleguy(); + + // OutdoorPvP zone scripts + // Must be _before_ map scripts call! + AddSC_outdoor_pvp_eastern_plaguelands(); + AddSC_outdoor_pvp_silithus(); + + // OutdoorPvP + AddSC_outdoor_pvp_eastern_kingdoms(); + AddSC_outdoor_pvp_kalimdor(); + AddSC_outdoor_pvp_northrend(); + AddSC_outdoor_pvp_outland(); //examples AddSC_example_creature(); @@ -493,8 +596,8 @@ void AddScripts() AddSC_boss_gyth(); AddSC_boss_rend_blackhand(); AddSC_instance_blackrock_spire(); - AddSC_boss_razorgore(); //blackwing_lair - AddSC_boss_vael(); + AddSC_boss_razorgore(); // blackwing_lair + AddSC_boss_vaelastrasz(); AddSC_boss_broodlord(); AddSC_boss_firemaw(); AddSC_boss_ebonroc(); @@ -551,15 +654,8 @@ void AddScripts() AddSC_instance_scarlet_monastery(); AddSC_boss_darkmaster_gandling(); //scholomance AddSC_boss_death_knight_darkreaver(); - AddSC_boss_theolenkrastinov(); - AddSC_boss_illuciabarov(); - AddSC_boss_instructormalicia(); AddSC_boss_jandicebarov(); AddSC_boss_kormok(); - AddSC_boss_lordalexeibarov(); - AddSC_boss_lorekeeperpolkelt(); - AddSC_boss_rasfrost(); - AddSC_boss_theravenian(); AddSC_boss_vectus(); AddSC_instance_scholomance(); AddSC_shadowfang_keep(); //shadowfang_keep @@ -651,8 +747,6 @@ void AddScripts() AddSC_boss_lieutenant_drake(); AddSC_instance_old_hillsbrad(); AddSC_old_hillsbrad(); - AddSC_culling_of_stratholme(); // Culling of Stratholme - AddSC_instance_culling_of_stratholme(); AddSC_boss_celebras_the_cursed(); //maraudon AddSC_boss_landslide(); AddSC_boss_noxxion(); @@ -675,8 +769,9 @@ void AddScripts() AddSC_boss_twinemperors(); AddSC_mob_anubisath_sentinel(); AddSC_instance_temple_of_ahnqiraj(); - AddSC_instance_wailing_caverns(); // Wailing Caverns - AddSC_zulfarrak(); //zulfarrak + AddSC_instance_wailing_caverns(); // wailing_caverns + AddSC_wailing_caverns(); + AddSC_boss_zumrah(); // zulfarrak AddSC_instance_zulfarrak(); AddSC_ashenvale(); @@ -703,7 +798,14 @@ void AddScripts() AddSC_winterspring(); //northrend + AddSC_trial_of_the_champion(); //trial_of_the_champion + AddSC_boss_argent_challenge(); + AddSC_boss_black_knight(); + AddSC_boss_grand_champions(); + AddSC_instance_trial_of_the_champion(); + AddSC_boss_jedoga(); //ahnkahet + AddSC_boss_amanitar(); AddSC_boss_nadox(); AddSC_boss_taldaram(); AddSC_boss_volazj(); @@ -712,13 +814,17 @@ void AddScripts() AddSC_boss_hadronox(); AddSC_boss_krikthir(); AddSC_instance_azjol_nerub(); - AddSC_boss_anubarak_trial(); //trial_of_the_crusader + + AddSC_northrend_beasts(); //Crusaders' Coliseum, trial_of_the_crusader AddSC_boss_jaraxxus(); + AddSC_boss_anubarak_trial(); + AddSC_boss_faction_champions(); + AddSC_twin_valkyr(); AddSC_instance_trial_of_the_crusader(); - AddSC_northrend_beasts(); AddSC_trial_of_the_crusader(); - AddSC_twin_valkyr(); + AddSC_boss_novos(); //draktharon_keep + AddSC_boss_dred(); AddSC_boss_tharonja(); AddSC_boss_trollgore(); AddSC_instance_draktharon_keep(); @@ -728,14 +834,14 @@ void AddScripts() AddSC_boss_moorabi(); AddSC_boss_sladran(); AddSC_instance_gundrak(); - AddSC_boss_bronjahm(); // ICC, forge_of_souls - AddSC_boss_devourer_of_souls(); - AddSC_instance_forge_of_souls(); - AddSC_boss_gafrost(); // ICC, pit_of_saron + + AddSC_boss_garfrost(); // ICC, FH, pit_of_saron + AddSC_boss_krick_and_ick(); AddSC_boss_tyrannus(); AddSC_instance_pit_of_saron(); AddSC_pit_of_saron(); + AddSC_boss_anubrekhan(); //naxxramas AddSC_boss_four_horsemen(); AddSC_boss_faerlina(); @@ -745,18 +851,36 @@ void AddScripts() AddSC_boss_loatheb(); AddSC_boss_maexxna(); AddSC_boss_noth(); + AddSC_boss_grobbulus(); AddSC_boss_heigan(); AddSC_boss_patchwerk(); AddSC_boss_razuvious(); AddSC_boss_sapphiron(); AddSC_instance_naxxramas(); + AddSC_boss_anomalus(); //nexus AddSC_boss_keristrasza(); AddSC_boss_ormorok(); AddSC_boss_telestra(); AddSC_instance_nexus(); + + AddSC_oculus(); //Oculus + AddSC_instance_oculus(); + AddSC_boss_drakos(); + AddSC_boss_varos(); + AddSC_boss_urom(); + AddSC_boss_eregos(); + + AddSC_boss_malygos(); //eye of eternity + AddSC_instance_eye_of_eternity(); + AddSC_boss_sartharion(); //obsidian_sanctum AddSC_instance_obsidian_sanctum(); + AddSC_instance_vault_of_archavon(); //vault_of_archavon + AddSC_boss_toravon(); + AddSC_boss_koralon(); + AddSC_boss_emalon(); + AddSC_boss_archavon(); AddSC_boss_bjarngrim(); //Ulduar, halls_of_lightning AddSC_boss_ionar(); AddSC_boss_loken(); @@ -764,23 +888,26 @@ void AddScripts() AddSC_instance_halls_of_lightning(); AddSC_boss_maiden_of_grief(); //Ulduar, halls_of_stone AddSC_boss_sjonnir(); + AddSC_boss_krystallus(); AddSC_halls_of_stone(); AddSC_instance_halls_of_stone(); - AddSC_boss_assembly_of_iron(); //ulduar - AddSC_boss_algalon(); + AddSC_boss_algalon(); //Ulduar AddSC_boss_auriaya(); - AddSC_boss_flame_leviathan(); AddSC_boss_freya(); - AddSC_boss_general_vezax(); AddSC_boss_hodir(); AddSC_boss_ignis(); + AddSC_boss_iron_council(); AddSC_boss_kologarn(); + AddSC_boss_leviathan(); AddSC_boss_mimiron(); AddSC_boss_razorscale(); AddSC_boss_thorim(); - AddSC_boss_xt_002(); + AddSC_boss_vezax(); + AddSC_boss_xt002(); AddSC_boss_yogg_saron(); AddSC_instance_ulduar(); + AddSC_ulduar(); + AddSC_ulduar_teleport(); AddSC_boss_ingvar(); //utgarde_keep AddSC_boss_keleseth(); AddSC_boss_skarvald_and_dalronn(); @@ -791,18 +918,60 @@ void AddScripts() AddSC_boss_svala(); AddSC_boss_ymiron(); AddSC_instance_pinnacle(); - AddSC_instance_violet_hold(); //violet_hold - AddSC_violet_hold(); AddSC_borean_tundra(); AddSC_dalaran(); AddSC_dragonblight(); + AddSC_grizzly_hills(); AddSC_howling_fjord(); AddSC_icecrown(); AddSC_sholazar_basin(); AddSC_storm_peaks(); AddSC_zuldrak(); + AddSC_instance_violet_hold(); + AddSC_boss_cyanigosa(); + AddSC_boss_moragg(); + AddSC_boss_erekem(); + AddSC_boss_xevozz(); + AddSC_boss_ichoron(); + AddSC_boss_zuramat(); + AddSC_boss_lavanthor(); + AddSC_violet_hold(); + + AddSC_instance_icecrown_spire(); + AddSC_icecrown_spire(); + AddSC_icecrown_teleporter(); + AddSC_boss_lord_marrowgar(); + AddSC_boss_lady_deathwhisper(); + AddSC_boss_deathbringer_saurfang(); + AddSC_boss_rotface(); + AddSC_boss_festergut(); + AddSC_boss_proffesor_putricide(); + AddSC_blood_prince_council(); + AddSC_boss_blood_queen_lanathel(); + AddSC_boss_valithria_dreamwalker(); + AddSC_boss_sindragosa(); + AddSC_boss_lich_king_icc(); + + AddSC_instance_forge_of_souls(); + AddSC_boss_devourer_of_souls(); + AddSC_boss_bronjahm(); + AddSC_forge_of_souls(); + + AddSC_instance_halls_of_reflection(); + AddSC_halls_of_reflection(); + AddSC_boss_falric(); + AddSC_boss_marwyn(); + AddSC_boss_lich_king_hr(); + + AddSC_instance_ruby_sanctum(); // Ruby Sanctum + AddSC_ruby_sanctum(); + AddSC_boss_halion(); + AddSC_boss_ragefire(); + AddSC_boss_zarithian(); + AddSC_boss_baltharus(); + //outland AddSC_boss_exarch_maladaar(); //auchindoun, auchenai_crypts AddSC_boss_nexusprince_shaffar(); //auchindoun, mana_tombs @@ -871,6 +1040,16 @@ void AddScripts() AddSC_boss_pathaleon_the_calculator(); AddSC_instance_mechanar(); + AddSC_boss_lord_epoch(); //culling of stratholme + AddSC_boss_malganis(); + AddSC_boss_meathook(); + AddSC_boss_salramm(); + AddSC_boss_infinite_corruptor(); + AddSC_culling_of_stratholme(); + AddSC_culling_of_stratholmeAI(); + AddSC_instance_culling_of_stratholme(); + AddSC_trash_culling_of_stratholme(); + AddSC_blades_edge_mountains(); AddSC_boss_doomlordkazzak(); AddSC_boss_doomwalker(); diff --git a/system/ScriptLoader.h b/system/ScriptLoader.h index 3414f7f83..2241d289c 100644 --- a/system/ScriptLoader.h +++ b/system/ScriptLoader.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/system/system.cpp b/system/system.cpp index 244f69beb..4bc26c6f9 100644 --- a/system/system.cpp +++ b/system/system.cpp @@ -1,9 +1,10 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ #include "precompiled.h" #include "system.h" +#include "../config.h" #include "ProgressBar.h" #include "ObjectMgr.h" #include "Database/DatabaseEnv.h" @@ -32,16 +33,19 @@ void SystemMgr::LoadVersion() strSD2Version = pFields[0].GetCppString(); - outstring_log("Loading %s", strSD2Version.c_str()); - outstring_log(""); - delete pResult; } else - { error_log("SD2: Missing `sd2_db_version` information."); - outstring_log(""); - } + + // Setup version info and display it + if (strSD2Version.empty()) + strSD2Version.append("ScriptDev2 "); + + strSD2Version.append(_FULLVERSION); + + outstring_log("Loading %s", strSD2Version.c_str()); + outstring_log(""); } void SystemMgr::LoadScriptTexts() diff --git a/system/system.h b/system/system.h index c0f3be7bf..f2f29f76d 100644 --- a/system/system.h +++ b/system/system.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ @@ -6,7 +6,7 @@ #define SC_SYSTEM_H extern DatabaseType SD2Database; -extern std::string strSD2Version; //version info from database +extern std::string strSD2Version; //version info: database entry and revision #define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available diff --git a/tool/git_id/.gitignore b/tool/git_id/.gitignore new file mode 100644 index 000000000..a088f5bb5 --- /dev/null +++ b/tool/git_id/.gitignore @@ -0,0 +1,20 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# NOTE! Please use 'git-ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# +# Extractor generated files at Windows build +# + +*.bsc +*.pdb +*.ncb +*.sdf +*.opensdf +*.user +Debug +Release diff --git a/tool/git_id/CMakeLists.txt b/tool/git_id/CMakeLists.txt new file mode 100644 index 000000000..b5a14ac1b --- /dev/null +++ b/tool/git_id/CMakeLists.txt @@ -0,0 +1,3 @@ +SET(CMAKE_VERBOSE_MAKEFILE ON) +cmake_minimum_required (VERSION 2.6) +ADD_EXECUTABLE (git_id git_id.cpp) diff --git a/tool/git_id/git_id.cpp b/tool/git_id/git_id.cpp new file mode 100644 index 000000000..f8b43483f --- /dev/null +++ b/tool/git_id/git_id.cpp @@ -0,0 +1,936 @@ +/* + * Copyright (C) 2005-2011 MaNGOS + * Copyright (C) 2005-2011 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 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#define popen _popen +#define pclose _pclose +#define snprintf _snprintf +#define putenv _putenv +#pragma warning (disable:4996) +#else +#include +#endif + +// max string sizes + +#define MAX_REMOTE 256 +#define MAX_MSG 16384 +#define MAX_PATH 2048 +#define MAX_BUF 2048 +#define MAX_CMD 2048 +#define MAX_HASH 256 +#define MAX_DB 256 + +// config + +#define NUM_REMOTES 2 +#define NUM_DATABASES 2 + +char remotes[NUM_REMOTES][MAX_REMOTE] = { + "git@github.com:scriptdev2/scriptdev2.git", + "git://github.com/scriptdev2/scriptdev2.git" // used for fetch if present +}; + +char remote_branch[MAX_REMOTE] = "master"; +char rev_nr_file[MAX_PATH] = "sd2_revision_nr.h"; +char rev_sql_file[MAX_PATH] = "sd2_revision_sql.h"; +char sql_update_dir[MAX_PATH] = "sql/updates"; +char new_index_file[MAX_PATH] = ".git/git_id_index"; + +char databases[NUM_DATABASES][MAX_DB] = { + "scriptdev2", + "mangos" +}; + +char db_version_table[NUM_DATABASES][MAX_DB] = { + "sd2_db_version", + "db_version", +}; + +char db_sql_file[NUM_DATABASES][MAX_PATH] = { + "sql/scriptdev2_script_full.sql", + "sql/mangos_scriptname_full.sql", +}; + +char db_sql_rev_field[NUM_DATABASES][MAX_PATH] = { + "REVISION_DB_SCRIPTDEV2", + "REVISION_DB_SD2_MANGOS", +}; + +bool db_sql_rev_parent[NUM_DATABASES] = { + true, + true +}; + +#define SQL_REV_PREFIX "r" +#define SQL_REV_SCAN SQL_REV_PREFIX "%d" +#define SQL_REV_PRINT SQL_REV_PREFIX "%04d" +#define GIT_REV_PREFIX "" +#define GIT_REV_PRINT GIT_REV_PREFIX "%04d" +#define GIT_REV_FORMAT "[" GIT_REV_PRINT "]" + +bool allow_replace = false; +bool local = false; +bool do_fetch = false; +bool do_sql = false; +bool use_new_index = true; +bool generate_makefile = false; // not need for cmake build systems +// aux + +char origins[NUM_REMOTES][MAX_REMOTE]; +int rev; +int last_sql_rev[NUM_DATABASES] = {0,0}; +int last_sql_nr[NUM_DATABASES] = {0,0}; + +char head_message[MAX_MSG]; +char path_prefix[MAX_PATH] = ""; +char base_path[MAX_PATH]; +char buffer[MAX_BUF]; +char cmd[MAX_CMD]; +char origin_hash[MAX_HASH]; +char last_sql_update[NUM_DATABASES][MAX_PATH]; +char old_index_cmd[MAX_CMD]; +char new_index_cmd[MAX_CMD]; + +std::set new_sql_updates; + +FILE *cmd_pipe; + +bool find_path() +{ + printf("+ finding path\n"); + char *ptr; + char cur_path[MAX_PATH]; + getcwd(cur_path, MAX_PATH); + size_t len = strlen(cur_path); + strncpy(base_path, cur_path, len+1); + + if(cur_path[len-1] == '/' || cur_path[len-1] == '\\') + { + // we're in root, don't bother + return false; + } + + // don't count the root + int count_fwd = 0, count_back = 0; + for(ptr = cur_path-1; ptr = strchr(ptr+1, '/'); count_fwd++); + for(ptr = cur_path-1; ptr = strchr(ptr+1, '\\'); count_back++); + int count = std::max(count_fwd, count_back); + + char path[MAX_PATH]; + for(int i = 0; i < count; i++) + { + snprintf(path, MAX_PATH, "%s.git", path_prefix); + if(0 == chdir(path)) + { + chdir(cur_path); + return true; + } + strncat(path_prefix, "../", MAX_PATH); + + ptr = strrchr(base_path, '\\'); + if(ptr) *ptr = '\0'; + else + { + ptr = strrchr(base_path, '/'); + if(ptr) *ptr = '\0'; + } + } + + return false; +} + +bool find_origin() +{ + printf("+ finding origin\n"); + if( (cmd_pipe = popen( "git remote -v", "r" )) == NULL ) + return false; + + bool ret = false; + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + char name[256], remote[MAX_REMOTE]; + sscanf(buffer, "%s %s", name, remote); + for(int i = 0; i < NUM_REMOTES; i++) + { + if(strcmp(remote, remotes[i]) == 0) + { + strncpy(origins[i], name, MAX_REMOTE); + ret = true; + } + } + } + pclose(cmd_pipe); + return ret; +} + +bool fetch_origin() +{ + printf("+ fetching origin\n"); + // use the public clone url if present because the private may require a password + snprintf(cmd, MAX_CMD, "git fetch %s %s", (origins[1][0] ? origins[1] : origins[0]), remote_branch); + int ret = system(cmd); + return true; +} + +bool check_fwd() +{ + printf("+ checking fast forward\n"); + snprintf(cmd, MAX_CMD, "git log -n 1 --pretty=\"format:%%H\" %s/%s", (origins[1][0] ? origins[1] : origins[0]), remote_branch); + if( (cmd_pipe = popen( cmd, "r" )) == NULL ) + return false; + + if(!fgets(buffer, MAX_BUF, cmd_pipe)) return false; + strncpy(origin_hash, buffer, MAX_HASH); + pclose(cmd_pipe); + + if( (cmd_pipe = popen( "git log --pretty=\"format:%H\"", "r" )) == NULL ) + return false; + + bool found = false; + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + buffer[strlen(buffer) - 1] = '\0'; + if(strncmp(origin_hash, buffer, MAX_BUF) == 0) + { + found = true; + break; + } + } + pclose(cmd_pipe); + + if(!found) + { + // with fetch you still get the latest rev, you just rebase afterwards and push + // without it you may not get the right rev + if(do_fetch) printf("WARNING: non-fastforward, use rebase!\n"); + else { printf("ERROR: non-fastforward, use rebase!\n"); return false; } + } + return true; +} + +int get_rev(const char *from_msg) +{ + // accept only the rev number format, not the sql update format + char nr_str[256]; + if(sscanf(from_msg, "[" GIT_REV_PREFIX "%[0123456789]]", nr_str) != 1) return 0; + // ("[")+(REV_PREFIX)+("]")-1 + if(from_msg[strlen(nr_str)+strlen(GIT_REV_PREFIX)+2-1] != ']') return 0; + + return atoi(nr_str); +} + +bool find_rev() +{ + printf("+ finding next revision number\n"); + // find the highest rev number on either of the remotes + for(int i = 0; i < NUM_REMOTES; i++) + { + if(!local && !origins[i][0]) continue; + + if(local) snprintf(cmd, MAX_CMD, "git log HEAD --pretty=\"format:%%s\""); + else sprintf(cmd, "git log %s/%s --pretty=\"format:%%s\"", origins[i], remote_branch); + if( (cmd_pipe = popen( cmd, "r" )) == NULL ) + continue; + + int nr; + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + nr = get_rev(buffer); + if(nr >= rev) + rev = nr+1; + } + pclose(cmd_pipe); + } + + if(rev > 0) printf("Found " GIT_REV_FORMAT ".\n", rev); + + return rev > 0; +} + +std::string generateNrHeader(char const* rev_str) +{ + std::ostringstream newData; + newData << "#ifndef __SD2_REVISION_NR_H__" << std::endl; + newData << "#define __SD2_REVISION_NR_H__" << std::endl; + newData << " #define SD2_REVISION_NR \"" << rev_str << "\"" << std::endl; + newData << "#endif // __SD2_REVISION_NR_H__" << std::endl; + return newData.str(); +} + +std::string generateSqlHeader() +{ + std::ostringstream newData; + newData << "#ifndef __SD2_REVISION_SQL_H__" << std::endl; + newData << "#define __SD2_REVISION_SQL_H__" << std::endl; + for(int i = 0; i < NUM_DATABASES; ++i) + { + newData << " #define " << db_sql_rev_field[i] << " \"required_" << last_sql_update[i] << "\"" << std::endl; + } + newData << "#endif // __SD2_REVISION_SQL_H__" << std::endl; + return newData.str(); +} + +void system_switch_index(const char *cmd) +{ + // do the command for the original index and then for the new index + // both need to be updated with the changes before commit + // but the new index will contains only the desired changes + // while the old may contain others + system(cmd); + if(!use_new_index) return; + if(putenv(new_index_cmd) != 0) return; + system(cmd); + if(putenv(old_index_cmd) != 0) return; +} + +bool write_rev_nr() +{ + printf("+ writing sd2_revision_nr.h\n"); + char rev_str[256]; + sprintf(rev_str, "%04d", rev); + std::string header = generateNrHeader(rev_str); + + char prefixed_file[MAX_PATH]; + snprintf(prefixed_file, MAX_PATH, "%s%s", path_prefix, rev_nr_file); + + if(FILE* OutputFile = fopen(prefixed_file, "wb")) + { + fprintf(OutputFile,"%s", header.c_str()); + fclose(OutputFile); + + // add the file to both indices, to be committed later + snprintf(cmd, MAX_CMD, "git add %s", prefixed_file); + system_switch_index(cmd); + + return true; + } + + return false; +} + +bool write_rev_sql() +{ + if(new_sql_updates.empty()) return true; + printf("+ writing sd2_revision_sql.h\n"); + std::string header = generateSqlHeader(); + + char prefixed_file[MAX_PATH]; + snprintf(prefixed_file, MAX_PATH, "%s%s", path_prefix, rev_sql_file); + + if(FILE* OutputFile = fopen(prefixed_file, "wb")) + { + fprintf(OutputFile,"%s", header.c_str()); + fclose(OutputFile); + + // add the file to both indices, to be committed later + snprintf(cmd, MAX_CMD, "git add %s", prefixed_file); + system_switch_index(cmd); + + return true; + } + + return false; +} + +bool find_head_msg() +{ + printf("+ finding last message on HEAD\n"); + if( (cmd_pipe = popen( "git log -n 1 --pretty=\"format:%s%n%n%b\"", "r" )) == NULL ) + return false; + + int poz = 0; + while(poz < 16384-1 && EOF != (head_message[poz++] = fgetc(cmd_pipe))); + head_message[poz-1] = '\0'; + + pclose(cmd_pipe); + + if(int head_rev = get_rev(head_message)) + { + if(!allow_replace) + { + printf("Last commit on HEAD is " GIT_REV_FORMAT ". Use -r to replace it with " GIT_REV_FORMAT ".\n", head_rev, rev); + return false; + } + + // skip the rev number in the commit + char *p = strchr(head_message, ']'), *q = head_message; + assert(p && *(p+1)); + p+=2; + while(*p) *q = *p, p++, q++; + *q = 0; + return true; + } + + return true; +} + +bool amend_commit() +{ + printf("+ amending last commit\n"); + + // commit the contents of the (new) index + if(use_new_index && putenv(new_index_cmd) != 0) return false; + snprintf(cmd, MAX_CMD, "git commit --amend -F-"); + if( (cmd_pipe = popen( cmd, "w" )) == NULL ) + return false; + + fprintf(cmd_pipe, GIT_REV_FORMAT " %s", rev, head_message); + pclose(cmd_pipe); + if(use_new_index && putenv(old_index_cmd) != 0) return false; + + return true; +} + +struct sql_update_info +{ + int rev; +// char parentRev[MAX_BUF]; + int nr; + int db_idx; + char db[MAX_BUF]; + char table[MAX_BUF]; + bool has_table; +}; + +bool get_sql_update_info(const char *buffer, sql_update_info &info) +{ + info.table[0] = '\0'; + int dummy[2]; + char dummyStr[MAX_BUF]; + if(sscanf(buffer, SQL_REV_SCAN "_%[^_]_%d_%d", &dummy[0], &dummyStr, &dummy[1]) == 3) + return false; + + if(sscanf(buffer, SQL_REV_SCAN "_%[^.].sql", &info.rev, info.db) != 2) + { + return false; + } + + for(info.db_idx = 0; info.db_idx < NUM_DATABASES; info.db_idx++) + if(strncmp(info.db, databases[info.db_idx], MAX_DB) == 0) break; + info.has_table = (info.table[0] != '\0'); + return true; +} + +bool find_sql_updates() +{ + printf("+ finding new sql updates on HEAD\n"); + // add all updates from HEAD + snprintf(cmd, MAX_CMD, "git show HEAD:%s", sql_update_dir); + if( (cmd_pipe = popen( cmd, "r" )) == NULL ) + return false; + + // skip first two lines + if(!fgets(buffer, MAX_BUF, cmd_pipe)) { pclose(cmd_pipe); return false; } + if(!fgets(buffer, MAX_BUF, cmd_pipe)) { pclose(cmd_pipe); return false; } + + sql_update_info info; + + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + buffer[strlen(buffer) - 1] = '\0'; + if(!get_sql_update_info(buffer, info)) continue; + + if(info.db_idx == NUM_DATABASES) + { + if(info.rev > 0) printf("WARNING: incorrect database name for sql update %s\n", buffer); + continue; + } + + new_sql_updates.insert(buffer); + } + + pclose(cmd_pipe); + + // remove updates from the last commit also found on origin + snprintf(cmd, MAX_CMD, "git show %s:%s", origin_hash, sql_update_dir); + if( (cmd_pipe = popen( cmd, "r" )) == NULL ) + return false; + + // skip first two lines + if(!fgets(buffer, MAX_BUF, cmd_pipe)) { pclose(cmd_pipe); return false; } + if(!fgets(buffer, MAX_BUF, cmd_pipe)) { pclose(cmd_pipe); return false; } + + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + buffer[strlen(buffer) - 1] = '\0'; + if(!get_sql_update_info(buffer, info)) continue; + + // find the old update with the highest rev for each database + // (will be the required version for the new update) + std::set::iterator itr = new_sql_updates.find(buffer); + if(itr != new_sql_updates.end() ) + { + if(info.rev > 0 && (info.rev > last_sql_rev[info.db_idx] || + (info.rev == last_sql_rev[info.db_idx] && info.nr > last_sql_nr[info.db_idx]))) + { + last_sql_rev[info.db_idx] = info.rev; + last_sql_nr[info.db_idx] = info.nr; + if(db_sql_rev_parent[info.db_idx]) + snprintf(last_sql_update[info.db_idx], MAX_PATH, "_%s%s%s", info.db, info.has_table ? "_" : "", info.table); + else + sscanf(buffer, "%[^.]", last_sql_update[info.db_idx]); + } + new_sql_updates.erase(itr); + } + } + + pclose(cmd_pipe); + + if(!new_sql_updates.empty()) + { + for(std::set::iterator itr = new_sql_updates.begin(); itr != new_sql_updates.end(); ++itr) + printf("%s\n", itr->c_str()); + } + else + printf("WARNING: no new sql updates found.\n"); + + return true; +} + +bool copy_file(const char *src_file, const char *dst_file) +{ + FILE * fin = fopen( src_file, "rb" ); + if(!fin) return false; + FILE * fout = fopen( dst_file, "wb" ); + if(!fout) { fclose(fin); return false; } + + for(char c = getc(fin); !feof(fin); putc(c, fout), c = getc(fin)); + + fclose(fin); + fclose(fout); + return true; +} + +bool convert_sql_updates() +{ + if(new_sql_updates.empty()) return true; + + printf("+ converting sql updates\n"); + + // rename the sql update files and add the required update statement + for(std::set::iterator itr = new_sql_updates.begin(); itr != new_sql_updates.end(); ++itr) + { + sql_update_info info; + if(!get_sql_update_info(itr->c_str(), info)) return false; + if(info.db_idx == NUM_DATABASES) return false; + + // generating the new name should work for updates with or without a rev + char src_file[MAX_PATH], new_name[MAX_PATH], new_req_name[MAX_PATH], dst_file[MAX_PATH]; + snprintf(src_file, MAX_PATH, "%s%s/%s", path_prefix, sql_update_dir, itr->c_str()); + snprintf(new_name, MAX_PATH, SQL_REV_PRINT "_%s%s%s", rev, info.db, info.has_table ? "_" : "", info.table); + snprintf(dst_file, MAX_PATH, "%s%s/%s.sql", path_prefix, sql_update_dir, new_name); + + if(db_sql_rev_parent[info.db_idx]) + snprintf(new_req_name, MAX_PATH, "_%s%s%s", info.db, info.has_table ? "_" : "", info.table); + else + strncpy(new_req_name, new_name, MAX_PATH); + + FILE * fin = fopen( src_file, "r" ); + if(!fin) return false; + + std::ostringstream out_buff; + + // add the update requirements for non-parent-controlled revision sql update + if(!db_sql_rev_parent[info.db_idx]) + { + // add the update requirements + out_buff << "ALTER TABLE " << db_version_table[info.db_idx] + << " CHANGE COLUMN required_" << last_sql_update[info.db_idx] + << " required_" << new_name << " bit;\n\n"; + + // skip the first one or two lines from the input + // if it already contains update requirements + if(fgets(buffer, MAX_BUF, fin)) + { + char dummy[MAX_BUF]; + if(sscanf(buffer, "ALTER TABLE %s CHANGE COLUMN required_%s required_%s bit", dummy, dummy, dummy) == 3) + { + if(fgets(buffer, MAX_BUF, fin) && buffer[0] != '\n') + out_buff << buffer; + } + else + out_buff << buffer; + } + } + + // copy the rest of the file + while(fgets(buffer, MAX_BUF, fin)) + out_buff << buffer; + + fclose(fin); + + FILE * fout = fopen( dst_file, "w" ); + if(!fout) { fclose(fin); return false; } + + fprintf(fout, "%s",out_buff.str().c_str()); + + fclose(fout); + + // rename the file in git + snprintf(cmd, MAX_CMD, "git add %s", dst_file); + system_switch_index(cmd); + + // delete src file if it different by name from dst file + if(strncmp(src_file,dst_file,MAX_PATH)) + { + snprintf(cmd, MAX_CMD, "git rm --quiet %s", src_file); + system_switch_index(cmd); + } + + // update the last sql update for the current database + strncpy(last_sql_update[info.db_idx], new_req_name, MAX_PATH); + } + + return true; +} + +bool generate_sql_makefile() +{ + if(new_sql_updates.empty()) return true; + + // find all files in the update dir + snprintf(cmd, MAX_CMD, "git show HEAD:%s", sql_update_dir); + if( (cmd_pipe = popen( cmd, "r" )) == NULL ) + return false; + + // skip first two lines + if(!fgets(buffer, MAX_BUF, cmd_pipe)) { pclose(cmd_pipe); return false; } + if(!fgets(buffer, MAX_BUF, cmd_pipe)) { pclose(cmd_pipe); return false; } + + char newname[MAX_PATH]; + std::set file_list; + sql_update_info info; + + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + buffer[strlen(buffer) - 1] = '\0'; + if(buffer[strlen(buffer) - 1] != '/' && + strncmp(buffer, "Makefile.am", MAX_BUF) != 0) + { + if(new_sql_updates.find(buffer) != new_sql_updates.end()) + { + if(!get_sql_update_info(buffer, info)) return false; + snprintf(newname, MAX_PATH, SQL_REV_PRINT "_%s%s%s.sql", rev, info.db, info.has_table ? "_" : "", info.table); + file_list.insert(newname); + } + else + file_list.insert(buffer); + } + } + + pclose(cmd_pipe); + + // write the makefile + char file_name[MAX_PATH]; + snprintf(file_name, MAX_PATH, "%s%s/Makefile.am", path_prefix, sql_update_dir); + FILE *fout = fopen(file_name, "w"); + if(!fout) { pclose(cmd_pipe); return false; } + + fprintf(fout, + "# Copyright (C) 2005-2011 ScriptDev2 \n" + "#\n" + "# This program is free software; you can redistribute it and/or modify\n" + "# it under the terms of the GNU General Public License as published by\n" + "# the Free Software Foundation; either version 2 of the License, or\n" + "# (at your option) any later version.\n" + "#\n" + "# This program is distributed in the hope that it will be useful,\n" + "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "# GNU General Public License for more details.\n" + "#\n" + "# You should have received a copy of the GNU General Public License\n" + "# along with this program; if not, write to the Free Software\n" + "# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" + "\n" + "## Process this file with automake to produce Makefile.in\n" + "\n" + "## Sub-directories to parse\n" + "\n" + "## Change installation location\n" + "# datadir = ScriptDev2/%s\n" + "pkgdatadir = $(datadir)/ScriptDev2/%s\n" + "\n" + "## Files to be installed\n" + "# Install basic SQL files to datadir\n" + "pkgdata_DATA = \\\n", + sql_update_dir, sql_update_dir + ); + + for(std::set::iterator itr = file_list.begin(), next; itr != file_list.end(); ++itr) + { + next = itr; ++next; + fprintf(fout, "\t%s%s\n", itr->c_str(), next == file_list.end() ? "" : " \\"); + } + + fclose(fout); + + snprintf(cmd, MAX_CMD, "git add %s%s/Makefile.am", path_prefix, sql_update_dir); + system_switch_index(cmd); + + return true; +} + +bool change_sql_database() +{ + if(new_sql_updates.empty()) return true; + printf("+ changing database sql files\n"); + + // rename the database files, copy their contents back + // and change the required update line + for(int i = 0; i < NUM_DATABASES; i++) + { + if(last_sql_update[i][0] == '\0') continue; + + char old_file[MAX_PATH], tmp_file[MAX_PATH], dummy[MAX_BUF]; + + snprintf(old_file, MAX_PATH, "%s%s", path_prefix, db_sql_file[i]); + snprintf(tmp_file, MAX_PATH, "%s%stmp", path_prefix, db_sql_file[i]); + + rename(old_file, tmp_file); + + FILE *fin = fopen( tmp_file, "r" ); + if(!fin) return false; + FILE *fout = fopen( old_file, "w" ); + if(!fout) return false; + + snprintf(dummy, MAX_CMD, "CREATE TABLE `%s` (\n", db_version_table[i]); + while(fgets(buffer, MAX_BUF, fin)) + { + fputs(buffer, fout); + if(strncmp(buffer, dummy, MAX_BUF) == 0) + break; + } + + while(1) + { + if(!fgets(buffer, MAX_BUF, fin)) return false; + if(sscanf(buffer, " `required_%s`", dummy) == 1) break; + fputs(buffer, fout); + } + + fprintf(fout, " `required_%s` bit(1) default NULL\n", last_sql_update[i]); + + while(fgets(buffer, MAX_BUF, fin)) + fputs(buffer, fout); + + fclose(fin); + fclose(fout); + remove(tmp_file); + + snprintf(cmd, MAX_CMD, "git add %s", old_file); + system_switch_index(cmd); + } + return true; +} + +bool change_sql_history() +{ + snprintf(cmd, MAX_CMD, "git log HEAD --pretty=\"format:%%H\""); + if( (cmd_pipe = popen( cmd, "r" )) == NULL ) + return false; + + std::list hashes; + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + buffer[strlen(buffer) - 1] = '\0'; + if(strncmp(origin_hash, buffer, MAX_HASH) == 0) + break; + + hashes.push_back(buffer); + } + pclose(cmd_pipe); + if(hashes.empty()) return false; // must have at least one commit + if(hashes.size() < 2) return true; // only one commit, ok but nothing to do + + snprintf(cmd, MAX_CMD, "git reset --hard %s", origin_hash); + system(cmd); + + for(std::list::reverse_iterator next = hashes.rbegin(), itr = next++; next != hashes.rend(); ++itr, ++next) + { + // stage the changes from the orignal commit + snprintf(cmd, MAX_CMD, "git cherry-pick -n %s", itr->c_str()); + system(cmd); + + // remove changed and deleted files + snprintf(cmd, MAX_CMD, "git checkout HEAD %s%s", path_prefix, sql_update_dir); + system(cmd); + + // remove the newly added files + snprintf(cmd, MAX_CMD, "git diff --cached --diff-filter=A --name-only %s%s", path_prefix, sql_update_dir); + if( (cmd_pipe = popen( cmd, "r" )) == NULL ) + return false; + + while(fgets(buffer, MAX_BUF, cmd_pipe)) + { + buffer[strlen(buffer) - 1] = '\0'; + snprintf(cmd, MAX_CMD, "git rm -f --quiet %s%s", path_prefix, buffer); + system(cmd); + } + + pclose(cmd_pipe); + + // make a commit with the same author and message as the original one + + snprintf(cmd, MAX_CMD, "git commit -C %s", itr->c_str()); + system(cmd); + } + + snprintf(cmd, MAX_CMD, "git cherry-pick %s", hashes.begin()->c_str()); + system(cmd); + + return true; +} + +bool prepare_new_index() +{ + if(!use_new_index) return true; + + // only use a new index if there are staged changes that should be preserved + if( (cmd_pipe = popen( "git diff --cached", "r" )) == NULL ) { + use_new_index = false; + return false; + } + + if(!fgets(buffer, MAX_BUF, cmd_pipe)) + { + use_new_index = false; + pclose(cmd_pipe); + return true; + } + + pclose(cmd_pipe); + + printf("+ preparing new index\n"); + + // copy the existing index file to a new one + char src_file[MAX_PATH], dst_file[MAX_PATH]; + + char *old_index = getenv("GIT_INDEX_FILE"); + if(old_index) strncpy(src_file, old_index, MAX_PATH); + else snprintf(src_file, MAX_PATH, "%s.git/index", path_prefix); + snprintf(dst_file, MAX_PATH, "%s%s", path_prefix, new_index_file); + + if(!copy_file(src_file, dst_file)) return false; + + // doesn't seem to work with path_prefix + snprintf(new_index_cmd, MAX_CMD, "GIT_INDEX_FILE=%s/%s", base_path, new_index_file); + if(putenv(new_index_cmd) != 0) return false; + + // clear the new index + system("git reset -q --mixed HEAD"); + + // revert to old index + snprintf(old_index_cmd, MAX_CMD, "GIT_INDEX_FILE="); + if(putenv(old_index_cmd) != 0) return false; + return true; +} + +bool cleanup_new_index() +{ + if(!use_new_index) return true; + printf("+ cleaning up the new index\n"); + char idx_file[MAX_PATH]; + snprintf(idx_file, MAX_PATH, "%s%s", path_prefix, new_index_file); + remove(idx_file); + return true; +} + +#define DO(cmd) if(!cmd) { printf("FAILED\n"); return 1; } + +int main(int argc, char *argv[]) +{ + for(int i = 1; i < argc; i++) + { + if(argv[i] == NULL) continue; + if(strncmp(argv[i], "-r", 2) == 0 || strncmp(argv[i], "--replace", 9) == 0) + allow_replace = true; + else if(strncmp(argv[i], "-l", 2) == 0 || strncmp(argv[i], "--local", 7) == 0) + local = true; + else if(strncmp(argv[i], "-f", 2) == 0 || strncmp(argv[i], "--fetch", 7) == 0) + do_fetch = true; + else if(strncmp(argv[i], "-s", 2) == 0 || strncmp(argv[i], "--sql", 5) == 0) + do_sql = true; + else if(strncmp(argv[i], "--branch=", 9) == 0) + snprintf(remote_branch, MAX_REMOTE, "%s", argv[i] + 9); + else if(strncmp(argv[i], "-h", 2) == 0 || strncmp(argv[i], "--help", 6) == 0) + { + printf("Usage: git_id [OPTION]\n"); + printf("Generates a new rev number and updates sd2_revision_nr.h and the commit message.\n"); + printf("Should be used just before push.\n"); + printf(" -h, --help show the usage\n"); + printf(" -r, --replace replace the rev number if it was already applied\n"); + printf(" to the last commit\n"); + printf(" -l, --local search for the highest rev number on HEAD\n"); + printf(" -f, --fetch fetch from origin before searching for the new rev\n"); + printf(" -s, --sql search for new sql updates and do all of the changes\n"); + printf(" for the new rev\n"); + printf(" --branch=BRANCH specify which remote branch to use\n"); + return 0; + } + } + + if (local && do_sql) + { + printf("Options -l/--local and -s/--sql can't be used in same time currently.\n"); + printf("FAILED\n"); + return 1; + } + + DO( find_path() ); + if(!local) + { + DO( find_origin() ); + if(do_fetch) + DO( fetch_origin() ); + DO( check_fwd() ); + } + DO( find_rev() ); + DO( find_head_msg() ); + if(do_sql) + DO( find_sql_updates() ); + DO( prepare_new_index() ); + DO( write_rev_nr() ); + if(do_sql) + { + DO( convert_sql_updates() ); + if (generate_makefile) + DO( generate_sql_makefile() ); + // DO( change_sql_database() ); // Currently not supported + DO( write_rev_sql() ); + } + DO( amend_commit() ); + DO( cleanup_new_index() ); + //if(do_sql) + // DO( change_sql_history() ); + + return 0; +}