diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2b77bcc --- /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 a9586ba..0000000 --- a/Makefile.am +++ /dev/null @@ -1,682 +0,0 @@ -# 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 -## 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 \ -base/BSW_instance.cpp \ -base/BSW_instance.h \ -base/BSW_ai.cpp \ -base/BSW_ai.h \ -base/pet_ai.cpp \ -base/pet_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/custom/custom_cybernetic.cpp \ -scripts/custom/npc_arena_honor.cpp \ -scripts/custom/teleguy.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_coren_direbrew.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/blackwing_lair.h \ -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/chess_event.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_jandice_barov.cpp \ -scripts/eastern_kingdoms/scholomance/boss_kormok.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/boss_hummel.cpp \ -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_eredar_twins.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp \ -scripts/eastern_kingdoms/sunwell_plateau/boss_muru.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/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/dire_maul/boss_pusillin.cpp \ -scripts/kalimdor/dire_maul/dire_maul.cpp \ -scripts/kalimdor/dire_maul/dire_maul.h \ -scripts/kalimdor/dire_maul/instance_dire_maul.cpp \ -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.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_amanitar.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/draktharon_keep/draktharon_keep.h \ -scripts/northrend/draktharon_keep/boss_dred.cpp \ -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/forge_of_souls/def_forge.h \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_bronjahm.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_forge_of_souls.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/halls_of_reflection/def_halls.h \ -scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp \ -scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falric.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/icecrown_citadel/icecrown_teleport.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_spire.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.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/blood_prince_council.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.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/icecrown_citadel.h \ -scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp \ -scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h \ -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/eye_of_eternity/eye_of_eternity.h \ -scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp \ -scripts/northrend/nexus/eye_of_eternity/boss_malygos.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/nexus/oculus/oculus.h \ -scripts/northrend/nexus/oculus/oculus.cpp \ -scripts/northrend/nexus/oculus/instance_oculus.cpp \ -scripts/northrend/nexus/oculus/boss_drakos.cpp \ -scripts/northrend/nexus/oculus/boss_varos.cpp \ -scripts/northrend/nexus/oculus/boss_urom.cpp \ -scripts/northrend/nexus/oculus/boss_eregos.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/ruby_sanctum.h \ -scripts/northrend/ruby_sanctum/ruby_sanctum.cpp \ -scripts/northrend/ruby_sanctum/boss_halion.cpp \ -scripts/northrend/ruby_sanctum/boss_zarithrian.cpp \ -scripts/northrend/ruby_sanctum/boss_baltharus.cpp \ -scripts/northrend/ruby_sanctum/boss_saviana.cpp \ -scripts/northrend/ruby_sanctum/instance_ruby_sanctum.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/boss_krystallus.cpp \ -scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp \ -scripts/northrend/ulduar/halls_of_stone/def_halls_of_stone.h \ -scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp \ -scripts/northrend/ulduar/ulduar/instance_ulduar.cpp \ -scripts/northrend/ulduar/ulduar/def_ulduar.h \ -scripts/northrend/ulduar/ulduar/boss_algalon.cpp \ -scripts/northrend/ulduar/ulduar/boss_auriaya.cpp \ -scripts/northrend/ulduar/ulduar/boss_freya.cpp \ -scripts/northrend/ulduar/ulduar/boss_hodir.cpp \ -scripts/northrend/ulduar/ulduar/boss_ignis.cpp \ -scripts/northrend/ulduar/ulduar/boss_iron_council.cpp \ -scripts/northrend/ulduar/ulduar/boss_kologarn.cpp \ -scripts/northrend/ulduar/ulduar/boss_leviathan.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_vezax.cpp \ -scripts/northrend/ulduar/ulduar/boss_xt002.cpp \ -scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp \ -scripts/northrend/ulduar/ulduar/ulduar.cpp \ -scripts/northrend/ulduar/ulduar/ulduar_teleport.cpp \ -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/vault_of_archavon/boss_archavon.cpp \ -scripts/northrend/vault_of_archavon/boss_emalon.cpp \ -scripts/northrend/vault_of_archavon/boss_koralon.cpp \ -scripts/northrend/vault_of_archavon/boss_toravon.cpp \ -scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp \ -scripts/northrend/vault_of_archavon/vault_of_archavon.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/auchenai_crypts/boss_shirrak.cpp \ -scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp \ -scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp \ -scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp \ -scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp \ -scripts/outland/auchindoun/sethekk_halls/boss_talon_king_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/slave_pens/boss_ahune.cpp \ -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_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/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp \ -scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.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/violet_hold/def_violet_hold.h \ -scripts/northrend/violet_hold/violet_hold.cpp \ -scripts/northrend/violet_hold/boss_cyanigosa.cpp \ -scripts/northrend/violet_hold/boss_moragg.cpp \ -scripts/northrend/violet_hold/instance_violet_hold.cpp \ -scripts/northrend/violet_hold/boss_erekem.cpp \ -scripts/northrend/violet_hold/boss_xevozz.cpp \ -scripts/northrend/violet_hold/boss_ichoron.cpp \ -scripts/northrend/violet_hold/boss_zuramat.cpp \ -scripts/northrend/violet_hold/boss_lavanthor.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_lord_epoch.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholmeai.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_malganis.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite_corruptor.cpp \ -scripts/kalimdor/caverns_of_time/culling_of_stratholme/trash_culling_of_stratholme.cpp \ -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/MangosdRev.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/ScriptMgr.cpp b/ScriptMgr.cpp index 3b68f78..5252713 100644 --- a/ScriptMgr.cpp +++ b/ScriptMgr.cpp @@ -231,13 +231,7 @@ void Script::RegisterSelf(bool bReportError) MANGOS_DLL_EXPORT char const* GetScriptLibraryVersion() { - if (!strSD2Version.empty()) - { - strSD2Version.append(_FULLVERSION); - return strSD2Version.c_str(); - } - - return _FULLVERSION; + return strSD2Version.c_str(); } MANGOS_DLL_EXPORT @@ -520,15 +514,12 @@ bool AuraDummy(Aura const* pAura, bool apply) } MANGOS_DLL_EXPORT -InstanceData* CreateInstanceData(Map *map) +InstanceData* CreateInstanceData(Map* pMap) { - if (!map->IsDungeon()) - return NULL; - - Script *tmpscript = m_scripts[((InstanceMap*)map)->GetScriptId()]; + Script *tmpscript = m_scripts[pMap->GetScriptId()]; if (!tmpscript || !tmpscript->GetInstanceData) return NULL; - return tmpscript->GetInstanceData(map); + return tmpscript->GetInstanceData(pMap); } diff --git a/VC90/90ScriptDev2.vcproj b/VC90/90ScriptDev2.vcproj index 2606b77..5bb7be8 100644 --- a/VC90/90ScriptDev2.vcproj +++ b/VC90/90ScriptDev2.vcproj @@ -102,8 +102,8 @@ /> - @@ -582,6 +582,10 @@ + + @@ -634,10 +638,6 @@ RelativePath="..\scripts\eastern_kingdoms\blackrock_spire\instance_blackrock_spire.cpp" > - - @@ -1354,7 +1354,7 @@ Name="culling_of_stratholme" > - - @@ -1886,6 +1882,10 @@ RelativePath="..\scripts\northrend\draktharon_keep\draktharon_keep.h" > + + @@ -2005,6 +2005,14 @@ RelativePath="..\scripts\northrend\nexus\eye_of_eternity\boss_malygos.cpp" > + + + + - @@ -2088,15 +2095,15 @@ Name="ruby_sanctum" > - - - - @@ -2246,6 +2245,14 @@ RelativePath="..\scripts\northrend\ulduar\ulduar\boss_yogg_saron.cpp" > + + + + @@ -2348,51 +2355,51 @@ Name="violet_hold" > @@ -2459,19 +2466,19 @@ > @@ -2482,27 +2489,27 @@ Name="pit_of_saron" > @@ -2522,18 +2529,17 @@ > - + + + + + + + + @@ -3094,7 +3116,7 @@ /> - - - - - - - - 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/pet_ai.cpp b/base/pet_ai.cpp index 27339e5..743fddd 100644 --- a/base/pet_ai.cpp +++ b/base/pet_ai.cpp @@ -49,7 +49,7 @@ void ScriptedPetAI::AttackedBy(Unit* pAttacker) return; if (m_creature->GetCharmInfo() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) && - m_creature->canReachWithAttack(pAttacker)) + m_creature->CanReachWithMeleeAttack(pAttacker)) AttackStart(pAttacker); } @@ -73,18 +73,6 @@ void ScriptedPetAI::ResetPetCombat() Reset(); } -void ScriptedPetAI::DoMeleeAttackIfReady() -{ - if (m_creature->isAttackReady()) - { - if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) - { - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); - } - } -} - void ScriptedPetAI::UpdatePetAI(const uint32 uiDiff) { DoMeleeAttackIfReady(); diff --git a/base/pet_ai.h b/base/pet_ai.h index db2ea77..077c1fc 100644 --- a/base/pet_ai.h +++ b/base/pet_ai.h @@ -24,9 +24,6 @@ class MANGOS_DLL_DECL ScriptedPetAI : public CreatureAI void UpdateAI(const uint32 uiDiff); - // extras - void DoMeleeAttackIfReady(); - virtual void Reset() {} virtual void UpdatePetAI(const uint32 uiDiff); // while in combat diff --git a/config.h.in b/config.h.in index daa4279..d94d95e 100644 --- a/config.h.in +++ b/config.h.in @@ -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 @@ -24,7 +24,7 @@ // Format is YYYYMMDDRR where RR is the change in the conf file // for that day. -#define SD2_CONF_VERSION 2009040501 +#define SD2_CONF_VERSION 2010062001 #ifdef WIN32 #define MANGOS_DLL_EXPORT extern "C" __declspec(dllexport) diff --git a/include/sc_creature.cpp b/include/sc_creature.cpp index 196afd7..f10b5d9 100644 --- a/include/sc_creature.cpp +++ b/include/sc_creature.cpp @@ -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()) diff --git a/include/sc_creature.h b/include/sc_creature.h index a10d688..a3d5667 100644 --- a/include/sc_creature.h +++ b/include/sc_creature.h @@ -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/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp index dd896c9..83bc9ab 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp @@ -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 */ @@ -54,40 +54,47 @@ bool GOUse_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 -}; - -static uint32 RingMob[]= -{ - 8925, // Dredge Worm - 8926, // Deep Stinger - 8927, // Dark Screecher - 8928, // Burrowing Thundersnout - 8933, // Cave Creeper - 8932, // Borer Beetle + 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, }; -static uint32 RingBoss[]= +enum SpawnPosition { - 9027, // Gorosh - 9028, // Grizzle - 9029, // Eviscerator - 9030, // Ok'thor - 9031, // Anub'shiah - 9032, // Hedrum + POS_EAST = 0, + POS_NORTH = 1, + POS_GRIMSTONE = 2, }; static const float aSpawnPositions[3][4] = @@ -97,15 +104,30 @@ static const float aSpawnPositions[3][4] = {625.559f, -205.618f, -52.735f, 2.609f} // Grimstone spawn position }; +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 +{ + PHASE_MOBS = 0, + PHASE_BOSS = 2, + PHASE_GLADIATORS = 3, +}; + bool AreaTrigger_at_ring_of_law(Player* pPlayer, AreaTriggerEntry const* pAt) { 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; - pInstance->SetData(TYPE_RING_OF_LAW, IN_PROGRESS); - pPlayer->SummonCreature(NPC_GRIMSTONE, aSpawnPositions[2][0], aSpawnPositions[2][1], aSpawnPositions[2][2], aSpawnPositions[2][3], TEMPSUMMON_DEAD_DESPAWN, 0); + if (pPlayer->isGameMaster()) + return false; + + 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; @@ -117,13 +139,23 @@ 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 = (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(); } @@ -133,10 +165,13 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI uint32 m_uiEventTimer; uint8 m_uiMobSpawnId; - uint8 m_uiMobCount; uint8 m_uiMobDeadCount; - bool m_bCanWalk; + Phases m_uiPhase; + + uint32 m_uiGladiatorId[MAX_THELDREN_ADDS]; + + std::list m_lSummonedGUIDList; void Reset() { @@ -144,66 +179,76 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI m_uiEventTimer = 1000; m_uiEventPhase = 0; - m_uiMobCount = 0; m_uiMobDeadCount = 0; - m_bCanWalk = false; + m_uiPhase = PHASE_MOBS; } void JustSummoned(Creature* pSummoned) { - // Ring mob or boss summoned - ++m_uiMobCount; - if (!m_pInstance) return; + // Ring mob or boss summoned float fX, fY, fZ; + float fcX, fcY, fcZ; m_pInstance->GetArenaCenterCoords(fX, fY, fZ); - pSummoned->GetMotionMaster()->MovePoint(1, 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 SummonedCreatureJustDied(Creature* pSummoned) + void DoChallengeQuestCredit() { - // Ring mob killed - if (pSummoned->GetEntry() == RingMob[m_uiMobSpawnId]) - { - ++m_uiMobDeadCount; + Map::PlayerList const &PlayerList = m_creature->GetMap()->GetPlayers(); - if (m_uiMobDeadCount == MAX_MOB_AMOUNT) - { - m_uiEventTimer = 5000; - m_uiMobDeadCount = 0; - m_uiMobCount = 0; - } + 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); } - // Ring boss killed - else + } + + void SummonedCreatureJustDied(Creature* pSummoned) + { + ++m_uiMobDeadCount; + + switch (m_uiPhase) { - for (uint8 i = 0; i < sizeof(RingBoss)/sizeof(uint32); ++i) - { - if (pSummoned->GetEntry() == RingBoss[i]) + case PHASE_MOBS: // Ring mob killed + if (m_uiMobDeadCount == MAX_MOB_AMOUNT) { - ++m_uiMobDeadCount; - - if (m_uiMobDeadCount == 1) - { - m_uiEventTimer = 5000; - m_uiMobDeadCount = 0; - m_uiMobCount = 0; - } - return; + 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; } } - void DoGate(uint32 id, uint32 state) + void SummonRingMob(uint32 uiEntry, SpawnPosition uiPosition) { - if (GameObject* pGo = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(id))) - pGo->SetGoState(GOState(state)); - - debug_log("SD2: npc_grimstone, arena gate update state."); + 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) @@ -212,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: @@ -241,11 +286,36 @@ 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_pInstance->GetData(TYPE_RING_OF_LAW) == FAIL) + { + // 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_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_1)); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_ARENA_4)); + } + + // 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(); + + // Despawn NPC + m_creature->ForcedDespawn(); + return; + } + if (m_uiEventTimer) { if (m_uiEventTimer <= uiDiff) @@ -255,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(GO_ARENA_4, 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: @@ -270,53 +340,65 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI break; case 3: // Open East Gate - DoGate(GO_ARENA_1, 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); // Summon Ring Mob(s) - m_creature->SummonCreature(RingMob[m_uiMobSpawnId], aSpawnPositions[0][0], aSpawnPositions[0][1], aSpawnPositions[0][2], aSpawnPositions[0][3], TEMPSUMMON_DEAD_DESPAWN, 0); + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); m_uiEventTimer = 8000; break; case 5: // Summon Ring Mob(s) - m_creature->SummonCreature(RingMob[m_uiMobSpawnId], aSpawnPositions[0][0], aSpawnPositions[0][1], aSpawnPositions[0][2], aSpawnPositions[0][3], TEMPSUMMON_DEAD_DESPAWN, 0); - m_creature->SummonCreature(RingMob[m_uiMobSpawnId], aSpawnPositions[0][0], aSpawnPositions[0][1], aSpawnPositions[0][2], aSpawnPositions[0][3], TEMPSUMMON_DEAD_DESPAWN, 0); + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); m_uiEventTimer = 8000; break; case 6: // Summon Ring Mob(s) - m_creature->SummonCreature(RingMob[m_uiMobSpawnId], aSpawnPositions[0][0], aSpawnPositions[0][1], aSpawnPositions[0][2], aSpawnPositions[0][3], TEMPSUMMON_DEAD_DESPAWN, 0); + SummonRingMob(aRingMob[m_uiMobSpawnId], POS_EAST); m_uiEventTimer = 0; break; case 7: // Summoned Mobs are dead, continue event m_creature->SetVisibility(VISIBILITY_ON); - DoGate(GO_ARENA_1, 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(GO_ARENA_2, 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); - m_creature->SummonCreature(RingBoss[urand(0, 5)], aSpawnPositions[1][0], aSpawnPositions[1][1], aSpawnPositions[1][2], aSpawnPositions[1][3], TEMPSUMMON_DEAD_DESPAWN, 0); + // 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(GO_ARENA_2, GO_STATE_READY); - DoGate(GO_ARENA_3, GO_STATE_ACTIVE); - DoGate(GO_ARENA_4, 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; } @@ -325,9 +407,6 @@ struct MANGOS_DLL_DECL npc_grimstoneAI : public npc_escortAI else m_uiEventTimer -= uiDiff; } - - if (m_bCanWalk) - npc_escortAI::UpdateAI(uiDiff); } }; @@ -336,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 ######*/ @@ -712,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; diff --git a/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h index be92d4e..db83243 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h +++ b/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h @@ -46,7 +46,46 @@ enum GO_THRONE_ROOM = 170575, GO_SPECTRAL_CHALICE = 164869, - GO_CHEST_SEVEN = 169243 + 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 @@ -66,6 +105,7 @@ class MANGOS_DLL_DECL instance_blackrock_depths : public ScriptedInstance 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; } @@ -106,6 +146,7 @@ class MANGOS_DLL_DECL instance_blackrock_depths : public ScriptedInstance uint64 m_uiSpectralChaliceGUID; uint64 m_uiSevensChestGUID; + uint64 m_uiArenaSpoilsGUID; uint32 m_uiBarAleCount; diff --git a/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp b/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp index 680f776..cf58b38 100644 --- a/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp +++ b/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp @@ -16,8 +16,8 @@ /* ScriptData SDName: Instance_Blackrock_Depths -SD%Complete: 20 -SDComment: events: ring of law +SD%Complete: 80 +SDComment: SDCategory: Blackrock Depths EndScriptData */ @@ -56,6 +56,7 @@ instance_blackrock_depths::instance_blackrock_depths(Map* pMap) : ScriptedInstan m_uiSpectralChaliceGUID(0), m_uiSevensChestGUID(0), + m_uiArenaSpoilsGUID(0), m_uiBarAleCount(0), @@ -111,6 +112,7 @@ void instance_blackrock_depths::OnObjectCreate(GameObject* pGo) 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; } } @@ -119,6 +121,9 @@ void instance_blackrock_depths::SetData(uint32 uiType, uint32 uiData) switch(uiType) { case TYPE_RING_OF_LAW: + // If finished the arena event after theldren fight + if (uiData == DONE && m_auiEncounter[0] == SPECIAL) + DoRespawnGameObject(m_uiArenaSpoilsGUID, HOUR*IN_MILLISECONDS); m_auiEncounter[0] = uiData; break; case TYPE_VAULT: @@ -267,6 +272,21 @@ void instance_blackrock_depths::Load(const char* chrIn) 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) { return new instance_blackrock_depths(pMap); diff --git a/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp b/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp index e5ec97d..1d5fa11 100644 --- a/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp +++ b/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp @@ -189,10 +189,11 @@ struct MANGOS_DLL_DECL boss_chromaggusAI : public ScriptedAI 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) { diff --git a/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp b/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp index 4c24146..73065a6 100644 --- a/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp +++ b/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp @@ -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/karazhan/boss_midnight.cpp b/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp index 30ccc93..b8e580d 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp @@ -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 46c3dbc..db805a4 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp @@ -304,7 +304,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); } diff --git a/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp b/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp index 6c458c0..60952fb 100644 --- a/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp +++ b/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp @@ -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/magisters_terrace/boss_felblood_kaelthas.cpp b/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp index 4fd7c58..cb38157 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp @@ -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 8048129..9628c53 100644 --- a/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp +++ b/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp @@ -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/molten_core/boss_ragnaros.cpp b/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp index 3a77ef0..8528b1f 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp @@ -231,10 +231,13 @@ struct MANGOS_DLL_DECL boss_ragnarosAI : public Scripted_NoMovementAI // 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->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + if (m_creature->IsNonMeleeSpellCasted(false) || !m_creature->getVictim()) + return; + + 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(); diff --git a/scripts/eastern_kingdoms/stratholme/stratholme.cpp b/scripts/eastern_kingdoms/stratholme/stratholme.cpp index 01a089c..fbb07ff 100644 --- a/scripts/eastern_kingdoms/stratholme/stratholme.cpp +++ b/scripts/eastern_kingdoms/stratholme/stratholme.cpp @@ -242,7 +242,7 @@ struct MANGOS_DLL_DECL mobs_spectral_ghostly_citizenAI : public ScriptedAI EnterEvadeMode(); break; case TEXTEMOTE_RUDE: - if (m_creature->IsWithinDistInMap(pPlayer, ATTACK_DISTANCE)) + if (m_creature->IsWithinDistInMap(pPlayer, INTERACTION_DISTANCE)) m_creature->CastSpell(pPlayer,SPELL_SLAP,false); else m_creature->HandleEmote(EMOTE_ONESHOT_RUDE); diff --git a/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp b/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp index ad12a39..1c9b3af 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.h b/scripts/eastern_kingdoms/uldaman/uldaman.h index d07cfda..86435c2 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/westfall.cpp b/scripts/eastern_kingdoms/westfall.cpp index a8fc850..de175f4 100644 --- a/scripts/eastern_kingdoms/westfall.cpp +++ b/scripts/eastern_kingdoms/westfall.cpp @@ -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); } diff --git a/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp b/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp index 12bdc6f..331eb4c 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp @@ -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* 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) + if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { - 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_mandokir.cpp b/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp index de9084c..524a73c 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp @@ -326,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_thekal.cpp b/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp index 75b3128..720d3d0 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp @@ -237,7 +237,8 @@ struct MANGOS_DLL_DECL boss_thekalAI : public ScriptedAI } } - DoMeleeAttackIfReady(); + if (m_creature->getVictim()) // TODO - use correct check here, this only prevents crash + DoMeleeAttackIfReady(); } }; @@ -297,6 +298,7 @@ struct MANGOS_DLL_DECL mob_zealot_lorkhanAI : public ScriptedAI }else BloodLust_Timer -= diff; //Casting Greaterheal to Thekal or Zath if they are in meele range. + // TODO - why this range check? if (GreaterHeal_Timer < diff) { if (m_pInstance) @@ -373,7 +375,8 @@ struct MANGOS_DLL_DECL mob_zealot_lorkhanAI : public ScriptedAI FakeDeath = true; } - DoMeleeAttackIfReady(); + if (!FakeDeath) + DoMeleeAttackIfReady(); } }; @@ -505,7 +508,8 @@ struct MANGOS_DLL_DECL mob_zealot_zathAI : public ScriptedAI FakeDeath = true; } - DoMeleeAttackIfReady(); + if (!FakeDeath) + DoMeleeAttackIfReady(); } }; diff --git a/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp b/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp index a1a92cc..6b7610b 100644 --- a/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp +++ b/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp @@ -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/kalimdor/boss_azuregos.cpp b/scripts/kalimdor/boss_azuregos.cpp index 7656892..be2a6c0 100644 --- a/scripts/kalimdor/boss_azuregos.cpp +++ b/scripts/kalimdor/boss_azuregos.cpp @@ -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/onyxias_lair/boss_onyxia.cpp b/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp index 0da255d..95dd9bb 100644 --- a/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp +++ b/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp @@ -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,6 +169,9 @@ struct MANGOS_DLL_DECL boss_onyxiaAI : public ScriptedAI void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); + + if (m_pInstance) + m_pInstance->SetData(TYPE_ONYXIA, IN_PROGRESS); } void JustReachedHome() @@ -174,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) @@ -181,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; } @@ -304,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; } @@ -376,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 @@ -413,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) @@ -423,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 7e470fe..62ac0e1 100644 --- a/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp +++ b/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp @@ -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 509a41f..08bc832 100644 --- a/scripts/kalimdor/onyxias_lair/onyxias_lair.h +++ b/scripts/kalimdor/onyxias_lair/onyxias_lair.h @@ -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/temple_of_ahnqiraj/boss_bug_trio.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp index c74d6b5..3b215e0 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp @@ -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 3d92f27..8f41678 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp @@ -1020,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)) @@ -1115,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_skeram.cpp b/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp index c18dc60..9a69081 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp @@ -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 72a95ea..df5140f 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp @@ -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; @@ -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/instance_temple_of_ahnqiraj.cpp b/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp index 0277a2c..3d3d41a 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp +++ b/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp @@ -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/temple_of_ahnqiraj.h b/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h index fdea640..4d7f46c 100644 --- a/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h +++ b/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h @@ -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/wailing_caverns/instance_wailing_caverns.cpp b/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp index c1a0e78..f711110 100644 --- a/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp +++ b/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp @@ -39,7 +39,8 @@ void instance_wailing_caverns::OnCreatureCreate(Creature* pCreature) { switch (pCreature->GetEntry()) { - case NPC_NARALEX: m_uiNaralexGUID = pCreature->GetGUID(); break; + case NPC_NARALEX: m_uiNaralexGUID = pCreature->GetGUID(); break; + case NPC_DISCIPLE: m_uiDiscipleGUID = pCreature->GetGUID(); break; } } @@ -68,8 +69,17 @@ void instance_wailing_caverns::SetData(uint32 uiType, uint32 uiData) } // 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) + 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) { diff --git a/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp b/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp index c7c1f5e..1ee57bd 100644 --- a/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp +++ b/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp @@ -16,12 +16,14 @@ /* ScriptData SDName: wailing_caverns -SD%Complete: 0 -SDComment: Placeholder +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 { @@ -30,7 +32,7 @@ enum SAY_CONTINUE = -1043003, SAY_CIRCLE_BANISH = -1043004, SAY_PURIFIED = -1043005, - SAY_NARALEX_CHAMBER = -1043016, + SAY_NARALEX_CHAMBER = -1043006, SAY_BEGIN_RITUAL = -1043007, SAY_MUTANUS = -1043012, SAY_NARALEX_AWAKE = -1043013, @@ -63,6 +65,434 @@ enum 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 d7cef27..7a7b9e6 100644 --- a/scripts/kalimdor/wailing_caverns/wailing_caverns.h +++ b/scripts/kalimdor/wailing_caverns/wailing_caverns.h @@ -17,6 +17,7 @@ enum TYPE_MUTANUS = 5, NPC_NARALEX = 3679, + NPC_DISCIPLE = 3678, SAY_INTRO = -1043000, // Say when the first 4 encounter are DONE }; @@ -42,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/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 16ae1e7..a8fa628 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 - 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/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 de3f3a8..fad3f99 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 - 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/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 f5f5f71..8cf000f 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,4 +1,4 @@ -/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2 +/* Copyright (C) 2009 - 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 */ diff --git a/scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp b/scripts/northrend/draktharon_keep/instance_draktharon_keep.cpp index e90dd41..c569cb3 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/gundrak/boss_eck.cpp b/scripts/northrend/gundrak/boss_eck.cpp index 59a1024..fa33159 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/gundrak.h b/scripts/northrend/gundrak/gundrak.h index 3b28130..e20129a 100644 --- a/scripts/northrend/gundrak/gundrak.h +++ b/scripts/northrend/gundrak/gundrak.h @@ -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, @@ -47,6 +48,14 @@ enum GO_BRIDGE = 193188, 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, + //Achievements ACHIEV_CRITERIA_SNAKES = 7363, ACHIEV_CRITERIA_LESS_RABI = 7319, @@ -54,6 +63,9 @@ enum ACHIEV_CRITERIA_SHARE_THE_LOVE = 7583 }; +typedef std::map TypeTimerMap; +typedef std::pair TypeTimerPair; + class MANGOS_DLL_DECL instance_gundrak : public ScriptedInstance { public: @@ -75,7 +87,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; @@ -87,15 +102,25 @@ 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; + uint32 m_uiBridgeCounter; bool m_bGuardSpawnt; diff --git a/scripts/northrend/gundrak/instance_gundrak.cpp b/scripts/northrend/gundrak/instance_gundrak.cpp index 60915dd..acb82b8 100644 --- a/scripts/northrend/gundrak/instance_gundrak.cpp +++ b/scripts/northrend/gundrak/instance_gundrak.cpp @@ -16,8 +16,8 @@ /* 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 */ @@ -44,7 +44,7 @@ bool GOUse_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; } @@ -57,10 +57,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), @@ -89,6 +91,7 @@ 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; } } @@ -113,6 +116,19 @@ void instance_gundrak::SetAchiev(uint32 uiType, bool get) } } +/* 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()) @@ -158,22 +174,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) @@ -193,6 +209,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; @@ -217,7 +237,7 @@ bool instance_gundrak::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player 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) { @@ -228,7 +248,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); if (uiData == SPECIAL) { - DoUseDoorOrButton(m_uiSnakeKeyGUID); + m_mAltarInProgress.insert(TypeTimerPair(TYPE_SLADRAN, TIMER_VISUAL_ALTAR)); m_uiBridgeCounter++; } break; @@ -243,7 +263,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) } if (uiData == SPECIAL) { - DoUseDoorOrButton(m_uiMammothKeyGUID); + m_mAltarInProgress.insert(TypeTimerPair(TYPE_MOORABI, TIMER_VISUAL_ALTAR)); m_uiBridgeCounter++; } break; @@ -254,7 +274,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); if (uiData == SPECIAL) { - DoUseDoorOrButton(m_uiTrollKeyGUID); + m_mAltarInProgress.insert(TypeTimerPair(TYPE_COLOSSUS, TIMER_VISUAL_ALTAR)); m_uiBridgeCounter++; } break; @@ -286,7 +306,7 @@ void instance_gundrak::SetData(uint32 uiType, uint32 uiData) } } - if (uiData == DONE) + if (uiData == DONE || uiData == SPECIAL) // Save activated altars, too { OUT_SAVE_INST_DATA; @@ -333,6 +353,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); 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 12ac976..0815074 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 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 d97bc66..4c79643 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 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 index b6d79b6..6dcab36 100644 --- 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 @@ -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/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 cb2875a..350eda5 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 diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_forge_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_forge_of_souls.cpp index b617e41..74f2447 100644 --- a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_forge_of_souls.cpp +++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_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 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 index a5577f7..7dc943b 100644 --- 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 @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software; you can redistribute it and/or modify * 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/halls_of_reflection/boss_lich_king.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp index 7ae0902..04eeaa7 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 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 e55de0a..b34437d 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 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 index 17bc8cc..5662ef3 100644 --- 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 @@ -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/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 index e592de1..b53e72e 100644 --- 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 @@ -1,3 +1,3 @@ -/* 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/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 index eb47fb2..28699e7 100644 --- 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 @@ -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/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp deleted file mode 100644 index f7a65e5..0000000 --- a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp +++ /dev/null @@ -1,243 +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_forgemaster_gafrost -SD%Complete: 60% -SDComment: by Tacx -SDCategory: Pit of Saron -EndScriptData */ - -#include "precompiled.h" -#include "pit_of_saron.h" -enum -{ - //common - SPELL_BERSERK = 47008, - //yells - SAY_AGGRO = -1658001, - SAY_SLAY_1 = -1658002, - SAY_SLAY_2 = -1658003, - SAY_DEATH = -1658004, - SAY_PHASE2 = -1658005, - SAY_PHASE3 = -1658006, - SAY_DEEPFREZE = -1658006, - SAY_TYRANNUS_DEATH = -1659007, - //summons - //Abilities - SPELL_PERMAFROST = 70326, - SPELL_PERMAFROST_TRIGGER = 68786, - SPELL_THROW_SARONITE = 68788, - SPELL_THUNDERING_STOMP = 68771, - SPELL_CHILLING_WAVE = 68778, - SPELL_CHILLING_WAVE_H = 70333, - SPELL_DEEP_FREEZE = 70381, - SPELL_DEEP_FREEZE_H = 72930, - SPELL_FORGE_MACE = 68785, - SPELL_FORGE_MACE_H = 70335, - SPELL_FORGE_BLADE = 68774, - SPELL_FORGE_BLADE_H = 70334, - EQUIP_ID_SWORD = 49345, - EQUIP_ID_MACE = 49344, - ACHIEV_DOESNT_GO_TO_ELEVEN = 4524 - -}; - -/* -enum saysSD2 -{ - 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, -}; -*/ - -struct MANGOS_DLL_DECL boss_forgemaster_gafrostAI : public ScriptedAI -{ - boss_forgemaster_gafrostAI(Creature* pCreature) : ScriptedAI(pCreature) - { - m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); - Reset(); - } - - ScriptedInstance *m_pInstance; - - - bool m_bIsRegularMode; - bool m_bIsPhase2; - bool m_bIsPhase3; - bool m_bIsAchievement; - - uint32 m_uiThrowSaronite_Timer; - uint32 m_uiChillingWave_Timer; - uint32 m_uiDeepFreeze_Timer; - uint32 m_uiBladeReturn_Timer; - uint32 m_uiMaceReturn_Timer; - - void Reset() - { - m_bIsPhase2 = false; - m_bIsPhase3 = false; - m_bIsAchievement = true; - m_uiThrowSaronite_Timer = 20000; - m_uiChillingWave_Timer = 9990000; - m_uiDeepFreeze_Timer = 9990000; - m_uiBladeReturn_Timer = 4500; - m_uiMaceReturn_Timer = 6000; - - if(!m_pInstance) return; - m_pInstance->SetData(TYPE_GARFROST, NOT_STARTED); - } - - void Aggro(Unit *who) - { - DoScriptText(SAY_AGGRO, m_creature); - DoCast(m_creature, SPELL_PERMAFROST); - if(!m_pInstance) return; - m_pInstance->SetData(TYPE_GARFROST, IN_PROGRESS); - } - - void KilledUnit(Unit* victim) - { - switch (urand(0,1)) - { - case 0: DoScriptText(SAY_SLAY_1, m_creature); break; - case 1: DoScriptText(SAY_SLAY_2, m_creature); break; - } - } - - void JustDied(Unit* pkiller) - { - DoScriptText(SAY_DEATH, m_creature); - if(!m_pInstance) return; - m_pInstance->SetData(TYPE_GARFROST, DONE); - } - - void UpdateAI(const uint32 diff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - return; - - if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 66) && !m_bIsPhase2) - { - m_bIsPhase2 = true; - DoScriptText(SAY_PHASE2, m_creature); - DoCast(m_creature, SPELL_THUNDERING_STOMP); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - m_creature->GetMotionMaster()->Clear(); - m_creature->GetMotionMaster()->MovePoint(0, 654.021f, -201.438f, 526.699f); - } - - if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 33) && !m_bIsPhase3) - { - m_bIsPhase3 = true; - DoScriptText(SAY_PHASE3, m_creature); - DoCast(m_creature, SPELL_THUNDERING_STOMP); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - m_creature->GetMotionMaster()->Clear(); - m_creature->GetMotionMaster()->MovePoint(0, 718.009f, -229.447f, 526.847f); - } - - if (m_bIsPhase2) - { - if (m_uiBladeReturn_Timer < diff) - { - DoCast(m_creature, m_bIsRegularMode ? SPELL_FORGE_BLADE : SPELL_FORGE_BLADE_H); - SetEquipmentSlots(false, EQUIP_ID_SWORD, -1, -1); - m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); - m_creature->GetMotionMaster()->Clear(); - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - m_uiBladeReturn_Timer = 9900000; - } - else - m_uiBladeReturn_Timer -= diff; - - m_uiChillingWave_Timer = 10000; - } - - if (m_bIsPhase3) - { - if (m_uiMaceReturn_Timer < diff) - { - m_creature->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_FORGE_BLADE : SPELL_FORGE_BLADE_H); - DoCast(m_creature, m_bIsRegularMode ? SPELL_FORGE_MACE : SPELL_FORGE_MACE_H); - SetEquipmentSlots(false, EQUIP_ID_MACE, -1, -1); - m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); - m_creature->GetMotionMaster()->Clear(); - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - m_uiMaceReturn_Timer = 9900000; - } - else - m_uiMaceReturn_Timer -= diff; - m_uiChillingWave_Timer = 999000; - m_uiDeepFreeze_Timer = 10000; - } - - if (m_uiThrowSaronite_Timer < diff) - { - if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCast(Target, SPELL_THROW_SARONITE); - m_uiThrowSaronite_Timer = (m_bIsRegularMode ? 20000 : 25000); - } - else - m_uiThrowSaronite_Timer -= diff; - - if (m_uiChillingWave_Timer < diff) - { - DoCast(m_creature, SPELL_CHILLING_WAVE); - m_uiChillingWave_Timer = (m_bIsRegularMode ? 40000 : 30000); - } - else - m_uiChillingWave_Timer -= diff; - - if (m_uiDeepFreeze_Timer < diff) - { - if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) - DoCast(Target, m_bIsRegularMode ? SPELL_DEEP_FREEZE : SPELL_DEEP_FREEZE_H); - m_uiDeepFreeze_Timer = (m_bIsRegularMode ? 27500 : 25000); - } - else - m_uiDeepFreeze_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; - - -CreatureAI* GetAI_boss_forgemaster_gafrost(Creature* pCreature) -{ - return new boss_forgemaster_gafrostAI(pCreature); -} - - -void AddSC_boss_gafrost() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_forgemaster_gafrost"; - newscript->GetAI = &GetAI_boss_forgemaster_gafrost; - newscript->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 4493d9c..6667a59 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 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 5bffcbd..9fbf113 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 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 a876801..9c0586a 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 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 b56ef56..13b0af1 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 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 42d2d02..134b986 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 edb8e56..228a593 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 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 39ccf2c..58be8a1 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 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 6467439..f3dcfc6 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 diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp index ec4e05c..ee711f3 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 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 91445fe..25e9523 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 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 8f3e2a8..7fb74a7 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 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 eccc914..02d3139 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 diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp index 3082050..1a0034c 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 diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp index 57b260a..53810de 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 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 f61d9c1..12bea52 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 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 2d4fd7b..97a0cde 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 diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h b/scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h index 6acf2f1..9030ef5 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 by /dev/rsa for ScriptDev2 +/* Copyright (C) 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 */ diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp index 905c401..caf8175 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 diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h index e592de1..b53e72e 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h @@ -1,3 +1,3 @@ -/* 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/icecrown_spire.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp index c4bd4a4..8e5a103 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_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 diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp index f0feb91..1f378cb 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software; you can redistribute it and/or modify * 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/icecrown_citadel/instance_icecrown_citadel.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp index d2346d4..9b4473b 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software; you can redistribute it and/or modify * 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/icecrown_citadel/instance_icecrown_spire.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_spire.cpp index 34c8458..084074c 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_spire.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_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 diff --git a/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp b/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp index 85a084e..eaff00a 100644 --- a/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp +++ b/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software; you can redistribute it and/or modify * 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/eye_of_eternity/instance_eye_of_eternity.cpp b/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp index b88c4ea..01296b9 100644 --- a/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp +++ b/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.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/northrend/nexus/nexus/boss_anomalus.cpp b/scripts/northrend/nexus/nexus/boss_anomalus.cpp index 3015b13..0b21132 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_ormorok.cpp b/scripts/northrend/nexus/nexus/boss_ormorok.cpp index 0a77e98..752022d 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 cfcc5ef..cf6349d 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/nexus.h b/scripts/northrend/nexus/nexus/nexus.h index 5da01c0..60a7e4b 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 index 71c809e..1c220c1 100644 --- a/scripts/northrend/nexus/oculus/boss_drakos.cpp +++ b/scripts/northrend/nexus/oculus/boss_drakos.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 - 2010 TrinityCore +/* Copyright (C) 2008 - 2011 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 diff --git a/scripts/northrend/nexus/oculus/instance_oculus.cpp b/scripts/northrend/nexus/oculus/instance_oculus.cpp index 95219b7..6e6576f 100644 --- a/scripts/northrend/nexus/oculus/instance_oculus.cpp +++ b/scripts/northrend/nexus/oculus/instance_oculus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 - 2010 TrinityCore +/* Copyright (C) 2008 - 2011 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 diff --git a/scripts/northrend/nexus/oculus/oculus.cpp b/scripts/northrend/nexus/oculus/oculus.cpp index 9a37579..7cdc0b3 100644 --- a/scripts/northrend/nexus/oculus/oculus.cpp +++ b/scripts/northrend/nexus/oculus/oculus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2010 ScriptDev2 +/* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software; you can redistribute it and/or modify * 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/obsidian_sanctum/boss_sartharion.cpp b/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp index c64cb64..4b14554 100644 --- a/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp +++ b/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp @@ -125,15 +125,7 @@ enum //using these custom points for dragons start and end POINT_ID_INIT = 100, - POINT_ID_LAND = 200, - - // achievements - THE_TWILIGHT_ZONE_25 = 2054, - THE_TWILIGHT_ZONE_10 = 2051, - TWILIGHT_DUO_25 = 2053, - TWILIGHT_DUO_10 = 2050, - TWILIGHT_ASSIST_25 = 2052, - TWILIGHT_ASSIST_10 = 2049 + POINT_ID_LAND = 200 }; struct Waypoint @@ -261,16 +253,15 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI m_bHasCalledShadron = false; m_bHasCalledVesperon = false; - bCanUseWill = false; bFirstWill = true; m_uiCheckTwilightTimer = 2000; if (m_pInstance) { - 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 (m_bTenebronHelpedInFight && pTene) { @@ -347,27 +338,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI DoScriptText(SAY_SARTHARION_DEATH, m_creature); if (m_pInstance) - { m_pInstance->SetData(TYPE_SARTHARION_EVENT, DONE); - - uint8 uiHardMode = 0; - if (m_bTenebronHelpedInFight) - ++uiHardMode; - if (m_bShadronHelpedInFight) - ++uiHardMode; - if (m_bVesperonHelpedInFight) - ++uiHardMode; - - switch (uiHardMode) - { - case 3: - m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? THE_TWILIGHT_ZONE_10 : THE_TWILIGHT_ZONE_25); - case 2: - m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? TWILIGHT_DUO_10 : TWILIGHT_DUO_25); - case 1: - m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? TWILIGHT_ASSIST_10 : TWILIGHT_ASSIST_25); - } - } } void KilledUnit(Unit* pVictim) @@ -382,14 +353,16 @@ 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 + 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); @@ -401,7 +374,7 @@ 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); @@ -413,7 +386,7 @@ 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); @@ -423,15 +396,17 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI pVesp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } - if (bCanUseWill) - DoCast(m_creature, SPELL_WILL_OF_SARTHARION); + 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()) { @@ -444,17 +419,17 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI int32 iTextId = 0; Creature* pAdd = NULL; - pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_TENEBRON)); + pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_TENEBRON)); if (pAdd) m_uiTeneHealth = pAdd->GetHealth(); - pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_SHADRON)); + pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_SHADRON)); if (pAdd) m_uiShadHealth = pAdd->GetHealth(); - pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_VESPERON)); + pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_VESPERON)); if (pAdd) m_uiVespHealth = pAdd->GetHealth(); - switch (pTemp->GetEntry()) + switch(uiEntry) { case NPC_TENEBRON: iTextId = SAY_SARTHARION_CALL_TENEBRON; @@ -522,13 +497,13 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI { m_creature->SetHealth(m_uiSarthHealth); Creature* pTemp = NULL; - pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_TENEBRON)); + 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(DATA_SHADRON)); + 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(DATA_VESPERON)); + pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_VESPERON)); if (pTemp && pTemp->isAlive()) pTemp->SetHealth(m_uiVespHealth); } @@ -542,13 +517,13 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI DoScriptText(SAY_SARTHARION_BERSERK, m_creature); //DoCast(m_creature, SPELL_BERSERK); Creature* pTemp = NULL; - pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_TENEBRON)); + 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(DATA_SHADRON)); + 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(DATA_VESPERON)); + pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VESPERON)); if (pTemp && pTemp->isAlive()) pTemp->CastSpell(pTemp, 27680, true); @@ -653,7 +628,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI // call tenebron if (!m_bHasCalledTenebron && m_uiTenebronTimer < uiDiff) { - CallDragon(DATA_TENEBRON); + CallDragon(NPC_TENEBRON); m_bHasCalledTenebron = true; } else @@ -662,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 @@ -671,7 +646,7 @@ 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 @@ -934,7 +909,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI switch(uiData) { - case DATA_SARTHARION: + case NPC_SARTHARION: if (!m_lPortalGUIDList.empty()) { if (Map* pMap = m_creature->GetMap()) @@ -949,15 +924,15 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI m_lPortalGUIDList.push_back(pPortal->GetGUID()); } break; - case DATA_TENEBRON: + case NPC_TENEBRON: pPortal = m_creature->SummonGameobject(193988,m_aPortalLoc[1][0],m_aPortalLoc[1][1],m_aPortalLoc[1][2],m_aPortalLoc[1][3], 100); m_lPortalGUIDList.push_back(pPortal->GetGUID()); break; - case DATA_SHADRON: + case NPC_SHADRON: pPortal = m_creature->SummonGameobject(193988,m_aPortalLoc[2][0],m_aPortalLoc[2][1],m_aPortalLoc[2][2],m_aPortalLoc[2][3], 100); m_lPortalGUIDList.push_back(pPortal->GetGUID()); break; - case DATA_VESPERON: + case NPC_VESPERON: pPortal = m_creature->SummonGameobject(193988,m_aPortalLoc[3][0],m_aPortalLoc[3][1],m_aPortalLoc[3][2],m_aPortalLoc[3][3], 100); m_lPortalGUIDList.push_back(pPortal->GetGUID()); break; @@ -976,7 +951,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI switch(m_creature->GetEntry()) { case NPC_TENEBRON: - if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS ? pPortal = SummonPortal(DATA_SARTHARION) : pPortal = SummonPortal(DATA_TENEBRON)) + if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS ? pPortal = SummonPortal(NPC_SARTHARION) : pPortal = SummonPortal(NPC_TENEBRON)) { if (pPortal) { @@ -984,7 +959,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI 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_DEAD_DESPAWN, 30000)) + 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()); @@ -994,7 +969,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI } break; case NPC_SHADRON: - if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS ? pPortal = SummonPortal(DATA_SARTHARION) : pPortal = SummonPortal(DATA_SHADRON)) + if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS ? pPortal = SummonPortal(NPC_SARTHARION) : pPortal = SummonPortal(NPC_SHADRON)) { if (pPortal) { @@ -1013,12 +988,12 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI } if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS) { - if (Creature* pSarth = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SARTHARION))) + 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(DATA_SHADRON))) + if (Creature* pShad = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SHADRON))) pShad->CastSpell(pShad, SPELL_GIFT_OF_TWILIGTH_SHA, true); } } @@ -1026,7 +1001,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI } break; case NPC_VESPERON: - if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS ? pPortal = SummonPortal(DATA_SARTHARION) : pPortal = SummonPortal(DATA_VESPERON)) + if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS ? pPortal = SummonPortal(NPC_SARTHARION) : pPortal = SummonPortal(NPC_VESPERON)) { if (pPortal) { @@ -1117,7 +1092,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : 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); @@ -1125,7 +1100,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : 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); @@ -1177,7 +1152,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI } // 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()) pSartharion->CastSpell(pSartharion, SPELL_TWILIGHT_REVENGE, true); @@ -1558,7 +1533,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); @@ -1566,7 +1541,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); diff --git a/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp b/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp index 7a4aac3..2f1bb92 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 801b3ad..8351380 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/ulduar/halls_of_lightning/boss_bjarngrim.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp index dc23763..52f9f4a 100644 --- a/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp +++ b/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp @@ -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/ulduar/boss_ignis.cpp b/scripts/northrend/ulduar/ulduar/boss_ignis.cpp index bfe7042..173361a 100644 --- a/scripts/northrend/ulduar/ulduar/boss_ignis.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_ignis.cpp @@ -50,8 +50,10 @@ enum BUFF_STRENGHT_OF_CREATOR = 64473, SPELL_STRENGHT_OF_CREATOR2 = 64474, SPELL_STRENGHT_OF_CREATOR3 = 64475, - SPELL_HASTE = 66045, + SPELL_HASTE = 62836, SPELL_ENRAGE = 26662, + + //iron construct SPELL_HEAT = 65667, SPELL_MOLTEN = 62373, @@ -267,15 +269,6 @@ struct MANGOS_DLL_DECL mob_iron_constructAI : public ScriptedAI 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; } diff --git a/scripts/northrend/ulduar/ulduar/boss_leviathan.cpp b/scripts/northrend/ulduar/ulduar/boss_leviathan.cpp index c87c9e4..a30ee2a 100644 --- a/scripts/northrend/ulduar/ulduar/boss_leviathan.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_leviathan.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: boss_leviathan SD%Complete: -SDComment: needs vehicles +SDComment: needs vehicles , add Flying Mobs, Throw Passenger, Grab Crate SDCategory: Ulduar EndScriptData */ @@ -53,6 +53,7 @@ enum spells SPELL_MISSILE_BARRAGE = 62400, SPELL_FLAME_VENTS = 62396, + SPELL_FLAME_VENTS_TIGGER= 63847, SPELL_BATTERING_RAM = 62376, SPELL_GATHERING_SPEED = 62375, @@ -65,23 +66,37 @@ enum spells 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_LASH = 65062, + SPELL_FREYA_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 + SPELL_TOWER_OF_FROST = 65079, + SPELL_HODIR_FURY = 62533, // tower of storms - SPELL_THORIMS_HAMMER = 62912, - SPELL_TOWER_OF_STORMS = 65076 + SPELL_THORIMS_HAMMER = 62911, + SPELL_TOWER_OF_STORMS = 65076, + + // pool of tar + SPELL_TAR_PASSIV = 62288, + SPELL_BLAZE = 62292, + + // Pyrit Vehicles + SPELL_LIQUID_PYRITE = 62494, + + + AURA_DUMMY_BLUE = 63294, + AURA_DUMMY_GREEN = 63295, + AURA_DUMMY_YELLOW = 63292, + }; enum Mobs @@ -89,6 +104,15 @@ enum Mobs MOB_MECHANOLIFT = 33214, MOB_LIQUID = 33189, MOB_CONTAINER = 33218, + + MOB_THORIM_BEACON = 33365, + MOB_MIMIRON_BEACON = 33370, + MOB_HODIR_BEACON = 33212, + MOB_FREYA_BEACON = 33367, + NPC_THORIM_TARGET_BEACON = 33364, + NPC_MIMIRON_TARGET_BEACON = 33369, + NPC_HODIR_TARGET_BEACON = 33108, + NPC_FREYA_TARGET_BEACON = 33366, DEFENSE_TURRET = 33142, KEEPER_OF_NORGANNON = 33686 @@ -99,6 +123,77 @@ enum Seats SEAT_PLAYER = 0, SEAT_TURRET = 1, SEAT_DEVICE = 2, + SEAT_CANNON = 7, +}; + +enum Vehicles +{ + VEHICLE_SIEGE = 33060, + VEHICLE_CHOPPER = 33062, + VEHICLE_DEMOLISHER = 33109, +}; + +enum eAchievementData +{ + ACHIEV_10_ORBITAL_BOMBARDMENT = 2913, // one Tower + ACHIEV_25_ORBITAL_BOMBARDMENT = 2918, + ACHIEV_10_ORBITAL_DEVASTATION = 2914, // two Towers + ACHIEV_25_ORBITAL_DEVASTATION = 2916, + ACHIEV_10_NUKED_FROM_ORBIT = 2915, // three Towers + ACHIEV_25_NUKED_FROM_ORBIT = 2917, + ACHIEV_10_ORBIT_UARY = 3056, + ACHIEV_25_ORBIT_UARY = 3057, +/* Nicht implementiert + ACHIEV_10_SHUTOUT = 2911, + ACHIEV_25_SHUTOUT = 2912, + ACHIEV_10_THREE_CAR_GARAGE = 2907, + ACHIEV_25_THREE_CAR_GARAGE = 2908, + ACHIEV_10_UNBROKEN = 2905, + ACHIEV_25_UNBROKEN = 2906,*/ +}; + +struct Positions +{ + float x,y,z,o; +}; +static Positions Center[]= +{ + {354.8771f, -12.90240f, 409.803650f, 0.0f}, +}; + +const Positions PosSiege[5] = +{ + {-814.59f,-64.54f,429.92f,5.969f}, + {-784.37f,-33.31f,429.92f,5.096f}, + {-808.99f,-52.10f,429.92f,5.668f}, + {-798.59f,-44.00f,429.92f,5.663f}, + {-812.83f,-77.71f,429.92f,0.046f}, +}; + +const Positions PosChopper[5] = +{ + {-717.83f,-106.56f,430.02f,0.122f}, + {-717.83f,-114.23f,430.44f,0.122f}, + {-717.83f,-109.70f,430.22f,0.122f}, + {-718.45f,-118.24f,430.26f,0.052f}, + {-718.45f,-123.58f,430.41f,0.085f}, +}; + +const Positions PosDemolisher[5] = +{ + {-724.12f,-176.64f,430.03f,2.543f}, + {-766.70f,-225.03f,430.50f,1.710f}, + {-729.54f,-186.26f,430.12f,1.902f}, + {-756.01f,-219.23f,430.50f,2.369f}, + {-798.01f,-227.24f,429.84f,1.446f}, +}; + +const float WayMimironBeacon[4][3] = +{ + {161.45f, -37.50f, 409.80f}, + {275.14f, 64.12f, 409.80f}, + {349.67f, -31.71f, 409.80f}, + {246.72f,-129.38f, 409.80f}, }; @@ -108,10 +203,6 @@ struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI { 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(); } @@ -126,6 +217,9 @@ struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI uint32 m_uiSummonFlyerTimer; uint8 maxFlyers; + uint8 uiActiveTowers; + uint8 uiShutdown; + bool isHardMode; bool isHodirsTower; bool isFreyasTower; @@ -139,30 +233,56 @@ struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI void Reset() { + if (m_pInstance) + m_pInstance->SetData(TYPE_LEVIATHAN, NOT_STARTED); + + m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); + m_creature->ApplySpellImmune(49560, 0, 0, true); + + m_creature->RemoveAurasDueToSpell(SPELL_TOWER_OF_FROST); + m_creature->RemoveAurasDueToSpell(SPELL_TOWER_OF_STORMS); + m_creature->RemoveAurasDueToSpell(SPELL_TOWER_OF_FLAMES); + m_creature->RemoveAurasDueToSpell(SPELL_TOWER_OF_LIFE); + m_uiBatteringRamTimer = 15000 + rand()%20000; m_uiFlameVentsTimer = 15000 + rand()%10000; m_uiMissileBarrageTimer = 1000; - m_uiPursueTimer = 30000; + m_uiPursueTimer = 0; m_uiGatheringSpeedTimer = 50000; m_uiSummonFlyerTimer = 2000; maxFlyers = 10; + uiActiveTowers = 0; + 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_uiFreyaWardTimer = urand(1000, 10000); + m_uiMimironInfernoTimer = urand(1000, 10000); + m_uiHodirFuryTimer = urand(1000, 10000); + m_uiThorimHammerTimer = urand(1000, 10000); m_creature->SetSpeedRate(MOVE_RUN, 0.3f); } + void StartFreyaEvent()//summon these 4 on each corner wich wil spawn additional hostile mobs + { + if (Creature* pFreayaBeacon = m_creature->SummonCreature(MOB_FREYA_BEACON, 377.02f, -119.10f, 409.81f, 0.0f ,TEMPSUMMON_MANUAL_DESPAWN, 0)) + DoCast(pFreayaBeacon,AURA_DUMMY_GREEN, true); + if (Creature* pFreayaBeacon = m_creature->SummonCreature(MOB_FREYA_BEACON, 377.02f, 54.78f, 409.81f, 0.0f ,TEMPSUMMON_MANUAL_DESPAWN, 0)) + DoCast(pFreayaBeacon,AURA_DUMMY_GREEN, true); + if (Creature* pFreayaBeacon = m_creature->SummonCreature(MOB_FREYA_BEACON, 185.62f, 54.78f, 409.81f, 0.0f ,TEMPSUMMON_MANUAL_DESPAWN, 0)) + DoCast(pFreayaBeacon,AURA_DUMMY_GREEN, true); + if (Creature* pFreayaBeacon = m_creature->SummonCreature(MOB_FREYA_BEACON, 185.62f, -119.10f, 409.81f, 0.0f ,TEMPSUMMON_MANUAL_DESPAWN, 0)) + DoCast(pFreayaBeacon,AURA_DUMMY_GREEN, true); + } + void Aggro(Unit *who) { + CheckForTowers(); if(m_pInstance) { m_pInstance->SetData(TYPE_LEVIATHAN, IN_PROGRESS); @@ -180,6 +300,21 @@ struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI m_pInstance->SetData(TYPE_LEVIATHAN, DONE); if(isHardMode) m_pInstance->SetData(TYPE_LEVIATHAN_HARD, DONE); + + if (uiActiveTowers) + { + switch (uiActiveTowers) + { + case 4: + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_10_ORBIT_UARY : ACHIEV_25_ORBIT_UARY); + case 3: + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_10_NUKED_FROM_ORBIT : ACHIEV_25_NUKED_FROM_ORBIT); + case 2: + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_10_ORBITAL_DEVASTATION : ACHIEV_25_ORBITAL_DEVASTATION); + case 1: + m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_10_ORBITAL_BOMBARDMENT : ACHIEV_25_ORBITAL_BOMBARDMENT); + } + } } DoScriptText(SAY_DEATH, m_creature); @@ -218,8 +353,77 @@ struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI uiDamage += uiDamage/2; } + bool CollossusDead() + { + std::list lCreatureList; + GetCreatureListWithEntryInGrid(lCreatureList, m_creature, 33237, 100.0f); + if (!lCreatureList.empty()) + for(std::list::iterator itr = lCreatureList.begin(); itr != lCreatureList.end(); ++itr) + if ((*itr)->isAlive()) + return false; + + return true; + } + + void CheckForTowers() + { + if (!isHodirsTower) + { + if (GameObject* pTower = m_creature->GetMap()->GetGameObject(m_pInstance->GetData64(GO_TOWER_OF_FROST))) + if (pTower->GetHealth()) + { + isHodirsTower = true; + m_creature->CastSpell(m_creature, SPELL_TOWER_OF_FROST,true); + isHardMode = true; + uiActiveTowers++; + } + } + if (!isFreyasTower) + { + if (GameObject* pTower = m_creature->GetMap()->GetGameObject(m_pInstance->GetData64(GO_TOWER_OF_LIFE))) + if (pTower->GetHealth()) + { + isFreyasTower = true; + m_creature->CastSpell(m_creature, SPELL_TOWER_OF_LIFE,true); + isHardMode = true; + uiActiveTowers++; + } + } + if (!isMimironsTower) + { + if (GameObject* pTower = m_creature->GetMap()->GetGameObject(m_pInstance->GetData64(GO_TOWER_OF_FLAME))) + if (pTower->GetHealth()) + { + isMimironsTower = true; + m_creature->CastSpell(m_creature, SPELL_TOWER_OF_FLAMES,true); + isHardMode = true; + uiActiveTowers++; + } + } + if (!isThorimsTower) + { + if (GameObject* pTower = m_creature->GetMap()->GetGameObject(m_pInstance->GetData64(GO_TOWER_OF_STORMS))) + if (pTower->GetHealth()) + { + isThorimsTower = true; + m_creature->CastSpell(m_creature, SPELL_TOWER_OF_STORMS,true); + isHardMode = true; + uiActiveTowers++; + } + } + m_creature->SetHealth(m_creature->GetMaxHealth()); + } + + void UpdateAI(const uint32 uiDiff) { + if(m_pInstance && (m_pInstance->GetData(TYPE_LEVIATHAN) == NOT_STARTED || m_pInstance->GetData(TYPE_LEVIATHAN) == FAIL)) + if (CollossusDead()) + { + m_creature->GetMotionMaster()->MovePoint(1,342.896f , -14.113f, 409.804f); + m_pInstance->SetData(TYPE_LEVIATHAN, SPECIAL); + } + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; @@ -287,57 +491,59 @@ struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI // this part should be done in other way // tower of freya - if(isFreyasTower) + if(isFreyasTower && m_uiFreyaWardTimer) { - DoCast(m_creature, SPELL_TOWER_OF_LIFE); - if(m_uiFreyaWardTimer < uiDiff) { - DoCast(m_creature, SPELL_FREYAS_WARD); - m_uiFreyaWardTimer = 40000 + urand(1000, 10000); + StartFreyaEvent(); + m_uiFreyaWardTimer = 0; } else m_uiFreyaWardTimer -= uiDiff; } // tower of mimiron - if(isMimironsTower) + if(isMimironsTower && m_uiMimironInfernoTimer) { - DoCast(m_creature, SPELL_TOWER_OF_FLAMES); - if(m_uiMimironInfernoTimer < uiDiff) { - DoCast(m_creature, SPELL_FREYAS_WARD); - m_uiMimironInfernoTimer = 40000 + urand(1000, 10000); - } + if (Creature* pMimironBeacon = m_creature->SummonCreature(MOB_MIMIRON_BEACON, WayMimironBeacon[0][0], WayMimironBeacon[0][1], WayMimironBeacon[0][2],0, TEMPSUMMON_MANUAL_DESPAWN, 0)) + { + DoCast(pMimironBeacon, AURA_DUMMY_YELLOW, true); + m_uiMimironInfernoTimer = 0; + } + } else m_uiMimironInfernoTimer -= uiDiff; } // tower of hodir - if(isHodirsTower) + if(isHodirsTower && m_uiHodirFuryTimer) { - 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); + for (uint8 i = 0; i < 3; ++i) + { + if (Creature* pHodir = DoSpawnCreature(MOB_HODIR_BEACON, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN, 0)) + DoCast(pHodir, AURA_DUMMY_BLUE, true); + } + m_uiHodirFuryTimer = 0; } else m_uiHodirFuryTimer -= uiDiff; } // tower of thorim - if(isThorimsTower) + if(isThorimsTower && m_uiThorimHammerTimer) { - DoCast(m_creature, SPELL_TOWER_OF_STORMS); - if(m_uiThorimHammerTimer < uiDiff) { - DoCast(m_creature, SPELL_THORIMS_HAMMER); - m_uiThorimHammerTimer = 40000 + urand(1000, 10000); + for (uint8 i = 0; i < 3; ++i) + { + if (Creature* pThorim = DoSpawnCreature(MOB_THORIM_BEACON, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN, 0)) + DoCast(pThorim, AURA_DUMMY_BLUE, true); + } + m_uiThorimHammerTimer = 0; } else m_uiThorimHammerTimer -= uiDiff; } - DoMeleeAttackIfReady(); } }; @@ -372,6 +578,286 @@ struct MANGOS_DLL_DECL mob_defense_turretAI : public ScriptedAI } }; +struct MANGOS_DLL_DECL mob_pool_of_tarAI : public ScriptedAI +{ + mob_pool_of_tarAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + void Reset() + { + DoCast(m_creature, SPELL_TAR_PASSIV, true); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + SetCombatMovement(false); + } + + void SpellHit(Unit *caster, const SpellEntry *spell) + { + if(spell->SchoolMask & SPELL_SCHOOL_MASK_FIRE && !m_creature->HasAura(SPELL_BLAZE)) + DoCast(m_creature,SPELL_BLAZE,true); + } + void DamageTaken(Unit * killer, uint32 &uidamage) + { + uidamage = 0; + } +}; + +struct MANGOS_DLL_DECL mob_mechanoliftAI : public ScriptedAI +{ + mob_mechanoliftAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + void Reset() + { + } + + void JustDied(Unit* pKiller) + { + if (Creature* pLiquid = DoSpawnCreature(MOB_LIQUID,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 30000)) + { + pLiquid->CastSpell(pLiquid, SPELL_LIQUID_PYRITE, true); + } + + } +}; + +struct MANGOS_DLL_DECL mob_freyas_wardAI : public ScriptedAI +{ + mob_freyas_wardAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 summonTimer ; + + void Reset() + { + summonTimer = 5000 ; + } + + void UpdateAI(const uint32 uiDiff) + { + if(summonTimer <= uiDiff) + { + DoCast(m_creature,SPELL_FREYA_WARD, true); + summonTimer = 20000; + } + else + summonTimer -= uiDiff ; + + if (!m_creature->HasAura(AURA_DUMMY_GREEN, EFFECT_INDEX_1)) + DoCast(m_creature, AURA_DUMMY_GREEN,true); + + if (m_pInstance->GetData(TYPE_LEVIATHAN) != IN_PROGRESS) + { + m_creature->ForcedDespawn(); + } + } +}; + +struct MANGOS_DLL_DECL mob_hodirs_furyAI : public ScriptedAI +{ + mob_hodirs_furyAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + + uint32 m_uiHodirFuryTimer; + uint32 m_uiSwitchTargetTimer; //hack for RandomMovement + + bool m_bHodirFuryReady; + + void Reset() + { + m_uiHodirFuryTimer = 0; + m_bHodirFuryReady = true; + + m_uiSwitchTargetTimer = 30000; + } + + void MoveInLineOfSight(Unit* who) + { + if (who->GetTypeId() == TYPEID_PLAYER && m_creature->IsInRange(who,0,5,false) && m_bHodirFuryReady) + { + if (Creature* pTrigger = DoSpawnCreature(NPC_HODIR_TARGET_BEACON, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 1000)) + pTrigger->CastSpell(who, SPELL_HODIR_FURY, true); + m_uiHodirFuryTimer = 4000; + m_bHodirFuryReady = false; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->HasAura(AURA_DUMMY_BLUE, EFFECT_INDEX_1)) + DoCast(m_creature, AURA_DUMMY_BLUE,true); + if (m_pInstance->GetData(TYPE_LEVIATHAN) != IN_PROGRESS) + { + m_creature->ForcedDespawn(); + } + + if (!m_bHodirFuryReady) + { + if(m_uiHodirFuryTimer <= uiDiff) + { + m_bHodirFuryReady = true; + } + else + m_uiHodirFuryTimer -= uiDiff; + } + + + if(m_uiSwitchTargetTimer <= uiDiff) + { + SwitchTarget(); + } + else + m_uiSwitchTargetTimer -= uiDiff; + } + + void SwitchTarget() + { + if (m_pInstance) + { + if (Player* target = m_pInstance->GetPlayerInMap(true, true)) + m_creature->GetMotionMaster()->MoveChase(target); + } + } +}; + +struct MANGOS_DLL_DECL mob_mimirons_infernoAI : public ScriptedAI +{ + mob_mimirons_infernoAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 infernoTimer; + uint32 m_uiWalkTimer; + uint8 waypointId; + + void Reset() + { + waypointId = 0; + m_uiWalkTimer = 200; + infernoTimer = 4000; + m_creature->GetMotionMaster()->MovePoint(waypointId,WayMimironBeacon[waypointId][0],WayMimironBeacon[waypointId][1],WayMimironBeacon[waypointId][2]); + } + + void MovementInform(uint32 type, uint32 id) + { + ++waypointId; + m_uiWalkTimer = 200; + if (waypointId > 3) + waypointId = 0; + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiWalkTimer) + { + if (m_uiWalkTimer <= uiDiff) + { + m_creature->GetMotionMaster()->MovePoint(waypointId,WayMimironBeacon[waypointId][0],WayMimironBeacon[waypointId][1],WayMimironBeacon[waypointId][2]); + m_uiWalkTimer = 0; + }else m_uiWalkTimer -= uiDiff; + } + + if(infernoTimer <= uiDiff) + { + if (Creature* pTrigger = DoSpawnCreature(NPC_MIMIRON_TARGET_BEACON, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000)) + { + pTrigger->CastSpell(pTrigger, SPELL_MIMIRON_INFERNO, true); + infernoTimer = 4000; + } + } + else + infernoTimer -= uiDiff; + + if (!m_creature->HasAura(AURA_DUMMY_YELLOW, EFFECT_INDEX_1)) + DoCast(m_creature, AURA_DUMMY_YELLOW,true); + if (m_pInstance->GetData(TYPE_LEVIATHAN) != IN_PROGRESS) + { + m_creature->ForcedDespawn(); + } + } +}; + +struct MANGOS_DLL_DECL mob_thorims_hammerAI : public ScriptedAI +{ + mob_thorims_hammerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* m_pInstance; + uint32 m_uiHammerTimer; + uint32 m_uiSwitchTargetTimer; //hack for RandomMovement + + bool m_bHammerReady; + + void Reset() + { + m_uiHammerTimer = 0; + m_bHammerReady = true; + + m_uiSwitchTargetTimer = 30000; + } + + void MoveInLineOfSight(Unit* who) + { + if (who->GetTypeId() == TYPEID_PLAYER && m_creature->IsInRange(who,0,10,false) && m_bHammerReady) + { + if (Creature* pTrigger = DoSpawnCreature(NPC_THORIM_TARGET_BEACON,0 ,0 ,0 ,0 , TEMPSUMMON_TIMED_DESPAWN, 1000)) + pTrigger->CastSpell(who, SPELL_THORIMS_HAMMER, true); + m_bHammerReady = false; + m_uiHammerTimer = 4000; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_bHammerReady) + { + if(m_uiHammerTimer <= uiDiff) + { + m_bHammerReady = true; + } + else + m_uiHammerTimer -= uiDiff; + } + + if(m_uiSwitchTargetTimer <= uiDiff) + { + SwitchTarget(); + } + else + m_uiSwitchTargetTimer -= uiDiff; + + + if (!m_creature->HasAura(AURA_DUMMY_BLUE, EFFECT_INDEX_1)) + DoCast(m_creature, AURA_DUMMY_BLUE,true); + if (m_pInstance->GetData(TYPE_LEVIATHAN) != IN_PROGRESS) + { + m_creature->ForcedDespawn(); + } + } + + void SwitchTarget() + { + if (m_pInstance) + { + if (Player* target = m_pInstance->GetPlayerInMap(true, true)) + m_creature->GetMotionMaster()->MoveChase(target); + } + } +}; + CreatureAI* GetAI_mob_defense_turret(Creature* pCreature) { return new mob_defense_turretAI(pCreature); @@ -382,6 +868,67 @@ CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature) return new boss_flame_leviathan(pCreature); } +CreatureAI* GetAI_mob_pool_of_tar(Creature* pCreature) +{ + return new mob_pool_of_tarAI(pCreature); +} + +CreatureAI* GetAI_mob_mechanolift(Creature* pCreature) +{ + return new mob_mechanoliftAI(pCreature); +} + +CreatureAI* GetAI_mob_freyas_ward(Creature* pCreature) +{ + return new mob_freyas_wardAI(pCreature); +} + +CreatureAI* GetAI_mob_hodirs_fury(Creature* pCreature) +{ + return new mob_hodirs_furyAI(pCreature); +} + +CreatureAI* GetAI_mob_mimirons_inferno(Creature* pCreature) +{ + return new mob_mimirons_infernoAI(pCreature); +} + +CreatureAI* GetAI_mob_thorims_hammer(Creature* pCreature) +{ + return new mob_thorims_hammerAI(pCreature); +} + +bool GossipHello_mob_lorekeeper(Player *player, Creature *pCreature) +{ + player->ADD_GOSSIP_ITEM( GOSSIP_ICON_CHAT, "Gib mir Macht mit einen Zerstörer." , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->ADD_GOSSIP_ITEM( GOSSIP_ICON_CHAT, "Gib mir Stärke mit einer Belagerungsmaschine." , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->ADD_GOSSIP_ITEM( GOSSIP_ICON_CHAT, "Gib mir Geschwindigkeit mit einen Moped." , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID()); + return true; +} + +bool GossipSelect_mob_lorekeeper(Player *pPlayer, Creature *pCreature, uint32 sender, uint32 uiAction ) +{ + uint32 i = urand(0,4); + if (uiAction == GOSSIP_ACTION_INFO_DEF + 1) + { + pPlayer->CLOSE_GOSSIP_MENU(); + pCreature->SummonCreature(VEHICLE_DEMOLISHER, PosSiege[i].x, PosSiege[i].y, PosSiege[i].z, PosSiege[i].o, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF + 2) + { + pPlayer->CLOSE_GOSSIP_MENU(); + pCreature->SummonCreature(VEHICLE_SIEGE, PosDemolisher[i].x, PosDemolisher[i].y, PosDemolisher[i].z, PosDemolisher[i].o, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF + 3) + { + pPlayer->CLOSE_GOSSIP_MENU(); + pCreature->SummonCreature(VEHICLE_CHOPPER, PosChopper[i].x, PosChopper[i].y, PosChopper[i].z, PosChopper[i].o, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + + } + return true; +} + void AddSC_boss_leviathan() { Script *newscript; @@ -394,4 +941,40 @@ void AddSC_boss_leviathan() newscript->Name = "mob_defense_turret"; newscript->GetAI = &GetAI_mob_defense_turret; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_pool_of_tar"; + newscript->GetAI = &GetAI_mob_pool_of_tar; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_mechanolift"; + newscript->GetAI = &GetAI_mob_mechanolift; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_freyas_ward"; + newscript->GetAI = &GetAI_mob_freyas_ward; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_hodirs_fury"; + newscript->GetAI = &GetAI_mob_hodirs_fury; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_mimiron_inferno"; + newscript->GetAI = &GetAI_mob_mimirons_inferno; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_thorims_hammer"; + newscript->GetAI = &GetAI_mob_thorims_hammer; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_lorekeeper"; + newscript->pGossipHello = &GossipHello_mob_lorekeeper; + newscript->pGossipSelect = &GossipSelect_mob_lorekeeper; + newscript->RegisterSelf(); } diff --git a/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp b/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp index 306cb13..a25f4d9 100644 --- a/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp @@ -2249,7 +2249,7 @@ void AddSC_boss_mimiron() newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_mimiron_inferno"; + newscript->Name = "mob_mimirons_inferno"; newscript->GetAI = &GetAI_mob_mimiron_inferno; newscript->RegisterSelf(); diff --git a/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp b/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp index eadfe5b..ff04c76 100644 --- a/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp @@ -64,8 +64,10 @@ enum // harpoons SPELL_HARPOON_SHOT = 63659, - GO_HARPOON = 194543, // 41, 42, 194519 - + GO_REPAIR_HARPOON_4 = 194543, // BROKEN HARBOON 194565 + GO_REPAIR_HARPOON_3 = 194542, + GO_REPAIR_HARPOON_2 = 194541, + GO_REPAIR_HARPOON_1 = 194519, //dark rune watcher SPELL_LIGHTNING_BOLT = 63809, SPELL_LIGHTNING_BOLT_H = 64696, @@ -109,6 +111,7 @@ static LocationsXY PositionLoc[]= {587.629761f, -179.022522f, 435.415070f},//air }; + #define HOME_X 587.546997f #define HOME_Y -174.927002f @@ -493,9 +496,7 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI 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_uiWave_spawn; uint32 m_uiBerserk_Timer; uint32 m_uiGrounded_Timer; // 8 secs after ground fase is over, adds come uint32 m_uiGround_Cast; @@ -504,39 +505,40 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI uint8 m_uiHarpoonsRepaired; uint8 m_uiMaxHarpoons; uint64 m_uiHarpoonsGUID[4]; - uint32 m_uiTimetoground; + uint64 m_uiRepairHarpoonsGUID[4]; + uint64 m_uiHarpoonsDummyGUID[4]; uint32 m_uiStun_Timer; bool m_bAirphase; bool m_bIsGrounded; - bool m_bHasBerserk; - bool m_bKnockback; + bool m_bIsPermGrounded; 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_uiMaxHarpoons = m_bIsRegularMode ? 2 : 4; + BreakHarpoons(); + + 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_uiWave_spawn = urand(5000, 10000); + m_uiBerserk_Timer = 600000; // 10 min + m_uiRepairHarpoonTimer = 51000; + m_uiHarpoonsRepaired = 0; + m_uiGrounded_Timer = 0; + for(int i = 0; i < 4; i++) + { m_uiHarpoonsGUID[i] = 0; - m_bAirphase = false; + m_uiRepairHarpoonsGUID[i] = 0; + m_uiHarpoonsDummyGUID[i] = 0; + } + + m_bAirphase = true; m_bIsGrounded = false; - m_bHasBerserk = false; - m_bKnockback = false; + m_bIsPermGrounded = 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); @@ -551,11 +553,31 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI pCommander->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } + void GetHarpoons() + { + std::list lHarpoons; + GetGameObjectListWithEntryInGrid(lHarpoons, m_creature, GO_BROKEN_HARPOON, 400.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; + } + } + if (i != m_uiMaxHarpoons) + m_creature->MonsterSay("Fehler in der Suche der Harpoonen", LANG_UNIVERSAL); + } + } void JustDied(Unit* pKiller) { if (m_pInstance) m_pInstance->SetData(TYPE_RAZORSCALE, DONE); + BreakHarpoons(); if (m_uiFlyNo < 2) { // hacky way to complete achievements; use only if you have this function @@ -569,21 +591,7 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI 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; + GetHarpoons(); SetCombatMovement(false); m_creature->GetMotionMaster()->MoveIdle(); m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f); @@ -594,112 +602,67 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI { if (m_pInstance) m_pInstance->SetData(TYPE_RAZORSCALE, NOT_STARTED); - - BreakHarpoons(); } void BreakHarpoons() { // reset harpoons - if (!lHarpoons.empty()) + for (int i = 0; i< m_uiMaxHarpoons; i++) { - 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); - } - } + if (GameObject* pHarpoon = m_pInstance->instance->GetGameObject(m_uiHarpoonsGUID[i])) + pHarpoon->SetPhaseMask(1, true); + if (Creature* pHarpoonDummy = m_pInstance->instance->GetCreature(m_uiHarpoonsDummyGUID[i])) + pHarpoonDummy->ForcedDespawn(); + if (GameObject* pRepairHarpoon = m_pInstance->instance->GetGameObject(m_uiRepairHarpoonsGUID[i])) + pRepairHarpoon->Delete(); } } - void UpdateAI(const uint32 uiDiff) + void RepairHarpoons() { - 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) + if(GameObject* pHarpoon = m_pInstance->instance->GetGameObject(m_uiHarpoonsGUID[m_uiHarpoonsRepaired])) { - 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 + switch(m_uiHarpoonsRepaired) { - if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) - DoCast(target, DEVOURING_FLAME_VISUAL); + case 0: + { + if (GameObject* pRepairHarpoon = pHarpoon->SummonGameobject(GO_REPAIR_HARPOON_1, pHarpoon->GetPositionX(),pHarpoon->GetPositionY(),pHarpoon->GetPositionZ(), 4.732974f, 0)) + m_uiRepairHarpoonsGUID[m_uiHarpoonsRepaired] = pRepairHarpoon->GetGUID(); + break; + } + case 1: + { + if (GameObject* pRepairHarpoon = pHarpoon->SummonGameobject(GO_REPAIR_HARPOON_2, pHarpoon->GetPositionX(),pHarpoon->GetPositionY(),pHarpoon->GetPositionZ(), 5.269379f, 0)) + m_uiRepairHarpoonsGUID[m_uiHarpoonsRepaired] = pRepairHarpoon->GetGUID(); + break; + } + case 2: + { + if (GameObject* pRepairHarpoon = pHarpoon->SummonGameobject(GO_REPAIR_HARPOON_3, pHarpoon->GetPositionX(),pHarpoon->GetPositionY(),pHarpoon->GetPositionZ(), pHarpoon->GetOrientation(), 0)) + m_uiRepairHarpoonsGUID[m_uiHarpoonsRepaired] = pRepairHarpoon->GetGUID(); + break; + } + case 3: + { + if (GameObject* pRepairHarpoon = pHarpoon->SummonGameobject(GO_REPAIR_HARPOON_4, pHarpoon->GetPositionX(),pHarpoon->GetPositionY(),pHarpoon->GetPositionZ(), pHarpoon->GetAngle(m_creature), 0)) + m_uiRepairHarpoonsGUID[m_uiHarpoonsRepaired] = pRepairHarpoon->GetGUID(); + break; + } } - 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])) + if (Creature* pHarpoonDummy = pHarpoon->SummonCreature(NPC_HARPOONS_DUMMY, pHarpoon->GetPositionX(), pHarpoon->GetPositionY(), pHarpoon->GetPositionZ(),0 , TEMPSUMMON_DEAD_DESPAWN, 0)) { - pHarpoon->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); - //pHarpoon->SetUInt32Value(GAMEOBJECT_DISPLAYID, 8245); - m_uiHarpoonsRepaired += 1; + m_uiHarpoonsDummyGUID[m_uiHarpoonsRepaired] = pHarpoonDummy->GetGUID(); } - DoScriptText(EMOTE_HARPOON, m_creature); - m_uiRepairHarpoonTimer = 20000; + pHarpoon->SetPhaseMask(128,true); } - 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; + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + // Switch from Air to Ground Phase if (m_uiHarpoonsUsed == m_uiMaxHarpoons && m_bAirphase) { if(Creature* pCommander = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_COMMANDER))) @@ -709,53 +672,27 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI // timers m_uiHarpoonsUsed = 0; m_bIsGrounded = true; + m_bAirphase = false; m_uiStun_Timer = 2000; - m_uiGround_Cast = 35000; - m_uiGrounded_Timer = 45000; + m_uiGrounded_Timer = 9999999; // 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); + } + + // Switch from Ground to Air Phase + 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_bAirphase = true; + m_bIsGrounded = false; + m_uiFireball_Timer = 10000; + m_uiDevouring_Flame_Timer = 18000; + m_uiWave_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); @@ -764,7 +701,7 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI }else m_uiGrounded_Timer -= uiDiff; // make boss land at 50% hp - if (m_bAirphase && m_creature->GetHealthPercent() < 50) + if (m_creature->GetHealthPercent() < 50 && !m_bIsPermGrounded) { if (m_creature->HasAura(SPELL_STUN)) m_creature->RemoveAurasDueToSpell(SPELL_STUN); @@ -773,49 +710,134 @@ struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI m_uiGround_Knockback = m_bIsGrounded ? 0 : 3000; m_bAirphase = false; m_bIsGrounded = false; + m_bIsPermGrounded = true; 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); + BreakHarpoons(); // 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) + // AIR PHASE + if (m_bAirphase) { - m_creature->CastStop(); - DoCast(m_creature, SPELL_WING_BUFFET); - m_bKnockback = true; - }else m_uiGround_Knockback -= uiDiff; + // air position check (sometimes it falls to the ground like a rock + if(m_creature->GetPositionZ() < 430.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); + } + + // air spells + if (m_uiFireball_Timer < uiDiff) + { + 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) + { + if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) + DoCast(target, DEVOURING_FLAME_VISUAL); + m_uiDevouring_Flame_Timer = 12000; + }else m_uiDevouring_Flame_Timer -= uiDiff; - if (m_uiFuse_Armor_Timer < uiDiff && !m_bAirphase) + // repair harpoons + if (m_uiRepairHarpoonTimer < uiDiff && m_uiHarpoonsRepaired <= m_uiMaxHarpoons) + { + RepairHarpoons(); + m_uiHarpoonsRepaired += 1; + DoScriptText(EMOTE_HARPOON, m_creature); + m_uiRepairHarpoonTimer = 20000; + } + else m_uiRepairHarpoonTimer -= uiDiff; + } + + // GROUND PHASE + if (m_bIsGrounded) { - 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_uiStun_Timer < uiDiff) + { + DoCast(m_creature, SPELL_STUN, true); + m_uiStun_Timer = 9999999; + m_uiGround_Cast = 33000; + }else m_uiStun_Timer -= uiDiff; + + if (m_uiGround_Cast < uiDiff) + { + 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 = 9999999; + m_uiGround_Knockback = 7000; + }else m_uiGround_Cast -= uiDiff; + + if (m_uiGround_Knockback < uiDiff) + { + DoCast(m_creature, SPELL_WING_BUFFET); + BreakHarpoons(); + m_uiGround_Knockback = 9999999; + m_uiGrounded_Timer = 4000; + }else m_uiGround_Knockback -= uiDiff; + } + + // PERMA GROUNDED PHASE + if (m_bIsPermGrounded) + { + if (m_uiDevouring_Flame_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), DEVOURING_FLAME_VISUAL); + m_uiDevouring_Flame_Timer = 12000; + }else m_uiDevouring_Flame_Timer -= uiDiff; + + if (m_uiFuse_Armor_Timer < uiDiff) + { + DoCast(m_creature->getVictim(), SPELL_FUSE_ARMOR, true); + m_uiFuse_Armor_Timer = 13000; + } else m_uiFuse_Armor_Timer -= uiDiff; + + if (m_uiFlame_Buffet_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BUFFET : SPELL_FLAME_BUFFET_H , true); + m_uiFlame_Buffet_Timer = 13000; + }else m_uiFlame_Buffet_Timer -= uiDiff; + + if (m_uiFlame_Breath_Timer < uiDiff) + { + DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H); + DoScriptText(EMOTE_DEEP_BREATH, m_creature); + m_uiFlame_Breath_Timer = 14000; + }else m_uiFlame_Breath_Timer -= uiDiff; + } + + // ground adds only in Air and grounded phase NOT in Permagrounded Phase + if (m_uiWave_spawn < uiDiff && !m_bIsPermGrounded) + { + m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[0].x, PositionLoc[0].y, PositionLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); + m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[1].x, PositionLoc[1].y, PositionLoc[1].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); + if (roll_chance_i(33)) + { + 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; + } + m_uiWave_spawn = urand(40000, 50000); + }else m_uiWave_spawn -= uiDiff; + + // berserk + if (m_uiBerserk_Timer < uiDiff) + { + DoCast(m_creature, SPELL_BERSERK,true); + m_uiBerserk_Timer = 9999999; + }else m_uiBerserk_Timer -= uiDiff; if (m_creature->GetDistance2d(HOME_X, HOME_Y) > 100) EnterEvadeMode(); @@ -827,14 +849,12 @@ CreatureAI* GetAI_boss_razorscale(Creature* pCreature) return new boss_razorscaleAI(pCreature); } -bool GOHello_go_broken_harpoon(Player* pPlayer, GameObject* pGo) +bool GOHello_go_repair_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; @@ -883,7 +903,7 @@ void AddSC_boss_razorscale() NewScript->RegisterSelf(); NewScript = new Script; - NewScript->Name = "go_broken_harpoon"; - NewScript->pGOUse = &GOHello_go_broken_harpoon; + NewScript->Name = "go_repair_harpoon"; + NewScript->pGOUse = &GOHello_go_repair_harpoon; NewScript->RegisterSelf(); } \ No newline at end of file diff --git a/scripts/northrend/ulduar/ulduar/boss_xt002.cpp b/scripts/northrend/ulduar/ulduar/boss_xt002.cpp index fb8a775..e04e078 100644 --- a/scripts/northrend/ulduar/ulduar/boss_xt002.cpp +++ b/scripts/northrend/ulduar/ulduar/boss_xt002.cpp @@ -60,6 +60,10 @@ enum NPC_VOIDZONE = 34001, NPC_LIFESPARK = 34004, + // Void Zone + SPELL_VOID_ZONE_10 = 64203, + SPELL_VOID_ZONE_25 = 64235, + //heart of the deconstructor SPELL_EXPOSED_HEART = 63849, @@ -282,15 +286,14 @@ struct MANGOS_DLL_DECL mob_xtheartAI : public ScriptedAI { DoCast(m_creature, SPELL_EXPOSED_HEART); m_creature->SetRespawnDelay(DAY); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_uiTotalDamage = 0; m_uiDeathTimer = 30000; } void DamageTaken(Unit* pDoneBy, uint32& uiDamage) { - m_uiTotalDamage += uiDamage; - // double damage - uiDamage += uiDamage; + m_uiTotalDamage += (uiDamage *2); } void JustDied(Unit* pKiller) @@ -529,7 +532,7 @@ struct MANGOS_DLL_DECL boss_xt002AI : public ScriptedAI if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { // fix spell range - DoCast(pTarget, m_bIsRegularMode ? SPELL_LIGHT_BOMB : SPELL_LIGHT_BOMB_H); + pTarget->CastSpell(pTarget, m_bIsRegularMode ? SPELL_LIGHT_BOMB : SPELL_LIGHT_BOMB_H, true); pLightBombTarGUID = pTarget->GetGUID(); } @@ -546,7 +549,7 @@ struct MANGOS_DLL_DECL boss_xt002AI : public ScriptedAI if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { // fix spell range - DoCast(pTarget, m_bIsRegularMode ? SPELL_GRAVITY_BOMB : SPELL_GRAVITY_BOMB_H); + pTarget->CastSpell(pTarget, m_bIsRegularMode ? SPELL_GRAVITY_BOMB : SPELL_GRAVITY_BOMB_H, true); pGravityBombTarGUID = pTarget->GetGUID(); } @@ -680,12 +683,7 @@ struct MANGOS_DLL_DECL boss_xt002AI : public ScriptedAI 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) diff --git a/scripts/northrend/ulduar/ulduar/def_ulduar.h b/scripts/northrend/ulduar/ulduar/def_ulduar.h index 1145e16..ca7c4d3 100644 --- a/scripts/northrend/ulduar/ulduar/def_ulduar.h +++ b/scripts/northrend/ulduar/ulduar/def_ulduar.h @@ -146,6 +146,7 @@ enum // doors // the siege + GO_SHIELD_DOOR = 194905, GO_SHIELD_WALL = 194416, GO_LEVIATHAN_GATE = 194630, GO_XT002_GATE = 194631, @@ -188,7 +189,6 @@ enum 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 @@ -208,6 +208,23 @@ enum ACHIEV_CELESTIAL_DEFENDER = 3259, // realm first algalon SPELL_ALGALON_ACHIEV_TRIGG = 65184, ACHIEV_DEATHS_DEMISE = 3117, // realm first yogg + + // hard mode Flame Leviathan + GO_TOWER_OF_FROST = 194370, + GO_TOWER_OF_FLAME = 194371, + GO_TOWER_OF_LIFE = 194375, + GO_TOWER_OF_STORMS = 194377, + GO_FREYA_STORM_GENERATOR = 194663, + GO_MIMIRON_STORM_GENERATOR = 194664, + GO_HODIR_STORM_GENERATOR = 194665, + GO_THORIM_WEATHER_GENERATOR = 194666, + GO_FREYA_TARGETTING_CRYSTAL = 194704, + GO_MIMIRON_TARGETTING_CRYSTAL=194705, + GO_THORIM_TARGETTING_CRYSTAL= 194706, + GO_HODIR_TARGETTING_CRYSTAL = 194707, + + + }; #endif diff --git a/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp b/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp index 465f632..4212bf8 100644 --- a/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp +++ b/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp @@ -84,9 +84,23 @@ struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance //doors & objects // The siege uint64 m_uiShieldWallGUID; + uint64 m_uiShieldDoorGUID; uint64 m_uiLeviathanGateGUID; uint64 m_uiXT002GateGUID; uint64 m_uiBrokenHarpoonGUID; + // hardmode for Leviathan + uint64 m_uiTowerOfFrostGUID; + uint64 m_uiTowerOfFlameGUID; + uint64 m_uiTowerOfLifeGUID; + uint64 m_uiTowerOfStormsGUID; + uint64 m_uiFreyaStormGeneratorGUID; + uint64 m_uiMimironStormGeneratorGUID; + uint64 m_uiHodirStormGeneratorGUID; + uint64 m_uiTorimWeatherGeneratorGUID; + uint64 m_uiFreyaTargettingCrystalGUID; + uint64 m_uiMimironTargettingCrystalGUID; + uint64 m_uiThorimTargettingCrystalGUID; + uint64 m_uiHodirTargettingCrystalGUID; // Archivum uint64 m_uiIronCouncilDoorGUID; uint64 m_uiArchivumDoorGUID; @@ -206,9 +220,24 @@ struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance // doors // The siege m_uiShieldWallGUID = 0; + m_uiShieldDoorGUID = 0; m_uiLeviathanGateGUID = 0; m_uiXT002GateGUID = 0; m_uiBrokenHarpoonGUID = 0; + // hardmode for Leviathan + m_uiTowerOfFrostGUID = 0; + m_uiTowerOfFlameGUID = 0; + m_uiTowerOfLifeGUID = 0; + m_uiTowerOfStormsGUID = 0; + m_uiFreyaStormGeneratorGUID = 0; + m_uiMimironStormGeneratorGUID = 0; + m_uiHodirStormGeneratorGUID = 0; + m_uiTorimWeatherGeneratorGUID = 0; + m_uiFreyaTargettingCrystalGUID = 0; + m_uiMimironTargettingCrystalGUID= 0; + m_uiThorimTargettingCrystalGUID = 0; + m_uiHodirTargettingCrystalGUID = 0; + // Archivum m_uiIronCouncilDoorGUID = 0; m_uiArchivumDoorGUID = 0; @@ -394,6 +423,9 @@ struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance case GO_SHIELD_WALL: m_uiShieldWallGUID = pGo->GetGUID(); break; + case GO_SHIELD_DOOR: + m_uiShieldDoorGUID = pGo->GetGUID(); + break; case GO_LEVIATHAN_GATE: m_uiLeviathanGateGUID = pGo->GetGUID(); if(m_auiEncounter[0] == DONE) @@ -412,6 +444,44 @@ struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); break; + // Leviathan hard mode + case GO_TOWER_OF_FROST: + m_uiTowerOfFrostGUID = pGo->GetGUID(); + break; + case GO_TOWER_OF_FLAME: + m_uiTowerOfFlameGUID = pGo->GetGUID(); + break; + case GO_TOWER_OF_LIFE: + m_uiTowerOfLifeGUID = pGo->GetGUID(); + break; + case GO_TOWER_OF_STORMS: + m_uiTowerOfStormsGUID = pGo->GetGUID(); + break; + case GO_FREYA_STORM_GENERATOR: + m_uiFreyaStormGeneratorGUID = pGo->GetGUID(); + break; + case GO_MIMIRON_STORM_GENERATOR: + m_uiMimironStormGeneratorGUID = pGo->GetGUID(); + break; + case GO_HODIR_STORM_GENERATOR: + m_uiHodirStormGeneratorGUID = pGo->GetGUID(); + break; + case GO_THORIM_WEATHER_GENERATOR: + m_uiTorimWeatherGeneratorGUID = pGo->GetGUID(); + break; + case GO_FREYA_TARGETTING_CRYSTAL: + m_uiFreyaTargettingCrystalGUID = pGo->GetGUID(); + break; + case GO_MIMIRON_TARGETTING_CRYSTAL: + m_uiMimironTargettingCrystalGUID = pGo->GetGUID(); + break; + case GO_THORIM_TARGETTING_CRYSTAL: + m_uiThorimTargettingCrystalGUID = pGo->GetGUID(); + break; + case GO_HODIR_TARGETTING_CRYSTAL: + m_uiHodirTargettingCrystalGUID = pGo->GetGUID(); + break; + // Archivum case GO_IRON_ENTRANCE_DOOR: m_uiIronCouncilDoorGUID = pGo->GetGUID(); @@ -715,11 +785,17 @@ struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance { case TYPE_LEVIATHAN: m_auiEncounter[0] = uiData; + if (uiData == SPECIAL) + { + OpenDoor(m_uiLeviathanGateGUID); + CloseDoor(m_uiShieldDoorGUID); + return; + } DoUseDoorOrButton(m_uiShieldWallGUID); if (uiData == DONE) { OpenDoor(m_uiXT002GateGUID); - OpenDoor(m_uiLeviathanGateGUID); + OpenDoor(m_uiShieldDoorGUID); } break; case TYPE_IGNIS: @@ -995,76 +1071,102 @@ struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance { switch(uiData) { - // Siege - case NPC_LEVIATHAN: - return m_uiLeviathanGUID; - case NPC_IGNIS: - return m_uiIgnisGUID; - case NPC_RAZORSCALE: - return m_uiRazorscaleGUID; - case NPC_COMMANDER: - return m_uiCommanderGUID; - case NPC_XT002: - return m_uiXT002GUID; - // Antechamber - case NPC_STEELBREAKER: - return m_auiAssemblyGUIDs[0]; - case NPC_MOLGEIM: - return m_auiAssemblyGUIDs[1]; - case NPC_BRUNDIR: - return m_auiAssemblyGUIDs[2]; - case NPC_KOLOGARN: - return m_uiKologarnGUID; - case NPC_LEFT_ARM: - return m_uiLeftArmGUID; - case NPC_RIGHT_ARM: - return m_uiRightArmGUID; - case NPC_AURIAYA: - return m_uiAuriayaGUID; - // Keepers - case NPC_MIMIRON: - return m_uiMimironGUID; - case NPC_LEVIATHAN_MK: - return m_uiLeviathanMkGUID; - case NPC_HODIR: - return m_uiMimironGUID; - case NPC_THORIM: - return m_uiThorimGUID; - case NPC_RUNE_GIANT: - return m_uiRuneGiantGUID; - case NPC_RUNIC_COLOSSUS: - return m_uiRunicColossusGUID; - case NPC_JORMUNGAR_BEHEMOTH: - return m_uiJormungarGUID; - case NPC_FREYA: - return m_uiFreyaGUID; - case NPC_BRIGHTLEAF: - return m_uiElderBrightleafGUID; - case NPC_IRONBRACH: - return m_uiElderIronbrachGUID; - case NPC_STONEBARK: - return m_uiElderStonebarkGUID; - case NPC_VEZAX: - return m_uiVezaxGUID; - case NPC_YOGGSARON: - return m_uiYoggSaronGUID; - case NPC_SARA: - return m_uiSaraGUID; - case NPC_YOGG_BRAIN: - return m_uiYoggBrainGUID; - case NPC_ALGALON: - return m_uiAlgalonGUID; - - // mimiron hard mode button - case GO_MIMIRON_BUTTON: - return m_uiMimironButtonGUID; - // thorim encounter starter lever - case GO_DOOR_LEVER: - return m_uiThorimLeverGUID; - // celestial door - case GO_CELESTIAL_DOOR: - return m_uiCelestialDoorGUID; - } + // Siege + case NPC_LEVIATHAN: + return m_uiLeviathanGUID; + case NPC_IGNIS: + return m_uiIgnisGUID; + case NPC_RAZORSCALE: + return m_uiRazorscaleGUID; + case NPC_COMMANDER: + return m_uiCommanderGUID; + case NPC_XT002: + return m_uiXT002GUID; + // Antechamber + case NPC_STEELBREAKER: + return m_auiAssemblyGUIDs[0]; + case NPC_MOLGEIM: + return m_auiAssemblyGUIDs[1]; + case NPC_BRUNDIR: + return m_auiAssemblyGUIDs[2]; + case NPC_KOLOGARN: + return m_uiKologarnGUID; + case NPC_LEFT_ARM: + return m_uiLeftArmGUID; + case NPC_RIGHT_ARM: + return m_uiRightArmGUID; + case NPC_AURIAYA: + return m_uiAuriayaGUID; + // Keepers + case NPC_MIMIRON: + return m_uiMimironGUID; + case NPC_LEVIATHAN_MK: + return m_uiLeviathanMkGUID; + case NPC_HODIR: + return m_uiMimironGUID; + case NPC_THORIM: + return m_uiThorimGUID; + case NPC_RUNE_GIANT: + return m_uiRuneGiantGUID; + case NPC_RUNIC_COLOSSUS: + return m_uiRunicColossusGUID; + case NPC_JORMUNGAR_BEHEMOTH: + return m_uiJormungarGUID; + case NPC_FREYA: + return m_uiFreyaGUID; + case NPC_BRIGHTLEAF: + return m_uiElderBrightleafGUID; + case NPC_IRONBRACH: + return m_uiElderIronbrachGUID; + case NPC_STONEBARK: + return m_uiElderStonebarkGUID; + case NPC_VEZAX: + return m_uiVezaxGUID; + case NPC_YOGGSARON: + return m_uiYoggSaronGUID; + case NPC_SARA: + return m_uiSaraGUID; + case NPC_YOGG_BRAIN: + return m_uiYoggBrainGUID; + case NPC_ALGALON: + return m_uiAlgalonGUID; + + // mimiron hard mode button + case GO_MIMIRON_BUTTON: + return m_uiMimironButtonGUID; + // thorim encounter starter lever + case GO_DOOR_LEVER: + return m_uiThorimLeverGUID; + // celestial door + case GO_CELESTIAL_DOOR: + return m_uiCelestialDoorGUID; + + // Leviathan hard mode + case GO_TOWER_OF_FROST: + return m_uiTowerOfFrostGUID; + case GO_TOWER_OF_FLAME: + return m_uiTowerOfFlameGUID; + case GO_TOWER_OF_LIFE: + return m_uiTowerOfLifeGUID; + case GO_TOWER_OF_STORMS: + return m_uiTowerOfStormsGUID; + case GO_FREYA_STORM_GENERATOR: + return m_uiFreyaStormGeneratorGUID; + case GO_MIMIRON_STORM_GENERATOR: + return m_uiMimironStormGeneratorGUID; + case GO_HODIR_STORM_GENERATOR: + return m_uiHodirStormGeneratorGUID; + case GO_THORIM_WEATHER_GENERATOR: + return m_uiTorimWeatherGeneratorGUID; + case GO_FREYA_TARGETTING_CRYSTAL: + return m_uiFreyaTargettingCrystalGUID; + case GO_MIMIRON_TARGETTING_CRYSTAL: + return m_uiMimironTargettingCrystalGUID; + case GO_THORIM_TARGETTING_CRYSTAL: + return m_uiThorimTargettingCrystalGUID; + case GO_HODIR_TARGETTING_CRYSTAL: + return m_uiHodirTargettingCrystalGUID; + } return 0; } @@ -1239,6 +1341,51 @@ struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance 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); } + + void Update(uint32 uiDiff) + { + if (GameObject* pTowerFrost = instance->GetGameObject(m_uiTowerOfFrostGUID)) + { + if (!pTowerFrost->GetHealth()) + { + if (GameObject* pHodirGenerator = instance->GetGameObject(m_uiHodirStormGeneratorGUID)) + pHodirGenerator->UseDoorOrButton(); + if (GameObject* pHodirCrystal = instance->GetGameObject(m_uiHodirTargettingCrystalGUID)) + pHodirCrystal->UseDoorOrButton(); + } + } + if (GameObject* pTowerFlame = instance->GetGameObject(m_uiTowerOfFlameGUID)) + { + if (!pTowerFlame->GetHealth()) + { + if (GameObject* pMimironGenerator = instance->GetGameObject(m_uiMimironStormGeneratorGUID)) + pMimironGenerator->UseDoorOrButton(); + if (GameObject* pMimironCrystal = instance->GetGameObject(m_uiMimironTargettingCrystalGUID)) + pMimironCrystal->UseDoorOrButton(); + } + } + if (GameObject* pTowerLife = instance->GetGameObject(m_uiTowerOfLifeGUID)) + { + if (!pTowerLife->GetHealth()) + { + if (GameObject* pFreyaGenerator = instance->GetGameObject(m_uiFreyaStormGeneratorGUID)) + pFreyaGenerator->UseDoorOrButton(); + if (GameObject* pFreyaCrystal = instance->GetGameObject(m_uiFreyaTargettingCrystalGUID)) + pFreyaCrystal->UseDoorOrButton(); + } + } + + if (GameObject* pTowerStorm = instance->GetGameObject(m_uiTowerOfStormsGUID)) + { + if (!pTowerStorm->GetHealth()) + { + if (GameObject* pTorimGenerator = instance->GetGameObject(m_uiTorimWeatherGeneratorGUID)) + pTorimGenerator->UseDoorOrButton(); + if (GameObject* pTorimCrystal = instance->GetGameObject(m_uiThorimTargettingCrystalGUID)) + pTorimCrystal->UseDoorOrButton(); + } + } + } }; InstanceData* GetInstanceData_instance_ulduar(Map* pMap) diff --git a/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp b/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp index 95bd5f7..13b9e81 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp @@ -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/instance_utgarde_keep.cpp b/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp index 390b464..37a6307 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp @@ -24,169 +24,177 @@ 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_uiIngvarGUID(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; + case NPC_INGVAR: m_uiIngvarGUID = 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 NPC_INGVAR: return m_uiIngvarGUID; + 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 +203,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 2c66e4a..a75c669 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp +++ b/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp @@ -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 0d682a4..58d9d99 100644 --- a/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h +++ b/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h @@ -7,21 +7,71 @@ 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_INGVAR = 23954, + 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_INGVAR_DOOR = 186612 + + 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_uiIngvarGUID; + + 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/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp b/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp index 0bb648a..bea06f3 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp @@ -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 6a07f41..84ef3b9 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp @@ -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 568eaea..8c5e042 100644 --- a/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp +++ b/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp @@ -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/black_temple/boss_illidan.cpp b/scripts/outland/black_temple/boss_illidan.cpp index 327ef97..ca22719 100644 --- a/scripts/outland/black_temple/boss_illidan.cpp +++ b/scripts/outland/black_temple/boss_illidan.cpp @@ -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); @@ -2273,6 +2274,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 { @@ -2286,7 +2290,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)) @@ -2300,6 +2304,7 @@ struct MANGOS_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI } } }; +*/ struct MANGOS_DLL_DECL blazeAI : public ScriptedAI { @@ -2401,10 +2406,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() { @@ -2467,8 +2474,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_supremus.cpp b/scripts/outland/black_temple/boss_supremus.cpp index 0ea7b22..818cb1d 100644 --- a/scripts/outland/black_temple/boss_supremus.cpp +++ b/scripts/outland/black_temple/boss_supremus.cpp @@ -235,7 +235,7 @@ struct MANGOS_DLL_DECL boss_supremusAI : public ScriptedAI { Unit* pUnit = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); - if (pUnit && m_creature->IsWithinDistInMap(pUnit, ATTACK_DISTANCE)) + if (pUnit && m_creature->CanReachWithMeleeAttack(pUnit)) { if (pUnit->GetHealth() > health) { 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 9dff4d5..8639580 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_fathomlord_karathress.cpp @@ -407,7 +407,7 @@ struct MANGOS_DLL_DECL boss_fathomguard_sharkkisAI : public Advisor_Base_AI { 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); } 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 a6194b5..dd55617 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_lady_vashj.cpp @@ -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_morogrim_tidewalker.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp index 9cb11ee..945445d 100644 --- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp +++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_morogrim_tidewalker.cpp @@ -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/gruuls_lair/boss_gruul.cpp b/scripts/outland/gruuls_lair/boss_gruul.cpp index f5561cf..1aba7b7 100644 --- a/scripts/outland/gruuls_lair/boss_gruul.cpp +++ b/scripts/outland/gruuls_lair/boss_gruul.cpp @@ -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 || 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 b6fcd4c..e31e7fe 100644 --- a/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp +++ b/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp @@ -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/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp b/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp index f147107..c7e7c0a 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 @@ -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/tempest_keep/the_eye/boss_astromancer.cpp b/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp index d71bb0e..3850ac6 100644 --- a/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp +++ b/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp @@ -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,7 +153,7 @@ 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); @@ -151,236 +161,269 @@ struct MANGOS_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI 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(); } }; @@ -394,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(); } @@ -460,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 fbda4c6..a265857 100644 --- a/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp +++ b/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp @@ -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/terokkar_forest.cpp b/scripts/outland/terokkar_forest.cpp index f2cf866..9438a9c 100644 --- a/scripts/outland/terokkar_forest.cpp +++ b/scripts/outland/terokkar_forest.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Terokkar_Forest SD%Complete: 80 -SDComment: Quest support: 9889, 10009, 10873, 10896, 10446/10447, 10852, 10887, 10922, 11096, 11093. 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 */ @@ -36,6 +36,7 @@ npc_skyguard_handler_deesak npc_slim go_veil_skith_cage npc_captive_child +npc_isla_starmane EndContentData */ #include "precompiled.h" @@ -46,28 +47,31 @@ EndContentData */ ## 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); } @@ -80,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(); } @@ -152,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); @@ -176,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) @@ -224,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->GetGUID()); } 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); } } } @@ -350,7 +369,7 @@ CreatureAI* GetAI_npc_akuno(Creature* pCreature) } /*###### -## npc_floon +## npc_floon -- TODO move to EventAI and WorldDB (gossip) ######*/ enum @@ -450,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" @@ -969,83 +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->HandleEmoteCommand(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->pQuestAcceptNPC = &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_hungry_nether_ray"; - newscript->GetAI = &GetAI_npc_hungry_nether_ray; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_letoll"; - newscript->GetAI = &GetAI_npc_letoll; - newscript->pQuestAcceptNPC = &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->pGOUse = &GOUse_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->pGOUse = &GOUse_go_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/world/mob_generic_creature.cpp b/scripts/world/mob_generic_creature.cpp index 279960e..065af99 100644 --- a/scripts/world/mob_generic_creature.cpp +++ b/scripts/world/mob_generic_creature.cpp @@ -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/spell_scripts.cpp b/scripts/world/spell_scripts.cpp index 1462d45..2ef2290 100644 --- a/scripts/world/spell_scripts.cpp +++ b/scripts/world/spell_scripts.cpp @@ -35,6 +35,7 @@ spell 50706 spell 45109 spell 45111 spell 39246 +spell 52090 EndContentData */ #include "precompiled.h" @@ -264,6 +265,10 @@ 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 }; bool EffectAuraDummy_spell_aura_dummy_npc(const Aura* pAura, bool bApply) @@ -737,6 +742,19 @@ 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; + } } return false; diff --git a/sql/Updates/r1979_scriptdev2.sql b/sql/Updates/r1979_scriptdev2.sql new file mode 100644 index 0000000..9ade737 --- /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 0000000..da0cca6 --- /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 0000000..bf4a6d6 --- /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 0000000..15fdc02 --- /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 0000000..a7aa8a2 --- /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/custom/reservation/mangos_ulduar_raid.sql b/sql/custom/reservation/mangos_ulduar_raid.sql index a6fea5c..eb661a2 100644 --- a/sql/custom/reservation/mangos_ulduar_raid.sql +++ b/sql/custom/reservation/mangos_ulduar_raid.sql @@ -1,31 +1,79 @@ /* 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; + UPDATE creature_template SET ScriptName = 'boss_flame_leviathan' WHERE entry = 33113; + UPDATE creature_template SET ScriptName = 'mob_defense_turret' WHERE entry = 33142; + UPDATE creature_template SET ScriptName = 'mob_pool_of_tar' WHERE entry = 33090; + UPDATE creature_template SET ScriptName = 'mob_mechanolift' WHERE entry = 33214; + UPDATE creature_template SET ScriptName = 'mob_freyas_ward' WHERE entry = 33367; + UPDATE creature_template SET ScriptName = 'mob_hodirs_fury' WHERE entry = 33212; + UPDATE creature_template SET ScriptName = 'mob_mimiron_inferno' WHERE entry = 33370; + UPDATE creature_template SET ScriptName = 'mob_thorims_hammer' WHERE entry = 33365; + UPDATE creature_template SET ScriptName = 'mob_lorekeeper' WHERE entry=33686; + + -- grünes leuchten + DELETE FROM spell_script_target WHERE spell_script_target.entry = 63295; + INSERT INTO spell_script_target (entry, type, targetEntry) VALUES (63295,1,33367); + -- blaues leuchten + DELETE FROM spell_script_target WHERE spell_script_target.entry = 63294; + INSERT INTO spell_script_target (entry, type, targetEntry) VALUES (63294,1,33212),(63294,1,33365); + -- gelbes(rotes) leuchten + DELETE FROM spell_script_target WHERE spell_script_target.entry = 63292; + INSERT INTO spell_script_target (entry, type, targetEntry) VALUES (63292,1,33370); + + + -- Freya Wall (Pflanzen) + DELETE FROM spell_script_target WHERE spell_script_target.entry = 62906; + INSERT INTO spell_script_target (entry, type, targetEntry) VALUES (62906,1,33060),(62906,1,33109) ; + + -- Hodir Fury (Eis) + DELETE FROM spell_script_target WHERE spell_script_target.entry = 62533; + INSERT INTO spell_script_target (entry, type, targetEntry) VALUES (62533,1,33060),(62533,1,33109); + + -- mimiron inferno (Feuer) + DELETE FROM spell_script_target WHERE spell_script_target.entry = 62909; + INSERT INTO spell_script_target (entry, type, targetEntry) VALUES (62909,1,33369); + + -- Thorim Hammer + DELETE FROM spell_script_target WHERE spell_script_target.entry = 62911 ; + INSERT INTO spell_script_target (entry, type, targetEntry) VALUES (62911 ,1,33060),(62911 ,1,33109); -- 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; + 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; + 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); + UPDATE creature SET position_x = 590.346741, position_y = -226.947647, position_z = 442.897583 WHERE id = 33186; + + DELETE FROM spell_script_target WHERE spell_script_target.entry = 63524; + INSERT INTO spell_script_target VALUES (63524 ,1,33282); + DELETE FROM spell_script_target WHERE spell_script_target.entry = 63657; + INSERT INTO spell_script_target VALUES (63657 ,1,33282); + DELETE FROM spell_script_target WHERE spell_script_target.entry = 63658; + INSERT INTO spell_script_target VALUES (63658 ,1,33282); + DELETE FROM spell_script_target WHERE spell_script_target.entry = 63659; + INSERT INTO spell_script_target VALUES (63659 ,1,33282); + + DELETE FROM spell_script_target WHERE spell_script_target.entry = 62505; + INSERT INTO spell_script_target VALUES (62505 ,1,33186); + + + UPDATE gameobject_template SET data3 = 180000, ScriptName='go_repair_harpoon' WHERE entry IN (194543,194542,194541,194519); + -- 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; diff --git a/sql/mangos_scriptname_full.sql b/sql/mangos_scriptname_full.sql index 6b0cb7e..fefb13f 100644 --- a/sql/mangos_scriptname_full.sql +++ b/sql/mangos_scriptname_full.sql @@ -135,7 +135,7 @@ UPDATE creature_template SET ScriptName='npc_tabard_vendor' WHERE entry=28776; UPDATE creature_template SET ScriptName='npc_locksmith' WHERE entry IN (29665,29725,29728); /* 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,17326,17654,16847,18879,26270,26268,30146,25084,25085,32149,22105,29330,29338,29329,28465,28600); UPDATE gameobject_template SET ScriptName='spell_dummy_go' WHERE entry IN (181616,186949); /* */ @@ -293,6 +293,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; @@ -567,7 +568,7 @@ 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 */ @@ -1121,6 +1122,7 @@ 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; @@ -1213,9 +1215,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); diff --git a/sql/scriptdev2_script_full.sql b/sql/scriptdev2_script_full.sql index 704a5fd..93e06b3 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 10950+) '); +INSERT INTO sd2_db_version (version) VALUES ('ScriptDev2 (for MaNGOS 11167+) '); -- -- Below contains data for table `script_texts` mainly used in C++ parts. @@ -670,7 +670,14 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-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'); +(-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'); -- -1 033 000 SHADOWFANG KEEP INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES @@ -720,7 +727,7 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-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'), +(-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'), @@ -744,35 +751,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 @@ -2930,7 +2939,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 @@ -5270,28 +5298,143 @@ 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, ''); -- EOF diff --git a/system/ScriptLoader.cpp b/system/ScriptLoader.cpp index 905bb8a..d318f4e 100644 --- a/system/ScriptLoader.cpp +++ b/system/ScriptLoader.cpp @@ -309,7 +309,8 @@ extern void AddSC_boss_moorabi(); extern void AddSC_boss_sladran(); extern void AddSC_instance_gundrak(); -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(); @@ -346,6 +347,7 @@ 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(); @@ -820,7 +822,8 @@ void AddScripts() AddSC_boss_sladran(); AddSC_instance_gundrak(); - 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(); @@ -857,6 +860,7 @@ void AddScripts() AddSC_boss_eregos(); AddSC_boss_malygos(); //eye of eternity + AddSC_instance_eye_of_eternity(); AddSC_boss_sartharion(); //obsidian_sanctum AddSC_instance_obsidian_sanctum(); diff --git a/system/system.cpp b/system/system.cpp index 70e5d89..a9fb789 100644 --- a/system/system.cpp +++ b/system/system.cpp @@ -4,6 +4,7 @@ #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 9f87d67..2b716c1 100644 --- a/system/system.h +++ b/system/system.h @@ -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