diff --git a/Makefile.am b/Makefile.am
index 2acab3b..183bead 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,6 +36,10 @@ 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 \
@@ -49,6 +53,8 @@ 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 \
@@ -79,6 +85,7 @@ 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 \
@@ -101,6 +108,7 @@ 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 \
@@ -128,6 +136,7 @@ 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 \
@@ -178,6 +187,7 @@ scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp \
scripts/eastern_kingdoms/scholomance/boss_vectus.cpp \
scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp \
scripts/eastern_kingdoms/scholomance/scholomance.h \
+scripts/eastern_kingdoms/shadowfang_keep/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 \
@@ -199,7 +209,11 @@ 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 \
@@ -258,9 +272,6 @@ scripts/kalimdor/ungoro_crater.cpp \
scripts/kalimdor/winterspring.cpp \
scripts/kalimdor/blackfathom_deeps/blackfathom_deeps.h \
scripts/kalimdor/blackfathom_deeps/instance_blackfathom_deeps.cpp \
-scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h \
-scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp \
-scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp \
scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp \
scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp \
scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp \
@@ -280,6 +291,7 @@ 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 \
@@ -329,8 +341,8 @@ 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_amanitar.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 \
@@ -341,55 +353,56 @@ scripts/northrend/azjol-nerub/azjol-nerub/boss_anubarak.cpp \
scripts/northrend/azjol-nerub/azjol-nerub/boss_hadronox.cpp \
scripts/northrend/azjol-nerub/azjol-nerub/boss_krikthir.cpp \
scripts/northrend/azjol-nerub/azjol-nerub/instance_azjol-nerub.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp \
-scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h \
+scripts/northrend/draktharon_keep/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_eck.cpp \
scripts/northrend/gundrak/boss_colossus.cpp \
+scripts/northrend/gundrak/boss_eck.cpp \
scripts/northrend/gundrak/boss_galdarah.cpp \
scripts/northrend/gundrak/boss_moorabi.cpp \
scripts/northrend/gundrak/boss_sladran.cpp \
scripts/northrend/gundrak/gundrak.h \
scripts/northrend/gundrak/instance_gundrak.cpp \
-scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falryn.cpp \
-scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp \
-scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp \
+scripts/northrend/icecrown_citadel/frozen_halls/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/forge_of_souls/boss_bronjahm.cpp \
-scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp \
-scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.h \
-scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp \
-scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp \
-scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp \
+scripts/northrend/icecrown_citadel/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_festergut.cpp \
scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp \
scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp \
+scripts/northrend/icecrown_citadel/icecrown_citadel/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 \
@@ -407,19 +420,30 @@ 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/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/boss_zarithian.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 \
@@ -428,26 +452,28 @@ 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/halls_of_stone.h \
+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/assembly_of_iron.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_flame_leviathan.cpp \
scripts/northrend/ulduar/ulduar/boss_freya.cpp \
-scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp \
scripts/northrend/ulduar/ulduar/boss_hodir.cpp \
scripts/northrend/ulduar/ulduar/boss_ignis.cpp \
+scripts/northrend/ulduar/ulduar/boss_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_xt_002.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/instance_ulduar.cpp \
scripts/northrend/ulduar/ulduar/ulduar.cpp \
-scripts/northrend/ulduar/ulduar/ulduar.h \
+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 \
@@ -460,16 +486,12 @@ scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp \
scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp \
scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_utgarde_pinnacle.cpp \
scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h \
-scripts/northrend/violet_hold/boss_cyanigosa.cpp \
-scripts/northrend/violet_hold/boss_erekem.cpp \
-scripts/northrend/violet_hold/boss_ichoron.cpp \
-scripts/northrend/violet_hold/boss_lavanthor.cpp \
-scripts/northrend/violet_hold/boss_moragg.cpp \
-scripts/northrend/violet_hold/boss_xevozz.cpp \
-scripts/northrend/violet_hold/boss_zuramat.cpp \
-scripts/northrend/violet_hold/instance_violet_hold.cpp \
-scripts/northrend/violet_hold/violet_hold.cpp \
-scripts/northrend/violet_hold/violet_hold.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 \
@@ -481,8 +503,10 @@ 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_tailonking_ikiss.cpp \
scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp \
@@ -513,6 +537,7 @@ 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 \
@@ -554,12 +579,45 @@ scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp \
scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp \
scripts/outland/tempest_keep/the_eye/the_eye.cpp \
scripts/outland/tempest_keep/the_eye/the_eye.h \
-scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp \
scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp \
scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp \
scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp \
scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp \
scripts/outland/tempest_keep/the_mechanar/mechanar.h \
+scripts/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 \
diff --git a/ScriptMgr.cpp b/ScriptMgr.cpp
index 731fae4..564529b 100644
--- a/ScriptMgr.cpp
+++ b/ScriptMgr.cpp
@@ -17,10 +17,16 @@ Script *m_scripts[MAX_SCRIPTS];
Config SD2Config;
+QueryResult* strSD2Pquery(char* str)
+{
+return SD2Database.Query(str);
+}
+
void FillSpellSummary();
void LoadDatabase()
{
+
std::string strSD2DBinfo = SD2Config.GetStringDefault("ScriptDev2DatabaseInfo", "");
if (strSD2DBinfo.empty())
@@ -47,8 +53,6 @@ void LoadDatabase()
return;
}
- SD2Database.HaltDelayThread();
-
}
struct TSpellSummary {
@@ -67,6 +71,7 @@ void ScriptsFree()
delete m_scripts[i];
num_sc_scripts = 0;
+ SD2Database.HaltDelayThread();
}
MANGOS_DLL_EXPORT
@@ -270,7 +275,9 @@ bool GossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32
if (!tmpscript || !tmpscript->pGossipSelect)
return false;
- pPlayer->PlayerTalkClass->ClearMenus();
+// pPlayer->PlayerTalkClass->ClearMenus();
+// this expression is wrong, where 'return false' from script's GossipSelect
+// not return menu ID (cleared in this string) and not allow to work with database-based menus
return tmpscript->pGossipSelect(pPlayer, pCreature, uiSender, uiAction);
}
diff --git a/ScriptMgr.h b/ScriptMgr.h
index 66d7685..3ed890b 100644
--- a/ScriptMgr.h
+++ b/ScriptMgr.h
@@ -7,6 +7,7 @@
#include "Common.h"
#include "DBCStructure.h"
+#include "Database/DatabaseEnv.h"
class Player;
class Creature;
@@ -75,6 +76,9 @@ struct Script
//Generic scripting text function
void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget = NULL);
+//DB query
+QueryResult* strSD2Pquery(char*);
+
#if COMPILER == COMPILER_GNU
#define FUNC_PTR(name,callconvention,returntype,parameters) typedef returntype(*name)parameters __attribute__ ((callconvention));
#else
diff --git a/VC100/100ScriptDev2.vcxproj b/VC100/100ScriptDev2.vcxproj
index a7eabb3..6c7eda5 100644
--- a/VC100/100ScriptDev2.vcxproj
+++ b/VC100/100ScriptDev2.vcxproj
@@ -210,10 +210,15 @@
+
+
+
+
+
@@ -243,6 +248,7 @@
+
@@ -289,6 +295,7 @@
+
@@ -334,6 +341,7 @@
+
@@ -352,10 +360,13 @@
+
+
+
+
-
@@ -389,6 +400,13 @@
+
+
+
+
+
+
+
@@ -423,6 +441,8 @@
+
+
@@ -452,19 +472,9 @@
+
+
-
-
-
-
-
-
-
-
-
-
-
-
@@ -475,6 +485,12 @@
+
+
+
+
+
+
@@ -482,14 +498,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -506,38 +561,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
+
+
+
@@ -548,29 +620,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -582,8 +645,10 @@
+
+
@@ -608,7 +673,9 @@
+
+
@@ -673,11 +740,15 @@
+
+
+
+
@@ -694,28 +765,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
diff --git a/VC100/100ScriptDev2.vcxproj.filters b/VC100/100ScriptDev2.vcxproj.filters
index 53595c0..1b15e87 100644
--- a/VC100/100ScriptDev2.vcxproj.filters
+++ b/VC100/100ScriptDev2.vcxproj.filters
@@ -309,6 +309,9 @@
base
+
+ base
+
scripts\battlegrounds
@@ -399,6 +402,9 @@
scripts\eastern_kingdoms\blackrock_depths
+
+ scripts\eastern_kingdoms\blackrock_depths
+
scripts\eastern_kingdoms\blackrock_depths
@@ -537,6 +543,9 @@
scripts\eastern_kingdoms\karazhan
+
+ scripts\eastern_kingdoms\karazhan
+
scripts\eastern_kingdoms\karazhan
@@ -672,6 +681,9 @@
scripts\eastern_kingdoms\scholomance
+
+ scripts\eastern_kingdoms\shadowfang_keep
+
scripts\eastern_kingdoms\shadowfang_keep
@@ -726,18 +738,27 @@
scripts\eastern_kingdoms\sunwell_plateau
+
+ scripts\eastern_kingdoms\sunwell_plateau
+
+
+ scripts\eastern_kingdoms\sunwell_plateau
+
scripts\eastern_kingdoms\sunwell_plateau
+
+ scripts\eastern_kingdoms\sunwell_plateau
+
+
+ scripts\eastern_kingdoms\sunwell_plateau
+
scripts\eastern_kingdoms\sunwell_plateau
scripts\eastern_kingdoms\uldaman
-
- scripts\eastern_kingdoms\uldaman
-
scripts\eastern_kingdoms\uldaman
@@ -939,6 +960,12 @@
scripts\kalimdor\caverns_of_time\old_hillsbrad
+
+ scripts\kalimdor\dire_maul
+
+
+ scripts\kalimdor\dire_maul
+
scripts\kalimdor\maraudon
@@ -1026,185 +1053,504 @@
scripts\kalimdor\wailing_caverns
-
+
scripts\kalimdor\zulfarrak
-
- scripts\northrend
+
+ scripts\kalimdor\zulfarrak
-
- scripts\northrend
+
+ scripts\kalimdor\zulfarrak
-
- scripts\northrend
+
+ scripts\outland
-
- scripts\northrend
+
+ scripts\outland
-
- scripts\northrend
+
+ scripts\outland
-
- scripts\northrend
+
+ scripts\outland
-
- scripts\northrend
+
+ scripts\outland
-
- scripts\northrend
+
+ scripts\outland
-
- scripts\northrend
+
+ scripts\outland
-
- scripts\northrend\azjol-nerub\ahnkahet
+
+ scripts\outland
-
- scripts\northrend\azjol-nerub\ahnkahet
+
+ scripts\outland
-
- scripts\northrend\azjol-nerub\ahnkahet
+
+ scripts\outland
-
- scripts\northrend\azjol-nerub\ahnkahet
+
+ scripts\outland\auchindoun\auchenai_crypts
-
- scripts\northrend\azjol-nerub\ahnkahet
+
+ scripts\outland\auchindoun\mana_tombs
-
- scripts\northrend\azjol-nerub\azjol-nerub
+
+ scripts\outland\auchindoun\mana_tombs
-
- scripts\northrend\azjol-nerub\azjol-nerub
+
+ scripts\outland\auchindoun\sethekk_halls
-
- scripts\northrend\azjol-nerub\azjol-nerub
+
+ scripts\outland\auchindoun\sethekk_halls
-
- scripts\northrend\azjol-nerub\azjol-nerub
+
+ scripts\outland\auchindoun\sethekk_halls
-
- scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\outland\auchindoun\shadow_labyrinth
-
- scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\outland\auchindoun\shadow_labyrinth
-
- scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\outland\auchindoun\shadow_labyrinth
-
- scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\outland\auchindoun\shadow_labyrinth
-
- scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\outland\auchindoun\shadow_labyrinth
-
- scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\outland\black_temple
-
- scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\outland\black_temple
-
- scripts\northrend\draktharon_keep
+
+ scripts\outland\black_temple
-
- scripts\northrend\draktharon_keep
+
+ scripts\outland\black_temple
-
- scripts\northrend\draktharon_keep
+
+ scripts\outland\black_temple
-
- scripts\northrend\gundrak
+
+ scripts\outland\black_temple
-
- scripts\northrend\gundrak
+
+ scripts\outland\black_temple
-
- scripts\northrend\gundrak
+
+ scripts\outland\black_temple
-
- scripts\northrend\gundrak
+
+ scripts\outland\black_temple
-
- scripts\northrend\gundrak
+
+ scripts\outland\black_temple
-
- scripts\northrend\naxxramas
+
+ scripts\outland\black_temple
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\serpent_shrine
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\serpent_shrine
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\serpent_shrine
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\serpent_shrine
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\serpent_shrine
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\serpent_shrine
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\steam_vault
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\steam_vault
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\steam_vault
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\steam_vault
-
- scripts\northrend\naxxramas
+
+ scripts\outland\coilfang_reservoir\underbog
-
- scripts\northrend\naxxramas
+
+ scripts\outland\gruuls_lair
-
- scripts\northrend\naxxramas
+
+ scripts\outland\gruuls_lair
-
- scripts\northrend\naxxramas
+
+ scripts\outland\gruuls_lair
-
- scripts\northrend\naxxramas
+
+ scripts\outland\hellfire_citadel\blood_furnace
-
- scripts\northrend\nexus\nexus
+
+ scripts\outland\hellfire_citadel\blood_furnace
-
- scripts\northrend\nexus\nexus
+
+ scripts\outland\hellfire_citadel\blood_furnace
-
- scripts\northrend\nexus\nexus
+
+ scripts\outland\hellfire_citadel\blood_furnace
-
- scripts\northrend\nexus\nexus
+
+ scripts\outland\hellfire_citadel\hellfire_ramparts
-
- scripts\northrend\nexus\nexus
+
+ scripts\outland\hellfire_citadel\hellfire_ramparts
-
- scripts\northrend\obsidian_sanctum
+
+ scripts\outland\hellfire_citadel\hellfire_ramparts
-
- scripts\northrend\obsidian_sanctum
+
+ scripts\outland\hellfire_citadel\hellfire_ramparts
-
- scripts\northrend\ulduar\halls_of_lightning
+
+ scripts\outland\hellfire_citadel\magtheridons_lair
-
- scripts\northrend\ulduar\halls_of_lightning
+
+ scripts\outland\hellfire_citadel\magtheridons_lair
-
- scripts\northrend\ulduar\halls_of_lightning
+
+ scripts\outland\hellfire_citadel\shattered_halls
+
+
+ scripts\outland\hellfire_citadel\shattered_halls
+
+
+ scripts\outland\hellfire_citadel\shattered_halls
+
+
+ scripts\outland\hellfire_citadel\shattered_halls
+
+
+ scripts\outland\tempest_keep\arcatraz
+
+
+ scripts\outland\tempest_keep\arcatraz
+
+
+ scripts\outland\tempest_keep\arcatraz
+
+
+ scripts\outland\tempest_keep\botanica
+
+
+ scripts\outland\tempest_keep\botanica
+
+
+ scripts\outland\tempest_keep\botanica
+
+
+ scripts\outland\tempest_keep\the_eye
+
+
+ scripts\outland\tempest_keep\the_eye
+
+
+ scripts\outland\tempest_keep\the_eye
+
+
+ scripts\outland\tempest_keep\the_eye
+
+
+ scripts\outland\tempest_keep\the_eye
+
+
+ scripts\outland\tempest_keep\the_mechanar
+
+
+ scripts\outland\tempest_keep\the_mechanar
+
+
+ scripts\outland\tempest_keep\the_mechanar
+
+
+ scripts\outland\tempest_keep\the_mechanar
+
+
+ scripts\outland\tempest_keep\the_mechanar
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ scripts\world
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ system
+
+
+ system
+
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend
+
+
+ scripts\northrend\azjol-nerub\ahnkahet
+
+
+ scripts\northrend\azjol-nerub\ahnkahet
+
+
+ scripts\northrend\azjol-nerub\ahnkahet
+
+
+ scripts\northrend\azjol-nerub\ahnkahet
+
+
+ scripts\northrend\azjol-nerub\ahnkahet
+
+
+ scripts\northrend\azjol-nerub\ahnkahet
+
+
+ scripts\northrend\azjol-nerub\azjol-nerub
+
+
+ scripts\northrend\azjol-nerub\azjol-nerub
+
+
+ scripts\northrend\azjol-nerub\azjol-nerub
+
+
+ scripts\northrend\azjol-nerub\azjol-nerub
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_champion
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_champion
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_champion
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_champion
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_champion
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\draktharon_keep
+
+
+ scripts\northrend\draktharon_keep
+
+
+ scripts\northrend\draktharon_keep
+
+
+ scripts\northrend\draktharon_keep
+
+
+ scripts\northrend\draktharon_keep
+
+
+ scripts\northrend\gundrak
+
+
+ scripts\northrend\gundrak
+
+
+ scripts\northrend\gundrak
+
+
+ scripts\northrend\gundrak
+
+
+ scripts\northrend\gundrak
+
+
+ scripts\northrend\gundrak
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\nexus\eye_of_eternity
+
+
+ scripts\northrend\nexus\nexus
+
+
+ scripts\northrend\nexus\nexus
+
+
+ scripts\northrend\nexus\nexus
+
+
+ scripts\northrend\nexus\nexus
+
+
+ scripts\northrend\nexus\nexus
+
+
+ scripts\northrend\obsidian_sanctum
+
+
+ scripts\northrend\obsidian_sanctum
+
+
+ scripts\northrend\ulduar\halls_of_lightning
+
+
+ scripts\northrend\ulduar\halls_of_lightning
+
+
+ scripts\northrend\ulduar\halls_of_lightning
scripts\northrend\ulduar\halls_of_lightning
@@ -1269,45 +1615,69 @@
scripts\northrend\ulduar\ulduar
-
- scripts\northrend\ulduar\ulduar
+
+ scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls
-
- scripts\northrend\utgarde_keep\utgarde_keep
+
+ scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls
-
- scripts\northrend\utgarde_keep\utgarde_keep
+
+ scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls
-
- scripts\northrend\utgarde_keep\utgarde_keep
+
+ scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls
-
- scripts\northrend\utgarde_keep\utgarde_keep
+
+ scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
-
- scripts\northrend\utgarde_keep\utgarde_keep
+
+ scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
-
- scripts\northrend\utgarde_keep\utgarde_pinnacle
+
+ scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
-
- scripts\northrend\utgarde_keep\utgarde_pinnacle
+
+ scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
-
- scripts\northrend\utgarde_keep\utgarde_pinnacle
+
+ scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
-
- scripts\northrend\utgarde_keep\utgarde_pinnacle
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
-
- scripts\northrend\utgarde_keep\utgarde_pinnacle
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
-
+
+ scripts\northrend\vault_of_archavon
+
+
+ scripts\northrend\vault_of_archavon
+
+
+ scripts\northrend\vault_of_archavon
+
+
+ scripts\northrend\vault_of_archavon
+
+
+ scripts\northrend\vault_of_archavon
+
+
scripts\northrend\violet_hold
-
+
+ scripts\northrend\violet_hold
+
+
scripts\northrend\violet_hold
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
+
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
+
scripts\northrend\icecrown_citadel\icecrown_citadel
@@ -1344,6 +1714,9 @@
scripts\northrend\icecrown_citadel\icecrown_citadel
+
+ scripts\northrend\icecrown_citadel\icecrown_citadel
+
scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
@@ -1353,14 +1726,11 @@
scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
-
- scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
-
-
- scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
-
- scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls
@@ -1374,296 +1744,319 @@
scripts\outland
-
- scripts\outland
+
+ scripts\northrend\icecrown_citadel\icecrown_citadel
-
- scripts\outland
+
+ scripts\northrend\icecrown_citadel\icecrown_citadel
-
- scripts\outland
+
+ scripts\northrend\naxxramas
-
- scripts\outland
+
+ scripts\northrend\naxxramas
-
- scripts\outland
+
+ scripts\northrend\naxxramas
-
- scripts\outland
+
+ scripts\northrend\naxxramas
-
- scripts\outland
+
+ scripts\northrend\naxxramas
-
- scripts\outland
+
+ scripts\northrend\naxxramas
-
- scripts\outland
+
+ scripts\northrend\naxxramas
-
+
+ scripts\northrend\naxxramas
+
+
scripts\outland\auchindoun\auchenai_crypts
scripts\outland\auchindoun\mana_tombs
-
- scripts\outland\auchindoun\mana_tombs
+
+ scripts\northrend\naxxramas
-
+
scripts\outland\auchindoun\sethekk_halls
-
+
scripts\outland\auchindoun\sethekk_halls
-
- scripts\outland\auchindoun\sethekk_halls
+
+ scripts\northrend\naxxramas
-
- scripts\outland\auchindoun\shadow_labyrinth
+
+ scripts\northrend\naxxramas
-
- scripts\outland\auchindoun\shadow_labyrinth
+
+ scripts\northrend\naxxramas
-
- scripts\outland\auchindoun\shadow_labyrinth
+
+ scripts\northrend\naxxramas
-
- scripts\outland\auchindoun\shadow_labyrinth
+
+ scripts\northrend\naxxramas
-
- scripts\outland\auchindoun\shadow_labyrinth
+
+ scripts\northrend\nexus\eye_of_eternity
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\eye_of_eternity
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\nexus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\nexus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\nexus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\nexus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\nexus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\oculus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\oculus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\oculus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\oculus
-
- scripts\outland\black_temple
+
+ scripts\northrend\nexus\oculus
-
- scripts\outland\coilfang_reservoir\serpent_shrine
+
+ scripts\northrend\nexus\oculus
-
- scripts\outland\coilfang_reservoir\serpent_shrine
+
+ scripts\northrend\obsidian_sanctum
-
- scripts\outland\coilfang_reservoir\serpent_shrine
+
+ scripts\northrend\obsidian_sanctum
-
- scripts\outland\coilfang_reservoir\serpent_shrine
+
+ scripts\northrend\ruby_sanctum
-
- scripts\outland\coilfang_reservoir\serpent_shrine
+
+ scripts\northrend\ruby_sanctum
-
+
+ scripts\northrend\ruby_sanctum
+
+
+ scripts\northrend\ruby_sanctum
+
+
+ scripts\northrend\ruby_sanctum
+
+
+ scripts\northrend\ruby_sanctum
+
+
+ scripts\northrend\ulduar\halls_of_lightning
+
+
+ scripts\northrend\ulduar\halls_of_lightning
+
+
scripts\outland\coilfang_reservoir\serpent_shrine
+
+ scripts\outland\coilfang_reservoir\slave_pens
+
scripts\outland\coilfang_reservoir\steam_vault
-
- scripts\outland\coilfang_reservoir\steam_vault
+
+ scripts\northrend\ulduar\halls_of_lightning
-
- scripts\outland\coilfang_reservoir\steam_vault
+
+ scripts\northrend\ulduar\halls_of_stone
-
- scripts\outland\coilfang_reservoir\steam_vault
+
+ scripts\northrend\ulduar\halls_of_stone
-
- scripts\outland\coilfang_reservoir\underbog
+
+ scripts\northrend\ulduar\halls_of_stone
-
- scripts\outland\gruuls_lair
+
+ scripts\northrend\ulduar\halls_of_stone
-
- scripts\outland\gruuls_lair
+
+ scripts\northrend\ulduar\halls_of_stone
-
- scripts\outland\gruuls_lair
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\blood_furnace
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\blood_furnace
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\blood_furnace
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\blood_furnace
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\hellfire_ramparts
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\hellfire_ramparts
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\hellfire_ramparts
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\hellfire_ramparts
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\magtheridons_lair
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\magtheridons_lair
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\shattered_halls
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\shattered_halls
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\shattered_halls
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\hellfire_citadel\shattered_halls
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\tempest_keep\arcatraz
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\tempest_keep\arcatraz
+
+ scripts\northrend\ulduar\ulduar
-
- scripts\outland\tempest_keep\arcatraz
+
+ scripts\northrend\utgarde_keep\utgarde_keep
-
- scripts\outland\tempest_keep\botanica
+
+ scripts\northrend\utgarde_keep\utgarde_keep
-
- scripts\outland\tempest_keep\botanica
+
+ scripts\northrend\utgarde_keep\utgarde_keep
-
- scripts\outland\tempest_keep\botanica
+
+ scripts\northrend\utgarde_keep\utgarde_keep
-
- scripts\outland\tempest_keep\the_eye
+
+ scripts\northrend\utgarde_keep\utgarde_keep
-
- scripts\outland\tempest_keep\the_eye
+
+ scripts\northrend\utgarde_keep\utgarde_pinnacle
-
- scripts\outland\tempest_keep\the_eye
+
+ scripts\northrend\utgarde_keep\utgarde_pinnacle
-
- scripts\outland\tempest_keep\the_eye
+
+ scripts\northrend\utgarde_keep\utgarde_pinnacle
-
- scripts\outland\tempest_keep\the_eye
+
+ scripts\northrend\utgarde_keep\utgarde_pinnacle
-
- scripts\outland\tempest_keep\the_mechanar
+
+ scripts\northrend\utgarde_keep\utgarde_pinnacle
-
- scripts\outland\tempest_keep\the_mechanar
+
+ scripts\northrend\vault_of_archavon
-
- scripts\outland\tempest_keep\the_mechanar
+
+ scripts\northrend\vault_of_archavon
-
- scripts\outland\tempest_keep\the_mechanar
+
+ scripts\northrend\vault_of_archavon
-
- scripts\outland\tempest_keep\the_mechanar
+
+ scripts\northrend\vault_of_archavon
-
- scripts\world
+
+ scripts\northrend\vault_of_archavon
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ scripts\northrend\violet_hold
-
- scripts\world
+
+ base
-
- scripts\world
+
+ base
-
- include
+
+ scripts\custom
-
- include
+
+ scripts\custom
-
- include
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
-
- include
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
-
- system
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
-
- system
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
-
-
- scripts\northrend\ruby_sanctum
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
-
- scripts\northrend\ruby_sanctum
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
-
- scripts\northrend\ruby_sanctum
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
-
+
scripts\northrend\ruby_sanctum
@@ -1677,12 +2070,18 @@
base
+
+ base
+
scripts\eastern_kingdoms\blackrock_depths
scripts\eastern_kingdoms\blackrock_depths
+
+ scripts\eastern_kingdoms\blackwing_lair
+
scripts\eastern_kingdoms\deadmines
@@ -1743,6 +2142,9 @@
scripts\kalimdor\caverns_of_time\old_hillsbrad
+
+ scripts\kalimdor\dire_maul
+
scripts\kalimdor\onyxias_lair
@@ -1758,21 +2160,39 @@
scripts\kalimdor\wailing_caverns
+
+ scripts\kalimdor\zulfarrak
+
scripts\northrend\azjol-nerub\ahnkahet
scripts\northrend\azjol-nerub\azjol-nerub
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_champion
+
scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+ scripts\northrend\draktharon_keep
+
scripts\northrend\gundrak
+
+ scripts\northrend\icecrown_citadel\icecrown_citadel
+
scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls
+
+ scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
+
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
+
scripts\northrend\naxxramas
@@ -1782,6 +2202,9 @@
scripts\northrend\obsidian_sanctum
+
+ scripts\northrend\ruby_sanctum
+
scripts\northrend\ulduar\halls_of_lightning
@@ -1797,6 +2220,9 @@
scripts\northrend\utgarde_keep\utgarde_pinnacle
+
+ scripts\northrend\vault_of_archavon
+
scripts\northrend\violet_hold
@@ -1862,6 +2288,84 @@
+
+ scripts\northrend\azjol-nerub\ahnkahet
+
+
+ scripts\northrend\azjol-nerub\azjol-nerub
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_champion
+
+
+ scripts\northrend\crusaders_coliseum\trial_of_the_crusader
+
+
+ scripts\northrend\draktharon_keep
+
+
+ scripts\northrend\gundrak
+
+
+ scripts\northrend\icecrown_citadel\frozen_halls\forge_of_souls
+
+
+ scripts\northrend\icecrown_citadel\frozen_halls\halls_of_reflection
+
+
+ scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron
+
+
+ scripts\northrend\icecrown_citadel\icecrown_citadel
+
+
+ scripts\northrend\naxxramas
+
+
+ scripts\northrend\nexus\eye_of_eternity
+
+
+ scripts\northrend\nexus\nexus
+
+
+ scripts\northrend\nexus\oculus
+
+
+ scripts\northrend\obsidian_sanctum
+
+
+ scripts\northrend\ruby_sanctum
+
+
+ scripts\northrend\ulduar\halls_of_lightning
+
+
+ scripts\northrend\ulduar\halls_of_stone
+
+
+ scripts\northrend\ulduar\ulduar
+
+
+ scripts\northrend\utgarde_keep\utgarde_keep
+
+
+ scripts\northrend\utgarde_keep\utgarde_pinnacle
+
+
+ scripts\northrend\vault_of_archavon
+
+
+ scripts\northrend\violet_hold
+
+
+ base
+
+
+ base
+
+
+ scripts\kalimdor\caverns_of_time\culling_of_stratholme
+
diff --git a/VC80/80ScriptDev2.vcproj b/VC80/80ScriptDev2.vcproj
index 79f33f6..b8b0eab 100644
--- a/VC80/80ScriptDev2.vcproj
+++ b/VC80/80ScriptDev2.vcproj
@@ -381,6 +381,14 @@
RelativePath="..\base\guard_ai.h"
>
+
+
+
+
+
+
+
+
+
+
@@ -619,6 +639,10 @@
+
+
@@ -739,6 +763,10 @@
RelativePath="..\scripts\eastern_kingdoms\karazhan\bosses_opera.cpp"
>
+
+
@@ -963,6 +991,10 @@
+
+
@@ -1063,10 +1095,26 @@
RelativePath="..\scripts\eastern_kingdoms\sunwell_plateau\boss_brutallus.cpp"
>
+
+
+
+
+
+
+
+
@@ -1083,10 +1131,6 @@
RelativePath="..\scripts\eastern_kingdoms\uldaman\boss_archaedas.cpp"
>
-
-
@@ -1435,6 +1479,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1846,6 +1942,14 @@
RelativePath="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_valithria_dreamwalker.cpp"
>
+
+
+
+
@@ -1869,6 +1973,18 @@
RelativePath="..\scripts\northrend\icecrown_citadel\frozen_halls\pit_of_saron\boss_scourgelord_tyrannus.cpp"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2114,10 +2258,6 @@
-
-
@@ -2162,6 +2302,10 @@
RelativePath="..\scripts\northrend\ulduar\ulduar\boss_thorim.cpp"
>
+
+
@@ -2171,15 +2315,15 @@
>
@@ -2247,10 +2391,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2318,6 +2495,10 @@
RelativePath="..\scripts\outland\auchindoun\auchenai_crypts\boss_exarch_maladaar.cpp"
>
+
+
+
+
@@ -2458,6 +2643,10 @@
RelativePath="..\scripts\outland\coilfang_reservoir\serpent_shrine\boss_morogrim_tidewalker.cpp"
>
+
+
@@ -2470,6 +2659,10 @@
+
+
-
-
@@ -2837,6 +3026,22 @@
RelativePath="..\include\sc_instance.h"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -630,6 +642,10 @@
+
+
@@ -750,6 +766,10 @@
RelativePath="..\scripts\eastern_kingdoms\karazhan\bosses_opera.cpp"
>
+
+
@@ -974,6 +994,10 @@
+
+
@@ -1074,10 +1098,26 @@
RelativePath="..\scripts\eastern_kingdoms\sunwell_plateau\boss_brutallus.cpp"
>
+
+
+
+
+
+
+
+
@@ -1341,18 +1381,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1745,6 +1821,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1802,6 +1906,10 @@
RelativePath="..\scripts\northrend\draktharon_keep\draktharon_keep.h"
>
+
+
@@ -1917,6 +2025,10 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2021,6 +2177,10 @@
+
+
@@ -2045,10 +2205,6 @@
-
-
@@ -2058,27 +2214,27 @@
>
+
+
+
+
@@ -2110,7 +2274,7 @@
>
@@ -2178,6 +2342,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2215,11 +2411,11 @@
>
@@ -2273,10 +2469,34 @@
RelativePath="..\scripts\northrend\icecrown_citadel\icecrown_citadel\boss_valithria_dreamwalker.cpp"
>
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2313,7 +2533,7 @@
Name="halls_of_reflection"
>
+
+
+
+
+
+
+
+
+
+
@@ -2401,6 +2641,10 @@
RelativePath="..\scripts\outland\auchindoun\auchenai_crypts\boss_exarch_maladaar.cpp"
>
+
+
+
+
@@ -2557,6 +2805,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/base/BSW_ai.cpp b/base/BSW_ai.cpp
new file mode 100644
index 0000000..e65fb8a
--- /dev/null
+++ b/base/BSW_ai.cpp
@@ -0,0 +1,868 @@
+/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+#include "precompiled.h"
+#include "BSW_ai.h"
+#ifdef DEF_BOSS_SPELL_WORKER_H
+#include "ace/Process_Mutex.h"
+
+BSWScriptedAI::BSWScriptedAI(Creature* pCreature) : ScriptedAI(pCreature)
+{
+ doReset();
+ debug_log("BSW: Initialized BSWScriptedAI structure for creature %u difficulty %u",m_creature->GetEntry(),currentDifficulty);
+};
+
+BSWScriptedAI::~BSWScriptedAI()
+{
+ m_BSWRecords.clear();
+ debug_log("BSW: Removing BSWScriptedAI structure for creature %u",m_creature->GetEntry());
+};
+
+void BSWScriptedAI::doReset()
+{
+ Map* pMap = m_creature->GetMap();
+ if (pMap) currentDifficulty = pMap->GetDifficulty();
+ else currentDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
+ m_BSWRecords.clear();
+ setStage(0);
+ _loadFromDB();
+ _fillEmptyDataField();
+ resetTimers();
+};
+
+void BSWScriptedAI::_resetTimer(uint8 m_uiSpellIdx)
+{
+ if (m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMin[currentDifficulty] == 0
+ && m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS)
+ {
+ m_BSWRecords[m_uiSpellIdx].m_SpellTimer = 0;
+ }
+ else if (m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMin[currentDifficulty] != m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMax[currentDifficulty])
+ {
+ m_BSWRecords[m_uiSpellIdx].m_SpellTimer = urand(0,m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMax[currentDifficulty]);
+ }
+ else m_BSWRecords[m_uiSpellIdx].m_SpellTimer = m_BSWRecords[m_uiSpellIdx].m_uiSpellTimerMin[currentDifficulty];
+
+};
+
+void BSWScriptedAI::_loadFromDB()
+{
+ // mutex block for process-safe request execute
+ ACE_Process_Mutex mMutex = ACE_Process_Mutex("BSW_Lock");
+
+ debug_log("BSW: Loading table of creature %u spell on difficulty %u", m_creature->GetEntry(), currentDifficulty);
+
+ char query[MAX_QUERY_LEN];
+
+ sprintf(query, "SELECT entry, spellID_N10, spellID_N25, spellID_H10, spellID_H25, timerMin_N10, timerMin_N25, timerMin_H10, timerMin_H25, timerMax_N10, timerMax_N25, timerMax_H10, timerMax_H25, data1, data2, data3, data4, locData_x, locData_y, locData_z, varData, StageMask_N, StageMask_H, CastType, isVisualEffect, isBugged, textEntry FROM `boss_spell_table` WHERE entry = %u;\r\n", m_creature->GetEntry());
+
+ mMutex.acquire();
+ QueryResult* Result = strSD2Pquery(query);
+ mMutex.release();
+
+ if (Result)
+ {
+ uint32 uiCount = 0;
+ do
+ {
+ BSWRecord m_BSWRecord;
+
+ Field* pFields = Result->Fetch();
+
+ m_BSWRecord.id = uiCount;
+
+ uint32 m_creatureEntry = pFields[0].GetUInt32();
+
+ for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j)
+ m_BSWRecord.m_uiSpellEntry[j] = pFields[1+j].GetUInt32();
+
+ for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j)
+ m_BSWRecord.m_uiSpellTimerMin[j] = pFields[1+DIFFICULTY_LEVELS+j].GetUInt32();
+
+ for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j)
+ m_BSWRecord.m_uiSpellTimerMax[j] = pFields[1+DIFFICULTY_LEVELS*2+j].GetUInt32();
+
+ for (uint8 j = 0; j < DIFFICULTY_LEVELS; ++j)
+ m_BSWRecord.m_uiSpellData[j] = pFields[1+DIFFICULTY_LEVELS*3+j].GetUInt32();
+
+ m_BSWRecord.LocData.x = pFields[1+DIFFICULTY_LEVELS*4].GetFloat();
+ m_BSWRecord.LocData.y = pFields[2+DIFFICULTY_LEVELS*4].GetFloat();
+ m_BSWRecord.LocData.z = pFields[3+DIFFICULTY_LEVELS*4].GetFloat();
+
+ m_BSWRecord.varData = pFields[4+DIFFICULTY_LEVELS*4].GetInt32();
+
+ m_BSWRecord.StageMaskN = pFields[5+DIFFICULTY_LEVELS*4].GetUInt32();
+ m_BSWRecord.StageMaskH = pFields[6+DIFFICULTY_LEVELS*4].GetUInt32();
+
+ m_BSWRecord.m_CastTarget = _getBSWCastType(pFields[7+DIFFICULTY_LEVELS*4].GetUInt8());
+
+ m_BSWRecord.m_IsVisualEffect = (pFields[8+DIFFICULTY_LEVELS*4].GetUInt8() == 0) ? false : true ;
+
+ m_BSWRecord.m_IsBugged = (pFields[9+DIFFICULTY_LEVELS*4].GetUInt8() == 0) ? false : true ;
+
+ m_BSWRecord.textEntry = pFields[10+DIFFICULTY_LEVELS*4].GetInt32();
+
+ m_BSWRecords.push_back(m_BSWRecord);
+
+ if (m_creatureEntry != m_creature->GetEntry()) error_log("BSW: Unknown error while load boss_spell_table");
+ else ++uiCount;
+ } while (Result->NextRow());
+
+ delete Result;
+
+ debug_log("BSW: Loaded %u spell data records for creature %u", bossSpellCount(), m_creature->GetEntry());
+ }
+ else
+ {
+ error_log("BSW: BSW table for creature %u is empty.", m_creature->GetEntry());
+ };
+}
+
+bool BSWScriptedAI::_QuerySpellPeriod(uint8 m_uiSpellIdx, uint32 diff, bool ignorecast)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ if (m_creature->IsNonMeleeSpellCasted(false) && !ignorecast) return false;
+
+ if (pSpell->m_SpellTimer <= diff)
+ {
+ if (pSpell->m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS) pSpell->m_SpellTimer=HOUR*IN_MILLISECONDS;
+ else pSpell->m_SpellTimer = urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]);
+ return true;
+ }
+ else
+ {
+ pSpell->m_SpellTimer -= diff;
+ return false;
+ };
+};
+
+CanCastResult BSWScriptedAI::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget)
+{
+
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ Unit* pSummon = NULL;
+
+ CanCastResult result = CAST_FAIL_OTHER;
+
+ debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+
+ if (pSpell->m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS)
+ m_creature->InterruptNonMeleeSpells(true);
+
+ switch (pSpell->m_CastTarget) {
+
+ case DO_NOTHING:
+ result = CAST_OK;
+ break;
+
+ case CAST_ON_SELF:
+ result = _BSWCastOnTarget(m_creature, m_uiSpellIdx);
+ break;
+
+ case CAST_ON_SUMMONS:
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case CAST_ON_VICTIM:
+ pTarget = m_creature->getVictim();
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case CAST_ON_RANDOM:
+ pTarget = _doSelect(0, false, 60.0f);
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case CAST_ON_BOTTOMAGGRO:
+ pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0);
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case CAST_ON_TARGET:
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case APPLY_AURA_SELF:
+ if (_doAura(m_uiSpellIdx, m_creature, EFFECT_INDEX_0))
+ result = CAST_OK;
+ else result = CAST_FAIL_OTHER;
+ break;
+
+ case APPLY_AURA_TARGET:
+ if (!pTarget || !pTarget->IsInMap(m_creature))
+ {
+ result = CAST_FAIL_OTHER;
+ break;
+ }
+ if (_doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0))
+ result = CAST_OK;
+ else result = CAST_FAIL_OTHER;
+ break;
+
+ case SUMMON_NORMAL:
+ pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
+ if(pSummon) result = CAST_OK;
+ else result = CAST_FAIL_OTHER;
+ break;
+
+ case SUMMON_TEMP:
+ pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,
+ urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]));
+ if(pSummon) result = CAST_OK;
+ else result = CAST_FAIL_OTHER;
+ break;
+
+ case SUMMON_INSTANT:
+ pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0);
+ if(pSummon) result = CAST_OK;
+ else result = CAST_FAIL_OTHER;
+ break;
+
+ case CAST_ON_ALLPLAYERS:
+ {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const& pPlayers = pMap->GetPlayers();
+ if (!pPlayers.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
+ {
+ pTarget = itr->getSource();
+ if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x))
+ {
+ if (!pSpell->m_IsBugged)
+ {
+ m_creature->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false);
+ }
+ else
+ {
+ _BSWDoCast(m_uiSpellIdx, pTarget);
+ };
+ result = CAST_OK;
+ };
+ }
+ } else result = CAST_FAIL_OTHER;
+ }
+ break;
+
+ case CAST_ON_FRENDLY:
+ pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,0);
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case CAST_ON_FRENDLY_LOWHP:
+ pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,1);
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case CAST_ON_RANDOM_POINT:
+ if (!pTarget) pTarget = m_creature;
+ if (pSpell->LocData.z <= 1.0f)
+ {
+ float fPosX, fPosY, fPosZ;
+ if (!pTarget->IsPositionValid() || !pTarget->IsInMap(m_creature))
+ {
+ if (pTarget->GetTypeId() == TYPEID_PLAYER)
+ error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
+ else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
+ result = CAST_FAIL_OTHER;
+ break;
+ }
+
+ pTarget->GetPosition(fPosX, fPosY, fPosZ);
+ pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ);
+ if ((int)fPosZ == 0)
+ {
+ error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug");
+ result = CAST_FAIL_OTHER;
+ break;
+ }
+
+ if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]))
+ if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex))
+ if (m_creature->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange)
+ {
+ m_creature->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false);
+ result = CAST_OK;
+ break;
+ };
+ result = CAST_FAIL_TOO_FAR;
+ } else result = CAST_FAIL_OTHER;
+ break;
+
+ case CAST_ON_RANDOM_PLAYER:
+ if ( pSpell->LocData.x < 1 ) pTarget = _doSelect(0, false, 60.0f);
+ else pTarget = _doSelect(0, false, (float)pSpell->LocData.x);
+ result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
+ break;
+
+ case APPLY_AURA_ALLPLAYERS:
+ {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const& pPlayers = pMap->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
+ {
+ pTarget = itr->getSource();
+ if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x))
+ {
+ _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0);
+ result = CAST_OK;
+ }
+ }
+ }
+ break;
+
+ case FORCE_CAST:
+ result = _BSWDoForceCast(m_uiSpellIdx, pTarget);
+ break;
+
+ case SPELLTABLEPARM_NUMBER:
+ default:
+ error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+ result = CAST_FAIL_OTHER;
+ break;
+ };
+
+ if (pSpell->textEntry && result == CAST_OK)
+ {
+ if (pTarget)
+ DoScriptText(pSpell->textEntry,m_creature,pTarget);
+ else
+ DoScriptText(pSpell->textEntry,m_creature);
+ };
+
+ debug_log("BSW: Casted spell number %u, result = %u",pSpell->m_uiSpellEntry[currentDifficulty], result);
+
+ return result;
+};
+
+CanCastResult BSWScriptedAI::_BSWCastOnTarget(Unit* pTarget, uint8 m_uiSpellIdx)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
+ {
+ debug_log("BSW: warning - failed casting (on target) spell number %u - no target or target not in map",pSpell->m_uiSpellEntry[currentDifficulty]);
+ return CAST_FAIL_OTHER;
+ }
+
+ debug_log("BSW: Casting (on target) spell %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+
+ if (!pSpell->m_IsBugged) return _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]);
+ else if (pSpell->m_IsBugged) return _BSWDoCast(m_uiSpellIdx, pTarget);
+ else return CAST_FAIL_OTHER;
+};
+
+bool BSWScriptedAI::_hasAura(uint8 m_uiSpellIdx, Unit* pTarget)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ return _hasAura(pSpell->m_uiSpellEntry[currentDifficulty], pTarget);
+
+};
+
+bool BSWScriptedAI::_hasAura(uint32 SpellID, Unit* pTarget)
+{
+ if (!pTarget || !pTarget->IsInMap(m_creature))
+ {
+ error_log("BSW: FAILED Query aura for spell %u - no target or target not in map",SpellID);
+ return false;
+ }
+
+ return (pTarget->HasAura(SpellID));
+
+};
+
+uint8 BSWScriptedAI::_auraCount(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ return _auraCount(pSpell->m_uiSpellEntry[currentDifficulty], pTarget, index);
+
+};
+
+uint8 BSWScriptedAI::_auraCount(uint32 SpellID, Unit* pTarget, SpellEffectIndex index)
+{
+ if (!_hasAura(SpellID,pTarget)) return 0;
+
+ if (Aura* aura = pTarget->GetAura(SpellID, index))
+ if (aura->GetStackAmount() > 0)
+ return aura->GetStackAmount();
+ return 0;
+
+};
+
+uint8 BSWScriptedAI::_findSpellIDX(uint32 SpellID)
+{
+ if (bossSpellCount() > 0)
+ for(uint8 i = 0; i < bossSpellCount(); ++i)
+ if (m_BSWRecords[i].m_uiSpellEntry[RAID_DIFFICULTY_10MAN_NORMAL] == SpellID) return i;
+
+ error_log("BSW: spell %u not found in m_creature %u spelltable. Memory or database error?", SpellID, m_creature->GetEntry());
+
+ return SPELL_INDEX_ERROR;
+}
+
+BSWRecord* BSWScriptedAI::_getRecord(uint32 SpellID)
+{
+ if (!m_BSWRecords.empty())
+ {
+ for(uint8 i = 0; i < m_BSWRecords.size(); ++i)
+ if (m_BSWRecords[i].m_uiSpellEntry[RAID_DIFFICULTY_10MAN_NORMAL] == SpellID) return &m_BSWRecords[i];
+ }
+ error_log("BSW: spell %u not found in m_creature %u spelltable. Memory or database error?", SpellID, m_creature->GetEntry());
+ return NULL;
+}
+
+BossSpellTableParameters BSWScriptedAI::_getBSWCastType(uint32 pTemp)
+{
+ switch (pTemp) {
+ case 0: return DO_NOTHING;
+ case 1: return CAST_ON_SELF;
+ case 2: return CAST_ON_SUMMONS;
+ case 3: return CAST_ON_VICTIM;
+ case 4: return CAST_ON_RANDOM;
+ case 5: return CAST_ON_BOTTOMAGGRO;
+ case 6: return CAST_ON_TARGET;
+ case 7: return APPLY_AURA_SELF;
+ case 8: return APPLY_AURA_TARGET;
+ case 9: return SUMMON_NORMAL;
+ case 10: return SUMMON_INSTANT;
+ case 11: return SUMMON_TEMP;
+ case 12: return CAST_ON_ALLPLAYERS;
+ case 13: return CAST_ON_FRENDLY;
+ case 14: return CAST_ON_FRENDLY_LOWHP;
+ case 15: return CAST_ON_RANDOM_POINT;
+ case 16: return CAST_ON_RANDOM_PLAYER;
+ case 17: return APPLY_AURA_ALLPLAYERS;
+ case 18: return FORCE_CAST;
+ case 19: return SPELLTABLEPARM_NUMBER;
+ default: return DO_NOTHING;
+ };
+};
+
+CanCastResult BSWScriptedAI::_BSWDoCast(uint8 m_uiSpellIdx, Unit* pTarget)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
+ {
+ error_log("BSW: warning - failed casting bugged spell number %u - no target or target not in map",pSpell->m_uiSpellEntry[currentDifficulty]);
+ return CAST_FAIL_OTHER;
+ }
+
+ debug_log("BSW: Casting bugged spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+
+ pTarget->InterruptNonMeleeSpells(false);
+
+ pTarget->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false);
+
+ return CAST_OK;
+};
+
+CanCastResult BSWScriptedAI::_BSWDoForceCast(uint8 m_uiSpellIdx, Unit* pTarget)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
+ {
+ error_log("BSW: warning - failed forced casting spell number %u - no target or target not in map",pSpell->m_uiSpellEntry[currentDifficulty]);
+ return CAST_FAIL_OTHER;
+ }
+
+ debug_log("BSW: Forced casting spell number %u ",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+
+ pTarget->InterruptNonMeleeSpells(false);
+
+ pTarget->CastSpell(m_creature, pSpell->m_uiSpellEntry[currentDifficulty], true);
+
+ return CAST_OK;
+};
+
+void BSWScriptedAI::_fillEmptyDataField()
+{
+ for (uint8 i = 0; i < bossSpellCount(); ++i)
+ for (uint8 j = 1; j < DIFFICULTY_LEVELS; ++j)
+ {
+ if (m_BSWRecords[i].m_uiSpellEntry[j] == 0)
+ {
+ SpellEntry const* spell = GetSpellEntryByDifficulty(m_BSWRecords[i].m_uiSpellEntry[0],(Difficulty)j);
+ if (spell)
+ m_BSWRecords[i].m_uiSpellEntry[j] = spell->Id;
+ else m_BSWRecords[i].m_uiSpellEntry[j] = m_BSWRecords[i].m_uiSpellEntry[j-1];
+ }
+
+ if (m_BSWRecords[i].m_uiSpellTimerMin[j] == 0)
+ m_BSWRecords[i].m_uiSpellTimerMin[j] = m_BSWRecords[i].m_uiSpellTimerMin[j-1];
+
+ if (m_BSWRecords[i].m_uiSpellTimerMax[j] == 0)
+ m_BSWRecords[i].m_uiSpellTimerMax[j] = m_BSWRecords[i].m_uiSpellTimerMax[j-1];
+
+ if (m_BSWRecords[i].m_uiSpellData[j] == 0)
+ m_BSWRecords[i].m_uiSpellData[j] = m_BSWRecords[i].m_uiSpellData[j-1];
+ };
+};
+
+Unit* BSWScriptedAI::_doSummon(uint8 m_uiSpellIdx, TempSummonType summontype, uint32 delay)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ debug_log("BSW: Summoning creature number %u type %u despawn delay %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget, delay);
+
+ if (pSpell->LocData.z <= 1.0f)
+ {
+ float fPosX, fPosY, fPosZ;
+ if (!m_creature->IsPositionValid())
+ {
+ error_log("BSW: FAILED summoning creature, creature %u has invalid position",m_creature->GetEntry());
+ return NULL;
+ }
+ m_creature->GetPosition(fPosX, fPosY, fPosZ);
+ m_creature->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ);
+ return m_creature->SummonCreature(pSpell->m_uiSpellEntry[currentDifficulty], fPosX, fPosY, fPosZ+0.8f, 0, summontype, delay);
+ }
+ else return m_creature->SummonCreature(pSpell->m_uiSpellEntry[currentDifficulty], pSpell->LocData.x, pSpell->LocData.y, pSpell->LocData.z, 0, summontype, delay);
+};
+
+Unit* BSWScriptedAI::_doSummonAtPosition(uint8 m_uiSpellIdx, float fPosX, float fPosY, float fPosZ)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ switch (pSpell->m_CastTarget)
+ {
+ case SUMMON_NORMAL:
+ return _doSummonAtPosition(pSpell->m_uiSpellEntry[m_uiSpellIdx], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 0, fPosX, fPosY, fPosZ);
+ break;
+
+ case SUMMON_TEMP:
+ return _doSummonAtPosition(pSpell->m_uiSpellEntry[m_uiSpellIdx], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]), fPosX, fPosY, fPosZ);
+ break;
+
+ case SUMMON_INSTANT:
+ return _doSummonAtPosition(pSpell->m_uiSpellEntry[m_uiSpellIdx], TEMPSUMMON_MANUAL_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty]), fPosX, fPosY, fPosZ);
+ break;
+
+ default:
+ break;
+ }
+ error_log("BSW: FAILED creature number %u type %u ",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+ return NULL;
+};
+
+Unit* BSWScriptedAI::_doSummonAtPosition(uint32 guid, TempSummonType summontype, uint32 delay, float fPosX, float fPosY, float fPosZ)
+{
+
+ debug_log("BSW: Summoning creature number %u despawn delay %u at position %f %f %f", guid, delay, fPosX, fPosY, fPosZ);
+
+ return m_creature->SummonCreature(guid, fPosX, fPosY, fPosZ, 0, summontype, delay);
+};
+
+bool BSWScriptedAI::_doRemove(uint8 m_uiSpellIdx, Unit* pTarget, uint8 index)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ debug_log("BSW: Removing effects of spell %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+
+ switch (pSpell->m_CastTarget)
+ {
+ case DO_NOTHING:
+ return true;
+ break;
+
+ case SUMMON_NORMAL:
+ case SUMMON_TEMP:
+ case SUMMON_INSTANT:
+ return false;
+ break;
+
+ case CAST_ON_SELF:
+ case APPLY_AURA_SELF:
+ pTarget = m_creature;
+ break;
+
+ case CAST_ON_SUMMONS:
+ case CAST_ON_VICTIM:
+ case CAST_ON_BOTTOMAGGRO:
+ case CAST_ON_TARGET:
+ case FORCE_CAST:
+ case APPLY_AURA_TARGET:
+ if (!pTarget)
+ return false;
+ break;
+
+ case CAST_ON_RANDOM:
+ case CAST_ON_RANDOM_PLAYER:
+ case APPLY_AURA_ALLPLAYERS:
+ case CAST_ON_ALLPLAYERS:
+ _doRemoveFromAll(m_uiSpellIdx);
+ return true;
+ break;
+
+ default:
+ debug_log("BSW: FAILED Removing effects of spell %u type %u - unsupported type",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
+ return false;
+ break;
+ }
+
+ return _doRemove(pSpell->m_uiSpellEntry[currentDifficulty], pTarget, index);
+
+};
+
+bool BSWScriptedAI::_doRemove(uint32 SpellID, Unit* pTarget, uint8 index)
+{
+
+ if (!_hasAura(SpellID, pTarget)) return false;
+
+ if (index == EFFECT_INDEX_ALL)
+ {
+ pTarget->RemoveAurasDueToSpell(SpellID);
+ }
+ else if (_auraCount(SpellID,pTarget,(SpellEffectIndex)index) > 1)
+ {
+ if (SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(SpellID, pTarget->GetGUID()))
+ {
+ if (holder->ModStackAmount(-1))
+ {
+ pTarget->RemoveSpellAuraHolder(holder, AURA_REMOVE_BY_DISPEL);
+ } else return false;
+ }
+ }
+ else
+ pTarget->RemoveAurasDueToSpell(SpellID);
+
+ debug_log("BSW: Removed effects of spell %u index %u",SpellID, index);
+ return true;
+};
+
+bool BSWScriptedAI::_doRemoveFromAll(uint8 m_uiSpellIdx)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+ return _doRemoveFromAll(pSpell->m_uiSpellEntry[currentDifficulty]);
+};
+
+bool BSWScriptedAI::_doRemoveFromAll(uint32 SpellID)
+{
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const& pPlayers = pMap->GetPlayers();
+ if (!pPlayers.isEmpty())
+ {
+ debug_log("BSW: Removing effects of spell %u from all players",SpellID);
+
+ for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
+ {
+ Unit* pTarget = itr->getSource();
+ if (pTarget && pTarget->IsInWorld())
+ {
+ pTarget->RemoveAurasDueToSpell(SpellID);
+ if (Pet* pPet = pTarget->GetPet())
+ pPet->RemoveAurasDueToSpell(SpellID);
+ }
+ }
+ return true;
+ }
+ else
+ {
+ debug_log("BSW: Removing effects of spell %u from all players FAILED - no players in map",SpellID);
+ return false;
+ }
+};
+
+bool BSWScriptedAI::_doAura(uint8 m_uiSpellIdx, Unit* pTarget)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ if (!pTarget)
+ pTarget = m_creature;
+
+ bool result = true;
+
+ for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
+ result = result && _doAura(m_uiSpellIdx, pTarget, SpellEffectIndex(i), !i);
+
+ return result;
+
+};
+
+bool BSWScriptedAI::_doAura(uint32 SpellID, Unit* pTarget)
+{
+ if (!pTarget)
+ pTarget = m_creature;
+
+ bool result = true;
+
+ for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
+ result = result && _doAura(SpellID, pTarget, SpellEffectIndex(i), 0, !i);
+
+ return result;
+
+};
+
+
+bool BSWScriptedAI::_doAura(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index, bool isStack)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ if (!pTarget)
+ pTarget = m_creature;
+
+ return _doAura(pSpell->m_uiSpellEntry[currentDifficulty], pTarget, index, pSpell->varData, isStack);
+
+};
+
+
+bool BSWScriptedAI::_doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint, bool isStack)
+{
+ if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
+ {
+ error_log("BSW: FAILED adding aura of spell number %u - no target or target not in map or target is dead",SpellID);
+ return false;
+ }
+
+ if (_hasAura(SpellID,pTarget))
+ debug_log("BSW: adding aura stack from spell %u index %u",SpellID, index);
+ else debug_log("BSW: adding new aura from spell %u index %u",SpellID, index);
+
+ SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SpellID);
+
+ if (spell)
+ {
+ if (IsSpellAppliesAura(spell, (1 << EFFECT_INDEX_0) | (1 << EFFECT_INDEX_1) | (1 << EFFECT_INDEX_2)) || IsSpellHaveEffect(spell, SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ {
+ int32 _basepoint = basepoint ? basepoint - 1 : spell->EffectBasePoints[index] + 1;
+
+ bool addedToExisting = true;
+
+ SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(SpellID, pTarget->GetGUID());
+
+ Aura* aura = NULL;
+
+ if (!holder)
+ {
+ holder = CreateSpellAuraHolder(spell, pTarget, pTarget);
+ addedToExisting = false;
+ }
+
+
+ if (aura = holder->GetAuraByEffectIndex(index))
+ {
+ if (isStack)
+ holder->ModStackAmount(1);
+ }
+ else
+ {
+ aura = CreateAura(spell, index, &_basepoint, holder, pTarget);
+ aura->SetAuraDuration(aura->GetAuraMaxDuration());
+ holder->AddAura(aura, index);
+ }
+
+ if (addedToExisting)
+ {
+ pTarget->AddAuraToModList(aura);
+ holder->SetInUse(true);
+ aura->ApplyModifier(true,true);
+ holder->SetInUse(false);
+ }
+ else
+ pTarget->AddSpellAuraHolder(holder);
+
+ return true;
+ }
+ }
+
+ error_log("BSW: FAILED adding aura from spell %u index %u",SpellID, index);
+
+ return false;
+};
+
+CanCastResult BSWScriptedAI::_DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags, uint64 uiOriginalCasterGUID)
+{
+ if (!pTarget || !pTarget->IsInWorld() || !pTarget->IsInMap(m_creature)|| !pTarget->isAlive()) return CAST_FAIL_OTHER;
+
+ return DoCastSpellIfCan(pTarget,uiSpell,uiCastFlags,uiOriginalCasterGUID);
+}
+
+// Not threat-based select random player function
+
+Unit* BSWScriptedAI::_doSelect(uint32 SpellID, bool spellsearchtype, float range)
+{
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &pList = pMap->GetPlayers();
+ if (pList.isEmpty()) return NULL;
+
+ std::vector _list;
+ _list.clear();
+
+ for(Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i)
+ if (Player* player = i->getSource())
+ {
+ if (player->isGameMaster()) continue;
+
+ if (!player->IsInMap(m_creature)) continue;
+
+ if (player->isAlive()
+ && player->IsWithinDistInMap(m_creature, range)
+ && (SpellID == 0 || (player->HasAura(SpellID) == spellsearchtype))
+ )
+ _list.push_back((Unit*)player);
+ }
+
+ debug_log("BSW: search random player with criteria = %u, found %u players.",SpellID,_list.size());
+
+ if (_list.empty()) return NULL;
+ else return _list[urand(0,_list.size() - 1)];
+};
+
+Creature* BSWScriptedAI::doSelectNearestCreature(uint32 id, float range)
+{
+ Creature* pTarget = GetClosestCreatureWithEntry(m_creature, id, range);
+
+ if (pTarget && pTarget->IsInMap(m_creature) && pTarget != m_creature && pTarget->isAlive())
+ {
+ debug_log("BSW: search creature %u in range %f - found it.",id,range);
+ return pTarget;
+ }
+ else
+ {
+ debug_log("BSW: search creature %u in range %f - NOT found.",id,range);
+ return NULL;
+ }
+}
+
+uint32 BSWScriptedAI::_getSpellData(uint8 m_uiSpellIdx)
+{
+ BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx];
+
+ return pSpell->m_uiSpellData[currentDifficulty];
+};
+
+bool BSWScriptedAI::doCastAll(uint32 diff)
+{
+
+ uint8 succesfulCast = 0;
+
+ if (bossSpellCount() > 0)
+ {
+ for(uint8 i = 0; i < bossSpellCount(); ++i)
+ if (_QuerySpellPeriod(i, diff))
+ if (_BSWSpellSelector(i) == CAST_OK)
+ ++succesfulCast;
+
+ if (succesfulCast)
+ debug_log("BSW: Casting all spells for creature %u done. Successful casted %u spells from %u.", m_creature->GetEntry(),succesfulCast,bossSpellCount());
+ }
+ else
+ {
+ error_log("BSW: Casting all spells for creature %u failed. Database has no spells.", m_creature->GetEntry());
+ }
+
+ return (succesfulCast >= 1) ? true : false;
+
+};
+
+bool BSWScriptedAI::_isDifficultyInMask(uint8 mask)
+{
+ return ((uint8)currentDifficulty & mask);
+};
+
+#endif
\ No newline at end of file
diff --git a/base/BSW_ai.h b/base/BSW_ai.h
new file mode 100644
index 0000000..158484e
--- /dev/null
+++ b/base/BSW_ai.h
@@ -0,0 +1,296 @@
+/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_BOSS_SPELL_WORKER_H
+#define DEF_BOSS_SPELL_WORKER_H
+#define BSW_VERSION 0.6.12
+
+#include "precompiled.h"
+#include "Player.h"
+#include "SpellAuras.h"
+#include "SpellMgr.h"
+#include "Unit.h"
+#include "Database/DatabaseEnv.h"
+#include "../ScriptMgr.h"
+
+
+enum
+{
+ DIFFICULTY_LEVELS = 4,
+ EFFECT_INDEX_ALL = 255,
+ SPELL_INDEX_ERROR = 255,
+};
+
+enum BossSpellFlag
+{
+ CAST_NORMAL,
+ CAST_REMOVE,
+ CAST_OVERRIDE,
+ SPELLFLAG_NUMBER
+};
+
+enum BossSpellTableParameters
+{
+ DO_NOTHING = 0,
+ CAST_ON_SELF = 1,
+ CAST_ON_SUMMONS = 2,
+ CAST_ON_VICTIM = 3,
+ CAST_ON_RANDOM = 4,
+ CAST_ON_BOTTOMAGGRO = 5,
+ CAST_ON_TARGET = 6,
+ APPLY_AURA_SELF = 7,
+ APPLY_AURA_TARGET = 8,
+ SUMMON_NORMAL = 9,
+ SUMMON_INSTANT = 10,
+ SUMMON_TEMP = 11,
+ CAST_ON_ALLPLAYERS = 12,
+ CAST_ON_FRENDLY = 13,
+ CAST_ON_FRENDLY_LOWHP = 14,
+ CAST_ON_RANDOM_POINT = 15,
+ CAST_ON_RANDOM_PLAYER = 16,
+ APPLY_AURA_ALLPLAYERS = 17,
+ FORCE_CAST = 18,
+ SPELLTABLEPARM_NUMBER
+};
+
+struct Locations
+{
+ float x, y, z, o;
+ int32 id;
+};
+
+struct WayPoints
+{
+ WayPoints(int32 _id, float _x, float _y, float _z)
+ {
+ id = _id;
+ x = _x;
+ y = _y;
+ z = _z;
+ }
+ int32 id;
+ float x, y, z;
+};
+
+struct BSWRecord
+{
+
+ public:
+ // External (loaded from database) variables
+ uint32 id;
+ uint32 m_uiSpellEntry[DIFFICULTY_LEVELS]; // Stores spell entry for difficulty levels
+ uint32 m_uiSpellTimerMin[DIFFICULTY_LEVELS]; // The timer (min) before the next spell casting, in milliseconds
+ uint32 m_uiSpellTimerMax[DIFFICULTY_LEVELS]; // The timer (max) before the next spell casting
+ uint32 m_uiSpellData[DIFFICULTY_LEVELS]; // Additional data for spell casting or summon
+ Locations LocData; // Float data structure for locations
+ int varData; // Additional data for spell
+ uint32 StageMaskN; // Stage mask for this spell (normal)
+ uint32 StageMaskH; // Stage mask for this spell (heroic)
+ BossSpellTableParameters m_CastTarget; // Target on casting spell
+ bool m_IsVisualEffect; // Spellcasting is visual effect or real effect
+ bool m_IsBugged; // Need override for this spell
+ int32 textEntry; // Text entry from script_text for this spell
+ // Internal variables
+ uint32 m_SpellTimer; // Current timer for this spell
+};
+
+struct MANGOS_DLL_DECL BSWScriptedAI : public ScriptedAI
+{
+ public:
+ explicit BSWScriptedAI(Creature* pCreature);
+
+ ~BSWScriptedAI();
+
+ void doReset();
+
+ void resetTimer(uint32 SpellID)
+ {
+ if (queryIndex(_findSpellIDX(SpellID))) _resetTimer(_findSpellIDX(SpellID));
+ else return;
+ };
+
+ void resetTimers()
+ {
+ for (uint8 i = 0; i < bossSpellCount(); ++i)
+ _resetTimer(i);
+ };
+
+ bool timedQuery(uint32 SpellID, uint32 diff, bool ignorecast = false)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _QuerySpellPeriod(_findSpellIDX(SpellID), diff, ignorecast) : false;
+ };
+
+ CanCastResult timedCast(uint32 SpellID, uint32 diff, Unit* pTarget = NULL)
+ {
+ if (!queryIndex(_findSpellIDX(SpellID))) return CAST_FAIL_OTHER;
+ return _QuerySpellPeriod(_findSpellIDX(SpellID), diff) ? _BSWSpellSelector(_findSpellIDX(SpellID), pTarget) : CAST_FAIL_STATE;
+ };
+
+ CanCastResult doCast(uint32 SpellID, Unit* pTarget = NULL)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _BSWSpellSelector(_findSpellIDX(SpellID), pTarget) : CAST_FAIL_OTHER;
+ };
+
+ CanCastResult doCast(Unit* pTarget, uint32 SpellID)
+ {
+ if (!pTarget) return CAST_FAIL_OTHER;
+ return queryIndex(_findSpellIDX(SpellID)) ? _BSWCastOnTarget(pTarget, _findSpellIDX(SpellID)) : CAST_FAIL_OTHER;
+ };
+
+ bool doRemove(uint32 SpellID, Unit* pTarget = NULL, uint8 index = EFFECT_INDEX_ALL)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _doRemove(_findSpellIDX(SpellID),pTarget,index) : _doRemove(SpellID,pTarget,index);
+ };
+
+ bool doRemoveFromAll(uint32 SpellID)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _doRemoveFromAll(_findSpellIDX(SpellID)) : _doRemoveFromAll(SpellID);
+ };
+
+ bool doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint = 0, bool isStack = true)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _doAura(_findSpellIDX(SpellID), pTarget, index, isStack) : _doAura(SpellID, pTarget, index, basepoint, isStack);
+ };
+
+ bool doAura(uint32 SpellID, Unit* pTarget = NULL)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _doAura(_findSpellIDX(SpellID), pTarget) : _doAura(SpellID, pTarget);
+ };
+
+ bool hasAura(uint32 SpellID, Unit* pTarget = NULL)
+ {
+ if (!pTarget) pTarget = m_creature;
+ return queryIndex(_findSpellIDX(SpellID)) ? _hasAura(_findSpellIDX(SpellID),pTarget) : _hasAura(SpellID,pTarget);
+ };
+
+ uint8 auraCount(uint32 SpellID, Unit* pTarget = NULL, SpellEffectIndex index = EFFECT_INDEX_0)
+ {
+ if (!pTarget) pTarget = m_creature;
+ return queryIndex(_findSpellIDX(SpellID)) ? _auraCount(_findSpellIDX(SpellID),pTarget,index) : _auraCount(SpellID,pTarget,index);
+ };
+
+ Unit* doSummon(uint32 SpellID, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN, uint32 delay = 60000)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _doSummon(_findSpellIDX(SpellID), type, delay) : NULL;
+ };
+
+ Unit* doSelectRandomPlayer(uint32 SpellID = 0, bool spellsearchtype = false, float range = 100.0f)
+ {
+ return _doSelect(SpellID, spellsearchtype, range);
+ };
+
+ Unit* doSelectRandomPlayerAtRange(float range)
+ {
+ return _doSelect(0, false, range);
+ };
+
+ Unit* doSummon(uint32 SpellID, float fPosX, float fPosY, float fPosZ, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN, uint32 delay = 60000)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _doSummonAtPosition(_findSpellIDX(SpellID), fPosX, fPosY, fPosZ) : _doSummonAtPosition(SpellID, type, delay, fPosX, fPosY, fPosZ);
+ };
+
+ uint8 bossSpellCount()
+ {
+ return m_BSWRecords.size();
+ };
+
+ bool queryIndex(uint8 m_uiSpellIdx)
+ {
+ if (m_uiSpellIdx == SPELL_INDEX_ERROR) return false;
+ else if (m_uiSpellIdx >= 0 && m_uiSpellIdx < bossSpellCount()) return true;
+ else return false;
+ };
+
+ Creature* doSelectNearestCreature(uint32 guid, float range = 120.0f);
+
+ uint32 getSpellData(uint32 SpellID)
+ {
+ return queryIndex(_findSpellIDX(SpellID)) ? _getSpellData(_findSpellIDX(SpellID)) : 0;
+ };
+
+ bool doCastAll(uint32 diff);
+
+ uint8 getStage() { return _stage; };
+
+ void setStage(uint8 stage) { _stage = stage; };
+
+ bool isHeroic() { Map* pMap = m_creature->GetMap(); return pMap->IsRaid() ? _isDifficultyInMask(12) : _isDifficultyInMask(2); };
+
+ bool isNormal() { return !isHeroic(); };
+
+ bool is25() { Map* pMap = m_creature->GetMap(); return pMap->IsRaid() ? _isDifficultyInMask(10) : false; };
+
+ protected:
+
+ Difficulty currentDifficulty;
+
+ std::vector m_BSWRecords;
+
+ private:
+
+ BossSpellTableParameters _getBSWCastType(uint32 pTemp);
+
+ uint8 _findSpellIDX(uint32 SpellID);
+
+ BSWRecord* _getRecord(uint32 SpellID);
+
+ void _loadFromDB();
+
+ void _resetTimer(uint8 m_uiSpellIdx);
+
+ Unit* _doSelect(uint32 SpellID, bool spellsearchtype = false, float range = 100.0f);
+
+ Unit* _doSummon(uint8 m_uiSpellIdx, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN, uint32 delay = 60000);
+
+ Unit* _doSummonAtPosition(uint8 m_uiSpellIdx, float fPosX, float fPosY, float fPosZ);
+
+ Unit* _doSummonAtPosition(uint32 guid, TempSummonType type, uint32 delay, float fPosX, float fPosY, float fPosZ);
+
+ CanCastResult _BSWDoCast(uint8 m_uiSpellIdx, Unit* pTarget);
+
+ CanCastResult _BSWDoForceCast(uint8 m_uiSpellIdx, Unit* pTarget);
+
+ CanCastResult _BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget = NULL);
+
+ CanCastResult _BSWCastOnTarget(Unit* pTarget, uint8 m_uiSpellIdx);
+
+ bool _QuerySpellPeriod(uint8 m_uiSpellIdx, uint32 diff, bool ignorecast = false);
+
+ CanCastResult _DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags = 0, uint64 uiOriginalCasterGUID = 0);
+
+ bool _doRemove(uint8 m_uiSpellIdx, Unit* pTarget = NULL, uint8 index = EFFECT_INDEX_ALL);
+
+ bool _doRemove(uint32 SpellID, Unit* pTarget, uint8 index = EFFECT_INDEX_ALL);
+
+ bool _doRemoveFromAll(uint8 m_uiSpellIdx);
+
+ bool _doRemoveFromAll(uint32 SpellID);
+
+ bool _doAura(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index, bool isStack = true);
+
+ bool _doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint = 0, bool isStack = true);
+
+ bool _doAura(uint8 m_uiSpellIdx, Unit* pTarget);
+
+ bool _doAura(uint32 SpellID, Unit* pTarget);
+
+ bool _hasAura(uint8 m_uiSpellIdx, Unit* pTarget);
+
+ bool _hasAura(uint32 SpellID, Unit* pTarget);
+
+ uint8 _auraCount(uint8 m_uiSpellIdx, Unit* pTarget = NULL, SpellEffectIndex index = EFFECT_INDEX_0);
+
+ uint8 _auraCount(uint32 SpellID, Unit* pTarget, SpellEffectIndex index);
+
+ void _fillEmptyDataField();
+
+ uint32 _getSpellData(uint8 m_uiSpellIdx);
+
+ bool _isDifficultyInMask(uint8 mask);
+
+ uint8 _stage;
+
+};
+
+#endif
\ No newline at end of file
diff --git a/base/BSW_instance.cpp b/base/BSW_instance.cpp
new file mode 100644
index 0000000..5d40240
--- /dev/null
+++ b/base/BSW_instance.cpp
@@ -0,0 +1,103 @@
+/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#include "precompiled.h"
+#include "BSW_instance.h"
+
+BSWScriptedInstance::BSWScriptedInstance(Map* pMap) : ScriptedInstance(pMap)
+{
+ debug_log("BSW: Initialized BSWScriptedInstance structure for map %u difficulty %u",pMap->GetId(),pMap->GetDifficulty());
+ m_auiEvent = 0;
+ m_auiEventTimer = 0;
+ m_auiCreatureID = 0;
+ m_auiEventLock = false;
+ m_pMap = pMap;
+};
+
+BSWScriptedInstance::~BSWScriptedInstance()
+{
+ debug_log("BSW: Removing BSWScriptedInstance structure for map %u",m_pMap->GetId());
+};
+
+void BSWScriptedInstance::DoCompleteAchievement(uint32 uiAchievmentId)
+{
+ Map::PlayerList const& lPlayers = instance->GetPlayers();
+
+ if (!lPlayers.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ if (Player* pPlayer = itr->getSource())
+ pPlayer->CompletedAchievement(uiAchievmentId);
+ }
+ }
+ else
+ debug_log("BSW: DoCompleteAchievement attempt set data, but no players in map.");
+}
+
+void BSWScriptedInstance::DoOpenDoor(uint64 guid)
+{
+ if (!guid)
+ return;
+
+ GameObject* pGo = instance->GetGameObject(guid);
+
+ if (pGo)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ debug_log("BSW: DoOpenDoor attempt set data to object %u, but no this object", guid);
+}
+
+void BSWScriptedInstance::DoCloseDoor(uint64 guid)
+{
+ if (!guid)
+ return;
+
+ GameObject* pGo = instance->GetGameObject(guid);
+
+ if (pGo)
+ pGo->SetGoState(GO_STATE_READY);
+ else
+ debug_log("BSW: DoCloseDoor attempt set data to object %u, but no this object", guid);
+}
+
+uint32 BSWScriptedInstance::GetEvent(uint32 creatureID)
+{
+ if (m_auiEventLock || m_auiCreatureID != creatureID)
+ {
+ return 0;
+ }
+ else
+ {
+ debug_log("BSW: GetEvent: send event %u to creature %u",m_auiEvent, creatureID);
+ m_auiEventLock = true;
+ return m_auiEvent;
+ }
+}
+
+void BSWScriptedInstance::SetNextEvent(uint32 EventNum, uint32 creatureID, uint32 timer)
+{
+ m_auiEvent = EventNum;
+ m_auiCreatureID = creatureID;
+ m_auiEventTimer = timer;
+ m_auiEventLock = false;
+ debug_log("BSW: SetNextEvent: setted event %u to creature %u, timer %u",m_auiEvent, creatureID, timer);
+}
+
+bool BSWScriptedInstance::GetEventTimer(uint32 creatureID, const uint32 diff)
+{
+ if (m_auiEvent == 0 || m_auiCreatureID != creatureID)
+ return false;
+
+ if (m_auiEventTimer <= diff)
+ {
+ m_auiEventTimer = 0;
+ return true;
+ }
+ else
+ {
+ m_auiEventTimer -= diff;
+ return false;
+ }
+}
diff --git a/base/BSW_instance.h b/base/BSW_instance.h
new file mode 100644
index 0000000..93758eb
--- /dev/null
+++ b/base/BSW_instance.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef BSW_INSTANCE_H
+#define BSW_INSTANCE_H
+#define BSW_INSTANCE_VERSION 0.6.14
+#include "sc_instance.h"
+
+class MANGOS_DLL_DECL BSWScriptedInstance : public ScriptedInstance
+{
+ public:
+
+ BSWScriptedInstance(Map* pMap);
+ ~BSWScriptedInstance();
+
+ //sends completed achievments to all players in instance
+ void DoCompleteAchievement(uint32 uiAchievmentId);
+ void DoOpenDoor(uint64 guid);
+ void DoCloseDoor(uint64 guid);
+
+ void SetNextEvent(uint32 EventNum, uint32 creatureID, uint32 timer = 1000);
+ uint32 GetEvent(uint32 creatureID);
+ bool GetEventTimer(uint32 creatureID, const uint32 diff);
+
+ private:
+ uint32 m_auiEvent;
+ uint32 m_auiCreatureID;
+ uint32 m_auiEventTimer;
+ bool m_auiEventLock;
+ Map* m_pMap;
+};
+#endif
diff --git a/base/escort_ai.cpp b/base/escort_ai.cpp
index ecc4a62..b34f1d6 100644
--- a/base/escort_ai.cpp
+++ b/base/escort_ai.cpp
@@ -517,3 +517,4 @@ void npc_escortAI::SetEscortPaused(bool bPaused)
else
RemoveEscortState(STATE_ESCORT_PAUSED);
}
+
diff --git a/include/sc_creature.cpp b/include/sc_creature.cpp
index f0526c8..684938b 100644
--- a/include/sc_creature.cpp
+++ b/include/sc_creature.cpp
@@ -525,7 +525,7 @@ bool ScriptedAI::EnterEvadeIfOutOfCombatArea(const uint32 uiDiff)
return false;
break;
case NPC_SARTHARION: // sartharion (calculate box)
- if (fX > 3218.86f && fX < 3275.69f && fY < 572.40f && fY > 484.68f)
+ if (fX > 3203.97f && fX < 3289.40f && fY < 576.70f && fY > 484.68f)
return false;
break;
default:
diff --git a/include/sc_instance.cpp b/include/sc_instance.cpp
index f91b8a0..0ad8a52 100644
--- a/include/sc_instance.cpp
+++ b/include/sc_instance.cpp
@@ -56,3 +56,19 @@ void ScriptedInstance::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData)
else
debug_log("SD2: DoUpdateWorldState attempt send data but no players in map.");
}
+
+void ScriptedInstance::DoCompleteAchievement(uint32 uiAchievmentId)
+{
+ Map::PlayerList const& lPlayers = instance->GetPlayers();
+
+ if (!lPlayers.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ if (Player* pPlayer = itr->getSource())
+ pPlayer->CompletedAchievement(uiAchievmentId);
+ }
+ }
+ else
+ debug_log("SD2: DoCompleteAchievement attempt set data but no players in map.");
+}
diff --git a/include/sc_instance.h b/include/sc_instance.h
index 3b44167..4176e51 100644
--- a/include/sc_instance.h
+++ b/include/sc_instance.h
@@ -38,5 +38,8 @@ class MANGOS_DLL_DECL ScriptedInstance : public InstanceData
//sends world state update to all players in instance
void DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData);
+
+ //sends completed achievments to all players in instance
+ void DoCompleteAchievement(uint32 uiAchievmentId);
};
#endif
diff --git a/patches/MaNGOS-10790-ScriptDev2.patch b/patches/MaNGOS-10790-ScriptDev2.patch
new file mode 100644
index 0000000..a394bcc
--- /dev/null
+++ b/patches/MaNGOS-10790-ScriptDev2.patch
@@ -0,0 +1,63 @@
+From df5d403e6d51a9dbc3dcea66faa20aa3d096f13d Mon Sep 17 00:00:00 2001
+From: Reve
+Date: Fri, 5 Mar 2010 21:41:55 +0100
+Subject: [PATCH] ScriptDev2 patch.
+
+---
+ configure.ac | 6 +++++-
+ src/bindings/Makefile.am | 2 +-
+ src/mangosd/Makefile.am | 4 ++--
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 4e7d76c..c86e539 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -364,7 +364,11 @@ AC_CONFIG_FILES([
+ src/mangosd/Makefile
+ src/mangosd/mangosd.conf.dist
+ src/bindings/Makefile
+- src/bindings/universal/Makefile
++ src/bindings/ScriptDev2/Makefile
++ src/bindings/ScriptDev2/scriptdev2.conf.dist
++ src/bindings/ScriptDev2/config.h
++ src/bindings/ScriptDev2/sql/Makefile
++ src/bindings/ScriptDev2/sql/Updates/Makefile
+ ])
+
+ ## Configure ACE, if needed
+diff --git a/src/bindings/Makefile.am b/src/bindings/Makefile.am
+index d7dc654..79ea910 100644
+--- a/src/bindings/Makefile.am
++++ b/src/bindings/Makefile.am
+@@ -14,4 +14,4 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+-SUBDIRS = universal
++SUBDIRS = ScriptDev2
+diff --git a/src/mangosd/Makefile.am b/src/mangosd/Makefile.am
+index dd1b2a4..b7723f5 100644
+--- a/src/mangosd/Makefile.am
++++ b/src/mangosd/Makefile.am
+@@ -40,7 +40,7 @@ mangos_worldd_SOURCES = \
+
+ ## Link world daemon against the shared library
+ mangos_worldd_LDADD = \
+- ../bindings/universal/libmangosscript.la \
++ ../bindings/ScriptDev2/libmangosscript.la \
+ ../game/libmangosgame.a \
+ ../game/vmap/libmangosvmaps.a \
+ ../shared/Database/libmangosdatabase.a \
+@@ -51,7 +51,7 @@ mangos_worldd_LDADD = \
+ ../../dep/src/g3dlite/libg3dlite.a \
+ ../../dep/src/gsoap/libgsoap.a
+
+-mangos_worldd_LDFLAGS = -L../../dep/src/g3dlite -L../../dep/src/gsoap -L../bindings/universal/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic
++mangos_worldd_LDFLAGS = -L../../dep/src/g3dlite -L../../dep/src/gsoap -L../bindings/ScriptDev2/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic
+
+ ## Additional files to include when running 'make dist'
+ # Include world daemon configuration
+--
+1.6.5.1.1367.gcd48
+
diff --git a/revision.h b/revision.h
new file mode 100644
index 0000000..6740dc0
--- /dev/null
+++ b/revision.h
@@ -0,0 +1,6 @@
+#ifndef __REVISION_H__
+#define __REVISION_H__
+ #define REVISION_ID "54"
+ #define REVISION_DATE "2010-12-04"
+ #define REVISION_TIME "21:01:31"
+#endif // __REVISION_H__
diff --git a/scripts/battlegrounds/battleground.cpp b/scripts/battlegrounds/battleground.cpp
index dcb1b21..ec95533 100644
--- a/scripts/battlegrounds/battleground.cpp
+++ b/scripts/battlegrounds/battleground.cpp
@@ -57,7 +57,10 @@ struct MANGOS_DLL_DECL npc_spirit_guideAI : public ScriptedAI
{
// auto cast the whole time this spell
if (!m_creature->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
+ {
+ m_creature->CastSpell(m_creature, SPELL_SPIRIT_HEAL, true);
m_creature->CastSpell(m_creature, SPELL_SPIRIT_HEAL_CHANNEL, false);
+ }
}
void CorpseRemoved(uint32 &)
diff --git a/scripts/custom/npc_arena_honor.cpp b/scripts/custom/npc_arena_honor.cpp
new file mode 100644
index 0000000..daf5247
--- /dev/null
+++ b/scripts/custom/npc_arena_honor.cpp
@@ -0,0 +1,100 @@
+/* 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: npc_arena_honor
+SD%Complete: 100%
+SDComment: by tempura, corrected by /dev/rsa
+SDCategory: custom
+EndScriptData */
+/* проверка руÑÑкого */
+#include "precompiled.h"
+#include "sc_creature.h"
+#include "sc_gossip.h"
+
+#define GOSSIP_ITEM_ARENA_TO_HONOR -3000770
+#define GOSSIP_ITEM_ARENA_TO_HONOR1 -3000771
+#define GOSSIP_ITEM_HONOR_TO_ARENA -3000772
+#define GOSSIP_ITEM_HONOR_TO_ARENA1 -3000773
+
+#define UNSUCCESSFUL_HONOR -1001007
+#define UNSUCCESSFUL_ARENA -1001008
+
+bool GossipHello_npc_arena_honor(Player* pPlayer, Creature *pCreature)
+{
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_HONOR_TO_ARENA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_HONOR_TO_ARENA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARENA_TO_HONOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARENA_TO_HONOR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
+ pPlayer->SEND_GOSSIP_MENU(3961,pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_arena_honor(Player *pPlayer, Creature *pCreature, uint32 sender, uint32 action)
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 1)
+ {
+ if (pPlayer->GetHonorPoints() >= 1000)
+ {
+ pPlayer->ModifyHonorPoints(-1000);
+ pPlayer->ModifyArenaPoints(+90);
+ }
+ else
+ DoScriptText(UNSUCCESSFUL_HONOR, pCreature);
+ }
+ if (action == GOSSIP_ACTION_INFO_DEF + 2)
+ {
+ if (pPlayer->GetHonorPoints() >= 10000)
+ {
+ pPlayer->ModifyHonorPoints(-10000);
+ pPlayer->ModifyArenaPoints(+900);
+ }
+ else
+ DoScriptText(UNSUCCESSFUL_HONOR, pCreature);
+ }
+ if (action == GOSSIP_ACTION_INFO_DEF + 3)
+ {
+ if (pPlayer->GetArenaPoints() >= 100)
+ {
+ pPlayer->ModifyArenaPoints(-100);
+ pPlayer->ModifyHonorPoints(+900);
+ }
+ else
+ DoScriptText(UNSUCCESSFUL_ARENA, pCreature);
+ }
+ if (action == GOSSIP_ACTION_INFO_DEF + 4)
+ {
+ if (pPlayer->GetArenaPoints() >= 1000)
+ {
+ pPlayer->ModifyArenaPoints(-1000);
+ pPlayer->ModifyHonorPoints(+9000);
+ }
+ else
+ DoScriptText(UNSUCCESSFUL_ARENA, pCreature);
+ }
+ pPlayer->CLOSE_GOSSIP_MENU();
+ return true;
+}
+
+void AddSC_npc_arena_honor()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="npc_arena_honor";
+ newscript->pGossipHello = &GossipHello_npc_arena_honor;
+ newscript->pGossipSelect = &GossipSelect_npc_arena_honor;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/custom/teleguy.cpp b/scripts/custom/teleguy.cpp
new file mode 100644
index 0000000..f2e8f18
--- /dev/null
+++ b/scripts/custom/teleguy.cpp
@@ -0,0 +1,877 @@
+#include "precompiled.h"
+long long int money;
+int costo;
+
+bool GossipHello_mob_teleguy(Player *player, Creature *_Creature)
+{
+ if ( player->GetTeam() == ALLIANCE ) {
+ player->ADD_GOSSIP_ITEM( 5, "Darnassus. 5 Silver" , GOSSIP_SENDER_MAIN, 1203);
+ player->ADD_GOSSIP_ITEM( 5, "Exodar. 5 Silver" , GOSSIP_SENDER_MAIN, 1216);
+ player->ADD_GOSSIP_ITEM( 5, "Stormwind. 5 Silver" , GOSSIP_SENDER_MAIN, 1206);
+ player->ADD_GOSSIP_ITEM( 5, "Ironforge. 5 Silver" , GOSSIP_SENDER_MAIN, 1224);
+ player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222);
+ player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287);
+ player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205);
+ player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288);
+ player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550);
+ player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554);
+ } else {
+ player->ADD_GOSSIP_ITEM( 5, "Orgrimmar. 5 Silver" , GOSSIP_SENDER_MAIN, 1215);
+ player->ADD_GOSSIP_ITEM( 5, "Silvermoon. 5 Silver" , GOSSIP_SENDER_MAIN, 1217);
+ player->ADD_GOSSIP_ITEM( 5, "Undercity. 5 Silver" , GOSSIP_SENDER_MAIN, 1213);
+ player->ADD_GOSSIP_ITEM( 5, "Thunder Bluff. 5 Silver" , GOSSIP_SENDER_MAIN, 1225);
+ player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222);
+ player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287);
+ player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205);
+ player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288);
+ player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550);
+ player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554);
+ }
+ player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID());
+ return true;
+}
+
+
+void SendDefaultMenu_mob_teleguy(Player *player, Creature *_Creature, uint32 action )
+{
+ if(!player->getAttackers().empty())
+ {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You are in combat!", LANG_UNIVERSAL);
+ return;
+ }
+
+ if( player->getLevel() < 8 )
+ {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be lvl 8+", LANG_UNIVERSAL);
+ return;
+ }
+
+ money = player-> GetMoney();
+ costo = 500;
+
+ if (money < costo )
+ {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You haven't enough money", LANG_UNIVERSAL);
+ return;
+ }
+
+ switch(action)
+ {
+ case 5550: //Instances
+ player->ADD_GOSSIP_ITEM( 5, "Ragefire Chasm. 10 Silver" , GOSSIP_SENDER_MAIN, 1248);
+ player->ADD_GOSSIP_ITEM( 5, "The Wailing Caverns. 10 Silver" , GOSSIP_SENDER_MAIN, 1249);
+ player->ADD_GOSSIP_ITEM( 5, "The Stockade. 10 Silver" , GOSSIP_SENDER_MAIN, 1253);
+ player->ADD_GOSSIP_ITEM( 5, "Deadmines. 10 Silver" , GOSSIP_SENDER_MAIN, 1250);
+ player->ADD_GOSSIP_ITEM( 5, "Shadowfang Keep. 10 Silver" , GOSSIP_SENDER_MAIN, 1251);
+ player->ADD_GOSSIP_ITEM( 5, "Blackfathom Deeps. 10 Silver" , GOSSIP_SENDER_MAIN, 1252);
+ player->ADD_GOSSIP_ITEM( 5, "Razorfen Kraul. 20 Silver" , GOSSIP_SENDER_MAIN, 1254);
+ player->ADD_GOSSIP_ITEM( 5, "Razorfen Downs. 20 Silver" , GOSSIP_SENDER_MAIN, 1256);
+ player->ADD_GOSSIP_ITEM( 5, "Scarlet Monastery. 20 Silver" , GOSSIP_SENDER_MAIN, 1257);
+ player->ADD_GOSSIP_ITEM( 7, "[More] ->" , GOSSIP_SENDER_MAIN, 5551);
+ player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552);
+ player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID());
+ break;
+ case 5551: //More Instances
+ player->ADD_GOSSIP_ITEM( 5, "Uldaman. 30 Silver" , GOSSIP_SENDER_MAIN, 1258);
+ player->ADD_GOSSIP_ITEM( 5, "Zul'Farrak. 30 Silver" , GOSSIP_SENDER_MAIN, 1259);
+ player->ADD_GOSSIP_ITEM( 5, "Maraudon. 40 Silver" , GOSSIP_SENDER_MAIN, 1260);
+ player->ADD_GOSSIP_ITEM( 5, "Maraudon. 40 Silver" , GOSSIP_SENDER_MAIN, 1260);
+ player->ADD_GOSSIP_ITEM( 5, "The Sunken Temple. 40 Silver" , GOSSIP_SENDER_MAIN, 1261);
+ player->ADD_GOSSIP_ITEM( 5, "Blackrock Depths. 40 Silver" , GOSSIP_SENDER_MAIN, 1262);
+ player->ADD_GOSSIP_ITEM( 5, "Dire Maul. 50 Silver" , GOSSIP_SENDER_MAIN, 1263);
+ player->ADD_GOSSIP_ITEM( 5, "Blackrock Spire. 50 Silver" , GOSSIP_SENDER_MAIN, 1264);
+ player->ADD_GOSSIP_ITEM( 5, "Stratholme. 50 Silver" , GOSSIP_SENDER_MAIN, 1265);
+ player->ADD_GOSSIP_ITEM( 5, "Scholomance. 50 Silver" , GOSSIP_SENDER_MAIN, 1266);
+ player->ADD_GOSSIP_ITEM( 7, "[More] ->" , GOSSIP_SENDER_MAIN, 5553);
+ player->ADD_GOSSIP_ITEM( 7, "<- [Back]" , GOSSIP_SENDER_MAIN, 5550);
+ player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552);
+ player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID());
+ break;
+
+case 5553: //Instances 60-70
+player->ADD_GOSSIP_ITEM( 5, "Karazhan. 1 Gold" , GOSSIP_SENDER_MAIN, 4007);
+player->ADD_GOSSIP_ITEM( 5, "Gruul's Lair. 1 Gold" , GOSSIP_SENDER_MAIN, 4008);
+player->ADD_GOSSIP_ITEM( 5, "Hellfire Citadel. 1 Gold" , GOSSIP_SENDER_MAIN, 4009);
+player->ADD_GOSSIP_ITEM( 5, "Coilfang Reservoir. 1 Gold" , GOSSIP_SENDER_MAIN, 4010);
+player->ADD_GOSSIP_ITEM( 5, "Tempest Keep. 1 Gold" , GOSSIP_SENDER_MAIN, 4011);
+player->ADD_GOSSIP_ITEM( 5, "Caverns of Time. 1 Gold" , GOSSIP_SENDER_MAIN, 4012);
+player->ADD_GOSSIP_ITEM( 5, "Zul'Aman. 1 Gold" , GOSSIP_SENDER_MAIN, 4016);
+player->ADD_GOSSIP_ITEM( 5, "Black Temple. 1 Gold" , GOSSIP_SENDER_MAIN, 4013);
+player->ADD_GOSSIP_ITEM( 5, "Magister's Terrace. 2 Gold" , GOSSIP_SENDER_MAIN, 4017);
+player->ADD_GOSSIP_ITEM( 5, "Sunwell Plateau. 2 Gold" , GOSSIP_SENDER_MAIN, 4018);
+player->ADD_GOSSIP_ITEM( 7, "<- [Back]" , GOSSIP_SENDER_MAIN, 5550);
+player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552);
+
+
+player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID());
+
+break;
+
+case 5554: //Instances 75-80 NORTHREND
+player->ADD_GOSSIP_ITEM( 5, "Utgarde Keep. 20 Gold" , GOSSIP_SENDER_MAIN, 4019);
+player->ADD_GOSSIP_ITEM( 5, "The Nexus. 20 Gold" , GOSSIP_SENDER_MAIN, 4020);
+player->ADD_GOSSIP_ITEM( 5, "Azjol-Nerub. 20 Gold" , GOSSIP_SENDER_MAIN, 4021);
+player->ADD_GOSSIP_ITEM( 5, "Ahn'kahet: The Old Kingdom. 20 Gold" , GOSSIP_SENDER_MAIN, 4022);
+player->ADD_GOSSIP_ITEM( 5, "Drak'Tharon Keep. 20 Gold" , GOSSIP_SENDER_MAIN, 4023);
+player->ADD_GOSSIP_ITEM( 5, "The Violet Hold. 20 Gold" , GOSSIP_SENDER_MAIN, 4024);
+player->ADD_GOSSIP_ITEM( 5, "Gun' Drak. 20 Gold" , GOSSIP_SENDER_MAIN, 4025);
+player->ADD_GOSSIP_ITEM( 5, "Utgarde Pinnacle. 20 Gold" , GOSSIP_SENDER_MAIN, 4026);
+player->ADD_GOSSIP_ITEM( 5, "Ulduar. 20 Gold" , GOSSIP_SENDER_MAIN, 4027);
+player->ADD_GOSSIP_ITEM( 5, "The Obsidian Sanctum. 20 Gold" , GOSSIP_SENDER_MAIN, 4028);
+player->ADD_GOSSIP_ITEM( 5, "Naxxramas. 20 Gold" , GOSSIP_SENDER_MAIN, 4029);
+player->ADD_GOSSIP_ITEM( 7, "<- [Back]" , GOSSIP_SENDER_MAIN, 5550);
+player->ADD_GOSSIP_ITEM( 7, "<- [Main Menu]" , GOSSIP_SENDER_MAIN, 5552);
+
+
+player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID());
+
+break;
+
+case 5552: //Back To Main Menu
+ if ( player->GetTeam() == ALLIANCE ) {
+player->ADD_GOSSIP_ITEM( 5, "Darnassus. 5 Silver" , GOSSIP_SENDER_MAIN, 1203);
+player->ADD_GOSSIP_ITEM( 5, "Exodar. 5 Silver" , GOSSIP_SENDER_MAIN, 1216);
+player->ADD_GOSSIP_ITEM( 5, "Stormwind. 5 Silver" , GOSSIP_SENDER_MAIN, 1206);
+player->ADD_GOSSIP_ITEM( 5, "Ironforge. 5 Silver" , GOSSIP_SENDER_MAIN, 1224);
+player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222);
+player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287);
+player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205);
+player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288);
+player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550);
+player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554);
+
+ } else {
+
+
+player->ADD_GOSSIP_ITEM( 5, "Orgrimmar. 5 Silver" , GOSSIP_SENDER_MAIN, 1215);
+player->ADD_GOSSIP_ITEM( 5, "Silvermoon. 5 Silver" , GOSSIP_SENDER_MAIN, 1217);
+player->ADD_GOSSIP_ITEM( 5, "Undercity. 5 Silver" , GOSSIP_SENDER_MAIN, 1213);
+player->ADD_GOSSIP_ITEM( 5, "Thunder Bluff. 5 Silver" , GOSSIP_SENDER_MAIN, 1225);
+player->ADD_GOSSIP_ITEM( 5, "Gnomeregan. 5 Silver" , GOSSIP_SENDER_MAIN, 1222);
+player->ADD_GOSSIP_ITEM( 5, "Shattrath City. 5 Silver" , GOSSIP_SENDER_MAIN, 1287);
+player->ADD_GOSSIP_ITEM( 5, "Dalaran. 5 Silver" , GOSSIP_SENDER_MAIN, 1205);
+player->ADD_GOSSIP_ITEM( 5, "Isle Of Quel'Danas. 5 Silver" , GOSSIP_SENDER_MAIN, 1288);
+player->ADD_GOSSIP_ITEM( 7, "[Instances] ->" , GOSSIP_SENDER_MAIN, 5550);
+player->ADD_GOSSIP_ITEM( 7, "[Instances WotLK] ->" , GOSSIP_SENDER_MAIN, 5554);
+ }
+
+player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,_Creature->GetGUID());
+
+break;
+
+case 1203: // Teleport to Darnassus
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(1, 9947.52f, 2482.73f, 1316.21f, 0.0f);
+player->ModifyMoney(-1*costo);
+break;
+
+// Teleport to Stormwind
+case 1206:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(0, -8960.14f, 516.266f, 96.3568f, 0.0f);
+player->ModifyMoney(-1*costo);
+break;
+
+// Teleport to Dalaran
+case 1205:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(571, 5804.14f, 624.770f, 647.7670f, 1.64f);
+player->ModifyMoney(-1*costo);
+break;
+
+// Teleport to Undercity
+case 1213:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(0, 1819.71f, 238.79f, 60.5321f, 0.0f);
+player->ModifyMoney(-1*costo);
+
+break;
+
+// Teleport to Orgrimmar
+case 1215:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(1, 1552.5f, -4420.66f, 8.94802f, 0.0f);
+player->ModifyMoney(-1*costo);
+break;
+
+// Teleport to Exodar
+case 1216:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(530, -4073.03f, -12020.4f, -1.47f, 0.0f);
+player->ModifyMoney(-1*costo);
+break;
+
+// Teleport to Silvermoon
+case 1217:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(530, 9338.74f, -7277.27f, 13.7895f, 0.0f);
+player->ModifyMoney(-1*costo);
+
+break;
+
+case 1222://teleport player to Gnomeregan
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(0, -5163.43f,660.40f,348.28f,4.65f);
+player->ModifyMoney(-1*costo);
+
+break;
+
+// Teleport to Ironforge
+case 1224:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(0, -4924.07f, -951.95f, 501.55f, 5.40f);
+player->ModifyMoney(-1*costo);
+
+break;
+
+// Teleport to Thunder Bluff
+case 1225:
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(1, -1280.19f,127.21f,131.35f,5.16f);
+player->ModifyMoney(-1*costo);
+
+break;
+
+case 1248://teleport player to Ragefire Chasm
+
+if( player->getLevel() >= 8)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, 1800.53f,-4394.68f,-17.93f,5.49f);
+ player->ModifyMoney(-2*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 8!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1249://teleport player to the Wailing Caverns
+
+if (player->getLevel() >= 10)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, -722.53f,-2226.30f,16.94f,2.71f);
+ player->ModifyMoney(-2*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 10!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1250://teleport player to the Deadmines
+
+if (player->getLevel() >= 10)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -11212.04f,1658.58f,25.67f,1.45f);
+ player->ModifyMoney(-2*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 10!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1251://teleport player to Shadowfang Keep
+
+ if (player->getLevel() >= 15)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -254.47f,1524.68f,76.89f,1.56f);
+ player->ModifyMoney(-2*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 15!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1252://teleport player to Blackfathom Deeps
+
+ if (player->getLevel() >= 15)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, 4254.58f,664.74f,-29.04f,1.97f);
+ player->ModifyMoney(-2*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 15!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1253://teleport player to the Stockade
+
+ if (player->getLevel() >= 20)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -8769.76f,813.08f,97.63f,2.26f);
+ player->ModifyMoney(-2*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 20!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1254://teleport player to Razorfen Kraul
+
+ if (player->getLevel() >= 24)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, -4484.04f,-1739.40f,86.47f,1.23f);
+ player->ModifyMoney(-4*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 24!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1255://teleport player to Gnomeregan
+
+ if (player->getLevel() >= 20)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -5162.62f,667.81f,248.05f,1.48f);
+ player->ModifyMoney(-4*costo);
+
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 20!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1256://teleport player to Razorfen Downs
+
+ if (player->getLevel() >= 25)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, -4645.08f,-2470.85f,85.53f,4.39f);
+ player->ModifyMoney(-4*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 25!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1257://teleport player to the Scarlet Monastery
+
+ if (player->getLevel() >= 25)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, 2843.89f,-693.74f,139.32f,5.11f);
+ player->ModifyMoney(-4*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 25!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1258://teleport player to Uldaman
+
+ if (player->getLevel() >= 35)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -6119.70f,-2957.30f,204.11f,0.03f);
+ player->ModifyMoney(-6*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 35!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1259://teleport player to Zul'Farrak
+
+ if (player->getLevel() >= 35)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, -6839.39f,-2911.03f,8.87f,0.41f);
+ player->ModifyMoney(-6*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 35!", LANG_UNIVERSAL);
+ }
+
+break;
+
+
+case 1260://teleport player to Maraudon
+
+ if (player->getLevel() >= 40)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, -1433.33f,2955.34f,96.21f,4.82f);
+ player->ModifyMoney(-8*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 40!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1261://teleport player to the Sunken Temple
+
+ if (player->getLevel() >= 45)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -10346.92f,-3851.90f,-43.41f,6.09f);
+ player->ModifyMoney(-8*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 45!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1262://teleport player to Blackrock Depths
+
+ if (player->getLevel() >= 45)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -7301.03f,-913.19f,165.37f,0.08f);
+ player->ModifyMoney(-8*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 45!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1263://teleport player to Dire Maul
+
+ if (player->getLevel() >= 50)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, -3982.47f,1127.79f,161.02f,0.05f);
+ player->ModifyMoney(-10*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1264://teleport player to Blackrock Spire
+
+ if (player->getLevel() >= 50)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -7535.43f,-1212.04f,285.45f,5.29f);
+ player->ModifyMoney(-10*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1265://teleport player to Stratholme
+
+ if (player->getLevel() >= 50)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, 3263.54f,-3379.46f,143.59f,0.00f);
+ player->ModifyMoney(-10*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1266://teleport player to Scholomance
+
+ if (player->getLevel() >= 50)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, 1219.01f,-2604.66f,85.61f,0.50f);
+ player->ModifyMoney(-10*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 50!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1287:// Shattrath City
+
+if( player->getLevel() >= 58)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, -1850.209961f, 5435.821777f, -10.961435f, 3.403913f);
+ player->ModifyMoney(-1*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 58!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 1288://teleport player to Isle Of Quel'Danas
+
+ if (player->getLevel() >= 65)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, 12947.4f,-6893.31f,5.68398f,3.09154f);
+ player->ModifyMoney(-1*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 65!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4007:// Karazhan
+
+ if (player->getLevel() >= 70)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(0, -11118.8f, -2010.84f, 47.0807f, 0.0f);
+ player->ModifyMoney(-20*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4008:// Gruul's Lair
+
+ if (player->getLevel() >= 65)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, 3539.007568f, 5082.357910f, 1.691071f, 0.0f);
+ player->ModifyMoney(-20*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 65!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4009:// Hellfire Citadel
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(530, -305.816223f, 3056.401611f, -2.473183f, 2.01f);
+player->ModifyMoney(-20*costo);
+break;
+
+case 4010:// Coilfang Reservoir
+player->CLOSE_GOSSIP_MENU();
+player->TeleportTo(530, 517.288025f, 6976.279785f, 32.007198f, 0.0f);
+player->ModifyMoney(-20*costo);
+break;
+
+case 4011:// Tempest Keep
+
+ if (player->getLevel() >= 70)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, 3089.579346f, 1399.046509f, 187.653458f, 4.794070f);
+ player->ModifyMoney(-20*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4012:// Caverns of Time
+
+ if (player->getLevel() >= 66)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(1, -8173.66f, -4746.36f, 33.8423f, 4.93989f);
+ player->ModifyMoney(-20*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 66!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4016:// Zul'Aman
+
+ if (player->getLevel() >= 70)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, 6846.95f, -7954.5f, 170.028f, 4.61501f);
+ player->ModifyMoney(-20*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4013:// Black Temple
+
+ if (player->getLevel() >= 70)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, -3610.719482f, 324.987579f, 37.400028f, 3.282981f);
+ player->ModifyMoney(-20*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4017:// magistrate
+
+ if (player->getLevel() >= 70)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, 12884.6f, -7317.69f, 65.5023f, 4.799f);
+ player->ModifyMoney(-40*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4018:// sunwell
+
+ if (player->getLevel() >= 70)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(530, 12574.1f, -6774.81f, 15.0904f, 3.13788f);
+ player->ModifyMoney(-40*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 70!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4019:// Utgarde Keep
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 1219.720f, -4865.28f, 41.25f, 0.31f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4020:// The Nexus
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 3776.950f, 6953.80f, 105.05f, 0.345f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4021:// Azjol-Nerub
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 3675.430f, 2169.00f, 35.90f, 2.29f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4022:// Ahn'kahet: The Old Kingdom
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 3646.760f, 2045.17f, 1.79f, 4.37f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4023:// Drak'Tharon Keep
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 4450.860f, -2045.25f, 162.83f, 0.00f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4024:// The Violet Hold
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 5679.820f, 486.80f, 652.40f, 4.08f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4025:// Gun' Drak
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 6937.540f, -4455.98f, 450.68f, 1.00f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4026:// Utgarde Pinnacle
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 1245.690f, -4856.59f, 216.86f, 3.45f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+case 4027:// Ulduar
+
+ if (player->getLevel() >= 80)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 8976.240f, -1281.33f, 1059.01f, 0.58f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+break;
+
+case 4028:// The Obsidian Sanctum
+
+ if (player->getLevel() >= 80)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 3625.780f, 280.40f, -120.14f, 3.25f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+break;
+
+case 4029:// Naxxramas
+
+ if (player->getLevel() >= 80)
+
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TeleportTo(571, 3668.719f, -1262.460f, 243.63f, 5.03f);
+ player->ModifyMoney(-400*costo);
+ } else {
+ player->CLOSE_GOSSIP_MENU();
+ _Creature->MonsterSay("You must be at least level 80!", LANG_UNIVERSAL);
+ }
+
+break;
+
+}
+
+
+}
+
+bool GossipSelect_mob_teleguy(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ // Main menu
+ if (sender == GOSSIP_SENDER_MAIN)
+ {
+ player->PlayerTalkClass->ClearMenus();
+ SendDefaultMenu_mob_teleguy(player, _Creature, action );
+ }
+ return true;
+}
+
+void AddSC_mob_teleguy()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "mob_teleguy";
+ newscript->pGossipHello = &GossipHello_mob_teleguy;
+ newscript->pGossipSelect = &GossipSelect_mob_teleguy;
+ newscript->pItemHello = NULL;
+ newscript->pGOHello = NULL;
+ newscript->pAreaTrigger = NULL;
+ newscript->pItemQuestAccept = NULL;
+ newscript->pGOQuestAccept = NULL;
+ newscript->pGOChooseReward = NULL;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/eastern_kingdoms/blackrock_depths/boss_coren_direbrew.cpp b/scripts/eastern_kingdoms/blackrock_depths/boss_coren_direbrew.cpp
new file mode 100644
index 0000000..9c03843
--- /dev/null
+++ b/scripts/eastern_kingdoms/blackrock_depths/boss_coren_direbrew.cpp
@@ -0,0 +1,28 @@
+/* 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_coren_direbrew
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Blackrock Depths
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_boss_coren_direbrew()
+{
+}
diff --git a/scripts/eastern_kingdoms/blackwing_lair/blackwing_lair.h b/scripts/eastern_kingdoms/blackwing_lair/blackwing_lair.h
new file mode 100644
index 0000000..e592de1
--- /dev/null
+++ b/scripts/eastern_kingdoms/blackwing_lair/blackwing_lair.h
@@ -0,0 +1,3 @@
+/* Copyright (C) 2006 - 2010 ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp b/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp
index 6a0a8bb..89b6a5f 100644
--- a/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp
+++ b/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp
@@ -22,3 +22,7 @@ SDCategory: Blackwing Lair
EndScriptData */
#include "precompiled.h"
+
+void AddSC_instance_blackwing_lair()
+{
+}
diff --git a/scripts/eastern_kingdoms/eversong_woods.cpp b/scripts/eastern_kingdoms/eversong_woods.cpp
index f552cc0..727062f 100644
--- a/scripts/eastern_kingdoms/eversong_woods.cpp
+++ b/scripts/eastern_kingdoms/eversong_woods.cpp
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Eversong_Woods
SD%Complete: 100
-SDComment: Quest support: 8483, 8488, 9686
+SDComment: Quest support: 8483, 8488, 8490, 9686
SDCategory: Eversong Woods
EndScriptData */
@@ -26,6 +26,7 @@ npc_kelerun_bloodmourn
go_harbinger_second_trial
npc_prospector_anvilward
npc_apprentice_mirveda
+npc_infused_crystal
EndContentData */
#include "precompiled.h"
@@ -434,6 +435,106 @@ CreatureAI* GetAI_npc_apprentice_mirvedaAI(Creature* pCreature)
return new npc_apprentice_mirvedaAI (pCreature);
}
+/*######
+## npc_infused_crystal
+######*/
+
+enum
+{
+ NPC_ENRAGED_WRATH = 17086,
+ QUEST_POWERING_OUR_DEFENSES = 8490,
+ INFUSED_CRYSTAL_EMOTE = -1999811
+};
+
+float fEnragedWrathPosition[3][4] =
+{
+ {8259.375977f, -7202.288574f, 139.287430f, 5.0f},
+ {8255.425781f, -7222.026367f, 139.607162f, 5.0f},
+ {8267.902344f, -7193.510742f, 139.430374f, 5.0f}
+};
+
+struct MANGOS_DLL_DECL npc_infused_crystalAI : public ScriptedAI
+{
+ npc_infused_crystalAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ uint32 m_uiQuestTimer;
+ uint32 m_uiSpawnTimer;
+ uint64 m_uiPlayerGUID;
+
+ bool bCompleted;
+
+ void Reset()
+ {
+ m_uiQuestTimer = 60000;
+ m_uiSpawnTimer = 1000;
+ m_uiPlayerGUID = 0;
+ bCompleted = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (pWho->GetTypeId() != TYPEID_PLAYER)
+ return;
+ Player* pPlayer = (Player*)pWho;
+
+ if (pPlayer->GetQuestStatus(QUEST_POWERING_OUR_DEFENSES) != QUEST_STATUS_INCOMPLETE)
+ return;
+
+ m_uiPlayerGUID = pPlayer->GetGUID();
+ }
+
+ void Aggro(Unit* pWho){}
+
+ void JustDied(Unit* pWho)
+ {
+ if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID))
+ if (pPlayer->GetQuestStatus(QUEST_POWERING_OUR_DEFENSES) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->FailQuest(QUEST_POWERING_OUR_DEFENSES);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (bCompleted)
+ return;
+
+ if (m_uiSpawnTimer < uiDiff)
+ {
+ for (uint8 i = 0; i < 3; ++i)
+ {
+ if (Creature* pEnragedWrath = m_creature->SummonCreature(NPC_ENRAGED_WRATH, fEnragedWrathPosition[i][0], fEnragedWrathPosition[i][1], fEnragedWrathPosition[i][2], fEnragedWrathPosition[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
+ {
+ pEnragedWrath->AI()->AttackStart(m_creature);
+ }
+ }
+ m_uiSpawnTimer = 40000;
+ }
+ else
+ m_uiSpawnTimer -= uiDiff;
+
+ if (m_uiQuestTimer < uiDiff)
+ {
+ if(Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiPlayerGUID))
+ {
+ pPlayer->KilledMonsterCredit(m_creature->GetEntry());
+ DoScriptText(INFUSED_CRYSTAL_EMOTE , m_creature);
+ m_creature->ForcedDespawn(5000);
+ }
+ bCompleted = true;
+ }
+ else
+ m_uiQuestTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_infused_crystal(Creature* pCreature)
+{
+ return new npc_infused_crystalAI (pCreature);
+}
+
void AddSC_eversong_woods()
{
Script* pNewScript;
@@ -461,4 +562,9 @@ void AddSC_eversong_woods()
pNewScript->GetAI = GetAI_npc_apprentice_mirvedaAI;
pNewScript->pQuestAccept = &QuestAccept_unexpected_results;
pNewScript->RegisterSelf();
+
+ pNewScript = new Script;
+ pNewScript->Name= "npc_infused_crystal";
+ pNewScript->GetAI = &GetAI_npc_infused_crystal;
+ pNewScript->RegisterSelf();
}
diff --git a/scripts/eastern_kingdoms/karazhan/chess_event.cpp b/scripts/eastern_kingdoms/karazhan/chess_event.cpp
new file mode 100644
index 0000000..f373d69
--- /dev/null
+++ b/scripts/eastern_kingdoms/karazhan/chess_event.cpp
@@ -0,0 +1,28 @@
+/* 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: chess_event
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Karazhan
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_chess_event()
+{
+}
diff --git a/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp b/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp
index 1678318..eddd135 100644
--- a/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp
+++ b/scripts/eastern_kingdoms/scarlet_enclave/ebon_hold.cpp
@@ -16,16 +16,23 @@
/* ScriptData
SDName: Ebon_Hold
-SD%Complete: 95
-SDComment: Quest support: 12641, 12733, 12739(and 12742 to 12750), 12727, 12848, 12754
- , 12801, Hacked: 12680, 12687, 12698
+SD%Complete: 85
+SDComment: Quest support: 12848, 12733, 12739(and 12742 to 12750), 12727, 12698.
SDCategory: Ebon Hold
EndScriptData */
+/* ContentData
+npc_a_special_surprise
+npc_death_knight_initiate
+npc_unworthy_initiate_anchor
+npc_unworthy_initiate
+go_acherus_soul_prison
+mob_scarlet_ghoul
+EndContentData */
+
#include "precompiled.h"
#include "escort_ai.h"
-#include "WorldPacket.h"
-#include "follower_ai.h"
+#include "ObjectMgr.h"
/*######
## npc_a_special_surprise
@@ -477,11 +484,16 @@ struct MANGOS_DLL_DECL npc_a_special_surpriseAI : public ScriptedAI
}
};
+CreatureAI* GetAI_npc_a_special_surprise(Creature* pCreature)
+{
+ return new npc_a_special_surpriseAI(pCreature);
+}
+
/*######
## npc_death_knight_initiate
######*/
-enum npc_death_knight_initiate
+enum
{
SAY_DUEL_A = -1609016,
SAY_DUEL_B = -1609017,
@@ -676,7 +688,6 @@ bool GossipSelect_npc_death_knight_initiate(Player* pPlayer, Creature* pCreature
enum eKoltira
{
- SAY_BREAKOUT0 = -1609089,
SAY_BREAKOUT1 = -1609079,
SAY_BREAKOUT2 = -1609080,
SAY_BREAKOUT3 = -1609081,
@@ -697,7 +708,8 @@ enum eKoltira
NPC_HIGH_INQUISITOR_VALROTH = 29001,
NPC_KOLTIRA_ALT = 28447,
- MODEL_KOLTIRA_TRANSFORM = 25446,
+ //not sure about this id
+ //NPC_DEATH_KNIGHT_MOUNT = 29201,
MODEL_DEATH_KNIGHT_MOUNT = 25278
};
@@ -711,7 +723,6 @@ struct MANGOS_DLL_DECL npc_koltira_deathweaverAI : public npc_escortAI
void Reset()
{
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
if (!HasEscortState(STATE_ESCORT_ESCORTING))
{
m_uiWave = 0;
@@ -724,40 +735,26 @@ struct MANGOS_DLL_DECL npc_koltira_deathweaverAI : public npc_escortAI
{
switch(uiPointId)
{
- case 0: // Jump off
- m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ case 0:
DoScriptText(SAY_BREAKOUT1, m_creature);
break;
- case 1: // Go to chest and get equip
+ case 1:
m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
break;
- case 2:
+ case 2:
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
- DoCast(m_creature, SPELL_KOLTIRA_TRANSFORM, true);
- m_creature->UpdateEntry(NPC_KOLTIRA_ALT); //Somehow aura will be reseted
+ //m_creature->UpdateEntry(NPC_KOLTIRA_ALT); //unclear if we must update or not
+ DoCastSpellIfCan(m_creature, SPELL_KOLTIRA_TRANSFORM);
break;
- case 3: // Kneel with Anti Magic Zone
+ case 3:
SetEscortPaused(true);
m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
DoScriptText(SAY_BREAKOUT2, m_creature);
- DoCast(m_creature, SPELL_ANTI_MAGIC_ZONE, true);
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- SetCombatMovement(false);
+ DoCastSpellIfCan(m_creature, SPELL_ANTI_MAGIC_ZONE); // cast again that makes bubble up
break;
- case 4: // Valroth dead, he runs away
- {
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
- SetCombatMovement(true);
- // just makes him stronger and be able to kill out
- const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
- m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, cinfo->mindmg * 100);
- m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, cinfo->maxdmg * 100);
- m_creature->UpdateDamagePhysical(BASE_ATTACK);
+ case 4:
SetRun(true);
break;
- }
case 9:
m_creature->Mount(MODEL_DEATH_KNIGHT_MOUNT);
break;
@@ -772,7 +769,7 @@ struct MANGOS_DLL_DECL npc_koltira_deathweaverAI : public npc_escortAI
if (Player* pPlayer = GetPlayerForEscort())
{
pSummoned->AI()->AttackStart(pPlayer);
- pSummoned->AddThreat(pPlayer);
+ pSummoned->AddThreat(m_creature);
}
if (pSummoned->GetEntry() == NPC_HIGH_INQUISITOR_VALROTH)
@@ -831,7 +828,7 @@ struct MANGOS_DLL_DECL npc_koltira_deathweaverAI : public npc_escortAI
}
case 5:
DoScriptText(SAY_BREAKOUT9, m_creature);
- DoCast(m_creature, SPELL_ANTI_MAGIC_ZONE, false);
+ m_creature->RemoveAurasDueToSpell(SPELL_ANTI_MAGIC_ZONE);
m_uiWave_Timer = 2500;
break;
case 6:
@@ -845,13 +842,11 @@ struct MANGOS_DLL_DECL npc_koltira_deathweaverAI : public npc_escortAI
else
m_uiWave_Timer -= uiDiff;
}
- else
- {
+
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
DoMeleeAttackIfReady();
- }
}
};
@@ -864,8 +859,7 @@ bool QuestAccept_npc_koltira_deathweaver(Player* pPlayer, Creature* pCreature, c
{
if (pQuest->GetQuestId() == QUEST_BREAKOUT)
{
- pCreature->SetStandState(UNIT_STAND_STATE_SIT);
- DoScriptText(SAY_BREAKOUT0, pCreature);
+ pCreature->SetStandState(UNIT_STAND_STATE_STAND);
if (npc_koltira_deathweaverAI* pEscortAI = dynamic_cast(pCreature->AI()))
pEscortAI->Start(false, pPlayer->GetGUID(), pQuest);
@@ -874,97 +868,10 @@ bool QuestAccept_npc_koltira_deathweaver(Player* pPlayer, Creature* pCreature, c
}
/*######
-## mob_high_inquisitor_valroth
+##
######*/
-enum valroth
-{
- SAY_VALROTH1 = -1609090,
- SAY_VALROTH2 = -1609091,
- SAY_VALROTH3 = -1609092,
- SAY_VALROTH4 = -1609093,
- SAY_VALROTH5 = -1609094,
- SAY_VALROTH6 = -1609095,
- SAY_VALROTH7 = -1609096,
- SPELL_RENEW = 38210,
- SPELL_INQUISITOR_PENANCE = 52922,
- SPELL_VALROTH_SMITE = 52926,
- SPELL_SUMMON_VALROTH_REMAINS = 52929
-};
-struct MANGOS_DLL_DECL mob_high_inquisitor_valrothAI : public ScriptedAI
-{
- mob_high_inquisitor_valrothAI(Creature *pCreature) : ScriptedAI(pCreature)
- {
- Reset();
- }
-
- uint32 uiRenew_timer;
- uint32 uiInquisitor_Penance_timer;
- uint32 uiValroth_Smite_timer;
-
- void Reset()
- {
- uiRenew_timer = 10000;
- uiInquisitor_Penance_timer = 2000;
- uiValroth_Smite_timer = 1000;
- DoScriptText(SAY_VALROTH1, m_creature);
- }
-
- void Aggro(Unit* who)
- {
- DoScriptText(SAY_VALROTH2, m_creature);
- DoCast(who, SPELL_VALROTH_SMITE);
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (uiRenew_timer < diff)
- {
- Shout();
- DoCast(m_creature, SPELL_RENEW);
- uiRenew_timer = 15000 + rand()%5000;
- }else uiRenew_timer -= diff;
-
- if (uiInquisitor_Penance_timer < diff)
- {
- Shout();
- DoCast(m_creature->getVictim(), SPELL_INQUISITOR_PENANCE);
- uiInquisitor_Penance_timer = 2000 + rand()%5000;
- }else uiInquisitor_Penance_timer -= diff;
-
- if (uiValroth_Smite_timer < diff)
- {
- Shout();
- DoCast(m_creature->getVictim(), SPELL_VALROTH_SMITE);
- uiValroth_Smite_timer = 1000 + rand()%5000;
- }else uiValroth_Smite_timer -= diff;
-
- DoMeleeAttackIfReady();
- }
-
- void Shout()
- {
- switch(rand()%30)
- {
- case 0: DoScriptText(SAY_VALROTH3, m_creature);break;
- case 1: DoScriptText(SAY_VALROTH4, m_creature);break;
- case 2: DoScriptText(SAY_VALROTH5, m_creature);break;
- case 3: DoScriptText(SAY_VALROTH6, m_creature);break;
- }
- }
-
- void JustDied(Unit* killer)
- {
- DoScriptText(SAY_VALROTH7, m_creature);
- killer->CastSpell(m_creature, SPELL_SUMMON_VALROTH_REMAINS, true);
- }
-};
-
-/*######
-## Quest: The Endless Hunger
-######*/
-
-enum npc_unworthy_initiate
+enum
{
SAY_START = -1609000, // 8 texts in total, GetTextId() generates random with this as base
SAY_AGGRO = -1609008, // 8 texts in total, GetTextId() generates random with this as base
@@ -975,11 +882,6 @@ enum npc_unworthy_initiate
SPELL_CHAINED_PESANT_BREATH = 54613,
SPELL_INITIATE_VISUAL = 51519,
- //SPELL_BLOOD_STRIKE = 52374, // Already declared in npc_death_knight_initiate
- //SPELL_DEATH_COIL = 52375,
- //SPELL_ICY_TOUCH = 52372,
- //SPELL_PLAGUE_STRIKE = 52373,
-
NPC_ANCHOR = 29521,
FACTION_MONSTER = 16,
@@ -1059,6 +961,11 @@ struct MANGOS_DLL_DECL npc_unworthy_initiate_anchorAI : public ScriptedAI
}
};
+CreatureAI* GetAI_npc_unworthy_initiate_anchor(Creature* pCreature)
+{
+ return new npc_unworthy_initiate_anchorAI(pCreature);
+}
+
/*######
## npc_unworthy_initiate
######*/
@@ -1262,11 +1169,6 @@ CreatureAI* GetAI_npc_unworthy_initiate(Creature* pCreature)
return new npc_unworthy_initiateAI(pCreature);
}
-CreatureAI* GetAI_npc_unworthy_initiate_anchor(Creature* pCreature)
-{
- return new npc_unworthy_initiate_anchorAI(pCreature);
-}
-
/*######
## go_acherus_soul_prison
######*/
@@ -1290,41 +1192,37 @@ struct MANGOS_DLL_DECL npc_eye_of_acherusAI : public ScriptedAI
{
npc_eye_of_acherusAI(Creature *pCreature) : ScriptedAI(pCreature)
{
- m_creature->SetActiveObjectState(true);
- m_creature->SetLevel(55); //else one hack
- StartTimer = 2000;
- Active = false;
+ Reset();
}
- uint32 StartTimer;
+ int32 StartTimer;
bool Active;
+ ObjectGuid ownerGuid;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(26320);
+ StartTimer = 2000;
+ Active = false;
+ }
- void Reset(){}
void AttackStart(Unit *) {}
void MoveInLineOfSight(Unit*) {}
- void JustDied(Unit*u)
+ void JustDied(Unit* killer)
{
if(!m_creature || m_creature->GetTypeId() != TYPEID_UNIT)
return;
- Unit *target = m_creature->GetCharmer();
+ m_creature->RemoveAurasDueToSpell(530);
- if(!target || target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- m_creature->SetCharmerGuid(ObjectGuid());
- target->RemoveAurasDueToSpell(51852);
- target->SetCharm(NULL);
-
- ((Player*)target)->GetCamera().ResetView();
- ((Player*)target)->SetClientControl(m_creature,0);
- ((Player*)target)->SetMover(NULL);
+ Player* owner = m_creature->GetMap()->GetPlayer(ownerGuid);
- m_creature->CleanupsBeforeDelete();
- m_creature->AddObjectToRemoveList();
- //m_creature->ForcedDespawn();
+ if(!owner)
return;
+
+ owner->RemoveAurasDueToSpell(51923);
+ owner->RemoveAurasDueToSpell(51852);
}
void MovementInform(uint32 uiType, uint32 uiPointId)
@@ -1332,8 +1230,10 @@ struct MANGOS_DLL_DECL npc_eye_of_acherusAI : public ScriptedAI
if (uiType != POINT_MOTION_TYPE && uiPointId == 0)
return;
- //char * text = "The Eye of Acherus is in your control";
- //m_creature->MonsterTextEmote(text, m_creature->GetGUID(), true);
+ DoScriptText(-1666452, m_creature);
+ m_creature->SetDisplayId(25499);
+// m_creature->SetDisplayId(26320);
+ m_creature->RemoveAurasDueToSpell(51923);
m_creature->CastSpell(m_creature, 51890, true);
}
@@ -1341,22 +1241,33 @@ struct MANGOS_DLL_DECL npc_eye_of_acherusAI : public ScriptedAI
{
if(m_creature->isCharmed())
{
+ if (ownerGuid.IsEmpty())
+ ownerGuid = m_creature->GetCharmerOrOwner()->GetObjectGuid();
+
if (StartTimer < uiDiff && !Active)
{
m_creature->CastSpell(m_creature, 70889, true);
m_creature->CastSpell(m_creature, 51892, true);
- //char * text = "The Eye of Acherus launches towards its destination";
- //m_creature->MonsterTextEmote(text, m_creature->GetGUID(), true);
- m_creature->SetSpeedRate(MOVE_FLIGHT, 6.4f,true);
+ m_creature->CastSpell(m_creature, 51923, true);
+ m_creature->SetSpeedRate(MOVE_FLIGHT, 4.0f,true);
+ DoScriptText(-1666451, m_creature);
m_creature->GetMotionMaster()->MovePoint(0, 1750.8276f, -5873.788f, 147.2266f);
Active = true;
}
- else StartTimer -= uiDiff;
+ else
+ StartTimer -= uiDiff;
}
else
{
- m_creature->CleanupsBeforeDelete();
- m_creature->AddObjectToRemoveList();
+ if (StartTimer < uiDiff)
+ {
+ m_creature->ForcedDespawn();
+ if (Player* owner = m_creature->GetMap()->GetPlayer(ownerGuid))
+ {
+ owner->RemoveAurasDueToSpell(51852);
+ owner->RemoveAurasDueToSpell(51923);
+ }
+ }
}
}
};
@@ -1366,404 +1277,162 @@ CreatureAI* GetAI_npc_eye_of_acherus(Creature* pCreature)
return new npc_eye_of_acherusAI(pCreature);
}
-enum zone
-{
- SPELL_UNDYING_RESOLVE = 51915,
- SPELL_UNDYING_RESOLVE_VISUAL = 51916,
- SPELL_REVIVE = 51918,
- NPC_VALKYR_BATTLE_MAIDEN = 28534
-};
-
-void UpdateWorldState(Map *map, uint32 id, uint32 state)
-{
- Map::PlayerList const& players = map->GetPlayers();
-
- if (!players.isEmpty())
- {
- for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- {
- if (Player* pPlayer = itr->getSource())
- pPlayer->SendUpdateWorldState(id,state);
- }
- }
-}
-
/*######
-## npc_palomino - Quest: Grand Theft Palomino - Vehicle HACK
+## mob_scarlet_ghoul
######*/
-enum npc_palomino
-{
- QUEST_GRAND_THEFT_PALOMINO = 12680,
- NPC_SALANAR_THE_HORSEMAN = 28653
-};
-struct MANGOS_DLL_DECL npc_palominoAI : public FollowerAI
-{
- npc_palominoAI(Creature* pCreature) : FollowerAI(pCreature) { Reset();}
- void Reset()
- {
- m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PASSIVE);
- m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
- }
- void MoveInLineOfSight(Unit *pWho)
- {
- FollowerAI::MoveInLineOfSight(pWho);
- if (!m_creature->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && pWho->GetEntry() == NPC_SALANAR_THE_HORSEMAN)
- {
- if (m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE*2))
- {
- if (Player* pPlayer = GetLeaderForFollower())
- {
- pPlayer->KilledMonsterCredit(28767);
- }
-
- SetFollowComplete();
- }
- }
- }
-};
-CreatureAI* GetAI_npc_palomino(Creature* pCreature)
-{
- return new npc_palominoAI(pCreature);
-}
-bool GossipHello_npc_palomino(Player* pPlayer, Creature* pCreature)
+enum
{
+ SPELL_HARVESTER_PING_DUMMY = 52514,
+ ENTRY_GOTHIK = 28658,
+
+ SAY_SCARLET_GHOUL_SPAWN1 = -1609286,
+ SAY_SCARLET_GHOUL_SPAWN2 = -1609285,
+ SAY_SCARLET_GHOUL_SPAWN3 = -1609284,
+ SAY_SCARLET_GHOUL_SPAWN4 = -1609283,
+ SAY_SCARLET_GHOUL_SPAWN5 = -1609282,
+ SAY_SCARLET_GHOUL_SPAWN6 = -1609281,
+
+ SAY_SCARLET_GOTHIK1 = -1609280,
+ SAY_SCARLET_GOTHIK2 = -1609279,
+ SAY_SCARLET_GOTHIK3 = -1609278,
+ SAY_SCARLET_GOTHIK4 = -1609277,
+ SAY_SCARLET_GOTHIK5 = -1609276,
+};
- if (pPlayer->GetQuestStatus(QUEST_GRAND_THEFT_PALOMINO) == QUEST_STATUS_INCOMPLETE)
- pPlayer->ADD_GOSSIP_ITEM( 0, "Let´s go for a ride!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
-
- return true;
-}
-
-bool GossipSelect_npc_palomino(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+struct MANGOS_DLL_DECL mob_scarlet_ghoulAI : public ScriptedAI
{
- if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ mob_scarlet_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature)
{
- pPlayer->CLOSE_GOSSIP_MENU();
+ m_bIsSpawned = false;
+ fDist = (float)urand(1, 5);
+ m_uiCreatorGuid = m_creature->GetCreatorGuid();
+ if (Player* pOwner = m_creature->GetMap()->GetPlayer(m_uiCreatorGuid) )
+ fAngle = m_creature->GetAngle(pOwner);
- if (npc_palominoAI* ppalominoAI = dynamic_cast(pCreature->AI()))
- ppalominoAI->StartFollow(pPlayer, FACTION_ESCORT_N_FRIEND_PASSIVE);
+ Reset();
}
- return true;
-}
-
-/*######
-## npc_salanar_the_horseman
-######*/
-enum salanar
-{
- SPELL_REALM_OF_SHADOWS = 52275,
- SPELL_HORSEMANS_CALL = 52362, // not working
- NPC_ACHERUS_DEATHCHARGER = 28782,
- NPC_DARK_RIDER_OF_ACHERUS = 28768
-};
-
-bool GossipHello_npc_salanar_the_horseman(Player* pPlayer, Creature* pCreature)
-{
- if (pCreature->isQuestGiver())
- pPlayer->PrepareQuestMenu( pCreature->GetGUID() );
- if (pPlayer->GetQuestStatus(12687) == QUEST_STATUS_INCOMPLETE)
- pPlayer->ADD_GOSSIP_ITEM( 0, "Send me into the Realm of Shadows.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ Unit* pTarget;
- return true;
-}
+ ObjectGuid m_uiCreatorGuid;
+ uint64 m_uiTargetGUID;
+ uint64 m_uiHarvesterGUID;
-bool GossipSelect_npc_salanar_the_horseman(Player* pPlayer, Creature *pCreature, uint32 uiSender, uint32 uiAction)
-{
- switch (uiAction)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- pPlayer->CLOSE_GOSSIP_MENU();
- pPlayer->CastSpell(pPlayer, SPELL_REALM_OF_SHADOWS, true);
- pPlayer->SummonCreature(NPC_DARK_RIDER_OF_ACHERUS, pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
- break;
- }
- return true;
-}
+ uint32 m_uiWaitForThrowTimer;
-/*######
-## mob_dark_rider_of_acherus
-######*/
-enum darkrider
-{
- //SPELL_ICY_TOUCH = 52372,
- //SPELL_BLOOD_STRIKE = 52374,
- SPELL_PLAGUE_STRIKE2 = 50688,
- SPELL_THROW = 52356,
- SPELL_DEATH_RACE_COMPLETE = 52361,
- SPELL_ACHERUS_DEATHCHARGER = 48778
-};
-struct Locations2
-{
- float x, y, z;
-};
-static Locations2 DarkriderWP[]=
-{
- {2317.0f, -5662.0f, 153.1f},
- {2248.4f, -5630.8f, 139.1f},
- {2211.3f, -5658.9f, 122.7f},
- {2144.7f, -5705.0f, 102.1f},
- {2097.5f, -5737.9f, 100.1f},
- {2037.7f, -5738.9f, 99.0f}
-};
+ bool m_bWaitForThrow;
+ bool m_bIsSpawned;
-struct MANGOS_DLL_DECL mob_dark_rider_of_acherusAI : public ScriptedAI
-{
- mob_dark_rider_of_acherusAI(Creature *pCreature) : ScriptedAI(pCreature)
- {
- StartRunning();
- }
- uint32 id;
- uint32 m_uiWalkTimer;
- uint32 uiBlood_strike_timer;
- uint32 uiIcy_touch_timer;
- uint32 uiPlague_strike_timer;
- uint32 uiThrow_timer;
-
- void StartRunning()
- {
- m_creature->Mount(25279);
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
- m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
- m_creature->SetSpeedRate(MOVE_RUN, 1.4f); // you cant get him, but see
- id = 0;
- Reset();
- }
+ float fAngle;
+ float fDist;
void Reset()
{
- m_creature->GetMotionMaster()->MovePoint(id,DarkriderWP[id].x, DarkriderWP[id].y, DarkriderWP[id].z);
- uiBlood_strike_timer = 3000;
- uiIcy_touch_timer = 4000;
- uiPlague_strike_timer = 5000;
- uiThrow_timer = 10000;
+ m_uiWaitForThrowTimer = 3000;
+ m_bWaitForThrow = false;
+ pTarget = NULL;
+ m_uiTargetGUID = 0;
+ m_uiHarvesterGUID = 0;
}
- void UpdateAI(const uint32 diff)
+ void MoveInLineOfSight(Unit *pWho)
{
- if (m_creature->getVictim())
- {
- if (uiBlood_strike_timer < diff)
- {
- DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLOOD_STRIKE);
- uiBlood_strike_timer = 5000 + rand()%1000;
- }else uiBlood_strike_timer -= diff;
-
- if (uiIcy_touch_timer < diff)
- {
- DoCastSpellIfCan(m_creature->getVictim(), SPELL_ICY_TOUCH);
- uiIcy_touch_timer = 6000 + rand()%1000;
- }else uiIcy_touch_timer -= diff;
-
- if (uiPlague_strike_timer < diff)
- {
- DoCastSpellIfCan(m_creature->getVictim(), SPELL_PLAGUE_STRIKE2);
- uiPlague_strike_timer = 12000 + rand()%1000;
- }else uiPlague_strike_timer -= diff;
-
- if (uiThrow_timer < diff)
- {
- DoCastSpellIfCan(m_creature->getVictim(), SPELL_THROW);
- uiThrow_timer = 10000 + rand()%1000;
- }else uiThrow_timer -= diff;
- }
- if (m_uiWalkTimer)
+ if (!m_bWaitForThrow && pWho->GetEntry() == ENTRY_GOTHIK && m_creature->GetDistance(pWho) < 15.0f)
{
- if (m_uiWalkTimer <= diff)
- {
- m_creature->GetMotionMaster()->MovePoint(id,DarkriderWP[id].x, DarkriderWP[id].y, DarkriderWP[id].z);
- m_uiWalkTimer = 0;
-
- }else m_uiWalkTimer -= diff;
- }
+ m_uiHarvesterGUID = pWho->GetGUID();
- DoMeleeAttackIfReady();
- if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
- m_creature->CombatStop();
- }
- void JustDied(Unit* killer)
- {
- killer->CastSpell(killer, SPELL_DEATH_RACE_COMPLETE, true);
- m_creature->Unmount();
- Creature* pTemp = killer->SummonCreature(NPC_ACHERUS_DEATHCHARGER, m_creature->GetPositionX()+2, m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
- pTemp->setFaction(killer->getFaction());
- pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
- }
-
- void MovementInform(uint32 type, uint32 tempid)
- {
- switch (id)
- {
- case 1:
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- break;
- case 5:
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
- return;
+ if (Player* pOwner = m_creature->GetMap()->GetPlayer(m_uiCreatorGuid) )
+ {
+ pOwner->KilledMonsterCredit(m_creature->GetEntry(), m_creature->GetGUID() );
+ // this will execute if m_creature survived Harvester's wrath
+ float x, y, z, o;
+ o = float(urand(53, 57))/10.0f;
+ pWho->GetNearPoint(pWho, x, y, z, pWho->GetObjectBoundingRadius(), 5.0f, o);
+ m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
+ m_bWaitForThrow = true;
+ }
}
-
- ++id;
- m_uiWalkTimer = 200;
- }
-};
-// Hack until Vehicle Support
-bool GossipHello_npc_acherus_deathcharger(Player* pPlayer, Creature* pCreature)
-{
- if (pPlayer->GetQuestStatus(12687) == QUEST_STATUS_COMPLETE)
- {
- pPlayer->Mount(25279);
- pCreature->ForcedDespawn();
}
- return true;
-}
-
-/*######
-## mob_scarlet_miner
-######*/
-enum scarlet_miner
-{
- NPC_SCARLET_GHOUL = 28845,
- SPELL_GIFT_OF_THE_HARVESTER = 52479, // only works, when miner attack you
- SPELL_GIFT_OF_THE_HARVESTER_MISSILE = 52481,
- SPELL_SCARLET_MINER_GHOUL_TRANSFORM = 52490, // approx 35%
- SPELL_SCARLET_GHOUL_COUNTER = 52500, // not working
- SPELL_SCARLET_MINER_GHOST_TRANSFORM = 52505,
- SPELL_SCARLET_GHOUL_CREDIT = 52517, // not working
- SPELL_GHOULPLOSION_GOTHIK = 52519, // no idea how to implement, but spell works
- SPELL_GHOULZAP = 52521, // not working
- SPELL_DISPEL_SCARLET_GHOUL_CREDIT_COUNTER = 52555 // is propably castet on player after quest complete
-};
+ void AttackStart(Unit *pWho) { return; }
-struct MANGOS_DLL_DECL mob_scarlet_minerAI : public ScriptedAI
-{
- mob_scarlet_minerAI(Creature *pCreature) : ScriptedAI(pCreature)
+ void UpdateAI(uint32 const uiDiff)
{
- // hack spell 52481
- SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_GIFT_OF_THE_HARVESTER_MISSILE);
- if (TempSpell && TempSpell->EffectImplicitTargetB[0] != 16)
+ if (!m_bIsSpawned)
{
- TempSpell->EffectImplicitTargetB[0] = 16;
- TempSpell->EffectImplicitTargetB[1] = 87;
- TempSpell->EffectImplicitTargetB[2] = 16;
+ DoScriptText(SAY_SCARLET_GHOUL_SPAWN1 + urand(0, 5), m_creature);
+ m_bIsSpawned = true;
}
- Reset();
- }
-
- void Reset() {}
- void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
- {
- if (pCaster->GetTypeId() == TYPEID_PLAYER && m_creature->isAlive() && pSpell->Id == SPELL_GIFT_OF_THE_HARVESTER_MISSILE)
+ if (m_bWaitForThrow)
{
- if(((Player*)pCaster)->GetQuestStatus(12698) == QUEST_STATUS_INCOMPLETE)
+ if (m_uiWaitForThrowTimer <= uiDiff)
{
- if (rand()%100 < 35)
+ if (Creature* pGothik = m_creature->GetMap()->GetCreature(m_uiHarvesterGUID) )
{
- pCaster->CastSpell(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), SPELL_SCARLET_MINER_GHOUL_TRANSFORM, true);
- //pCaster->CastSpell(pCaster, SPELL_SCARLET_GHOUL_CREDIT, true);
- ((Player*)pCaster)->KilledMonsterCredit(NPC_SCARLET_GHOUL); // hack quest credit
- }
- else
- pCaster->CastSpell(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), SPELL_SCARLET_MINER_GHOST_TRANSFORM, true, 0, 0, m_creature->GetGUID());
+ if (pGothik->AI()->DoCastSpellIfCan(m_creature, roll_chance_i(50) ? 52519 : 52521) == CAST_OK)
+ DoScriptText(SAY_SCARLET_GOTHIK1 + urand(0, 4), pGothik);
- m_creature->SetDeathState(JUST_DIED);
- m_creature->RemoveCorpse();
+ m_uiWaitForThrowTimer = 5000;
+ m_creature->KnockBackFrom(pGothik, 15.0, 5.0);
+ m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false);
+ }
+ else m_bWaitForThrow = false;
}
+ else m_uiWaitForThrowTimer -= uiDiff;
+ return;
+ }
+
+ Player* pOwner = m_creature->GetMap()->GetPlayer(m_uiCreatorGuid);
+ if (!pOwner || !pOwner->IsInWorld())
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false);
+ return;
+ }
+
+ if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != FOLLOW_MOTION_TYPE)
+ {
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveFollow(pOwner, fDist, fAngle);
}
}
};
-/*######
-## mob_scarlet_courier
-######*/
-enum scarletcourier
+CreatureAI* GetAI_mob_scarlet_ghoul(Creature* pCreature)
{
- SAY_TREE1 = -1609101,
- SAY_TREE2 = -1609102,
- SPELL_SHOOT = 52818, //creature will hardly be in right distance to use this
- GO_INCONSPICUOUS_TREE = 191144,
- NPC_SCARLET_COURIER = 29076
+ return new mob_scarlet_ghoulAI(pCreature);
};
-struct MANGOS_DLL_DECL mob_scarlet_courierAI : public ScriptedAI
-{
- mob_scarlet_courierAI(Creature *pCreature) : ScriptedAI(pCreature)
- {
- StartRunning();
- }
+// quest 12801 from Ckegg
+/*######
+## Npc Highlord Darion Mograine
+######*/
- uint32 uiWait_timer;
- ObjectGuid m_uiPlayer;
- bool found;
+void UpdateWorldState(Map *map, uint32 id, uint32 state)
+{
+ Map::PlayerList const& players = map->GetPlayers();
- void StartRunning()
+ if (!players.isEmpty())
{
- Reset();
-
- if (GameObject* treeGO = GetClosestGameObjectWithEntry(m_creature, GO_INCONSPICUOUS_TREE, 20.0f))
+ for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
- m_uiPlayer = treeGO->GetOwnerGuid();
- m_creature->Mount(14338);
- m_creature->GetMotionMaster()->MovePoint(1, treeGO->GetPositionX()+3, treeGO->GetPositionY(), treeGO->GetPositionZ());
- DoScriptText(SAY_TREE1, m_creature);
+ if (Player* pPlayer = itr->getSource())
+ pPlayer->SendUpdateWorldState(id,state);
}
}
+}
- void Reset()
- {
- uiWait_timer = 3000;
- m_uiPlayer = 0;
- found = false;
- }
- void MovementInform(uint32 type, uint32 id)
- {
- if(type == POINT_MOTION_TYPE && id ==1)
- {
- if (GameObject* treeGO = GetClosestGameObjectWithEntry(m_creature, GO_INCONSPICUOUS_TREE, ATTACK_DISTANCE))
- {
- DoScriptText(SAY_TREE2, m_creature);
- m_creature->Unmount();
- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_KICK);
- treeGO->Delete();
- found = true;
- }
- }
- }
- void UpdateAI(const uint32 diff)
- {
- if(found)
- {
- if (uiWait_timer < diff)
- {
- Unit* pPlayer = m_creature->GetMap()->GetUnit(m_uiPlayer);
- pPlayer->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- AttackStart(pPlayer);
- }
- else uiWait_timer -= diff;
- }
- DoMeleeAttackIfReady();
- }
-};
-/*######
-## npc_highlord_darion_mograine
-######*/
enum mograine
{
ENCOUNTER_DK_NUMBER = 5, // how many player queue to start the quest , or -
ENCOUNTER_DK_TIMER = 10, // *every 5 minutes. These have to be done in instance data
- ENCOUNTER_DEFENDER_NUMBER = 15, // how many of defender
- ENCOUNTER_EARTHSHATTER_NUMBER = 5, // how many of earthshatter
+ ENCOUNTER_DEFENDER_NUMBER = 20, // how many of defender
+ ENCOUNTER_EARTHSHATTER_NUMBER = 20, // how many of earthshatter
ENCOUNTER_ABOMINATION_NUMBER = 3, // how many of abomination
ENCOUNTER_BEHEMOTH_NUMBER = 2, // how many of behemoth
- ENCOUNTER_GHOUL_NUMBER = 15, // how many of ghoul
+ ENCOUNTER_GHOUL_NUMBER = 10, // how many of ghoul
ENCOUNTER_WARRIOR_NUMBER = 2, // how many of warrior
ENCOUNTER_TOTAL_DAWN = 300, // Total number
ENCOUNTER_TOTAL_SCOURGE = 10000,
@@ -1950,7 +1619,7 @@ enum mograine
NPC_RIMBLAT_EARTHSHATTER = 29182,
SPELL_CHAIN_HEAL = 33642,
- //SPELL_THUNDER = 53630 //spell is annoying and kicking units around
+ SPELL_THUNDER = 53630
};
struct Locations
@@ -1961,36 +1630,36 @@ struct Locations
static Locations LightofDawnLoc[]=
{
- {2281.335f, -5300.409f, 85.170f, 0}, // 0 Tirion Fordring loc
+ {2281.335f, -5300.409f, 85.170f, 0.0f}, // 0 Tirion Fordring loc
{2283.896f, -5287.914f, 83.066f, 1.55f}, // 1 Tirion Fordring loc2
- {2281.461f, -5263.014f, 81.164f, 0}, // 2 Tirion charges
- {2262.277f, -5293.477f, 82.167f, 0}, // 3 Tirion run
- {2270.286f, -5287.73f, 82.262f, 0}, // 4 Tirion relocate
- {2269.511f, -5288.289f, 82.225f, 0}, // 5 Tirion forward
- {2262.277f, -5293.477f, 82.167f, 0}, // 6 Tirion runs to Darion
- {2270.286f, -5287.73f, 82.262f, 0},
- {2269.511f, -5288.289f, 82.225f, 0},
- {2273.205f, -5288.848f, 82.617f, 0}, // 9 Korfax loc1
- {2274.739f, -5287.926f, 82.684f, 0}, // 10 Korfax loc2
- {2253.673f, -5318.004f, 81.724f, 0}, // 11 Korfax kicked
- {2287.028f, -5309.644f, 87.253f, 0}, // 12 Maxwell loc1
- {2286.978f, -5308.025f, 86.83f, 0}, // 13 Maxwell loc2
- {2248.877f, -5307.586f, 82.166f, 0}, // 14 maxwell kicked
- {2278.58f, -5316.933f, 88.319f, 0}, // 15 Eligor loc1
- {2278.535f, -5315.479f, 88.08f, 0}, // 16 Eligor loc2
- {2259.416f, -5304.505f, 82.149f, 0}, // 17 eligor kicked
- {2289.259f, -5280.355f, 82.112f, 0}, // 18 Koltira loc1
- {2289.02f, -5281.985f, 82.207f, 0}, // 19 Koltira loc2
- {2273.289f, -5273.675f, 81.701f, 0}, // 20 Thassarian loc1
- {2273.332f, -5275.544f, 81.849f, 0}, // 21 Thassarian loc2
- {2281.198f, -5257.397f, 80.224f, 4.66f}, // 22 Alexandros loc1
- {2281.156f, -5259.934f, 80.647f, 0}, // 23 Alexandros loc2
- {2281.294f, -5281.895f, 82.445f, 1.35f}, // 24 Darion loc1
- {2281.093f, -5263.013f, 81.125f, 0}, // 25 Darion loc1
- {2281.313f, -5250.282f, 79.322f, 4.69f}, // 26 Lich King spawns
- {2281.523f, -5261.058f, 80.877f, 0}, // 27 Lich king move forwards
- {2272.709f, -5255.552f, 78.226f, 0}, // 28 Lich king kicked
- {2273.972f, -5257.676f, 78.862f, 0} // 29 Lich king moves forward
+ {2281.461f, -5263.014f, 81.164f, 0.0f}, // 2 Tirion charges
+ {2262.277f, -5293.477f, 82.167f, 0.0f}, // 3 Tirion run
+ {2270.286f, -5287.73f, 82.262f, 0.0f}, // 4 Tirion relocate
+ {2269.511f, -5288.289f, 82.225f, 0.0f}, // 5 Tirion forward
+ {2262.277f, -5293.477f, 82.167f, 0.0f}, // 6 Tirion runs to Darion
+ {2270.286f, -5287.73f, 82.262f, 0.0f},
+ {2269.511f, -5288.289f, 82.225f, 0.0f},
+ {2273.205f, -5288.848f, 82.617f, 0.0f}, // 9 Korfax loc1
+ {2274.739f, -5287.926f, 82.684f, 0.0f}, // 10 Korfax loc2
+ {2253.673f, -5318.004f, 81.724f, 0.0f}, // 11 Korfax kicked
+ {2287.028f, -5309.644f, 87.253f, 0.0f}, // 12 Maxwell loc1
+ {2286.978f, -5308.025f, 86.83f, 0.0f}, // 13 Maxwell loc2
+ {2248.877f, -5307.586f, 82.166f, 0.0f}, // 14 maxwell kicked
+ {2278.58f, -5316.933f, 88.319f, 0.0f}, // 15 Eligor loc1
+ {2278.535f, -5315.479f, 88.08f, 0.0f}, // 16 Eligor loc2
+ {2259.416f, -5304.505f, 82.149f, 0.0f}, // 17 eligor kicked
+ {2289.259f, -5280.355f, 82.112f, 0.0f}, // 18 Koltira loc1
+ {2289.02f, -5281.985f, 82.207f, 0.0f}, // 19 Koltira loc2
+ {2273.289f, -5273.675f, 81.701f, 0.0f}, // 20 Thassarian loc1
+ {2273.332f, -5275.544f, 81.849f, 0.0f}, // 21 Thassarian loc2
+ {2281.198f, -5257.397f, 80.224f, 4.66f}, // 22 Alexandros loc1
+ {2281.156f, -5259.934f, 80.647f, 0.0f}, // 23 Alexandros loc2
+ {2281.294f, -5281.895f, 82.445f, 1.35f}, // 24 Darion loc1
+ {2281.093f, -5263.013f, 81.125f, 0.0f}, // 25 Darion loc1
+ {2281.313f, -5250.282f, 79.322f, 4.69f}, // 26 Lich King spawns
+ {2281.523f, -5261.058f, 80.877f, 0.0f}, // 27 Lich king move forwards
+ {2272.709f, -5255.552f, 78.226f, 0.0f}, // 28 Lich king kicked
+ {2273.972f, -5257.676f, 78.862f, 0.0f} // 29 Lich king moves forward
};
struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
@@ -2090,13 +1759,13 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
uiEligorGUID = NULL;
uiRayneGUID = NULL;
- for(uint8 i = 0; i < ENCOUNTER_DEFENDER_NUMBER; ++i)
+ for (uint8 i = 0; i < ENCOUNTER_DEFENDER_NUMBER; ++i)
{
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiDefenderGUID[i]))
pTemp->SetDeathState(JUST_DIED);
uiDefenderGUID[i] = 0;
}
- for(uint8 i = 0; i < ENCOUNTER_EARTHSHATTER_NUMBER; ++i)
+ for (uint8 i = 0; i < ENCOUNTER_EARTHSHATTER_NUMBER; ++i)
{
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiEarthshatterGUID[i]))
pTemp->SetDeathState(JUST_DIED);
@@ -2170,21 +1839,16 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
AttackStart(who);
}
- void SetHoldState(bool bOnHold)
- {
- SetEscortPaused(bOnHold);
- }
-
void WaypointReached(uint32 i)
{
switch(i)
{
case 0:
m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
- SetHoldState(true);
+ SetEscortPaused(true);
break;
case 1:
- SetHoldState(true);
+ SetEscortPaused(true);
if (GameObject* pGo = GetClosestGameObjectWithEntry(m_creature, GO_LIGHT_OF_DAWN, 100.0f)) // make dawn of light effect off
{
@@ -2211,7 +1875,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
NPCChangeTarget(uiThassarianGUID);
m_creature->Unmount();
- //m_creature->CastSpell(m_creature, SPELL_THE_MIGHT_OF_MOGRAINE, true); // need to fix, on player only
+ m_creature->CastSpell(m_creature, SPELL_THE_MIGHT_OF_MOGRAINE, true); // need to fix, on player only
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID))
pTemp->Unmount();
@@ -2226,21 +1890,21 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
break;
case 3:
{
- Unit* pTirion = m_creature->GetMap()->GetUnit(uiTirionGUID);
+ Creature* pTirion = m_creature->GetMap()->GetCreature(uiTirionGUID);
DoScriptText(EMOTE_LIGHT_OF_DAWN05, m_creature);
- if (m_creature->HasAura(SPELL_THE_LIGHT_OF_DAWN, EFFECT_INDEX_0))
+ if (m_creature->HasAura(SPELL_THE_LIGHT_OF_DAWN))
m_creature->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN);
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID))
{
- if (pTemp->HasAura(SPELL_THE_LIGHT_OF_DAWN, EFFECT_INDEX_0))
+ if (pTemp->HasAura(SPELL_THE_LIGHT_OF_DAWN))
pTemp->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN);
pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[19].x, LightofDawnLoc[19].y, LightofDawnLoc[19].z);
}
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID))
{
- if (pTemp->HasAura(SPELL_THE_LIGHT_OF_DAWN, EFFECT_INDEX_0))
+ if (pTemp->HasAura(SPELL_THE_LIGHT_OF_DAWN))
pTemp->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN);
pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[21].x, LightofDawnLoc[21].y, LightofDawnLoc[21].z);
@@ -2271,19 +1935,19 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
pTemp->SetStandState(UNIT_STAND_STATE_KNEEL);
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID))
pTemp->SetStandState(UNIT_STAND_STATE_KNEEL);
- SetHoldState(true);
+ SetEscortPaused(true);
break;
case 5:
DoScriptText(SAY_LIGHT_OF_DAWN33, m_creature);
- SetHoldState(true);
+ SetEscortPaused(true);
break;
case 6:
- SetHoldState(true);
+ SetEscortPaused(true);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SPECIALATTACK1H);
JumpToNextStep(1000);
break;
case 7:
- SetHoldState(true);
+ SetEscortPaused(true);
JumpToNextStep(2000);
break;
case 8:
@@ -2291,7 +1955,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID))
m_creature->CastSpell(pTemp, SPELL_ASHBRINGER, true);
DoScriptText(EMOTE_LIGHT_OF_DAWN14, m_creature);
- SetHoldState(true);
+ SetEscortPaused(true);
break;
}
}
@@ -2312,8 +1976,8 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
break;
case 1: // just delay
- UpdateWorldState(m_creature->GetMap(), WORLD_STATE_REMAINS, 1);
- //UpdateWorldState(m_creature->GetMap(), WORLD_STATE_COUNTDOWN, 0);
+ //UpdateWorldState(m_creature->GetMap(), WORLD_STATE_REMAINS, 1);
+ UpdateWorldState(m_creature->GetMap(), WORLD_STATE_COUNTDOWN, 0);
UpdateWorldState(m_creature->GetMap(), WORLD_STATE_EVENT_BEGIN, 1);
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
JumpToNextStep(3000);
@@ -2418,12 +2082,11 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
case 8: // summon announce
DoScriptText(SAY_LIGHT_OF_DAWN06, m_creature);
- m_creature->CastSpell(m_creature, SPELL_THE_MIGHT_OF_MOGRAINE, true); // need to fix, on player only
JumpToNextStep(5000);
break;
case 9: // charge begins
- SetHoldState(false);
+ SetEscortPaused(false);
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiKoltiraGUID))
{
pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
@@ -2497,7 +2160,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[23].x, LightofDawnLoc[23].y, LightofDawnLoc[23].z);
DoScriptText(SAY_LIGHT_OF_DAWN32, pTemp);
}
- SetHoldState(false); // makes darion turns back
+ SetEscortPaused(false); // makes darion turns back
JumpToNextStep(5000);
break;
@@ -2589,7 +2252,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
{
DoScriptText(SAY_LIGHT_OF_DAWN43, pTemp);
uiLichKingGUID = pTemp->GetGUID();
- if (Unit* pAlex = m_creature->GetMap()->GetUnit(uiAlexandrosGUID))
+ if (Creature* pAlex = m_creature->GetMap()->GetCreature(uiAlexandrosGUID))
pTemp->CastSpell(pAlex, SPELL_SOUL_FEAST_ALEX, false);
}
JumpToNextStep(2000);
@@ -2623,12 +2286,12 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
break;
case 33: // Darion supports to jump to lich king here
-// disable if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID))
+// disable if (Creature* pTemp = ((Creature*)Unit::GetUnit((*m_creature), uiLichKingGUID)))
// because mangos DoCast(m_creature, SPELL_MOGRAINE_CHARGE); // jumping charge
// doesn't make it looks well, so workarounds, Darion charges, looks better
m_creature->SetSpeedRate(MOVE_RUN, 3.0f);
m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
- SetHoldState(false);
+ SetEscortPaused(false);
JumpToNextStep(0);
break;
@@ -2640,7 +2303,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
}
m_creature->SetSpeedRate(MOVE_RUN, 6.0f);
((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_DEAD);
- SetHoldState(false); // Darion got kicked by lich king
+ SetEscortPaused(false); // Darion got kicked by lich king
JumpToNextStep(0);
break;
@@ -2803,12 +2466,12 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_LIGHT_OF_DAWN53, m_creature);
- SetHoldState(false); // Darion throws sword
+ SetEscortPaused(false); // Darion throws sword
JumpToNextStep(7000);
break;
case 47: // Ashbringer rebirth
- ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_DEAD);
+ ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_KNEEL);
DoScriptText(EMOTE_LIGHT_OF_DAWN15, m_creature);
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID))
{
@@ -2824,7 +2487,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
pGo->SetPhaseMask(128, true);
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID))
{
- if (pTemp->HasAura(SPELL_REBIRTH_OF_THE_ASHBRINGER, EFFECT_INDEX_0))
+ if (pTemp->HasAura(SPELL_REBIRTH_OF_THE_ASHBRINGER))
pTemp->RemoveAurasDueToSpell(SPELL_REBIRTH_OF_THE_ASHBRINGER);
pTemp->CastSpell(pTemp, 41542, false); // workarounds, light expoded, makes it cool
pTemp->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
@@ -2860,9 +2523,9 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
pTemp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
pTemp->SetSpeedRate(MOVE_RUN, 3.0f); // workarounds, make Tirion still running
pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
- //pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[2].x -1, LightofDawnLoc[2].y, LightofDawnLoc[2].z);
- //if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID))
- // pTemp->GetMap()->CreatureRelocation(pTemp, LightofDawnLoc[28].x, LightofDawnLoc[28].y, LightofDawnLoc[28].z, 0.0f); // workarounds, he should kick back by Tirion, but here we relocate him
+ pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[2].x, LightofDawnLoc[2].y, LightofDawnLoc[2].z);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID))
+ pTemp->GetMap()->CreatureRelocation(pTemp, LightofDawnLoc[28].x, LightofDawnLoc[28].y, LightofDawnLoc[28].z, 0.0f); // workarounds, he should kick back by Tirion, but here we relocate him
}
JumpToNextStep(1500);
break;
@@ -2874,13 +2537,13 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
break;
case 54:
- //if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID))
- //{
- // pTemp->SetSpeedRate(MOVE_RUN, 1.0f);
- // m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
- // pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[29].x, LightofDawnLoc[29].y, LightofDawnLoc[29].z); // 26
- //}
- JumpToNextStep(0);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiLichKingGUID))
+ {
+ pTemp->SetSpeedRate(MOVE_RUN, 1.0f);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[29].x, LightofDawnLoc[29].y, LightofDawnLoc[29].z); // 26
+ }
+ JumpToNextStep(4000);
break;
case 55:
@@ -2930,11 +2593,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
case 61:
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID))
- {
DoScriptText(SAY_LIGHT_OF_DAWN60, pTemp);
- pTemp->CastSpell(m_creature, SPELL_LAY_ON_HANDS, false);
- }
- ((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_KNEEL);
JumpToNextStep(3000);
break;
@@ -2993,8 +2652,8 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
break;
case 70:
- DoScriptText(SAY_LIGHT_OF_DAWN68, m_creature);
((Unit*)m_creature)->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_LIGHT_OF_DAWN68, m_creature);
JumpToNextStep(10000);
break;
@@ -3018,7 +2677,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
break;
case 72:
- SetHoldState(false); // Escort ends
+ SetEscortPaused(false); // Escort ends
JumpToNextStep(0);
break;
}
@@ -3193,10 +2852,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
}
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiOrbazGUID))
- {
DoScriptText(EMOTE_LIGHT_OF_DAWN04, pTemp);
- DespawnNPC(uiOrbazGUID);
- }
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiThassarianGUID))
{
@@ -3213,7 +2869,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
if (Creature* pTemp = m_creature->GetMap()->GetCreature(uiTirionGUID))
DoScriptText(SAY_LIGHT_OF_DAWN26, pTemp);
- SetHoldState(false);
+ SetEscortPaused(false);
}else uiFight_duration -= diff;
@@ -3249,7 +2905,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
for(uint8 i = 0; i < ENCOUNTER_GHOUL_NUMBER; ++i)
{
if (!(pTemp = m_creature->GetMap()->GetCreature(uiGhoulGUID[i])))
- {
+ {
pTemp = m_creature->SummonCreature(NPC_ACHERUS_GHOUL, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
pTemp->setFaction(2084);
uiGhoulGUID[i] = pTemp->GetGUID();
@@ -3290,7 +2946,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
{
pTemp = m_creature->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
pTemp->setFaction(2089);
- //m_creature->AddThreat(pTemp, 0.0f);
+ m_creature->AddThreat(pTemp, 0.0f);
uiDefenderGUID[i] = pTemp->GetGUID();
}
}
@@ -3300,7 +2956,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
{
pTemp = m_creature->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
pTemp->setFaction(2089);
- //m_creature->AddThreat(pTemp, 0.0f);
+ m_creature->AddThreat(pTemp, 0.0f);
uiEarthshatterGUID[i] = pTemp->GetGUID();
}
}
@@ -3308,28 +2964,28 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
{
pTemp = m_creature->SummonCreature(NPC_KORFAX_CHAMPION_OF_THE_LIGHT, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000);
pTemp->setFaction(2089);
- //m_creature->AddThreat(pTemp, 0.0f);
+ m_creature->AddThreat(pTemp, 0.0f);
uiKorfaxGUID = pTemp->GetGUID();
}
if (!(pTemp = m_creature->GetMap()->GetCreature(uiMaxwellGUID)))
{
pTemp = m_creature->SummonCreature(NPC_LORD_MAXWELL_TYROSUS, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000);
pTemp->setFaction(2089);
- //m_creature->AddThreat(pTemp, 0.0f);
+ m_creature->AddThreat(pTemp, 0.0f);
uiMaxwellGUID = pTemp->GetGUID();
}
if (!(pTemp = m_creature->GetMap()->GetCreature(uiEligorGUID)))
{
pTemp = m_creature->SummonCreature(NPC_COMMANDER_ELIGOR_DAWNBRINGER, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000);
pTemp->setFaction(2089);
- //m_creature->AddThreat(pTemp, 0.0f);
+ m_creature->AddThreat(pTemp, 0.0f);
uiEligorGUID = pTemp->GetGUID();
}
if (!(pTemp = m_creature->GetMap()->GetCreature(uiRayneGUID)))
{
pTemp = m_creature->SummonCreature(NPC_RAYNE, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
pTemp->setFaction(2089);
- //m_creature->AddThreat(pTemp, 0.0f);
+ m_creature->AddThreat(pTemp, 0.0f);
uiRayneGUID = pTemp->GetGUID();
}
}
@@ -3344,6 +3000,7 @@ struct MANGOS_DLL_DECL npc_highlord_darion_mograineAI : public npc_escortAI
}
}
};
+
bool GossipHello_npc_highlord_darion_mograine(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
@@ -3364,7 +3021,7 @@ bool GossipSelect_npc_highlord_darion_mograine(Player* pPlayer, Creature* pCreat
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->CLOSE_GOSSIP_MENU();
((npc_highlord_darion_mograineAI*)pCreature->AI())->uiStep = 1;
- ((npc_highlord_darion_mograineAI*)pCreature->AI())->Start(true, false, false, pPlayer->GetGUID());
+ ((npc_highlord_darion_mograineAI*)pCreature->AI())->Start(false, pPlayer->GetGUID());
break;
}
return true;
@@ -3377,61 +3034,261 @@ struct MANGOS_DLL_DECL npc_the_lich_king_tirion_dawnAI : public ScriptedAI
{
npc_the_lich_king_tirion_dawnAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
void Reset() {}
- void AttackStart(Unit *who) { return; } // very simple, just don't make them aggreesive
+ void AttackStart(Unit *who) { return; } // very sample, just don't make them aggreesive
void UpdateAI(const uint32 diff) { return; }
void JustDied(Unit* killer) {}
};
-CreatureAI* GetAI_mob_dark_rider_of_acherus(Creature* pCreature)
-{
- return new mob_dark_rider_of_acherusAI (pCreature);
-}
-
-CreatureAI* GetAI_npc_a_special_surprise(Creature* pCreature)
-{
- return new npc_a_special_surpriseAI (pCreature);
-}
-
-CreatureAI* GetAI_mob_scarlet_miner(Creature* pCreature)
-{
- return new mob_scarlet_minerAI (pCreature);
-}
+/*######
+## npc orbaz, koltira, tassarian
+######*/
+struct MANGOS_DLL_DECL npc_minibosses_dawn_of_lightAI : public ScriptedAI
+{
+ npc_minibosses_dawn_of_lightAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
+
+ uint32 uiIcyTouchTimer;
+ uint32 uiBloodStrikeTimer;
+ uint32 uiPlagueStrikeTimer;
+
+ void Reset()
+ {
+ uiIcyTouchTimer = urand(10000, 20000);
+ uiBloodStrikeTimer = urand(10000, 20000);
+ uiPlagueStrikeTimer = urand(10000, 20000);
+ }
+
+ bool EnterEvadeIfOutOfCombatArea(const uint32 uiDiff)
+ {
+ m_creature->GetMotionMaster()->MoveIdle();
+ return false;
+ }
+ void EnterEvadeMode()
+ {
+ m_creature->GetMotionMaster()->MoveIdle();
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->getVictim() || !m_creature->SelectHostileTarget() )
+ return;
+
+ if (uiIcyTouchTimer <= uiDiff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SPELL_ICY_TOUCH);
+ uiIcyTouchTimer = urand(10000, 20000);
+ }
+ else uiIcyTouchTimer -= uiDiff;
+
+ if (uiBloodStrikeTimer <= uiDiff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLOOD_STRIKE);
+ uiBloodStrikeTimer = urand(10000, 20000);
+ }
+ else uiBloodStrikeTimer -= uiDiff;
+
+ if (uiPlagueStrikeTimer <= uiDiff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SPELL_PLAGUE_STRIKE1);
+ uiPlagueStrikeTimer = urand(10000, 20000);
+ }
+ else uiPlagueStrikeTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
-CreatureAI* GetAI_mob_scarlet_courier(Creature* pCreature)
+/*######
+## Acherus Ghoul (29219)
+######*/
+struct MANGOS_DLL_DECL mob_acherus_ghoulAI : public ScriptedAI
{
- return new mob_scarlet_courierAI (pCreature);
-}
+ mob_acherus_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsReady = false;
+ m_bIsSpawned = false;
+ m_bIsInBattle = (m_creature->GetPositionX() < 2300.0f) ? true : false;
+
+ m_pMap = m_creature->GetMap();
+
+ Reset();
+ }
+
+ Map *m_pMap;
+
+ uint32 m_uiReadyTimer;
+ uint32 m_uiGhoulplosionTimer;
+
+ bool m_bIsReady;
+ bool m_bIsSpawned;
+ bool m_bIsInBattle;
+
+ void EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) { return; }
+
+ void Reset()
+ {
+ m_uiReadyTimer = 4000;
+ m_uiGhoulplosionTimer = 30000;
+ }
+
+ void MoveInLineOfSight(Unit *pWho)
+ {
+ if (!m_bIsReady)
+ return;
+
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ if (!m_bIsReady)
+ return;
+
+ ScriptedAI::AttackStart(pWho);
+ }
+
+ void UpdateAI(uint32 const uiDiff)
+ {
+ if (!m_bIsReady)
+ {
+ if (!m_bIsSpawned)
+ {
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
+ m_bIsSpawned = true;
+ }
+
+ if (m_uiReadyTimer <= uiDiff)
+ m_bIsReady = true;
+ else m_uiReadyTimer -= uiDiff;
+
+ return;
+ }
+
+ if (!m_creature->getVictim() || !m_creature->SelectHostileTarget() )
+ {
+ if (m_bIsInBattle && m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CONFUSED_MOTION_TYPE)
+ m_creature->GetMotionMaster()->MoveConfused();
+
+ return;
+ }
+
+ if (m_uiGhoulplosionTimer <= uiDiff)
+ {
+ DoCastSpellIfCan(m_creature, SPELL_GHOULPLOSION);
+ m_uiGhoulplosionTimer = 30000;
+ }
+ else m_uiGhoulplosionTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
-CreatureAI* GetAI_mob_high_inquisitor_valroth(Creature* pCreature)
+/*######
+## mob_warrior_of_the_frozen_wastes (53631)
+######*/
+struct MANGOS_DLL_DECL mob_warrior_of_the_frozen_wastesAI : public ScriptedAI
{
- return new mob_high_inquisitor_valrothAI (pCreature);
-}
+ mob_warrior_of_the_frozen_wastesAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsReady = false;
+ m_bIsSpawned = false;
+ m_bIsInBattle = (m_creature->GetPositionX() < 2300.0f) ? true : false;
+
+ Reset();
+ }
+
+ uint32 m_uiReadyTimer;
+ uint32 m_uiCleaveTimer;
+
+ bool m_bIsReady;
+ bool m_bIsSpawned;
+ bool m_bIsInBattle;
+
+ void EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) { return; }
+
+ void Reset()
+ {
+ m_uiReadyTimer = 4000;
+ m_uiCleaveTimer = urand(3000, 5000);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ if (!m_bIsReady)
+ return;
+
+ ScriptedAI::AttackStart(pWho);
+ }
+
+ void MoveInLineOfSight(Unit *pWho)
+ {
+ if (!m_bIsReady)
+ return;
+
+ CreatureAI::MoveInLineOfSight(pWho);
+ }
+
+ void UpdateAI(uint32 const uiDiff)
+ {
+ if (!m_bIsReady)
+ {
+ if (!m_bIsSpawned)
+ {
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
+ m_bIsSpawned = true;
+ }
+
+ if (m_uiReadyTimer <= uiDiff)
+ m_bIsReady = true;
+ else m_uiReadyTimer -= uiDiff;
+
+ return;
+ }
+
+ if (!m_creature->getVictim() || !m_creature->SelectHostileTarget() )
+ {
+ if (m_bIsInBattle && m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CONFUSED_MOTION_TYPE)
+ m_creature->GetMotionMaster()->MoveConfused();
+
+ return;
+ }
+
+ if (m_uiCleaveTimer <= uiDiff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE);
+ m_uiCleaveTimer = urand(13000, 15000);
+ }
+ else m_uiCleaveTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
CreatureAI* GetAI_npc_highlord_darion_mograine(Creature* pCreature)
-{
+{
return new npc_highlord_darion_mograineAI(pCreature);
}
CreatureAI* GetAI_npc_the_lich_king_tirion_dawn(Creature* pCreature)
{
- return new npc_the_lich_king_tirion_dawnAI (pCreature);
+ return new npc_the_lich_king_tirion_dawnAI(pCreature);
+};
+
+CreatureAI* GetAI_npc_minibosses_dawn_of_light(Creature* pCreature)
+{
+ return new npc_minibosses_dawn_of_lightAI (pCreature);
}
-// Hack until Vehicle Support
-bool GossipHello_scarlet_cannon(Player* pPlayer, Creature* pCreature)
+CreatureAI* GetAI_mob_warrior_of_the_frozen_wastes(Creature* pCreature)
{
- if (pPlayer->GetQuestStatus(12701) == QUEST_STATUS_INCOMPLETE)
- {
- if (rand()%100 < 50)
- {
- Creature* pTemp = GetClosestCreatureWithEntry(pPlayer, 28834, DEFAULT_VISIBILITY_DISTANCE);
- pCreature->CastSpell(pTemp,52436,true,0,0,pPlayer->GetGUID());
- }
- else pPlayer->CastSpell(pPlayer,13261,true,0,0,pCreature->GetGUID()); // Some fun malfunction :)
- }
- return true;
+ return new mob_warrior_of_the_frozen_wastesAI(pCreature);
}
+CreatureAI* GetAI_mob_acherus_ghoul(Creature* pCreature)
+{
+ return new mob_acherus_ghoulAI(pCreature);
+};
+
void AddSC_ebon_hold()
{
Script* pNewScript;
@@ -3475,29 +3332,8 @@ void AddSC_ebon_hold()
pNewScript->RegisterSelf();
pNewScript = new Script;
- pNewScript->Name = "npc_salanar_the_horseman";
- pNewScript->pGossipHello = &GossipHello_npc_salanar_the_horseman;
- pNewScript->pGossipSelect = &GossipSelect_npc_salanar_the_horseman;
- pNewScript->RegisterSelf();
-
- pNewScript = new Script;
- pNewScript->Name = "mob_dark_rider_of_acherus";
- pNewScript->GetAI = &GetAI_mob_dark_rider_of_acherus;
- pNewScript->RegisterSelf();
-
- pNewScript = new Script;
- pNewScript->Name = "mob_scarlet_miner";
- pNewScript->GetAI = &GetAI_mob_scarlet_miner;
- pNewScript->RegisterSelf();
-
- pNewScript = new Script;
- pNewScript->Name = "mob_scarlet_courier";
- pNewScript->GetAI = &GetAI_mob_scarlet_courier;
- pNewScript->RegisterSelf();
-
- pNewScript = new Script;
- pNewScript->Name = "mob_high_inquisitor_valroth";
- pNewScript->GetAI = &GetAI_mob_high_inquisitor_valroth;
+ pNewScript->Name = "mob_scarlet_ghoul";
+ pNewScript->GetAI = &GetAI_mob_scarlet_ghoul;
pNewScript->RegisterSelf();
pNewScript = new Script;
@@ -3513,19 +3349,18 @@ void AddSC_ebon_hold()
pNewScript->RegisterSelf();
pNewScript = new Script;
- pNewScript->Name = "scarlet_cannon";
- pNewScript->pGossipHello = &GossipHello_scarlet_cannon;
+ pNewScript->Name = "npc_minibosses_dawn_of_light";
+ pNewScript->GetAI = &GetAI_npc_minibosses_dawn_of_light;
pNewScript->RegisterSelf();
pNewScript = new Script;
- pNewScript->Name = "npc_acherus_deathcharger";
- pNewScript->pGossipHello = &GossipHello_npc_acherus_deathcharger;
+ pNewScript->Name = "mob_acherus_ghoul";
+ pNewScript->GetAI = &GetAI_mob_acherus_ghoul;
pNewScript->RegisterSelf();
pNewScript = new Script;
- pNewScript->Name = "npc_palomino";
- pNewScript->GetAI = &GetAI_npc_palomino;
- pNewScript->pGossipHello = &GossipHello_npc_palomino;
- pNewScript->pGossipSelect = &GossipSelect_npc_palomino;
+ pNewScript->Name = "mob_warrior_of_the_frozen_wastes";
+ pNewScript->GetAI = &GetAI_mob_warrior_of_the_frozen_wastes;
pNewScript->RegisterSelf();
+
}
diff --git a/scripts/eastern_kingdoms/shadowfang_keep/boss_hummel.cpp b/scripts/eastern_kingdoms/shadowfang_keep/boss_hummel.cpp
new file mode 100644
index 0000000..c3eddcf
--- /dev/null
+++ b/scripts/eastern_kingdoms/shadowfang_keep/boss_hummel.cpp
@@ -0,0 +1,28 @@
+/* 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_hummel
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Shadowfang Keep
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_boss_hummel()
+{
+}
diff --git a/scripts/eastern_kingdoms/stranglethorn_vale.cpp b/scripts/eastern_kingdoms/stranglethorn_vale.cpp
index 0623f82..7635685 100644
--- a/scripts/eastern_kingdoms/stranglethorn_vale.cpp
+++ b/scripts/eastern_kingdoms/stranglethorn_vale.cpp
@@ -17,15 +17,25 @@
/* ScriptData
SDName: Stranglethorn_Vale
SD%Complete: 100
-SDComment: Quest support: 592
+SDComment: Quest support: 592, 8193
SDCategory: Stranglethorn Vale
EndScriptData */
/* ContentData
mob_yenniku
+npc_riggle_bassbait
EndContentData */
#include "precompiled.h"
+#include "GameEventMgr.h"
+
+enum
+{
+ SAY_START = -1510356,
+ SAY_WINNER = -1510357,
+ SAY_END = -1510358,
+ QUEST_MASTER_ANGLER = 8193,
+};
/*######
## mob_yenniku
@@ -93,8 +103,110 @@ CreatureAI* GetAI_mob_yenniku(Creature *_Creature)
}
/*######
-##
+##npc_riggle_bassbait
######*/
+/**
+ * AI for Riggle Bassbait.
+ * This is the AI for Riggle Bassbait, see http://www.wowhead.com/?npc=15077
+ * @see ScriptedAI
+ * @author burned, gotisch
+ */
+struct MANGOS_DLL_DECL npc_riggle_bassbaitAI : public ScriptedAI
+{
+ /**
+ * Constructor of the Creature.
+ * This is called when the creature is spawned.
+ * @param c The Creature that this AI is for
+ */
+ npc_riggle_bassbaitAI(Creature *c) : ScriptedAI(c)
+ {
+ // This will keep the NPC active even if there are no players around!
+ c->SetActiveObjectState(true);
+ bEventAnnounced = bEventIsOver = bEventWinnerFound = false;
+ Reset();
+ }
+ /**
+ * Flag to check if event was announced. True if event was announced.
+ */
+ bool bEventAnnounced;
+ /**
+ * Flag to check if event is over. True if event is over.
+ */
+ bool bEventIsOver;
+ /**
+ * Flag to check if someone won the event. True if someone has won.
+ */
+ bool bEventWinnerFound;
+
+ void Reset() { }
+
+ void Aggro(Unit *who) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Announce the event max 1 minute after being spawned. But only if Fishing extravaganza is running.
+ if (!bEventAnnounced && time(NULL) % 60 == 0 && IsHolidayActive(HOLIDAY_FISHING_EXTRAVAGANZA))
+ {
+ debug_log("SD2: npc_riggle_bassbait announce HOLIDAY_FISHING_EXTRAVAGANZA contest");
+ DoScriptText(SAY_START, m_creature);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); //Quest&Gossip are now active
+ bEventAnnounced = true;
+ }
+ // The Event was started (announced) & It was not yet ended & One minute passed & the Fish are gone
+ if ( bEventAnnounced && !bEventIsOver && time(NULL) % 60 == 0 && !IsHolidayActive(HOLIDAY_FISHING_EXTRAVAGANZA))
+ {
+ debug_log("SD2: npc_riggle_bassbait end HOLIDAY_FISHING_EXTRAVAGANZA contest");
+ DoScriptText(SAY_END, m_creature);
+ bEventIsOver = true;
+ }
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+/**
+ * GossipHello for NPC Riggle Bassbait.
+ * This is called each time a Player tries to talk with the NPC.
+ */
+bool GossipHello_npc_riggle_bassbait(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver()) // If the quest is still running.
+ {
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+ pPlayer->SEND_GOSSIP_MENU(7614, pCreature->GetGUID());
+ return true;
+ }
+ // The Quest is not there anymore
+ // There is a winner!
+ pPlayer->SEND_GOSSIP_MENU(7714, pCreature->GetGUID());
+ return true;
+}
+
+bool ChooseReward_npc_riggle_bassbait(Player* pPlayer, Creature* pCreature, const Quest* pQuest, uint32 uiItem)
+{
+ // TODO: check if this can only be called if NPC has QUESTGIVER flag.
+ if (pQuest->GetQuestId() == QUEST_MASTER_ANGLER && ((npc_riggle_bassbaitAI*)(pCreature->AI()))->bEventWinnerFound == false)
+ {
+ DoScriptText(SAY_WINNER, pCreature,pPlayer);
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ ((npc_riggle_bassbaitAI*)(pCreature->AI()))->bEventWinnerFound = true;
+ Creature* creature2 = GetClosestCreatureWithEntry(pCreature,15087,60.0f);
+ if (creature2)
+ {
+ creature2->SetFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_QUESTGIVER);
+ } else {
+ debug_log("Could not change flag of Jang");
+ }
+ return true;
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_riggle_bassbait(Creature* pCreature)
+{
+ return new npc_riggle_bassbaitAI(pCreature);
+}
void AddSC_stranglethorn_vale()
{
@@ -104,4 +216,11 @@ void AddSC_stranglethorn_vale()
newscript->Name = "mob_yenniku";
newscript->GetAI = &GetAI_mob_yenniku;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_riggle_bassbait";
+ newscript->GetAI = &GetAI_npc_riggle_bassbait;
+ newscript->pGossipHello = &GossipHello_npc_riggle_bassbait;
+ newscript->pChooseReward = &ChooseReward_npc_riggle_bassbait;
+ newscript->RegisterSelf();
}
diff --git a/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp b/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp
new file mode 100644
index 0000000..feb22ba
--- /dev/null
+++ b/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp
@@ -0,0 +1,28 @@
+/* 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_muru
+SD%Complete:
+SDComment:
+SDCategory: Sunwell Plateau
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_boss_muru()
+{
+}
diff --git a/scripts/examples/boss_general.cpp b/scripts/examples/boss_general.cpp
new file mode 100644
index 0000000..659125d
--- /dev/null
+++ b/scripts/examples/boss_general.cpp
@@ -0,0 +1,113 @@
+/* Copyright (C) 2010 /dev/rsa for ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: boss_general
+SD%Complete: ?%
+SDComment: by /dev/rsa
+SDCategory: General boss instance script template
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_instance.h"
+
+enum BossSpells
+{
+ SPELL_SUPERSPELL = 99999,
+};
+
+struct MANGOS_DLL_DECL boss_generalAI : public BSWScriptedAI
+{
+ boss_generalAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_GENERAL, NOT_STARTED);
+ resetTimers();
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE) return;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+/* switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631006,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631007,m_creature,pVictim);
+ break;
+ };*/
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance) return;
+ pInstance->SetData(TYPE_GENERAL, FAIL);
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_GENERAL, IN_PROGRESS);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_GENERAL, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_SUPERSPELL, diff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+
+CreatureAI* GetAI_boss_general(Creature* pCreature)
+{
+ return new boss_generalAI(pCreature);
+}
+
+void AddSC_boss_general()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_general";
+ newscript->GetAI = &GetAI_boss_general;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite_corruptor.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite_corruptor.cpp
new file mode 100644
index 0000000..1cd08c7
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite_corruptor.cpp
@@ -0,0 +1,132 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+
+enum
+{
+ SPELL_COURSE = 60588,
+ SPELL_STRIKE = 60590
+};
+
+struct MANGOS_DLL_DECL boss_infinite_corruptorAI : public ScriptedAI
+{
+ boss_infinite_corruptorAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiStrikeTimer;
+ uint32 m_uiCourseTimer;
+
+ void Reset()
+ {
+ m_uiCourseTimer = 7000;
+ m_uiStrikeTimer = 5000;
+ }
+
+ void Aggro(Unit* who)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_BONUS, SPECIAL);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_BONUS, DONE);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ //switch(rand()%3)
+ // {
+ // case 0: DoScriptText(SAY_EPOCH_SLAY01, m_creature); break;
+ // case 1: DoScriptText(SAY_EPOCH_SLAY02, m_creature); break;
+ // case 2: DoScriptText(SAY_EPOCH_SLAY03, m_creature); break;
+ // }
+ }
+
+ void EnterEvadeMode()
+ {
+ if(!m_pInstance) return;
+
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_BONUS, IN_PROGRESS);
+
+ if(m_creature->isAlive())
+ m_creature->GetMotionMaster()->MoveTargetedHome();
+
+ m_creature->SetLootRecipient(NULL);
+
+ Reset();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+
+ if (m_uiCourseTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_COURSE);
+
+ m_uiCourseTimer = 17000;
+ }else m_uiCourseTimer -= diff;
+
+ if (m_uiStrikeTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_STRIKE);
+
+ m_uiStrikeTimer = 5000;
+ }else m_uiStrikeTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_infinite_corruptor(Creature* pCreature)
+{
+ return new boss_infinite_corruptorAI(pCreature);
+}
+
+void AddSC_boss_infinite_corruptor()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_infinite_corruptor";
+ newscript->GetAI = &GetAI_boss_infinite_corruptor;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_lord_epoch.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_lord_epoch.cpp
new file mode 100644
index 0000000..5ea369c
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_lord_epoch.cpp
@@ -0,0 +1,148 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+
+enum
+{
+ SPELL_COURSE = 52772,
+ SPELL_TIME_STOP = 58848,
+ SPELL_TIME_WARP = 52766,
+ SPELL_SPIKE_N = 52771,
+ SPELL_SPIKE_H = 58830,
+
+ SAY_EPOCH_DEATH = -1594119,
+ SAY_EPOCH_SLAY01 = -1594120,
+ SAY_EPOCH_SLAY02 = -1594121,
+ SAY_EPOCH_SLAY03 = -1594122,
+ SAY_EPOCH_WARP01 = -1594123,
+ SAY_EPOCH_WARP02 = -1594124,
+ SAY_EPOCH_WARP03 = -1594125
+};
+
+struct MANGOS_DLL_DECL boss_lord_epochAI : public ScriptedAI
+{
+ boss_lord_epochAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 Spike_Timer;
+ uint32 Warp_Timer;
+ uint32 Stop_Timer;
+ uint32 Course_Timer;
+ uint64 m_uiArthasGUID;
+
+ void Reset()
+ {
+ Course_Timer = 9300;
+ Stop_Timer = 21300;
+ Warp_Timer = 25300;
+ Spike_Timer = 5300;
+ }
+
+ void JustDied(Unit *killer)
+ {
+ DoScriptText(SAY_EPOCH_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_EPOCH_SLAY01, m_creature); break;
+ case 1: DoScriptText(SAY_EPOCH_SLAY02, m_creature); break;
+ case 2: DoScriptText(SAY_EPOCH_SLAY03, m_creature); break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+
+ if (Course_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_COURSE);
+
+ Course_Timer = 9300;
+ }else Course_Timer -= diff;
+
+ if (Spike_Timer < diff)
+ {
+
+ DoCast(m_creature->getVictim(),m_bIsHeroic ? SPELL_SPIKE_H : SPELL_SPIKE_N);
+
+ Spike_Timer = 5300;
+ }else Spike_Timer -= diff;
+
+ if (Stop_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_TIME_STOP);
+
+ Stop_Timer = 21300;
+ }else Stop_Timer -= diff;
+
+ if (Warp_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_TIME_WARP);
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_EPOCH_WARP01, m_creature); break;
+ case 1: DoScriptText(SAY_EPOCH_WARP02, m_creature); break;
+ case 2: DoScriptText(SAY_EPOCH_WARP03, m_creature); break;
+ }
+
+ Warp_Timer = 25300;
+ }else Warp_Timer -= diff;
+
+ }
+};
+
+CreatureAI* GetAI_boss_lord_epoch(Creature* pCreature)
+{
+ return new boss_lord_epochAI(pCreature);
+}
+
+void AddSC_boss_lord_epoch()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_lord_epoch";
+ newscript->GetAI = &GetAI_boss_lord_epoch;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_malganis.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_malganis.cpp
new file mode 100644
index 0000000..31f668e
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_malganis.cpp
@@ -0,0 +1,243 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+
+enum
+{
+ SAY_MALGANIS_AGGRO = -1594170,
+ SAY_MALGANIS_SLAY01 = -1594172,
+ SAY_MALGANIS_SLAY02 = -1594173,
+ SAY_MALGANIS_SLAY03 = -1594174,
+ SAY_MALGANIS_SLAY04 = -1594175,
+ SAY_MALGANIS_SLAY05 = -1594176,
+ SAY_MALGANIS_SLAY06 = -1594177,
+ SAY_MALGANIS_SLAY07 = -1594166,
+ SAY_MALGANIS_SLEEP01 = -1594185,
+ SAY_MALGANIS_SLEEP02 = -1594186,
+ SAY_MALGANIS_Sleep = -1594178,
+ SAY_MALGANIS_15HP = -1594179,
+
+ SPELL_SWAMP_N = 52720,
+ SPELL_SWAMP_H = 58852,
+ SPELL_MIND_BLAST_N = 52722,
+ SPELL_MIND_BLAST_H = 58850,
+ SPELL_SLEEP_N = 52721,
+ SPELL_SLEEP_H = 58849,
+ SPELL_VAMPIRE = 52723
+};
+
+struct MANGOS_DLL_DECL boss_malganisAI : public ScriptedAI
+{
+ boss_malganisAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ Unit* pTarget;
+ bool Sleep;
+ bool Vampire;
+ uint32 Phase;
+ Creature* Malganis;
+ Creature* Arthas;
+
+ uint32 Swamp_Timer;
+ uint32 MindBlast_Timer;
+ uint32 Sleep_Timer;
+ uint32 Vampire_Timer;
+
+ void Reset()
+ {
+ Sleep = false;
+ Vampire = false;
+ Swamp_Timer = 6300;
+ MindBlast_Timer = 11300;
+ Sleep_Timer = 17300;
+ Vampire_Timer = 30000;
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if(m_pInstance->GetData(TYPE_PHASE) > 9) return;
+
+ if(m_pInstance->GetData(TYPE_MALGANIS) != IN_PROGRESS) return;
+
+ if(!who || who == m_creature)
+ return;
+
+ ScriptedAI::AttackStart(who);
+ }
+
+ void KillCreditMalganis()
+ {
+ Map *map = m_creature->GetMap();
+ Map::PlayerList const& players = map->GetPlayers();
+ if (!players.isEmpty() && map->IsDungeon())
+ {
+ for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ if(Player* pPlayer = itr->getSource())
+ pPlayer->KilledMonsterCredit(31006, m_creature->GetGUID());
+ }
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+
+ if(m_pInstance->GetData(TYPE_PHASE) > 9)
+ {
+ KillCreditMalganis();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (Creature* pArthas = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ARTHAS)))
+ m_creature->SetInCombatWith(pArthas);
+ }
+ else
+ m_creature->RemoveFromWorld();
+
+ m_creature->SetLootRecipient(NULL);
+ }
+
+ void Aggro(Unit* who)
+ {
+ if(m_pInstance->GetData(TYPE_PHASE) > 9) return;
+
+ DoScriptText(SAY_MALGANIS_AGGRO, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch(rand()%7)
+ {
+ case 0: DoScriptText(SAY_MALGANIS_SLAY01, m_creature); break;
+ case 1: DoScriptText(SAY_MALGANIS_SLAY02, m_creature); break;
+ case 2: DoScriptText(SAY_MALGANIS_SLAY03, m_creature); break;
+ case 3: DoScriptText(SAY_MALGANIS_SLAY04, m_creature); break;
+ case 4: DoScriptText(SAY_MALGANIS_SLAY05, m_creature); break;
+ case 5: DoScriptText(SAY_MALGANIS_SLAY06, m_creature); break;
+ case 6: DoScriptText(SAY_MALGANIS_SLAY07, m_creature); break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(m_pInstance->GetData(TYPE_PHASE) > 9) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+
+ if (Swamp_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsHeroic ? SPELL_SWAMP_H : SPELL_SWAMP_N);
+
+ Swamp_Timer = 7300;
+ }else Swamp_Timer -= diff;
+
+ if (MindBlast_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsHeroic ? SPELL_MIND_BLAST_H : SPELL_MIND_BLAST_N);
+
+ MindBlast_Timer = 11300;
+ }else MindBlast_Timer -= diff;
+
+ if(m_creature->GetHealthPercent() < 40.0f)
+ {
+ if(Sleep == false)
+ {
+ Sleep = true;
+ DoScriptText(SAY_MALGANIS_Sleep, m_creature);
+ }
+
+ if (Sleep_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsHeroic ? SPELL_SLEEP_H : SPELL_SLEEP_N);
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_MALGANIS_SLEEP01, m_creature); break;
+ case 1: DoScriptText(SAY_MALGANIS_SLEEP02, m_creature); break;
+ }
+
+ Sleep_Timer = 17300;
+ }else Sleep_Timer -= diff;
+ }
+
+ if(m_creature->GetHealthPercent() < 25.0f)
+ {
+ if(Vampire == false)
+ {
+ Vampire = true;
+ DoScriptText(SAY_MALGANIS_15HP, m_creature);
+ DoCast(m_creature, SPELL_VAMPIRE);
+ }
+
+ if (Vampire_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_VAMPIRE);
+
+ Vampire_Timer = 30000;
+ }else Vampire_Timer -= diff;
+
+ }
+
+ if(m_creature->GetHealthPercent() < 5.0f)
+ {
+ m_pInstance->SetData(TYPE_PHASE, 10);
+ m_pInstance->SetData(TYPE_MALGANIS, DONE);
+ EnterEvadeMode();
+ }
+
+ }
+};
+
+CreatureAI* GetAI_boss_malganis(Creature* pCreature)
+{
+ return new boss_malganisAI(pCreature);
+}
+
+void AddSC_boss_malganis()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_malganis";
+ newscript->GetAI = &GetAI_boss_malganis;
+ newscript->RegisterSelf();
+
+}
\ No newline at end of file
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp
new file mode 100644
index 0000000..7ecbfeb
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp
@@ -0,0 +1,137 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+
+enum
+{
+ SPELL_CHAIN_N = 52696,
+ SPELL_CHAIN_H = 58823,
+ SPELL_EXPLODED_N = 52666,
+ SPELL_EXPLODED_H = 58824,
+ SPELL_FRENZY = 58841,
+
+ SAY_MEATHOOK_AGGRO = -1594111,
+ SAY_MEATHOOK_DEATH = -1594112,
+ SAY_MEATHOOK_SLAY01 = -1594113,
+ SAY_MEATHOOK_SLAY02 = -1594114,
+ SAY_MEATHOOK_SLAY03 = -1594115
+};
+
+struct MANGOS_DLL_DECL boss_meathookAI : public ScriptedAI
+{
+ boss_meathookAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 Chain_Timer;
+ uint32 Exploded_Timer;
+ uint32 Frenzy_Timer;
+
+ void Reset()
+ {
+ Chain_Timer = 6300;
+ Exploded_Timer = 5000;
+ Frenzy_Timer = 22300;
+ }
+
+ void Aggro(Unit* who)
+ {
+ DoScriptText(SAY_MEATHOOK_AGGRO, m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ DoScriptText(SAY_MEATHOOK_DEATH, m_creature);
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_PHASE, 3);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_MEATHOOK_SLAY01, m_creature); break;
+ case 1: DoScriptText(SAY_MEATHOOK_SLAY02, m_creature); break;
+ case 2: DoScriptText(SAY_MEATHOOK_SLAY03, m_creature); break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+
+ if (Chain_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsHeroic ? SPELL_CHAIN_H : SPELL_CHAIN_N);
+
+ Chain_Timer = 6300;
+ }else Chain_Timer -= diff;
+
+ if (Exploded_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsHeroic ? SPELL_EXPLODED_H : SPELL_EXPLODED_N);
+
+ Exploded_Timer = 5000;
+ }else Exploded_Timer -= diff;
+
+ if (Frenzy_Timer < diff)
+ {
+ m_creature->InterruptNonMeleeSpells(false);
+ DoCast(m_creature,SPELL_FRENZY);
+
+ Frenzy_Timer = 23300;
+ }else Frenzy_Timer -= diff;
+
+ }
+};
+
+CreatureAI* GetAI_boss_meathook(Creature* pCreature)
+{
+ return new boss_meathookAI(pCreature);
+}
+
+void AddSC_boss_meathook()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_meathook";
+ newscript->GetAI = &GetAI_boss_meathook;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp
new file mode 100644
index 0000000..ec38367
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp
@@ -0,0 +1,267 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+
+enum
+{
+ SAY_SALRAMM_AGGRO = -1594130,
+ SAY_SALRAMM_DEATH = -1594131,
+ SAY_SALRAMM_SLAY01 = -1594132,
+ SAY_SALRAMM_SLAY02 = -1594133,
+ SAY_SALRAMM_SLAY03 = -1594134,
+ SAY_SALRAMM_STEAL01 = -1594135,
+ SAY_SALRAMM_STEAL02 = -1594136,
+ SAY_SALRAMM_STEAL03 = -1594137,
+ SAY_SUMMON01 = -1594138,
+ SAY_SUMMON02 = -1594139,
+ SAY_BOOM01 = -1594140,
+ SAY_BOOM02 = -1594141,
+
+ SPELL_SB_N = 57725,
+ SPELL_SB_H = 58827,
+ SPELL_FLESH = 58845,
+ SPELL_STEAL = 52708,
+ SPELL_GNOUL_BLOW = 58825,
+ SPELL_SUMMON_GNOUL = 52451,
+
+ NPC_GNOUL = 27733
+};
+
+struct MANGOS_DLL_DECL boss_salrammAI : public ScriptedAI
+{
+ boss_salrammAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 ShadowBoltTimer;
+ uint32 FleshTimer;
+ uint32 StealTimer;
+ uint32 SummonTimer;
+
+ void Reset()
+ {
+ ShadowBoltTimer = 5000;
+ FleshTimer = (urand(7000, 9000));
+ StealTimer = (urand(9000, 17000));
+ SummonTimer = (urand(12000, 17000));
+ if(m_pInstance)
+ m_pInstance->SetData64(NPC_SALRAMM, m_creature->GetGUID());
+ }
+
+ void Aggro(Unit* who)
+ {
+ DoScriptText(SAY_SALRAMM_AGGRO, m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ DoScriptText(SAY_SALRAMM_DEATH, m_creature);
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_ENCOUNTER, DONE);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SALRAMM_SLAY01, m_creature); break;
+ case 1: DoScriptText(SAY_SALRAMM_SLAY02, m_creature); break;
+ case 2: DoScriptText(SAY_SALRAMM_SLAY03, m_creature); break;
+ }
+ }
+
+ void SpellHitTarget(Unit *target, const SpellEntry *spell)
+ {
+ if(spell->Id == SPELL_GNOUL_BLOW)
+ if(target->GetTypeId() != TYPEID_PLAYER && target->GetEntry() == NPC_GNOUL)
+ target->SetDisplayId(11686);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (ShadowBoltTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsHeroic ? SPELL_SB_H : SPELL_SB_N);
+
+ ShadowBoltTimer = (urand(5000, 6000));
+ }else ShadowBoltTimer -= diff;
+
+ if (FleshTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target,SPELL_FLESH);
+
+ FleshTimer = 7300;
+ }else FleshTimer -= diff;
+
+ if (StealTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target,SPELL_STEAL);
+
+ switch(rand()%3)
+ {
+ case 0: DoScriptText(SAY_SALRAMM_STEAL01, m_creature); break;
+ case 1: DoScriptText(SAY_SALRAMM_STEAL02, m_creature); break;
+ case 2: DoScriptText(SAY_SALRAMM_STEAL03, m_creature); break;
+ }
+
+ StealTimer = (urand(8000, 11000));
+ }else StealTimer -= diff;
+
+ if (SummonTimer < diff)
+ {
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_SUMMON01, m_creature); break;
+ case 1: DoScriptText(SAY_SUMMON02, m_creature); break;
+ }
+
+ m_creature->InterruptNonMeleeSpells(false);
+ DoCast(m_creature,SPELL_SUMMON_GNOUL);
+
+ SummonTimer = (urand(12000, 17000));
+ }else SummonTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*###
+## npc_salramm_gnoul
+###*/
+
+struct MANGOS_DLL_DECL npc_salramm_gnoulAI : public ScriptedAI
+{
+ npc_salramm_gnoulAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 m_uiBlowTimer;
+
+ void Reset()
+ {
+ m_uiBlowTimer = (urand(3000, 15000));
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiBlowTimer < uiDiff)
+ {
+ if(Creature* pSalramm = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_SALRAMM)))
+ {
+ if(pSalramm->isDead()) return;
+
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_BOOM01, pSalramm); break;
+ case 1: DoScriptText(SAY_BOOM02, pSalramm); break;
+ }
+ pSalramm->InterruptNonMeleeSpells(false);
+ pSalramm->CastSpell(m_creature, SPELL_GNOUL_BLOW, false);
+ }
+ }
+ else m_uiBlowTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+CreatureAI* GetAI_boss_salramm(Creature* pCreature)
+{
+ return new boss_salrammAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_salramm_gnoul(Creature* pCreature)
+{
+ return new npc_salramm_gnoulAI(pCreature);
+}
+
+void AddSC_boss_salramm()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_salramm";
+ newscript->GetAI = &GetAI_boss_salramm;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_salramm_gnoul";
+ newscript->GetAI = &GetAI_npc_salramm_gnoul;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp
index abf2044..05207e0 100644
--- a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp
@@ -14,222 +14,1765 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
/* ScriptData
-SDName: culling_of_stratholme
-SD%Complete: 5%
-SDComment: Placeholder
+SDName: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
SDCategory: Culling of Stratholme
EndScriptData */
#include "precompiled.h"
-#include "culling_of_stratholme.h"
+#include "def_culling_of_stratholme.h"
+#include "escort_ai.h"
+#include "WorldPacket.h"
+#include "Weather.h"
-/* *************
-** npc_chromie (gossip, quest-accept)
-************* */
+/*###
+## npc_arthas
+###*/
enum
{
- QUEST_DISPELLING_ILLUSIONS = 13149,
- QUEST_A_ROYAL_ESCORT = 13151,
+ SAY_INTRO01 = -1594071, //Arthas
+ SAY_INTRO02 = -1594072, //Uther
+ SAY_INTRO03 = -1594073, //Arthas
+ SAY_INTRO04 = -1594074, //Arthas
+ SAY_INTRO05 = -1594075, //Uther
+ SAY_INTRO06 = -1594076, //Arthas
+ SAY_INTRO07 = -1594077, //Uther
+ SAY_INTRO08 = -1594078, //Arthas
+ SAY_INTRO09 = -1594079, //Arthas
+ SAY_INTRO10 = -1594080, //Uther
+ SAY_INTRO11 = -1594081, //Arthas
+ SAY_INTRO12 = -1594082, //Uther
+ SAY_INTRO13 = -1594083, //Jaina
+ SAY_INTRO14 = -1594084, //Arthas
+ SAY_INTRO15 = -1594085, //Uther
+ SAY_INTRO16 = -1594086, //Arthas
+ SAY_INTRO17 = -1594087, //Jaina
+ SAY_INTRO18 = -1594088, //Arthas
+
+ SAY_ENTER01 = -1594089, //Arthas
+ SAY_ENTER02 = -1594090, //Cityman
+ SAY_ENTER03 = -1594091, //Arthas
+ SAY_ENTER04 = -1594092, //Crazyman
+ SAY_ENTER05 = -1594093, //Crazyman2
+ SAY_ENTER06 = -1594094, //Arthas
+ SAY_ENTER07 = -1594095, //Malganis
+ SAY_ENTER08 = -1594096, //Malganis
+ SAY_ENTER09 = -1594097, //Arthas
+ SAY_ENTER10 = -1594098, //Arthas
+
+ SAY_SALRAMM_SPAWN = -1594129,
+ SAY_MEATHOOK_SPAWN = -1594110,
- ITEM_ARCANE_DISRUPTOR = 37888,
+ SAY_PHASE501 = -1594142, //Arthas
+ SAY_PHASE502 = -1594143, //Arthas
+ SAY_PHASE503 = -1594144, //Human
+ SAY_PHASE504 = -1594145, //Arthas
+ SAY_PHASE505 = -1594146, //Arthas
+ SAY_PHASE506 = -1594147, //Human
+ SAY_PHASE507 = -1594148, //Arthas
+ SAY_PHASE508 = -1594149, //Arthas
+ SAY_PHASE509 = -1594150, //Arthas
+ SAY_PHASE510 = -1594151, //Arthas
+ SAY_PHASE511 = -1594152, //Arthas
+ SAY_PHASE512 = -1594153, //Arthas
+ SAY_PHASE513 = -1594154, //Arthas
- GOSSIP_ITEM_ENTRANCE_1 = -3595000,
- GOSSIP_ITEM_ENTRANCE_2 = -3595001,
- GOSSIP_ITEM_ENTRANCE_3 = -3595002,
+ SAY_EPOCH_INTRO = -1594155,
+ SAY_ARTHAS_INTRO = -1594156,
+ SAY_EPOCH_AGGRO = -1594157,
- TEXT_ID_ENTRANCE_1 = 12992,
- TEXT_ID_ENTRANCE_2 = 12993,
- TEXT_ID_ENTRANCE_3 = 12994,
- TEXT_ID_ENTRANCE_4 = 12995,
+ SAY_PHASE514 = -1594158, //Arthas Shkaf 01
+ SAY_PHASE515 = -1594159, //Arthas Shkaf 02
+ SAY_PHASE601 = -1594160, //Arthas Fire
+ SAY_PHASE602 = -1594161, //Arthas Picnic
+ SAY_PHASE603 = -1594162, //Arthas Picnic End
+ SAY_PHASE605 = -1594164, //Arthas mall start
+ SAY_PHASE606 = -1594188,
- GOSSIP_ITEM_INN_1 = -3595003,
- GOSSIP_ITEM_INN_2 = -3595004,
- GOSSIP_ITEM_INN_3 = -3595005,
+ SAY_MALGANIS_ESCAPE02 = -1594180,
+ SAY_MALGANIS_ESCAPE01 = -1594187,
+ SAY_MALGANIS_OUTRO = -1594182,
+ SAY_ARTHAS_OUTRO01 = -1594181,
+ SAY_ARTHAS_OUTRO02 = -1594183,
+ SAY_ARTHAS_OUTRO03 = -1594184,
- TEXT_ID_INN_1 = 12939,
- TEXT_ID_INN_2 = 12949,
- TEXT_ID_INN_3 = 12950,
- TEXT_ID_INN_4 = 12952,
+ /*SPELL*/
+ SPELL_EXORCISM_N = 52445,
+ SPELL_EXORCISM_H = 58822,
+ SPELL_HOLY_LIGHT = 52444,
+ SPELL_ARTHAS_AURA = 52442,
+
+ /*NPC*/
+ NPC_CITYMAN = 28167,
+ NPC_CRAZYMAN = 28169,
+ NPC_MALGANIS_INTRO = 26533,
+
+ /*OTHER*/
+ POINT_LAST_POINT = 0xFFFFFF,
+ FACTION = 2076
};
-bool GossipHello_npc_chromie(Player *pPlayer, Creature *pCreature)
+const float SummonScourge[2][4] =
{
- if (pCreature->isQuestGiver())
- pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+ {2340.058f, 1253.570f, 132.733f, 5.09f}, //right wing
+ {2272.773f, 1331.824f, 124.171f, 3.12f}, //left wing
+};
+
+struct MANGOS_DLL_DECL npc_arthasAI : public npc_escortAI
+{
+ npc_arthasAI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ m_creature->SetSpeedRate(MOVE_RUN, 1);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint64 m_uiUtherGUID;
+ uint64 m_uiJainaGUID;
+ uint64 m_uiPeople01GUID;
+ uint64 m_uiPeople02GUID;
+ uint64 m_uiMalganisGUID;
+ uint64 m_uiMarine01GUID;
+ uint64 m_uiMarine02GUID;
+ uint64 m_uiMarine03GUID;
+ uint64 m_uiMarine04GUID;
+ uint64 m_uiPriest01GUID;
+ uint64 m_uiPriest02GUID;
+ uint64 m_uiHuman01GUID;
+ uint64 m_uiHuman02GUID;
+ uint64 m_uiHuman03GUID;
+
+ uint32 culling_faction;
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ uint32 m_uiMoveTimer;
+ uint32 m_uiHealTimer;
+ uint32 m_uiExorcismTimer;
+ uint32 m_uiSummonTimer;
+ uint32 m_uiWaveCount;
+
+ Creature* Malganis;
+ Creature* pEpoch;
+ bool StartEvent;
+ bool MoveSoldier;
+
+ float LastX;
+ float LastY;
+ float LastZ;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+
+ m_creature->SetSpeedRate(MOVE_RUN, 1);
+
+ if(m_pInstance->GetData(TYPE_INTRO) == NOT_STARTED)
+ {
+ m_creature->setFaction(35);
+ RemoveGossip();
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 11)
+ {
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+ }
+
+ void RemoveGossip()
+ {
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+
+ void MoveSoldiers()
+ {
+ if(Unit* Marine01 = m_creature->GetMap()->GetUnit( m_uiMarine01GUID))
+ {
+ Marine01->GetMotionMaster()->MovePoint(0, 2083.483f,1282.313f,141.198f);
+ Marine01->setFaction(culling_faction);
+ }
+ if(Unit* Marine02 = m_creature->GetMap()->GetUnit( m_uiMarine02GUID))
+ {
+ Marine02->GetMotionMaster()->MovePoint(0, 2083.681f,1292.809f,141.141f);
+ Marine02->setFaction(culling_faction);
+ }
+ if(Unit* Marine03 = m_creature->GetMap()->GetUnit( m_uiMarine03GUID))
+ {
+ Marine03->GetMotionMaster()->MovePoint(0, 2082.158f,1290.406f,141.261f);
+ Marine03->setFaction(culling_faction);
+ }
+ if(Unit* Marine04 = m_creature->GetMap()->GetUnit( m_uiMarine04GUID))
+ {
+ Marine04->GetMotionMaster()->MovePoint(0, 2081.899f,1285.122f,141.302f);
+ Marine04->setFaction(culling_faction);
+ }
+ if(Unit* Priest01 = m_creature->GetMap()->GetUnit( m_uiPriest01GUID))
+ {
+ Priest01->GetMotionMaster()->MovePoint(0, 2081.072f,1292.233f,141.329f);
+ Priest01->setFaction(culling_faction);
+ }
+ if(Unit* Priest02 = m_creature->GetMap()->GetUnit( m_uiPriest02GUID))
+ {
+ Priest02->GetMotionMaster()->MovePoint(0, 2080.632f,1283.004f,141.358f);
+ Priest02->setFaction(culling_faction);
+ }
+ }
+
+ void EnableEscort()
+ {
+ SetEscortPaused(false);
+ }
+
+ void SummonPeople()
+ {
+ if(Creature* Cityman = m_creature->SummonCreature(NPC_CITYMAN,2091.977f,1275.021f,140.757f,0.558f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000))
+ m_uiPeople01GUID = Cityman->GetGUID();
+ if(Creature* Crazyman = m_creature->SummonCreature(NPC_CRAZYMAN,2093.514f,1275.842f,140.408f,3.801f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000))
+ m_uiPeople02GUID = Crazyman->GetGUID();
+ }
+
+ void StartAI()
+ {
+ SummonPeople();
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ StartEvent = true;
+ }
+
+ void Aggro(Unit* who)
+ {
+ DoCast(m_creature, SPELL_ARTHAS_AURA);
+ }
+
+ void EnterEvadeMode()
+ {
+ if(!m_pInstance) return;
+
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ m_uiExorcismTimer = 7400;
+ m_uiHealTimer = 100;
+
+ m_creature->SetLootRecipient(NULL);
- if (instance_culling_of_stratholme* m_pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData())
+ if(m_pInstance->GetData(TYPE_PHASE) > 4)
+ {
+ npc_escortAI::EnterEvadeMode();
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) > 2 && m_pInstance->GetData(TYPE_PHASE) < 5)
+ {
+ m_creature->GetMotionMaster()->MovePoint(POINT_LAST_POINT, LastX, LastY, LastZ);
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if(!pWho || pWho == m_creature)
+ return;
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 4) return;
+
+ npc_escortAI::AttackStart(pWho);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
{
- switch (pCreature->GetEntry())
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
{
- case NPC_CHROMIE_INN:
- if (m_pInstance->GetData(TYPE_GRAIN_EVENT) != DONE)
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
{
- if (pPlayer->GetQuestRewardStatus(QUEST_DISPELLING_ILLUSIONS) && !pPlayer->HasItemCount(ITEM_ARCANE_DISRUPTOR, 1))
- pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INN_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
}
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_1, pCreature->GetGUID());
- break;
- case NPC_CHROMIE_ENTRANCE:
- if (m_pInstance->GetData(TYPE_GRAIN_EVENT) == DONE && m_pInstance->GetData(TYPE_ARTHAS_INTRO_EVENT) == NOT_STARTED && pPlayer->GetQuestRewardStatus(QUEST_A_ROYAL_ESCORT))
- pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ENTRANCE_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_1, pCreature->GetGUID());
- break;
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
}
}
- return true;
-}
-bool GossipSelect_npc_chromie(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 uiAction)
-{
- switch (pCreature->GetEntry())
+ void WaypointReached(uint32 uiPointId)
{
- case NPC_CHROMIE_INN:
- switch (uiAction)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INN_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_2, pCreature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INN_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_3, pCreature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_INN_4, pCreature->GetGUID());
- if (!pPlayer->HasItemCount(ITEM_ARCANE_DISRUPTOR, 1))
- {
- if (Item* pItem = pPlayer->StoreNewItemInInventorySlot(ITEM_ARCANE_DISRUPTOR, 1))
+ switch(uiPointId)
+ {
+ case 2:
+ DoScriptText(SAY_INTRO18, m_creature);
+ SetRun(true);
+ break;
+ case 8:
+ GetSoldier();
+ SetEscortPaused(true);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ m_pInstance->SetData(TYPE_INTRO, DONE);
+ SetRun(false);
+ break;
+ case 9:
+ DoScriptText(SAY_ENTER01, m_creature);
+ MoveSoldier = true;
+ m_uiMoveTimer = 12000;
+ break;
+ case 10:
+ SetEscortPaused(true);
+ m_pInstance->SetData(TYPE_PHASE, 2);
+ ResetStep(2000);
+ if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID))
+ {
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Cityman->GetGUID());
+ Cityman->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ Cityman->GetMotionMaster()->MovePoint(0, 2088.625f,1279.191f,140.743f);
+ }
+ break;
+ case 14:
+ if(Creature* Human01 = m_creature->SummonCreature(NPC_CITY,2397.308f,1207.565f,134.038f,5.593f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000))
+ m_uiHuman01GUID = Human01->GetGUID();
+ if(Creature* Human02 = m_creature->SummonCreature(NPC_CITY,2400.770f,1207.362f,134.038f,3.454f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000))
+ m_uiHuman02GUID = Human02->GetGUID();
+ if(Creature* Human03 = m_creature->SummonCreature(NPC_CITY,2400.547f,1204.892f,134.038f,2.479f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,30000))
+ m_uiHuman03GUID = Human03->GetGUID();
+ break;
+ case 20:
+ SetEscortPaused(true);
+ m_creature->setFaction(35);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ SetRun(false);
+ break;
+ case 21:
+ DoScriptText(SAY_PHASE502, m_creature);
+ break;
+ case 22:
+ SetEscortPaused(true);
+ m_pInstance->SetData(TYPE_PHASE, 6);
+ ResetStep(1000);
+ break;
+ case 25:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H);
+ m_creature->SummonCreature(NPC_TIME_RIFT,2428.901f, 1192.164f, 148.076f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ DoScriptText(SAY_PHASE508, m_creature);
+ break;
+ case 26:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
+ DoScriptText(SAY_PHASE509, m_creature);
+ break;
+ case 29:
+ m_creature->SummonCreature(NPC_TIME_RIFT,2413.773f, 1137.820f, 148.076f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_TIME_RIFT,2404.990f, 1175.121f, 148.076f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ DoScriptText(SAY_PHASE510, m_creature);
+ break;
+ case 30:
+ DoScriptText(SAY_PHASE513, m_creature);
+ break;
+ case 31:
+ ResetStep(1000);
+ m_pInstance->SetData(TYPE_PHASE, 7);
+ break;
+ case 32:
+ SetEscortPaused(true);
+ m_pInstance->SetData(TYPE_PHASE, 8);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ SetRun(false);
+ break;
+ case 36:
+ DoScriptText(SAY_PHASE514, m_creature);
+ break;
+ case 37:
+ if(GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_SHKAF_GATE)))
+ pGate->SetGoState(GO_STATE_ACTIVE);
+ SetRun(true);
+ DoScriptText(SAY_PHASE515, m_creature);
+ break;
+ case 45:
+ DoScriptText(SAY_PHASE601, m_creature);
+ break;
+ case 48:
+ DoScriptText(SAY_PHASE602, m_creature);
+ break;
+ case 51:
+ SetEscortPaused(true);
+ m_pInstance->SetData(TYPE_PHASE, 9);
+ DoScriptText(SAY_PHASE606, m_creature);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ break;
+ case 53:
+ SetEscortPaused(true);
+ m_creature->StopMoving();
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->setFaction(FACTION);
+ DoScriptText(SAY_PHASE605, m_creature);
+ if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS)))
+ {
+ m_pInstance->SetData(TYPE_MALGANIS, IN_PROGRESS);
+ Malganis->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->AI()->AttackStart(Malganis);
+ Malganis->AI()->AttackStart(m_creature);
+ }
+ break;
+ }
+ }
+
+ void JumpNextStep(uint32 Timer)
+ {
+ m_uiStepTimer = Timer;
+ m_uiStep++;
+ }
+
+ void GetSoldier() //huck
+ {
+ //Marine Close Left
+ if(Creature* pEscort01 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f))
+ {
+ m_uiMarine01GUID = pEscort01->GetGUID();
+ pEscort01->UpdateEntry(NPC_CITYMAN);
+ if(Creature* pEscort02 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f))
+ {
+ m_uiMarine02GUID = pEscort02->GetGUID();
+ pEscort02->UpdateEntry(NPC_CITYMAN);
+ // Right marine 2
+ if(Creature* pEscort03 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f))
+ {
+ m_uiMarine03GUID = pEscort03->GetGUID();
+ pEscort03->UpdateEntry(NPC_CITYMAN);
+ if(Creature* pEscort04 = GetClosestCreatureWithEntry(m_creature, NPC_MARINE, 50.0f))
+ {
+ m_uiMarine04GUID = pEscort04->GetGUID();
+ pEscort01->UpdateEntry(NPC_MARINE);
+ pEscort02->UpdateEntry(NPC_MARINE);
+ pEscort03->UpdateEntry(NPC_MARINE);
+ }
+ }
+ }
+ }
+
+ if(Creature* pEscort05 = GetClosestCreatureWithEntry(m_creature, NPC_PRIEST, 50.0f))
+ {
+ m_uiPriest01GUID = pEscort05->GetGUID();
+ pEscort05->UpdateEntry(NPC_CITYMAN);
+ if(Creature* pEscort06 = GetClosestCreatureWithEntry(m_creature, NPC_PRIEST, 50.0f))
+ {
+ m_uiPriest02GUID = pEscort06->GetGUID();
+ pEscort05->UpdateEntry(NPC_PRIEST);
+ }
+ }
+ }
+
+ void ResetStep(uint32 Timer)
+ {
+ m_uiStep = 0;
+ m_uiStepTimer = Timer;
+ }
+
+ void IntroEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ DoScriptText(SAY_INTRO01, m_creature);
+ JumpNextStep(2000);
+ break;
+ case 1:
+ m_uiUtherGUID = m_pInstance->GetData64(NPC_UTHER);
+ m_uiJainaGUID = m_pInstance->GetData64(NPC_JAINA);
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ DoScriptText(SAY_INTRO02, pUther);
+ JumpNextStep(8000);
+ break;
+ case 2:
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ DoScriptText(SAY_INTRO03, m_creature);
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ m_creature->GetMotionMaster()->MovePoint(0, 1908.334f, 1315.354f, 149.551f);
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ pUther->GetMotionMaster()->MovePoint(0, 1903.600f, 1296.678f, 143.383f);
+ JumpNextStep(2000);
+ break;
+ case 3:
+ if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID))
+ pJaina->GetMotionMaster()->MovePoint(0, 1899.641f, 1298.684f, 143.831f);
+ JumpNextStep(7000);
+ break;
+ case 4:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 1911.087f, 1314.263f, 150.026f);
+ JumpNextStep(1000);
+ break;
+ case 5:
+ DoScriptText(SAY_INTRO04, m_creature);
+ JumpNextStep(10000);
+ break;
+ case 6:
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ DoScriptText(SAY_INTRO05, pUther);
+ JumpNextStep(1000);
+ break;
+ case 7:
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pUther->GetGUID());
+ DoScriptText(SAY_INTRO06, m_creature);
+ JumpNextStep(4000);
+ break;
+ case 8:
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ DoScriptText(SAY_INTRO07, pUther);
+ JumpNextStep(6000);
+ break;
+ case 9:
+ DoScriptText(SAY_INTRO08, m_creature);
+ JumpNextStep(4000);
+ break;
+ case 10:
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ DoScriptText(SAY_INTRO09, pUther);
+ JumpNextStep(8000);
+ break;
+ case 11:
+ DoScriptText(SAY_INTRO10, m_creature);
+ JumpNextStep(4000);
+ break;
+ case 12:
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ DoScriptText(SAY_INTRO11, pUther);
+ JumpNextStep(4000);
+ break;
+ case 13:
+ DoScriptText(SAY_INTRO12, m_creature);
+ JumpNextStep(11000);
+ break;
+ case 14:
+ if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID))
+ DoScriptText(SAY_INTRO13, pJaina);
+ JumpNextStep(3000);
+ break;
+ case 15:
+ DoScriptText(SAY_INTRO14, m_creature);
+ JumpNextStep(9000);
+ break;
+ case 16:
+ if(Creature* pUther = m_pInstance->instance->GetCreature(m_uiUtherGUID))
+ DoScriptText(SAY_INTRO15, pUther);
+ JumpNextStep(5000);
+ break;
+ case 17:
+ if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID))
+ {
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pJaina->GetGUID());
+ pJaina->GetMotionMaster()->MovePoint(0, 1794.357f,1272.183f,140.558f);
+ }
+ JumpNextStep(1000);
+ break;
+ case 18:
+ DoScriptText(SAY_INTRO16, m_creature);
+ JumpNextStep(1000);
+ break;
+ case 19:
+ if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID))
+ DoScriptText(SAY_INTRO17, pJaina);
+ JumpNextStep(3000);
+ break;
+ case 20:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ ((npc_arthasAI*)m_creature->AI())->Start(false);
+ JumpNextStep(3000);
+ break;
+ }
+ }
+
+ void EnterEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID))
+ DoScriptText(SAY_ENTER02, Cityman);
+ JumpNextStep(4000);
+ break;
+ case 1:
+ m_creature->GetMotionMaster()->MovePoint(0, 2087.689f,1280.344f,140.73f);
+ DoScriptText(SAY_ENTER03, m_creature);
+ JumpNextStep(3000);
+ break;
+ case 2:
+ if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID))
+ DoScriptText(SAY_ENTER04, Cityman);
+ m_creature->HandleEmoteCommand(37);
+ JumpNextStep(1000);
+ break;
+ case 3:
+ if(Unit* Cityman = m_creature->GetMap()->GetUnit( m_uiPeople01GUID))
+ m_creature->DealDamage(Cityman, Cityman->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ if(Unit* Crazyman = m_creature->GetMap()->GetUnit( m_uiPeople02GUID))
+ {
+ DoScriptText(SAY_ENTER05, Crazyman);
+ Crazyman->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Crazyman->GetGUID());
+ m_creature->GetMotionMaster()->MovePoint(0, 2092.154f,1276.645f,140.52f);
+ }
+ JumpNextStep(3000);
+ break;
+ case 4:
+ m_creature->HandleEmoteCommand(37);
+ JumpNextStep(1000);
+ break;
+ case 5:
+ if(Unit* Crazyman = m_creature->GetMap()->GetUnit( m_uiPeople02GUID))
+ Crazyman->DealDamage(Crazyman, Crazyman->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ JumpNextStep(1000);
+ break;
+ case 6:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ m_creature->GetMotionMaster()->MovePoint(0, 2091.179f,1278.065f,140.476f);
+ DoScriptText(SAY_ENTER06, m_creature);
+ JumpNextStep(3000);
+ break;
+ case 7:
+ if(Creature* StalkerM = m_creature->SummonCreature(20562,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,60000))
+ StalkerM->CastSpell(StalkerM,63793,false);
+ JumpNextStep(1000);
+ break;
+ case 8:
+ m_pInstance->SetData(TYPE_ENCOUNTER, IN_PROGRESS);
+ if(Creature* TempMalganis = m_creature->SummonCreature(NPC_MALGANIS_INTRO,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,29000))
+ {
+ m_uiMalganisGUID = TempMalganis->GetGUID();
+ DoScriptText(SAY_ENTER07, TempMalganis);
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, TempMalganis->GetGUID());
+ TempMalganis->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ TempMalganis->setFaction(35);
+ }
+ JumpNextStep(11000);
+ break;
+ case 9:
+ if(Unit* TempMalganis = m_creature->GetMap()->GetUnit( m_uiMalganisGUID))
+ DoScriptText(SAY_ENTER08, TempMalganis);
+ JumpNextStep(17000);
+ break;
+ case 10:
+ DoScriptText(SAY_ENTER09, m_creature);
+ JumpNextStep(7000);
+ break;
+ case 11:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ DoScriptText(SAY_ENTER10, m_creature);
+ JumpNextStep(12000);
+ break;
+ case 12:
+ m_creature->GetMotionMaster()->MovePoint(0, 2084.584f,1278.331f,141.479f);
+ JumpNextStep(4000);
+ break;
+ case 13:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 2087.414f,1279.293f,140.933f);
+ JumpNextStep(2000);
+ break;
+ case 14:
+ LastX = m_creature->GetPositionX();
+ LastY = m_creature->GetPositionY();
+ LastZ = m_creature->GetPositionZ();
+ if(m_bIsHeroic)
+ m_pInstance->SetData(TYPE_BONUS, IN_PROGRESS);
+ m_uiWaveCount = 0;
+ SetRun(true);
+ m_pInstance->SetData(TYPE_WING, RIGHT);
+ m_creature->setFaction(FACTION);
+ m_uiSummonTimer = 100;
+ m_pInstance->SetData(TYPE_PHASE, 3);
+ break;
+ }
+ }
+
+ void SummonWing()
+ {
+ m_uiWaveCount++;
+ m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_WAVE_COUNT, m_uiWaveCount);
+
+ switch(m_uiWaveCount)
+ {
+ case 1:
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 2:
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_FIEND,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 3:
+ m_pInstance->SetData(TYPE_WING, LEFT);
+ m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_FIEND,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 4:
+ m_pInstance->SetData(TYPE_WING, RIGHT);
+ m_creature->SummonCreature(NPC_ACOLYTE,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_ACOLYTE,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_FIEND,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 5:
+ m_pInstance->SetData(TYPE_PHASE, 4);
+ if(Creature* pMeathook = m_creature->SummonCreature(NPC_MEATHOOK,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000))
+ {
+ DoScriptText(SAY_MEATHOOK_SPAWN, pMeathook);
+ pMeathook->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pMeathook->GetMotionMaster()->MovePoint(0, 2196.036f, 1328.818f, 129.997f);
+ }
+ break;
+ case 6:
+ m_pInstance->SetData(TYPE_WING, LEFT);
+ m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_FIEND,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_FIEND,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 7:
+ m_pInstance->SetData(TYPE_WING, RIGHT);
+ m_creature->SummonCreature(NPC_CONSTRUCT,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 8:
+ m_pInstance->SetData(TYPE_WING, LEFT);
+ m_creature->SummonCreature(NPC_CONSTRUCT,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2272.773f, 1331.824f, 124.171f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 9:
+ m_pInstance->SetData(TYPE_WING, RIGHT);
+ m_creature->SummonCreature(NPC_CONSTRUCT,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_FIEND,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_NECROMANCER,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ m_creature->SummonCreature(NPC_GHOUL,2340.058f, 1253.570f, 132.733f, 5.09f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000);
+ break;
+ case 10:
+ m_pInstance->SetData(TYPE_PHASE, 4);
+ if(Creature* pSalramm = m_creature->SummonCreature(NPC_SALRAMM,2196.036f, 1328.818f, 129.997f, 3.12f,TEMPSUMMON_CORPSE_TIMED_DESPAWN,29000))
+ {
+ DoScriptText(SAY_SALRAMM_SPAWN, pSalramm);
+ pSalramm->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pSalramm->GetMotionMaster()->MovePoint(0, 2196.036f, 1328.818f, 129.997f);
+ }
+ break;
+ }
+ }
+
+ void HouseEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ if(Creature* Human = m_pInstance->instance->GetCreature(m_uiHuman01GUID))
+ {
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Human->GetGUID());
+ Human->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ DoScriptText(SAY_PHASE503, Human);
+ }
+ JumpNextStep(4000);
+ break;
+ case 1:
+ DoScriptText(SAY_PHASE504, m_creature);
+ m_creature->GetMotionMaster()->MovePoint(0, 2396.035f, 1206.942f, 134.038f);
+ JumpNextStep(3000);
+ break;
+ case 2:
+ m_creature->HandleEmoteCommand(37);
+ JumpNextStep(2000);
+ break;
+ case 3:
+ DoScriptText(SAY_PHASE505, m_creature);
+ JumpNextStep(2000);
+ break;
+ case 4:
+ if(Creature* Human = m_pInstance->instance->GetCreature(m_uiHuman01GUID))
+ DoScriptText(SAY_PHASE506, Human);
+ JumpNextStep(6000);
+ break;
+ case 5:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ if(Creature* Human = m_pInstance->instance->GetCreature(m_uiHuman01GUID))
+ {
+ Human->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ Human->UpdateEntry(NPC_INFINITE_ADVERSARY);
+ }
+ if(Creature* Human2 = m_pInstance->instance->GetCreature(m_uiHuman02GUID))
+ Human2->UpdateEntry(NPC_INFINITE_HUNTER);
+ if(Creature* Human3 = m_pInstance->instance->GetCreature(m_uiHuman03GUID))
+ Human3->UpdateEntry(NPC_INFINITE_AGENT);
+ JumpNextStep(1000);
+ break;
+ case 6:
+ SetRun(true);
+ m_creature->GetMotionMaster()->MovePoint(0, 2384.320f, 1202.779f, 134.040f);
+ DoScriptText(SAY_PHASE507, m_creature);
+ JumpNextStep(5000);
+ break;
+ case 7:
+ SetEscortPaused(false);
+ m_creature->setFaction(FACTION);
+ m_pInstance->SetData(TYPE_PHASE, 5);
+ JumpNextStep(1000);
+ break;
+ }
+ }
+
+ void EpochEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ m_creature->SummonCreature(NPC_TIME_RIFT_2,2445.629f,1111.500f,148.076f,3.229f,TEMPSUMMON_TIMED_DESPAWN,9000);
+ JumpNextStep(2000);
+ break;
+ case 1:
+ pEpoch = m_creature->SummonCreature(NPC_EPOCH,2445.629f,1111.500f,148.076f,3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000);
+ if(pEpoch)
+ {
+ pEpoch->setFaction(35);
+ DoScriptText(SAY_EPOCH_INTRO, pEpoch);
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pEpoch->GetGUID());
+ }
+ JumpNextStep(20000);
+ break;
+ case 2:
+ DoScriptText(SAY_ARTHAS_INTRO, m_creature);
+ JumpNextStep(6000);
+ break;
+ case 3:
+ if(pEpoch)
+ {
+ DoScriptText(SAY_EPOCH_AGGRO, pEpoch);
+ m_creature->AI()->AttackStart(pEpoch);
+ pEpoch->AI()->AttackStart(m_creature);
+ pEpoch->setFaction(14);
+ }
+ m_pInstance->SetData(TYPE_PHASE, 5);
+ SetRun(false);
+ JumpNextStep(6000);
+ break;
+ }
+ }
+
+ void MalganisEvent()
+ {
+ Map::PlayerList const &PlayerList = m_pInstance->instance->GetPlayers();
+ bool bNeedSpawn = false;
+
+ switch(m_uiStep)
+ {
+ case 0:
+ m_creature->setFaction(35);
+ m_creature->GetMotionMaster()->MovePoint(0, 2302.326f, 1491.386f, 128.362f);
+ if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS)))
+ {
+ DoScriptText(SAY_MALGANIS_ESCAPE01, Malganis);
+ Malganis->InterruptNonMeleeSpells(false);
+ Malganis->GetMotionMaster()->MovePoint(0, 2296.665f,1502.362f,128.362f);
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Malganis->GetGUID());
+ Malganis->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ }
+ JumpNextStep(10000);
+ break;
+ case 1:
+ if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS)))
+ DoScriptText(SAY_MALGANIS_ESCAPE02, Malganis);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ DoScriptText(SAY_ARTHAS_OUTRO01, m_creature);
+ JumpNextStep(5000);
+ break;
+ case 3:
+ if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS)))
+ DoScriptText(SAY_MALGANIS_OUTRO, Malganis);
+ JumpNextStep(20000);
+ break;
+ case 4:
+ if(Creature* Malganis = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALGANIS)))
+ {
+ Malganis->SetVisibility(VISIBILITY_OFF);
+ m_creature->GetMotionMaster()->MovePoint(0, Malganis->GetPositionX(), Malganis->GetPositionY(), Malganis->GetPositionZ());
+ }
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ JumpNextStep(3000);
+ break;
+ case 5:
+ DoScriptText(SAY_ARTHAS_OUTRO02, m_creature);
+ JumpNextStep(6000);
+ break;
+ case 6:
+ m_creature->GetMotionMaster()->MovePoint(0, 2298.298f,1500.362f,128.362f);
+ DoScriptText(SAY_ARTHAS_OUTRO03, m_creature);
+ JumpNextStep(11000);
+ break;
+ case 7:
+ m_creature->GetMotionMaster()->MovePoint(0, 2243.311f, 1476.025f, 132.352f);
+
+ if (!PlayerList.isEmpty())
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (i->getSource()->GetQuestStatus(QUEST_A_ROYAL_ESCORT) == QUEST_STATUS_INCOMPLETE ||
+ i->getSource()->GetQuestStatus(QUEST_A_ROYAL_ESCORT) == QUEST_STATUS_COMPLETE)
{
- pPlayer->SendNewItem(pItem, 1, true, false);
- if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData())
- {
- if (pInstance->GetData(TYPE_GRAIN_EVENT) == NOT_STARTED)
- pInstance->SetData(TYPE_GRAIN_EVENT, SPECIAL);
- }
+ bNeedSpawn = true;
+ break;
}
- }
- break;
+
+ if (bNeedSpawn)
+ m_creature->SummonCreature(30997, 2311.61f, 1497.85f, 128.01f, 4.14f, TEMPSUMMON_TIMED_DESPAWN, 1800000);
+ JumpNextStep(11000);
+ break;
+ case 8:
+ m_pInstance->SetData(TYPE_PHASE, 12);
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if(!m_pInstance) return;
+
+ if(StartEvent == true)
+ {
+ if(m_pInstance->GetData(TYPE_INTRO) != DONE)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ IntroEvent();
}
- break;
- case NPC_CHROMIE_ENTRANCE:
- switch (uiAction)
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 2)
+ {
+ if(m_uiStepTimer < uiDiff)
{
- case GOSSIP_ACTION_INFO_DEF+1:
- pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ENTRANCE_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_2, pCreature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ENTRANCE_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_3, pCreature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_ENTRANCE_4, pCreature->GetGUID());
- if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData())
- {
- if (pInstance->GetData(TYPE_ARTHAS_INTRO_EVENT) == NOT_STARTED)
- pInstance->DoSpawnArthasIfNeeded();
- }
- break;
+ EnterEvent();
}
- break;
- }
- return true;
-}
+ else m_uiStepTimer -= uiDiff;
+ }
-bool QuestAccept_npc_chromie(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
-{
- switch (pQuest->GetQuestId())
- {
- case QUEST_DISPELLING_ILLUSIONS:
- if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData())
+ if(MoveSoldier == true)
+ {
+ if(m_uiMoveTimer < uiDiff)
+ {
+ MoveSoldiers();
+ MoveSoldier = false;
+ }
+ else m_uiMoveTimer -= uiDiff;
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 3)
+ {
+ if(m_uiSummonTimer < uiDiff)
+ {
+ SummonWing();
+ m_uiSummonTimer = 70000;
+ }
+ else m_uiSummonTimer -= uiDiff;
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 4 && m_pInstance->GetData(TYPE_ENCOUNTER) == DONE)
+ {
+ m_pInstance->SetData(TYPE_PHASE, 5);
+ SetRun(true);
+ EnableEscort();
+ DoScriptText(SAY_PHASE501, m_creature);
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 6)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ HouseEvent();
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 7)
+ {
+ if(m_uiStepTimer < uiDiff)
{
- if (pInstance->GetData(TYPE_GRAIN_EVENT) == NOT_STARTED)
- pInstance->SetData(TYPE_GRAIN_EVENT, SPECIAL);
+ EpochEvent();
}
- break;
- case QUEST_A_ROYAL_ESCORT:
- if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pCreature->GetInstanceData())
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ } //close event!
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 10)
+ {
+ SetEscortPaused(true);
+ ResetStep(1000);
+ m_creature->AttackStop();
+ m_pInstance->SetData(TYPE_PHASE, 11);
+ }
+
+ if(m_pInstance->GetData(TYPE_PHASE) == 11)
+ {
+ if(m_uiStepTimer < uiDiff)
{
- if (pInstance->GetData(TYPE_ARTHAS_INTRO_EVENT) == NOT_STARTED)
- pInstance->DoSpawnArthasIfNeeded();
+ MalganisEvent();
}
- break;
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ //} //close event!
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_pInstance->GetData(TYPE_PHASE) > 9) return;
+
+ if (m_uiExorcismTimer < uiDiff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsHeroic ? SPELL_EXORCISM_H : SPELL_EXORCISM_N);
+
+ m_uiExorcismTimer = 7300;
+ }else m_uiExorcismTimer -= uiDiff;
+
+ if (m_uiHealTimer < uiDiff)
+ {
+ if(m_creature->GetHealthPercent() < 40.0f)
+ {
+ DoCast(m_creature, SPELL_HOLY_LIGHT);
+ m_uiHealTimer = 20000;
+ }
+ } else m_uiHealTimer -= uiDiff;
+
+ return;
}
+};
+
+/*###
+## npc_uther
+###*/
+
+struct MANGOS_DLL_DECL npc_utherAI : public npc_escortAI
+{
+ npc_utherAI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint64 m_uiArthasGUID;
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ bool StartEvent;
+
+ uint64 m_uiKnightGUID01;
+ uint64 m_uiKnightGUID02;
+ uint64 m_uiKnightGUID03;
+
+ void Reset()
+ {
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ }
+
+ void StartAI()
+ {
+ //m_pInstance->SetWeather(WEATHER_STATE_MEDIUM_RAIN, 0.9999f);
+ StartEvent = true;
+ m_creature->SetVisibility(VISIBILITY_ON);
+ ((npc_utherAI*)m_creature->AI())->Start(true);
+
+ if(Creature* Knight01 = m_creature->SummonCreature(NPC_KNIGHT,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,110000))
+ {
+ m_uiKnightGUID01 = Knight01->GetGUID();
+ Knight01->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ Knight01->GetMotionMaster()->MoveFollow(m_creature,PET_FOLLOW_DIST,M_PI_F/2);
+ }
+
+ if(Creature* Knight02 = m_creature->SummonCreature(NPC_KNIGHT,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,110000))
+ {
+ m_uiKnightGUID02 = Knight02->GetGUID();
+ Knight02->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ Knight02->GetMotionMaster()->MoveFollow(m_creature,PET_FOLLOW_DIST,M_PI_F/4);
+ }
+
+ if(Creature* Knight03 = m_creature->SummonCreature(NPC_KNIGHT,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,110000))
+ {
+ m_uiKnightGUID03 = Knight03->GetGUID();
+ Knight03->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ Knight03->GetMotionMaster()->MoveFollow(m_creature,PET_FOLLOW_DIST,M_PI_F/3);
+ }
+ }
+
+ void WaypointReached(uint32 uiPointId)
+ {
+ switch(uiPointId)
+ {
+ case 3:
+ m_uiArthasGUID = m_pInstance->GetData64(NPC_ARTHAS);
+ if(Creature* pArthas = m_pInstance->instance->GetCreature(m_uiArthasGUID))
+ {
+ pArthas->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pArthas->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ pArthas->GetMotionMaster()->MovePoint(0, 1902.974f, 1291.635f, 143.337f);
+ }
+ break;
+ case 4:
+ SetRun(false);
+ if(Creature *pArthas = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ARTHAS)))
+ ((npc_arthasAI*)pArthas->AI())->StartAI();
+ break;
+ case 6:
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ uint64 m_uiJainaGUID = m_pInstance->GetData64(NPC_JAINA);
+ if(Creature* pJaina = m_pInstance->instance->GetCreature(m_uiJainaGUID))
+ pJaina->SetVisibility(VISIBILITY_OFF);
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if(!m_pInstance) return;
+
+ return;
+ }
+};
+
+/*###
+## npc_chromi_middle
+###*/
+
+#define GOSSIP_ITEM_CHROMI1 "What do you think they're up to?"
+#define GOSSIP_ITEM_CHROMI2 "What want me to do what?"
+#define GOSSIP_ITEM_CHROMI3 "Very well, Chromie."
+
+enum
+{
+ QUEST_ROYAL_ESCORT = 13151,
+ GOSSIP_TEXTID_CHROMI1 = 12953,
+ GOSSIP_TEXTID_CHROMI2 = 12949,
+ GOSSIP_TEXTID_CHROMI3 = 12950,
+ GOSSIP_TEXTID_CHROMI4 = 12952
+};
+
+bool GossipHello_npc_chromi_middle(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ //if (pPlayer->GetQuestStatus(QUEST_ROYAL_ESCORT) == QUEST_STATUS_INCOMPLETE) return true;
+
+ ScriptedInstance* pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ if(pInstance && pInstance->GetData(TYPE_INTRO) == NOT_STARTED)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI1, pCreature->GetGUID());
+
return true;
}
-/* *************
-** npc_crates_bunny (spell aura effect dummy)
-************* */
+bool GossipSelect_npc_chromi_middle(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ if(ScriptedInstance* m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()))
+ if(m_pInstance->GetData(TYPE_INTRO) != NOT_STARTED) return true;
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI2, pCreature->GetGUID());
+ }
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI3, pCreature->GetGUID());
+ }
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+3)
+ {
+ if(ScriptedInstance* m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()))
+ {
+ m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 0);
+ m_pInstance->SetData(TYPE_INTRO, IN_PROGRESS);
+ if (Creature *pUther = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_UTHER)))
+ ((npc_utherAI*)pUther->AI())->StartAI();
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI4, pCreature->GetGUID());
+ }
+
+ return true;
+}
+
+struct MANGOS_DLL_DECL npc_chromi_middleAI : public ScriptedAI
+{
+ npc_chromi_middleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ m_bUtherHere = false;
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bUtherHere;
+
+ void Reset()
+ {
+ m_bUtherHere = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_bUtherHere && m_pInstance && pWho && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(pWho) <= 15 && ((Player*)pWho)->GetQuestStatus(QUEST_A_ROYAL_ESCORT) == QUEST_STATUS_INCOMPLETE)
+ {
+ m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 0);
+ m_pInstance->SetData(TYPE_INTRO, IN_PROGRESS);
+ if (Creature *pUther = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_UTHER)))
+ ((npc_utherAI*)pUther->AI())->StartAI();
+ m_bUtherHere = true;
+ }
+ }
+};
+
+/*###
+## npc_arthas_dialog
+###*/
+
+enum
+{
+ GOSSIP_MENU_ARTHAS_1 = 100001,
+ GOSSIP_MENU_ARTHAS_2 = 100002,
+ GOSSIP_MENU_ARTHAS_3 = 100003,
+ GOSSIP_MENU_ARTHAS_4 = 100004,
+ GOSSIP_MENU_ARTHAS_5 = 100005
+};
+
+#define GOSSIP_ITEM_ARTHAS_0 "I'm ready to start Culling of Stratholme."
+#define GOSSIP_ITEM_ARTHAS_1 "Yes, my Prince. We're ready."
+#define GOSSIP_ITEM_ARTHAS_2 "We're only doing what is best for Loarderon your Highness."
+#define GOSSIP_ITEM_ARTHAS_3 "I'm ready."
+#define GOSSIP_ITEM_ARTHAS_4 "For Lordaeron!"
+#define GOSSIP_ITEM_ARTHAS_5 "I'm ready to battle the dreadlord, sire."
+
+bool GossipHello_npc_arthas(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance* pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+
+ if(pInstance && pInstance->GetData(TYPE_PHASE) == 0)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_1, pCreature->GetGUID());
+ }
+
+ if(pInstance && pInstance->GetData(TYPE_PHASE) == 5)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_2, pCreature->GetGUID());
+ }
+
+ if(pInstance && pInstance->GetData(TYPE_PHASE) == 8)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_3, pCreature->GetGUID());
+ }
+
+ if(pInstance && pInstance->GetData(TYPE_PHASE) == 9)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_4, pCreature->GetGUID());
+ }
+
+ return true;
+}
+
+bool GossipSelect_npc_arthas(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance* m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 0)
+ {
+ m_pInstance->SetData(TYPE_PHASE, 1);
+ ((npc_arthasAI*)pCreature->AI())->EnableEscort();
+ ((npc_arthasAI*)pCreature->AI())->RemoveGossip();
+ ((npc_arthasAI*)pCreature->AI())->culling_faction = pPlayer->getFaction();
+ }
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 5)
+ {
+ ((npc_arthasAI*)pCreature->AI())->EnableEscort();
+ ((npc_arthasAI*)pCreature->AI())->RemoveGossip();
+ }
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 8)
+ {
+ ((npc_arthasAI*)pCreature->AI())->EnableEscort();
+ ((npc_arthasAI*)pCreature->AI())->RemoveGossip();
+ }
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_PHASE) == 9)
+ {
+ ((npc_arthasAI*)pCreature->AI())->EnableEscort();
+ ((npc_arthasAI*)pCreature->AI())->RemoveGossip();
+ if(Creature* pMalganis = pCreature->SummonCreature(NPC_MALGANIS,2296.665f,1502.362f,128.362f,4.961f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000))
+ {
+ m_pInstance->SetData64(NPC_MALGANIS, pMalganis->GetGUID());
+ pMalganis->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ }
+
+ return true;
+}
+
+/*###
+## npc_arthas_priest
+###*/
enum
{
- SPELL_ARCANE_DISRUPTION = 49590
+ SPELL_SMITE = 61923,
+ SPELL_HEAL = 62442
};
-bool EffectAuraDummy_spell_aura_dummy_npc_crates_dummy(const Aura* pAura, bool bApply)
+struct MANGOS_DLL_DECL npc_arthas_priestAI : public ScriptedAI
{
- if (pAura->GetId() == SPELL_ARCANE_DISRUPTION && pAura->GetEffIndex() == EFFECT_INDEX_0 && bApply)
+ npc_arthas_priestAI(Creature *c) : ScriptedAI(c)
+ {
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ uint32 m_uiSmiteTimer;
+ uint32 m_uiHealTimer;
+
+ void Reset()
+ {
+ m_uiSmiteTimer = 100;
+ m_uiHealTimer = 1000;
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+
+ m_creature->SetLootRecipient(NULL);
+
+ Reset();
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
{
- if (Creature* pTarget = (Creature*)pAura->GetTarget())
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
{
- std::list lCrateBunnyList;
- if (instance_culling_of_stratholme* pInstance = (instance_culling_of_stratholme*)pTarget->GetInstanceData())
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
{
- pInstance->GetCratesBunnyOrderedList(lCrateBunnyList);
- uint8 i = 0;
- for (std::list::const_iterator itr = lCrateBunnyList.begin(); itr != lCrateBunnyList.end(); ++itr)
+ if (!m_creature->getVictim())
{
- i++;
- if (*itr == pTarget)
- break;
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
}
-
- switch (i)
+ else if (m_creature->GetMap()->IsDungeon())
{
- case 1:
- // Start NPC_ROGER_OWENS Event
- break;
- case 2:
- // Start NPC_SERGEANT_MORIGAN Event
- break;
- case 3:
- // Start NPC_JENA_ANDERSON Event
- break;
- case 4:
- // Start NPC_MALCOM_MOORE Event
- break;
- case 5:
- // Start NPC_BARTLEBY_BATTSON Event
- break;
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
}
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
- if (pInstance->GetData(TYPE_GRAIN_EVENT) != DONE)
- pInstance->SetData(TYPE_GRAIN_EVENT, IN_PROGRESS);
- // pTarget->ForcedDespawn(); // direct despawn has influence on visual effects,
- // but despawning makes it impossible to multi-use the spell at the same place
- // perhaps some add. GO-Visual
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiSmiteTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_SMITE);
+ m_uiSmiteTimer = 3000;
+ }
+ else m_uiSmiteTimer -= uiDiff;
+
+ if(m_uiHealTimer < uiDiff)
+ {
+ if(m_creature->GetHealthPercent() <= 40.0f)
+ {
+ m_creature->InterruptNonMeleeSpells(false);
+ DoCast(m_creature, SPELL_HEAL);
+ m_uiHealTimer = 3000;
+ }
+ }
+ else m_uiHealTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+/*###
+## npc_arthas_marine
+###*/
+
+struct MANGOS_DLL_DECL npc_arthas_marineAI : public ScriptedAI
+{
+ npc_arthas_marineAI(Creature *c) : ScriptedAI(c)
+ {
+ Reset();
+ }
+
+ float LastX;
+ float LastY;
+ float LastZ;
+
+ uint32 m_uiHealTimer;
+
+ void Reset()
+ {
+ m_uiHealTimer = 3000;
+ }
+
+ void Aggro(Unit* who)
+ {
+ LastX = m_creature->GetPositionX();
+ LastY = m_creature->GetPositionY();
+ LastZ = m_creature->GetPositionZ();
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+
+ if (IsCombatMovement())
+ m_creature->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+
+ m_creature->SetLootRecipient(NULL);
+ m_creature->GetMotionMaster()->MovePoint(POINT_LAST_POINT, LastX, LastY, LastZ);
+
+ Reset();
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
}
}
}
- return true;
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiHealTimer < uiDiff)
+ {
+ if(m_creature->GetHealthPercent() <= 40.0f)
+ {
+ if(Creature* pHeal = GetClosestCreatureWithEntry(m_creature, NPC_PRIEST, 50.0f))
+ {
+ if(pHeal->GetHealthPercent() > 40.0f)
+ {
+ pHeal->InterruptNonMeleeSpells(false);
+ pHeal->CastSpell(m_creature, SPELL_HEAL, false);
+ m_uiHealTimer = 3000;
+ }
+ }
+ }
+ }
+ else m_uiHealTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+/*###
+## npc_dark_conversion
+###*/
+
+/*enum
+{
+ SAY_PEOPLE01 = -1594099,
+ SAY_PEOPLE02 = -1594100,
+ SAY_PEOPLE03 = -1594101,
+ SAY_PEOPLE04 = -1594102,
+ SAY_PEOPLE05 = -1594103,
+};*/
+
+struct MANGOS_DLL_DECL npc_dark_conversionAI : public ScriptedAI
+{
+ npc_dark_conversionAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+
+ if (m_pInstance && m_pInstance->GetData(TYPE_ENCOUNTER) == IN_PROGRESS)
+ m_creature->UpdateEntry(NPC_ZOMBIE);
+
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+
+bool Special;
+bool Conversion;
+uint32 m_uiStep;
+uint32 m_uiStepTimer;
+
+ void Reset()
+ {
+ m_creature->setFaction(35);
+ Conversion = false;
+ Special = false;
+ m_uiStep = 1;
+ m_uiStepTimer = 5000;
+
+ if (m_pInstance && m_pInstance->GetData(TYPE_ENCOUNTER) == IN_PROGRESS)
+ m_creature->UpdateEntry(NPC_ZOMBIE);
+ }
+
+ void MalganisScared(Creature* target, float horizontalSpeed, float verticalSpeed)
+ {
+ float angle = target->GetAngle(m_creature);
+ float vsin = sin(angle);
+ float vcos = cos(angle);
+
+ float ox, oy, oz;
+ m_creature->GetPosition(ox, oy, oz);
+
+ float g = 19.23f;// seems that physic constant g(earth's gravity) in world of warcraft is about 2 times larger than real
+ float dh = verticalSpeed*verticalSpeed / (2*g); // maximum parabola height
+ float time = sqrtf(dh/(0.124976 * verticalSpeed)); //full move time in seconds // should be time = 2*Vert_speed/g, but..
+
+ float dis = time * horizontalSpeed;
+ float fx = ox + dis * vcos;
+ float fy = oy + dis * vsin;
+ float fz = oz;
+
+ m_creature->UpdateGroundPositionZ(fx, fy, fz);
+
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MovePoint(0, fx, fy, fz);
+ }
+
+ void DarkConversion(bool Move)
+ {
+ m_creature->UpdateEntry(NPC_ZOMBIE);
+ if(Move == true)
+ {
+ uint64 m_uiArthasGUID = m_pInstance->GetData64(NPC_ARTHAS);
+ if(Creature* pArthas = m_pInstance->instance->GetCreature(m_uiArthasGUID))
+ m_creature->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ());
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(!m_pInstance) return;
+
+ if(m_pInstance->GetData(TYPE_ENCOUNTER) == IN_PROGRESS)
+ {
+ if(Creature* pMalganis = GetClosestCreatureWithEntry(m_creature, NPC_MALGANIS_INTRO, 20.0f))
+ {
+ if(Special == false)
+ {
+ float Dist = m_creature->GetDistance2d(pMalganis->GetPositionX(), pMalganis->GetPositionY());
+ Dist = Dist + 2.0f;
+ MalganisScared(pMalganis, Dist, 1.0f);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER);
+ m_uiStepTimer = 5000;
+ Special = true;
+ }
+ }
+
+ if(m_uiStepTimer < uiDiff && Conversion != true)
+ {
+ Conversion = true;
+ if(Special != false)
+ DarkConversion(true);
+ else
+ DarkConversion(false);
+ }
+ else m_uiStepTimer -= uiDiff;
+
+ }
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_chromi_middle(Creature* pCreature)
+{
+ return new npc_chromi_middleAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_uther(Creature* pCreature)
+{
+ return new npc_utherAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_arthas(Creature* pCreature)
+{
+ return new npc_arthasAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_arthas_priest(Creature* pCreature)
+{
+ return new npc_arthas_priestAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_arthas_marine(Creature* pCreature)
+{
+ return new npc_arthas_marineAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_dark_conversion(Creature* pCreature)
+{
+ return new npc_dark_conversionAI(pCreature);
}
void AddSC_culling_of_stratholme()
{
- Script* pNewScript;
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_chromi_middle";
+ newscript->pGossipHello = &GossipHello_npc_chromi_middle;
+ newscript->pGossipSelect = &GossipSelect_npc_chromi_middle;
+ newscript->GetAI = &GetAI_npc_chromi_middle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_uther";
+ newscript->GetAI = &GetAI_npc_uther;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_arthas";
+ newscript->GetAI = &GetAI_npc_arthas;
+ newscript->pGossipHello = &GossipHello_npc_arthas;
+ newscript->pGossipSelect = &GossipSelect_npc_arthas;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_arthas_priest";
+ newscript->GetAI = &GetAI_npc_arthas_priest;
+ newscript->RegisterSelf();
- pNewScript = new Script;
- pNewScript->Name = "npc_chromie";
- pNewScript->pGossipHello = &GossipHello_npc_chromie;
- pNewScript->pGossipSelect = &GossipSelect_npc_chromie;
- pNewScript->pQuestAccept = &QuestAccept_npc_chromie;
- pNewScript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "npc_arthas_marine";
+ newscript->GetAI = &GetAI_npc_arthas_marine;
+ newscript->RegisterSelf();
- pNewScript = new Script;
- pNewScript->Name = "spell_dummy_npc_crates_bunny";
- pNewScript->pEffectAuraDummy = &EffectAuraDummy_spell_aura_dummy_npc_crates_dummy;
- pNewScript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "npc_dark_conversion";
+ newscript->GetAI = &GetAI_npc_dark_conversion;
+ newscript->RegisterSelf();
}
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholmeai.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholmeai.cpp
new file mode 100644
index 0000000..3778873
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholmeai.cpp
@@ -0,0 +1,1293 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+#include "escort_ai.h"
+#include "WorldPacket.h"
+
+/*###
+## npc_chromi_start
+###*/
+
+#define GOSSIP_ITEM_CHROMI1 "Why have I been sent back to this particular place and time?"
+#define GOSSIP_ITEM_CHROMI2 "What was this decision?"
+#define GOSSIP_ITEM_CHROMI3 "So how does the infinite Dragonflight plan to Interfere?"
+
+enum
+{
+ GOSSIP_TEXTID_CHROMI1 = 12939,
+ GOSSIP_TEXTID_CHROMI2 = 12949,
+ GOSSIP_TEXTID_CHROMI3 = 12950,
+ GOSSIP_TEXTID_CHROMI4 = 12952
+};
+
+bool GossipHello_npc_chromi_start(Player* pPlayer, Creature* pCreature)
+{
+ if(pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ ScriptedInstance* pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ if (pPlayer && pPlayer->GetQuestStatus(QUEST_DISPELLING_ILLUSIONS) == QUEST_STATUS_COMPLETE && pInstance && pInstance->GetData(TYPE_QUEST) == NOT_STARTED)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI1, pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_chromi_start(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI2, pCreature->GetGUID());
+ }
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHROMI3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI3, pCreature->GetGUID());
+ }
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+3)
+ {
+ // START COUNTER HERE
+ if (ScriptedInstance* pInstance = (ScriptedInstance*)pCreature->GetInstanceData())
+ {
+ pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 1);
+ pInstance->SetData(TYPE_QUEST, IN_PROGRESS);
+ }
+
+ if (pPlayer)
+ if (Item* pItem = pPlayer->StoreNewItemInInventorySlot(ITEM_ARCANE_DISRUPTOR, 1))
+ pPlayer->SendNewItem(pItem, 1, true, false);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_CHROMI4, pCreature->GetGUID());
+ }
+
+ return true;
+}
+
+struct MANGOS_DLL_DECL npc_chromi_startAI : public ScriptedAI
+{
+ npc_chromi_startAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ m_bCounterHere = false;
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bCounterHere;
+
+ void Reset()
+ {
+ m_bCounterHere = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_bCounterHere && m_pInstance && pWho && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(pWho) <= 15 && ((Player*)pWho)->GetQuestStatus(QUEST_DISPELLING_ILLUSIONS) == QUEST_STATUS_INCOMPLETE)
+ {
+ m_pInstance->DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 1);
+ m_pInstance->SetData(TYPE_QUEST, IN_PROGRESS);
+ m_bCounterHere = true;
+ }
+ }
+};
+
+/*###
+## npc_mike
+###*/
+
+enum
+{
+ SAY_MIKE01 = -1557270,
+ SAY_FORRESTER02 = -1557271,
+ SAY_JAMES03 = -1557272,
+ SAY_SIABI04 = -1557273,
+ SAY_MIKE05 = -1557274,
+ SAY_CORICKS06 = -1557275,
+ SAY_GRIAN07 = -1557276,
+ SAY_CORICKS08 = -1557277,
+ SAY_JAMES09 = -1557278,
+ SAY_FORRESTER10 = -1557279,
+
+ EMOTE_SHOT = 5,
+ EMOTE_TALK = 1,
+ EMOTE_POINT = 25,
+ EMOTE_NO = 274,
+ EMOTE_LAUGH = 11
+};
+
+struct MANGOS_DLL_DECL npc_mikeAI : public ScriptedAI
+{
+ npc_mikeAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ uint32 m_uiPhase;
+
+ uint64 m_uiForesterGUID;
+ uint64 m_uiJamesGUID;
+ uint64 m_uiSiabiGUID;
+ uint64 m_uiCorricksGUID;
+ uint64 m_uiGryanGUID;
+
+ void Reset()
+ {
+ if(m_uiPhase != 2)
+ {
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ m_uiPhase = 0;
+ }
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if(!m_pInstance) return;
+
+ if (who->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(who) <= 15 && who->GetPositionZ() > 99.50f && m_uiPhase == 0)
+ {
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, who->GetGUID());
+ m_uiPhase = 1;
+ }
+ }
+
+ void TavernEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ DoScriptText(SAY_MIKE01, m_creature);
+ m_uiStepTimer = 4000;
+ break;
+ case 1:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ m_uiStepTimer = 5000;
+ break;
+ case 2:
+ m_uiForesterGUID = m_pInstance->GetData64(NPC_FORRESTER);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiForesterGUID))
+ DoScriptText(SAY_FORRESTER02, pTemp);
+ m_uiStepTimer = 6000;
+ break;
+ case 3:
+ m_uiJamesGUID = m_pInstance->GetData64(NPC_JAMES);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiJamesGUID))
+ DoScriptText(SAY_JAMES03, pTemp);
+ m_uiStepTimer = 5000;
+ break;
+ case 4:
+ m_uiSiabiGUID = m_pInstance->GetData64(NPC_FRAS_FRASIABI);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiSiabiGUID))
+ DoScriptText(SAY_SIABI04, pTemp);
+ m_uiStepTimer = 2000;
+ break;
+ case 5:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiSiabiGUID))
+ pTemp->HandleEmoteCommand(EMOTE_SHOT);
+ m_uiStepTimer = 5000;
+ break;
+ case 6:
+ m_creature->GetMotionMaster()->MovePoint(0, 1554.849f, 588.465f, 99.775f);
+ m_uiStepTimer = 3000;
+ break;
+ case 7:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiSiabiGUID))
+ pTemp->HandleEmoteCommand(EMOTE_LAUGH);
+ m_uiStepTimer = 3000;
+ break;
+ case 8:
+ DoScriptText(SAY_MIKE05, m_creature);
+ m_uiStepTimer = 2000;
+ break;
+ case 9:
+ m_creature->HandleEmoteCommand(EMOTE_SHOT);
+ m_uiStepTimer = 1000;
+ break;
+ case 10:
+ m_uiCorricksGUID = m_pInstance->GetData64(NPC_MAL_CORICS);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiCorricksGUID))
+ DoScriptText(SAY_CORICKS06, pTemp);
+ m_uiStepTimer = 4000;
+ break;
+ case 11:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiCorricksGUID))
+ pTemp->HandleEmoteCommand(EMOTE_TALK);
+ m_uiGryanGUID = m_pInstance->GetData64(NPC_GRIAN_STONE);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiGryanGUID))
+ DoScriptText(SAY_GRIAN07, pTemp);
+ m_uiStepTimer = 11000;
+ break;
+ case 12:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiCorricksGUID))
+ DoScriptText(SAY_CORICKS08, pTemp);
+ m_creature->GetMotionMaster()->MovePoint(0, 1549.609f, 575.544f, 100.052f);
+ m_uiStepTimer = 2000;
+ break;
+ case 13:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiJamesGUID))
+ DoScriptText(SAY_JAMES09, pTemp);
+ m_uiStepTimer = 2000;
+ break;
+ case 14:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiJamesGUID))
+ pTemp->HandleEmoteCommand(EMOTE_TALK);
+ m_uiStepTimer = 5000;
+ break;
+ case 15:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiForesterGUID))
+ DoScriptText(SAY_FORRESTER10, pTemp);
+ m_uiPhase = 2;
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiPhase == 1)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ TavernEvent();
+ m_uiStep++;
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ return;
+ }
+};
+
+/*###
+## npc_roger
+###*/
+
+enum
+{
+ SAY_ROGER01 = -1557280,
+ SAY_ROGER02 = -1557281,
+ SAY_ROGER03 = -1557282,
+ SAY_ROGER04 = -1557283,
+};
+
+struct MANGOS_DLL_DECL npc_rogerAI : public ScriptedAI
+{
+ npc_rogerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ uint32 m_uiPhase;
+
+ void Reset()
+ {
+ if(m_uiPhase != 2)
+ {
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ m_uiPhase = 0;
+ }
+ }
+
+ void StartRoger()
+ {
+ m_uiPhase = 1;
+ }
+
+ void FirstCrateEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_uiStepTimer = 7000;
+ break;
+ case 1:
+ MoveToPoint(m_creature, 1590.055f, 615.727f, 99.795f, 7000);
+ m_uiStepTimer = 6900;
+ break;
+ case 2:
+ MoveToPoint(m_creature, 1584.039f, 622.049f, 99.907f, 4000);
+ m_uiStepTimer = 3900;
+ break;
+ case 3:
+ MoveToPoint(m_creature, 1578.787f, 623.924f, 99.855f, 2000);
+ m_uiStepTimer = 2500;
+ break;
+ case 4:
+ DoScriptText(SAY_ROGER01, m_creature);
+ m_uiStepTimer = 6000;
+ break;
+ case 5:
+ MoveToPoint(m_creature, 1579.393f, 624.018f, 99.886f, 900);
+ m_uiStepTimer = 2000;
+ break;
+ case 6:
+ DoScriptText(SAY_ROGER02, m_creature);
+ m_uiStepTimer = 6000;
+ break;
+ case 7:
+ MoveToPoint(m_creature, 1579.387f, 623.198f, 99.837f, 300);
+ m_uiStepTimer = 1000;
+ break;
+ case 8:
+ DoScriptText(SAY_ROGER03, m_creature);
+ m_uiStepTimer = 4000;
+ break;
+ case 9:
+ MoveToPoint(m_creature, 1575.576f, 619.935f, 99.422f, 1500);
+ m_uiStepTimer = 2000;
+ break;
+ case 10:
+ MoveToPoint(m_creature, 1575.833f, 620.471f, 99.466f, 300);
+ m_uiStepTimer = 1000;
+ break;
+ case 11:
+ DoScriptText(SAY_ROGER04, m_creature);
+ m_uiStepTimer = 6000;
+ break;
+ case 12:
+ MoveToPoint(m_creature, 1580.215f, 624.368f, 99.924f, 2000);
+ m_uiStepTimer = 1900;
+ break;
+ case 13:
+ MoveToPoint(m_creature, 1587.471f, 618.181f, 99.850f, 4000);
+ m_uiStepTimer = 3900;
+ break;
+ case 14:
+ MoveToPoint(m_creature, 1592.646f, 590.888f, 99.151f, 11000);
+ m_uiStepTimer = 13000;
+ break;
+ case 15:
+ m_uiPhase = 2;
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ break;
+ }
+ }
+
+ void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer)
+ {
+ unit->GetMotionMaster()->MovementExpired(false);
+ unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation());
+ unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiPhase == 1)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ FirstCrateEvent();
+ m_uiStep++;
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ return;
+ }
+};
+
+/*###
+## npc_morigan
+###*/
+
+enum
+{
+ SAY_MORIGAN01 = -1557284,
+ SAY_PERELLI02 = -1557285,
+ SAY_MORIGAN03 = -1557286,
+ SAY_PERELLI04 = -1557287,
+ SAY_MORIGAN05 = -1557288,
+ SAY_PERELLI06 = -1557289,
+ SAY_MORIGAN07 = -1557290,
+};
+
+struct MANGOS_DLL_DECL npc_moriganAI : public ScriptedAI
+{
+ npc_moriganAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint64 m_uiPerelliGUID;
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ uint32 m_uiPhase;
+
+ void Reset()
+ {
+ if(m_uiPhase != 2)
+ {
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ m_uiPhase = 0;
+ }
+ }
+
+ void StartMorigan()
+ {
+ m_uiPhase = 1;
+ }
+
+ void SecondCrateEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ DoScriptText(SAY_MORIGAN01, m_creature);
+ m_uiStepTimer = 6000;
+ break;
+ case 1:
+ m_uiPerelliGUID = m_pInstance->GetData64(NPC_PERELLI);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID))
+ DoScriptText(SAY_PERELLI02, pTemp);
+ m_uiStepTimer = 2000;
+ break;
+ case 2:
+ m_creature->GetMotionMaster()->MovePoint(0, 1564.138f, 668.343f, 102.058f);
+ m_uiStepTimer = 2000;
+ break;
+ case 3:
+ m_creature->GetMotionMaster()->MovePoint(0, 1567.956f, 667.776f, 102.094f);
+ m_uiStepTimer = 1500;
+ break;
+ case 4:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 1569.615f, 668.859f, 102.180f);
+ m_uiStepTimer = 2000;
+ break;
+ case 5:
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ m_uiStepTimer = 1000;
+ break;
+ case 6:
+ DoScriptText(SAY_MORIGAN03, m_creature);
+ m_uiStepTimer = 3000;
+ break;
+ case 7:
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID))
+ {
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID());
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ }
+ m_uiStepTimer = 3000;
+ break;
+ case 8:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID))
+ DoScriptText(SAY_PERELLI04, pTemp);
+ m_uiStepTimer = 3000;
+ break;
+ case 9:
+ DoScriptText(SAY_MORIGAN05, m_creature);
+ m_uiStepTimer = 9000;
+ break;
+ case 10:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID))
+ DoScriptText(SAY_PERELLI06, pTemp);
+ m_uiStepTimer = 6000;
+ break;
+ case 11:
+ DoScriptText(SAY_MORIGAN07, m_creature);
+ m_uiStepTimer = 4000;
+ break;
+ case 12:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiPerelliGUID))
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ MoveToPoint(m_creature, 1576.119f, 657.675f, 102.09f, 5000);
+ m_uiStepTimer = 4900;
+ break;
+ case 13:
+ MoveToPoint(m_creature, 1586.040f, 646.113f, 100.910f, 6000);
+ m_uiStepTimer = 5900;
+ break;
+ case 14:
+ MoveToPoint(m_creature, 1609.189f, 697.134f, 106.902f, 23000);
+ m_uiStepTimer = 24900;
+ break;
+ case 15:
+ m_uiPhase = 2;
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ break;
+ }
+ }
+
+ void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer)
+ {
+ unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation());
+ unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiPhase == 1)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ SecondCrateEvent();
+ m_uiStep++;
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ return;
+ }
+};
+
+/*###
+## npc_jena
+###*/
+
+enum
+{
+ SAY_JENA01 = -1557291,
+ SAY_MARTHA02 = -1557292,
+ SAY_JENA03 = -1557293,
+ SAY_JENA04 = -1557294,
+ SAY_MARTHA05 = -1557295,
+
+};
+
+struct MANGOS_DLL_DECL npc_jenaAI : public ScriptedAI
+{
+ npc_jenaAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint64 m_uiMarthaGUID;
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ uint32 m_uiPhase;
+
+ void Reset()
+ {
+ if(m_uiPhase != 2)
+ {
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ m_uiPhase = 0;
+ }
+ }
+
+ void StartJena()
+ {
+ m_uiPhase = 1;
+ }
+
+ void ThirdCrateEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 1605.546f, 744.869f, 114.731f);
+ m_uiStepTimer = 1900;
+ break;
+ case 1:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 1614.967f, 743.673f, 114.063f);
+ m_uiStepTimer = 4900;
+ break;
+ case 2:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 1623.848f, 729.251f, 112.410f);
+ m_uiStepTimer = 6900;
+ break;
+ case 3:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 1633.460f, 726.261f, 113.518f);
+ m_uiStepTimer = 4000;
+ break;
+ case 4:
+ m_uiMarthaGUID = m_pInstance->GetData64(NPC_MARTHA);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID());
+ DoScriptText(SAY_JENA01, m_creature);
+ m_uiStepTimer = 3000;
+ break;
+ case 5:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ {
+ pTemp->RemoveAurasDueToSpell(58925);
+ pTemp->GetMotionMaster()->MovePoint(0, 1635.918f, 724.357f, 113.561f);
+ }
+ m_uiStepTimer = 1000;
+ break;
+ case 6:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ {
+ pTemp->GetMotionMaster()->MovementExpired(false);
+ pTemp->GetMotionMaster()->MovePoint(0, 1636.721f, 725.88f, 113.561f);
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ }
+ m_uiStepTimer = 1000;
+ break;
+ case 7:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ DoScriptText(SAY_MARTHA02, pTemp);
+ m_uiStepTimer = 4000;
+ break;
+ case 8:
+ DoScriptText(SAY_JENA03, m_creature);
+ m_uiStepTimer = 3000;
+ break;
+ case 9:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ m_creature->GetMotionMaster()->MovePoint(0, 1629.278f, 727.894f, 112.636f);
+ m_uiStepTimer = 1500;
+ break;
+ case 10:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ {
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ pTemp->GetMap()->CreatureRelocation(pTemp, 1640.089f, 725.766f, 113.561f, 4.77f);
+ pTemp->SendMonsterMove(1640.089f, 725.766f, 113.561f, SPLINETYPE_NORMAL , pTemp->GetSplineFlags(), 1500);
+ }
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, 1629.452f, 729.416f, 112.712f);
+ m_uiStepTimer = 1000;
+ break;
+ case 11:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ pTemp->GetMotionMaster()->MovePoint(0, 1640.103f, 725.522f, 113.561f);
+ m_uiStepTimer = 500;
+ break;
+ case 12:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ pTemp->CastSpell(pTemp, 58925, false);
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ m_uiStepTimer = 1500;
+ break;
+ case 13:
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_uiStepTimer = 1000;
+ break;
+ case 14:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID());
+ DoScriptText(SAY_JENA04, m_creature);
+ m_uiStepTimer = 3000;
+ break;
+ case 15:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiMarthaGUID))
+ {
+ pTemp->RemoveAurasDueToSpell(58925);
+ DoScriptText(SAY_MARTHA05, pTemp);
+ MoveToPoint(pTemp, 1638.196f, 726.171f, 113.561f, 1000);
+ }
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ MoveToPoint(m_creature, 1615.590f, 719.509f, 110.311f, 2000);
+ m_uiStepTimer = 2000;
+ break;
+ case 16:
+ MoveToPoint(m_creature, 1596.436f, 670.809f, 103.747f, 7000);
+ m_uiStepTimer = 6900;
+ break;
+ case 17:
+ MoveToPoint(m_creature, 1571.549f, 609.837f, 99.767f, 9000);
+ m_uiStepTimer = 11000;
+ break;
+ case 18:
+ m_uiPhase = 2;
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ break;
+ }
+ }
+
+ void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer)
+ {
+ unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation());
+ unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiPhase == 1)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ ThirdCrateEvent();
+ m_uiStep++;
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ return;
+ }
+};
+
+/*###
+## npc_malcolm
+###*/
+
+enum
+{
+ SOUND_ID_DOG_GROWL = 1108,
+ SOUND_ID_DOG_HOWL = 1018,
+ EMOTE_DOG_HOWL = 393,
+
+ SAY_MALCOLM01 = -1557296,
+ SAY_MALCOLM02 = -1557297,
+ SAY_MALCOLM03 = -1557298,
+ SAY_MALCOLM04 = -1557299,
+};
+
+struct MANGOS_DLL_DECL npc_malcolmAI : public ScriptedAI
+{
+ npc_malcolmAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint64 m_uiDogGUID;
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ uint32 m_uiPhase;
+
+ void Reset()
+ {
+ if(m_uiPhase != 2)
+ {
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ m_uiPhase = 0;
+ }
+ }
+
+ void StartMalcolm()
+ {
+ m_uiPhase = 1;
+ }
+
+ void FourCrateEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ MoveToPoint(m_creature, 1614.066f, 796.722f, 121.739f, 5500);
+ m_uiDogGUID = m_pInstance->GetData64(NPC_DOG);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ MoveToPoint(pTemp, 1611.459f, 793.274f, 121.928f, 5500);
+ m_uiStepTimer = 5400;
+ break;
+ case 1:
+ DoScriptText(SAY_MALCOLM01, m_creature);
+ MoveToPoint(m_creature, 1622.820f, 798.816f, 120.570f, 3500);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ MoveToPoint(pTemp, 1621.467f, 794.323f, 120.323f, 3500);
+ m_uiStepTimer = 3400;
+ break;
+ case 2:
+ MoveToPoint(m_creature, 1626.574f, 806.781f, 120.270f, 3500);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ MoveToPoint(pTemp, 1629.232f, 803.629f, 120.011f, 3500);
+ m_uiStepTimer = 3400;
+ break;
+ case 3:
+ MoveToPoint(m_creature, 1622.782f, 808.533f, 121.249f, 1500);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ MoveToPoint(pTemp, 1629.265f, 805.245f, 120.070f, 300);
+ m_uiStepTimer = 300;
+ break;
+ case 4:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ pTemp->PlayDirectSound(SOUND_ID_DOG_GROWL);
+ m_uiStepTimer = 500;
+ break;
+ case 5:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID());
+ DoScriptText(SAY_MALCOLM02, m_creature);
+ m_uiStepTimer = 2000;
+ break;
+ case 6:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ MoveToPoint(pTemp, 1629.163f, 809.738f, 120.369f, 1500);
+ m_uiStepTimer = 2000;
+ break;
+ case 7:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ {
+ pTemp->HandleEmoteCommand(EMOTE_DOG_HOWL);
+ pTemp->PlayDirectSound(SOUND_ID_DOG_HOWL);
+ }
+ m_uiStepTimer = 4000;
+ break;
+ case 8:
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ MoveToPoint(m_creature, 1629.922f, 807.799f, 120.122f, 3000);
+ m_uiStepTimer = 2900;
+ break;
+ case 9:
+ MoveToPoint(m_creature, 1632.169f, 809.851f, 120.047f, 1000);
+ m_uiStepTimer = 900;
+ break;
+ case 10:
+ MoveToPoint(m_creature, 1630.651f, 811.149f, 120.307f, 800);
+ m_uiStepTimer = 800;
+ break;
+ case 11:
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ DoScriptText(SAY_MALCOLM03, m_creature);
+ m_uiStepTimer = 4000;
+ break;
+ case 12:
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTemp->GetGUID());
+ DoScriptText(SAY_MALCOLM04, m_creature);
+ m_uiStepTimer = 7000;
+ break;
+ case 13:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ MoveToPoint(pTemp, 1630.692f, 808.011f, 120.083f, 400);
+ m_uiStepTimer = 600;
+ break;
+ case 14:
+ if(Creature* pTemp = m_pInstance->instance->GetCreature(m_uiDogGUID))
+ pTemp->SetStandState(UNIT_STAND_STATE_SIT);
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ MoveToPoint(m_creature, 1641.452f, 812.600f, 119.948f, 4000);
+ m_uiStepTimer = 3900;
+ break;
+ case 15:
+ MoveToPoint(m_creature, 1657.975f, 857.352f, 119.097f, 18000);
+ m_uiStepTimer = 17900;
+ break;
+ case 16:
+ MoveToPoint(m_creature, 1679.852f, 912.245f, 120.533f, 23000);
+ m_uiStepTimer = 22900;
+ break;
+ case 17:
+ MoveToPoint(m_creature, 1699.915f, 967.110f, 121.643f, 23000);
+ m_uiStepTimer = 22900;
+ break;
+ case 18:
+ MoveToPoint(m_creature, 1678.393f, 1026.890f, 125.431f, 25000);
+ m_uiStepTimer = 24900;
+ break;
+ case 19:
+ MoveToPoint(m_creature, 1678.943f, 1093.130f, 126.899f, 26000);
+ m_uiStepTimer = 25900;
+ break;
+ case 20:
+ MoveToPoint(m_creature, 1700.042f, 1103.880f, 130.872f, 9000);
+ m_uiStepTimer = 10900;
+ break;
+ case 21:
+ m_uiPhase = 2;
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ break;
+ }
+ }
+
+ void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer)
+ {
+ unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation());
+ unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiPhase == 1)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ FourCrateEvent();
+ m_uiStep++;
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ return;
+ }
+};
+
+/*###
+## npc_bartleby
+###*/
+
+enum
+{
+ SAY_BARTLEBY01 = -1557300,
+ SAY_BARTLEBY02 = -1557301,
+ SAY_BARTLEBY03 = -1557302,
+ SAY_BARTLEBY04 = -1557303,
+ SAY_BARTLEBY05 = -1557304,
+};
+
+struct MANGOS_DLL_DECL npc_bartleby_csAI : public ScriptedAI
+{
+ npc_bartleby_csAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiStep;
+ uint32 m_uiStepTimer;
+ uint32 m_uiPhase;
+
+ void Reset()
+ {
+ if(m_uiPhase != 4)
+ {
+ m_uiStep = 0;
+ m_uiStepTimer = 100;
+ m_uiPhase = 0;
+ }
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if(!m_pInstance) return;
+
+ if (who->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance2d(who) <= 20 && m_uiPhase == 0)
+ {
+ m_uiPhase = 1;
+ }
+ }
+
+ void StartBartleby()
+ {
+ m_uiPhase = 3;
+ }
+
+ void FifthCrateEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ DoScriptText(SAY_BARTLEBY03, m_creature);
+ MoveToPoint(m_creature, 1672.539f, 872.277f, 120.113f, 1000);
+ m_uiStepTimer = 1000;
+ break;
+ case 1:
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ m_uiStepTimer = 3000;
+ break;
+ case 2:
+ DoScriptText(SAY_BARTLEBY04, m_creature);
+ m_uiStepTimer = 7000;
+ break;
+ case 3:
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_uiStepTimer = 1000;
+ break;
+ case 4:
+ DoScriptText(SAY_BARTLEBY05, m_creature);
+ MoveToPoint(m_creature, 1663.054f, 869.959f, 119.734f, 3000);
+ m_uiStepTimer = 2900;
+ break;
+ case 5:
+ MoveToPoint(m_creature, 1640.732f, 812.422f, 119.933f, 24000);
+ m_uiStepTimer = 23900;
+ break;
+ case 6:
+ MoveToPoint(m_creature, 1623.704f, 755.741f, 115.710f, 23000);
+ m_uiStepTimer = 22900;
+ break;
+ case 7:
+ MoveToPoint(m_creature, 1607.108f, 699.637f, 106.971f, 23000);
+ m_uiStepTimer = 22900;
+ break;
+ case 8:
+ MoveToPoint(m_creature, 1587.750f, 646.929f, 100.990f, 21000);
+ m_uiStepTimer = 20900;
+ break;
+ case 9:
+ MoveToPoint(m_creature, 1571.103f, 660.949f, 102.084f, 8000);
+ m_uiStepTimer = 10900;
+ break;
+ case 10:
+ m_uiPhase = 4;
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ break;
+ }
+ }
+
+ void SpeechEvent()
+ {
+ switch(m_uiStep)
+ {
+ case 0:
+ DoScriptText(SAY_BARTLEBY01, m_creature);
+ m_uiStepTimer = 5000;
+ break;
+ case 1:
+ DoScriptText(SAY_BARTLEBY02, m_creature);
+ if(m_uiPhase == 1)
+ m_uiPhase = 2;
+ break;
+ }
+ }
+
+ void MoveToPoint(Creature* unit, float X, float Y, float Z, uint32 Timer)
+ {
+ unit->GetMap()->CreatureRelocation(unit, X, Y, Z, unit->GetOrientation());
+ unit->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL , unit->GetSplineFlags(), Timer);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiPhase == 3)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ FifthCrateEvent();
+ m_uiStep++;
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ if(m_uiPhase == 1)
+ {
+ if(m_uiStepTimer < uiDiff)
+ {
+ SpeechEvent();
+ m_uiStep++;
+ }
+ else m_uiStepTimer -= uiDiff;
+ }
+
+ return;
+ }
+};
+
+/*###
+## npc_crates
+###*/
+
+enum
+{
+ SPELL_LIGHT = 49590
+};
+
+struct MANGOS_DLL_DECL npc_stratholme_cratesAI : public ScriptedAI
+{
+ npc_stratholme_cratesAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool Active;
+
+ void Reset()
+ {
+ Active = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(!m_pInstance) return;
+
+ if(m_creature->HasAura(SPELL_LIGHT) && Active != true)
+ {
+ if(Creature* pRoger = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ROGER)))
+ {
+ if(m_creature->GetDistance2d(pRoger->GetPositionX(), pRoger->GetPositionY()) < 50.0f)
+ {
+ ((npc_rogerAI*)pRoger->AI())->StartRoger();
+ }
+ }
+
+ if(Creature* pMorigan = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MORIGAN)))
+ {
+ if(m_creature->GetDistance2d(pMorigan->GetPositionX(), pMorigan->GetPositionY()) < 50.0f)
+ {
+ ((npc_moriganAI*)pMorigan->AI())->StartMorigan();
+ }
+ }
+
+ if(Creature* pJena = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_JENA)))
+ {
+ if(m_creature->GetDistance2d(pJena->GetPositionX(), pJena->GetPositionY()) < 50.0f)
+ {
+ ((npc_jenaAI*)pJena->AI())->StartJena();
+ }
+ }
+
+ if(Creature* pMalcolm = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_MALCOLM)))
+ {
+ if(m_creature->GetDistance2d(pMalcolm->GetPositionX(), pMalcolm->GetPositionY()) < 50.0f)
+ {
+ ((npc_malcolmAI*)pMalcolm->AI())->StartMalcolm();
+ }
+ }
+
+ if(Creature* pBartleby = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_BARTLEBY)))
+ {
+ if(m_creature->GetDistance2d(pBartleby->GetPositionX(), pBartleby->GetPositionY()) < 50.0f)
+ {
+ ((npc_bartleby_csAI*)pBartleby->AI())->StartBartleby();
+ }
+ }
+
+ m_pInstance->SetData(TYPE_CRATES_COUNT, 1);
+ if(GameObject* pLight = GetClosestGameObjectWithEntry(m_creature, GO_CRATE_LIGHT, 5.0f))
+ pLight->SetPhaseMask(0, true);
+ //m_creature->SetPhaseMask(0, true);
+ Active = true;
+ }
+
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_chromi_start(Creature* pCreature)
+{
+ return new npc_chromi_startAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_mike(Creature* pCreature)
+{
+ return new npc_mikeAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_roger(Creature* pCreature)
+{
+ return new npc_rogerAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_morigan(Creature* pCreature)
+{
+ return new npc_moriganAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_jena(Creature* pCreature)
+{
+ return new npc_jenaAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_malcolm(Creature* pCreature)
+{
+ return new npc_malcolmAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_bartleby_cs(Creature* pCreature)
+{
+ return new npc_bartleby_csAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_stratholme_crates(Creature* pCreature)
+{
+ return new npc_stratholme_cratesAI(pCreature);
+}
+
+void AddSC_culling_of_stratholmeAI()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_chromi_start";
+ newscript->pGossipHello = &GossipHello_npc_chromi_start;
+ newscript->pGossipSelect = &GossipSelect_npc_chromi_start;
+ newscript->GetAI = &GetAI_npc_chromi_start;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_mike";
+ newscript->GetAI = &GetAI_npc_mike;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_roger";
+ newscript->GetAI = &GetAI_npc_roger;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_morigan";
+ newscript->GetAI = &GetAI_npc_morigan;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jena";
+ newscript->GetAI = &GetAI_npc_jena;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_malcolm";
+ newscript->GetAI = &GetAI_npc_malcolm;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_bartleby_cs";
+ newscript->GetAI = &GetAI_npc_bartleby_cs;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_stratholme_crates";
+ newscript->GetAI = &GetAI_npc_stratholme_crates;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h
new file mode 100644
index 0000000..ab16d2d
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/def_culling_of_stratholme.h
@@ -0,0 +1,110 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#ifndef DEF_CULLING_OF_STRATHOLME_H
+#define DEF_CULLING_OF_STRATHOLME_H
+
+enum Data
+{
+ TYPE_QUEST = 1,
+ TYPE_INTRO = 2,
+ TYPE_CRATES_COUNT = 3,
+ TYPE_PHASE = 4,
+ TYPE_ENCOUNTER = 5,
+ TYPE_WAVE_COUNT = 6,
+ TYPE_WING = 7,
+ TYPE_BONUS = 8,
+ TYPE_MALGANIS = 9,
+
+ DATA_TEMPSUMMON = 10,
+
+ QUEST_DISPELLING_ILLUSIONS = 13149,
+ QUEST_A_ROYAL_ESCORT = 13151,
+ ITEM_ARCANE_DISRUPTOR = 37888,
+
+ NPC_CHROMI01 = 26527,
+ NPC_CHROMI02 = 27915,
+ NPC_ARTHAS = 26499,
+ NPC_JAINA = 26497,
+ NPC_UTHER = 26528,
+ NPC_KNIGHT = 28612,
+ NPC_MIKE = 30571,
+ NPC_MAL_CORICS = 31017,
+ NPC_GRIAN_STONE = 30561,
+ NPC_JAMES = 30553,
+ NPC_FRAS_FRASIABI = 30552,
+ NPC_FORRESTER = 30551,
+ NPC_ROGER = 27903,
+ NPC_CRATE = 30996,
+ NPC_MORIGAN = 27877,
+ NPC_PERELLI = 27876,
+ NPC_JENA = 27885,
+ NPC_MARTHA = 27884,
+ NPC_MALCOLM = 27891,
+ NPC_DOG = 27892,
+ NPC_BARTLEBY = 27907,
+ NPC_MARINE = 27745,
+ NPC_PRIEST = 27747,
+
+ NPC_INFINITE_ADVERSARY = 27742,
+ NPC_INFINITE_HUNTER = 27743,
+ NPC_INFINITE_AGENT = 27744,
+ NPC_TIME_RIFT = 28409,
+ NPC_TIME_RIFT_2 = 28439,
+ NPC_ZOMBIE = 27737,
+ NPC_GHOUL = 28249,
+ NPC_NECROMANCER = 28200,
+ NPC_STALKER = 28199,
+ NPC_FIEND = 27734,
+ NPC_GOLEM = 28201,
+ NPC_EGHOUL = 27729,
+ NPC_CONSTRUCT = 27736,
+ NPC_ACOLYTE = 27731,
+ NPC_MEATHOOK = 26529,
+ NPC_SALRAMM = 26530,
+ NPC_EPOCH = 26532,
+ NPC_MALGANIS = 26533,
+ NPC_CITY = 28167,
+ NPC_INFINITE_CORRUPTOR = 32273,
+
+ GO_CRATE_LIGHT = 190117,
+ GO_SHKAF_GATE = 188686,
+ GO_MALGANIS_GATE1 = 187711,
+ GO_MALGANIS_GATE2 = 187723,
+ GO_MALGANIS_CHEST = 190663,
+ GO_MALGANIS_CHEST_H = 193597,
+ GO_EXIT = 191788,
+
+
+ WORLD_STATE_COS_TIME_ON = 3932,
+ WORLD_STATE_COS_TIME_COUNT = 3931,
+ WORLD_STATE_COS_WAVE_COUNT = 3504,
+ WORLD_STATE_COS_CRATE_ON = 3479,
+ WORLD_STATE_COS_CRATE_COUNT = 3480,
+
+ RIGHT = 1,
+ LEFT = 2
+};
+
+#endif
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp
index 9bc162c..73e8ff4 100644
--- a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp
@@ -14,560 +14,376 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
/* ScriptData
-SDName: Instance_culling_of_stratholme
-SD%Complete: 80%
-SDComment:
+SDName: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
SDCategory: Culling of Stratholme
EndScriptData */
#include "precompiled.h"
-#include "culling_of_stratholme.h"
-
-enum
-{
- MAX_ARTHAS_SPAWN_POS = 5,
- SAY_CHROMIE_HURRY = -1000000 // TODO
-};
-
-struct sSpawnLocation
-{
- float m_fX, m_fY, m_fZ, m_fO;
-};
-
-static sSpawnLocation m_aArthasSpawnLocs[] = // need tuning
-{
- {1969.73f, 1287.12f, 145.48f, 3.14f},
- {2049.43f, 1287.43f, 142.75f, 0.06f},
- {2365.54f, 1194.85f, 131.98f, 0.47f},
- {2534.46f, 1125.99f, 130.75f, 0.27f},
- {2363.77f, 1406.31f, 128.64f, 3.23f}
-};
+#include "def_culling_of_stratholme.h"
-static sSpawnLocation m_aChromieSpawnLocs[] = // need tuning, escpecially EndPositions!
+struct MANGOS_DLL_DECL instance_culling_of_stratholme : public ScriptedInstance
{
- {1814.46f, 1283.97f, 142.30f, 4.32f}, // near bridge
- {2311.0f, 1502.4f, 127.9f, 0.0f}, // End
- {1811.52f, 1285.92f, 142.37f, 4.47f}, // Hourglass, near bridge
- {2186.42f, 1323.77f, 129.91f, 0.0f}, // Hourglass, End
-};
-
-instance_culling_of_stratholme::instance_culling_of_stratholme(Map* pMap) : ScriptedInstance(pMap),
- m_uiGrainCrateCount(0),
- m_uiRemoveCrateStateTimer(0),
- m_uiArthasRespawnTimer(0),
-
- m_uiChromieInnGUID(0),
- m_uiChromieEntranceGUID(0),
- m_uiChromieEndGUID(0),
- m_uiHourglassGUID(0),
- m_uiArthasGUID(0),
- m_uiMeathookGUID(0),
- m_uiSalrammGUID(0),
- m_uiEpochGUID(0),
- m_uiCorrupterGUID(0),
- m_uiLordaeronCrierGUID(0),
-
- m_uiBelfastGUID(0),
- m_uiForrestenGUID(0),
- m_uiSiabiGUID(0),
- m_uiJamesGUID(0),
- m_uiCorricksGUID(0),
- m_uiStoutmantleGUID(0),
-
- m_uiOwensGUID(0),
- m_uiMoriganGUID(0),
- m_uiAndersonGUID(0),
- m_uiMooreGUID(0),
- m_uiBattsonGUID(0),
-
- m_uiOReillyGUID(0),
-
- m_uiDoorBookcaseGUID(0),
- m_uiDarkRunedChestGUID(0)
-{
- Initialize();
-}
-
-void instance_culling_of_stratholme::Initialize()
-{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
-}
-
-void instance_culling_of_stratholme::OnCreatureCreate(Creature* pCreature)
-{
- switch(pCreature->GetEntry())
- {
- case NPC_CHROMIE_INN: m_uiChromieInnGUID = pCreature->GetGUID(); break;
- case NPC_CHROMIE_ENTRANCE: m_uiChromieEntranceGUID = pCreature->GetGUID(); break;
- case NPC_CHROMIE_END: m_uiChromieEndGUID = pCreature->GetGUID(); break;
- case NPC_HOURGLASS: m_uiHourglassGUID = pCreature->GetGUID(); break;
- case NPC_ARTHAS: m_uiArthasGUID = pCreature->GetGUID(); break;
- case NPC_MEATHOOK: m_uiMeathookGUID = pCreature->GetGUID(); break;
- case NPC_SALRAMM_THE_FLESHCRAFTER: m_uiSalrammGUID = pCreature->GetGUID(); break;
- case NPC_CHRONO_LORD_EPOCH: m_uiEpochGUID = pCreature->GetGUID(); break;
- case NPC_MALGANIS: m_uiMalganisGUID = pCreature->GetGUID(); break;
- case NPC_MICHAEL_BELFAST: m_uiBelfastGUID = pCreature->GetGUID(); break;
- case NPC_HEARTHSINGER_FORRESTEN: m_uiForrestenGUID = pCreature->GetGUID(); break;
- case NPC_FRAS_SIABI: m_uiSiabiGUID = pCreature->GetGUID(); break;
- case NPC_FOOTMAN_JAMES: m_uiJamesGUID = pCreature->GetGUID(); break;
- case NPC_MAL_CORRICKS: m_uiCorricksGUID = pCreature->GetGUID(); break;
- case NPC_GRYAN_STOUTMANTLE: m_uiStoutmantleGUID = pCreature->GetGUID(); break;
- case NPC_ROGER_OWENS: m_uiOwensGUID = pCreature->GetGUID(); break;
- case NPC_SERGEANT_MORIGAN: m_uiMoriganGUID = pCreature->GetGUID(); break;
- case NPC_JENA_ANDERSON: m_uiAndersonGUID = pCreature->GetGUID(); break;
- case NPC_MALCOM_MOORE: m_uiMooreGUID = pCreature->GetGUID(); break;
- case NPC_BARTLEBY_BATTSON: m_uiBattsonGUID = pCreature->GetGUID(); break;
- case NPC_PATRICIA_O_REILLY: m_uiOReillyGUID = pCreature->GetGUID(); break;
- case NPC_LORDAERON_CRIER: m_uiLordaeronCrierGUID = pCreature->GetGUID(); break;
- case NPC_INFINITE_CORRUPTER: m_uiCorrupterGUID = pCreature->GetGUID(); break;
-
- case NPC_CRATES_BUNNY: m_luiCratesBunnyGUIDs.push_back(pCreature->GetGUID()); break;
- case NPC_LORDAERON_FOOTMAN: m_luiFootmanGUIDs.push_back(pCreature->GetGUID()); break;
-
- case NPC_STRATHOLME_CITIZEN:
- case NPC_STRATHOLME_RESIDENT:
- if (m_auiEncounter[TYPE_ARTHAS_INTRO_EVENT] == DONE)
- pCreature->UpdateEntry(NPC_ZOMBIE);
- else
- m_luiResidentGUIDs.push_back(pCreature->GetGUID());
- break;
- case NPC_AGIATED_STRATHOLME_CITIZEN: m_lAgiatedCitizenGUIDList.push_back(pCreature->GetGUID()); break;
- case NPC_AGIATED_STRATHOLME_RESIDENT: m_lAgiatedResidentGUIDList.push_back(pCreature->GetGUID()); break;
- }
-}
-
-void instance_culling_of_stratholme::OnObjectCreate(GameObject* pGo)
-{
- switch(pGo->GetEntry())
+ instance_culling_of_stratholme(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint8 m_uiCratesCount;
+ uint32 m_auiEncounter[7];
+ uint32 m_uiHeroicTimer;
+ uint32 m_uiLastTimer;
+
+ uint64 m_uiChromi01GUID;
+ uint64 m_uiChromi02GUID;
+ uint64 m_uiMikeGUID;
+ uint64 m_uiMalCoricsGUID;
+ uint64 m_uiGrianStoneGUID;
+ uint64 m_uiJamesGUID;
+ uint64 m_uiFrasCiabiGUID;
+ uint64 m_uiForrestenGUID;
+ uint64 m_uiRogerGUID;
+ uint64 m_uiMoriganGUID;
+ uint64 m_uiPerelliGUID;
+ uint64 m_uiJenaGUID;
+ uint64 m_uiMarthaGUID;
+ uint64 m_uiMalcolmGUID;
+ uint64 m_uiDogGUID;
+ uint64 m_uiBartlebyGUID;
+ uint64 m_uiArthasGUID;
+ uint64 m_uiUtherGUID;
+ uint64 m_uiJainaGUID;
+ uint64 m_uiSalrammGUID;
+ uint64 m_uiMalganisGUID;
+ uint64 m_uiCorruptorGUID;
+
+ uint64 m_uiShkafGateGUID;
+ uint64 m_uiMalGate1GUID;
+ uint64 m_uiMalGate2GUID;
+ uint64 m_uiMalChestGUID;
+ uint64 m_uiExitGUID;
+
+ void Initialize()
{
- case GO_DOOR_BOOKCASE:
- m_uiDoorBookcaseGUID = pGo->GetGUID();
- if (m_auiEncounter[TYPE_EPOCH_EVENT] == DONE)
- pGo->SetGoState(GO_STATE_ACTIVE);
- break;
- case GO_DARK_RUNED_CHEST:
- case GO_DARK_RUNED_CHEST_H:
- m_uiDarkRunedChestGUID = pGo->GetGUID();
- break;
+ m_uiHeroicTimer = 1500000;
+ m_uiLastTimer = 1500000;
+ m_auiEncounter[0] = NOT_STARTED;
+ m_auiEncounter[1] = NOT_STARTED;
+ m_auiEncounter[2] = 0;
+ m_auiEncounter[3] = NOT_STARTED;
+ m_auiEncounter[4] = 0;
+ m_auiEncounter[5] = NOT_STARTED;
+ m_auiEncounter[6] = NOT_STARTED;
+
+ DoUpdateWorldState(WORLD_STATE_COS_CRATE_COUNT, 0);
+ DoUpdateWorldState(WORLD_STATE_COS_CRATE_ON, 0);
+ DoUpdateWorldState(WORLD_STATE_COS_WAVE_COUNT, 0);
+ DoUpdateWorldState(WORLD_STATE_COS_TIME_COUNT, 0);
+ DoUpdateWorldState(WORLD_STATE_COS_TIME_ON, 0);
+
+ m_uiCratesCount = 0;
+ m_uiMikeGUID = 0;
+ m_uiChromi01GUID = 0;
+ m_uiChromi02GUID = 0;
+ m_uiMalCoricsGUID = 0;
+ m_uiGrianStoneGUID = 0;
+ m_uiJamesGUID = 0;
+ m_uiFrasCiabiGUID = 0;
+ m_uiForrestenGUID = 0;
+ m_uiRogerGUID = 0;
+ m_uiMoriganGUID = 0;
+ m_uiPerelliGUID = 0;
+ m_uiJenaGUID = 0;
+ m_uiMarthaGUID = 0;
+ m_uiMalcolmGUID = 0;
+ m_uiDogGUID = 0;
+ m_uiBartlebyGUID = 0;
+ m_uiArthasGUID = 0;
+ m_uiUtherGUID = 0;
+ m_uiJainaGUID = 0;
+ m_uiShkafGateGUID = 0;
+ m_uiSalrammGUID = 0;
+ m_uiCorruptorGUID = 0;
+ m_uiMalganisGUID = 0;
+ m_uiMalGate1GUID = 0;
+ m_uiMalGate2GUID = 0;
+ m_uiMalChestGUID = 0;
+ m_uiExitGUID = 0;
}
-}
-Player* instance_culling_of_stratholme::GetPlayerInMap()
-{
- Map::PlayerList const& players = instance->GetPlayers();
-
- if (!players.isEmpty())
+ void OnCreatureCreate(Creature* pCreature)
{
- for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ switch(pCreature->GetEntry())
{
- if (Player* plr = itr->getSource())
- return plr;
+ case NPC_CHROMI01:
+ pCreature->SetActiveObjectState(true);
+ m_uiChromi01GUID = pCreature->GetGUID();
+ break;
+ case NPC_CHROMI02:
+ pCreature->SetActiveObjectState(true);
+ m_uiChromi02GUID = pCreature->GetGUID();
+ if (m_auiEncounter[0] == DONE)
+ pCreature->SetVisibility(VISIBILITY_ON);
+ else
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ break;
+ case NPC_MIKE:
+ m_uiMikeGUID = pCreature->GetGUID();
+ break;
+ case NPC_MAL_CORICS:
+ pCreature->SetActiveObjectState(true);
+ m_uiMalCoricsGUID = pCreature->GetGUID();
+ break;
+ case NPC_GRIAN_STONE:
+ pCreature->SetActiveObjectState(true);
+ pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR);
+ m_uiGrianStoneGUID = pCreature->GetGUID();
+ break;
+ case NPC_JAMES:
+ pCreature->SetActiveObjectState(true);
+ pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR);
+ m_uiJamesGUID = pCreature->GetGUID();
+ break;
+ case NPC_FRAS_FRASIABI:
+ pCreature->SetActiveObjectState(true);
+ pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR);
+ m_uiFrasCiabiGUID = pCreature->GetGUID();
+ break;
+ case NPC_FORRESTER:
+ pCreature->SetActiveObjectState(true);
+ pCreature->SetStandState(UNIT_STAND_STATE_SIT_MEDIUM_CHAIR);
+ m_uiForrestenGUID = pCreature->GetGUID();
+ break;
+ case NPC_ROGER:
+ m_uiRogerGUID = pCreature->GetGUID();
+ break;
+ case NPC_MORIGAN:
+ m_uiMoriganGUID = pCreature->GetGUID();
+ break;
+ case NPC_PERELLI:
+ pCreature->SetActiveObjectState(true);
+ m_uiPerelliGUID = pCreature->GetGUID();
+ break;
+ case NPC_JENA:
+ m_uiJenaGUID = pCreature->GetGUID();
+ break;
+ case NPC_MARTHA:
+ pCreature->CastSpell(pCreature, 58925, false);
+ pCreature->SetActiveObjectState(true);
+ m_uiMarthaGUID = pCreature->GetGUID();
+ break;
+ case NPC_MALCOLM:
+ m_uiMalcolmGUID = pCreature->GetGUID();
+ break;
+ case NPC_DOG:
+ pCreature->SetActiveObjectState(true);
+ m_uiDogGUID = pCreature->GetGUID();
+ break;
+ case NPC_BARTLEBY:
+ m_uiBartlebyGUID = pCreature->GetGUID();
+ break;
+ case NPC_UTHER:
+ m_uiUtherGUID = pCreature->GetGUID();
+ break;
+ case NPC_ARTHAS:
+ m_uiArthasGUID = pCreature->GetGUID();
+ break;
+ case NPC_JAINA:
+ pCreature->SetActiveObjectState(true);
+ m_uiJainaGUID = pCreature->GetGUID();
+ break;
+ case NPC_INFINITE_CORRUPTOR:
+ pCreature->SetPhaseMask(0, true);
+ m_uiCorruptorGUID = pCreature->GetGUID();
+ break;
}
}
- return NULL;
-}
-void instance_culling_of_stratholme::UpdateQuestCredit()
-{
- Map::PlayerList const& players = instance->GetPlayers();
- if (!players.isEmpty())
+ void OnObjectCreate(GameObject* pGo)
{
- for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- {
- if (Player* pPlayer = itr->getSource())
- pPlayer->KilledMonsterCredit(NPC_CRATES_BUNNY);
- }
- }
-}
+ if (pGo->GetEntry() == GO_SHKAF_GATE)
+ m_uiShkafGateGUID = pGo->GetGUID();
-void instance_culling_of_stratholme::DoChromieHurrySpeech()
-{
- if (Creature* pChromie = instance->GetCreature(m_uiChromieEntranceGUID))
- {
- Map::PlayerList const& players = instance->GetPlayers();
- if (!players.isEmpty())
- {
- for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- {
- if (Player* pPlayer = itr->getSource())
- DoScriptText(SAY_CHROMIE_HURRY, pChromie, pPlayer);
- }
- }
- }
-}
+ if (pGo->GetEntry() == GO_MALGANIS_GATE1)
+ m_uiMalGate1GUID = pGo->GetGUID();
-void instance_culling_of_stratholme::SetData(uint32 uiType, uint32 uiData)
-{
- switch(uiType)
- {
- case TYPE_GRAIN_EVENT:
- m_auiEncounter[TYPE_GRAIN_EVENT] = uiData;
- if (uiData == SPECIAL)
- DoUpdateWorldState(WORLD_STATE_CRATES, 1);
- else if (uiData == IN_PROGRESS)
- {
- if (m_uiGrainCrateCount >= 5)
- return;
+ if (pGo->GetEntry() == GO_MALGANIS_GATE2)
+ m_uiMalGate2GUID = pGo->GetGUID();
- ++m_uiGrainCrateCount;
- DoUpdateWorldState(WORLD_STATE_CRATES_COUNT, m_uiGrainCrateCount);
+ if (pGo->GetEntry() == GO_MALGANIS_CHEST || pGo->GetEntry() == GO_MALGANIS_CHEST_H)
+ m_uiMalChestGUID = pGo->GetGUID();
- if (m_uiGrainCrateCount == 5)
- {
- UpdateQuestCredit();
- m_uiRemoveCrateStateTimer = 20000;
- SetData(TYPE_GRAIN_EVENT, DONE);
- }
- }
- break;
- case TYPE_ARTHAS_INTRO_EVENT:
- m_auiEncounter[TYPE_ARTHAS_INTRO_EVENT] = uiData;
- break;
- case TYPE_ARTHAS_ESCORT_EVENT:
- m_auiEncounter[TYPE_ARTHAS_ESCORT_EVENT] = uiData;
- break;
- case TYPE_MEATHOOK_EVENT:
- m_auiEncounter[TYPE_MEATHOOK_EVENT] = uiData;
- if (uiData == DONE)
- SetData(TYPE_SALRAMM_EVENT, IN_PROGRESS);
- break;
- case TYPE_SALRAMM_EVENT:
- m_auiEncounter[TYPE_SALRAMM_EVENT] = uiData;
- if (uiData == DONE)
- DoUpdateWorldState(WORLD_STATE_WAVE, 0); // Remove WaveCounter
- break;
- case TYPE_EPOCH_EVENT:
- m_auiEncounter[TYPE_EPOCH_EVENT] = uiData;
- break;
- case TYPE_MALGANIS_EVENT:
- m_auiEncounter[TYPE_MALGANIS_EVENT] = uiData;
- if (uiData == DONE)
- {
- DoRespawnGameObject(m_uiDarkRunedChestGUID, 30*MINUTE);
- DoSpawnChromieIfNeeded();
- }
- break;
- case TYPE_INFINITE_CORRUPTER_TIME:
- m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] = uiData;
- if (!uiData)
- {
- DoUpdateWorldState(WORLD_STATE_TIME, 0); // Remove Timer
- DoUpdateWorldState(WORLD_STATE_TIME_COUNTER, 0);
- }
- else
- DoUpdateWorldState(WORLD_STATE_TIME_COUNTER, uiData/(MINUTE*IN_MILLISECONDS));
- break;
- case TYPE_INFINITE_CORRUPTER:
- m_auiEncounter[TYPE_INFINITE_CORRUPTER] = uiData;
- switch(uiData)
- {
- case IN_PROGRESS:
- if (!m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME])
- SetData(TYPE_INFINITE_CORRUPTER_TIME, MINUTE*25*IN_MILLISECONDS);
- DoUpdateWorldState(WORLD_STATE_TIME, 1);// Show Timer
- break;
- case DONE:
- SetData(TYPE_INFINITE_CORRUPTER_TIME, 0);
- break;
- case SPECIAL:
- DoChromieHurrySpeech();
- break;
- case FAIL:
- SetData(TYPE_INFINITE_CORRUPTER_TIME, 0);
- if (Creature* pCorrupter = instance->GetCreature(m_uiCorrupterGUID))
- if (pCorrupter->isAlive())
- pCorrupter->ForcedDespawn();
- break;
- }
- break;
+ if (pGo->GetEntry() == GO_EXIT)
+ m_uiExitGUID = pGo->GetGUID();
}
- if (uiData == DONE || (uiType == TYPE_INFINITE_CORRUPTER && uiData == FAIL))
+ void ChromiWhispers()
{
- OUT_SAVE_INST_DATA;
- std::ostringstream saveStream;
- saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
- << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
- << m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8];
+ Map::PlayerList const &PlayerList = instance->GetPlayers();
- strInstData = saveStream.str();
+ if (PlayerList.isEmpty())
+ return;
- SaveToDB();
- OUT_SAVE_INST_DATA_COMPLETE;
- }
-}
-
-void instance_culling_of_stratholme::Load(const char* chrIn)
-{
- if (!chrIn)
- {
- OUT_LOAD_INST_DATA_FAIL;
- return;
+ if (Creature* pChromi = instance->GetCreature(m_uiChromi01GUID))
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ pChromi->MonsterWhisper("Good work with crates! Come to me in front of Stratholme for your next assignment!", i->getSource(), false);
+ i->getSource()->KilledMonsterCredit(30996, pChromi->GetGUID());
+ i->getSource()->DestroyItemCount(ITEM_ARCANE_DISRUPTOR, 1, true);
+ }
+ pChromi->SetVisibility(VISIBILITY_OFF);
+ }
+ if (Creature* pChromi2 = instance->GetCreature(m_uiChromi02GUID))
+ pChromi2->SetVisibility(VISIBILITY_ON);
}
- OUT_LOAD_INST_DATA(chrIn);
-
- std::istringstream loadStream(chrIn);
- loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
- >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7] >> m_auiEncounter[8];
-
- for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ void SetData(uint32 uiType, uint32 uiData)
{
- if (i != TYPE_INFINITE_CORRUPTER_TIME)
+ switch(uiType)
{
- if (m_auiEncounter[i] == IN_PROGRESS)
- m_auiEncounter[i] = NOT_STARTED;
+ case TYPE_QUEST:
+ m_auiEncounter[0] = uiData;
+ break;
+ case TYPE_CRATES_COUNT:
+ m_uiCratesCount = m_uiCratesCount + uiData;
+ if(m_uiCratesCount == 5)
+ {
+ m_auiEncounter[0] = DONE;
+ ChromiWhispers();
+ }
+ DoUpdateWorldState(WORLD_STATE_COS_CRATE_COUNT, m_uiCratesCount);
+ break;
+ case TYPE_INTRO:
+ m_auiEncounter[1] = uiData;
+ break;
+ case TYPE_PHASE:
+ m_auiEncounter[2] = uiData;
+ break;
+ case TYPE_ENCOUNTER:
+ m_auiEncounter[3] = uiData;
+ break;
+ case TYPE_WING:
+ m_auiEncounter[4] = uiData;
+ break;
+ case TYPE_BONUS:
+ m_auiEncounter[5] = uiData;
+ if(uiData == IN_PROGRESS)
+ {
+ if(Creature* Corruptor = instance->GetCreature(m_uiCorruptorGUID))
+ Corruptor->SetPhaseMask(1, true);
+ DoUpdateWorldState(WORLD_STATE_COS_TIME_ON, 1);
+ DoUpdateWorldState(WORLD_STATE_COS_TIME_COUNT, 25);
+ }
+ break;
+ case TYPE_MALGANIS:
+ m_auiEncounter[6] = uiData;
+ if (uiData == DONE)
+ {
+ DoRespawnGameObject(m_uiMalChestGUID, 30*MINUTE);
+ if (GameObject* pGo = instance->GetGameObject(m_uiMalChestGUID))
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
+ if (Creature* pChromi2 = instance->GetCreature(m_uiChromi02GUID))
+ pChromi2->SetVisibility(VISIBILITY_OFF);
+ if (GameObject* pGo = instance->GetGameObject(m_uiExitGUID))
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ }
+ break;
}
}
- // If already started counting down time, the event is "in progress"
- if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME])
- m_auiEncounter[TYPE_INFINITE_CORRUPTER] = IN_PROGRESS;
-
- OUT_LOAD_INST_DATA_COMPLETE;
-}
-
-void instance_culling_of_stratholme::OnPlayerEnter(Player* pPlayer)
-{
- if (instance->GetPlayersCountExceptGMs() == 0)
- {
- DoSpawnArthasIfNeeded();
- DoSpawnChromieIfNeeded();
-
- // Show World States if needed, TODO verify if needed and if this is the right way
- if (m_auiEncounter[TYPE_GRAIN_EVENT] == IN_PROGRESS || m_auiEncounter[TYPE_GRAIN_EVENT] == SPECIAL)
- DoUpdateWorldState(WORLD_STATE_CRATES, 1); // Show Crates Counter
- else
- DoUpdateWorldState(WORLD_STATE_CRATES, 0); // Remove Crates Counter
-
- if (m_auiEncounter[TYPE_MEATHOOK_EVENT] == IN_PROGRESS)
- DoUpdateWorldState(WORLD_STATE_WAVE, 1); // Add WaveCounter
- else if (m_auiEncounter[TYPE_SALRAMM_EVENT] == IN_PROGRESS)
- DoUpdateWorldState(WORLD_STATE_WAVE, 6); // Add WaveCounter
- else
- DoUpdateWorldState(WORLD_STATE_WAVE, 0); // Remove WaveCounter
-
- if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME])
- DoUpdateWorldState(WORLD_STATE_TIME, 1); // Show Timer
- else
- DoUpdateWorldState(WORLD_STATE_TIME, 0); // Remove Timer
- }
-}
-
-uint32 instance_culling_of_stratholme::GetData(uint32 uiType)
-{
- switch(uiType)
- {
- case TYPE_GRAIN_EVENT: return m_auiEncounter[0];
- case TYPE_ARTHAS_INTRO_EVENT: return m_auiEncounter[1];
- case TYPE_MEATHOOK_EVENT: return m_auiEncounter[2];
- case TYPE_SALRAMM_EVENT: return m_auiEncounter[3];
- case TYPE_EPOCH_EVENT: return m_auiEncounter[4];
- case TYPE_ARTHAS_ESCORT_EVENT: return m_auiEncounter[5];
- case TYPE_MALGANIS_EVENT: return m_auiEncounter[6];
- case TYPE_INFINITE_CORRUPTER_TIME: return m_auiEncounter[7];
- case TYPE_INFINITE_CORRUPTER: return m_auiEncounter[8];
- default: return 0;
- }
-}
-
-uint64 instance_culling_of_stratholme::GetData64(uint32 uiData)
-{
- switch(uiData)
- {
- case NPC_CHROMIE_INN: return m_uiChromieInnGUID;
- case NPC_CHROMIE_ENTRANCE: return m_uiChromieEntranceGUID;
- case NPC_CHROMIE_END: return m_uiChromieEndGUID;
- case NPC_HOURGLASS: return m_uiHourglassGUID;
- case NPC_ARTHAS: return m_uiArthasGUID;
- case NPC_MEATHOOK: return m_uiMeathookGUID;
- case NPC_SALRAMM_THE_FLESHCRAFTER: return m_uiSalrammGUID;
- case NPC_CHRONO_LORD_EPOCH: return m_uiEpochGUID;
- case NPC_MALGANIS: return m_uiMalganisGUID;
- case NPC_INFINITE_CORRUPTER: return m_uiCorrupterGUID;
- case NPC_MICHAEL_BELFAST: return m_uiBelfastGUID;
- case NPC_HEARTHSINGER_FORRESTEN: return m_uiForrestenGUID;
- case NPC_FRAS_SIABI: return m_uiSiabiGUID;
- case NPC_FOOTMAN_JAMES: return m_uiJamesGUID;
- case NPC_MAL_CORRICKS: return m_uiCorricksGUID;
- case NPC_GRYAN_STOUTMANTLE: return m_uiStoutmantleGUID;
- case NPC_ROGER_OWENS: return m_uiOwensGUID;
- case NPC_SERGEANT_MORIGAN: return m_uiMoriganGUID;
- case NPC_JENA_ANDERSON: return m_uiAndersonGUID;
- case NPC_MALCOM_MOORE: return m_uiMooreGUID;
- case NPC_BARTLEBY_BATTSON: return m_uiBattsonGUID;
- case NPC_PATRICIA_O_REILLY: return m_uiOReillyGUID;
- case GO_DOOR_BOOKCASE: return m_uiDoorBookcaseGUID;
- default: return 0;
- }
-}
-
-uint8 instance_culling_of_stratholme::GetInstancePosition()
-{
- if (m_auiEncounter[TYPE_MALGANIS_EVENT] == DONE)
- return POS_INSTANCE_FINISHED;
- else if (m_auiEncounter[TYPE_ARTHAS_ESCORT_EVENT] == DONE)
- return POS_ARTHAS_MALGANIS;
- else if (m_auiEncounter[TYPE_EPOCH_EVENT] == DONE)
- return POS_ARTHAS_ESCORTING;
- else if (m_auiEncounter[TYPE_SALRAMM_EVENT] == DONE)
- return POS_ARTHAS_TOWNHALL;
- else if (m_auiEncounter[TYPE_MEATHOOK_EVENT] == DONE)
- return POS_ARTHAS_WAVES;
- else if (m_auiEncounter[TYPE_ARTHAS_INTRO_EVENT] == DONE)
- return POS_ARTHAS_WAVES;
- else if (m_auiEncounter[TYPE_GRAIN_EVENT] == DONE)
- return POS_ARTHAS_INTRO;
- else
- return 0;
-}
-
-static bool sortFromEastToWest(Creature* pFirst, Creature* pSecond)
-{
- return pFirst && pSecond && pFirst->GetPositionY() < pSecond->GetPositionY();
-}
-
-static bool sortFromSouthToNorth(Creature* pFirst, Creature* pSecond)
-{
- return pFirst && pSecond && pFirst->GetPositionX() < pSecond->GetPositionX();
-}
-
-void instance_culling_of_stratholme::GetCratesBunnyOrderedList(std::list &lList)
-{
- std::list lCratesBunnyList;
- for (std::list::const_iterator itr = m_luiCratesBunnyGUIDs.begin(); itr != m_luiCratesBunnyGUIDs.end(); itr++)
- {
- if (Creature* pBunny = instance->GetCreature(*itr))
- lCratesBunnyList.push_back(pBunny);
- }
- if (lCratesBunnyList.empty())
- return;
-
- lCratesBunnyList.sort(sortFromEastToWest);
- lList = lCratesBunnyList;
-}
-
-Creature* instance_culling_of_stratholme::GetStratIntroFootman()
-{
- std::list lFootmanList;
- for (std::list::const_iterator itr = m_luiFootmanGUIDs.begin(); itr != m_luiFootmanGUIDs.end(); itr++)
- {
- if (Creature* pFootman = instance->GetCreature(*itr))
- lFootmanList.push_back(pFootman);
- }
-
- if (lFootmanList.empty())
- return NULL;
- else
+ void SetData64(uint32 uiData, uint64 uiGuid)
{
- lFootmanList.sort(sortFromSouthToNorth);
- return *lFootmanList.begin();
- }
-}
-
-void instance_culling_of_stratholme::GetResidentOrderedList(std::list &lList)
-{
- std::list lResidentList;
- for (std::list::const_iterator itr = m_luiResidentGUIDs.begin(); itr != m_luiResidentGUIDs.end(); itr++)
- {
- if (Creature* pResident = instance->GetCreature(*itr))
- lResidentList.push_back(pResident);
- }
- if (lResidentList.empty())
- return;
-
- lResidentList.sort(sortFromSouthToNorth);
- lList = lResidentList;
-}
-
-void instance_culling_of_stratholme::ArthasJustDied()
-{
- m_uiArthasRespawnTimer = 10000; // TODO, could be instant
-}
-
-void instance_culling_of_stratholme::DoSpawnArthasIfNeeded()
-{
- Creature* pArthas = instance->GetCreature(m_uiArthasGUID);
- if (pArthas && pArthas->isAlive())
- return;
-
- uint8 uiPosition = GetInstancePosition();
- if (uiPosition && uiPosition <= MAX_ARTHAS_SPAWN_POS)
- {
- if (Player* pPlayer = GetPlayerInMap())
- pPlayer->SummonCreature(NPC_ARTHAS, m_aArthasSpawnLocs[uiPosition-1].m_fX, m_aArthasSpawnLocs[uiPosition-1].m_fY, m_aArthasSpawnLocs[uiPosition-1].m_fZ, m_aArthasSpawnLocs[uiPosition-1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- }
-}
-
-// Atm here only new Chromies are spawned - despawning depends on Mangos featuring such a thing
-// The hourglass also is not yet spawned/ relocated.
-void instance_culling_of_stratholme::DoSpawnChromieIfNeeded()
-{
- Player* pPlayer = GetPlayerInMap();
- if (!pPlayer)
- return;
-
- if (GetInstancePosition() == POS_INSTANCE_FINISHED)
- {
- Creature* pChromie = instance->GetCreature(m_uiChromieEndGUID);
- if (!pChromie)
- pPlayer->SummonCreature(NPC_CHROMIE_END, m_aChromieSpawnLocs[1].m_fX, m_aChromieSpawnLocs[1].m_fY, m_aChromieSpawnLocs[1].m_fZ, m_aChromieSpawnLocs[1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- }
- else if (GetInstancePosition() >= POS_ARTHAS_INTRO)
- {
- Creature* pChromie = instance->GetCreature(m_uiChromieEntranceGUID);
- if (!pChromie)
- pPlayer->SummonCreature(NPC_CHROMIE_ENTRANCE, m_aChromieSpawnLocs[0].m_fX, m_aChromieSpawnLocs[0].m_fY, m_aChromieSpawnLocs[0].m_fZ, m_aChromieSpawnLocs[0].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
+ switch(uiData)
+ {
+ case NPC_SALRAMM:
+ m_uiSalrammGUID = uiGuid;
+ break;
+ case NPC_MALGANIS:
+ m_uiMalganisGUID = uiGuid;
+ break;
+ }
}
-}
-void instance_culling_of_stratholme::Update(uint32 uiDiff)
-{
- // 25min Run - decrease time, update worldstate every ~20s
- // as the time is always saved by m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME], there is no need for an extra timer
- if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME])
+ uint32 GetData(uint32 uiType)
{
- if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] <= uiDiff)
- SetData(TYPE_INFINITE_CORRUPTER, FAIL);
- else
+ switch(uiType)
{
- m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] -= uiDiff;
- if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]/IN_MILLISECONDS % 20 == 0)
- SetData(TYPE_INFINITE_CORRUPTER_TIME, m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]);
+ case TYPE_QUEST:
+ return m_auiEncounter[0];
+ case TYPE_INTRO:
+ return m_auiEncounter[1];
+ case TYPE_PHASE:
+ return m_auiEncounter[2];
+ case TYPE_ENCOUNTER:
+ return m_auiEncounter[3];
+ case TYPE_WING:
+ return m_auiEncounter[4];
+ case TYPE_BONUS:
+ return m_auiEncounter[5];
+ case TYPE_MALGANIS:
+ return m_auiEncounter[6];
}
-
- // This part is needed for a small "hurry up guys" note, TODO, verify 20min
- if (m_auiEncounter[TYPE_INFINITE_CORRUPTER] == IN_PROGRESS && m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] <= 24*MINUTE*IN_MILLISECONDS)
- SetData(TYPE_INFINITE_CORRUPTER, SPECIAL);
+ return 0;
}
- // Small Timer, to remove Grain-Crate WorldState and Spawn Second Chromie
- if (m_uiRemoveCrateStateTimer)
+ uint64 GetData64(uint32 uiData)
{
- if (m_uiRemoveCrateStateTimer <= uiDiff)
+ switch(uiData)
{
- DoUpdateWorldState(WORLD_STATE_CRATES, 0);
- DoSpawnChromieIfNeeded();
- m_uiRemoveCrateStateTimer = 0;
+ case NPC_FORRESTER: return m_uiForrestenGUID;
+ case NPC_JAMES: return m_uiJamesGUID;
+ case NPC_FRAS_FRASIABI: return m_uiFrasCiabiGUID;
+ case NPC_MAL_CORICS: return m_uiMalCoricsGUID;
+ case NPC_GRIAN_STONE: return m_uiGrianStoneGUID;
+ case NPC_ROGER: return m_uiRogerGUID;
+ case NPC_MORIGAN: return m_uiMoriganGUID;
+ case NPC_PERELLI: return m_uiPerelliGUID;
+ case NPC_JENA: return m_uiJenaGUID;
+ case NPC_MARTHA: return m_uiMarthaGUID;
+ case NPC_MALCOLM: return m_uiMalcolmGUID;
+ case NPC_DOG: return m_uiDogGUID;
+ case NPC_BARTLEBY: return m_uiBartlebyGUID;
+ case NPC_UTHER: return m_uiUtherGUID;
+ case NPC_ARTHAS: return m_uiArthasGUID;
+ case NPC_JAINA: return m_uiJainaGUID;
+ case NPC_SALRAMM: return m_uiSalrammGUID;
+ case NPC_MALGANIS: return m_uiMalganisGUID;
+ case GO_SHKAF_GATE: return m_uiShkafGateGUID;
+ case GO_MALGANIS_GATE1: return m_uiMalGate1GUID;
+ case GO_MALGANIS_GATE2: return m_uiMalGate2GUID;
+ case GO_MALGANIS_CHEST: return m_uiMalChestGUID;
+ case GO_EXIT: return m_uiExitGUID;
}
- else
- m_uiRemoveCrateStateTimer -= uiDiff;
+
+ return 0;
}
- // Respawn Arthas after some time
- if (m_uiArthasRespawnTimer)
+ void Update(uint32 uiDiff)
{
- if (m_uiArthasRespawnTimer <= uiDiff)
- {
- DoSpawnArthasIfNeeded();
- m_uiArthasRespawnTimer = 0;
- }
- else
- m_uiArthasRespawnTimer -= uiDiff;
+ if(m_auiEncounter[5] == IN_PROGRESS)
+ {
+ if(m_uiHeroicTimer < uiDiff)
+ {
+ m_auiEncounter[5] = FAIL;
+ DoUpdateWorldState(WORLD_STATE_COS_TIME_ON, 0);
+ if(Creature* Corruptor = instance->GetCreature(m_uiCorruptorGUID))
+ Corruptor->SetPhaseMask(0, true);
+
+ }else m_uiHeroicTimer -= uiDiff;
+
+ if(m_uiHeroicTimer < m_uiLastTimer - 60000)
+ {
+ m_uiLastTimer = m_uiHeroicTimer;
+ uint32 tMinutes = m_uiHeroicTimer / 60000;
+ DoUpdateWorldState(WORLD_STATE_COS_TIME_COUNT, tMinutes);
+ }
+ }
+
+ return;
}
-}
+};
InstanceData* GetInstanceData_instance_culling_of_stratholme(Map* pMap)
{
@@ -576,10 +392,9 @@ InstanceData* GetInstanceData_instance_culling_of_stratholme(Map* pMap)
void AddSC_instance_culling_of_stratholme()
{
- Script* pNewScript;
-
- pNewScript = new Script;
- pNewScript->Name = "instance_culling_of_stratholme";
- pNewScript->GetInstanceData = &GetInstanceData_instance_culling_of_stratholme;
- pNewScript->RegisterSelf();
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_culling_of_stratholme";
+ newscript->GetInstanceData = &GetInstanceData_instance_culling_of_stratholme;
+ newscript->RegisterSelf();
}
diff --git a/scripts/kalimdor/caverns_of_time/culling_of_stratholme/trash_culling_of_stratholme.cpp b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/trash_culling_of_stratholme.cpp
new file mode 100644
index 0000000..60b8a88
--- /dev/null
+++ b/scripts/kalimdor/caverns_of_time/culling_of_stratholme/trash_culling_of_stratholme.cpp
@@ -0,0 +1,1094 @@
+/* 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: instance_culling_of_stratholme
+SD%Complete: ?%
+SDComment: by MaxXx2021
+SDCategory: Culling of Stratholme
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_culling_of_stratholme.h"
+
+/*###
+## npc_cs_gnoul
+###*/
+
+enum
+{
+ SPELL_FLESH = 52352
+};
+
+struct MANGOS_DLL_DECL npc_cs_gnoulAI : public ScriptedAI
+{
+ npc_cs_gnoulAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 m_uiFleshTimer;
+
+ uint32 WaypointId;
+ uint32 MoveTimer;
+
+ void Reset()
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ MoveTimer = (urand(100, 5000));
+ m_uiFleshTimer = (urand(3000, 10000));
+ WaypointId = 1;
+ }
+
+ void MoveToPoint(float X, float Y, float Z)
+ {
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+
+ if (IsCombatMovement())
+ m_creature->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ m_uiFleshTimer = (urand(3000, 10000));
+
+ m_creature->SetLootRecipient(NULL);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
+ }
+ }
+
+ void JumpNextStep(uint32 Time)
+ {
+ MoveTimer = Time;
+ WaypointId++;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon())
+ {
+ if(MoveTimer < uiDiff)
+ {
+ if(m_pInstance->GetData(TYPE_WING) == RIGHT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2356.659f, 1185.501f, 130.636f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2301.735f, 1179.265f, 136.944f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2234.787f, 1180.638f, 136.344f);
+ JumpNextStep(9000);
+ break;
+ case 4:
+ MoveToPoint(2178.313f, 1244.350f, 136.107f);
+ JumpNextStep(12000);
+ break;
+ case 5:
+ MoveToPoint(2163.553f, 1277.814f, 133.444f);
+ JumpNextStep(5000);
+ break;
+ case 6:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(5000);
+ break;
+ }
+ }
+
+ if(m_pInstance->GetData(TYPE_WING) == LEFT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2188.318f, 1331.410f, 130.003f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2165.351f, 1279.156f, 133.388f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(9000);
+ break;
+ }
+ }
+
+ } else MoveTimer -= uiDiff;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiFleshTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_FLESH);
+ m_uiFleshTimer = (urand(3000, 10000));
+ }
+ else m_uiFleshTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+/*###
+## npc_cs_necromancer
+###*/
+
+enum
+{
+ SPELL_SHADOW_BOLT = 15472,
+ SPELL_COURSE = 20812,
+ SPELL_DRAIN_MANA = 58770
+};
+
+struct MANGOS_DLL_DECL npc_cs_necromancerAI : public ScriptedAI
+{
+ npc_cs_necromancerAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 m_uiShadowBoltTimer;
+ uint32 m_uiCourseTimer;
+
+ uint32 WaypointId;
+ uint32 MoveTimer;
+
+ void Reset()
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ MoveTimer = (urand(100, 5000));
+ m_uiCourseTimer = (urand(7000, 17000));
+ m_uiShadowBoltTimer = (urand(3000, 10000));
+ WaypointId = 1;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->StopMoving();
+ }
+
+ void MoveToPoint(float X, float Y, float Z)
+ {
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ }
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ m_uiShadowBoltTimer = (urand(3000, 10000));
+ m_uiCourseTimer = (urand(7000, 17000));
+
+ m_creature->SetLootRecipient(NULL);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
+ }
+ }
+
+ void JumpNextStep(uint32 Time)
+ {
+ MoveTimer = Time;
+ WaypointId++;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon())
+ {
+ if(MoveTimer < uiDiff)
+ {
+ if(m_pInstance->GetData(TYPE_WING) == RIGHT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2356.659f, 1185.501f, 130.636f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2301.735f, 1179.265f, 136.944f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2234.787f, 1180.638f, 136.344f);
+ JumpNextStep(9000);
+ break;
+ case 4:
+ MoveToPoint(2178.313f, 1244.350f, 136.107f);
+ JumpNextStep(12000);
+ break;
+ case 5:
+ MoveToPoint(2163.553f, 1277.814f, 133.444f);
+ JumpNextStep(5000);
+ break;
+ case 6:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(5000);
+ break;
+ }
+ }
+
+ if(m_pInstance->GetData(TYPE_WING) == LEFT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2188.318f, 1331.410f, 130.003f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2165.351f, 1279.156f, 133.388f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(9000);
+ break;
+ }
+ }
+
+ } else MoveTimer -= uiDiff;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiShadowBoltTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT);
+ m_uiShadowBoltTimer = (urand(3000, 5000));
+ }
+ else m_uiShadowBoltTimer -= uiDiff;
+
+ if(m_uiCourseTimer < uiDiff)
+ {
+ m_creature->InterruptNonMeleeSpells(false);
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_COURSE);
+ m_uiCourseTimer = (urand(7000, 17000));
+ }
+ else m_uiCourseTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+/*###
+## npc_cs_field
+###*/
+
+enum
+{
+ SPELL_BLOW = 52491,
+ SPELL_SCARAB = 52496
+};
+
+struct MANGOS_DLL_DECL npc_cs_fieldAI : public ScriptedAI
+{
+ npc_cs_fieldAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 m_uiScarabTimer;
+ uint32 m_uiBlowTimer;
+
+ uint32 WaypointId;
+ uint32 MoveTimer;
+
+ void Reset()
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ MoveTimer = (urand(100, 5000));
+ m_uiBlowTimer = (urand(7000, 17000));
+ m_uiScarabTimer = (urand(3000, 10000));
+ WaypointId = 1;
+ }
+
+ void MoveToPoint(float X, float Y, float Z)
+ {
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+
+ if (IsCombatMovement())
+ m_creature->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ m_uiScarabTimer = (urand(3000, 10000));
+ m_uiBlowTimer = (urand(7000, 17000));
+
+ m_creature->SetLootRecipient(NULL);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
+ }
+ }
+
+ void JumpNextStep(uint32 Time)
+ {
+ MoveTimer = Time;
+ WaypointId++;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon())
+ {
+ if(MoveTimer < uiDiff)
+ {
+ if(m_pInstance->GetData(TYPE_WING) == RIGHT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2356.659f, 1185.501f, 130.636f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2301.735f, 1179.265f, 136.944f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2234.787f, 1180.638f, 136.344f);
+ JumpNextStep(9000);
+ break;
+ case 4:
+ MoveToPoint(2178.313f, 1244.350f, 136.107f);
+ JumpNextStep(12000);
+ break;
+ case 5:
+ MoveToPoint(2163.553f, 1277.814f, 133.444f);
+ JumpNextStep(5000);
+ break;
+ case 6:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(5000);
+ break;
+ }
+ }
+
+ if(m_pInstance->GetData(TYPE_WING) == LEFT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2188.318f, 1331.410f, 130.003f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2165.351f, 1279.156f, 133.388f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(9000);
+ break;
+ }
+ }
+
+ } else MoveTimer -= uiDiff;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiScarabTimer < uiDiff)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_SCARAB);
+ m_uiScarabTimer = (urand(3000, 5000));
+ }
+ else m_uiScarabTimer -= uiDiff;
+
+ if(m_uiBlowTimer < uiDiff)
+ {
+ m_creature->InterruptNonMeleeSpells(false);
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_BLOW);
+ m_uiBlowTimer = (urand(7000, 17000));
+ }
+ else m_uiBlowTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+/*###
+## npc_cs_alocyte
+###*/
+
+enum
+{
+ SPELL_SHADOW = 17234,
+ SPELL_COLD = 15244,
+ SPELL_FIRE = 14145,
+ SPELL_COURSEA = 39621
+};
+
+struct MANGOS_DLL_DECL npc_cs_acolyteAI : public ScriptedAI
+{
+ npc_cs_acolyteAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 m_uiColdTimer;
+ uint32 m_uiFireTimer;
+ uint32 m_uiCourseTimer;
+ uint32 m_uiShadowTimer;
+
+ uint32 WaypointId;
+ uint32 MoveTimer;
+
+ void Reset()
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ MoveTimer = (urand(100, 5000));
+ m_uiColdTimer = (urand(7000, 17000));
+ m_uiFireTimer = (urand(3000, 10000));
+ m_uiCourseTimer = (urand(5000, 12000));
+ m_uiShadowTimer = (urand(1000, 3000));
+ WaypointId = 1;
+ }
+
+ void MoveToPoint(float X, float Y, float Z)
+ {
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->StopMoving();
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ }
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ m_uiColdTimer = (urand(7000, 17000));
+ m_uiFireTimer = (urand(3000, 10000));
+ m_uiCourseTimer = (urand(5000, 12000));
+ m_uiShadowTimer = (urand(1000, 3000));
+
+ m_creature->SetLootRecipient(NULL);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
+ }
+ }
+
+ void JumpNextStep(uint32 Time)
+ {
+ MoveTimer = Time;
+ WaypointId++;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon())
+ {
+ if(MoveTimer < uiDiff)
+ {
+ if(m_pInstance->GetData(TYPE_WING) == RIGHT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2356.659f, 1185.501f, 130.636f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2301.735f, 1179.265f, 136.944f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2234.787f, 1180.638f, 136.344f);
+ JumpNextStep(9000);
+ break;
+ case 4:
+ MoveToPoint(2178.313f, 1244.350f, 136.107f);
+ JumpNextStep(12000);
+ break;
+ case 5:
+ MoveToPoint(2163.553f, 1277.814f, 133.444f);
+ JumpNextStep(5000);
+ break;
+ case 6:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(5000);
+ break;
+ }
+ }
+
+ if(m_pInstance->GetData(TYPE_WING) == LEFT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2188.318f, 1331.410f, 130.003f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2165.351f, 1279.156f, 133.388f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(9000);
+ break;
+ }
+ }
+
+ } else MoveTimer -= uiDiff;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiShadowTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_SHADOW);
+ m_uiShadowTimer = (urand(3000, 8000));
+ }
+ else m_uiShadowTimer -= uiDiff;
+
+ if(m_uiCourseTimer < uiDiff)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_COURSEA);
+ m_uiCourseTimer = (urand(7000, 13000));
+ }
+ else m_uiCourseTimer -= uiDiff;
+
+ if(m_uiColdTimer < uiDiff)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_COLD);
+ m_uiColdTimer = (urand(13000, 17000));
+ }
+ else m_uiColdTimer -= uiDiff;
+
+ if(m_uiFireTimer < uiDiff)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, SPELL_FIRE);
+ m_uiFireTimer = (urand(6000, 11000));
+ }
+ else m_uiFireTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+/*###
+## npc_cs_butcher
+###*/
+
+enum
+{
+ SPELL_CLOUD = 52525
+};
+
+struct MANGOS_DLL_DECL npc_cs_butcherAI : public ScriptedAI
+{
+ npc_cs_butcherAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 WaypointId;
+ uint32 MoveTimer;
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_CLOUD);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ MoveTimer = (urand(100, 5000));
+ WaypointId = 1;
+ }
+
+ void MoveToPoint(float X, float Y, float Z)
+ {
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MovePoint(0, X, Y, Z);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+
+ if (IsCombatMovement())
+ m_creature->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+
+ m_creature->SetLootRecipient(NULL);
+ DoCast(m_creature, SPELL_CLOUD);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
+ }
+ }
+
+ void JumpNextStep(uint32 Time)
+ {
+ MoveTimer = Time;
+ WaypointId++;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() && m_creature->IsTemporarySummon())
+ {
+ if(MoveTimer < uiDiff)
+ {
+ if(m_pInstance->GetData(TYPE_WING) == RIGHT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2356.659f, 1185.501f, 130.636f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2301.735f, 1179.265f, 136.944f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2234.787f, 1180.638f, 136.344f);
+ JumpNextStep(9000);
+ break;
+ case 4:
+ MoveToPoint(2178.313f, 1244.350f, 136.107f);
+ JumpNextStep(12000);
+ break;
+ case 5:
+ MoveToPoint(2163.553f, 1277.814f, 133.444f);
+ JumpNextStep(5000);
+ break;
+ case 6:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(5000);
+ break;
+ }
+ }
+
+ if(m_pInstance->GetData(TYPE_WING) == LEFT)
+ {
+ switch(WaypointId)
+ {
+ case 1:
+ MoveToPoint(2188.318f, 1331.410f, 130.003f);
+ JumpNextStep(10000);
+ break;
+ case 2:
+ MoveToPoint(2165.351f, 1279.156f, 133.388f);
+ JumpNextStep(8000);
+ break;
+ case 3:
+ MoveToPoint(2083.952f, 1287.716f, 141.146f);
+ JumpNextStep(9000);
+ break;
+ }
+ }
+
+ } else MoveTimer -= uiDiff;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_time_riftCSAI : public ScriptedAI
+{
+ npc_time_riftCSAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsHeroic = pCreature->GetMap()->IsRaidOrHeroicDungeon();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsHeroic;
+
+ uint32 Step;
+ uint32 m_uiStepTimer;
+ Creature* Drakonian01;
+ Creature* Drakonian02;
+ Creature* Drakonian03;
+
+ void Reset()
+ {
+ m_uiStepTimer = 1000;
+ Step = 1;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiStepTimer < uiDiff)
+ {
+ switch(Step)
+ {
+ case 1:
+ if (Creature* pArthas = m_pInstance->instance->GetCreature(m_pInstance->GetData64(NPC_ARTHAS)))
+ {
+ Drakonian01 = m_creature->SummonCreature(NPC_INFINITE_ADVERSARY,(m_creature->GetPositionX()-2)+rand()%4, (m_creature->GetPositionY()-2)+rand()%4, m_creature->GetPositionZ(),3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000);
+ Drakonian01->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ());
+ Drakonian02 = m_creature->SummonCreature(NPC_INFINITE_HUNTER,(m_creature->GetPositionX()-2)+rand()%4, (m_creature->GetPositionY()-2)+rand()%4, m_creature->GetPositionZ(),3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000);
+ Drakonian02->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ());
+ Drakonian03 = m_creature->SummonCreature(NPC_INFINITE_AGENT,(m_creature->GetPositionX()-2)+rand()%4, (m_creature->GetPositionY()-2)+rand()%4, m_creature->GetPositionZ(),3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000);
+ Drakonian03->GetMotionMaster()->MovePoint(0, pArthas->GetPositionX(), pArthas->GetPositionY(), pArthas->GetPositionZ());
+ }
+ m_uiStepTimer = 3000;
+ Step++;
+ break;
+ case 2:
+ m_creature->RemoveFromWorld();
+ Step++;
+ break;
+ }
+ } else m_uiStepTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_cs_gnoul(Creature* pCreature)
+{
+ return new npc_cs_gnoulAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_cs_necromancer(Creature* pCreature)
+{
+ return new npc_cs_necromancerAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_cs_field(Creature* pCreature)
+{
+ return new npc_cs_fieldAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_cs_acolyte(Creature* pCreature)
+{
+ return new npc_cs_acolyteAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_cs_butcher(Creature* pCreature)
+{
+ return new npc_cs_butcherAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_time_riftCS(Creature* pCreature)
+{
+ return new npc_time_riftCSAI(pCreature);
+}
+
+void AddSC_trash_culling_of_stratholme()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_cs_gnoul";
+ newscript->GetAI = &GetAI_npc_cs_gnoul;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_cs_necromancer";
+ newscript->GetAI = &GetAI_npc_cs_necromancer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_cs_field";
+ newscript->GetAI = &GetAI_npc_cs_field;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_cs_acolyte";
+ newscript->GetAI = &GetAI_npc_cs_acolyte;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_cs_butcher";
+ newscript->GetAI = &GetAI_npc_cs_butcher;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_time_riftCS";
+ newscript->GetAI = &GetAI_npc_time_riftCS;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/kalimdor/dire_maul/dire_maul.cpp b/scripts/kalimdor/dire_maul/dire_maul.cpp
new file mode 100644
index 0000000..8ca88e1
--- /dev/null
+++ b/scripts/kalimdor/dire_maul/dire_maul.cpp
@@ -0,0 +1,28 @@
+/* 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: dire_maul
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Dire Maul
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_dire_maul()
+{
+}
diff --git a/scripts/kalimdor/dire_maul/dire_maul.h b/scripts/kalimdor/dire_maul/dire_maul.h
index e69de29..e592de1 100644
--- a/scripts/kalimdor/dire_maul/dire_maul.h
+++ b/scripts/kalimdor/dire_maul/dire_maul.h
@@ -0,0 +1,3 @@
+/* Copyright (C) 2006 - 2010 ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/scripts/kalimdor/moonglade.cpp b/scripts/kalimdor/moonglade.cpp
index 4f08965..56f0ec3 100644
--- a/scripts/kalimdor/moonglade.cpp
+++ b/scripts/kalimdor/moonglade.cpp
@@ -72,6 +72,7 @@ bool GossipHello_npc_bunthen_plainswind(Player* pPlayer, Creature* pCreature)
bool GossipSelect_npc_bunthen_plainswind(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
+ pPlayer->PlayerTalkClass->ClearMenus();
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF + 1:
@@ -253,6 +254,7 @@ bool GossipHello_npc_great_bear_spirit(Player* pPlayer, Creature* pCreature)
bool GossipSelect_npc_great_bear_spirit(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
+ pPlayer->PlayerTalkClass->ClearMenus();
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF:
@@ -310,6 +312,7 @@ bool GossipHello_npc_silva_filnaveth(Player* pPlayer, Creature* pCreature)
bool GossipSelect_npc_silva_filnaveth(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
+ pPlayer->PlayerTalkClass->ClearMenus();
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF + 1:
diff --git a/scripts/kalimdor/the_barrens.cpp b/scripts/kalimdor/the_barrens.cpp
index 163e43b..3f08e6f 100644
--- a/scripts/kalimdor/the_barrens.cpp
+++ b/scripts/kalimdor/the_barrens.cpp
@@ -467,15 +467,14 @@ CreatureAI* GetAI_npc_twiggy_flathead(Creature* pCreature)
bool AreaTrigger_at_twiggy_flathead(Player* pPlayer, AreaTriggerEntry const* pAt)
{
- if (!pPlayer->isDead() && pPlayer->GetQuestStatus(QUEST_AFFRAY) == QUEST_STATUS_INCOMPLETE)
- {
- if (uint16 slot = pPlayer->FindQuestSlot(QUEST_AFFRAY))
- {
- //we don't want player to start event if failed already.
- if (pPlayer->GetQuestSlotState(slot) == QUEST_STATE_FAIL)
- return true;
- }
+ if (pPlayer->GetQuestStatus(QUEST_AFFRAY) == QUEST_STATUS_FAILED)
+ {
+ //we don't want player to start event if failed already.
+ return true;
+ }
+ else if (!pPlayer->isDead() && pPlayer->GetQuestStatus(QUEST_AFFRAY) == QUEST_STATUS_INCOMPLETE)
+ {
Creature* pCreature = GetClosestCreatureWithEntry(pPlayer, NPC_TWIGGY, 30.0f);
if (!pCreature)
diff --git a/scripts/northrend/borean_tundra.cpp b/scripts/northrend/borean_tundra.cpp
index 3ce5b28..aa44b97 100644
--- a/scripts/northrend/borean_tundra.cpp
+++ b/scripts/northrend/borean_tundra.cpp
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Borean_Tundra
SD%Complete: 100
-SDComment: Quest support: 11708, 11692, 11961, 11865. Taxi vendors. 11570
+SDComment: Quest support: 11570, 11590, 11692, 11676, 11708, 11919, 11940, 11961. Taxi vendors.
SDCategory: Borean Tundra
EndScriptData */
@@ -30,10 +30,15 @@ go_caribou_trap
npc_surristrasz
npc_tiare
npc_lurgglbr
+npc_nexus_drake
+go_scourge_cage
+npc_beryl_sorcerer
EndContentData */
#include "precompiled.h"
#include "escort_ai.h"
+#include "ObjectMgr.h"
+#include "follower_ai.h"
/*######
## npc_fizzcrank_fullthrottle
@@ -527,6 +532,215 @@ CreatureAI* GetAI_npc_lurgglbr(Creature* pCreature)
return new npc_lurgglbrAI(pCreature);
}
+/*######
+## npc_nexus_drake_hatchling
+######*/
+
+enum
+{
+ SPELL_DRAKE_HARPOON = 46607,
+ SPELL_RED_DRAGONBLOOD = 46620,
+ SPELL_DRAKE_HATCHLING_SUBDUED = 46691,
+ SPELL_SUBDUED = 46675,
+
+ NPC_RAELORASZ = 26117,
+ DRAKE_HUNT_KILL_CREDIT = 26175,
+
+ QUEST_DRAKE_HUNT = 11919,
+ QUEST_DRAKE_HUNT_D = 11940
+
+};
+
+struct MANGOS_DLL_DECL npc_nexus_drakeAI : public FollowerAI
+{
+ npc_nexus_drakeAI(Creature* pCreature) : FollowerAI(pCreature) { Reset(); }
+
+ uint64 uiHarpoonerGUID;
+ bool bWithRedDragonBlood;
+ bool bIsFollowing;
+
+ void Reset()
+ {
+ bWithRedDragonBlood = false;
+ bIsFollowing = false;
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ AttackStart(pWho);
+ }
+
+ void SpellHit(Unit* pCaster, SpellEntry const* pSpell)
+ {
+ if (pSpell->Id == SPELL_DRAKE_HARPOON && pCaster->GetTypeId() == TYPEID_PLAYER)
+ {
+ uiHarpoonerGUID = pCaster->GetGUID();
+ DoCast(m_creature, SPELL_RED_DRAGONBLOOD, true);
+ }
+ m_creature->Attack(pCaster,true);
+ bWithRedDragonBlood = true;
+ }
+
+ void MoveInLineOfSight(Unit *pWho)
+ {
+ FollowerAI::MoveInLineOfSight(pWho);
+
+
+ if (pWho->GetEntry() == NPC_RAELORASZ && m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
+ {
+ if (Player *pHarpooner = m_creature->GetMap()->GetPlayer(uiHarpoonerGUID))
+ {
+
+ pHarpooner->KilledMonsterCredit(DRAKE_HUNT_KILL_CREDIT,m_creature->GetGUID());
+ pHarpooner->RemoveAurasByCasterSpell(SPELL_DRAKE_HATCHLING_SUBDUED,uiHarpoonerGUID);
+ SetFollowComplete();
+ uiHarpoonerGUID = 0;
+ m_creature->ForcedDespawn(1000);
+ }
+
+ }
+ }
+
+ void UpdateAI(const uint32 uidiff)
+ {
+ if (bWithRedDragonBlood && uiHarpoonerGUID && !m_creature->HasAura(SPELL_RED_DRAGONBLOOD))
+ {
+ if (Player *pHarpooner = m_creature->GetMap()->GetPlayer(uiHarpoonerGUID))
+ {
+ EnterEvadeMode();
+ StartFollow(pHarpooner, 35, NULL);
+
+ DoCast(m_creature, SPELL_SUBDUED, true);
+ pHarpooner->CastSpell(pHarpooner, SPELL_DRAKE_HATCHLING_SUBDUED, true);
+
+ m_creature->AttackStop();
+ bIsFollowing = true;
+ bWithRedDragonBlood = false;
+ }
+ }
+ if(bIsFollowing && !m_creature->HasAura(SPELL_SUBDUED))
+ {
+ m_creature->ForcedDespawn(1000);
+ }
+
+ if (!m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_nexus_drake(Creature* pCreature)
+{
+ return new npc_nexus_drakeAI(pCreature);
+}
+
+/*#####
+## go_scourge_cage
+#####*/
+
+enum
+{
+ QUEST_MERCIFUL_FREEDOM = 11676,
+ NPC_SCOURGE_PRISONER = 25610,
+};
+
+bool GOHello_go_scourge_cage(Player* pPlayer, GameObject* pGo)
+{
+ if (pPlayer->GetQuestStatus(QUEST_MERCIFUL_FREEDOM) == QUEST_STATUS_INCOMPLETE)
+ {
+ Creature *pCreature = GetClosestCreatureWithEntry(pGo, NPC_SCOURGE_PRISONER, INTERACTION_DISTANCE);
+ if(pCreature)
+ {
+ pPlayer->KilledMonsterCredit(NPC_SCOURGE_PRISONER, pCreature->GetGUID());
+ pCreature->CastSpell(pCreature, 43014, false);
+ }
+ }
+ return false;
+};
+
+/*######
+## npc_beryl_sorcerer
+######*/
+
+enum eBerylSorcerer
+{
+ NPC_CAPTURED_BERLY_SORCERER = 25474,
+ NPC_LIBRARIAN_DONATHAN = 25262,
+
+ SPELL_ARCANE_CHAINS = 45611,
+ SPELL_COSMETIC_CHAINS = 54324,
+ SPELL_COSMETIC_ENSLAVE_CHAINS_SELF = 45631
+};
+
+struct MANGOS_DLL_DECL npc_beryl_sorcererAI : public FollowerAI
+{
+ npc_beryl_sorcererAI(Creature* pCreature) : FollowerAI(pCreature) {
+ Reset();
+ m_uiNormalFaction = pCreature->getFaction();
+ }
+
+ bool bEnslaved;
+ uint64 uiChainerGUID;
+ uint32 m_uiNormalFaction;
+
+ void Reset()
+ {
+ m_creature->setFaction(m_uiNormalFaction);
+ bEnslaved = false;
+ }
+ void EnterCombat(Unit* pWho)
+ {
+ AttackStart(pWho);
+ }
+
+ void SpellHit(Unit* pCaster, SpellEntry const* pSpell)
+ {
+ if (pSpell->Id == SPELL_ARCANE_CHAINS && pCaster->GetTypeId() == TYPEID_PLAYER && !bEnslaved)
+ {
+ EnterEvadeMode(); //We make sure that the npc is not attacking the player!
+ m_creature->setFaction(35);
+ uiChainerGUID = pCaster->GetGUID();
+ if(Player *pChainer = m_creature->GetMap()->GetPlayer(uiChainerGUID))
+ {
+ StartFollow(pChainer, 35, NULL);
+ m_creature->UpdateEntry(NPC_CAPTURED_BERLY_SORCERER);
+ DoCast(m_creature, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF, true);
+
+ bEnslaved = true;
+ }
+ }
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ FollowerAI::MoveInLineOfSight(pWho);
+
+ if (pWho->GetEntry() == NPC_LIBRARIAN_DONATHAN && m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
+ {
+ if(Player *pChainer = m_creature->GetMap()->GetPlayer(uiChainerGUID))
+ {
+ pChainer->KilledMonsterCredit(NPC_CAPTURED_BERLY_SORCERER,m_creature->GetGUID());
+ SetFollowComplete();
+ m_creature->ForcedDespawn(1000);
+ }
+ }
+ }
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+};
+
+CreatureAI* GetAI_npc_beryl_sorcerer(Creature* pCreature)
+{
+ return new npc_beryl_sorcererAI(pCreature);
+}
+
void AddSC_borean_tundra()
{
Script *newscript;
@@ -576,4 +790,19 @@ void AddSC_borean_tundra()
newscript->GetAI = &GetAI_npc_lurgglbr;
newscript->pQuestAccept = &QuestAccept_npc_lurgglbr;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_nexus_drake";
+ newscript->GetAI = &GetAI_npc_nexus_drake;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_scourge_cage";
+ newscript->pGOHello = &GOHello_go_scourge_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_beryl_sorcerer";
+ newscript->GetAI = &GetAI_npc_beryl_sorcerer;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp
new file mode 100644
index 0000000..85c0a4c
--- /dev/null
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp
@@ -0,0 +1,434 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: boss_argent_challenge
+SD%Complete: 50%
+SDComment: missing yells. radiance is "wrong". modified by /dev/rsa
+SDCategory: Trial Of the Champion
+EndScriptData */
+
+#include "precompiled.h"
+#include "trial_of_the_champion.h"
+
+enum
+{
+ SPELL_BERSERK = 47008,
+ //yells
+
+ //eadric
+ SPELL_VENGEANCE = 66889,
+ SPELL_RADIANCE = 66862,
+ SPELL_RADIANCE_H = 67681,
+ SPELL_HAMMER_OF_JUSTICE = 66940,
+ SPELL_HAMMER = 67680,
+ //paletress
+ SPELL_SMITE = 66536,
+ SPELL_SMITE_H = 67674,
+ SPELL_HOLY_FIRE = 66538,
+ SPELL_HOLY_FIRE_H = 67676,
+ SPELL_RENEW = 66537,
+ SPELL_RENEW_H = 67675,
+ SPELL_HOLY_NOVA = 66546,
+ SPELL_SHIELD = 66515,
+ SPELL_CONFESS = 66547,
+ //memory
+ SPELL_FEAR = 66552,
+ SPELL_FEAR_H = 67677,
+ SPELL_SHADOWS = 66619,
+ SPELL_SHADOWS_H = 67678,
+ SPELL_OLD_WOUNDS = 66620,
+ SPELL_OLD_WOUNDS_H = 67679,
+};
+
+// Eadric The Pure
+struct MANGOS_DLL_DECL boss_eadricAI : public ScriptedAI
+{
+ boss_eadricAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Vengeance_Timer;
+ uint32 Radiance_Timer;
+ uint32 Hammer_Timer;
+ uint32 Hammer_Dmg_Timer;
+ uint32 m_uiBerserk_Timer;
+ uint64 HammerTarget;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ Vengeance_Timer = 1000;
+ Radiance_Timer = m_bIsRegularMode ? 15000 : 8000;
+ Hammer_Timer = m_bIsRegularMode ? 40000 : 10000;
+ Hammer_Dmg_Timer = m_bIsRegularMode ? 45000 : 20000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ HammerTarget = 0;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ if (m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) != DONE)
+ m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+ m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Vengeance_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_VENGEANCE);
+ Vengeance_Timer = m_bIsRegularMode ? 12000 : 8000;
+ }else Vengeance_Timer -= diff;
+
+ if (Radiance_Timer < diff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_RADIANCE : SPELL_RADIANCE_H);
+ Radiance_Timer = m_bIsRegularMode ? 20000 : 12000;
+ }else Radiance_Timer -= diff;
+
+ if (Hammer_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ {
+ DoCast(target, SPELL_HAMMER_OF_JUSTICE);
+ HammerTarget = target->GetGUID();
+ }
+ Hammer_Timer = m_bIsRegularMode ? 40000 : 15000;
+ }else Hammer_Timer -= diff;
+
+ if (Hammer_Dmg_Timer < diff)
+ {
+ if (Unit* pHammerTarget = m_creature->GetMap()->GetUnit(HammerTarget))
+ DoCast(pHammerTarget, SPELL_HAMMER);
+ Hammer_Dmg_Timer = m_bIsRegularMode ? 50000 : 15000;
+ }
+ else Hammer_Dmg_Timer -= diff;
+
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_eadric(Creature* pCreature)
+{
+ return new boss_eadricAI(pCreature);
+}
+
+// Argent Confessor Paletress
+struct MANGOS_DLL_DECL boss_paletressAI : public ScriptedAI
+{
+ boss_paletressAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Smite_Timer;
+ uint32 Holy_Fire_Timer;
+ uint32 Renew_Timer;
+ uint32 Shield_Delay;
+ uint32 Shield_Check;
+ uint32 m_uiBerserk_Timer;
+ bool summoned;
+ bool shielded;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->RemoveAurasDueToSpell(SPELL_SHIELD);
+ Smite_Timer = 5000;
+ Holy_Fire_Timer = m_bIsRegularMode ? 10000 : 8000;
+ Renew_Timer = m_bIsRegularMode ? 7000 : 5000;
+ Shield_Delay = 0;
+ Shield_Check = 1000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ summoned = false;
+ shielded = false;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+ void JustSummoned(Creature* _summoned)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ _summoned->AddThreat(target);
+ summoned = true;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ if (m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) != DONE)
+ m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+ m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Smite_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H);
+ Smite_Timer = 2000;
+ }else Smite_Timer -= diff;
+
+ if (Holy_Fire_Timer < diff)
+ {
+ m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H);
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H);
+ Holy_Fire_Timer = m_bIsRegularMode ? 10000 : 7000;
+ }else Holy_Fire_Timer -= diff;
+
+ if (Renew_Timer < diff)
+ {
+ m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H);
+ m_creature->CastStop(m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H);
+ switch(urand(0, 1))
+ {
+ case 0:
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MEMORY))))
+ if (pTemp->isAlive())
+ DoCast(pTemp, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H);
+ else
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H);
+ break;
+ case 1:
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H);
+ break;
+ }
+ Renew_Timer = 25000;
+ }else Renew_Timer -= diff;
+
+ if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 35 ) && !summoned )
+ {
+ m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H);
+ m_creature->CastStop(m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H);
+ DoCast(m_creature, SPELL_HOLY_NOVA);
+ switch(urand(0, 24))
+ {
+ case 0: m_creature->SummonCreature(MEMORY_ALGALON, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 1: m_creature->SummonCreature(MEMORY_CHROMAGGUS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 2: m_creature->SummonCreature(MEMORY_CYANIGOSA, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 3: m_creature->SummonCreature(MEMORY_DELRISSA, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 4: m_creature->SummonCreature(MEMORY_ECK, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 5: m_creature->SummonCreature(MEMORY_ENTROPIUS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 6: m_creature->SummonCreature(MEMORY_GRUUL, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 7: m_creature->SummonCreature(MEMORY_HAKKAR, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 8: m_creature->SummonCreature(MEMORY_HEIGAN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 9: m_creature->SummonCreature(MEMORY_HEROD, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 10: m_creature->SummonCreature(MEMORY_HOGGER, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 11: m_creature->SummonCreature(MEMORY_IGNIS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 12: m_creature->SummonCreature(MEMORY_ILLIDAN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 13: m_creature->SummonCreature(MEMORY_INGVAR, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 14: m_creature->SummonCreature(MEMORY_KALITHRESH, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 15: m_creature->SummonCreature(MEMORY_LUCIFRON, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 16: m_creature->SummonCreature(MEMORY_MALCHEZAAR, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 17: m_creature->SummonCreature(MEMORY_MUTANUS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 18: m_creature->SummonCreature(MEMORY_ONYXIA, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 19: m_creature->SummonCreature(MEMORY_THUNDERAAN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 20: m_creature->SummonCreature(MEMORY_VANCLEEF, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 21: m_creature->SummonCreature(MEMORY_VASHJ, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 22: m_creature->SummonCreature(MEMORY_VEKNILASH, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 23: m_creature->SummonCreature(MEMORY_VEZAX, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+ case 24: m_creature->SummonCreature(MEMORY_ARCHIMONDE, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ break;
+
+ }
+ Shield_Delay = 1000;
+ };
+ if (Shield_Delay < diff && !shielded && summoned)
+ {
+ m_creature->CastStop(m_bIsRegularMode ? SPELL_SMITE : SPELL_SMITE_H);
+ m_creature->CastStop(m_bIsRegularMode ? SPELL_HOLY_FIRE : SPELL_HOLY_FIRE_H);
+ DoCast(m_creature, SPELL_SHIELD);
+ shielded = true;
+ Shield_Check = m_bIsRegularMode ? 3000 : 5000;
+ }else Shield_Delay -= diff;
+
+ if (Shield_Check < diff && shielded)
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MEMORY))))
+ if (!pTemp->isAlive())
+ {
+ m_creature->RemoveAurasDueToSpell(SPELL_SHIELD);
+ shielded = false;
+ } else Shield_Check = 1000;
+ }else Shield_Check -= diff;
+
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_paletress(Creature* pCreature)
+{
+ return new boss_paletressAI(pCreature);
+}
+
+// Summoned Memory
+struct MANGOS_DLL_DECL mob_toc5_memoryAI : public ScriptedAI
+{
+ mob_toc5_memoryAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Old_Wounds_Timer;
+ uint32 Shadows_Timer;
+ uint32 Fear_Timer;
+
+ void Reset()
+ {
+ Old_Wounds_Timer = 5000;
+ Shadows_Timer = 8000;
+ Fear_Timer = 13000;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Old_Wounds_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsRegularMode ? SPELL_OLD_WOUNDS : SPELL_OLD_WOUNDS_H);
+ Old_Wounds_Timer = 10000;
+ }else Old_Wounds_Timer -= diff;
+
+ if (Fear_Timer < diff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_FEAR : SPELL_FEAR_H);
+ Fear_Timer = 40000;
+ }else Fear_Timer -= diff;
+
+ if (Shadows_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
+ DoCast(target, m_bIsRegularMode ? SPELL_SHADOWS : SPELL_SHADOWS_H);
+ Shadows_Timer = 10000;
+ }else Shadows_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_toc5_memory(Creature* pCreature)
+{
+ return new mob_toc5_memoryAI(pCreature);
+}
+
+void AddSC_boss_argent_challenge()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_eadric";
+ NewScript->GetAI = &GetAI_boss_eadric;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_paletress";
+ NewScript->GetAI = &GetAI_boss_paletress;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_toc5_memory";
+ NewScript->GetAI = &GetAI_mob_toc5_memory;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp
new file mode 100644
index 0000000..ef1b990
--- /dev/null
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp
@@ -0,0 +1,311 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: boss_black_knight
+SD%Complete: 70%
+SDComment: missing yells. not sure about timers. modified by /dev/rsa
+SDCategory: Trial Of the Champion
+EndScriptData */
+
+#include "precompiled.h"
+#include "trial_of_the_champion.h"
+
+enum
+{
+ SPELL_BERSERK = 47008,
+ //yells
+
+ //undead
+ SPELL_PLAGUE_STRIKE = 67724,
+ SPELL_PLAGUE_STRIKE_H = 67884,
+ SPELL_ICY_TOUCH = 67718,
+ SPELL_ICY_TOUCH_H = 67881,
+ SPELL_OBLITERATE = 67725,
+ SPELL_OBLITERATE_H = 67883,
+ SPELL_CHOKE = 68306,
+ //skeleton
+ SPELL_ARMY = 42650, //replacing original one, since that one spawns millions of ghouls!!
+ //ghost
+ SPELL_DEATH = 67808,
+ SPELL_DEATH_H = 67875,
+ SPELL_MARK = 67823,
+
+ //risen ghoul
+ SPELL_CLAW = 67879,
+ SPELL_EXPLODE = 67729,
+ SPELL_EXPLODE_H = 67886,
+ SPELL_LEAP = 67749,
+ SPELL_LEAP_H = 67880,
+
+ //sword ID
+ EQUIP_SWORD = 40343
+};
+
+// Risen Ghoul
+struct MANGOS_DLL_DECL mob_toc5_risen_ghoulAI : public ScriptedAI
+{
+ mob_toc5_risen_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Attack;
+
+ void Reset()
+ {
+ Attack = 2500;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Attack < diff)
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_BLACK_KNIGHT))))
+ if (pTemp->isAlive())
+ if ((pTemp->GetHealth()*100 / pTemp->GetMaxHealth()) < 25)
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLODE : SPELL_EXPLODE_H);
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 4))
+ {
+ DoCast(m_creature->getVictim(), SPELL_CLAW);
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
+ m_creature->AI()->AttackStart(target);
+ Attack = 2500;
+ }else
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 30))
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_LEAP : SPELL_LEAP_H);
+ Attack = 2500;
+ }
+ }else Attack -= diff;
+
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25)
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLODE : SPELL_EXPLODE_H);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_toc5_risen_ghoul(Creature* pCreature)
+{
+ return new mob_toc5_risen_ghoulAI(pCreature);
+}
+
+// The Black Knight
+struct MANGOS_DLL_DECL boss_black_knightAI : public ScriptedAI
+{
+ boss_black_knightAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Plague_Strike_Timer;
+ uint32 Icy_Touch_Timer;
+ uint32 Obliterate_Timer;
+ uint32 Choke_Timer;
+ uint32 Death_Timer;
+ uint32 Mark_Timer;
+ uint32 Phase_Delay;
+ uint32 Summon_Ghoul;
+ uint32 m_uiBerserk_Timer;
+ bool phase1;
+ bool phase2;
+ bool phase3;
+ bool ghoul;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->SetDisplayId(29837);
+ SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ Plague_Strike_Timer = m_bIsRegularMode ? 5000 : 4000;
+ Icy_Touch_Timer = m_bIsRegularMode ? 10000 : 7000;
+ Obliterate_Timer = m_bIsRegularMode ? 16000 : 10000;
+ Choke_Timer = 15000;
+ Summon_Ghoul = 4000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ phase1 = true;
+ phase2 = false;
+ phase3 = false;
+ ghoul = false;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ if (m_pInstance->GetData(TYPE_BLACK_KNIGHT) != DONE)
+ m_pInstance->SetData(TYPE_BLACK_KNIGHT, IN_PROGRESS);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if ((uiDamage > m_creature->GetHealth() ||
+ m_creature->GetHealth()/m_creature->GetHealth() <= 0.1 ) && !phase3){
+ uiDamage = 0;
+ if (phase2)
+ StartPhase3();
+ if (phase1)
+ StartPhase2();
+ }
+ }
+
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+ if (phase3 && !phase1 && !phase2)
+ {
+ m_pInstance->SetData(TYPE_BLACK_KNIGHT, DONE);
+ }
+/* if (phase2 && !phase1 && !phase3)
+ if (!m_creature->isAlive())
+ {
+ m_creature->Respawn();
+ StartPhase3();
+ }
+ if (phase1 && !phase2 && !phase3)
+ if (!m_creature->isAlive())
+ {
+ m_creature->Respawn();
+ StartPhase2();
+ }*/
+ }
+
+ void StartPhase2()
+ {
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetDisplayId(27550);
+ phase1 = false;
+ phase2 = true;
+ phase3 = false;
+ DoCast(m_creature, SPELL_ARMY);
+ Plague_Strike_Timer = m_bIsRegularMode ? 14000 : 8000;
+ Icy_Touch_Timer = m_bIsRegularMode ? 12000 : 7000;
+ Obliterate_Timer = m_bIsRegularMode ? 18000 : 10000;
+ }
+
+ void StartPhase3()
+ {
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetDisplayId(14560);
+ SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ phase1 = false;
+ phase2 = false;
+ phase3 = true;
+ Death_Timer = m_bIsRegularMode ? 5000 : 3000;
+ Mark_Timer = m_bIsRegularMode ? 9000 : 7000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Plague_Strike_Timer < diff && !phase3)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_PLAGUE_STRIKE : SPELL_PLAGUE_STRIKE_H);
+ Plague_Strike_Timer = m_bIsRegularMode ? 10500 : 7000;
+ }else Plague_Strike_Timer -= diff;
+
+ if (Icy_Touch_Timer < diff && !phase3)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ICY_TOUCH : SPELL_ICY_TOUCH_H);
+ Icy_Touch_Timer = m_bIsRegularMode ? 10000 : 8000;
+ }else Icy_Touch_Timer -= diff;
+
+ if (Obliterate_Timer < diff && !phase3)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_OBLITERATE : SPELL_OBLITERATE_H);
+ Obliterate_Timer = m_bIsRegularMode ? 11000 : 8000;
+ }else Obliterate_Timer -= diff;
+
+ if (Choke_Timer < diff && phase1)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
+ DoCast(m_creature->getVictim(), SPELL_CHOKE);
+ Choke_Timer = m_bIsRegularMode ? 15000 : 10000;
+ }else Choke_Timer -= diff;
+
+ if (Summon_Ghoul < diff && phase1 && !ghoul)
+ {
+ if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == m_pInstance->GetData(DATA_JAEREN))
+ m_creature->SummonCreature(NPC_RISEN_JAEREN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ else
+ m_creature->SummonCreature(NPC_RISEN_ARELAS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ ghoul = true;
+ }else Summon_Ghoul -= diff;
+
+ if (Mark_Timer < diff && phase3)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
+ DoCast(target, SPELL_MARK);
+ Mark_Timer = m_bIsRegularMode ? 15000 : 10000;
+ }else Mark_Timer -= diff;
+
+ if (Death_Timer < diff && phase3)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_DEATH : SPELL_DEATH_H);
+ Death_Timer = 3500;
+ }else Death_Timer -= diff;
+
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_black_knight(Creature* pCreature)
+{
+ return new boss_black_knightAI(pCreature);
+}
+
+void AddSC_boss_black_knight()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "mob_toc5_risen_ghoul";
+ NewScript->GetAI = &GetAI_mob_toc5_risen_ghoul;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_black_knight";
+ NewScript->GetAI = &GetAI_boss_black_knight;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp
index f54a2a9..f986fc4 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp
@@ -1,5 +1,5 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
- * This program is free software; you can redistribute it and/or modify
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
@@ -15,11 +15,734 @@
*/
/* ScriptData
-SDName: grand_champions
-SD%Complete: 0
-SDComment:
-SDCategory: Crusader Coliseum, Trial of the Champion
+SDName: boss_grand_champions
+SD%Complete: 70%
+SDComment: missing yells. hunter AI sucks. no pvp diminuishing returns(is it DB related?). modified by /dev/rsa
+SDCategory: Trial Of the Champion
EndScriptData */
#include "precompiled.h"
#include "trial_of_the_champion.h"
+
+enum
+{
+ //common
+ SPELL_BERSERK = 47008,
+ //yells
+ //warrior
+ SPELL_MORTAL_STRIKE = 68783,
+ SPELL_MORTAL_STRIKE_H = 68784,
+ SPELL_BLADESTORM = 63784,
+ SPELL_INTERCEPT = 67540,
+ SPELL_ROLLING_THROW = 47115, //need core support for spell 67546, using 47115 instead
+ //mage
+ SPELL_FIREBALL = 66042,
+ SPELL_FIREBALL_H = 68310,
+ SPELL_BLAST_WAVE = 66044,
+ SPELL_BLAST_WAVE_H = 68312,
+ SPELL_HASTE = 66045,
+ SPELL_POLYMORPH = 66043,
+ SPELL_POLYMORPH_H = 68311,
+ //shaman
+ SPELL_CHAIN_LIGHTNING = 67529,
+ SPELL_CHAIN_LIGHTNING_H = 68319,
+ SPELL_EARTH_SHIELD = 67530,
+ SPELL_HEALING_WAVE = 67528,
+ SPELL_HEALING_WAVE_H = 68318,
+ SPELL_HEX_OF_MENDING = 67534,
+ //hunter
+ SPELL_DISENGAGE = 68340,
+ SPELL_LIGHTNING_ARROWS = 66083,
+ SPELL_MULTI_SHOT = 66081,
+ SPELL_SHOOT = 66079,
+ //rogue
+ SPELL_EVISCERATE = 67709,
+ SPELL_EVISCERATE_H = 68317,
+ SPELL_FAN_OF_KNIVES = 67706,
+ SPELL_POISON_BOTTLE = 67701
+};
+
+// Warrior
+struct MANGOS_DLL_DECL mob_toc5_warriorAI : public ScriptedAI
+{
+ mob_toc5_warriorAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Mortal_Strike_Timer;
+ uint32 Bladestorm_Timer;
+ uint32 Rolling_Throw_Timer;
+ uint32 Intercept_Cooldown;
+ uint32 intercept_check;
+ uint32 m_uiBerserk_Timer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ Mortal_Strike_Timer = m_bIsRegularMode ? 9000 : 6000;
+ Bladestorm_Timer = m_bIsRegularMode ? 30000 : 20000;
+ Rolling_Throw_Timer = m_bIsRegularMode ? 45000 : 30000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ Intercept_Cooldown = 0;
+ intercept_check = 1000;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+
+ }
+
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ else
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1);
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) {
+ m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Mortal_Strike_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_MORTAL_STRIKE : SPELL_MORTAL_STRIKE_H);
+ Mortal_Strike_Timer = m_bIsRegularMode ? 6000 : 4000;
+ }else Mortal_Strike_Timer -= diff;
+
+ if (Rolling_Throw_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_ROLLING_THROW);
+ Rolling_Throw_Timer = m_bIsRegularMode ? 30000 : 15000;
+ }else Rolling_Throw_Timer -= diff;
+
+ if (Bladestorm_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BLADESTORM);
+ Bladestorm_Timer = m_bIsRegularMode ? 60000 : 20000;
+ }else Bladestorm_Timer -= diff;
+
+ if (intercept_check < diff)
+ {
+ if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 25) && Intercept_Cooldown < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_INTERCEPT);
+ Intercept_Cooldown = m_bIsRegularMode ? 15000 : 10000;
+ }
+ intercept_check = 1000;
+ }
+ else
+ {
+ intercept_check -= diff;
+ Intercept_Cooldown -= diff;
+ }
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_toc5_warrior(Creature* pCreature)
+{
+ return new mob_toc5_warriorAI(pCreature);
+}
+
+// Mage
+struct MANGOS_DLL_DECL mob_toc5_mageAI : public ScriptedAI
+{
+ mob_toc5_mageAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Fireball_Timer;
+ uint32 Blast_Wave_Timer;
+ uint32 Haste_Timer;
+ uint32 Polymorph_Timer;
+ uint32 m_uiBerserk_Timer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ Fireball_Timer = 0;
+ Blast_Wave_Timer = m_bIsRegularMode ? 20000 : 12000;
+ Haste_Timer = m_bIsRegularMode ? 12000 : 9000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ Polymorph_Timer = m_bIsRegularMode ? 12000 : 10000;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ else
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1);
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) {
+ m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Fireball_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FIREBALL : SPELL_FIREBALL_H);
+ Fireball_Timer = m_bIsRegularMode ? 5000 : 3000;
+ }else Fireball_Timer -= diff;
+
+ if (Blast_Wave_Timer < diff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_BLAST_WAVE : SPELL_BLAST_WAVE_H);
+ Blast_Wave_Timer = m_bIsRegularMode ? 20000 : 12000;
+ }else Blast_Wave_Timer -= diff;
+
+ if (Haste_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_HASTE);
+ Haste_Timer = m_bIsRegularMode ? 10000 : 8000;
+ }else Haste_Timer -= diff;
+
+ if (Polymorph_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(target, m_bIsRegularMode ? SPELL_POLYMORPH : SPELL_POLYMORPH_H);
+ Polymorph_Timer = m_bIsRegularMode ? 20000 : 15000;
+ }else Polymorph_Timer -= diff;
+
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_toc5_mage(Creature* pCreature)
+{
+ return new mob_toc5_mageAI(pCreature);
+}
+
+// Shaman
+struct MANGOS_DLL_DECL mob_toc5_shamanAI : public ScriptedAI
+{
+ mob_toc5_shamanAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Chain_Lightning_Timer;
+ uint32 Earth_Shield_Timer;
+ uint32 Healing_Wave_Timer;
+ uint32 Hex_Timer;
+
+ float mob1_health;
+ float mob2_health;
+ float mob3_health;
+ uint32 m_uiBerserk_Timer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ Chain_Lightning_Timer = m_bIsRegularMode ? 2000 : 1000;
+ Earth_Shield_Timer = m_bIsRegularMode ? 10000 : 5000;
+ Healing_Wave_Timer = m_bIsRegularMode ? 20000 : 12000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ Hex_Timer = m_bIsRegularMode ? 15000 : 10000;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ else
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1);
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) {
+ m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Chain_Lightning_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H);
+ Chain_Lightning_Timer = m_bIsRegularMode ? 12000 : 8000;
+ }else Chain_Lightning_Timer -= diff;
+
+ if (Hex_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_HEX_OF_MENDING);
+ Hex_Timer = m_bIsRegularMode ? 30000 : 20000;
+ }else Hex_Timer -= diff;
+
+ if (Healing_Wave_Timer < diff)
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ if (pTemp->isAlive())
+ mob1_health = pTemp->GetHealth()*100 / pTemp->GetMaxHealth();
+ else
+ mob1_health = 100;
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ if (pTemp->isAlive())
+ mob2_health = pTemp->GetHealth()*100 / pTemp->GetMaxHealth();
+ else
+ mob2_health = 100;
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ if (pTemp->isAlive())
+ mob3_health = pTemp->GetHealth()*100 / pTemp->GetMaxHealth();
+ else
+ mob3_health = 100;
+ if (mob1_health < mob2_health && mob1_health < mob3_health && mob1_health < 70)
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ DoCast(pTemp, m_bIsRegularMode ? SPELL_HEALING_WAVE : SPELL_HEALING_WAVE_H);
+ if (mob1_health > mob2_health && mob2_health < mob3_health && mob2_health < 70)
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ DoCast(pTemp, m_bIsRegularMode ? SPELL_HEALING_WAVE : SPELL_HEALING_WAVE_H);
+ if (mob3_health < mob2_health && mob1_health > mob3_health && mob3_health < 70)
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ DoCast(pTemp, m_bIsRegularMode ? SPELL_HEALING_WAVE : SPELL_HEALING_WAVE_H);
+ Healing_Wave_Timer = m_bIsRegularMode ? 8000 : 6000;
+ }else Healing_Wave_Timer -= diff;
+
+ if (Earth_Shield_Timer < diff)
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ if (pTemp->isAlive())
+ DoCast(pTemp, SPELL_EARTH_SHIELD);
+ else
+ DoCast(m_creature, SPELL_EARTH_SHIELD);
+ break;
+ case 1:
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ if (pTemp->isAlive())
+ DoCast(pTemp, SPELL_EARTH_SHIELD);
+ else
+ DoCast(m_creature, SPELL_EARTH_SHIELD);
+ break;
+ case 2:
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ if (pTemp->isAlive())
+ DoCast(pTemp, SPELL_EARTH_SHIELD);
+ else
+ DoCast(m_creature, SPELL_EARTH_SHIELD);
+ break;
+ }
+ Earth_Shield_Timer = m_bIsRegularMode ? 35000 : 25000;
+ }else Earth_Shield_Timer -= diff;
+
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_toc5_shaman(Creature* pCreature)
+{
+ return new mob_toc5_shamanAI(pCreature);
+}
+
+// Hunter
+struct MANGOS_DLL_DECL mob_toc5_hunterAI : public ScriptedAI
+{
+ mob_toc5_hunterAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Shoot_Timer;
+ uint32 Lightning_Arrows_Timer;
+ uint32 Multi_Shot_Timer;
+ uint32 Disengage_Cooldown;
+ uint32 enemy_check;
+ uint32 disengage_check;
+ uint32 m_uiBerserk_Timer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ Shoot_Timer = 0;
+ Lightning_Arrows_Timer = m_bIsRegularMode ? 18000 : 10000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ Multi_Shot_Timer = m_bIsRegularMode ? 15000 : 8000;
+ Disengage_Cooldown = 0;
+ enemy_check = 1000;
+ disengage_check;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ else
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1);
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) {
+ m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (enemy_check < diff)
+ {
+ if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 30))
+ {
+ m_creature->SetSpeedRate(MOVE_RUN, 0.0001);
+ }
+ else
+ {
+ m_creature->SetSpeedRate(MOVE_RUN, 1.2);
+ }
+ enemy_check = 100;
+ }else enemy_check -= diff;
+
+ if (Disengage_Cooldown>0)
+ Disengage_Cooldown -= diff;
+
+ if (Shoot_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_SHOOT);
+ Shoot_Timer = m_bIsRegularMode ? 5000 : 3000;
+ }else Shoot_Timer -= diff;
+
+ if (Multi_Shot_Timer < diff)
+ {
+ m_creature->CastStop(SPELL_SHOOT);
+ DoCast(m_creature->getVictim(), SPELL_MULTI_SHOT);
+ Multi_Shot_Timer = m_bIsRegularMode ? 10000 : 5000;
+ }else Multi_Shot_Timer -= diff;
+
+ if (Lightning_Arrows_Timer < diff)
+ {
+ m_creature->CastStop(SPELL_SHOOT);
+ DoCast(m_creature, SPELL_LIGHTNING_ARROWS);
+ Lightning_Arrows_Timer = m_bIsRegularMode ? 15000 : 8000;
+ }else Lightning_Arrows_Timer -= diff;
+
+ if (disengage_check < diff)
+ {
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 5) && Disengage_Cooldown == 0)
+ {
+ DoCast(m_creature, SPELL_DISENGAGE);
+ Disengage_Cooldown = m_bIsRegularMode ? 15000 : 10000;
+ }
+ disengage_check = 1000;
+ }else disengage_check -= diff;
+
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_toc5_hunter(Creature* pCreature)
+{
+ return new mob_toc5_hunterAI(pCreature);
+}
+
+// Rogue
+struct MANGOS_DLL_DECL mob_toc5_rogueAI : public ScriptedAI
+{
+ mob_toc5_rogueAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Eviscerate_Timer;
+ uint32 FoK_Timer;
+ uint32 Poison_Timer;
+ uint32 m_uiBerserk_Timer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ Eviscerate_Timer = m_bIsRegularMode ? 20000 : 10000;
+ FoK_Timer = m_bIsRegularMode ? 15000 : 10000;
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ Poison_Timer = m_bIsRegularMode ? 12000 : 5000;
+ m_creature->GetMotionMaster()->MovePoint(0, 746, 614, m_creature->GetPositionZ());
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+ else
+ {
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+// m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ m_pInstance->SetData(DATA_CHAMPIONS_COUNT, m_pInstance->GetData(DATA_CHAMPIONS_COUNT) - 1);
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ if (m_pInstance->GetData(DATA_CHAMPIONS_COUNT) < 1) {
+ m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_1))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_2))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (Creature* pTemp = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_CHAMPION_3))))
+ pTemp->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Eviscerate_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_EVISCERATE : SPELL_EVISCERATE_H);
+ Eviscerate_Timer = m_bIsRegularMode ? 15000 : 10000;
+ }else Eviscerate_Timer -= diff;
+
+ if (FoK_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_FAN_OF_KNIVES);
+ FoK_Timer = m_bIsRegularMode ? 12000 : 7000;
+ }else FoK_Timer -= diff;
+
+ if (Poison_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
+ DoCast(m_creature, SPELL_POISON_BOTTLE);
+ Poison_Timer = m_bIsRegularMode ? 10000 : 5000;
+ }else Poison_Timer -= diff;
+
+ if (m_uiBerserk_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = m_bIsRegularMode ? 300000 : 180000;
+ }
+ else m_uiBerserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_toc5_rogue(Creature* pCreature)
+{
+ return new mob_toc5_rogueAI(pCreature);
+}
+
+void AddSC_boss_grand_champions()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "mob_toc5_warrior";
+ NewScript->GetAI = &GetAI_mob_toc5_warrior;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_toc5_mage";
+ NewScript->GetAI = &GetAI_mob_toc5_mage;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_toc5_shaman";
+ NewScript->GetAI = &GetAI_mob_toc5_shaman;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_toc5_hunter";
+ NewScript->GetAI = &GetAI_mob_toc5_hunter;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_toc5_rogue";
+ NewScript->GetAI = &GetAI_mob_toc5_rogue;
+ NewScript->RegisterSelf();
+}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp
index 6fc6932..f6c756f 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp
@@ -1,31 +1,555 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
/* ScriptData
-SDName: instance_trial_of_the_champion
-SD%Complete: 0
-SDComment:
-SDCategory: Crusader Coliseum, Trial of the Champion
+SDName: Instance_Trial_Of_the_Champion
+SD%Complete: 70
+SDComment: modified by /dev/rsa
+SDCategory: Trial Of the Champion
EndScriptData */
#include "precompiled.h"
#include "trial_of_the_champion.h"
+#include "World.h"
-/* Trial of the Champion encounters:
-0 - Grand Champions
-1 - Argent Champion
-2 - Black Knight
-*/
+enum PhaseControl
+{
+ HORDE_CONTROL_PHASE_SHIFT_1 = 55773,
+ HORDE_CONTROL_PHASE_SHIFT_2 = 60028,
+ ALLIANCE_CONTROL_PHASE_SHIFT_1 = 55774,
+ ALLIANCE_CONTROL_PHASE_SHIFT_2 = 60027,
+};
+struct MANGOS_DLL_DECL instance_trial_of_the_champion : public ScriptedInstance
+{
+ instance_trial_of_the_champion(Map* pMap) : ScriptedInstance(pMap) { Initialize(); }
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER+1];
+
+ std::string m_strInstData;
+
+ uint64 m_uiJacobGUID;
+ uint64 m_uiAmbroseGUID;
+ uint64 m_uiColososGUID;
+ uint64 m_uiJaelyneGUID;
+ uint64 m_uiLanaGUID;
+ uint64 m_uiMokraGUID;
+ uint64 m_uiEresseaGUID;
+ uint64 m_uiRunokGUID;
+ uint64 m_uiZultoreGUID;
+ uint64 m_uiVisceriGUID;
+ uint64 m_uiChampionsLootGUID;
+ uint64 m_uiEadricGUID;
+ uint64 m_uiEadricLootGUID;
+ uint64 m_uiPaletressGUID;
+ uint64 m_uiPaletressLootGUID;
+ uint64 m_uiBlackKnightGUID;
+ uint64 m_uiJaerenGUID;
+ uint64 m_uiArelasGUID;
+ uint64 m_uiAnnouncerGUID;
+ uint32 m_uiChampionId1;
+ uint32 m_uiChampionId2;
+ uint32 m_uiChampionId3;
+ uint32 m_uiChampionsCount;
+ uint64 m_uiChampion1;
+ uint64 m_uiChampion2;
+ uint64 m_uiChampion3;
+ uint64 m_uiBlackKnightMinionGUID;
+ uint64 m_uiArgentChallenger;
+ uint64 m_uiArgentChallengerID;
+ uint64 m_uiMemoryGUID;
+
+ void Initialize()
+ {
+ m_uiJacobGUID = 0;
+ m_uiAmbroseGUID = 0;
+ m_uiColososGUID = 0;
+ m_uiJaelyneGUID = 0;
+ m_uiLanaGUID = 0;
+ m_uiMokraGUID = 0;
+ m_uiEresseaGUID = 0;
+ m_uiRunokGUID = 0;
+ m_uiZultoreGUID = 0;
+ m_uiVisceriGUID = 0;
+ m_uiChampionsLootGUID = 0;
+ m_uiEadricGUID = 0;
+ m_uiEadricLootGUID = 0;
+ m_uiPaletressGUID = 0;
+ m_uiPaletressLootGUID = 0;
+ m_uiBlackKnightGUID = 0;
+ m_uiJaerenGUID = 0;
+ m_uiArelasGUID = 0;
+ m_uiAnnouncerGUID = 0;
+ m_uiBlackKnightMinionGUID = 0;
+ m_uiChampionId1 = 0;
+ m_uiChampionId2 = 0;
+ m_uiChampionId3 = 0;
+ m_uiChampion1 = 0;
+ m_uiChampion2 = 0;
+ m_uiChampion3 = 0;
+ m_uiChampionsCount = 3;
+ m_uiArgentChallenger = 0;
+ m_uiMemoryGUID = 0;
+ m_uiArgentChallengerID = 0;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+
+ void OnPlayerEnter(Player *pPlayer)
+ {
+ //if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP)) return;
+
+ switch (pPlayer->GetTeam())
+ {
+ case ALLIANCE:
+ if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(HORDE_CONTROL_PHASE_SHIFT_1))
+ pPlayer->RemoveAurasDueToSpell(HORDE_CONTROL_PHASE_SHIFT_1);
+ pPlayer->CastSpell(pPlayer, HORDE_CONTROL_PHASE_SHIFT_2, false);
+ break;
+ case HORDE:
+ if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(ALLIANCE_CONTROL_PHASE_SHIFT_1))
+ pPlayer->RemoveAurasDueToSpell(ALLIANCE_CONTROL_PHASE_SHIFT_1);
+ pPlayer->CastSpell(pPlayer, ALLIANCE_CONTROL_PHASE_SHIFT_2, false);
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* pCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ // Champions of the Alliance
+ case NPC_JACOB:
+ m_uiJacobGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_AMBROSE:
+ m_uiAmbroseGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_COLOSOS:
+ m_uiColososGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_JAELYNE:
+ m_uiJaelyneGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_LANA:
+ m_uiLanaGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+
+ // Champions of the Horde
+ case NPC_MOKRA:
+ m_uiMokraGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_ERESSEA:
+ m_uiEresseaGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_RUNOK:
+ m_uiRunokGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_ZULTORE:
+ m_uiZultoreGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+ case NPC_VISCERI:
+ m_uiVisceriGUID = pCreature->GetGUID();
+ if (m_uiChampion1 == 0)
+ m_uiChampion1 = pCreature->GetGUID();
+ else
+ if (m_uiChampion2 == 0)
+ m_uiChampion2 = pCreature->GetGUID();
+ else
+ if (m_uiChampion3 == 0)
+ m_uiChampion3 = pCreature->GetGUID();
+ break;
+
+ // Argent Challenge
+ case NPC_EADRIC:
+ m_uiEadricGUID = pCreature->GetGUID();
+ m_uiArgentChallenger = pCreature->GetGUID();
+ break;
+ case NPC_PALETRESS:
+ m_uiPaletressGUID = pCreature->GetGUID();
+ m_uiArgentChallenger = pCreature->GetGUID();
+ break;
+
+ // Black Knight
+ case NPC_BLACK_KNIGHT:
+ m_uiBlackKnightGUID = pCreature->GetGUID();
+ break;
+ case NPC_RISEN_JAEREN:
+ m_uiBlackKnightMinionGUID = pCreature->GetGUID();
+ break;
+ case NPC_RISEN_ARELAS:
+ m_uiBlackKnightMinionGUID = pCreature->GetGUID();
+ break;
+
+ // Coliseum Announcers
+ case NPC_JAEREN:
+ m_uiJaerenGUID = pCreature->GetGUID();
+ break;
+ case NPC_ARELAS:
+ m_uiArelasGUID = pCreature->GetGUID();
+ break;
+
+ // memories
+ case MEMORY_ALGALON:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_ARCHIMONDE:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_CHROMAGGUS:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_CYANIGOSA:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_DELRISSA:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_ECK:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_ENTROPIUS:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_GRUUL:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_HAKKAR:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_HEIGAN:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_HEROD:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_HOGGER:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_IGNIS:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_ILLIDAN:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_INGVAR:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_KALITHRESH:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_LUCIFRON:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_MALCHEZAAR:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_MUTANUS:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_ONYXIA:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_THUNDERAAN:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_VANCLEEF:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_VASHJ:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_VEKNILASH:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ case MEMORY_VEZAX:
+ m_uiMemoryGUID = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void OnObjectCreate(GameObject *pGo)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_CHAMPIONS_LOOT:
+ m_uiChampionsLootGUID = pGo->GetGUID();
+ break;
+ case GO_EADRIC_LOOT:
+ m_uiEadricLootGUID = pGo->GetGUID();
+ break;
+ case GO_PALETRESS_LOOT:
+ m_uiPaletressLootGUID = pGo->GetGUID();
+ break;
+ case GO_CHAMPIONS_LOOT_H:
+ m_uiChampionsLootGUID = pGo->GetGUID();
+ break;
+ case GO_EADRIC_LOOT_H:
+ m_uiEadricLootGUID = pGo->GetGUID();
+ break;
+ case GO_PALETRESS_LOOT_H:
+ m_uiPaletressLootGUID = pGo->GetGUID();
+ break;
+ }
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ switch(uiType)
+ {
+ case DATA_TOC5_ANNOUNCER:
+ m_uiAnnouncerGUID = uiData;
+ break;
+ case DATA_CHAMPIONID_1:
+ m_uiChampionId1 = uiData;
+ break;
+ case DATA_CHAMPIONID_2:
+ m_uiChampionId2 = uiData;
+ break;
+ case DATA_CHAMPIONID_3:
+ m_uiChampionId3 = uiData;
+ break;
+ case DATA_CHAMPIONS_COUNT:
+ m_uiChampionsCount = uiData;
+ break;
+ case DATA_ARGENT_CHALLENGER:
+ m_uiArgentChallengerID = uiData;
+ break;
+ case DATA_BLACK_KNIGHT_MINION:
+ m_uiBlackKnightMinionGUID = uiData;
+ break;
+ case TYPE_GRAND_CHAMPIONS:
+ m_auiEncounter[0] = uiData;
+ if (uiData == DONE)
+ {
+ if (GameObject* pChest = instance->GetGameObject(m_uiChampionsLootGUID))
+ if (pChest && !pChest->isSpawned())
+ pChest->SetRespawnTime(DAY);
+ }
+ if (uiData == FAIL)
+ {
+ m_auiEncounter[0] = NOT_STARTED;
+ }
+ break;
+ case TYPE_ARGENT_CHALLENGE:
+ m_auiEncounter[1] = uiData;
+ if (uiData == DONE)
+ {
+ if (m_uiArgentChallenger == m_uiEadricGUID)
+ if (GameObject* pChest = instance->GetGameObject(m_uiEadricLootGUID))
+ if (pChest && !pChest->isSpawned())
+ pChest->SetRespawnTime(DAY);
+ if (m_uiArgentChallenger == m_uiPaletressGUID)
+ if (GameObject* pChest = instance->GetGameObject(m_uiPaletressLootGUID))
+ if (pChest && !pChest->isSpawned())
+ pChest->SetRespawnTime(DAY);
+ }
+ if (uiData == FAIL)
+ {
+ m_auiEncounter[1] = NOT_STARTED;
+ }
+ break;
+ case TYPE_BLACK_KNIGHT:
+ m_auiEncounter[2] = uiData;
+ if (uiData == FAIL)
+ {
+ m_auiEncounter[2] = NOT_STARTED;
+ }
+ break;
+ }
+
+ if (uiData == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ m_strInstData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case DATA_CHAMPION_1:
+ return m_uiChampion1;
+ case DATA_CHAMPION_2:
+ return m_uiChampion2;
+ case DATA_CHAMPION_3:
+ return m_uiChampion3;
+ case DATA_MEMORY:
+ return m_uiMemoryGUID;
+ case DATA_ARGENT_CHALLENGER:
+ return m_uiArgentChallenger;
+ case DATA_BLACK_KNIGHT:
+ return m_uiBlackKnightGUID;
+ }
+
+ return 0;
+ }
+
+ uint32 GetData(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case DATA_CHAMPIONID_1:
+ return m_uiChampionId1;
+ case DATA_CHAMPIONID_2:
+ return m_uiChampionId2;
+ case DATA_CHAMPIONID_3:
+ return m_uiChampionId3;
+ case DATA_CHAMPIONS_COUNT:
+ return m_uiChampionsCount;
+ case DATA_ARGENT_CHALLENGER:
+ return m_uiArgentChallengerID;
+ case DATA_BLACK_KNIGHT_MINION:
+ return m_uiBlackKnightMinionGUID;
+ case DATA_TOC5_ANNOUNCER:
+ return m_uiAnnouncerGUID;
+ case DATA_JAEREN:
+ return m_uiJaerenGUID;
+ case DATA_ARELAS:
+ return m_uiArelasGUID;
+ case TYPE_GRAND_CHAMPIONS: return m_auiEncounter[0];
+ case TYPE_ARGENT_CHALLENGE: return m_auiEncounter[1];
+ case TYPE_BLACK_KNIGHT: return m_auiEncounter[2];
+ }
+
+ return 0;
+ }
+
+ const char* Save()
+ {
+ return m_strInstData.c_str();
+ }
+
+ void Load(const char* strIn)
+ {
+ if (!strIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(strIn);
+
+ std::istringstream loadStream(strIn);
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
+
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_trial_of_the_champion(Map* pMap)
+{
+ return new instance_trial_of_the_champion(pMap);
+}
+
+void AddSC_instance_trial_of_the_champion()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_trial_of_the_champion";
+ newscript->GetInstanceData = &GetInstanceData_instance_trial_of_the_champion;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp
index 454af4d..7226fac 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,11 +15,235 @@
*/
/* ScriptData
-SDName: trial_of_the_champion
-SD%Complete: 0
-SDComment:
-SDCategory: Crusader Coliseum, Trial of the Champion
+SDName: Trial Of the Champion
+SD%Complete: 80%
+SDComment: event script. modified by /dev/rsa
+SDCategory: trial_of_the_champion
EndScriptData */
+/* ContentData
+npc_toc5_announcer
+EndContentData */
+
#include "precompiled.h"
#include "trial_of_the_champion.h"
+
+#define GOSSIP_START_EVENT "Im ready for the next challenge."
+
+/*######
+## npc_toc5_announcer
+######*/
+struct _Messages
+{
+ char const* name;
+ uint32 id;
+ bool state;
+ uint32 encounter;
+};
+
+static _Messages _GossipMessage[]=
+{
+{"Sind Sie bereit gegen die Champions der gegnerischen Fraktion zu kämpfen?",GOSSIP_ACTION_INFO_DEF+1,false,TYPE_GRAND_CHAMPIONS}, //
+{"Sind Sie bereit gegen den Meister der Argentumdämmerung zu kämpfen?",GOSSIP_ACTION_INFO_DEF+2,false,TYPE_ARGENT_CHALLENGE}, //
+{"Sind Sie bereit gegen den schwarzen Ritter zu kämpfen?",GOSSIP_ACTION_INFO_DEF+3,false,TYPE_BLACK_KNIGHT}, //
+{"Es besteht eine Notwendigkeit hier herumzulungern. Heute ist die Arena geschlossen.",GOSSIP_ACTION_INFO_DEF+4,true,TYPE_BLACK_KNIGHT}, //
+};
+
+struct MANGOS_DLL_DECL npc_toc5_announcerAI : public ScriptedAI
+{
+ npc_toc5_announcerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+ }
+};
+
+CreatureAI* GetAI_npc_toc5_announcer(Creature* pCreature)
+{
+ return new npc_toc5_announcerAI(pCreature);
+}
+
+bool GossipHello_npc_toc5_announcer(Player* pPlayer, Creature* pCreature)
+{
+
+ ScriptedInstance* m_pInstance;
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+
+ if (!m_pInstance) return false;
+
+ if(!pPlayer->getAttackers().empty()) return true;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER+1; i++) {
+ if (!_GossipMessage[i].state && (m_pInstance->GetData(_GossipMessage[i].encounter) == NOT_STARTED || m_pInstance->GetData(_GossipMessage[i].encounter) == IN_PROGRESS))
+ {pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _GossipMessage[i].name, GOSSIP_SENDER_MAIN,_GossipMessage[i].id);
+ break;
+ }
+ if (_GossipMessage[i].state && m_pInstance->GetData(_GossipMessage[i].encounter) == DONE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _GossipMessage[i].name, GOSSIP_SENDER_MAIN,_GossipMessage[i].id);
+ };
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_toc5_announcer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance* m_pInstance;
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+
+pPlayer->CLOSE_GOSSIP_MENU();
+
+switch(uiAction) {
+ case GOSSIP_ACTION_INFO_DEF+1: {
+ if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == 0) {
+ m_pInstance->SetData(DATA_TOC5_ANNOUNCER, pCreature->GetGUID());
+
+ if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == m_pInstance->GetData(DATA_ARELAS))
+ {
+ m_pInstance->SetData(DATA_BLACK_KNIGHT_MINION, 35564);
+ switch(urand(0, 4))
+ {
+ case 0: m_pInstance->SetData(DATA_CHAMPIONID_1, 35572); break;
+ case 1: m_pInstance->SetData(DATA_CHAMPIONID_1, 35569); break;
+ case 2: m_pInstance->SetData(DATA_CHAMPIONID_1, 35571); break;
+ case 3: m_pInstance->SetData(DATA_CHAMPIONID_1, 35570); break;
+ case 4: m_pInstance->SetData(DATA_CHAMPIONID_1, 35617); break;
+ };
+ do{
+ switch(urand(0, 4))
+ {
+ case 0: m_pInstance->SetData(DATA_CHAMPIONID_2, 35572); break;
+ case 1: m_pInstance->SetData(DATA_CHAMPIONID_2, 35569); break;
+ case 2: m_pInstance->SetData(DATA_CHAMPIONID_2, 35571); break;
+ case 3: m_pInstance->SetData(DATA_CHAMPIONID_2, 35570); break;
+ case 4: m_pInstance->SetData(DATA_CHAMPIONID_2, 35617); break;
+ }
+ } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_2));
+ do{
+ switch(urand(0, 4))
+ {
+ case 0: m_pInstance->SetData(DATA_CHAMPIONID_3, 35572); break;
+ case 1: m_pInstance->SetData(DATA_CHAMPIONID_3, 35569); break;
+ case 2: m_pInstance->SetData(DATA_CHAMPIONID_3, 35571); break;
+ case 3: m_pInstance->SetData(DATA_CHAMPIONID_3, 35570); break;
+ case 4: m_pInstance->SetData(DATA_CHAMPIONID_3, 35617); break;
+ }
+ } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_3) || m_pInstance->GetData(DATA_CHAMPIONID_2) == m_pInstance->GetData(DATA_CHAMPIONID_3));
+ };
+
+ if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == m_pInstance->GetData(DATA_JAEREN))
+ {
+ m_pInstance->SetData(DATA_BLACK_KNIGHT_MINION, 123);
+
+ switch(urand(0, 4))
+ {
+ case 0: m_pInstance->SetData(DATA_CHAMPIONID_1, 34705); break;
+ case 1: m_pInstance->SetData(DATA_CHAMPIONID_1, 34702); break;
+ case 2: m_pInstance->SetData(DATA_CHAMPIONID_1, 34701); break;
+ case 3: m_pInstance->SetData(DATA_CHAMPIONID_1, 34657); break;
+ case 4: m_pInstance->SetData(DATA_CHAMPIONID_1, 34703); break;
+ }
+ do{
+ switch(urand(0, 4))
+ {
+ case 0: m_pInstance->SetData(DATA_CHAMPIONID_2, 34705); break;
+ case 1: m_pInstance->SetData(DATA_CHAMPIONID_2, 34702); break;
+ case 2: m_pInstance->SetData(DATA_CHAMPIONID_2, 34701); break;
+ case 3: m_pInstance->SetData(DATA_CHAMPIONID_2, 34657); break;
+ case 4: m_pInstance->SetData(DATA_CHAMPIONID_2, 34703); break;
+ }
+ } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_2));
+ do{
+ switch(urand(0, 4))
+ {
+ case 0: m_pInstance->SetData(DATA_CHAMPIONID_3, 34705); break;
+ case 1: m_pInstance->SetData(DATA_CHAMPIONID_3, 34702); break;
+ case 2: m_pInstance->SetData(DATA_CHAMPIONID_3, 34701); break;
+ case 3: m_pInstance->SetData(DATA_CHAMPIONID_3, 34657); break;
+ case 4: m_pInstance->SetData(DATA_CHAMPIONID_3, 34703); break;
+ }
+ } while(m_pInstance->GetData(DATA_CHAMPIONID_1) == m_pInstance->GetData(DATA_CHAMPIONID_3) || m_pInstance->GetData(DATA_CHAMPIONID_2) == m_pInstance->GetData(DATA_CHAMPIONID_3));
+
+ };
+
+ switch(urand(0, 1))
+ {
+ case 0: m_pInstance->SetData(DATA_ARGENT_CHALLENGER, 35119); break;
+ case 1: m_pInstance->SetData(DATA_ARGENT_CHALLENGER, 34928); break;
+ };
+ };
+
+ if (m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == NOT_STARTED || m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == IN_PROGRESS)
+ {
+ m_pInstance->SetData(DATA_CHAMPIONS_COUNT, 3);
+ if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_CHAMPION_1)))
+ pTemp->Respawn();
+ else
+ pCreature->SummonCreature(m_pInstance->GetData(DATA_CHAMPIONID_1), 738.665771f, 661.031433f, 412.394623f, 4.698702f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_CHAMPION_2)))
+ pTemp->Respawn();
+ else
+ pCreature->SummonCreature(m_pInstance->GetData(DATA_CHAMPIONID_2), 746.864441f, 660.918762f, 411.695465f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_CHAMPION_3)))
+ pTemp->Respawn();
+ else
+ pCreature->SummonCreature(m_pInstance->GetData(DATA_CHAMPIONID_3), 754.360779f, 660.816162f, 412.395996f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
+ };
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+2: {
+ if ((m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) == NOT_STARTED || m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) == IN_PROGRESS) && m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE)
+ {
+ if (Creature* pTemp = pCreature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ARGENT_CHALLENGER)))
+ pTemp->Respawn();
+ else
+ pCreature->SummonCreature(m_pInstance->GetData(DATA_ARGENT_CHALLENGER), 746.864441f, 660.918762f, 411.695465f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ m_pInstance->SetData(TYPE_ARGENT_CHALLENGE, IN_PROGRESS);
+ };
+
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+3: {
+ if ((m_pInstance->GetData(TYPE_BLACK_KNIGHT) == NOT_STARTED || m_pInstance->GetData(TYPE_BLACK_KNIGHT) == IN_PROGRESS) && m_pInstance->GetData(TYPE_ARGENT_CHALLENGE) == DONE)
+ {
+ pCreature->SummonCreature(NPC_BLACK_KNIGHT, 746.864441f, 660.918762f, 411.695465f, 4.698700f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ pCreature->DealDamage(pCreature, pCreature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_pInstance->SetData(TYPE_BLACK_KNIGHT, IN_PROGRESS);
+ };
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+4: {
+ if (m_pInstance->GetData(TYPE_BLACK_KNIGHT) == DONE) {
+ pCreature->DealDamage(pCreature, pCreature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ };
+ };
+};
+
+ return true;
+}
+
+void AddSC_trial_of_the_champion()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "npc_toc5_announcer";
+ NewScript->GetAI = &GetAI_npc_toc5_announcer;
+ NewScript->pGossipHello = &GossipHello_npc_toc5_announcer;
+ NewScript->pGossipSelect = &GossipSelect_npc_toc5_announcer;
+ NewScript->RegisterSelf();
+}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h
index d90fd44..e8d6338 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h
@@ -1,17 +1,86 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
- * This program is free software licensed under GPL version 2
- * Please see the included DOCS/LICENSE.TXT for more information */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software licensed under GPL version 2
+* Please see the included DOCS/LICENSE.TXT for more information */
-#ifndef DEF_TRIAL_OF_THE_CHAMPION_H
-#define DEF_TRIAL_OF_THE_CHAMPION_H
+#ifndef DEF_TOC_H
+#define DEF_TOC_H
enum
{
- MAX_ENCOUNTER = 3,
+ MAX_ENCOUNTER = 3,
+
+ TYPE_GRAND_CHAMPIONS = 0,
+ TYPE_ARGENT_CHALLENGE = 1,
+ TYPE_BLACK_KNIGHT = 2,
+
+ DATA_CHAMPION_1 = 3,
+ DATA_CHAMPION_2 = 4,
+ DATA_CHAMPION_3 = 5,
+ DATA_BLACK_KNIGHT = 6,
+ DATA_BLACK_KNIGHT_MINION = 7,
+ DATA_TOC5_ANNOUNCER = 8,
+ DATA_JAEREN = 9,
+ DATA_ARELAS = 10,
+ DATA_CHAMPIONID_1 = 11,
+ DATA_CHAMPIONID_2 = 12,
+ DATA_CHAMPIONID_3 = 13,
+ DATA_MEMORY = 14,
+ DATA_ARGENT_CHALLENGER = 15,
+ DATA_CHAMPIONS_COUNT = 16,
+
+ NPC_JACOB = 34705,
+ NPC_AMBROSE = 34702,
+ NPC_COLOSOS = 34701,
+ NPC_JAELYNE = 34657,
+ NPC_LANA = 34703,
+ NPC_MOKRA = 35572,
+ NPC_ERESSEA = 35569,
+ NPC_RUNOK = 35571,
+ NPC_ZULTORE = 35570,
+ NPC_VISCERI = 35617,
+ NPC_EADRIC = 35119,
+ NPC_PALETRESS = 34928,
+ NPC_BLACK_KNIGHT = 35451,
+ NPC_RISEN_JAEREN = 35545,
+ NPC_RISEN_ARELAS = 35564,
+ NPC_JAEREN = 35004,
+
+ NPC_ARELAS = 35005,
+ MEMORY_ALGALON = 35052,
+ MEMORY_ARCHIMONDE = 35041,
+ MEMORY_CHROMAGGUS = 35033,
+ MEMORY_CYANIGOSA = 35046,
+ MEMORY_DELRISSA = 35043,
+ MEMORY_ECK = 35047,
+ MEMORY_ENTROPIUS = 35044,
+ MEMORY_GRUUL = 35039,
+ MEMORY_HAKKAR = 35034,
+ MEMORY_HEIGAN = 35049,
+ MEMORY_HEROD = 35030,
+ MEMORY_HOGGER = 34942,
+ MEMORY_IGNIS = 35050,
+ MEMORY_ILLIDAN = 35042,
+ MEMORY_INGVAR = 35045,
+ MEMORY_KALITHRESH = 35037,
+ MEMORY_LUCIFRON = 35031,
+ MEMORY_MALCHEZAAR = 35038,
+ MEMORY_MUTANUS = 35029,
+ MEMORY_ONYXIA = 35048,
+ MEMORY_THUNDERAAN = 35032,
+ MEMORY_VANCLEEF = 35028,
+ MEMORY_VASHJ = 35040,
+ MEMORY_VEKNILASH = 35036,
+ MEMORY_VEZAX = 35051,
+
+ GO_CHAMPIONS_LOOT = 195709,
+ GO_CHAMPIONS_LOOT_H = 195710,
+ GO_EADRIC_LOOT = 195374,
+ GO_EADRIC_LOOT_H = 195375,
+ GO_PALETRESS_LOOT = 195323,
+ GO_PALETRESS_LOOT_H = 195324,
+
+ DESPAWN_TIME = 300000
- TYPE_GRAND_CHAMPIONS = 0,
- TYPE_ARGENT_CHAMPION = 1,
- TYPE_BLACK_KNIGHT = 2,
};
-#endif
+#endif
\ No newline at end of file
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp
index 7558556..1fc973a 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_anubarak_trial.cpp
@@ -16,52 +16,110 @@
/* ScriptData
SDName: boss_anubarak_trial
-SD%Complete: 0
-SDComment:
+SD%Complete: 70%
+SDComment: by /dev/rsa
SDCategory:
EndScriptData */
+// Anubarak - underground phase partially not worked, timers need correct
+// Burrower - underground phase not implemented, buff not worked.
+// Leecheng Swarm spell not worked - awaiting core support
+// Anubarak spike aura worked only after 9750
+
#include "precompiled.h"
#include "trial_of_the_crusader.h"
-enum
+enum Summons
{
- SAY_AGGRO = -1649064,
- SAY_SLAY_1 = -1649065,
- SAY_SLAY_2 = -1649066,
- SAY_DEATH = -1649067,
- SAY_BERSERK = -1649068,
- SAY_SUBMERGE = -1649069,
- SAY_LEECHING_SWARM = -1649070,
+ NPC_FROST_SPHERE = 34606,
+ NPC_BURROWER = 34607,
+ NPC_SCARAB = 34605,
+ NPC_SPIKE = 34660,
};
-struct MANGOS_DLL_DECL boss_anubarak_trialAI : public ScriptedAI
+enum BossSpells
{
- boss_anubarak_trialAI(Creature* pCreature) : ScriptedAI(pCreature)
+SPELL_COLD = 66013,
+SPELL_MARK = 67574,
+SPELL_LEECHING_SWARM = 66118,
+SPELL_LEECHING_HEAL = 66125,
+SPELL_LEECHING_DAMAGE = 66240,
+SPELL_IMPALE = 65920,
+SPELL_SPIKE_CALL = 66169,
+SPELL_POUND = 66012,
+SPELL_SHOUT = 67730,
+SPELL_SUBMERGE_0 = 53421,
+SPELL_SUBMERGE_1 = 67322,
+SPELL_SUMMON_BEATLES = 66339,
+SPELL_DETERMINATION = 66092,
+SPELL_ACID_MANDIBLE = 67861,
+SPELL_SPIDER_FRENZY = 66129,
+SPELL_EXPOSE_WEAKNESS = 67847,
+SUMMON_SCARAB = NPC_SCARAB,
+SUMMON_BORROWER = NPC_BURROWER,
+SUMMON_FROSTSPHERE = NPC_FROST_SPHERE,
+SPELL_BERSERK = 26662,
+SPELL_PERMAFROST = 66193,
+};
+
+struct MANGOS_DLL_DECL boss_anubarak_trialAI : public BSWScriptedAI
+{
+ boss_anubarak_trialAI(Creature* pCreature) : BSWScriptedAI(pCreature)
{
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
+ uint8 stage;
+ bool intro;
+ Unit* pTarget;
+
+ void Reset() {
+ if(!m_pInstance) return;
+ stage = 0;
+ intro = true;
+ m_creature->SetRespawnDelay(DAY);
+ pTarget = NULL;
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
- void Reset() {}
+
+ void KilledUnit(Unit* pVictim)
+ {
+ DoScriptText(-1713563,m_creature);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!intro) return;
+ DoScriptText(-1713554,m_creature);
+ intro = false;
+ m_creature->SetInCombatWithZone();
+ }
void JustReachedHome()
{
if (m_pInstance)
- m_pInstance->SetData(TYPE_ANUBARAK, NOT_STARTED);
+ m_pInstance->SetData(TYPE_ANUBARAK, FAIL);
+// m_creature->ForcedDespawn();
}
void JustDied(Unit* pKiller)
{
- if (m_pInstance)
+ if (!m_pInstance) return;
+ DoScriptText(-1713564,m_creature);
m_pInstance->SetData(TYPE_ANUBARAK, DONE);
}
void Aggro(Unit* pWho)
{
+ if (!intro) DoScriptText(-1713555,m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetInCombatWithZone();
+ m_pInstance->SetData(TYPE_ANUBARAK, IN_PROGRESS);
}
void UpdateAI(const uint32 uiDiff)
@@ -69,6 +127,66 @@ struct MANGOS_DLL_DECL boss_anubarak_trialAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ switch(stage)
+ {
+ case 0: {
+ timedCast(SPELL_POUND, uiDiff);
+ timedCast(SPELL_COLD, uiDiff);
+ if (timedQuery(SUMMON_BORROWER, uiDiff)) {
+ doCast(SUMMON_BORROWER);
+ DoScriptText(-1713556,m_creature);
+ };
+ if (timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 1;
+
+ break;}
+ case 1: {
+ doCast(SPELL_SUBMERGE_0);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ stage = 2;
+ DoScriptText(-1713557,m_creature);
+ break;}
+ case 2: {
+ if (timedQuery(SPELL_SPIKE_CALL, uiDiff)) {
+ pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0);
+// doCast(SPELL_SPIKE_CALL);
+// This summon not supported in database. Temporary override.
+ Unit* spike = doSummon(NPC_SPIKE,TEMPSUMMON_TIMED_DESPAWN,60000);
+ if (spike) { spike->AddThreat(pTarget, 1000.0f);
+ DoScriptText(-1713558,m_creature,pTarget);
+ doCast(SPELL_MARK,pTarget);
+ spike->GetMotionMaster()->MoveChase(pTarget);
+ }
+ };
+ if (timedQuery(SPELL_SUMMON_BEATLES, uiDiff)) {
+ doCast(SPELL_SUMMON_BEATLES);
+ doCast(SUMMON_SCARAB);
+ DoScriptText(-1713560,m_creature);
+ };
+ if (timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 3;
+ break;}
+ case 3: {
+ stage = 0;
+ DoScriptText(-1713559,m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ doRemove(SPELL_SUBMERGE_0,m_creature);
+ break;}
+ case 4: {
+ doCast(SPELL_LEECHING_SWARM);
+ DoScriptText(-1713561,m_creature);
+ stage = 5;
+ break;}
+ case 5: {
+ timedCast(SPELL_POUND, uiDiff);
+ timedCast(SPELL_COLD, uiDiff);
+ break;}
+
+ }
+ timedCast(SUMMON_FROSTSPHERE, uiDiff);
+
+ timedCast(SPELL_BERSERK, uiDiff);
+
+ if (m_creature->GetHealthPercent() < 30.0f && stage == 0) stage = 4;
+
DoMeleeAttackIfReady();
}
};
@@ -78,6 +196,216 @@ CreatureAI* GetAI_boss_anubarak_trial(Creature* pCreature)
return new boss_anubarak_trialAI(pCreature);
}
+struct MANGOS_DLL_DECL mob_swarm_scarabAI : public BSWScriptedAI
+{
+ mob_swarm_scarabAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) return;
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_DETERMINATION, uiDiff);
+
+ timedCast(SPELL_ACID_MANDIBLE, uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_swarm_scarab(Creature* pCreature)
+{
+ return new mob_swarm_scarabAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_nerubian_borrowerAI : public BSWScriptedAI
+{
+ mob_nerubian_borrowerAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool submerged;
+ Unit* currentTarget;
+
+ void Reset()
+ {
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(DAY);
+ submerged = false;
+ currentTarget = NULL;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) return;
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_EXPOSE_WEAKNESS, uiDiff);
+
+ if (timedQuery(SPELL_SPIDER_FRENZY, uiDiff))
+ if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, NPC_BURROWER, 50.0f))
+ {
+ currentTarget = pTemp;
+ doCast(SPELL_SPIDER_FRENZY);
+ };
+
+ if (m_creature->GetHealthPercent() < 20.0f && timedQuery(SPELL_SUBMERGE_1, uiDiff) && !submerged)
+ {
+ doCast(SPELL_SUBMERGE_1);
+ submerged = true;
+ DoScriptText(-1713557,m_creature);
+ };
+
+ if (m_creature->GetHealthPercent() > 50.0f && submerged)
+ {
+ doRemove(SPELL_SUBMERGE_1,m_creature);
+ submerged = false;
+ DoScriptText(-1713559,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_nerubian_borrower(Creature* pCreature)
+{
+ return new mob_nerubian_borrowerAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_frost_sphereAI : public BSWScriptedAI
+{
+ mob_frost_sphereAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.1f);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MoveRandom();
+ }
+
+ void EnterCombat(Unit* attacker)
+ {
+ doCast(SPELL_PERMAFROST);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+ }
+};
+
+CreatureAI* GetAI_mob_frost_sphere(Creature* pCreature)
+{
+ return new mob_frost_sphereAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_anubarak_spikeAI : public BSWScriptedAI
+{
+ mob_anubarak_spikeAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ Unit* defaultTarget;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5f);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ defaultTarget = NULL;
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ doCast(SPELL_IMPALE);
+ defaultTarget = who;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_ANUBARAK) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+ if (defaultTarget)
+ if (!defaultTarget->isAlive() || !hasAura(SPELL_MARK,defaultTarget))
+ m_creature->ForcedDespawn();
+
+/* if (timedQuery(SPELL_IMPALE,uiDiff)) {
+ if (m_creature->IsWithinDist(m_creature->getVictim(), 4.0f)
+ && !hasAura(SPELL_PERMAFROST,m_creature->getVictim()))
+ {
+ doCast(SPELL_IMPALE);
+ } else doRemove(SPELL_IMPALE);
+ }*/
+ }
+};
+
+CreatureAI* GetAI_mob_anubarak_spike(Creature* pCreature)
+{
+ return new mob_anubarak_spikeAI(pCreature);
+};
+
void AddSC_boss_anubarak_trial()
{
Script* newscript;
@@ -86,4 +414,25 @@ void AddSC_boss_anubarak_trial()
newscript->Name = "boss_anubarak_trial";
newscript->GetAI = &GetAI_boss_anubarak_trial;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_swarm_scarab";
+ newscript->GetAI = &GetAI_mob_swarm_scarab;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_nerubian_borrower";
+ newscript->GetAI = &GetAI_mob_nerubian_borrower;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_anubarak_spike";
+ newscript->GetAI = &GetAI_mob_anubarak_spike;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_sphere";
+ newscript->GetAI = &GetAI_mob_frost_sphere;
+ newscript->RegisterSelf();
+
}
\ No newline at end of file
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp
index 733c5d8..16ae1e7 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_faction_champions.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -11,28 +11,1095 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: faction_champions
-SD%Complete: 0
-SDComment:
+SD%Complete: 60%
+SDComment: Scripts by Selector, modified by /dev/rsa
SDCategory: Crusader Coliseum
EndScriptData */
#include "precompiled.h"
#include "trial_of_the_crusader.h"
-enum
+#define AI_MELEE 0
+#define AI_RANGED 1
+#define AI_HEALER 2
+
+#define SPELL_ANTI_AOE 68595
+#define SPELL_PVP_TRINKET 65547
+
+struct MANGOS_DLL_DECL boss_faction_championsAI : public BSWScriptedAI
+{
+ boss_faction_championsAI(Creature* pCreature, uint32 aitype) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+ mAIType = aitype;
+ Init();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 mAIType;
+ uint32 ThreatTimer;
+ uint32 CCTimer;
+
+ void Init()
+ {
+ CCTimer = rand()%10000;
+ ThreatTimer = 5000;
+ resetTimers();
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_CRUSADERS, FAIL);
+ m_creature->ForcedDespawn();
+ }
+
+ float CalculateThreat(float distance, float armor, uint32 health)
+ {
+ float dist_mod = (mAIType == AI_MELEE) ? 15.0f/(15.0f + distance) : 1.0f;
+ float armor_mod = (mAIType == AI_MELEE) ? armor / 16635.0f : 0.0f;
+ float eh = (health+1) * (1.0f + armor_mod);
+ return dist_mod * 30000.0f / eh;
+ }
+
+ void UpdateThreat()
+ {
+ ThreatList const& tList = m_creature->getThreatManager().getThreatList();
+ ThreatList::const_iterator itr;
+ bool empty = true;
+ for(itr = tList.begin(); itr!=tList.end(); ++itr)
+ {
+ Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());
+ if (pUnit && m_creature->getThreatManager().getThreat(pUnit))
+ {
+ if(pUnit->GetTypeId()==TYPEID_PLAYER)
+ {
+ float threat = CalculateThreat(m_creature->GetDistance2d(pUnit), (float)pUnit->GetArmor(), pUnit->GetHealth());
+ m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);
+ m_creature->AddThreat(pUnit, 1000000.0f * threat);
+ empty = false;
+ }
+ }
+ }
+ }
+
+ void UpdatePower()
+ {
+ if(m_creature->getPowerType() == POWER_MANA)
+ m_creature->ModifyPower(POWER_MANA, m_creature->GetMaxPower(POWER_MANA) / 3);
+ //else if(m_creature->getPowerType() == POWER_ENERGY)
+ // m_creature->ModifyPower(POWER_ENERGY, 100);
+ }
+
+ void RemoveCC()
+ {
+ m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_STUN);
+ m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_FEAR);
+ m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
+ m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_PACIFY);
+ m_creature->RemoveSpellsCausingAura(SPELL_AURA_MOD_CONFUSE);
+ //DoCast(m_creature, SPELL_PVP_TRINKET);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance) m_pInstance->SetData(TYPE_CRUSADERS_COUNT, 0);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!m_pInstance) return;
+ m_pInstance->SetData(TYPE_CRUSADERS, IN_PROGRESS);
+ DoCast(m_creature, SPELL_ANTI_AOE, true);
+ if(who->GetTypeId() != TYPEID_PLAYER)
+ if (Unit* player = doSelectRandomPlayerAtRange(80.0f))
+ m_creature->AddThreat(player, 100.0f);
+ }
+
+ void Reset()
+ {
+ if(m_pInstance) m_pInstance->SetData(TYPE_CRUSADERS, NOT_STARTED);
+ }
+
+ Creature* SelectRandomFriendlyMissingBuff(uint32 spell)
+ {
+ std::list lst = DoFindFriendlyMissingBuff(40.0f, spell);
+ std::list::const_iterator itr = lst.begin();
+ if(lst.empty())
+ return NULL;
+ advance(itr, rand()%lst.size());
+ return (*itr);
+ }
+
+ Unit* SelectEnemyCaster(bool casting)
+ {
+ ThreatList const& tList = m_creature->getThreatManager().getThreatList();
+ ThreatList::const_iterator iter;
+ for(iter = tList.begin(); iter!=tList.end(); ++iter)
+ {
+ Unit *target;
+ if(target = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid()))
+ if(target->getPowerType() == POWER_MANA)
+ return target;
+ }
+ return NULL;
+ }
+
+ uint32 EnemiesInRange(float distance)
+ {
+ ThreatList const& tList = m_creature->getThreatManager().getThreatList();
+ ThreatList::const_iterator iter;
+ uint32 count = 0;
+ for(iter = tList.begin(); iter!=tList.end(); ++iter)
+ {
+ Unit *target;
+ if(target = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid()))
+ if(m_creature->GetDistance2d(target) < distance)
+ ++count;
+ }
+ return count;
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho) return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+
+ if(mAIType==AI_MELEE)
+ DoStartMovement(pWho);
+ else
+ DoStartMovement(pWho, 20.0f);
+
+ SetCombatMovement(true);
+
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(ThreatTimer < diff)
+ {
+ UpdatePower();
+ UpdateThreat();
+ ThreatTimer = 4000;
+ }
+ else ThreatTimer -= diff;
+
+ if(CCTimer < diff)
+ {
+ RemoveCC();
+ CCTimer = 8000+rand()%2000;
+ }
+ else CCTimer -= diff;
+
+ if(mAIType == AI_MELEE) DoMeleeAttackIfReady();
+ }
+};
+
+/********************************************************************
+ HEALERS
+********************************************************************/
+
+#define SPELL_LIFEBLOOM 66093
+#define SPELL_NOURISH 66066
+#define SPELL_REGROWTH 66067
+#define SPELL_REJUVENATION 66065
+#define SPELL_TRANQUILITY 66086
+#define SPELL_BARKSKIN 65860 //1 min cd
+#define SPELL_THORNS 66068
+#define SPELL_NATURE_GRASP 66071 //1 min cd, self buff
+
+struct MANGOS_DLL_DECL mob_toc_druidAI : public boss_faction_championsAI
+{
+ mob_toc_druidAI(Creature* pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 51799, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_NATURE_GRASP, diff);
+
+ timedCast(SPELL_TRANQUILITY, diff);
+
+ if(timedQuery(SPELL_BARKSKIN, diff))
+ if(m_creature->GetHealthPercent() < 50.0f)
+ doCast(SPELL_BARKSKIN);
+
+ if(timedQuery(SPELL_LIFEBLOOM, diff))
+ switch(urand(0,4))
+ {
+ case 0:
+ doCast(SPELL_LIFEBLOOM);
+ break;
+ case 1:
+ doCast(SPELL_NOURISH);
+ break;
+ case 2:
+ doCast(SPELL_REGROWTH);
+ break;
+ case 3:
+ doCast(SPELL_REJUVENATION);
+ break;
+ case 4:
+ if(Creature* target = SelectRandomFriendlyMissingBuff(SPELL_THORNS))
+ doCast(SPELL_THORNS, target);
+ break;
+ }
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_HEALING_WAVE 66055
+#define SPELL_RIPTIDE 66053
+#define SPELL_SPIRIT_CLEANSE 66056 //friendly only
+#define SPELL_HEROISM 65983
+#define SPELL_BLOODLUST 65980
+#define SPELL_HEX 66054
+#define SPELL_EARTH_SHIELD 66063
+#define SPELL_EARTH_SHOCK 65973
+
+struct MANGOS_DLL_DECL mob_toc_shamanAI : public boss_faction_championsAI
+{
+ mob_toc_shamanAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_HEROISM, diff);
+
+ timedCast(SPELL_HEX, diff);
+
+ if(timedQuery(SPELL_HEALING_WAVE, diff))
+ {
+ switch(urand(0,5))
+ {
+ case 0: case 1:
+ doCast(SPELL_HEALING_WAVE);
+ break;
+ case 2:
+ doCast(SPELL_RIPTIDE);
+ break;
+ case 3:
+ doCast(SPELL_EARTH_SHOCK);
+ break;
+ case 4:
+ doCast(SPELL_SPIRIT_CLEANSE);
+ break;
+ case 5:
+ if(Unit *target = SelectRandomFriendlyMissingBuff(SPELL_EARTH_SHIELD))
+ doCast(target, SPELL_EARTH_SHIELD);
+ break;
+ }
+ }
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_HAND_OF_FREEDOM 68757 //25 sec cd
+#define SPELL_BUBBLE 66010 //5 min cd
+#define SPELL_CLEANSE 66116
+#define SPELL_FLASH_OF_LIGHT 66113
+#define SPELL_HOLY_LIGHT 66112
+#define SPELL_HOLY_SHOCK 66114
+#define SPELL_HAND_OF_PROTECTION 66009
+#define SPELL_HAMMER_OF_JUSTICE 66613
+
+struct MANGOS_DLL_DECL mob_toc_paladinAI : public boss_faction_championsAI
+{
+ mob_toc_paladinAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 50771, 47079, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ //cast bubble at 20% hp
+ if(m_creature->GetHealthPercent() < 20.0f)
+ timedCast(SPELL_BUBBLE, diff);
+
+ if(Unit *target = DoSelectLowestHpFriendly(40.0f))
+ if(target->GetHealthPercent() < 15.0f)
+ timedCast(SPELL_HAND_OF_PROTECTION, diff);
+
+ timedCast(SPELL_HOLY_SHOCK, diff);
+
+ if(Unit *target = SelectRandomFriendlyMissingBuff(SPELL_HAND_OF_FREEDOM))
+ timedCast(SPELL_HAND_OF_FREEDOM, diff, target);
+
+ timedCast(SPELL_HAMMER_OF_JUSTICE, diff);
+
+ if(timedQuery(SPELL_FLASH_OF_LIGHT, diff))
+ {
+ switch(urand(0,4))
+ {
+ case 0: case 1:
+ doCast(SPELL_FLASH_OF_LIGHT);
+ break;
+ case 2: case 3:
+ doCast(SPELL_HOLY_LIGHT);
+ break;
+ case 4:
+ doCast(SPELL_CLEANSE);
+ break;
+ }
+ }
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_RENEW 66177
+#define SPELL_SHIELD 66099
+#define SPELL_FLASH_HEAL 66104
+#define SPELL_DISPEL 65546
+#define SPELL_PSYCHIC_SCREAM 65543
+#define SPELL_MANA_BURN 66100
+
+struct MANGOS_DLL_DECL mob_toc_priestAI : public boss_faction_championsAI
+{
+ mob_toc_priestAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_HEALER) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ if(EnemiesInRange(10.0f) > 2)
+ timedCast(SPELL_PSYCHIC_SCREAM, diff);
+
+ if(timedQuery(SPELL_RENEW, diff))
+ {
+ switch(urand(0,5))
+ {
+ case 0:
+ doCast(SPELL_RENEW);
+ break;
+ case 1:
+ doCast(SPELL_SHIELD);
+ break;
+ case 2: case 3:
+ doCast(SPELL_FLASH_HEAL);
+ break;
+ case 4:
+ if(Unit *target = urand(0,1) ? m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0) : DoSelectLowestHpFriendly(40.0f))
+ doCast(target, SPELL_DISPEL);
+ break;
+ case 5:
+ doCast(SPELL_MANA_BURN);
+ break;
+ }
+ }
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+/********************************************************************
+ RANGED
+********************************************************************/
+
+#define SPELL_SILENCE 65542
+#define SPELL_VAMPIRIC_TOUCH 65490
+#define SPELL_SW_PAIN 65541
+#define SPELL_MIND_FLAY 65488
+#define SPELL_MIND_BLAST 65492
+#define SPELL_HORROR 65545
+#define SPELL_DISPERSION 65544
+#define SPELL_SHADOWFORM 16592
+
+struct MANGOS_DLL_DECL mob_toc_shadow_priestAI : public boss_faction_championsAI
+{
+ mob_toc_shadow_priestAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 50040, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void Aggro(Unit *who)
+ {
+ boss_faction_championsAI::Aggro(who);
+ doCast(SPELL_SHADOWFORM);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ if(EnemiesInRange(10.0f) > 2)
+ timedCast(SPELL_PSYCHIC_SCREAM, diff);
+
+ if(m_creature->GetHealthPercent() < 20.0f)
+ timedCast(SPELL_DISPERSION, diff);
+
+ if(Unit *target = SelectEnemyCaster(false))
+ timedCast(SPELL_SILENCE, diff, target);
+
+ timedCast(SPELL_MIND_BLAST, diff);
+
+ if(timedQuery(SPELL_MIND_FLAY, diff))
+ {
+ switch(urand(0,4))
+ {
+ case 0: case 1:
+ doCast(SPELL_MIND_FLAY);
+ break;
+ case 2:
+ doCast(SPELL_VAMPIRIC_TOUCH);
+ break;
+ case 3:
+ doCast(SPELL_SW_PAIN);
+ break;
+ case 4:
+ doCast(SPELL_DISPEL);
+ break;
+ }
+ }
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_HELLFIRE 65816
+#define SPELL_CORRUPTION 65810
+#define SPELL_Curse_of_Agony 65814
+#define SPELL_Curse_of_Exhaustion 65815
+#define SPELL_Fear 65809 //8s
+#define SPELL_Searing_Pain 65819
+#define SPELL_Shadow_Bolt 65821
+#define SPELL_Unstable_Affliction 65812
+#define H_SPELL_Unstable_Affliction 68155 //15s
+
+struct MANGOS_DLL_DECL mob_toc_warlockAI : public boss_faction_championsAI
+{
+ mob_toc_warlockAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_Fear, diff);
+
+ if(EnemiesInRange(10.0f) > 2)
+ timedCast(SPELL_HELLFIRE, diff);
+
+ timedCast(SPELL_Unstable_Affliction, diff);
+
+ if(timedQuery(SPELL_Shadow_Bolt, diff))
+ {
+ switch(urand(0,5))
+ {
+ case 0:
+ doCast(SPELL_Searing_Pain);
+ break;
+ case 1: case 2:
+ doCast(SPELL_Shadow_Bolt);
+ break;
+ case 3:
+ doCast(SPELL_CORRUPTION);
+ break;
+ case 4:
+ doCast(SPELL_Curse_of_Agony);
+ break;
+ case 5:
+ doCast(SPELL_Curse_of_Exhaustion);
+ break;
+ }
+ }
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_Arcane_Barrage 65799 //3s
+#define SPELL_Arcane_Blast 65791
+#define SPELL_Arcane_Explosion 65800
+#define SPELL_Blink 65793 //15s
+#define SPELL_Counterspell 65790 //24s
+#define SPELL_Frost_Nova 65792 //25s
+#define SPELL_Frostbolt 65807
+#define SPELL_Ice_Block 65802 //5min
+#define SPELL_Polymorph 65801 //15s
+
+struct MANGOS_DLL_DECL mob_toc_mageAI : public boss_faction_championsAI
{
- SAY_GARROSH_PVP_A_SLAY_1 = -1649048,
- SAY_GARROSH_PVP_A_SLAY_2 = -1649049,
- SAY_GARROSH_PVP_A_SLAY_3 = -1649050,
- SAY_GARROSH_PVP_A_SLAY_4 = -1649051,
+ mob_toc_mageAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();}
- SAY_VARIAN_PVP_H_SLAY_1 = -1649052,
- SAY_VARIAN_PVP_H_SLAY_2 = -1649053,
- SAY_VARIAN_PVP_H_SLAY_3 = -1649054,
- SAY_VARIAN_PVP_H_SLAY_4 = -1649055,
+ void Init()
+ {
+ SetEquipmentSlots(false, 47524, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ if(Unit *target = SelectEnemyCaster(false))
+ timedCast(SPELL_Counterspell, diff, target);
+
+ if(m_creature->GetHealthPercent() < 50.0f
+ && EnemiesInRange(10.0f)>3 )
+ {
+ timedCast(SPELL_Frost_Nova, diff);
+ timedCast(SPELL_Blink, diff);
+ }
+
+ if(m_creature->GetHealthPercent() < 20.0f)
+ timedCast(SPELL_Ice_Block, diff);
+
+ timedCast(SPELL_Polymorph, diff);
+
+ if(timedQuery(SPELL_Arcane_Barrage, diff))
+ {
+ switch(urand(0,2))
+ {
+ case 0:
+ doCast(SPELL_Arcane_Barrage);
+ break;
+ case 1:
+ doCast(SPELL_Arcane_Blast);
+ break;
+ case 2:
+ doCast(SPELL_Frostbolt);
+ break;
+ }
+ }
+ boss_faction_championsAI::UpdateAI(diff);
+ }
};
+
+
+#define SPELL_AIMED_SHOT 65883
+#define SPELL_Deterrence 65871 //90s
+#define SPELL_Disengage 65869 //30s
+#define SPELL_EXPLOSIVE_SHOT 65866
+#define SPELL_Frost_Trap 65880 //30s
+#define SPELL_SHOOT 65868 //1.7s
+#define SPELL_Steady_Shot 65867 //3s
+#define SPELL_WING_CLIP 66207 //6s
+#define SPELL_Wyvern_Sting 65877 //60s
+
+struct MANGOS_DLL_DECL mob_toc_hunterAI : public boss_faction_championsAI
+{
+ mob_toc_hunterAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 47156, EQUIP_NO_CHANGE, 48711);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ if(EnemiesInRange(10.0f) > 3)
+ timedCast(SPELL_Disengage, diff);
+
+ if(m_creature->GetHealthPercent() < 20.0f)
+ timedCast(SPELL_Deterrence, diff);
+
+ timedCast(SPELL_Wyvern_Sting, diff);
+
+ timedCast(SPELL_Frost_Trap, diff );
+
+ if(m_creature->GetDistance2d(m_creature->getVictim()) < 5.0f)
+ timedCast(SPELL_WING_CLIP, diff);
+
+ if(timedQuery(SPELL_SHOOT, diff))
+ {
+ switch(urand(0,3))
+ {
+ case 0: case 1:
+ doCast(SPELL_SHOOT);
+ break;
+ case 2:
+ doCast(SPELL_EXPLOSIVE_SHOT);
+ break;
+ case 3:
+ doCast(SPELL_AIMED_SHOT);
+ break;
+ }
+ }
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_Cyclone 65859 //6s
+#define SPELL_Entangling_Roots 65857 //10s
+#define SPELL_Faerie_Fire 65863
+#define SPELL_Force_of_Nature 65861 //180s
+#define SPELL_Insect_Swarm 65855
+#define SPELL_Moonfire 65856 //5s
+#define SPELL_Starfire 65854
+#define SPELL_Wrath 65862
+
+struct MANGOS_DLL_DECL mob_toc_boomkinAI : public boss_faction_championsAI
+{
+ mob_toc_boomkinAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_RANGED) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 50966, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ if(m_creature->GetHealthPercent() < 50.0f)
+ timedCast(SPELL_BARKSKIN, diff);
+
+ timedCast(SPELL_Cyclone, diff);
+
+ timedCast(SPELL_Entangling_Roots, diff);
+
+ timedCast(SPELL_Faerie_Fire, diff);
+
+ if(timedQuery(SPELL_Moonfire, diff))
+ {
+ switch(urand(0,6))
+ {
+ case 0: case 1:
+ doCast(SPELL_Moonfire);
+ break;
+ case 2:
+ doCast(SPELL_Insect_Swarm);
+ break;
+ case 3:
+ doCast(SPELL_Starfire);
+ break;
+ case 4: case 5: case 6:
+ doCast(SPELL_Wrath);
+ break;
+ }
+ }
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+/********************************************************************
+ MELEE
+********************************************************************/
+
+#define SPELL_BLADESTORM 65947
+#define SPELL_INTIMIDATING_SHOUT 65930
+#define SPELL_MORTAL_STRIKE 65926
+#define SPELL_CHARGE 68764
+#define SPELL_DISARM 65935
+#define SPELL_OVERPOWER 65924
+#define SPELL_SUNDER_ARMOR 65936
+#define SPELL_SHATTERING_THROW 65940
+#define SPELL_RETALIATION 65932
+
+struct MANGOS_DLL_DECL mob_toc_warriorAI : public boss_faction_championsAI
+{
+ mob_toc_warriorAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 47427, 46964, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_BLADESTORM, diff);
+
+ timedCast(SPELL_INTIMIDATING_SHOUT, diff);
+
+ timedCast(SPELL_MORTAL_STRIKE, diff);
+
+ timedCast(SPELL_SUNDER_ARMOR, diff);
+
+ timedCast(SPELL_CHARGE, diff);
+
+ timedCast(SPELL_RETALIATION, diff);
+
+ timedCast(SPELL_OVERPOWER, diff);
+
+ timedCast(SPELL_SHATTERING_THROW, diff);
+
+ timedCast(SPELL_DISARM, diff);
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_Chains_of_Ice 66020 //8sec
+#define SPELL_Death_Coil 66019 //5sec
+#define SPELL_Death_Grip 66017 //35sec
+#define SPELL_Frost_Strike 66047 //6sec
+#define SPELL_Icebound_Fortitude 66023 //1min
+#define SPELL_Icy_Touch 66021 //8sec
+#define SPELL_Strangulate 66018 //2min
+
+struct MANGOS_DLL_DECL mob_toc_dkAI : public boss_faction_championsAI
+{
+ mob_toc_dkAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 47518, 51021, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ if(m_creature->GetHealthPercent() < 50.0f)
+ timedCast(SPELL_Icebound_Fortitude, diff);
+
+ timedCast(SPELL_Chains_of_Ice, diff);
+
+ timedCast(SPELL_Death_Coil, diff);
+
+ if(Unit *target = SelectEnemyCaster(false))
+ timedCast(SPELL_Strangulate, diff, target);
+
+ timedCast(SPELL_Frost_Strike, diff);
+
+ timedCast(SPELL_Icy_Touch, diff);
+
+ if(m_creature->IsInRange(m_creature->getVictim(), 10.0f, 30.0f, false))
+ timedCast(SPELL_Death_Grip, diff);
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_FAN_OF_KNIVES 65955 //2sec
+#define SPELL_BLIND 65960 //2min
+#define SPELL_CLOAK 65961 //90sec
+#define SPELL_Blade_Flurry 65956 //2min
+#define SPELL_SHADOWSTEP 66178 //30sec
+#define SPELL_HEMORRHAGE 65954
+#define SPELL_EVISCERATE 65957
+
+struct MANGOS_DLL_DECL mob_toc_rogueAI : public boss_faction_championsAI
+{
+ mob_toc_rogueAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 47422, 49982, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ if(EnemiesInRange(15.0f) > 2)
+ timedCast(SPELL_FAN_OF_KNIVES, diff);
+
+ timedCast(SPELL_HEMORRHAGE, diff);
+
+ timedCast(SPELL_EVISCERATE, diff);
+
+ if(m_creature->IsInRange(m_creature->getVictim(), 10.0f, 40.0f))
+ timedCast(SPELL_SHADOWSTEP, diff);
+
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
+ if(m_creature->IsInRange(target, 0.0f, 15.0f, false))
+ timedCast(SPELL_BLIND, diff, target);
+
+ if(m_creature->GetHealthPercent() < 50.0f)
+ timedCast(SPELL_CLOAK, diff);
+
+ timedCast(SPELL_Blade_Flurry, diff);
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_EARTH_SHOCK 65973
+#define SPELL_LAVA_LASH 65974
+#define SPELL_STORMSTRIKE 65970
+
+struct MANGOS_DLL_DECL mob_toc_enh_shamanAI : public boss_faction_championsAI
+{
+ mob_toc_enh_shamanAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 51803, 48013, EQUIP_NO_CHANGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_HEROISM, diff);
+
+ timedCast(SPELL_EARTH_SHOCK, diff);
+
+ timedCast(SPELL_STORMSTRIKE, diff);
+
+ timedCast(SPELL_LAVA_LASH, diff);
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_Avenging_Wrath 66011 //3min cd
+#define SPELL_Crusader_Strike 66003 //6sec cd
+#define SPELL_Divine_Shield 66010 //5min cd
+#define SPELL_Divine_Storm 66006 //10sec cd
+#define SPELL_Hammer_of_Justice 66007 //40sec cd
+#define SPELL_Hand_of_Protection 66009 //5min cd
+#define SPELL_Judgement_of_Command 66005 //8sec cd
+#define SPELL_REPENTANCE 66008 //60sec cd
+#define SPELL_Seal_of_Command 66004 //no cd
+
+struct MANGOS_DLL_DECL mob_toc_retro_paladinAI : public boss_faction_championsAI
+{
+ mob_toc_retro_paladinAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();}
+
+ void Init()
+ {
+ SetEquipmentSlots(false, 47519, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
+
+ void Aggro(Unit *who)
+ {
+ boss_faction_championsAI::Aggro(who);
+ doCast(SPELL_Seal_of_Command);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_REPENTANCE, diff);
+
+ timedCast(SPELL_Crusader_Strike, diff);
+
+ timedCast(SPELL_Avenging_Wrath, diff);
+
+ if(m_creature->GetHealthPercent() < 20.0f)
+ timedCast(SPELL_Divine_Shield, diff);
+
+ timedCast(SPELL_Divine_Storm, diff);
+
+ timedCast(SPELL_Judgement_of_Command, diff);
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_WPET0 67518
+#define SPELL_WPET1 67519
+
+struct MANGOS_DLL_DECL mob_toc_pet_warlockAI : public boss_faction_championsAI
+{
+ mob_toc_pet_warlockAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();}
+
+ void Aggro(Unit *who)
+ {
+ boss_faction_championsAI::Aggro(who);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_WPET0, diff);
+
+ timedCast(SPELL_WPET1, diff);
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+#define SPELL_HPET0 67793
+struct MANGOS_DLL_DECL mob_toc_pet_hunterAI : public boss_faction_championsAI
+{
+ mob_toc_pet_hunterAI(Creature *pCreature) : boss_faction_championsAI(pCreature, AI_MELEE) {Init();}
+
+ void Aggro(Unit *who)
+ {
+ boss_faction_championsAI::Aggro(who);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
+
+ timedCast(SPELL_HPET0, diff);
+
+ boss_faction_championsAI::UpdateAI(diff);
+ }
+};
+
+
+/*========================================================*/
+CreatureAI* GetAI_mob_toc_druid(Creature *pCreature) {
+ return new mob_toc_druidAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_shaman(Creature *pCreature) {
+ return new mob_toc_shamanAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_paladin(Creature *pCreature) {
+ return new mob_toc_paladinAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_priest(Creature *pCreature) {
+ return new mob_toc_priestAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_shadow_priest(Creature *pCreature) {
+ return new mob_toc_shadow_priestAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_warlock(Creature *pCreature) {
+ return new mob_toc_warlockAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_mage(Creature *pCreature) {
+ return new mob_toc_mageAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_hunter(Creature *pCreature) {
+ return new mob_toc_hunterAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_boomkin(Creature *pCreature) {
+ return new mob_toc_boomkinAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_warrior(Creature *pCreature) {
+ return new mob_toc_warriorAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_dk(Creature *pCreature) {
+ return new mob_toc_dkAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_rogue(Creature *pCreature) {
+ return new mob_toc_rogueAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_enh_shaman(Creature *pCreature) {
+ return new mob_toc_enh_shamanAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_retro_paladin(Creature *pCreature) {
+ return new mob_toc_retro_paladinAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_pet_warlock(Creature *pCreature) {
+ return new mob_toc_pet_warlockAI (pCreature);
+}
+CreatureAI* GetAI_mob_toc_pet_hunter(Creature *pCreature) {
+ return new mob_toc_pet_hunterAI (pCreature);
+}
+
+void AddSC_boss_faction_champions()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_druid";
+ newscript->GetAI = &GetAI_mob_toc_druid;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_shaman";
+ newscript->GetAI = &GetAI_mob_toc_shaman;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_paladin";
+ newscript->GetAI = &GetAI_mob_toc_paladin;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_priest";
+ newscript->GetAI = &GetAI_mob_toc_priest;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_shadow_priest";
+ newscript->GetAI = &GetAI_mob_toc_shadow_priest;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_mage";
+ newscript->GetAI = &GetAI_mob_toc_mage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_warlock";
+ newscript->GetAI = &GetAI_mob_toc_warlock;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_hunter";
+ newscript->GetAI = &GetAI_mob_toc_hunter;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_boomkin";
+ newscript->GetAI = &GetAI_mob_toc_boomkin;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_warrior";
+ newscript->GetAI = &GetAI_mob_toc_warrior;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_dk";
+ newscript->GetAI = &GetAI_mob_toc_dk;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_rogue";
+ newscript->GetAI = &GetAI_mob_toc_rogue;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_enh_shaman";
+ newscript->GetAI = &GetAI_mob_toc_enh_shaman;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_retro_paladin";
+ newscript->GetAI = &GetAI_mob_toc_retro_paladin;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_pet_warlock";
+ newscript->GetAI = &GetAI_mob_toc_pet_warlock;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toc_pet_hunter";
+ newscript->GetAI = &GetAI_mob_toc_pet_hunter;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp
index 1d1dd75..c2335a3 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_jaraxxus.cpp
@@ -13,60 +13,112 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+// Jaraxxus - Magic aura (from start?) not fully offlike implemented.
+// Legion flame visual effect not imlemented
/* ScriptData
SDName: trial_of_the_crusader
-SD%Complete: 0
-SDComment:
+SD%Complete: 80%
+SDComment: by /dev/rsa
SDCategory: Crusader Coliseum
EndScriptData */
#include "precompiled.h"
#include "trial_of_the_crusader.h"
+enum Equipment
+{
+ EQUIP_MAIN = 47266,
+ EQUIP_OFFHAND = 46996,
+ EQUIP_RANGED = 47267,
+ EQUIP_DONE = EQUIP_NO_CHANGE,
+};
-/*######
-## boss_jaraxxus
-######*/
+enum Summons
+{
+ NPC_LEGION_FLAME = 34784,
+ NPC_INFERNAL_VOLCANO = 34813,
+ NPC_FEL_INFERNAL = 34815,
+ NPC_NETHER_PORTAL = 34825,
+ NPC_MISTRESS = 34826,
+};
-enum
+enum BossSpells
{
- SAY_AGGRO = -1649040,
- SAY_SLAY_1 = -1649041,
- SAY_SLAY_2 = -1649042,
- SAY_DEATH = -1649043,
- SAY_BERSERK = -1649044,
- SAY_INCINERATE = -1649045,
- SAY_MISTRESS = -1649046,
- SAY_INFERNO = -1649047,
+SPELL_NETHER_POWER = 67108,
+SPELL_INFERNAL = 66258,
+SPELL_INFERNAL_ERUPTION = 66255,
+SPELL_FEL_FIREBALL = 66532,
+SPELL_FEL_LIGHTING = 66528,
+SPELL_INCINERATE_FLESH = 66237,
+SPELL_BURNING_INFERNO = 66242,
+SPELL_NETHER_PORTAL = 66264,
+SPELL_LEGION_FLAME_0 = 66199,
+SPELL_LEGION_FLAME_1 = 66197,
+SPELL_SHIVAN_SLASH = 67098,
+SPELL_SPINNING_STRIKE = 66316,
+SPELL_FEL_INFERNO = 67047,
+SPELL_FEL_STREAK = 66494,
+SPELL_BERSERK = 26662,
};
-struct MANGOS_DLL_DECL boss_jaraxxusAI : public ScriptedAI
+/*######
+## boss_jaraxxus
+######*/
+
+struct MANGOS_DLL_DECL boss_jaraxxusAI : public BSWScriptedAI
{
- boss_jaraxxusAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_jaraxxusAI(Creature* pCreature) : BSWScriptedAI(pCreature)
{
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
+ uint8 stage;
+ uint8 substage;
+ uint8 m_portalsCount;
+ uint8 m_volcanoCount;
- void Reset() {}
+ void Reset() {
+ if(!m_pInstance) return;
+ m_pInstance->SetData(TYPE_JARAXXUS, NOT_STARTED);
+// SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
+ m_portalsCount = 1;
+ if (currentDifficulty == RAID_DIFFICULTY_10MAN_HEROIC || currentDifficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+ {
+ m_portalsCount = 2;
+ m_volcanoCount = 4;
+ } else {
+ m_portalsCount = 1;
+ m_volcanoCount = 4;
+ }
+ DoScriptText(-1713517,m_creature);
+ m_creature->SetRespawnDelay(DAY);
+ }
void JustReachedHome()
{
- if (m_pInstance)
- m_pInstance->SetData(TYPE_JARAXXUS, NOT_STARTED);
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_JARAXXUS, FAIL);
+ m_creature->ForcedDespawn();
}
void JustDied(Unit* pKiller)
{
- if (m_pInstance)
+ if (!m_pInstance) return;
+ DoScriptText(-1713525,m_creature);
m_pInstance->SetData(TYPE_JARAXXUS, DONE);
+ m_pInstance->SetData(TYPE_EVENT,2000);
+ m_pInstance->SetData(TYPE_STAGE,0);
}
void Aggro(Unit* pWho)
{
+ if (!m_pInstance) return;
m_creature->SetInCombatWithZone();
+ m_pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS);
+ DoScriptText(-1713514,m_creature);
+ doCast(SPELL_NETHER_POWER);
}
void UpdateAI(const uint32 uiDiff)
@@ -74,6 +126,37 @@ struct MANGOS_DLL_DECL boss_jaraxxusAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ timedCast(SPELL_FEL_FIREBALL, uiDiff);
+
+ timedCast(SPELL_FEL_LIGHTING, uiDiff);
+
+ if (timedQuery(SPELL_INCINERATE_FLESH, uiDiff)) {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
+ {
+ DoScriptText(-1713522,m_creature,pTarget);
+ doCast(SPELL_INCINERATE_FLESH,pTarget);
+ }
+ }
+
+ if (timedQuery(SPELL_LEGION_FLAME_1, uiDiff)) {
+ DoScriptText(-1713518,m_creature);
+ doCast(SPELL_LEGION_FLAME_1);
+ };
+
+ if (timedQuery(SPELL_INFERNAL_ERUPTION, uiDiff)
+ && m_volcanoCount > 0) {
+ DoScriptText(-1713520,m_creature);
+ if (doCast(NPC_INFERNAL_VOLCANO) == CAST_OK) --m_volcanoCount;
+ };
+
+ if (timedQuery(SPELL_NETHER_PORTAL, uiDiff)
+ && m_portalsCount > 0
+ && m_creature->GetHealthPercent() <= 90.0f)
+ {
+ DoScriptText(-1713519,m_creature);
+ if (doCast(NPC_NETHER_PORTAL) == CAST_OK) --m_portalsCount;
+ };
+
DoMeleeAttackIfReady();
}
};
@@ -83,6 +166,320 @@ CreatureAI* GetAI_boss_jaraxxus(Creature* pCreature)
return new boss_jaraxxusAI(pCreature);
}
+struct MANGOS_DLL_DECL mob_legion_flameAI : public BSWScriptedAI
+{
+ mob_legion_flameAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_uiRangeCheck_Timer;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(DAY);
+
+ if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ) {
+ m_creature->GetMotionMaster()->MoveChase(pTarget);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5);
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) return;
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiRangeCheck_Timer < uiDiff)
+ {
+ if (m_pInstance)
+ {
+ if (m_creature->IsWithinDist(m_creature->getVictim(), 4.0f, false))
+ {
+ DoCast(m_creature,SPELL_LEGION_FLAME_0);
+ }
+ }
+ m_uiRangeCheck_Timer = 1000;
+ if (m_creature->getVictim()) {
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5);
+ }
+ }
+ else m_uiRangeCheck_Timer -= uiDiff;
+
+ }
+};
+
+CreatureAI* GetAI_mob_legion_flame(Creature* pCreature)
+{
+ return new mob_legion_flameAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_infernal_volcanoAI : public BSWScriptedAI
+{
+ mob_infernal_volcanoAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint8 m_Count;
+ uint32 m_Timer;
+
+ void Reset()
+ {
+ m_Timer = 15000;
+ m_creature->SetRespawnDelay(DAY);
+ if (currentDifficulty != RAID_DIFFICULTY_10MAN_HEROIC && currentDifficulty != RAID_DIFFICULTY_25MAN_HEROIC)
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_Count = 3;
+ } else
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_Count = 6;
+ }
+ }
+
+ void AttackStart(Unit *who)
+ {
+ return;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) return;
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (timedQuery(SPELL_INFERNAL_ERUPTION,diff) && m_Count > 0) {
+ doCast(SPELL_INFERNAL_ERUPTION);
+ DoScriptText(-1713524,m_creature);
+ --m_Count;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ }
+};
+
+CreatureAI* GetAI_mob_infernal_volcano(Creature* pCreature)
+{
+ return new mob_infernal_volcanoAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_fel_infernalAI : public BSWScriptedAI
+{
+ mob_fel_infernalAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) return;
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_FEL_INFERNO, uiDiff);
+
+ timedCast(SPELL_FEL_STREAK, uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_fel_infernal(Creature* pCreature)
+{
+ return new mob_fel_infernalAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_nether_portalAI : public BSWScriptedAI
+{
+ mob_nether_portalAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_Timer;
+ uint8 m_Count;
+
+ void Reset()
+ {
+ m_Timer = 10000;
+ m_creature->SetRespawnDelay(DAY);
+ if (currentDifficulty != RAID_DIFFICULTY_10MAN_HEROIC && currentDifficulty != RAID_DIFFICULTY_25MAN_HEROIC)
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_Count = 1;
+ } else
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_Count = 2;
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) return;
+ }
+
+ void AttackStart(Unit *who)
+ {
+ return;
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_Timer < diff && m_Count > 0) {
+ DoCast(m_creature,SPELL_NETHER_PORTAL,false);
+ DoScriptText(-1713521,m_creature);
+ --m_Count;
+ m_Timer = 60000;
+ } else m_Timer -= diff;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ }
+};
+
+CreatureAI* GetAI_mob_nether_portal(Creature* pCreature)
+{
+ return new mob_nether_portalAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_mistress_of_painAI : public BSWScriptedAI
+{
+ mob_mistress_of_painAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) return;
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ DoScriptText(-1713523,m_creature, who);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) return;
+ if (m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_SHIVAN_SLASH, uiDiff);
+
+ timedCast(SPELL_SPINNING_STRIKE, uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_mistress_of_pain(Creature* pCreature)
+{
+ return new mob_mistress_of_painAI(pCreature);
+}
+
void AddSC_boss_jaraxxus()
{
Script* newscript;
@@ -91,4 +488,29 @@ void AddSC_boss_jaraxxus()
newscript->Name = "boss_jaraxxus";
newscript->GetAI = &GetAI_boss_jaraxxus;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_legion_flame";
+ newscript->GetAI = &GetAI_mob_legion_flame;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_infernal_volcano";
+ newscript->GetAI = &GetAI_mob_infernal_volcano;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_fel_infernal";
+ newscript->GetAI = &GetAI_mob_fel_infernal;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_nether_portal";
+ newscript->GetAI = &GetAI_mob_nether_portal;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_mistress_of_pain";
+ newscript->GetAI = &GetAI_mob_mistress_of_pain;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp
index ed9e8b3..24e891b 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_northrend_beasts.cpp
@@ -13,42 +13,113 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+// Gormok - Firebomb not implemented, timers need correct
+// Snakes - Underground phase not worked, timers need correct
+// Icehowl - Trample&Crash event not implemented, timers need correct
/* ScriptData
-SDName:
-SD%Complete: 0
-SDComment:
+SDName: northrend_beasts
+SD%Complete: 90%
+SDComment: by /dev/rsa
SDCategory:
EndScriptData */
+// not implemented:
+// snobolds link
+// snakes underground cast (not support in core)
+
#include "precompiled.h"
#include "trial_of_the_crusader.h"
-/*######
-## boss_gormok
-######*/
+enum Equipment
+{
+ EQUIP_MAIN = 50760,
+ EQUIP_OFFHAND = 48040,
+ EQUIP_RANGED = 47267,
+ EQUIP_DONE = EQUIP_NO_CHANGE,
+};
+
+enum Summons
+{
+ NPC_SNOBOLD_VASSAL = 34800,
+ NPC_SLIME_POOL = 35176,
+ NPC_FIRE_BOMB = 34854,
+};
+
+enum BossSpells
+{
+SPELL_IMPALE = 66331,
+SPELL_STAGGERING_STOMP = 67648,
+SPELL_RISING_ANGER = 66636,
+SUMMON_SNOBOLD = NPC_SNOBOLD_VASSAL,
+SPELL_ACID_SPIT = 66880,
+SPELL_PARALYTIC_SPRAY = 66901,
+SPELL_ACID_SPEW = 66819,
+SPELL_PARALYTIC_BITE = 66824,
+SPELL_SWEEP_0 = 66794,
+SPELL_SLIME_POOL = 66883,
+SPELL_FIRE_SPIT = 66796,
+SPELL_MOLTEN_SPEW = 66821,
+SPELL_BURNING_BITE = 66879,
+SPELL_BURNING_SPRAY = 66902,
+SPELL_SWEEP_1 = 67646,
+SPELL_FEROCIOUS_BUTT = 66770,
+SPELL_MASSIVE_CRASH = 66683,
+SPELL_WHIRL = 67345,
+SPELL_ARCTIC_BREATH = 66689,
+SPELL_TRAMPLE = 66734,
+SPELL_ADRENALINE = 68667,
+SPELL_SNOBOLLED = 66406,
+SPELL_BATTER = 66408,
+SPELL_FIRE_BOMB = 66313,
+SPELL_FIRE_BOMB_1 = 66317,
+SPELL_FIRE_BOMB_DOT = 66318,
+SPELL_HEAD_CRACK = 66407,
+SPELL_SUBMERGE_0 = 53421,
+SPELL_ENRAGE = 68335,
+SPELL_FROTHING_RAGE = 66759,
+SPELL_STAGGERED_DAZE = 66758,
+SPELL_SLIME_POOL_1 = 66881,
+SPELL_SLIME_POOL_2 = 66882,
+SPELL_SLIME_POOL_VISUAL = 63084,
+};
-struct MANGOS_DLL_DECL boss_gormokAI : public ScriptedAI
+struct MANGOS_DLL_DECL boss_gormokAI : public BSWScriptedAI
{
- boss_gormokAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_gormokAI(Creature* pCreature) : BSWScriptedAI(pCreature)
{
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
+ uint8 SnoboldsCount;
- void Reset() {}
+ void Reset() {
+
+ if(!m_pInstance) return;
+ SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetInCombatWithZone();
+ SnoboldsCount = 4;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_DONE);
+ }
void JustReachedHome()
{
- if (m_pInstance)
- m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED);
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ m_creature->ForcedDespawn();
}
void Aggro(Unit* pWho)
{
- m_creature->SetInCombatWithZone();
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_IN_PROGRESS);
}
void UpdateAI(const uint32 uiDiff)
@@ -56,6 +127,16 @@ struct MANGOS_DLL_DECL boss_gormokAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ timedCast(SPELL_IMPALE, uiDiff);
+
+ timedCast(SPELL_STAGGERING_STOMP, uiDiff);
+
+ if (timedQuery(SUMMON_SNOBOLD, uiDiff) && SnoboldsCount > 0 ) {
+ doCast(SUMMON_SNOBOLD);
+ DoScriptText(-1713601,m_creature);
+ --SnoboldsCount;
+ };
+
DoMeleeAttackIfReady();
}
};
@@ -65,38 +146,175 @@ CreatureAI* GetAI_boss_gormok(Creature* pCreature)
return new boss_gormokAI(pCreature);
}
-/*######
-## boss_acidmaw
-######*/
+struct MANGOS_DLL_DECL mob_snobold_vassalAI : public BSWScriptedAI
+{
+ mob_snobold_vassalAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ Unit* pBoss;
+ Unit* defaultTarget;
+
+ void Reset()
+ {
+ pBoss = NULL;
+ defaultTarget = NULL;
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(DAY);
+ pBoss = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_GORMOK));
+ if (pBoss) doCast(SPELL_RISING_ANGER,pBoss);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance) return;
+ defaultTarget = who;
+ doCast(SPELL_SNOBOLLED, defaultTarget);
+ }
+
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_creature->ForcedDespawn();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (defaultTarget && defaultTarget->isAlive()) doRemove(SPELL_SNOBOLLED, defaultTarget);
+// if (pBoss && pBoss->isAlive()) doRemove(SPELL_RISING_ANGER,pBoss);
+// This string - not offlike, in off this buff not removed! especially for small servers.
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_BATTER, uiDiff);
+
+ if (timedCast(SPELL_FIRE_BOMB, uiDiff, m_creature->getVictim()) == CAST_OK) {
+ doCast(SPELL_FIRE_BOMB_1, m_creature->getVictim());
+ doCast(SPELL_FIRE_BOMB_DOT, m_creature->getVictim());
+ }
+
+ timedCast(SPELL_HEAD_CRACK, uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_snobold_vassal(Creature* pCreature)
+{
+ return new mob_snobold_vassalAI(pCreature);
+}
-struct MANGOS_DLL_DECL boss_acidmawAI : public ScriptedAI
+struct MANGOS_DLL_DECL boss_acidmawAI : public BSWScriptedAI
{
- boss_acidmawAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_acidmawAI(Creature* pCreature) : BSWScriptedAI(pCreature)
{
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
+ uint8 stage;
+ bool enraged;
- void Reset() {}
+ void Reset()
+ {
+ stage = 1;
+ enraged = false;
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(7*DAY);
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ACIDMAW_SUBMERGED);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DREADSCALE)))
+ if (!pSister->isAlive())
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_DONE);
+ else m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_SPECIAL);
+ }
void JustReachedHome()
{
- if (m_pInstance)
- m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED);
+ if (!m_pInstance) return;
+ if (m_pInstance->GetData(TYPE_BEASTS) == IN_PROGRESS
+ && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != FAIL)
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ m_creature->ForcedDespawn();
}
void Aggro(Unit* pWho)
{
- m_creature->SetInCombatWithZone();
}
void UpdateAI(const uint32 uiDiff)
{
- if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+
+ if ((!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ && (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != ACIDMAW_SUBMERGED))
return;
+ switch (stage)
+ {
+ case 0: {
+ timedCast(SPELL_ACID_SPEW, uiDiff);
+
+ timedCast(SPELL_PARALYTIC_BITE, uiDiff);
+
+ timedCast(SPELL_ACID_SPIT, uiDiff);
+
+ timedCast(SPELL_PARALYTIC_SPRAY, uiDiff);
+
+ timedCast(SPELL_SWEEP_0, uiDiff);
+
+ if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == ACIDMAW_SUBMERGED)
+ stage = 1;
+
+ break;}
+ case 1: {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->InterruptNonMeleeSpells(true);
+ doCast(SPELL_SUBMERGE_0);
+ stage = 2;
+ DoScriptText(-1713557,m_creature);
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ACIDMAW_SUBMERGED);
+ break;}
+ case 2: {
+ if (timedQuery(SPELL_SLIME_POOL, uiDiff))
+ doCast(NPC_SLIME_POOL);
+
+ if ((timedQuery(SPELL_SUBMERGE_0, uiDiff) && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == ACIDMAW_SUBMERGED)
+ || m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == DREADSCALE_SUBMERGED)
+ stage = 3;
+ break;}
+ case 3: {
+ DoScriptText(-1713559,m_creature);
+ doRemove(SPELL_SUBMERGE_0);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ stage = 0;
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, DREADSCALE_SUBMERGED);
+ break;}
+ }
+
+ if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL && !enraged)
+ {
+ DoScriptText(-1713559,m_creature);
+ doRemove(SPELL_SUBMERGE_0);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ doCast(SPELL_ENRAGE);
+ enraged = true;
+ stage = 0;
+ DoScriptText(-1713504,m_creature);
+ };
+
DoMeleeAttackIfReady();
}
};
@@ -106,38 +324,108 @@ CreatureAI* GetAI_boss_acidmaw(Creature* pCreature)
return new boss_acidmawAI(pCreature);
}
-/*######
-## boss_dreadscale
-######*/
-
-struct MANGOS_DLL_DECL boss_dreadscaleAI : public ScriptedAI
+struct MANGOS_DLL_DECL boss_dreadscaleAI : public BSWScriptedAI
{
- boss_dreadscaleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_dreadscaleAI(Creature* pCreature) : BSWScriptedAI(pCreature)
{
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
+ uint8 stage;
+ bool enraged;
+
+ void Reset()
+ {
+ stage = 0;
+ enraged = false;
+ m_creature->SetInCombatWithZone();
+ m_creature->SetRespawnDelay(7*DAY);
+ }
- void Reset() {}
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ACIDMAW)))
+ if (!pSister->isAlive())
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_DONE);
+ else m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_SPECIAL);
+ }
void JustReachedHome()
{
- if (m_pInstance)
- m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED);
+ if (!m_pInstance) return;
+ if (m_pInstance->GetData(TYPE_BEASTS) == IN_PROGRESS
+ && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != FAIL)
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ m_creature->ForcedDespawn();
}
void Aggro(Unit* pWho)
{
- m_creature->SetInCombatWithZone();
}
void UpdateAI(const uint32 uiDiff)
{
- if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ if ((!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ && (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != DREADSCALE_SUBMERGED))
return;
+ switch (stage)
+ {
+ case 0: {
+ timedCast(SPELL_BURNING_BITE, uiDiff);
+
+ timedCast(SPELL_MOLTEN_SPEW, uiDiff);
+
+ timedCast(SPELL_FIRE_SPIT, uiDiff);
+
+ timedCast(SPELL_BURNING_SPRAY, uiDiff);
+
+ timedCast(SPELL_SWEEP_0, uiDiff);
+
+ if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == DREADSCALE_SUBMERGED)
+ stage = 1;
+
+ break;}
+ case 1: {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->InterruptNonMeleeSpells(true);
+ doCast(SPELL_SUBMERGE_0);
+ stage = 2;
+ DoScriptText(-1713557,m_creature);
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, DREADSCALE_SUBMERGED);
+ break;}
+ case 2: {
+
+ if (timedQuery(SPELL_SLIME_POOL, uiDiff))
+ doCast(NPC_SLIME_POOL);
+
+ if ((timedQuery(SPELL_SUBMERGE_0, uiDiff) && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == DREADSCALE_SUBMERGED)
+ || m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == ACIDMAW_SUBMERGED)
+ stage = 3;
+ break;}
+ case 3: {
+ DoScriptText(-1713559,m_creature);
+ doRemove(SPELL_SUBMERGE_0);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ stage = 0;
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ACIDMAW_SUBMERGED);
+ break;}
+ }
+
+ if (m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL && !enraged)
+ {
+ DoScriptText(-1713559,m_creature);
+ doRemove(SPELL_SUBMERGE_0);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ doCast(SPELL_ENRAGE);
+ enraged = true;
+ stage = 0;
+ DoScriptText(-1713504,m_creature);
+ };
+
DoMeleeAttackIfReady();
}
};
@@ -147,36 +435,113 @@ CreatureAI* GetAI_boss_dreadscale(Creature* pCreature)
return new boss_dreadscaleAI(pCreature);
}
-/*######
-## boss_icehowl
-######*/
-
-enum
+struct MANGOS_DLL_DECL mob_slime_poolAI : public BSWScriptedAI
{
- EMOTE_MASSIVE_CRASH = -1649039,
+ mob_slime_poolAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+ float m_Size;
+ bool cloudcasted;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWithZone();
+ m_creature->SetSpeedRate(MOVE_RUN, 0.05f);
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MoveRandom();
+ doCast(SPELL_SLIME_POOL_2);
+ m_Size = m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X);
+ cloudcasted = false;
+ }
+
+ void AttackStart(Unit *who)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!cloudcasted) {
+ doCast(SPELL_SLIME_POOL_VISUAL);
+ cloudcasted = true;
+ }
+
+ if (timedQuery(SPELL_SLIME_POOL_2,uiDiff)) {
+ m_Size = m_Size*1.035;
+ m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_Size);
+ }
+ // Override especially for clean core
+ if (m_Size >= 6.0f) m_creature->ForcedDespawn();
+ }
+
};
-struct MANGOS_DLL_DECL boss_icehowlAI : public ScriptedAI
+CreatureAI* GetAI_mob_slime_pool(Creature* pCreature)
{
- boss_icehowlAI(Creature* pCreature) : ScriptedAI(pCreature)
+ return new mob_slime_poolAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL boss_icehowlAI : public BSWScriptedAI
+{
+ boss_icehowlAI(Creature* pCreature) : BSWScriptedAI(pCreature)
{
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
+ bool MovementStarted;
+ bool TrampleCasted;
+ uint8 stage;
+ float fPosX, fPosY, fPosZ;
+ Unit* pTarget;
+
+ void Reset() {
+ if(!m_pInstance) return;
+ m_creature->SetRespawnDelay(7*DAY);
+ MovementStarted = false;
+ stage = 0;
+ }
- void Reset() {}
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_DONE);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if(!m_pInstance) return;
+ if(type != POINT_MOTION_TYPE) return;
+ if(id != 1 && MovementStarted)
+ {
+ m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ);
+ }
+ else {
+ m_creature->GetMotionMaster()->MovementExpired();
+ MovementStarted = false;
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ }
+ }
void JustReachedHome()
{
- if (m_pInstance)
- m_pInstance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED);
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ m_creature->ForcedDespawn();
}
void Aggro(Unit* pWho)
{
m_creature->SetInCombatWithZone();
+ m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_IN_PROGRESS);
}
void UpdateAI(const uint32 uiDiff)
@@ -184,7 +549,95 @@ struct MANGOS_DLL_DECL boss_icehowlAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
- DoMeleeAttackIfReady();
+ switch (stage)
+ {
+ case 0: {
+ timedCast(SPELL_FEROCIOUS_BUTT, uiDiff);
+
+ timedCast(SPELL_ARCTIC_BREATH, uiDiff);
+
+ timedCast(SPELL_WHIRL, uiDiff);
+
+ if (timedQuery(SPELL_MASSIVE_CRASH, uiDiff)) stage = 1;
+
+ timedCast(SPELL_FROTHING_RAGE, uiDiff);
+
+ DoMeleeAttackIfReady();
+
+ break;
+ }
+ case 1: {
+ if (doCast(SPELL_MASSIVE_CRASH) == CAST_OK)
+ stage = 2;
+ break;
+ }
+ case 2: {
+ if (pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) {
+ TrampleCasted = false;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ stage = 3;
+ resetTimer(SPELL_TRAMPLE);
+ DoScriptText(-1713506,m_creature,pTarget);
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ }
+ break;
+ }
+ case 3: {
+ if (timedQuery(SPELL_TRAMPLE,uiDiff)) {
+ if (pTarget && pTarget->isAlive() && (pTarget->IsWithinDistInMap(m_creature, 200.0f))) {
+ pTarget->GetPosition(fPosX, fPosY, fPosZ);
+ TrampleCasted = false;
+ MovementStarted = true;
+ m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ);
+ DoScriptText(-1713508,m_creature);
+ doCast(SPELL_ADRENALINE);
+ stage = 4;
+ }
+ else {
+ TrampleCasted = true;
+ stage = 5;
+ }
+ }
+ break;
+ }
+ case 4: {
+ if (MovementStarted)
+ {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ Unit* pPlayer = itr->getSource();
+ if (!pPlayer) continue;
+ if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(m_creature, 5.0f)) {
+ doCast(SPELL_TRAMPLE, pPlayer);
+ TrampleCasted = true;
+ MovementStarted = false;
+ m_creature->GetMotionMaster()->MovementExpired();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ }
+ }
+
+ } else stage = 5;
+ if (TrampleCasted) stage = 5;
+ break;
+ }
+ case 5: {
+ if (!TrampleCasted) {
+ doCast(SPELL_STAGGERED_DAZE);
+ DoScriptText(-1713507,m_creature);
+ }
+ MovementStarted = false;
+ m_creature->GetMotionMaster()->MovementExpired();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ SetCombatMovement(true);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ stage = 0;
+ break;
+ }
+ }
+
}
};
@@ -217,4 +670,14 @@ void AddSC_northrend_beasts()
newscript->GetAI = &GetAI_boss_icehowl;
newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "mob_snobold_vassal";
+ newscript->GetAI = &GetAI_mob_snobold_vassal;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_slime_pool";
+ newscript->GetAI = &GetAI_mob_slime_pool;
+ newscript->RegisterSelf();
+
}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp
index 5923e63..a1f7075 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/boss_twin_valkyr.cpp
@@ -16,48 +16,211 @@
/* ScriptData
SDName: trial_of_the_crusader
-SD%Complete: 0
-SDComment:
+SD%Complete: 80%
+SDComment: by /dev/rsa
SDCategory: Crusader Coliseum
EndScriptData */
+// Twin pact - heal part not worked now by undefined reason. Need override?
+// timers need correct
+
#include "precompiled.h"
#include "trial_of_the_crusader.h"
-enum
+enum Equipment
{
- SAY_AGGRO = -1649056,
- SAY_BERSERK = -1649057,
- SAY_COLORSWITCH = -1649058,
- SAY_DEATH = -1649059,
- SAY_SLAY_1 = -1649060,
- SAY_SLAY_2 = -1649061,
- SAY_TO_BLACK = -1649062,
- SAY_TO_WHITE = -1649063,
+ EQUIP_MAIN_1 = 49303,
+ EQUIP_OFFHAND_1 = 47146,
+ EQUIP_RANGED_1 = 47267,
+ EQUIP_MAIN_2 = 45990,
+ EQUIP_OFFHAND_2 = 47470,
+ EQUIP_RANGED_2 = 47267,
+ EQUIP_DONE = EQUIP_NO_CHANGE,
+};
+
+enum Summons
+{
+ NPC_DARK_ESSENCE = 34567,
+ NPC_LIGHT_ESSENCE = 34568,
+
+ NPC_UNLEASHED_DARK = 34628,
+ NPC_UNLEASHED_LIGHT = 34630,
};
-/*######
-## boss_fjola
-######*/
+enum BossSpells
+{
+ SPELL_TWIN_SPIKE_L = 66075,
+ SPELL_LIGHT_SURGE = 65766,
+ SPELL_SHIELD_LIGHT = 65858,
+ SPELL_TWIN_PACT_L = 65875,
+ SPELL_LIGHT_VORTEX = 66046,
+ SPELL_LIGHT_TOUCH = 67297,
+ SPELL_TWIN_SPIKE_H = 66069,
+ SPELL_DARK_SURGE = 65768,
+ SPELL_SHIELD_DARK = 65874,
+ SPELL_TWIN_PACT_H = 65876,
+ SPELL_DARK_VORTEX = 66058,
+ SPELL_DARK_TOUCH = 67282,
+ SPELL_TWIN_POWER = 65916,
+ SPELL_LIGHT_ESSENCE = 65686,
+ SPELL_DARK_ESSENCE = 65684,
+ SPELL_BERSERK = 64238,
+ SPELL_REMOVE_TOUCH = 68084,
+ SPELL_NONE = 0,
+//
+ SPELL_UNLEASHED_DARK = 65808,
+ SPELL_UNLEASHED_LIGHT = 65795,
+};
-struct MANGOS_DLL_DECL boss_fjolaAI : public ScriptedAI
+struct MANGOS_DLL_DECL boss_fjolaAI : public BSWScriptedAI
{
- boss_fjolaAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+ boss_fjolaAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
ScriptedInstance* m_pInstance;
+ uint8 stage;
- void Reset() {}
+ void Reset() {
+ if(!m_pInstance) return;
+ SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_OFFHAND_1, EQUIP_RANGED_1);
+ m_creature->SetRespawnDelay(7*DAY);
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ stage = 0;
+ }
+
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_VALKIRIES, FAIL);
+ m_pInstance->SetData(DATA_HEALTH_FJOLA, m_creature->GetMaxHealth());
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ m_creature->ForcedDespawn();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ DoScriptText(-1713547,m_creature);
+ if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DARKBANE)))
+ if (!pSister->isAlive())
+ m_pInstance->SetData(TYPE_VALKIRIES, DONE);
+ else m_pInstance->SetData(TYPE_VALKIRIES, SPECIAL);
+ m_pInstance->SetData(DATA_HEALTH_FJOLA, 0);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (!m_pInstance) return;
+ DoScriptText(-1713544,m_creature,pVictim);
+ }
void Aggro(Unit* pWho)
{
+ if (!m_pInstance) return;
m_creature->SetInCombatWithZone();
+ m_pInstance->SetData(TYPE_VALKIRIES, IN_PROGRESS);
+ if (m_creature->isAlive()) m_creature->SummonCreature(NPC_LIGHT_ESSENCE, SpawnLoc[24].x, SpawnLoc[24].y, SpawnLoc[24].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ if (m_creature->isAlive()) m_creature->SummonCreature(NPC_LIGHT_ESSENCE, SpawnLoc[25].x, SpawnLoc[25].y, SpawnLoc[25].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ DoScriptText(-1713541,m_creature);
+ m_pInstance->SetData(DATA_HEALTH_FJOLA, m_creature->GetMaxHealth());
+ doCast(SPELL_LIGHT_SURGE);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if(pDoneBy->GetGUID() == m_creature->GetGUID()) return;
+
+ if(pDoneBy->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(pDoneBy->HasAura(SPELL_LIGHT_ESSENCE))
+ uiDamage /= 2;
+ else if(pDoneBy->HasAura(SPELL_DARK_ESSENCE))
+ uiDamage += uiDamage/2;
+ }
+
+ m_pInstance->SetData(DATA_HEALTH_FJOLA, m_creature->GetHealth() >= uiDamage ? m_creature->GetHealth() - uiDamage : 0);
}
void UpdateAI(const uint32 uiDiff)
{
+ if (!m_pInstance) return;
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ if (m_creature->GetHealth() > m_pInstance->GetData(DATA_HEALTH_EYDIS) &&
+ m_pInstance->GetData(DATA_HEALTH_EYDIS) != 0)
+ m_creature->SetHealth(m_pInstance->GetData(DATA_HEALTH_EYDIS));
+
+ switch (stage)
+ {
+ case 0:
+ timedCast(SPELL_TWIN_SPIKE_L, uiDiff);
+
+ if (timedQuery(SPELL_LIGHT_TOUCH, uiDiff))
+ {
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_LIGHT_ESSENCE, false, 50.0f))
+ doCast(SPELL_LIGHT_TOUCH, pTarget);
+ doCast(NPC_UNLEASHED_LIGHT);
+ };
+ if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_NONE )
+ {
+ if (timedQuery(SPELL_LIGHT_VORTEX, uiDiff))
+ {
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_LIGHT_VORTEX);
+ DoScriptText(-1713538,m_creature);
+ stage = 1;
+ break;
+ };
+ if (timedQuery(SPELL_TWIN_PACT_L, uiDiff)
+ && m_creature->GetHealthPercent() <= 50.0f)
+ {
+ m_creature->InterruptNonMeleeSpells(true);
+ doCast(SPELL_SHIELD_LIGHT);
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_TWIN_PACT_L);
+ DoScriptText(-1713539,m_creature);
+ stage = 3;
+ };
+ };
+ if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_TWIN_PACT_H)
+ if (!m_creature->HasAura(SPELL_TWIN_POWER))
+ doCast(SPELL_TWIN_POWER);
+ break;
+ case 1:
+ doCast(SPELL_LIGHT_VORTEX);
+ stage = 2;
+ break;
+ case 2:
+ if (!m_creature->HasAura(SPELL_LIGHT_VORTEX)
+ && timedQuery(SPELL_SHIELD_LIGHT, uiDiff))
+ {
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ stage = 0;
+ };
+ break;
+ case 3:
+ doCast(SPELL_TWIN_PACT_L);
+ stage = 4;
+ break;
+ case 4:
+ if (!m_creature->HasAura(SPELL_SHIELD_LIGHT)
+ && timedQuery(SPELL_SHIELD_LIGHT, uiDiff))
+ {
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ stage = 0;
+ };
+ default:
+ break;
+ }
+
+ timedCast(SPELL_BERSERK, uiDiff);
+
DoMeleeAttackIfReady();
}
};
@@ -67,19 +230,80 @@ CreatureAI* GetAI_boss_fjola(Creature* pCreature)
return new boss_fjolaAI(pCreature);
}
-/*######
-## boss_eydis
-######*/
-
-struct MANGOS_DLL_DECL boss_eydisAI : public ScriptedAI
+struct MANGOS_DLL_DECL boss_eydisAI : public BSWScriptedAI
{
- boss_eydisAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+ boss_eydisAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint8 stage;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+ SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_OFFHAND_2, EQUIP_RANGED_2);
+ m_creature->SetRespawnDelay(7*DAY);
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ stage = 0;
+ }
- void Reset() {}
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_VALKIRIES, FAIL);
+ m_pInstance->SetData(DATA_HEALTH_EYDIS, m_creature->GetMaxHealth());
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ m_creature->ForcedDespawn();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ DoScriptText(-1713547,m_creature);
+ if (Creature* pSister = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LIGHTBANE)))
+ if (!pSister->isAlive())
+ m_pInstance->SetData(TYPE_VALKIRIES, DONE);
+ else m_pInstance->SetData(TYPE_VALKIRIES, SPECIAL);
+ m_pInstance->SetData(DATA_HEALTH_EYDIS, 0);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ DoScriptText(-1713543,m_creature,pVictim);
+ }
void Aggro(Unit* pWho)
{
+ if (!m_pInstance) return;
m_creature->SetInCombatWithZone();
+ m_pInstance->SetData(TYPE_VALKIRIES, IN_PROGRESS);
+ DoScriptText(-1713741,m_creature);
+ if (m_creature->isAlive()) m_creature->SummonCreature(NPC_DARK_ESSENCE, SpawnLoc[22].x, SpawnLoc[22].y, SpawnLoc[22].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ if (m_creature->isAlive()) m_creature->SummonCreature(NPC_DARK_ESSENCE, SpawnLoc[23].x, SpawnLoc[23].y, SpawnLoc[23].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ m_pInstance->SetData(DATA_HEALTH_EYDIS, m_creature->GetMaxHealth());
+ doCast(SPELL_DARK_SURGE);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if(pDoneBy->GetGUID() == m_creature->GetGUID()) return;
+
+ if(pDoneBy->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(pDoneBy->HasAura(SPELL_DARK_ESSENCE))
+ uiDamage /= 2;
+ else if(pDoneBy->HasAura(SPELL_LIGHT_ESSENCE))
+ uiDamage += uiDamage/2;
+ }
+
+ m_pInstance->SetData(DATA_HEALTH_EYDIS, m_creature->GetHealth() >= uiDamage ? m_creature->GetHealth() - uiDamage : 0);
}
void UpdateAI(const uint32 uiDiff)
@@ -87,6 +311,74 @@ struct MANGOS_DLL_DECL boss_eydisAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ if (m_creature->GetHealth() > m_pInstance->GetData(DATA_HEALTH_FJOLA) &&
+ m_pInstance->GetData(DATA_HEALTH_FJOLA) != 0)
+ m_creature->SetHealth(m_pInstance->GetData(DATA_HEALTH_FJOLA));
+
+ switch (stage)
+ {
+ case 0:
+ timedCast(SPELL_TWIN_SPIKE_H, uiDiff);
+
+ if (timedQuery(SPELL_DARK_TOUCH, uiDiff))
+ {
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_DARK_ESSENCE, false, 50.0f))
+ doCast(SPELL_DARK_TOUCH, pTarget);
+ doCast(NPC_UNLEASHED_DARK);
+ };
+ if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_NONE )
+ {
+ if (timedQuery(SPELL_DARK_VORTEX, uiDiff))
+ {
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_DARK_VORTEX);
+ DoScriptText(-1713540,m_creature);
+ stage = 1;
+ break;
+ };
+ if (timedQuery(SPELL_TWIN_PACT_H, uiDiff)
+ && m_creature->GetHealthPercent() <= 50.0f)
+ {
+ m_creature->InterruptNonMeleeSpells(true);
+ doCast(SPELL_SHIELD_DARK);
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_TWIN_PACT_H);
+ DoScriptText(-1713539,m_creature);
+ stage = 3;
+ break;
+ };
+ };
+ if (m_pInstance->GetData(DATA_CASTING_VALKYRS) == SPELL_TWIN_PACT_L)
+ if (!m_creature->HasAura(SPELL_TWIN_POWER))
+ doCast(SPELL_TWIN_POWER);
+ break;
+ case 1:
+ doCast(SPELL_DARK_VORTEX);
+ stage = 2;
+ break;
+ case 2:
+ if (!m_creature->HasAura(SPELL_DARK_VORTEX)
+ && timedQuery(SPELL_SHIELD_DARK, uiDiff))
+ {
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ stage = 0;
+ };
+ break;
+ case 3:
+ doCast(SPELL_TWIN_PACT_H);
+ stage = 4;
+ break;
+ case 4:
+ if (!m_creature->HasAura(SPELL_SHIELD_DARK)
+ && timedQuery(SPELL_SHIELD_DARK, uiDiff))
+ {
+ m_pInstance->SetData(DATA_CASTING_VALKYRS, SPELL_NONE);
+ stage = 0;
+ };
+ default:
+ break;
+ }
+
+ timedCast(SPELL_BERSERK, uiDiff);
+
DoMeleeAttackIfReady();
}
};
@@ -96,6 +388,250 @@ CreatureAI* GetAI_boss_eydis(Creature* pCreature)
return new boss_eydisAI(pCreature);
}
+struct MANGOS_DLL_DECL mob_light_essenceAI : public ScriptedAI
+{
+ mob_light_essenceAI(Creature* pCreature) : ScriptedAI(pCreature) {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MoveRandom();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) m_creature->ForcedDespawn();
+ if (m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS) {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ Unit* pPlayer = itr->getSource();
+ if (!pPlayer) continue;
+ if (pPlayer->isAlive())
+ pPlayer->RemoveAurasDueToSpell(SPELL_LIGHT_ESSENCE);
+ }
+
+ m_creature->ForcedDespawn();
+ }
+ return;
+ }
+};
+
+CreatureAI* GetAI_mob_light_essence(Creature* pCreature)
+{
+ return new mob_light_essenceAI(pCreature);
+};
+
+bool GossipHello_mob_light_essence(Player *player, Creature* pCreature)
+{
+ ScriptedInstance *pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+ if(!pInstance) return true;
+ player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
+ player->RemoveAurasDueToSpell(SPELL_DARK_ESSENCE);
+// player->CastSpell(player,SPELL_REMOVE_TOUCH,false); // Not worked now
+ player->CastSpell(player,SPELL_LIGHT_ESSENCE,false);
+ player->RemoveAurasDueToSpell(SPELL_LIGHT_TOUCH); // Override for REMOVE_TOUCH
+ player->CLOSE_GOSSIP_MENU();
+ return true;
+};
+
+struct MANGOS_DLL_DECL mob_dark_essenceAI : public ScriptedAI
+{
+ mob_dark_essenceAI(Creature* pCreature) : ScriptedAI(pCreature) {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MoveRandom();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) m_creature->ForcedDespawn();
+ if (m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS) {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ Unit* pPlayer = itr->getSource();
+ if (!pPlayer) continue;
+ if (pPlayer->isAlive())
+ pPlayer->RemoveAurasDueToSpell(SPELL_DARK_ESSENCE);
+ }
+ m_creature->ForcedDespawn();
+ }
+ return;
+ }
+};
+
+CreatureAI* GetAI_mob_dark_essence(Creature* pCreature)
+{
+ return new mob_dark_essenceAI(pCreature);
+};
+
+bool GossipHello_mob_dark_essence(Player *player, Creature* pCreature)
+{
+ ScriptedInstance *pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+ if(!pInstance) return true;
+ player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
+ player->RemoveAurasDueToSpell(SPELL_LIGHT_ESSENCE);
+// player->CastSpell(player,SPELL_REMOVE_TOUCH,false); // Not worked now
+ player->CastSpell(player,SPELL_DARK_ESSENCE,false);
+ player->RemoveAurasDueToSpell(SPELL_DARK_TOUCH); // Override for REMOVE_TOUCH
+ player->CLOSE_GOSSIP_MENU();
+ return true;
+}
+
+struct MANGOS_DLL_DECL mob_unleashed_darkAI : public ScriptedAI
+{
+ mob_unleashed_darkAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_uiRangeCheck_Timer;
+ Creature* pboss1;
+ Creature* pboss2;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MoveRandom();
+ m_uiRangeCheck_Timer = 1000;
+ pboss1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DARKBANE));
+ pboss2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LIGHTBANE));
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_uiRangeCheck_Timer < uiDiff)
+ {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ Unit* pPlayer = itr->getSource();
+ if (!pPlayer) continue;
+ if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ m_creature->CastSpell(m_creature, SPELL_UNLEASHED_DARK, true);
+ m_creature->ForcedDespawn();
+ }
+
+ }
+ if (pboss1 && pboss1->isAlive() && pboss1->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ m_creature->CastSpell(m_creature, SPELL_UNLEASHED_DARK, true);
+ m_creature->ForcedDespawn();
+ }
+ if (pboss2 && pboss2->isAlive() && pboss2->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ m_creature->CastSpell(m_creature, SPELL_UNLEASHED_DARK, true);
+ m_creature->ForcedDespawn();
+ }
+ m_uiRangeCheck_Timer = 1000;
+ }
+ else m_uiRangeCheck_Timer -= uiDiff;
+ }
+
+};
+
+CreatureAI* GetAI_mob_unleashed_dark(Creature *pCreature)
+{
+ return new mob_unleashed_darkAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_unleashed_lightAI : public ScriptedAI
+{
+ mob_unleashed_lightAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_uiRangeCheck_Timer;
+ Creature* pboss1;
+ Creature* pboss2;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MoveRandom();
+ m_uiRangeCheck_Timer = 1000;
+ pboss1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_DARKBANE));
+ pboss2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_LIGHTBANE));
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_VALKIRIES) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_uiRangeCheck_Timer < uiDiff)
+ {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ Unit* pPlayer = itr->getSource();
+ if (!pPlayer) continue;
+ if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ m_creature->CastSpell(m_creature, SPELL_UNLEASHED_LIGHT, true);
+ m_creature->ForcedDespawn();
+ }
+ }
+ if (pboss1 && pboss1->isAlive() && pboss1->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ m_creature->CastSpell(m_creature, SPELL_UNLEASHED_LIGHT, true);
+ m_creature->ForcedDespawn();
+ }
+ if (pboss2 && pboss2->isAlive() && pboss2->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ m_creature->CastSpell(m_creature, SPELL_UNLEASHED_LIGHT, true);
+ m_creature->ForcedDespawn();
+ }
+ m_uiRangeCheck_Timer = 1000;
+ }
+ else m_uiRangeCheck_Timer -= uiDiff;
+ }
+
+};
+
+CreatureAI* GetAI_mob_unleashed_light(Creature *pCreature)
+{
+ return new mob_unleashed_lightAI(pCreature);
+}
+
void AddSC_twin_valkyr()
{
Script* newscript;
@@ -107,6 +643,29 @@ void AddSC_twin_valkyr()
newscript = new Script;
newscript->Name = "boss_eydis";
- newscript->GetAI = &GetAI_boss_fjola;
+ newscript->GetAI = &GetAI_boss_eydis;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_unleashed_light";
+ newscript->GetAI = &GetAI_mob_unleashed_light;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_unleashed_dark";
+ newscript->GetAI = &GetAI_mob_unleashed_dark;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_light_essence";
+ newscript->GetAI = &GetAI_mob_light_essence;
+ newscript->pGossipHello = &GossipHello_mob_light_essence;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_essence";
+ newscript->GetAI = &GetAI_mob_dark_essence;
+ newscript->pGossipHello = &GossipHello_mob_dark_essence;
+ newscript->RegisterSelf();
+
}
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp
index 9fba55a..4388690 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/instance_trial_of_the_crusader.cpp
@@ -1,185 +1,606 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
/* ScriptData
SDName: instance_trial_of_the_crusader
-SD%Complete: 100
-SDComment:
-SDCategory: Crusader Coliseum
+SD%Complete: 80%
+SDComment: by /dev/rsa
+SDCategory: Trial of the Crusader
EndScriptData */
#include "precompiled.h"
#include "trial_of_the_crusader.h"
-/* Trial Of The Crusader encounters:
-0 - Northrend Beasts
-1 - Jaraxxus
-2 - Faction Champions
-3 - Twin Valkyr
-4 - Anubarak
-*/
-
struct MANGOS_DLL_DECL instance_trial_of_the_crusader : public ScriptedInstance
{
- instance_trial_of_the_crusader(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+ instance_trial_of_the_crusader(Map* pMap) : ScriptedInstance(pMap) {
+ Difficulty = pMap->GetDifficulty();
+ Initialize();
+ }
+
+ uint32 m_auiEncounter[MAX_ENCOUNTERS+1];
+ uint32 m_auiEventTimer;
+ uint32 m_auiEventNPCId;
+ uint32 m_auiNorthrendBeasts;
+ uint8 Difficulty;
+ std::string m_strInstData;
+ bool needsave;
+
+ uint32 m_uiDataDamageFjola;
+ uint32 m_uiDataDamageEydis;
+ uint32 m_uiValkyrsCasting;
+
+ uint32 m_auiCrusadersCount;
+
+ uint64 m_uiBarrentGUID;
+ uint64 m_uiTirionGUID;
+ uint64 m_uiFizzlebangGUID;
+ uint64 m_uiGarroshGUID;
+ uint64 m_uiRinnGUID;
+ uint64 m_uiLich0GUID;
+ uint64 m_uiLich1GUID;
+
+ uint64 m_uiGormokGUID;
+ uint64 m_uiAcidmawGUID;
+ uint64 m_uiDreadscaleGUID;
+ uint64 m_uiIcehowlGUID;
+ uint64 m_uiJaraxxusGUID;
+ uint64 m_uiDarkbaneGUID;
+ uint64 m_uiLightbaneGUID;
+ uint64 m_uiAnubarakGUID;
+
+ uint64 m_uiCrusader11Guid;
+ uint64 m_uiCrusader12Guid;
+ uint64 m_uiCrusader13Guid;
+ uint64 m_uiCrusader14Guid;
+ uint64 m_uiCrusader15Guid;
+ uint64 m_uiCrusader16Guid;
+ uint64 m_uiCrusader17Guid;
+ uint64 m_uiCrusader18Guid;
+ uint64 m_uiCrusader19Guid;
+ uint64 m_uiCrusader1aGuid;
+ uint64 m_uiCrusader1bGuid;
+ uint64 m_uiCrusader1cGuid;
+ uint64 m_uiCrusader1dGuid;
+ uint64 m_uiCrusader1eGuid;
- uint32 m_auiEncounter[MAX_ENCOUNTER];
- std::string strInstData;
+ uint64 m_uiCrusader21Guid;
+ uint64 m_uiCrusader22Guid;
+ uint64 m_uiCrusader23Guid;
+ uint64 m_uiCrusader24Guid;
+ uint64 m_uiCrusader25Guid;
+ uint64 m_uiCrusader26Guid;
+ uint64 m_uiCrusader27Guid;
+ uint64 m_uiCrusader28Guid;
+ uint64 m_uiCrusader29Guid;
+ uint64 m_uiCrusader2aGuid;
+ uint64 m_uiCrusader2bGuid;
+ uint64 m_uiCrusader2cGuid;
+ uint64 m_uiCrusader2dGuid;
+ uint64 m_uiCrusader2eGuid;
+
+ uint64 m_uiCrusader01Guid;
+ uint64 m_uiCrusader02Guid;
+
+ uint64 m_uiCrusadersCacheGUID;
+ uint64 m_uiFloorGUID;
+
+ uint64 m_uiTC10h25GUID;
+ uint64 m_uiTC10h45GUID;
+ uint64 m_uiTC10h50GUID;
+ uint64 m_uiTC10h99GUID;
+
+ uint64 m_uiTC25h25GUID;
+ uint64 m_uiTC25h45GUID;
+ uint64 m_uiTC25h50GUID;
+ uint64 m_uiTC25h99GUID;
+
+ uint64 m_uiTributeChest1GUID;
+ uint64 m_uiTributeChest2GUID;
+ uint64 m_uiTributeChest3GUID;
+ uint64 m_uiTributeChest4GUID;
+
+ uint64 m_uiMainGateDoorGUID;
+
+ uint64 m_uiWestPortcullisGUID;
+ uint64 m_uiNorthPortcullisGUID;
+ uint64 m_uiSouthPortcullisGUID;
- uint32 m_uiGormokGUID;
- uint32 m_uiAcidmawGUID;
- uint32 m_uiDreadscaleGUID;
- uint32 m_uiIcehowlGUID;
- uint32 m_uiJaraxxusGUID;
- uint32 m_uiFjolaGUID;
- uint32 m_uiEydisGUID;
- uint32 m_uiAnubarakGUID;
void Initialize()
{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ m_auiEncounter[0] = 0;
+ m_auiEncounter[7] = 50;
+ m_auiEncounter[8] = 0;
+
+ m_uiTributeChest1GUID = 0;
+ m_uiTributeChest2GUID = 0;
+ m_uiTributeChest3GUID = 0;
+ m_uiTributeChest4GUID = 0;
+ m_uiDataDamageFjola = 0;
+ m_uiDataDamageEydis = 0;
+ m_uiLich0GUID = 0;
+ m_uiLich1GUID = 0;
+
+ m_auiNorthrendBeasts = NOT_STARTED;
- m_uiGormokGUID = 0;
- m_uiAcidmawGUID = 0;
- m_uiDreadscaleGUID = 0;
- m_uiIcehowlGUID = 0;
- m_uiJaraxxusGUID = 0;
- m_uiFjolaGUID = 0;
- m_uiEydisGUID = 0;
- m_uiAnubarakGUID = 0;
+ m_auiEventTimer = 1000;
+ m_auiCrusadersCount = 6;
+
+ needsave = false;
}
bool IsEncounterInProgress() const
{
- for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ for(uint8 i = 1; i < MAX_ENCOUNTERS-2 ; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
return false;
}
- void OnCreatureCreate(Creature* pCreature)
+ void OnPlayerEnter(Player *m_player)
+ {
+ if (Difficulty == RAID_DIFFICULTY_10MAN_HEROIC || Difficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+ {
+ m_player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,1);
+ m_player->SendUpdateWorldState(UPDATE_STATE_UI_COUNT, GetData(TYPE_COUNTER));
+ }
+ }
+
+ bool IsRaidWiped()
{
+ Map::PlayerList const &players = instance->GetPlayers();
+
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ {
+ if(Player* pPlayer = i->getSource())
+ {
+ if(pPlayer->isAlive())
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void OpenDoor(uint64 guid)
+ {
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ }
+
+ void CloseDoor(uint64 guid)
+ {
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_READY);
+ }
+
+ void OnCreatureCreate(Creature* pCreature)
+ {
switch(pCreature->GetEntry())
{
- case 34796: m_uiGormokGUID = pCreature->GetGUID(); break;
- case 35144: m_uiAcidmawGUID = pCreature->GetGUID(); break;
- case 34799: m_uiDreadscaleGUID = pCreature->GetGUID(); break;
- case 34797: m_uiIcehowlGUID = pCreature->GetGUID(); break;
- case 34780: m_uiJaraxxusGUID = pCreature->GetGUID(); break;
- case 34497: m_uiFjolaGUID = pCreature->GetGUID(); break;
- case 34496: m_uiEydisGUID = pCreature->GetGUID(); break;
- case 34564: m_uiAnubarakGUID = pCreature->GetGUID(); break;
+ case NPC_BARRENT: m_uiBarrentGUID = pCreature->GetGUID(); break;
+ case NPC_TIRION: m_uiTirionGUID = pCreature->GetGUID(); break;
+ case NPC_FIZZLEBANG: m_uiFizzlebangGUID = pCreature->GetGUID(); break;
+ case NPC_GARROSH: m_uiGarroshGUID = pCreature->GetGUID(); break;
+ case NPC_RINN: m_uiRinnGUID = pCreature->GetGUID(); break;
+ case NPC_LICH_KING_0: m_uiLich0GUID = pCreature->GetGUID(); break;
+ case NPC_LICH_KING_1: m_uiLich1GUID = pCreature->GetGUID(); break;
+
+ case NPC_GORMOK: m_uiGormokGUID = pCreature->GetGUID(); break;
+ case NPC_ACIDMAW: m_uiAcidmawGUID = pCreature->GetGUID(); break;
+ case NPC_DREADSCALE: m_uiDreadscaleGUID = pCreature->GetGUID(); break;
+ case NPC_ICEHOWL: m_uiIcehowlGUID = pCreature->GetGUID(); break;
+ case NPC_JARAXXUS: m_uiJaraxxusGUID = pCreature->GetGUID(); break;
+ case NPC_DARKBANE: m_uiDarkbaneGUID = pCreature->GetGUID(); break;
+ case NPC_LIGHTBANE: m_uiLightbaneGUID = pCreature->GetGUID(); break;
+ case NPC_ANUBARAK: m_uiAnubarakGUID = pCreature->GetGUID(); break;
+
+ case NPC_CRUSADER_1_1: m_uiCrusader11Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_2: m_uiCrusader12Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_3: m_uiCrusader13Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_4: m_uiCrusader14Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_5: m_uiCrusader15Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_6: m_uiCrusader16Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_7: m_uiCrusader17Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_8: m_uiCrusader18Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_9: m_uiCrusader19Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_10: m_uiCrusader1aGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_11: m_uiCrusader1bGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_12: m_uiCrusader1cGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_13: m_uiCrusader1dGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_1_14: m_uiCrusader1eGuid = pCreature->GetGUID(); break;
+
+ case NPC_CRUSADER_2_1: m_uiCrusader21Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_2: m_uiCrusader22Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_3: m_uiCrusader23Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_4: m_uiCrusader24Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_5: m_uiCrusader25Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_6: m_uiCrusader26Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_7: m_uiCrusader27Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_8: m_uiCrusader28Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_9: m_uiCrusader29Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_10: m_uiCrusader2aGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_11: m_uiCrusader2bGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_12: m_uiCrusader2cGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_13: m_uiCrusader2dGuid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_2_14: m_uiCrusader2eGuid = pCreature->GetGUID(); break;
+
+ case NPC_CRUSADER_0_1: m_uiCrusader01Guid = pCreature->GetGUID(); break;
+ case NPC_CRUSADER_0_2: m_uiCrusader02Guid = pCreature->GetGUID(); break;
}
}
- void SetData(uint32 uiType, uint32 uiData)
+ void OnObjectCreate(GameObject *pGo)
{
- debug_log("SD2: Instance Trial Of The Crusader: SetData received for type %u with data %u",uiType,uiData);
+ switch(pGo->GetEntry())
+ {
+ case GO_CRUSADERS_CACHE_10:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL)
+ m_uiCrusadersCacheGUID = pGo->GetGUID();
+ break;
+ case GO_CRUSADERS_CACHE_25:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL)
+ m_uiCrusadersCacheGUID = pGo->GetGUID();
+ break;
+ case GO_CRUSADERS_CACHE_10_H:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC)
+ m_uiCrusadersCacheGUID = pGo->GetGUID();
+ break;
+ case GO_CRUSADERS_CACHE_25_H:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+ m_uiCrusadersCacheGUID = pGo->GetGUID();
+ break;
+ case GO_ARGENT_COLISEUM_FLOOR:
+ m_uiFloorGUID = pGo->GetGUID();
+ break;
+ case GO_MAIN_GATE_DOOR: m_uiMainGateDoorGUID = pGo->GetGUID(); break;
+
+ case GO_SOUTH_PORTCULLIS: m_uiSouthPortcullisGUID = pGo->GetGUID(); break;
+ case GO_WEST_PORTCULLIS: m_uiWestPortcullisGUID = pGo->GetGUID(); break;
+ case GO_NORTH_PORTCULLIS: m_uiNorthPortcullisGUID = pGo->GetGUID(); break;
+
+ case GO_TRIBUTE_CHEST_10H_25: m_uiTC10h25GUID = pGo->GetGUID(); break;
+ case GO_TRIBUTE_CHEST_10H_45: m_uiTC10h45GUID = pGo->GetGUID(); break;
+ case GO_TRIBUTE_CHEST_10H_50: m_uiTC10h50GUID = pGo->GetGUID(); break;
+ case GO_TRIBUTE_CHEST_10H_99: m_uiTC10h99GUID = pGo->GetGUID(); break;
+
+ case GO_TRIBUTE_CHEST_25H_25: m_uiTC25h25GUID = pGo->GetGUID(); break;
+ case GO_TRIBUTE_CHEST_25H_45: m_uiTC25h45GUID = pGo->GetGUID(); break;
+ case GO_TRIBUTE_CHEST_25H_50: m_uiTC25h50GUID = pGo->GetGUID(); break;
+ case GO_TRIBUTE_CHEST_25H_99: m_uiTC25h99GUID = pGo->GetGUID(); break;
+ }
+ }
+ void SetData(uint32 uiType, uint32 uiData)
+ {
switch(uiType)
{
- case TYPE_NORTHREND_BEASTS:
- m_auiEncounter[0] = uiData;
- break;
- case TYPE_JARAXXUS:
- m_auiEncounter[1] = uiData;
- break;
- case TYPE_FACTION_CHAMPIONS:
- m_auiEncounter[2] = uiData;
- break;
- case TYPE_TWIN_VALKYR:
- m_auiEncounter[3] = uiData;
- break;
- case TYPE_ANUBARAK:
- m_auiEncounter[4] = uiData;
- break;
- default:
- error_log("SD2: Instance Trial of The Crusader: ERROR SetData = %u for type %u does not exist/not implemented.",uiType,uiData);
- break;
+ case TYPE_STAGE: m_auiEncounter[0] = uiData; break;
+ case TYPE_BEASTS: m_auiEncounter[1] = uiData; break;
+ case TYPE_JARAXXUS: m_auiEncounter[2] = uiData; break;
+ case TYPE_CRUSADERS: if (uiData == FAIL && (m_auiEncounter[3] == FAIL || m_auiEncounter[3] == NOT_STARTED))
+ m_auiEncounter[3] = NOT_STARTED;
+ else m_auiEncounter[3] = uiData;
+ if (uiData == DONE) {
+ if (GameObject* pChest = instance->GetGameObject(m_uiCrusadersCacheGUID))
+ if (pChest && !pChest->isSpawned())
+ pChest->SetRespawnTime(7*DAY);
+ };
+ break;
+ case TYPE_CRUSADERS_COUNT: if (uiData == 0) --m_auiCrusadersCount;
+ else m_auiCrusadersCount = uiData;
+ break;
+ case TYPE_VALKIRIES: if (m_auiEncounter[4] == SPECIAL && uiData == SPECIAL) uiData = DONE;
+ m_auiEncounter[4] = uiData; break;
+ case TYPE_LICH_KING: m_auiEncounter[5] = uiData; break;
+ case TYPE_ANUBARAK: m_auiEncounter[6] = uiData;
+ if (uiData == DONE) {
+ if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC){
+ if ( m_auiEncounter[7] >= 25) m_uiTributeChest1GUID = m_uiTC10h25GUID;
+ if ( m_auiEncounter[7] >= 45) m_uiTributeChest2GUID = m_uiTC10h45GUID;
+ if ( m_auiEncounter[7] >= 49) m_uiTributeChest3GUID = m_uiTC10h50GUID;
+ m_uiTributeChest4GUID = m_uiTC10h99GUID;
+ }
+ if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC){
+ if ( m_auiEncounter[7] >= 25) m_uiTributeChest1GUID = m_uiTC25h25GUID;
+ if ( m_auiEncounter[7] >= 45) m_uiTributeChest2GUID = m_uiTC25h45GUID;
+ if ( m_auiEncounter[7] >= 49) m_uiTributeChest3GUID = m_uiTC25h50GUID;
+ m_uiTributeChest4GUID = m_uiTC25h99GUID;
+ }
+ // Attention! It is (may be) not off-like, but spawning all Tribute Chests is real
+ // reward for clearing TOC instance
+ if (m_uiTributeChest1GUID)
+ if (GameObject* pChest1 = instance->GetGameObject(m_uiTributeChest1GUID))
+ if (pChest1 && !pChest1->isSpawned()) pChest1->SetRespawnTime(7*DAY);
+ if (m_uiTributeChest2GUID)
+ if (GameObject* pChest2 = instance->GetGameObject(m_uiTributeChest2GUID))
+ if (pChest2 && !pChest2->isSpawned()) pChest2->SetRespawnTime(7*DAY);
+ if (m_uiTributeChest3GUID)
+ if (GameObject* pChest3 = instance->GetGameObject(m_uiTributeChest3GUID))
+ if (pChest3 && !pChest3->isSpawned()) pChest3->SetRespawnTime(7*DAY);
+ if (m_uiTributeChest4GUID)
+ if (GameObject* pChest4 = instance->GetGameObject(m_uiTributeChest4GUID))
+ if (pChest4 && !pChest4->isSpawned()) pChest4->SetRespawnTime(7*DAY);
+ };
+ break;
+ case TYPE_COUNTER: m_auiEncounter[7] = uiData; uiData = DONE; break;
+ case TYPE_EVENT: m_auiEncounter[8] = uiData; uiData = NOT_STARTED; break;
+ case TYPE_EVENT_TIMER: m_auiEventTimer = uiData; uiData = NOT_STARTED; break;
+ case TYPE_NORTHREND_BEASTS: m_auiNorthrendBeasts = uiData; break;
+ case DATA_HEALTH_FJOLA: m_uiDataDamageFjola = uiData; uiData = NOT_STARTED; break;
+ case DATA_HEALTH_EYDIS: m_uiDataDamageEydis = uiData; uiData = NOT_STARTED; break;
+ case DATA_CASTING_VALKYRS: m_uiValkyrsCasting = uiData; uiData = NOT_STARTED; break;
+ }
+
+ if (IsEncounterInProgress()) {
+ CloseDoor(GetData64(GO_WEST_PORTCULLIS));
+ CloseDoor(GetData64(GO_NORTH_PORTCULLIS));
+// CloseDoor(GetData64(GO_SOUTH_PORTCULLIS));
+ }
+ else {
+ OpenDoor(GetData64(GO_WEST_PORTCULLIS));
+ OpenDoor(GetData64(GO_NORTH_PORTCULLIS));
+// OpenDoor(GetData64(GO_SOUTH_PORTCULLIS));
+ };
+
+ if (uiData == FAIL && uiType != TYPE_STAGE
+ && uiType != TYPE_EVENT
+ && uiType != TYPE_COUNTER
+ && uiType != TYPE_EVENT_TIMER)
+ { if (IsRaidWiped()) { --m_auiEncounter[7];
+ needsave = true;
+ }
+ uiData = NOT_STARTED;
}
- if (uiData == DONE)
+ if ((uiData == DONE && uiType != TYPE_STAGE
+ && uiType != TYPE_EVENT
+ && uiType != TYPE_EVENT_TIMER)
+ || needsave == true)
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
- saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
- << m_auiEncounter[3] << " " << m_auiEncounter[4];
- strInstData = saveStream.str();
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ m_strInstData = saveStream.str();
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE;
+ needsave = false;
}
}
- uint32 GetData(uint32 uiType)
+ uint64 GetData64(uint32 uiData)
{
- switch(uiType)
+ switch(uiData)
{
- case TYPE_NORTHREND_BEASTS: return m_auiEncounter[0];
- case TYPE_JARAXXUS: return m_auiEncounter[1];
- case TYPE_FACTION_CHAMPIONS: return m_auiEncounter[2];
- case TYPE_TWIN_VALKYR: return m_auiEncounter[3];
- case TYPE_ANUBARAK: return m_auiEncounter[4];
+ case NPC_BARRENT: return m_uiBarrentGUID;
+ case NPC_TIRION: return m_uiTirionGUID;
+ case NPC_FIZZLEBANG: return m_uiFizzlebangGUID;
+ case NPC_GARROSH: return m_uiGarroshGUID;
+ case NPC_RINN: return m_uiRinnGUID;
+ case NPC_LICH_KING_0: return m_uiLich0GUID;
+ case NPC_LICH_KING_1: return m_uiLich1GUID;
+
+ case NPC_GORMOK: return m_uiGormokGUID;
+ case NPC_ACIDMAW: return m_uiAcidmawGUID;
+ case NPC_DREADSCALE: return m_uiDreadscaleGUID;
+ case NPC_ICEHOWL: return m_uiIcehowlGUID;
+ case NPC_JARAXXUS: return m_uiJaraxxusGUID;
+ case NPC_DARKBANE: return m_uiDarkbaneGUID;
+ case NPC_LIGHTBANE: return m_uiLightbaneGUID;
+ case NPC_ANUBARAK: return m_uiAnubarakGUID;
+
+ case NPC_CRUSADER_1_1: return m_uiCrusader11Guid;
+ case NPC_CRUSADER_1_2: return m_uiCrusader12Guid;
+ case NPC_CRUSADER_1_3: return m_uiCrusader13Guid;
+ case NPC_CRUSADER_1_4: return m_uiCrusader14Guid;
+ case NPC_CRUSADER_1_5: return m_uiCrusader15Guid;
+ case NPC_CRUSADER_1_6: return m_uiCrusader16Guid;
+ case NPC_CRUSADER_1_7: return m_uiCrusader17Guid;
+ case NPC_CRUSADER_1_8: return m_uiCrusader18Guid;
+ case NPC_CRUSADER_1_9: return m_uiCrusader19Guid;
+ case NPC_CRUSADER_1_10: return m_uiCrusader1aGuid;
+ case NPC_CRUSADER_1_11: return m_uiCrusader1bGuid;
+ case NPC_CRUSADER_1_12: return m_uiCrusader1cGuid;
+ case NPC_CRUSADER_1_13: return m_uiCrusader1dGuid;
+ case NPC_CRUSADER_1_14: return m_uiCrusader1eGuid;
+
+ case NPC_CRUSADER_2_1: return m_uiCrusader21Guid;
+ case NPC_CRUSADER_2_2: return m_uiCrusader22Guid;
+ case NPC_CRUSADER_2_3: return m_uiCrusader23Guid;
+ case NPC_CRUSADER_2_4: return m_uiCrusader24Guid;
+ case NPC_CRUSADER_2_5: return m_uiCrusader25Guid;
+ case NPC_CRUSADER_2_6: return m_uiCrusader26Guid;
+ case NPC_CRUSADER_2_7: return m_uiCrusader27Guid;
+ case NPC_CRUSADER_2_8: return m_uiCrusader28Guid;
+ case NPC_CRUSADER_2_9: return m_uiCrusader29Guid;
+ case NPC_CRUSADER_2_10: return m_uiCrusader2aGuid;
+ case NPC_CRUSADER_2_11: return m_uiCrusader2bGuid;
+ case NPC_CRUSADER_2_12: return m_uiCrusader2cGuid;
+ case NPC_CRUSADER_2_13: return m_uiCrusader2dGuid;
+ case NPC_CRUSADER_2_14: return m_uiCrusader2eGuid;
+
+ case NPC_CRUSADER_0_1: return m_uiCrusader01Guid;
+ case NPC_CRUSADER_0_2: return m_uiCrusader02Guid;
+
+ case GO_ARGENT_COLISEUM_FLOOR: return m_uiFloorGUID;
+ case GO_MAIN_GATE_DOOR: return m_uiMainGateDoorGUID;
+
+ case GO_SOUTH_PORTCULLIS: return m_uiSouthPortcullisGUID;
+ case GO_WEST_PORTCULLIS: return m_uiWestPortcullisGUID;
+ case GO_NORTH_PORTCULLIS: return m_uiNorthPortcullisGUID;
+
}
return 0;
}
- uint64 GetData64(uint32 uiData)
+ uint32 GetData(uint32 uiType)
{
- switch(uiData)
+ switch(uiType)
{
- case DATA_GORMOK: return m_uiGormokGUID;
- case DATA_ACIDMAW: return m_uiAcidmawGUID;
- case DATA_DREADSCALE: return m_uiDreadscaleGUID;
- case DATA_ICEHOWL: return m_uiIcehowlGUID;
- case DATA_JARAXXUS: return m_uiJaraxxusGUID;
- case DATA_FJOLA: return m_uiFjolaGUID;
- case DATA_EYDIS: return m_uiEydisGUID;
- case DATA_ANUBARAK: return m_uiAnubarakGUID;
+ case TYPE_STAGE: return m_auiEncounter[0];
+ case TYPE_BEASTS: return m_auiEncounter[1];
+ case TYPE_JARAXXUS: return m_auiEncounter[2];
+ case TYPE_CRUSADERS: return m_auiEncounter[3];
+ case TYPE_VALKIRIES: return m_auiEncounter[4];
+ case TYPE_LICH_KING: return m_auiEncounter[5];
+ case TYPE_ANUBARAK: return m_auiEncounter[6];
+ case TYPE_COUNTER: return m_auiEncounter[7];
+ case TYPE_EVENT: return m_auiEncounter[8];
+ case TYPE_DIFFICULTY: return Difficulty;
+ case TYPE_NORTHREND_BEASTS: return m_auiNorthrendBeasts;
+ case TYPE_EVENT_TIMER: return m_auiEventTimer;
+ case TYPE_CRUSADERS_COUNT: return m_auiCrusadersCount;
+ case TYPE_EVENT_NPC: switch (m_auiEncounter[8])
+ {
+ case 110:
+ case 140:
+ case 150:
+ case 200:
+ case 205:
+ case 210:
+ case 300:
+ case 305:
+ case 310:
+ case 400:
+ case 666:
+ case 1010:
+ case 1180:
+ case 2000:
+ case 2030:
+ case 3000:
+ case 3001:
+ case 3060:
+ case 3061:
+ case 3090:
+ case 3091:
+ case 3100:
+ case 3110:
+ case 4000:
+ case 4010:
+ case 4015:
+ case 4040:
+ case 4050:
+ case 5000:
+ case 5005:
+ case 5020:
+ case 6000:
+ case 6005:
+ case 6010:
+ m_auiEventNPCId = NPC_TIRION;
+ break;
+
+ case 5010:
+ case 5030:
+ case 5040:
+ case 5050:
+ case 5060:
+ case 5070:
+ case 5080:
+ m_auiEventNPCId = NPC_LICH_KING_1;
+ break;
+
+ case 130:
+ case 132:
+ case 2020:
+ case 3080:
+ case 3051:
+ case 3071:
+ case 4020:
+ m_auiEventNPCId = NPC_RINN;
+ break;
+
+ case 120:
+ case 122:
+ case 2010:
+ case 3050:
+ case 3070:
+ case 3081:
+ case 4030:
+ m_auiEventNPCId = NPC_GARROSH;
+ break;
+
+ case 1110:
+ case 1120:
+ case 1130:
+ case 1132:
+ case 1134:
+ case 1135:
+ case 1140:
+ case 1142:
+ case 1144:
+ case 1145:
+ case 1150:
+ case 1160:
+ m_auiEventNPCId = NPC_FIZZLEBANG;
+ break;
+
+ default:
+ m_auiEventNPCId = NPC_TIRION;
+ break;
+
+ };
+ return m_auiEventNPCId;
+
+ case DATA_HEALTH_FJOLA: return m_uiDataDamageFjola;
+ case DATA_HEALTH_EYDIS: return m_uiDataDamageEydis;
+ case DATA_CASTING_VALKYRS: return m_uiValkyrsCasting;
}
return 0;
}
const char* Save()
{
- return strInstData.c_str();
+ return m_strInstData.c_str();
}
- void Load(const char* chrIn)
+ void Load(const char* strIn)
{
- if (!chrIn)
+ if (!strIn)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
- OUT_LOAD_INST_DATA(chrIn);
+ OUT_LOAD_INST_DATA(strIn);
- std::istringstream loadStream(chrIn);
- loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
- >> m_auiEncounter[4];
+ std::istringstream loadStream(strIn);
- for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead.
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
+
+ if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
+ }
+ m_auiEncounter[TYPE_EVENT] = 0;
+ m_auiEncounter[TYPE_STAGE] = 0;
OUT_LOAD_INST_DATA_COMPLETE;
+
}
};
@@ -190,8 +611,7 @@ InstanceData* GetInstanceData_instance_trial_of_the_crusader(Map* pMap)
void AddSC_instance_trial_of_the_crusader()
{
- Script* newscript;
-
+ Script *newscript;
newscript = new Script;
newscript->Name = "instance_trial_of_the_crusader";
newscript->GetInstanceData = &GetInstanceData_instance_trial_of_the_crusader;
diff --git a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp
index 48ac55f..de3f3a8 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,123 +15,1383 @@
*/
/* ScriptData
-SDName: trial_of_the_crusader
-SD%Complete: 0
-SDComment:
-SDCategory: Crusader Coliseum
+SDName: Trial Of the crusader
+SD%Complete: 60%
+SDComment: event script by /dev/rsa
+SDCategory: trial_of_the_crusader
EndScriptData */
#include "precompiled.h"
#include "trial_of_the_crusader.h"
+struct _Messages
+{
+ AnnounserMessages msgnum;
+ uint32 id;
+ bool state;
+ uint32 encounter;
+};
+
+static _Messages _GossipMessage[]=
+{
+{MSG_BEASTS,GOSSIP_ACTION_INFO_DEF+1,false,TYPE_BEASTS}, //
+{MSG_JARAXXUS,GOSSIP_ACTION_INFO_DEF+2,false,TYPE_JARAXXUS}, //
+{MSG_CRUSADERS,GOSSIP_ACTION_INFO_DEF+3,false,TYPE_CRUSADERS}, //
+{MSG_VALKIRIES,GOSSIP_ACTION_INFO_DEF+4,false,TYPE_VALKIRIES}, //
+{MSG_LICH_KING,GOSSIP_ACTION_INFO_DEF+5,false,TYPE_ANUBARAK}, //
+{MSG_ANUBARAK,GOSSIP_ACTION_INFO_DEF+6,true,TYPE_ANUBARAK}, //
+};
+
enum
{
- SAY_TIRION_RAID_INTRO_LONG = -1649000,
- SAY_RAID_TRIALS_INTRO = -1649001,
-
- // Northrend Beasts
- SAY_TIRION_BEAST_1 = -1649002,
- SAY_VARIAN_BEAST_1 = -1649003,
- SAY_GARROSH_BEAST_1 = -1649004,
- SAY_TIRION_BEAST_2 = -1649005,
- SAY_TIRION_BEAST_3 = -1649006,
- SAY_TIRION_BEAST_SLAY = -1649007,
- SAY_TIRION_BEAST_WIPE = -1649008,
-
- // Jaraxxus Encounter
- SAY_TIRION_JARAXXUS_INTRO_1 = -1649009,
- SAY_WILFRED_JARAXXUS_INTRO_1 = -1649010,
- SAY_WILFRED_JARAXXUS_INTRO_2 = -1649011,
- SAY_WILFRED_JARAXXUS_INTRO_3 = -1649012,
- SAY_JARAXXUS_JARAXXAS_INTRO_1 = -1649013,
- SAY_WILFRED_DEATH = -1649014,
- SAY_TIRION_JARAXXUS_INTRO_2 = -1649015,
- SAY_TIRION_JARAXXUS_EXIT_1 = -1649016,
- SAY_GARROSH_JARAXXUS_EXIT_1 = -1649017,
- SAY_VARIAN_JARAXXUS_SLAY = -1649018,
- SAY_TIRION_JARAXXUS_EXIT_2 = -1649019,
-
- // Faction-Champions
- SAY_TIRION_PVP_INTRO_1 = -1649020,
- SAY_GARROSH_PVP_A_INTRO_1 = -1649021,
- SAY_VARIAN_PVP_H_INTRO_1 = -1649022,
- SAY_TIRION_PVP_INTRO_2 = -1649023,
- SAY_VARIAN_PVP_A_INTRO_2 = -1649024,
- SAY_GARROSH_PVP_H_INTRO_2 = -1649025,
- SAY_VARIAN_PVP_A_WIN = -1649026,
- SAY_GARROSH_PVP_H_WIN = -1649027,
- SAY_TIRION_PVP_WIN = -1649028,
-
- // Twin Valkyrs
- SAY_TIRION_TWINS_INTRO = -1649029,
- SAY_RAID_INTRO_SHORT = -1649030,
- SAY_VARIAN_TWINS_A_WIN = -1649031,
- SAY_GARROSH_TWINS_H_WIN = -1649032,
- SAY_TIRION_TWINS_WIN = -1649033,
-
- // Anub'Arak Encounter
- SAY_LKING_ANUB_INTRO_1 = -1649034,
- SAY_TIRION_ABUN_INTRO_1 = -1649035,
- SAY_LKING_ANUB_INTRO_2 = -1649036,
- SAY_LKING_ANUB_INTRO_3 = -1649037,
- SAY_ANUB_ANUB_INTRO_1 = -1649038,
-
- NPC_GORMOK = 34796,
- NPC_JARAXXUS = 34780,
-
- GOSSIP_ITEM_START_EVENT1 = -3649000
+ NUM_MESSAGES = 6,
+ SPELL_WILFRED_PORTAL = 68424,
+ SPELL_JARAXXUS_CHAINS = 67924,
};
-/*######
-## npc_barrett_ramsey
-######*/
-struct MANGOS_DLL_DECL npc_barrett_ramseyAI : public ScriptedAI
+struct MANGOS_DLL_DECL npc_toc_announcerAI : public ScriptedAI
{
- npc_barrett_ramseyAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+ npc_toc_announcerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
- ScriptedInstance* m_pInstance;
+ ScriptedInstance* pInstance;
+ uint32 DelayTimer;
+ uint32 substage;
- void Reset() {}
+ void Reset()
+ {
+ if (!pInstance) return;
+ pInstance->SetData(TYPE_STAGE,0);
+ DelayTimer = 0;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if(Creature *pAlly = GetClosestCreatureWithEntry(m_creature, NPC_THRALL, 300.0f))
+ pAlly->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if(Creature *pAlly = GetClosestCreatureWithEntry(m_creature, NPC_PROUDMOORE, 300.0f))
+ pAlly->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetRespawnDelay(DAY);
+ }
- void StartEvent(Player* pPlayer)
+ void AttackStart(Unit *who)
{
- // code starting the event here
+ //ignore all attackstart commands
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!pInstance) return;
+
+ if(DelayTimer < diff) {
+ switch (pInstance->GetData(TYPE_STAGE)) {
+ case 0: break;
+ case 1: {
+ if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == GORMOK_DONE) {
+ pInstance->SetData(TYPE_STAGE,2);
+ pInstance->SetData(TYPE_EVENT,200);
+ pInstance->SetData(TYPE_NORTHREND_BEASTS,SNAKES_IN_PROGRESS);
+ pInstance->SetData(TYPE_BEASTS,IN_PROGRESS);
+ };
+ if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == FAIL) {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_EVENT,666);
+ pInstance->SetData(TYPE_BEASTS,NOT_STARTED);
+ };
+ break;
+ };
+ case 2: {
+ if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_DONE) {
+ pInstance->SetData(TYPE_STAGE,3);
+ pInstance->SetData(TYPE_EVENT,300);
+ pInstance->SetData(TYPE_NORTHREND_BEASTS,ICEHOWL_IN_PROGRESS);
+ pInstance->SetData(TYPE_BEASTS,IN_PROGRESS);
+ };
+ if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == FAIL) {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_EVENT,666);
+ pInstance->SetData(TYPE_BEASTS,NOT_STARTED);
+ };
+ break;
+ }
+ case 3: {
+ if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == ICEHOWL_DONE) {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_BEASTS,DONE);
+ pInstance->SetData(TYPE_EVENT,400);
+ pInstance->SetData(TYPE_NORTHREND_BEASTS,DONE);
+ }
+ if (pInstance->GetData(TYPE_NORTHREND_BEASTS) == FAIL) {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_EVENT,666);
+ pInstance->SetData(TYPE_BEASTS,NOT_STARTED);
+ };
+ break;
+ };
+
+ case 4: {
+ break;
+ };
+
+ case 5: {
+ break;
+ };
+
+ case 6: {
+ if (pInstance->GetData(TYPE_CRUSADERS_COUNT) == 0
+ && pInstance->GetData(TYPE_CRUSADERS) == IN_PROGRESS)
+ {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_CRUSADERS,DONE);
+ pInstance->SetData(TYPE_EVENT,3100);
+ }
+ break;
+ };
+
+ case 7: {
+ if (pInstance->GetData(TYPE_VALKIRIES) == DONE) {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_EVENT,4020);
+ }
+ if (pInstance->GetData(TYPE_VALKIRIES) == FAIL) {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_EVENT,0);
+ }
+ break;
+ };
+ case 8: {
+ break;
+ };
+ case 9: {
+ if (pInstance->GetData(TYPE_ANUBARAK) == DONE) {
+ pInstance->SetData(TYPE_STAGE,10);
+ pInstance->SetData(TYPE_EVENT,6000);
+ }
+ if (pInstance->GetData(TYPE_ANUBARAK) == FAIL) {
+ pInstance->SetData(TYPE_STAGE,0);
+ pInstance->SetData(TYPE_EVENT,0);
+ }
+ break;
+ };
+ case 10: {
+// m_creature->ForcedDespawn();
+ break;
+ };
+
+ }
+ } else DelayTimer -= diff;
}
};
-bool GossipHello_npc_barrett_ramsey(Player* pPlayer, Creature* pCreature)
+CreatureAI* GetAI_npc_toc_announcer(Creature* pCreature)
{
- pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START_EVENT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return new npc_toc_announcerAI(pCreature);
+}
+
+bool GossipHello_npc_toc_announcer(Player* pPlayer, Creature* pCreature)
+{
+
+ ScriptedInstance* pInstance;
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ char const* _message;
+ uint8 i;
+
+ if (!pInstance) return false;
+
+ if( !pPlayer->getAttackers().empty() ||
+ pInstance->IsEncounterInProgress() ||
+ pInstance->GetData(TYPE_EVENT))
+ return true;
+
+ switch (LocaleConstant currentlocale = pPlayer->GetSession()->GetSessionDbcLocale())
+ {
+ case LOCALE_enUS:
+ case LOCALE_koKR:
+ case LOCALE_frFR:
+ case LOCALE_deDE:
+ case LOCALE_zhCN:
+ case LOCALE_zhTW:
+ case LOCALE_esES:
+ case LOCALE_esMX:
+ _message = "We are ready!";
+ break;
+ case LOCALE_ruRU:
+ _message = "Ð’Ñегда готовы!";
+ break;
+ default:
+ _message = "We are ready!";
+ break;
+ };
+
+ for(i = 0; i < NUM_MESSAGES; i++) {
+ if (!_GossipMessage[i].state && (pInstance->GetData(_GossipMessage[i].encounter) != DONE )) {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _message, GOSSIP_SENDER_MAIN,_GossipMessage[i].id);
+ break;
+ }
+ if (_GossipMessage[i].state && pInstance->GetData(_GossipMessage[i].encounter) == DONE) {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _message, GOSSIP_SENDER_MAIN,_GossipMessage[i].id);
+ break;
+ }
+ };
+
+ pPlayer->SEND_GOSSIP_MENU(_GossipMessage[i].msgnum, pCreature->GetGUID());
+
return true;
}
-bool GossipSelect_npc_barrett_ramsey(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+bool GossipSelect_npc_toc_announcer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
- if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ ScriptedInstance* pInstance;
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ if (!pInstance) return false;
+
+pPlayer->CLOSE_GOSSIP_MENU();
+
+switch(uiAction) {
+ case GOSSIP_ACTION_INFO_DEF+1: {
+ if (pInstance->GetData(TYPE_BEASTS) != DONE) {
+ pInstance->SetData(TYPE_EVENT,110);
+ pInstance->SetData(TYPE_NORTHREND_BEASTS,NOT_STARTED);
+ pInstance->SetData(TYPE_BEASTS,IN_PROGRESS);
+ };
+ break;
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+2: {
+ if (pInstance->GetData(TYPE_JARAXXUS) != DONE)
+ pInstance->SetData(TYPE_EVENT,1010);
+ break;
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+3: {
+ if (pInstance->GetData(TYPE_CRUSADERS) != DONE) {
+ if (pPlayer->GetTeam() == ALLIANCE) pInstance->SetData(TYPE_EVENT,3000);
+ else pInstance->SetData(TYPE_EVENT,3001);
+ };
+ break;
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+4: {
+ if (pInstance->GetData(TYPE_VALKIRIES) != DONE)
+ pInstance->SetData(TYPE_EVENT,4000);
+ break;
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+5: {
+ if (pInstance->GetData(TYPE_LICH_KING) != DONE) return false;
+ if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
+ {
+ pGoFloor->SetUInt32Value(GAMEOBJECT_DISPLAYID,9060);
+ pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
+ pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449);
+ }
+ pCreature->CastSpell(pCreature,69016,false);
+
+ Creature* pTemp = pCreature->GetMap()->GetCreature(pInstance->GetData64(NPC_ANUBARAK));
+ if (!pTemp || !pTemp->isAlive())
+ pCreature->SummonCreature(NPC_ANUBARAK, SpawnLoc[19].x, SpawnLoc[19].y, SpawnLoc[19].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (pTemp) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[20].x, SpawnLoc[20].y, SpawnLoc[20].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ pInstance->SetData(TYPE_STAGE,9);
+ pInstance->SetData(TYPE_ANUBARAK,IN_PROGRESS);
+ if (pCreature->GetVisibility() == VISIBILITY_ON)
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ break;
+ };
+
+ case GOSSIP_ACTION_INFO_DEF+6: {
+ pInstance->SetData(TYPE_STAGE,10);
+ break;
+ };
+
+ };
+
+return true;
+}
+
+struct MANGOS_DLL_DECL boss_lich_king_tocAI : public ScriptedAI
+{
+ boss_lich_king_tocAI(Creature *pCreature) : ScriptedAI(pCreature)
{
- pPlayer->CLOSE_GOSSIP_MENU();
- if (npc_barrett_ramseyAI* pBarrettAI = dynamic_cast(pCreature->AI()))
- pBarrettAI->StartEvent(pPlayer);
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ WayPointList.clear();
+ JustRespawned();
}
- return true;
+ ScriptedInstance* pInstance;
+ uint32 UpdateTimer;
+ uint32 event_state_lich_king;
+ bool Event;
+ bool MovementStarted;
+ std::list WayPointList;
+ std::list::iterator WayPoint;
+ uint32 WalkTimer;
+ bool IsWalking;
+ Creature* pPortal;
+
+ void Reset()
+ {
+ UpdateTimer = 0;
+ event_state_lich_king = 0;
+ Event = false;
+ MovementStarted = false;
+ m_creature->SetRespawnDelay(DAY);
+ pPortal = m_creature->SummonCreature(NPC_TRIGGER, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ pPortal->SetRespawnDelay(DAY);
+ pPortal->CastSpell(pPortal, 51807, false);
+ pPortal->SetDisplayId(17612);
+ if(pInstance) pInstance->SetData(TYPE_LICH_KING,IN_PROGRESS);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void JustRespawned()
+ {
+ Reset();
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ }
+
+ void StartMovement()
+ {
+ if(!WayPointList.empty() || MovementStarted)
+ return;
+
+ AddWaypoint(0, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z);
+ AddWaypoint(1, SpawnLoc[17].x, SpawnLoc[17].y, SpawnLoc[17].z);
+ AddWaypoint(2, SpawnLoc[18].x, SpawnLoc[18].y, SpawnLoc[18].z);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ WayPoint = WayPointList.begin();
+ MovementStarted = true;
+ IsWalking = true;
+ WalkTimer = 200;
+ event_state_lich_king = 1;
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+ }
+
+ void AddWaypoint(uint32 id, float x, float y, float z)
+ {
+ WayPoints wp(id, x, y, z);
+ WayPointList.push_back(wp);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if(!pInstance) return;
+ if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_LICH_KING_1) return;
+ if (!MovementStarted) StartMovement();
+
+ if (IsWalking && WalkTimer)
+ {
+ if (WalkTimer <= diff)
+ {
+ if (WayPoint != WayPointList.end())
+ {
+ m_creature->GetMotionMaster()->MovePoint(WayPoint->id, WayPoint->x, WayPoint->y,WayPoint->z);
+ WalkTimer = 0;
+ }
+ }else WalkTimer -= diff;
+ }
+
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+
+ if (UpdateTimer <= diff)
+ {
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 5010:
+ DoScriptText(-1713550,m_creature);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,5020);
+ break;
+ case 5030:
+ DoScriptText(-1713552,m_creature);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,5040);
+ break;
+ case 5040:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ UpdateTimer = 1000;
+ pInstance->SetData(TYPE_EVENT,5050);
+ break;
+ case 5050:
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,5060);
+ break;
+ case 5060: if (Event) {
+ DoScriptText(-1713553,m_creature);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
+ UpdateTimer = 2500;
+ pInstance->SetData(TYPE_EVENT,5070);
+ }
+ break;
+ case 5070:
+ m_creature->CastSpell(m_creature,68198,false);
+ UpdateTimer = 1500;
+ pInstance->SetData(TYPE_EVENT,5080);
+ break;
+ case 5080:
+ if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
+ {
+ pGoFloor->SetUInt32Value(GAMEOBJECT_DISPLAYID,9060);
+ pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
+ pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449);
+ }
+ m_creature->CastSpell(m_creature,69016,false);
+ if(pInstance) pInstance->SetData(TYPE_LICH_KING,DONE);
+
+ pInstance->SetData(TYPE_ANUBARAK,IN_PROGRESS);
+ m_creature->SummonCreature(NPC_ANUBARAK, SpawnLoc[19].x, SpawnLoc[19].y, SpawnLoc[19].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ANUBARAK))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[20].x, SpawnLoc[20].y, SpawnLoc[20].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ pInstance->SetData(TYPE_STAGE,9);
+ Event=false;
+ m_creature->ForcedDespawn();
+ pPortal->ForcedDespawn();
+ pInstance->SetData(TYPE_EVENT,0);
+ UpdateTimer = 20000;
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if(pInstance)
+ {
+ if(id == 2)
+ {
+ Event = true;
+ }
+ }
+ if(type != POINT_MOTION_TYPE) return;
+ if(WayPoint->id != id) return;
+ ++WayPoint;
+ WalkTimer = 200;
+ }
+};
+
+CreatureAI* GetAI_boss_lich_king_toc(Creature* pCreature)
+{
+ return new boss_lich_king_tocAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL npc_fizzlebang_tocAI : public ScriptedAI
+{
+ npc_fizzlebang_tocAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)m_creature->GetInstanceData();
+ Reset();
+ }
+
+ InstanceData* pInstance;
+ uint32 UpdateTimer;
+ Creature* pPortal;
+ Creature* pTrigger;
+
+ void JustDied(Unit* pKiller)
+ {
+ DoScriptText(-1713715, m_creature, pKiller);
+ pInstance->SetData(TYPE_EVENT, 1180);
+ if (pPortal) pPortal->ForcedDespawn();
+ }
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[27].x, SpawnLoc[27].y, SpawnLoc[27].z);
+ pPortal = NULL;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!pInstance) return;
+
+ if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_FIZZLEBANG) return;
+
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+ if(UpdateTimer <= diff)
+ {
+ switch(pInstance->GetData(TYPE_EVENT))
+ {
+ case 1110:
+ pInstance->SetData(TYPE_EVENT, 1120);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_JARAXXUS,IN_PROGRESS);
+ break;
+ case 1120:
+ DoScriptText(-1713511, m_creature);
+ pInstance->SetData(TYPE_EVENT, 1130);
+ UpdateTimer = 12000;
+ break;
+ case 1130:
+ m_creature->GetMotionMaster()->MovementExpired();
+ m_creature->HandleEmoteCommand(EMOTE_STATE_SPELL_CHANNEL_OMNI);
+ pPortal = m_creature->SummonCreature(NPC_WILFRED_PORTAL, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 5, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ if (pPortal) {
+ pPortal->SetRespawnDelay(DAY);
+ pPortal->SetDisplayId(22862);
+ }
+ DoScriptText(-1713512, m_creature);
+ pInstance->SetData(TYPE_EVENT, 1132);
+ UpdateTimer = 4000;
+ break;
+ case 1132:
+ m_creature->GetMotionMaster()->MovementExpired();
+ if (pPortal) pPortal->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.5f);
+ pInstance->SetData(TYPE_EVENT, 1134);
+ UpdateTimer = 4000;
+ break;
+ case 1134:
+ if (pPortal) pPortal->SetDisplayId(15900);
+ pTrigger = m_creature->SummonCreature(NPC_TRIGGER, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 5.0f, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ if (pTrigger) {
+ pTrigger->SetDisplayId(17612);
+ pTrigger->CastSpell(pTrigger, SPELL_WILFRED_PORTAL, false);
+ pTrigger->SetRespawnDelay(DAY);
+ }
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST_OMNI);
+ UpdateTimer = 4000;
+ pInstance->SetData(TYPE_EVENT, 1135);
+ break;
+ case 1135:
+ if (pTrigger) pTrigger->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST_OMNI);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT, 1140);
+ break;
+ case 1140:
+ pInstance->SetData(TYPE_STAGE,4);
+ m_creature->SummonCreature(NPC_JARAXXUS, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_JARAXXUS))) {
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->CastSpell(pTemp, SPELL_JARAXXUS_CHAINS, false);
+ }
+ pInstance->SetData(TYPE_EVENT, 1142);
+ UpdateTimer = 5000;
+ break;
+ case 1142:
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT, 1144);
+ DoScriptText(-1713513, m_creature);
+ break;
+ case 1144:
+ if (pTrigger) pTrigger->ForcedDespawn();
+ pInstance->SetData(TYPE_EVENT, 1150);
+ UpdateTimer = 5000;
+ break;
+ case 1150:
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_JARAXXUS))) {
+ pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
+ pTemp->SetInCombatWithZone();
+ m_creature->SetInCombatWith(pTemp);
+ pTemp->AddThreat(m_creature, 1000.0f);
+ pTemp->AI()->AttackStart(m_creature);
+ }
+ DoScriptText(-1713515, m_creature);
+ pInstance->SetData(TYPE_EVENT, 1160);
+ UpdateTimer = 3000;
+ break;
+ case 1160:
+ pInstance->SetData(TYPE_EVENT, 1170);
+ UpdateTimer = 1000;
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+ }
+};
+
+CreatureAI* GetAI_npc_fizzlebang_toc(Creature* pCreature)
+{
+ return new npc_fizzlebang_tocAI(pCreature);
}
-CreatureAI* GetAI_npc_barrett_ramsey(Creature* pCreature)
+struct MANGOS_DLL_DECL npc_tirion_tocAI : public ScriptedAI
+{
+ npc_tirion_tocAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)m_creature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ uint32 UpdateTimer;
+ uint32 crusader[12];
+ uint8 crusaderscount;
+
+ void Reset()
+ {
+ crusaderscount = 0;
+ memset(&crusader, 0, sizeof(crusader));
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!pInstance) return;
+ if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_TIRION) return;
+
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+
+ if (UpdateTimer <= diff)
+ {
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 110:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
+ DoScriptText(-1713500, m_creature);
+ UpdateTimer = 12000;
+ pInstance->SetData(TYPE_EVENT,120);
+// pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_WEST_PORTCULLIS));
+ break;
+ case 140:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
+ DoScriptText(-1713501, m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,150);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+ case 150:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
+ if (pInstance->GetData(TYPE_BEASTS) != DONE) {
+ m_creature->SummonCreature(NPC_GORMOK, SpawnLoc[26].x, SpawnLoc[26].y, SpawnLoc[26].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_GORMOK))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ }
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,160);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ pInstance->SetData(TYPE_STAGE,1);
+ pInstance->SetData(TYPE_BEASTS,IN_PROGRESS);
+ break;
+
+ case 200:
+ DoScriptText(-1713503, m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,205);
+ break;
+
+ case 205:
+ UpdateTimer = 8000;
+ pInstance->SetData(TYPE_EVENT,210);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+
+ case 210:
+ if (pInstance->GetData(TYPE_BEASTS) != DONE){
+ m_creature->SummonCreature(NPC_DREADSCALE, SpawnLoc[3].x, SpawnLoc[3].y, SpawnLoc[3].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ m_creature->SummonCreature(NPC_ACIDMAW, SpawnLoc[4].x, SpawnLoc[4].y, SpawnLoc[4].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_DREADSCALE))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ACIDMAW))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ }
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,220);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+ case 300:
+ DoScriptText(-1713505, m_creature);
+ UpdateTimer = 15000;
+ pInstance->SetData(TYPE_EVENT,305);
+ break;
+ case 305:
+ UpdateTimer = 8000;
+ pInstance->SetData(TYPE_EVENT,310);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+ case 310:
+ if (pInstance->GetData(TYPE_BEASTS) != DONE) {
+ m_creature->SummonCreature(NPC_ICEHOWL, SpawnLoc[26].x, SpawnLoc[26].y, SpawnLoc[26].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ICEHOWL))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ }
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,320);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+ case 400:
+ DoScriptText(-1713509, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,0);
+// pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_WEST_PORTCULLIS));
+ break;
+
+ case 666:
+ DoScriptText(-1713709, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,0);
+ pInstance->SetData(TYPE_NORTHREND_BEASTS,NOT_STARTED);
+// pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_WEST_PORTCULLIS));
+ break;
+
+ case 1010:
+ DoScriptText(-1713510, m_creature);
+ UpdateTimer = 5000;
+ m_creature->SummonCreature(NPC_FIZZLEBANG, SpawnLoc[21].x, SpawnLoc[21].y, SpawnLoc[21].z, 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ pInstance->SetData(TYPE_EVENT,1110);
+ break;
+
+ case 1180:
+ DoScriptText(-1713516, m_creature);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,0);
+ break;
+
+ case 2000:
+ DoScriptText(-1713526, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,2010);
+ break;
+ case 2030:
+ DoScriptText(-1713529, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,0);
+ break;
+ case 3000:
+ DoScriptText(-1713530, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3050);
+ break;
+ case 3001:
+ DoScriptText(-1713530, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3051);
+ break;
+ case 3060:
+ DoScriptText(-1713532, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3070);
+ break;
+ case 3061:
+ DoScriptText(-1713532, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3071);
+ break;
+//Summoning crusaders
+ case 3091:
+ pInstance->SetData(TYPE_STAGE,6);
+ if (pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_NORMAL
+ || pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_HEROIC)
+ {
+ crusaderscount = 12;
+ switch (urand(0,3)){ // Healers, 3 in 25-mode
+ case 0: crusader[0] = NPC_CRUSADER_1_1;
+ crusader[1] = NPC_CRUSADER_1_12;
+ crusader[2] = NPC_CRUSADER_1_13;
+ break;
+ case 1: crusader[0] = NPC_CRUSADER_1_1;
+ crusader[1] = NPC_CRUSADER_1_2;
+ crusader[2] = NPC_CRUSADER_1_13;
+ break;
+ case 2: crusader[0] = NPC_CRUSADER_1_1;
+ crusader[1] = NPC_CRUSADER_1_2;
+ crusader[2] = NPC_CRUSADER_1_12;
+ break;
+ case 3: crusader[0] = NPC_CRUSADER_1_2;
+ crusader[1] = NPC_CRUSADER_1_12;
+ crusader[2] = NPC_CRUSADER_1_13;
+ break;
+ }
+ switch (urand(0,5)){ // Random melee DD, 2 in 25-mode
+ case 0: crusader[3] = NPC_CRUSADER_1_3;
+ crusader[4] = NPC_CRUSADER_1_4;
+ break;
+ case 1: crusader[3] = NPC_CRUSADER_1_3;
+ crusader[4] = NPC_CRUSADER_1_5;
+ break;
+ case 2: crusader[3] = NPC_CRUSADER_1_3;
+ crusader[4] = NPC_CRUSADER_1_6;
+ break;
+ case 3: crusader[3] = NPC_CRUSADER_1_4;
+ crusader[4] = NPC_CRUSADER_1_5;
+ break;
+ case 4: crusader[3] = NPC_CRUSADER_1_4;
+ crusader[4] = NPC_CRUSADER_1_6;
+ break;
+ case 5: crusader[3] = NPC_CRUSADER_1_5;
+ crusader[4] = NPC_CRUSADER_1_6;
+ break;
+ }
+
+ switch (urand(0,3)){ // Random magic DD, 3 in 25-mode
+ case 0: crusader[5] = NPC_CRUSADER_1_7;
+ crusader[6] = NPC_CRUSADER_1_8;
+ crusader[7] = NPC_CRUSADER_1_11;
+ break;
+ case 1: crusader[5] = NPC_CRUSADER_1_7;
+ crusader[6] = NPC_CRUSADER_1_8;
+ crusader[7] = NPC_CRUSADER_1_14;
+ break;
+ case 2: crusader[5] = NPC_CRUSADER_1_8;
+ crusader[6] = NPC_CRUSADER_1_11;
+ crusader[7] = NPC_CRUSADER_1_14;
+ break;
+ case 3: crusader[5] = NPC_CRUSADER_1_7;
+ crusader[6] = NPC_CRUSADER_1_11;
+ crusader[7] = NPC_CRUSADER_1_14;
+ break;
+ }
+ crusader[8] = NPC_CRUSADER_1_9; //Hunter+warlock
+ crusader[9] = NPC_CRUSADER_1_10;
+ crusader[10] = NPC_CRUSADER_0_1;
+ crusader[11] = NPC_CRUSADER_0_2;
+
+ } else {
+ crusaderscount = 6;
+ switch (urand(0,5)){ // Healers, 2 in 10-mode
+ case 0: crusader[0] = NPC_CRUSADER_1_1;
+ crusader[1] = NPC_CRUSADER_1_12;
+ break;
+ case 1: crusader[0] = NPC_CRUSADER_1_1;
+ crusader[1] = NPC_CRUSADER_1_2;
+ break;
+ case 2: crusader[0] = NPC_CRUSADER_1_2;
+ crusader[1] = NPC_CRUSADER_1_12;
+ break;
+ case 3: crusader[0] = NPC_CRUSADER_1_1;
+ crusader[1] = NPC_CRUSADER_1_13;
+ break;
+ case 4: crusader[0] = NPC_CRUSADER_1_2;
+ crusader[1] = NPC_CRUSADER_1_13;
+ break;
+ case 5: crusader[0] = NPC_CRUSADER_1_12;
+ crusader[1] = NPC_CRUSADER_1_13;
+ break;
+ }
+ switch (urand(0,5)){ // Random melee DD, 2 in 10-mode
+ case 0: crusader[3] = NPC_CRUSADER_1_3;
+ crusader[2] = NPC_CRUSADER_1_4;
+ break;
+ case 1: crusader[3] = NPC_CRUSADER_1_3;
+ crusader[2] = NPC_CRUSADER_1_5;
+ break;
+ case 2: crusader[3] = NPC_CRUSADER_1_3;
+ crusader[2] = NPC_CRUSADER_1_6;
+ break;
+ case 3: crusader[3] = NPC_CRUSADER_1_4;
+ crusader[2] = NPC_CRUSADER_1_5;
+ break;
+ case 4: crusader[3] = NPC_CRUSADER_1_4;
+ crusader[2] = NPC_CRUSADER_1_6;
+ break;
+ case 5: crusader[3] = NPC_CRUSADER_1_5;
+ crusader[2] = NPC_CRUSADER_1_6;
+ break;
+ }
+
+ switch (urand(0,5)){ // Random magic DD, 2 in 10-mode
+ case 0: crusader[4] = NPC_CRUSADER_1_7;
+ crusader[5] = NPC_CRUSADER_1_8;
+ break;
+ case 1: crusader[5] = NPC_CRUSADER_1_7;
+ crusader[4] = NPC_CRUSADER_1_14;
+ break;
+ case 2: crusader[5] = NPC_CRUSADER_1_7;
+ crusader[4] = NPC_CRUSADER_1_11;
+ break;
+ case 3: crusader[5] = NPC_CRUSADER_1_8;
+ crusader[4] = NPC_CRUSADER_1_11;
+ break;
+ case 4: crusader[5] = NPC_CRUSADER_1_8;
+ crusader[4] = NPC_CRUSADER_1_14;
+ break;
+ case 5: crusader[5] = NPC_CRUSADER_1_11;
+ crusader[4] = NPC_CRUSADER_1_14;
+ break;
+ }
+
+ }
+ for(uint8 i = 0; i < crusaderscount; ++i)
+ {
+ m_creature->SummonCreature(crusader[i], SpawnLoc[i+2].x, SpawnLoc[i+2].y, SpawnLoc[i+2].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(crusader[i]))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+ }
+ pInstance->SetData(TYPE_CRUSADERS_COUNT,crusaderscount);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,0);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ pInstance->SetData(TYPE_CRUSADERS,IN_PROGRESS);
+ break;
+
+//summoning crusaders
+ case 3090:
+ pInstance->SetData(TYPE_STAGE,6);
+ if (pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_NORMAL
+ || pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_HEROIC)
+ {
+ crusaderscount = 12;
+ switch (urand(0,3)){ // Healers, 3 in 25-mode
+ case 0: crusader[0] = NPC_CRUSADER_2_1;
+ crusader[1] = NPC_CRUSADER_2_12;
+ crusader[2] = NPC_CRUSADER_2_13;
+ break;
+ case 1: crusader[0] = NPC_CRUSADER_2_1;
+ crusader[1] = NPC_CRUSADER_2_2;
+ crusader[2] = NPC_CRUSADER_2_13;
+ break;
+ case 2: crusader[0] = NPC_CRUSADER_2_1;
+ crusader[1] = NPC_CRUSADER_2_2;
+ crusader[2] = NPC_CRUSADER_2_12;
+ break;
+ case 3: crusader[0] = NPC_CRUSADER_2_2;
+ crusader[1] = NPC_CRUSADER_2_12;
+ crusader[2] = NPC_CRUSADER_2_13;
+ break;
+ }
+ switch (urand(0,5)){ // Random melee DD, 2 in 25-mode
+ case 0: crusader[3] = NPC_CRUSADER_2_3;
+ crusader[4] = NPC_CRUSADER_2_4;
+ break;
+ case 1: crusader[3] = NPC_CRUSADER_2_3;
+ crusader[4] = NPC_CRUSADER_2_5;
+ break;
+ case 2: crusader[3] = NPC_CRUSADER_2_3;
+ crusader[4] = NPC_CRUSADER_2_6;
+ break;
+ case 3: crusader[3] = NPC_CRUSADER_2_4;
+ crusader[4] = NPC_CRUSADER_2_5;
+ break;
+ case 4: crusader[3] = NPC_CRUSADER_2_4;
+ crusader[4] = NPC_CRUSADER_2_6;
+ break;
+ case 5: crusader[3] = NPC_CRUSADER_2_5;
+ crusader[4] = NPC_CRUSADER_2_6;
+ break;
+ }
+
+ switch (urand(0,3)){ // Random magic DD, 3 in 25-mode
+ case 0: crusader[5] = NPC_CRUSADER_2_7;
+ crusader[6] = NPC_CRUSADER_2_8;
+ crusader[7] = NPC_CRUSADER_2_11;
+ break;
+ case 1: crusader[5] = NPC_CRUSADER_2_7;
+ crusader[6] = NPC_CRUSADER_2_8;
+ crusader[7] = NPC_CRUSADER_2_14;
+ break;
+ case 2: crusader[5] = NPC_CRUSADER_2_8;
+ crusader[6] = NPC_CRUSADER_2_11;
+ crusader[7] = NPC_CRUSADER_2_14;
+ break;
+ case 3: crusader[5] = NPC_CRUSADER_2_7;
+ crusader[6] = NPC_CRUSADER_2_11;
+ crusader[7] = NPC_CRUSADER_2_14;
+ break;
+ }
+ crusader[8] = NPC_CRUSADER_2_9; //Hunter+warlock
+ crusader[9] = NPC_CRUSADER_2_10;
+ crusader[10] = NPC_CRUSADER_0_1;
+ crusader[11] = NPC_CRUSADER_0_2;
+
+ } else {
+ crusaderscount = 6;
+ switch (urand(0,5)){ // Healers, 2 in 10-mode
+ case 0: crusader[0] = NPC_CRUSADER_2_1;
+ crusader[1] = NPC_CRUSADER_2_12;
+ break;
+ case 1: crusader[0] = NPC_CRUSADER_2_1;
+ crusader[1] = NPC_CRUSADER_2_2;
+ break;
+ case 2: crusader[0] = NPC_CRUSADER_2_2;
+ crusader[1] = NPC_CRUSADER_2_12;
+ break;
+ case 3: crusader[0] = NPC_CRUSADER_2_1;
+ crusader[1] = NPC_CRUSADER_2_13;
+ break;
+ case 4: crusader[0] = NPC_CRUSADER_2_2;
+ crusader[1] = NPC_CRUSADER_2_13;
+ break;
+ case 5: crusader[0] = NPC_CRUSADER_2_12;
+ crusader[1] = NPC_CRUSADER_2_13;
+ break;
+ }
+ switch (urand(0,5)){ // Random melee DD, 2 in 10-mode
+ case 0: crusader[3] = NPC_CRUSADER_2_3;
+ crusader[2] = NPC_CRUSADER_2_4;
+ break;
+ case 1: crusader[3] = NPC_CRUSADER_2_3;
+ crusader[2] = NPC_CRUSADER_2_5;
+ break;
+ case 2: crusader[3] = NPC_CRUSADER_2_3;
+ crusader[2] = NPC_CRUSADER_2_6;
+ break;
+ case 3: crusader[3] = NPC_CRUSADER_2_4;
+ crusader[2] = NPC_CRUSADER_2_5;
+ break;
+ case 4: crusader[3] = NPC_CRUSADER_2_4;
+ crusader[2] = NPC_CRUSADER_2_6;
+ break;
+ case 5: crusader[3] = NPC_CRUSADER_2_5;
+ crusader[2] = NPC_CRUSADER_2_6;
+ break;
+ }
+
+ switch (urand(0,5)){ // Random magic DD, 2 in 10-mode
+ case 0: crusader[4] = NPC_CRUSADER_2_7;
+ crusader[5] = NPC_CRUSADER_2_8;
+ break;
+ case 1: crusader[5] = NPC_CRUSADER_2_7;
+ crusader[4] = NPC_CRUSADER_2_14;
+ break;
+ case 2: crusader[5] = NPC_CRUSADER_2_7;
+ crusader[4] = NPC_CRUSADER_2_11;
+ break;
+ case 3: crusader[5] = NPC_CRUSADER_2_8;
+ crusader[4] = NPC_CRUSADER_2_11;
+ break;
+ case 4: crusader[5] = NPC_CRUSADER_2_8;
+ crusader[4] = NPC_CRUSADER_2_14;
+ break;
+ case 5: crusader[5] = NPC_CRUSADER_2_11;
+ crusader[4] = NPC_CRUSADER_2_14;
+ break;
+ }
+
+ }
+ for(uint8 i = 0; i < crusaderscount; ++i)
+ {
+ m_creature->SummonCreature(crusader[i], SpawnLoc[i+2].x, SpawnLoc[i+2].y, SpawnLoc[i+2].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(crusader[i]))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+ }
+ pInstance->SetData(TYPE_CRUSADERS_COUNT,crusaderscount);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,0);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ pInstance->SetData(TYPE_CRUSADERS,IN_PROGRESS);
+ break;
+
+//Crusaders battle end
+ case 3100:
+ DoScriptText(-1713535, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,0);
+ break;
+
+ case 4000:
+ DoScriptText(-1713536, m_creature);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,4010);
+ break;
+ case 4010:
+ DoScriptText(-1713537, m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,4015);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+
+ case 4015:
+ pInstance->SetData(TYPE_STAGE,7);
+ pInstance->SetData(TYPE_VALKIRIES,IN_PROGRESS);
+ m_creature->SummonCreature(NPC_LIGHTBANE, SpawnLoc[3].x, SpawnLoc[3].y, SpawnLoc[3].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LIGHTBANE))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ m_creature->SummonCreature(NPC_DARKBANE, SpawnLoc[4].x, SpawnLoc[4].y, SpawnLoc[4].z, 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_DARKBANE))) {
+ pTemp->GetMotionMaster()->MovePoint(0, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ pTemp->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetInCombatWithZone();
+ }
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,4016);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+
+ case 4040:
+ UpdateTimer = 60000;
+ pInstance->SetData(TYPE_EVENT,5000);
+ break;
+
+ case 5000:
+ DoScriptText(-1713549, m_creature);
+ UpdateTimer = 8000;
+ pInstance->SetData(TYPE_EVENT,5005);
+ break;
+ case 5005:
+ UpdateTimer = 8000;
+ pInstance->SetData(TYPE_EVENT,5010);
+ pInstance->SetData(TYPE_STAGE,8);
+ m_creature->SummonCreature(NPC_LICH_KING_1, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z, 5, TEMPSUMMON_MANUAL_DESPAWN, 0);
+ break;
+ case 5020:
+ DoScriptText(-1713551, m_creature);
+ UpdateTimer = 8000;
+ pInstance->SetData(TYPE_EVENT,5030);
+ break;
+ case 6000:
+ m_creature->NearTeleportTo(SpawnLoc[19].x, SpawnLoc[19].y, SpawnLoc[19].z, 4.0f);
+ UpdateTimer = 20000;
+ pInstance->SetData(TYPE_EVENT,6005);
+ break;
+ case 6005:
+ DoScriptText(-1713565, m_creature);
+ UpdateTimer = 20000;
+ pInstance->SetData(TYPE_EVENT,6010);
+ break;
+ case 6010:
+ if (pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_10MAN_HEROIC
+ || pInstance->GetData(TYPE_DIFFICULTY) == RAID_DIFFICULTY_25MAN_HEROIC)
+ DoScriptText(-1713566, m_creature);
+ UpdateTimer = 60000;
+ pInstance->SetData(TYPE_EVENT,6020);
+ break;
+ case 6020:
+ pInstance->SetData(TYPE_STAGE,10);
+ m_creature->ForcedDespawn();
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,6030);
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+
+ }
+};
+
+CreatureAI* GetAI_npc_tirion_toc(Creature* pCreature)
{
- return new npc_barrett_ramseyAI(pCreature);
+ return new npc_tirion_tocAI(pCreature);
}
+struct MANGOS_DLL_DECL npc_garrosh_tocAI : public ScriptedAI
+{
+ npc_garrosh_tocAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)m_creature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ uint32 UpdateTimer;
+
+ void Reset()
+ {
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!pInstance) return;
+ if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_GARROSH) return;
+
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+
+ if (UpdateTimer <= diff)
+ {
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 120:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
+ DoScriptText(-1713702, m_creature);
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,122);
+ break;
+ case 122:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,130);
+ break;
+ case 2010:
+ DoScriptText(-1713527, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,2020);
+ break;
+ case 3050:
+ DoScriptText(-1713531, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3060);
+ break;
+ case 3070:
+ DoScriptText(-1713533, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3080);
+ break;
+ case 3081:
+ DoScriptText(-1713734, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3091);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+ case 4030:
+ DoScriptText(-1713748, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,4040);
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+ }
+};
+
+CreatureAI* GetAI_npc_garrosh_toc(Creature* pCreature)
+{
+ return new npc_garrosh_tocAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL npc_rinn_tocAI : public ScriptedAI
+{
+ npc_rinn_tocAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)m_creature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ uint32 UpdateTimer;
+
+ void Reset()
+ {
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!pInstance) return;
+ if (pInstance->GetData(TYPE_EVENT_NPC) != NPC_RINN) return;
+
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+
+ if (UpdateTimer <= diff)
+ {
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 130:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
+ DoScriptText(-1713502, m_creature);
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,132);
+ break;
+ case 132:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,140);
+ break;
+ case 2020:
+ DoScriptText(-1713528, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,2030);
+ break;
+ case 3051:
+ DoScriptText(-1713731, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3061);
+ break;
+ case 3071:
+ DoScriptText(-1713733, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3081);
+ break;
+ case 3080:
+ DoScriptText(-1713534, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,3090);
+ pInstance->DoUseDoorOrButton(pInstance->GetData64(GO_MAIN_GATE_DOOR));
+ break;
+ case 4020:
+ DoScriptText(-1713548, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,4030);
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER,UpdateTimer);
+ }
+};
+
+CreatureAI* GetAI_npc_rinn_toc(Creature* pCreature)
+{
+ return new npc_rinn_tocAI(pCreature);
+};
+
void AddSC_trial_of_the_crusader()
{
- Script* pNewScript;
+ Script* NewScript;
- pNewScript = new Script;
- pNewScript->Name = "npc_barrett_ramsey";
- pNewScript->GetAI = &GetAI_npc_barrett_ramsey;
- pNewScript->pGossipHello = &GossipHello_npc_barrett_ramsey;
- pNewScript->pGossipSelect = &GossipSelect_npc_barrett_ramsey;
- pNewScript->RegisterSelf();
-}
+ NewScript = new Script;
+ NewScript->Name = "npc_toc_announcer";
+ NewScript->GetAI = &GetAI_npc_toc_announcer;
+ NewScript->pGossipHello = &GossipHello_npc_toc_announcer;
+ NewScript->pGossipSelect = &GossipSelect_npc_toc_announcer;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_lich_king_toc";
+ NewScript->GetAI = &GetAI_boss_lich_king_toc;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_fizzlebang_toc";
+ NewScript->GetAI = &GetAI_npc_fizzlebang_toc;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_tirion_toc";
+ NewScript->GetAI = &GetAI_npc_tirion_toc;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_garrosh_toc";
+ NewScript->GetAI = &GetAI_npc_garrosh_toc;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_rinn_toc";
+ NewScript->GetAI = &GetAI_npc_rinn_toc;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
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 4a2b680..f5f5f71 100644
--- a/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h
+++ b/scripts/northrend/crusaders_coliseum/trial_of_the_crusader/trial_of_the_crusader.h
@@ -1,29 +1,177 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
-#ifndef DEF_TRIAL_OF_THE_CRUSADER_H
-#define DEF_TRIAL_OF_THE_CRUSADER_H
+#ifndef DEF_CRUSADER_H
+#define DEF_CRUSADER_H
+#include "BSW_ai.h"
enum
{
- MAX_ENCOUNTER = 5,
-
- TYPE_NORTHREND_BEASTS = 1,
- TYPE_JARAXXUS = 2,
- TYPE_FACTION_CHAMPIONS = 3,
- TYPE_TWIN_VALKYR = 4,
- TYPE_ANUBARAK = 5,
-
- DATA_GORMOK = 6,
- DATA_ACIDMAW = 7,
- DATA_DREADSCALE = 8,
- DATA_ICEHOWL = 9,
- DATA_JARAXXUS = 10,
- DATA_FACTION_CHAMPIONS = 11,
- DATA_FJOLA = 12,
- DATA_EYDIS = 13,
- DATA_ANUBARAK = 14,
+ TYPE_STAGE = 0,
+ TYPE_BEASTS = 1,
+ TYPE_JARAXXUS = 2,
+ TYPE_CRUSADERS = 3,
+ TYPE_VALKIRIES = 4,
+ TYPE_LICH_KING = 5,
+ TYPE_ANUBARAK = 6,
+ TYPE_COUNTER = 7,
+ TYPE_EVENT = 8,
+ MAX_ENCOUNTERS = 9,
+
+ NPC_BARRENT = 34816,
+ NPC_TIRION = 34996,
+ NPC_FIZZLEBANG = 35458,
+ NPC_GARROSH = 34995,
+ NPC_RINN = 34990,
+ NPC_LICH_KING_0 = 16980,
+ NPC_LICH_KING_1 = 35877,
+
+ NPC_THRALL = 34994,
+ NPC_PROUDMOORE = 34992,
+ NPC_TRIGGER = 22517,
+ NPC_WILFRED_PORTAL = 35651,
+
+ NPC_ICEHOWL = 34797,
+ NPC_GORMOK = 34796,
+ NPC_DREADSCALE = 34799,
+ NPC_ACIDMAW = 35144,
+
+ NPC_JARAXXUS = 34780,
+
+ NPC_CRUSADER_1_1 = 34460, //Druid
+ NPC_CRUSADER_1_2 = 34463, //Shaman
+ NPC_CRUSADER_1_3 = 34461, //DK
+ NPC_CRUSADER_1_4 = 34472, //Rogue
+ NPC_CRUSADER_1_5 = 34475, //Warrior
+ NPC_CRUSADER_1_6 = 34471, //Retro pal
+ NPC_CRUSADER_1_7 = 34473, //Shadow priest
+ NPC_CRUSADER_1_8 = 34468, //Mage
+ NPC_CRUSADER_1_9 = 34467, //Hunter
+ NPC_CRUSADER_1_10 = 34474, //Warlock
+ NPC_CRUSADER_1_11 = 34470, //Enh shaman
+ NPC_CRUSADER_1_12 = 34466, //Priest
+ NPC_CRUSADER_1_13 = 34465, //Holy paladin
+ NPC_CRUSADER_1_14 = 34469, //Moonkin
+
+ NPC_CRUSADER_2_1 = 34451, //Druid
+ NPC_CRUSADER_2_2 = 34455, //Shaman
+ NPC_CRUSADER_2_3 = 34458, //DK
+ NPC_CRUSADER_2_4 = 34454, //Rogue
+ NPC_CRUSADER_2_5 = 34453, //Warrior
+ NPC_CRUSADER_2_6 = 34456, //Retro pal
+ NPC_CRUSADER_2_7 = 34441, //Shadow Priest
+ NPC_CRUSADER_2_8 = 34449, //Mage
+ NPC_CRUSADER_2_9 = 34448, //Hunter
+ NPC_CRUSADER_2_10 = 34450, //Warlock
+ NPC_CRUSADER_2_11 = 34444, //Enh shaman
+ NPC_CRUSADER_2_12 = 34447, //Priest
+ NPC_CRUSADER_2_13 = 34445, //Holy paladin
+ NPC_CRUSADER_2_14 = 34459, //Moonkin
+
+ NPC_CRUSADER_0_1 = 35465,
+ NPC_CRUSADER_0_2 = 35610,
+
+ NPC_LIGHTBANE = 34497,
+ NPC_DARKBANE = 34496,
+
+ NPC_ANUBARAK = 34564,
+
+ GO_CRUSADERS_CACHE_10 = 195631,
+ GO_CRUSADERS_CACHE_25 = 195632,
+ GO_CRUSADERS_CACHE_10_H = 195633,
+ GO_CRUSADERS_CACHE_25_H = 195635,
+
+ GO_TRIBUTE_CHEST_10H_25 = 195665,
+ GO_TRIBUTE_CHEST_10H_45 = 195666,
+ GO_TRIBUTE_CHEST_10H_50 = 195667,
+ GO_TRIBUTE_CHEST_10H_99 = 195668,
+
+ GO_TRIBUTE_CHEST_25H_25 = 195669,
+ GO_TRIBUTE_CHEST_25H_45 = 195670,
+ GO_TRIBUTE_CHEST_25H_50 = 195671,
+ GO_TRIBUTE_CHEST_25H_99 = 195672,
+
+ GO_ARGENT_COLISEUM_FLOOR = 195527, //20943
+ GO_MAIN_GATE_DOOR = 195647,
+
+ GO_WEST_PORTCULLIS = 195589,
+ GO_SOUTH_PORTCULLIS = 195590,
+ GO_NORTH_PORTCULLIS = 195591,
+
+ TYPE_DIFFICULTY = 101,
+ TYPE_EVENT_TIMER = 102,
+ TYPE_EVENT_NPC = 103,
+ TYPE_NORTHREND_BEASTS = 104,
+ TYPE_CRUSADERS_COUNT = 105,
+
+ DATA_HEALTH_EYDIS = 201,
+ DATA_HEALTH_FJOLA = 202,
+ DATA_CASTING_VALKYRS = 203,
+
+ DESPAWN_TIME = 300000,
+
+};
+
+static Locations SpawnLoc[]=
+{
+ {559.257996f, 90.266197f, 395.122986f}, // 0 Barrent
+ {563.672974f, 139.571f, 393.837006f}, // 1 Center
+ {563.833008f, 187.244995f, 394.5f}, // 2 Backdoor
+ {577.347839f, 195.338888f, 395.14f}, // 3 - Right
+ {550.955933f, 195.338888f, 395.14f}, // 4 - Left
+ {575.042358f, 195.260727f, 395.137146f}, // 5
+ {552.248901f, 195.331955f, 395.132658f}, // 6
+ {573.342285f, 195.515823f, 395.135956f}, // 7
+ {554.239929f, 195.825577f, 395.137909f}, // 8
+ {571.042358f, 195.260727f, 395.137146f}, // 9
+ {556.720581f, 195.015472f, 395.132658f}, // 10
+ {569.534119f, 195.214478f, 395.139526f}, // 11
+ {569.231201f, 195.941071f, 395.139526f}, // 12
+ {558.811610f, 195.985779f, 394.671661f}, // 13
+ {567.641724f, 195.351501f, 394.659943f}, // 14
+ {560.633972f, 195.391708f, 395.137543f}, // 15
+ {565.816956f, 195.477921f, 395.136810f}, // 16
+ {563.549f, 152.474f, 394.393f}, // 17 - Lich king start
+ {563.547f, 141.613f, 393.908f}, // 18 - Lich king end
+ {787.932556f, 133.28978f, 142.612152f}, // 19 - Anub'arak start location
+ {618.157898f, 132.640869f, 139.559769f}, // 20 - Anub'arak move point location
+ {508.104767f, 138.247345f, 395.128052f}, // 21 - Fizzlebang start location
+ {586.060242f, 117.514809f, 394.314026f}, // 22 - Dark essence 1
+ {541.602112f, 161.879837f, 394.587952f}, // 23 - Dark essence 2
+ {541.021118f, 117.262932f, 395.314819f}, // 24 - Light essence 1
+ {586.200562f, 162.145523f, 394.626129f}, // 25 - Light essence 2
+ {563.833008f, 195.244995f, 394.585561f}, // 26 - outdoor
+ {548.610596f, 139.807800f, 394.321838f}, // 27 - fizzlebang end
+};
+
+enum uiWorldStates
+{
+ UPDATE_STATE_UI_SHOW = 4390,
+ UPDATE_STATE_UI_COUNT = 4389,
+};
+
+enum NorthrendBeasts
+{
+ GORMOK_IN_PROGRESS = 1000,
+ GORMOK_DONE = 1001,
+ SNAKES_IN_PROGRESS = 2000,
+ DREADSCALE_SUBMERGED = 2001,
+ ACIDMAW_SUBMERGED = 2002,
+ SNAKES_SPECIAL = 2003,
+ SNAKES_DONE = 2004,
+ ICEHOWL_IN_PROGRESS = 3000,
+ ICEHOWL_DONE = 3001,
+};
+
+enum AnnounserMessages
+{
+ MSG_BEASTS = 724001,
+ MSG_JARAXXUS = 724002,
+ MSG_CRUSADERS = 724003,
+ MSG_VALKIRIES = 724004,
+ MSG_LICH_KING = 724005,
+ MSG_ANUBARAK = 724006,
};
#endif
diff --git a/scripts/northrend/draktharon_keep/boss_dred.cpp b/scripts/northrend/draktharon_keep/boss_dred.cpp
new file mode 100644
index 0000000..c10ee39
--- /dev/null
+++ b/scripts/northrend/draktharon_keep/boss_dred.cpp
@@ -0,0 +1,196 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Tharonja
+SD%Complete: 80%
+SDComment: Timers
+SDCategory: Drak'Tharon Keep
+EndScriptData */
+
+#include "precompiled.h"
+#include "draktharon_keep.h"
+
+enum
+{
+ SAY_KING_DRED_TALON = -1600020,
+ SAY_CALL_FOR_RAPTOR = -1600021,
+
+ SPELL_BELLOWING_ROAR = 22686,
+ SPELL_FEARSOME_ROAR = 48849,
+ H_SPELL_FEARSOME_ROAR = 59422,
+ SPELL_GRIEVOUS_BITE = 48920,
+ SPELL_MANGLING_SLASH = 48873,
+ SPELL_PIERCING_SLASH = 48878,
+ SPELL_RAPTOR_CALL = 59416, //not yet implemented
+
+};
+
+const float PosSummon1[3] = {-528.8f, -690.58f, 30.25f};
+/*######
+## boss_dred
+######*/
+
+struct MANGOS_DLL_DECL boss_dredAI : public ScriptedAI
+{
+ boss_dredAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 FearsomeRoar_Timer;
+ uint32 ManglingSlash_Timer;
+ uint32 PiercingSlash_Timer;
+ uint32 GrievousBite_Timer;
+ uint32 BellowingRoar_Timer;
+ uint32 Check_Timer;
+ uint32 CallForRaptor_Timer;
+ uint32 CallForRaptorSpawn_Timer;
+ uint32 CallForRaptorSpawn_Check;
+
+ void Reset()
+ {
+ FearsomeRoar_Timer = 15000;
+ ManglingSlash_Timer = urand(5000, 10000);
+ PiercingSlash_Timer = urand(10000, 15000);
+ GrievousBite_Timer = urand (15000, 20000);
+ BellowingRoar_Timer = 60000;
+ Check_Timer = 15000;
+ CallForRaptor_Timer = 25000;
+ CallForRaptorSpawn_Check = 0;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+
+ }
+
+ void CallForRaptorSpawnCheck()
+ {
+ CallForRaptorSpawn_Timer = 1000;
+ CallForRaptorSpawn_Check = 1;
+ }
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ //Fearsome Roar
+ if (FearsomeRoar_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FEARSOME_ROAR : H_SPELL_FEARSOME_ROAR, true);
+ FearsomeRoar_Timer = 15000;
+ }else FearsomeRoar_Timer -= uiDiff;
+
+ //Piercing Slash
+ if (PiercingSlash_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_PIERCING_SLASH, true);
+ PiercingSlash_Timer = urand(20000, 25000);
+ }else PiercingSlash_Timer -= uiDiff;
+
+ //Mangling Slash
+ if (ManglingSlash_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_MANGLING_SLASH, true);
+ ManglingSlash_Timer = urand(20000, 25000);
+ }else ManglingSlash_Timer -= uiDiff;
+
+ //Mangling Slash
+ if (GrievousBite_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_GRIEVOUS_BITE, true);
+ GrievousBite_Timer = urand(20000, 25000);
+ }else GrievousBite_Timer -= uiDiff;
+
+ //Grievous Bite remove
+ if (Check_Timer < uiDiff)
+ {
+ Unit* pPlayer = m_creature->getVictim();
+ if (pPlayer->GetHealth() == pPlayer->GetMaxHealth())
+ if (pPlayer->HasAura(SPELL_GRIEVOUS_BITE))
+ pPlayer->RemoveAura(SPELL_GRIEVOUS_BITE, EFFECT_INDEX_0);
+ Check_Timer = 1000;
+ }else Check_Timer -= uiDiff;
+
+ //Bellowing Roar
+ if (BellowingRoar_Timer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_BELLOWING_ROAR);
+ BellowingRoar_Timer = 60000;
+ }else BellowingRoar_Timer -= uiDiff;
+
+ //Call For Raptor - spell
+ if (CallForRaptor_Timer < uiDiff)
+ {
+ DoScriptText(SAY_CALL_FOR_RAPTOR, m_creature);
+ m_creature->CastSpell(m_creature, SAY_CALL_FOR_RAPTOR, true);
+ CallForRaptor_Timer = 25000;
+ CallForRaptorSpawnCheck();
+ }else CallForRaptor_Timer -= uiDiff;
+
+ //Call For Raptor - spawn
+ if (CallForRaptorSpawn_Timer < uiDiff && CallForRaptorSpawn_Check == 1)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ {
+ if (Creature* pRaptor1 = m_creature->SummonCreature(NPC_DRAKKARI_GUTRIPPER, PosSummon1[0], PosSummon1[1], PosSummon1[2], 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 240000))
+ pRaptor1->AI()->AttackStart(m_creature->getVictim());
+ }
+ case 1:
+ {
+ if (Creature* pRaptor2 = m_creature->SummonCreature(NPC_DRAKKARI_SCYTHECLAW, PosSummon1[0], PosSummon1[1], PosSummon1[2], 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 240000))
+ pRaptor2->AI()->AttackStart(m_creature->getVictim());
+ }
+ }
+ CallForRaptorSpawn_Check = 0;
+ }else CallForRaptorSpawn_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_dred(Creature* pCreature)
+{
+ return new boss_dredAI(pCreature);
+}
+
+void AddSC_boss_dred()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_dred";
+ newscript->GetAI = &GetAI_boss_dred;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/draktharon_keep/boss_novos.cpp b/scripts/northrend/draktharon_keep/boss_novos.cpp
index 5ea06c7..6cfada9 100644
--- a/scripts/northrend/draktharon_keep/boss_novos.cpp
+++ b/scripts/northrend/draktharon_keep/boss_novos.cpp
@@ -16,8 +16,8 @@
/* ScriptData
SDName: Boss_Novos
-SD%Complete: 20%
-SDComment:
+SD%Complete: 80%
+SDComment: Timers
SDCategory: Drak'Tharon Keep
EndScriptData */
@@ -35,12 +35,32 @@ enum
EMOTE_ASSISTANCE = -1600011,
- NPC_CRYSTAL_HANDLER = 26627,
- NPC_HULKING_CORPSE = 27597,
- NPC_FETID_TROLL_CORPSE = 27598,
- NPC_RISON_SHADOWCASTER = 27600
+ POS = 3,
+
+ SPELL_ARCANE_FIELD = 47346,
+ SPELL_FROSTBOLT = 49037,
+ H_SPELL_FROSTBOLT = 59855,
+ SPELL_ARCANE_BLAST = 49198,
+ H_SPELL_ARCANE_BLAST = 59909,
+ SPELL_BLIZZARD = 49034,
+ H_SPELL_BLIZZARD = 59854,
+ SPELL_WRATH_OF_MISERY = 50089,
+ H_SPELL_WRATH_OF_MISERY = 59856,
+
+ SPELL_RITUAL_CRYSTAL_KEY = 51404,
+ SPELL_EFFECT = 52106,
+ SPELL_DEAD_EFFECT = 47336,
+
+ SPELL_SHADOW_BOLT = 51363,
+ H_SPELL_SHADOW_BOLT = 59016,
};
+const float PosSummonHandler[POS][3] =
+{
+ {-337.78f, -720.39f, 28.58f},
+ {-379.31f, -818.36f, 59.70f},
+ {-412.45f, -726.96f, 28.58f},
+};
/*######
## boss_novos
######*/
@@ -57,14 +77,29 @@ struct MANGOS_DLL_DECL boss_novosAI : public ScriptedAI
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
+ bool Phase1;
+ bool Phase2;
+ uint32 Start_Check;
+ uint32 Handler_Spawn;
+ uint32 Handler_Count;
+ uint32 Cast_Timer;
+ uint32 ArcaneBlast_Timer;
+ uint32 SpecialCast_Timer;
+ uint32 SummonMinion_Timer;
+
void Reset()
{
+ Start_Check = 1;
+ Handler_Spawn = 5000;
+ Handler_Count = 0;
+ Phase1 = false;
+ Phase2 = false;
}
void MoveInLineOfSight(Unit* pWho)
{
// An Add reached the ground, if its z-pos is near the z pos of Novos
- if (pWho->GetEntry() == NPC_HULKING_CORPSE || pWho->GetEntry() == NPC_FETID_TROLL_CORPSE || pWho->GetEntry() == NPC_RISON_SHADOWCASTER)
+ if (pWho->GetEntry() == NPC_HULKING_CORPSE || pWho->GetEntry() == NPC_FETID_TROLL_CORPSE || pWho->GetEntry() == NPC_RISEN_SHADOWCASTER)
{
// Add reached ground, and the failure has not yet been reported
if (pWho->GetPositionZ() < m_creature->GetPositionZ() + 1.5f && m_pInstance && m_pInstance->GetData(TYPE_NOVOS) == IN_PROGRESS)
@@ -79,6 +114,9 @@ struct MANGOS_DLL_DECL boss_novosAI : public ScriptedAI
{
DoScriptText(SAY_AGGRO, m_creature);
+ m_creature->SummonCreature(NPC_CRYSTAL_CHANNEL_TARGET, -379.269f, -737.728f, 39.313f, 0 , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000);
+ m_creature->CallForHelp(50.0f);
+
if (m_pInstance)
m_pInstance->SetData(TYPE_NOVOS, IN_PROGRESS);
}
@@ -102,26 +140,236 @@ struct MANGOS_DLL_DECL boss_novosAI : public ScriptedAI
m_pInstance->SetData(TYPE_NOVOS, FAIL);
}
+ void EnterPhase1()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetInCombatWithZone();
+ Phase1 = true;
+ }
+
+ void EnterPhase2()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ SummonMinion_Timer = urand (15000,20000);
+ SpecialCast_Timer = urand(15000, 20000);
+ ArcaneBlast_Timer = urand(25000, 30000);
+ Cast_Timer = 500;
+ Phase1 = false;
+ Phase2 = true;
+ }
+
void UpdateAI(const uint32 uiDiff)
{
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ if (Phase2 == true)
+ {
+ //Arcane Blast
+ if (ArcaneBlast_Timer < uiDiff)
+ {
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_ARCANE_BLAST : H_SPELL_ARCANE_BLAST, true);
+ ArcaneBlast_Timer = urand(25000, 30000);
+ }else ArcaneBlast_Timer -= uiDiff;
+
+ //Wrath Of Misery or Blizzard
+ if (SpecialCast_Timer < uiDiff)
+ {
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ switch(urand(0, 1))
+ {
+ case 0:
+ DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_WRATH_OF_MISERY : H_SPELL_WRATH_OF_MISERY);
+ case 1:
+ DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_BLIZZARD : H_SPELL_BLIZZARD);
+ }
+ SpecialCast_Timer = urand(10000, 15000);
+ }else ArcaneBlast_Timer -= uiDiff;
+
+ //Regual cast - frostbolt
+ if (Cast_Timer < uiDiff && ArcaneBlast_Timer > uiDiff && SpecialCast_Timer > uiDiff)
+ {
+ DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_FROSTBOLT : H_SPELL_FROSTBOLT);
+ Cast_Timer = 1000;
+ }else Cast_Timer -= uiDiff;
+
+ //Summon Minions (Heroic)
+ if (SummonMinion_Timer < uiDiff)
+ {
+ if(m_bIsRegularMode)
+ return;
+
+ uint8 SummonLoc = rand()%POS;
+ if (Creature* pAdd1 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd1->AI()->AttackStart(m_creature->getVictim());
+ if (Creature* pAdd2 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd2->AI()->AttackStart(m_creature->getVictim());
+ if (Creature* pAdd3 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd3->AI()->AttackStart(m_creature->getVictim());
+ if (Creature* pAdd4 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd4->AI()->AttackStart(m_creature->getVictim());
+ if (Creature* pAdd5 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd5->AI()->AttackStart(m_creature->getVictim());
+ SummonMinion_Timer = urand (15000,20000);
+ }else SummonMinion_Timer -= uiDiff;
+
+ }
- DoMeleeAttackIfReady();
+ if (m_creature->getVictim() && Start_Check == 1)
+ {
+ EnterPhase1();
+ DoCast(m_creature, SPELL_ARCANE_FIELD);
+ Start_Check = 0;
+ }
+
+ //Phase 1 Waves spawn
+ if (Handler_Spawn < uiDiff && Phase1 == true)
+ {
+ Handler_Count ++;
+ if(Handler_Count < 5)
+ {
+ uint8 SummonLoc = rand()%POS;
+ m_creature->SummonCreature(NPC_CRYSTAL_HANDLER, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000);
+ if (Creature* pAdd1 = m_creature->SummonCreature(NPC_HULKING_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd1->AI()->AttackStart(m_creature->getVictim());
+ if (Creature* pAdd2 = m_creature->SummonCreature(NPC_RISEN_SHADOWCASTER, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd2->AI()->AttackStart(m_creature->getVictim());
+ if (Creature* pAdd3 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd3->AI()->AttackStart(m_creature->getVictim());
+ if (Creature* pAdd4 = m_creature->SummonCreature(NPC_FETID_TROLL_CORPSE, PosSummonHandler[SummonLoc][0],PosSummonHandler[SummonLoc][1],PosSummonHandler[SummonLoc][2],0, TEMPSUMMON_TIMED_DESPAWN, 120000))
+ pAdd4->AI()->AttackStart(m_creature->getVictim());
+ Handler_Spawn = 17500;
+ }
+ if(Handler_Count == 5)
+ {
+ EnterPhase2();
+ if (Creature* pTrigger = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL, 85.0f))
+ pTrigger->ForcedDespawn();
+ }
+ }else Handler_Spawn -= uiDiff;
}
};
+
+
CreatureAI* GetAI_boss_novos(Creature* pCreature)
{
return new boss_novosAI(pCreature);
}
+struct MANGOS_DLL_DECL crystal_handlerAI : public ScriptedAI
+{
+ crystal_handlerAI(Creature* pCreature) : ScriptedAI(pCreature){Reset();}
+ void Reset(){}
+ void MoveInLineOfSight(Unit* who)
+ {
+ if (Unit* pNovos = GetClosestCreatureWithEntry(m_creature, NPC_NOVOS, 85.0f))
+ m_creature->AI()->AttackStart(pNovos->getVictim());
+ }
+
+ void JustDied()
+ {
+ if (Creature* pDeadTrigger = m_creature->SummonCreature(NPC_TRIGGER_TARGET,0,0,0,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,10000))
+ {
+ if (Unit* pTarget = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL, 85.0f))
+ {
+ pDeadTrigger->CastSpell(pTarget, SPELL_DEAD_EFFECT, true);
+ }
+ }
+ if (Creature* pTrigger = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL, 85.0f))
+ pTrigger->ForcedDespawn();
+ }
+};
+
+CreatureAI* GetAI_crystal_handler(Creature* pCreature)
+{
+ return new crystal_handlerAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL crystal_channelAI : public ScriptedAI
+{
+ crystal_channelAI(Creature* pCreature) : ScriptedAI(pCreature){Reset();}
+ uint32 Check_Timer;
+ void Reset()
+ {
+ Check_Timer = 1000;
+ }
+ void AttackStart(Unit *pWho){}
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (Check_Timer < uiDiff)
+ {
+ Creature* pNovos = GetClosestCreatureWithEntry(m_creature, NPC_NOVOS, 85.0f);
+ if (Creature* pTarget = GetClosestCreatureWithEntry(m_creature, NPC_CRYSTAL_CHANNEL_TARGET , 85.0f))
+ if (pNovos && ((boss_novosAI*)pNovos->AI())->Phase1 == true)
+ DoCast(pTarget, SPELL_EFFECT, true);
+ else
+ pTarget->ForcedDespawn();
+ Check_Timer = 1000;
+ }else Check_Timer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_crystal_channel(Creature* pCreature)
+{
+ return new crystal_channelAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL risen_shadowcasterAI : public ScriptedAI
+{
+ risen_shadowcasterAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 Check_Timer;
+ void Reset()
+ {
+ Check_Timer = 1000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (Check_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BOLT : H_SPELL_SHADOW_BOLT);
+ Check_Timer = 1000;
+ }else Check_Timer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_risen_shadowcaster(Creature* pCreature)
+{
+ return new risen_shadowcasterAI(pCreature);
+}
void AddSC_boss_novos()
{
- Script* pNewScript;
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_novos";
+ newscript->GetAI = &GetAI_boss_novos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "crystal_handler";
+ newscript->GetAI = &GetAI_crystal_handler;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "crystal_channel";
+ newscript->GetAI = &GetAI_crystal_channel;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "risen_shadowcaster";
+ newscript->GetAI = &GetAI_risen_shadowcaster;
+ newscript->RegisterSelf();
- pNewScript = new Script;
- pNewScript->Name = "boss_novos";
- pNewScript->GetAI = &GetAI_boss_novos;
- pNewScript->RegisterSelf();
}
diff --git a/scripts/northrend/draktharon_keep/boss_tharonja.cpp b/scripts/northrend/draktharon_keep/boss_tharonja.cpp
index ab2ad05..b2af3d0 100644
--- a/scripts/northrend/draktharon_keep/boss_tharonja.cpp
+++ b/scripts/northrend/draktharon_keep/boss_tharonja.cpp
@@ -16,8 +16,8 @@
/* ScriptData
SDName: Boss_Tharonja
-SD%Complete: 20%
-SDComment:
+SD%Complete: 80%
+SDComment: Timers, end event with drakuru
SDCategory: Drak'Tharon Keep
EndScriptData */
@@ -33,9 +33,53 @@ enum
SAY_FLESH_2 = -1600016,
SAY_SKELETON_1 = -1600017,
SAY_SKELETON_2 = -1600018,
- SAY_DEATH = -1600019
+ SAY_DEATH = -1600019,
+
+ //Phase 1 (Skeleton) Spells
+ SPELL_CURSE_OF_LIFE = 49527,
+ H_SPELL_CURSE_OF_LIFE = 59972,
+
+ SPELL_SHADOW_VOLLEY = 49528,
+ H_SPELL_SHADOW_VOLLEY = 59973,
+ SPELL_RAIN_OF_FIRE = 49518,
+ H_SPELL_RAIN_OF_FIRE = 59971,
+
+ SPELL_DECAY_FLESH = 49356, //not working
+
+ //Phase 2 (Flesh) Spells
+ SPELL_GIFT_OF_THARONJA = 52509,
+
+ SPELL_LIGHTNING_BREATH = 49537,
+ H_SPELL_LIGHTNING_BREATH = 59936,
+ SPELL_EYE_BEAM = 49544,
+ H_SPELL_EYE_BEAM = 59965,
+
+ SPELL_POISON_CLOUD = 49548,
+ H_SPELL_POSION_CLOUD = 59969,
+
+ SPELL_RETURN_FLESH = 53463, //not working
+
+ //achie hacks
+ ACHIEVEMENT_NORMAL = 482,
+ ACHIEVEMENT_HEROIC = 493
+
+};
+
+//Phasses
+enum Phase
+{
+ PHASE_SKELETON = 0,
+ PHASE_INTOFLESH = 1,
+ PHASE_FLESH = 2,
+ PHASE_INTOSKELETON = 3
};
+enum PhaseChangeTimer
+{
+ PHASE_CHANGE_SKELETON = 12000,
+ PHASE_CHANGE_REAL = 6000,
+ PHASE_CHANGE_FLESH = 20000
+};
/*######
## boss_tharonja
######*/
@@ -51,9 +95,19 @@ struct MANGOS_DLL_DECL boss_tharonjaAI : public ScriptedAI
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
+ uint32 PhaseChangeTimer;
+ uint32 Phase;
+ uint32 CurseOfLife_Timer;
+ uint32 SkeletonSpells_Timer;
+ uint32 PoisonCloud_Timer;
+ uint32 FleshSpells_Timer;
void Reset()
{
+ PhaseChangeTimer = PHASE_CHANGE_SKELETON;
+ Phase = PHASE_SKELETON;
+ SkeletonSpells_Timer = urand (5000, 10000);
+ CurseOfLife_Timer = urand (5000, 10000);
}
void Aggro(Unit* pWho)
@@ -88,7 +142,91 @@ struct MANGOS_DLL_DECL boss_tharonjaAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
- DoMeleeAttackIfReady();
+ if (Phase == PHASE_SKELETON)
+ {
+ if (CurseOfLife_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CURSE_OF_LIFE : H_SPELL_CURSE_OF_LIFE);
+ CurseOfLife_Timer = urand (5000, 10000);
+ }else CurseOfLife_Timer -= uiDiff;
+
+ if (SkeletonSpells_Timer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_VOLLEY : H_SPELL_SHADOW_VOLLEY);
+ case 1:
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_RAIN_OF_FIRE : H_SPELL_RAIN_OF_FIRE);
+ }
+ SkeletonSpells_Timer = urand (5000, 10000);
+ }else SkeletonSpells_Timer -= uiDiff;
+
+ if (PhaseChangeTimer < uiDiff)
+ {
+ m_creature->CastSpell(m_creature, SPELL_DECAY_FLESH, true);
+ PhaseChangeTimer = PHASE_CHANGE_REAL;
+ Phase = PHASE_INTOFLESH;
+ }else PhaseChangeTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ if (Phase == PHASE_INTOFLESH)
+ {
+ if (PhaseChangeTimer < uiDiff)
+ {
+ m_creature->CastSpell(m_creature, SPELL_GIFT_OF_THARONJA, true);
+ m_creature->SetDisplayId(27073);
+ PhaseChangeTimer = PHASE_CHANGE_FLESH;
+ Phase = PHASE_FLESH;
+ FleshSpells_Timer = 1500;
+ PoisonCloud_Timer = 10000;
+ }else PhaseChangeTimer -= uiDiff;
+ }
+
+ if (Phase == PHASE_FLESH)
+ {
+ if (PhaseChangeTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_RETURN_FLESH);
+ PhaseChangeTimer = PHASE_CHANGE_REAL;
+ Phase = PHASE_INTOSKELETON;
+ }else PhaseChangeTimer -= uiDiff;
+
+ if (PoisonCloud_Timer < uiDiff)
+ {
+ DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_POISON_CLOUD : H_SPELL_POSION_CLOUD);
+ PoisonCloud_Timer = 10000;
+ }else PoisonCloud_Timer -= uiDiff;
+
+ if (FleshSpells_Timer < uiDiff)
+ {
+ switch(urand(0, 3))
+ {
+ case 0:
+ case 1:
+ case 2:
+ DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_LIGHTNING_BREATH : H_SPELL_LIGHTNING_BREATH);
+ case 3:
+ DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_EYE_BEAM : SPELL_EYE_BEAM);
+ }
+ FleshSpells_Timer = 1500;
+ }else FleshSpells_Timer -= uiDiff;
+ }
+
+ if (Phase == PHASE_INTOSKELETON)
+ {
+ if (PhaseChangeTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_DECAY_FLESH);
+ m_creature->SetDisplayId(27072);
+ PhaseChangeTimer = PHASE_CHANGE_SKELETON;
+ Phase = PHASE_SKELETON;
+ SkeletonSpells_Timer = urand (5000, 10000);
+ CurseOfLife_Timer = urand (5000, 10000);
+ }else PhaseChangeTimer -= uiDiff;
+ }
}
};
diff --git a/scripts/northrend/draktharon_keep/boss_trollgore.cpp b/scripts/northrend/draktharon_keep/boss_trollgore.cpp
index 4dcd46f..6601e58 100644
--- a/scripts/northrend/draktharon_keep/boss_trollgore.cpp
+++ b/scripts/northrend/draktharon_keep/boss_trollgore.cpp
@@ -16,8 +16,8 @@
/* ScriptData
SDName: Boss_Trollgore
-SD%Complete: 20%
-SDComment:
+SD%Complete: 90%
+SDComment: Timers
SDCategory: Drak'Tharon Keep
EndScriptData */
@@ -30,9 +30,29 @@ enum
SAY_CONSUME = -1600001,
SAY_DEATH = -1600002,
SAY_EXPLODE = -1600003,
- SAY_KILL = -1600004
+ SAY_KILL = -1600004,
+
+ SPELL_CRUSH = 49639,
+ SPELL_INFECTED_WOUND = 49367,
+ SPELL_CORPSE_EXPLODE = 49555,
+ H_SPELL_CORPSE_EXPLODE = 59087,
+ SPELL_CONSUME = 49380,
+ H_SPELL_CONSUME = 59803,
+ SPELL_CONSUME_BUFF = 49381,
+ H_SPELL_CONSUME_BUFF = 59805,
+
+ SPELL_CORPSE_EXPLODE_PROC = 49618,
+ H_SPELL_CORPSE_EXPLODE_PROC = 59809,
+
+ NPC_DRAKKARI_INVADER = 27753,
+ NPC_TROLLGORE = 26630
};
+const float PosSummon1[3] = {-259.59f, -652.49f, 26.52f};
+const float PosSummon2[3] = {-261.60f, -658.71f, 26.51f};
+const float PosSummon3[3] = {-262.05f, -665.71f, 26.49f};
+
+
/*######
## boss_trollgore
######*/
@@ -49,8 +69,19 @@ struct MANGOS_DLL_DECL boss_trollgoreAI : public ScriptedAI
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
+ uint32 Consume_Timer;
+ uint32 Crush_Timer;
+ uint32 InfectedWound_Timer;
+ uint32 Wave_Timer;
+ uint32 CorpseExplode_Timer;
+
void Reset()
{
+ CorpseExplode_Timer = 10000;
+ Consume_Timer = 5000;
+ Crush_Timer = 10000;
+ InfectedWound_Timer = 30000;
+ Wave_Timer = 2000;
}
void Aggro(Unit* pWho)
@@ -81,11 +112,78 @@ struct MANGOS_DLL_DECL boss_trollgoreAI : public ScriptedAI
m_pInstance->SetData(TYPE_TROLLGORE, FAIL);
}
+ void SummonWaves()
+ {
+ if (Creature* pInvader1 = m_creature->SummonCreature(NPC_DRAKKARI_INVADER,PosSummon1[0],PosSummon1[1],PosSummon1[2],0, TEMPSUMMON_TIMED_DESPAWN, 15000))
+ pInvader1->AI()->AttackStart(m_creature);
+ if (Creature* pInvader2 = m_creature->SummonCreature(NPC_DRAKKARI_INVADER,PosSummon2[0],PosSummon2[1],PosSummon2[2],0, TEMPSUMMON_TIMED_DESPAWN, 15000))
+ pInvader2->AI()->AttackStart(m_creature);
+ if (Creature* pInvader3 = m_creature->SummonCreature(NPC_DRAKKARI_INVADER,PosSummon3[0],PosSummon3[1],PosSummon3[2],0, TEMPSUMMON_TIMED_DESPAWN, 15000))
+ pInvader3->AI()->AttackStart(m_creature);
+ }
+
void UpdateAI(const uint32 uiDiff)
{
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ // Crush
+ if (Crush_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_CRUSH);
+ Crush_Timer = 10000;
+ }else Crush_Timer -= uiDiff;
+
+ // Infected Wound
+ if (InfectedWound_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_CRUSH);
+ InfectedWound_Timer = 30000;
+ }else InfectedWound_Timer -= uiDiff;
+
+ // Summon npcs
+ if (Wave_Timer < uiDiff)
+ {
+ SummonWaves();
+ Wave_Timer = 15000;
+ }else Wave_Timer -= uiDiff;
+
+ // Consume
+ if (Consume_Timer < uiDiff)
+ {
+ m_creature->CastSpell(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CONSUME : H_SPELL_CONSUME, true);
+ m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_CONSUME_BUFF : H_SPELL_CONSUME_BUFF, true);
+ Consume_Timer = 15000;
+ }else Consume_Timer -= uiDiff;
+
+ //Corpse Explosion
+ if (CorpseExplode_Timer < uiDiff)
+ {
+ //DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CORPSE_EXPLODE : H_SPELL_CORPSE_EXPLODE);
+
+ if (Creature* pCorpse = GetClosestCreatureWithEntry(m_creature, NPC_DRAKKARI_INVADER, 85.0f))
+ {
+ if (!pCorpse->isAlive())
+ {
+ Map *map = pCorpse->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && pCorpse->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) <= 5)
+ m_creature->DealDamage(i->getSource(), (m_bIsRegularMode ? urand(3770, 4230) : urand(9425, 10575)), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NATURE, NULL, false);
+ }
+ }
+ }
+ }
+ CorpseExplode_Timer = 15000;
+ }else CorpseExplode_Timer -= uiDiff;
+
DoMeleeAttackIfReady();
}
};
diff --git a/scripts/northrend/draktharon_keep/draktharon_keep.h b/scripts/northrend/draktharon_keep/draktharon_keep.h
index 4c36b6e..090b05d 100644
--- a/scripts/northrend/draktharon_keep/draktharon_keep.h
+++ b/scripts/northrend/draktharon_keep/draktharon_keep.h
@@ -16,6 +16,23 @@ enum
NPC_KING_DRED = 27483,
+ TYPE_CRYSTAL_1 = 5,
+ TYPE_CRYSTAL_2 = 6,
+ TYPE_CRYSTAL_3 = 7,
+ TYPE_CRYSTAL_4 = 8,
+ TYPE_NOVOS_PHASE2_CHECK = 9,
+ TYPE_NOVOS_EVENT = 10,
+
+ NPC_CRYSTAL_CHANNEL_TARGET = 26710,
+ NPC_CRYSTAL_CHANNEL = 26712,
+ NPC_TRIGGER_TARGET = 26714,
+ NPC_NOVOS = 26631,
+
+ NPC_CRYSTAL_HANDLER = 26627,
+ NPC_HULKING_CORPSE = 27597,
+ NPC_FETID_TROLL_CORPSE = 27598,
+ NPC_RISEN_SHADOWCASTER = 27600,
+
// Adds of King Dred Encounter - deaths counted for achievement
NPC_DRAKKARI_GUTRIPPER = 26641,
NPC_DRAKKARI_SCYTHECLAW = 26628,
diff --git a/scripts/northrend/howling_fjord.cpp b/scripts/northrend/howling_fjord.cpp
index d165729..9c34eb5 100644
--- a/scripts/northrend/howling_fjord.cpp
+++ b/scripts/northrend/howling_fjord.cpp
@@ -229,6 +229,64 @@ bool GossipSelect_npc_dark_ranger_lyana(Player* pPlayer, Creature* pCreature, ui
return true;
}
+/*######
+## npc_greer_orehammer
+######*/
+
+enum
+{
+ GOSSIP_ITEM_TAXI = -3000106,
+ GOSSIP_ITEM_GET_BOMBS = -3000107,
+ GOSSIP_ITEM_FLIGHT = -3000108,
+
+ QUEST_MISSION_PLAGUE_THIS = 11332,
+ ITEM_PRECISION_BOMBS = 33634,
+ TAXI_PATH_PLAGUE_THIS = 745,
+};
+
+bool GossipHello_npc_greer_orehammer(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_MISSION_PLAGUE_THIS) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (!pPlayer->HasItemCount(ITEM_PRECISION_BOMBS, 1, true))
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_GET_BOMBS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ }
+
+ if (pCreature->isTaxi())
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_TAXI, GOSSIP_ITEM_TAXI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_greer_orehammer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (Item* pItem = pPlayer->StoreNewItemInInventorySlot(ITEM_PRECISION_BOMBS, 10))
+ pPlayer->SendNewItem(pItem, 10, true, false);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(TAXI_PATH_PLAGUE_THIS);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ pPlayer->GetSession()->SendTaxiMenu(pCreature);
+ break;
+ }
+
+ return true;
+}
+
/*######
## npc_mcgoyver - TODO, can be moved to database
######*/
@@ -489,6 +547,12 @@ void AddSC_howling_fjord()
pNewScript->pGossipSelect = &GossipSelect_npc_dark_ranger_lyana;
pNewScript->RegisterSelf();
+ pNewScript = new Script;
+ pNewScript->Name = "npc_greer_orehammer";
+ pNewScript->pGossipHello = &GossipHello_npc_greer_orehammer;
+ pNewScript->pGossipSelect = &GossipSelect_npc_greer_orehammer;
+ pNewScript->RegisterSelf();
+
pNewScript = new Script;
pNewScript->Name = "npc_mcgoyver";
pNewScript->pGossipHello = &GossipHello_npc_mcgoyver;
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 3a002cb..12ac976 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
@@ -16,70 +16,211 @@
/* ScriptData
SDName: boss_bronjahm
-SD%Complete: 0%
-SDComment: Placeholder
-SDCategory: The Forge of Souls
+SD%Complete: 10%
+SDComment: by /dev/rsa
+SDCategory: Icecrown - forge of souls
EndScriptData */
#include "precompiled.h"
-#include "forge_of_souls.h"
+#include "def_forge.h"
-enum
+enum BossSpells
{
- SAY_AGGRO_1 = -1632000, // without sound, really correct?
- SAY_AGGRO_2 = -1632001,
- SAY_SLAY_1 = -1632002,
- SAY_SLAY_2 = -1632003,
- SAY_DEATH = -1632004,
- SAY_SOULSTORM = -1632005,
- SAY_CORRUPT_SOUL = -1632006,
+ //common
+ SPELL_BERSERK = 47008,
+ //yells
+ //summons
+ NPC_SOUL_FRAGMENT = 36535,
+ //Abilities
+ SPELL_MAGIC_BANE = 68793,
+ SPELL_CORRUPT_SOUL = 68839,
+ SPELL_CONSUME_SOUL = 68858,
+ SPELL_TELEPORT = 68988,
+ SPELL_SOULSTORM = 68872,
+ SPELL_SOULSTORM_2 = 68921,
+ SPELL_FEAR = 68950,
+ SPELL_SHADOW_BOLT = 70043,
+
+ /*Music*/
+ Battle01 = 6077,
+ Battle02 = 6078,
+ Battle03 = 6079,
+
};
-struct MANGOS_DLL_DECL boss_bronjahmAI : public ScriptedAI
+struct MANGOS_DLL_DECL boss_bronjahmAI : public BSWScriptedAI
{
- boss_bronjahmAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_bronjahmAI(Creature* pCreature) : BSWScriptedAI(pCreature)
{
- m_pInstance = (instance_forge_of_souls*)pCreature->GetInstanceData();
- m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
- instance_forge_of_souls* m_pInstance;
- bool m_bIsRegularMode;
+ ScriptedInstance *pInstance;
+ uint8 stage;
+ uint32 BattleMusicTimer;
+ uint32 Music;
void Reset()
{
+ if(pInstance) pInstance->SetData(TYPE_BRONJAHM, NOT_STARTED);
+ resetTimers();
+ stage = 0;
+ }
+
+ void Aggro(Unit *who)
+ {
+ Music = (urand(0, 2));
+ switch(Music)
+ {
+ case 0:
+ m_creature->PlayDirectSound(Battle01);
+ BattleMusicTimer = 48000;
+ break;
+ case 1:
+ m_creature->PlayDirectSound(Battle02);
+ BattleMusicTimer = 27000;
+ break;
+ case 2:
+ m_creature->PlayDirectSound(Battle03);
+ BattleMusicTimer = 36000;
+ break;
+ }
+
+ if(pInstance) pInstance->SetData(TYPE_BRONJAHM, IN_PROGRESS);
+ DoScriptText(-1632001,m_creature,who);
+ SetCombatMovement(true);
}
- void Aggro(Unit* pWho)
+ void JustDied(Unit *killer)
{
- DoScriptText(urand(0, 1) ? SAY_AGGRO_1 : SAY_AGGRO_2, m_creature);
- if (m_pInstance)
- m_pInstance->SetData(TYPE_BRONJAHM, IN_PROGRESS);
+ if(pInstance) pInstance->SetData(TYPE_BRONJAHM, DONE);
+ doRemove(SPELL_SOULSTORM);
+ DoScriptText(-1632004,m_creature,killer);
}
void KilledUnit(Unit* pVictim)
{
- if (pVictim->GetTypeId() != TYPEID_PLAYER)
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1632002,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1632003,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
- if (urand(0, 1))
- DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature);
+ switch(stage)
+ {
+ case 0:
+ if (timedQuery(SPELL_CORRUPT_SOUL, diff))
+ {
+ if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ if (doCast(SPELL_CORRUPT_SOUL, pTarget) == CAST_OK)
+ {
+ DoScriptText(-1632006,m_creature,pTarget);
+ float fPosX, fPosY, fPosZ;
+ pTarget->GetPosition(fPosX, fPosY, fPosZ);
+ doSummon(NPC_SOUL_FRAGMENT,fPosX, fPosY, fPosZ);
+ }
+ }
+ }
+ break;
+ case 1:
+ if (timedCast(SPELL_TELEPORT, diff) == CAST_OK) stage = 2;
+ break;
+ case 2:
+ if (timedCast(SPELL_SOULSTORM, diff) == CAST_OK) {
+ DoScriptText(-1632005,m_creature);
+ SetCombatMovement(false);
+ stage = 3;
+ }
+ break;
+ case 3:
+ timedCast(SPELL_FEAR, diff);
+ break;
+ }
+
+ timedCast(SPELL_SHADOW_BOLT, diff);
+
+ timedCast(SPELL_MAGIC_BANE, diff);
+
+ if (m_creature->GetHealthPercent() <= 30.0f && stage == 0) stage = 1;
+
+ DoMeleeAttackIfReady();
+
+ if (BattleMusicTimer < diff && m_creature->isAlive())
+ {
+ switch(Music)
+ {
+ case 0:
+ m_creature->PlayDirectSound(Battle01);
+ BattleMusicTimer = 49000;
+ break;
+ case 1:
+ m_creature->PlayDirectSound(Battle02);
+ BattleMusicTimer = 28000;
+ break;
+ case 2:
+ m_creature->PlayDirectSound(Battle03);
+ BattleMusicTimer = 37000;
+ break;
+ }
+ } else BattleMusicTimer -= diff;
+ }
+};
+
+struct MANGOS_DLL_DECL mob_soul_fragmentAI : public ScriptedAI
+{
+ mob_soul_fragmentAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
}
- void JustDied(Unit* pKiller)
+ ScriptedInstance *m_pInstance;
+ Creature* pBoss;
+ uint32 m_uiRangeCheck_Timer;
+
+ void Reset()
{
- DoScriptText(SAY_DEATH, m_creature);
+ m_uiRangeCheck_Timer = 1000;
+ if (!m_pInstance) return;
+ pBoss = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRONJAHM));
+ m_creature->SetSpeedRate(MOVE_RUN, 0.2f);
+ m_creature->GetMotionMaster()->MoveChase(pBoss);
+ m_creature->SetRespawnDelay(DAY);
+ }
- if (m_pInstance)
- m_pInstance->SetData(TYPE_BRONJAHM, DONE);
+ void AttackStart(Unit* pWho)
+ {
+ return;
}
- void JustReachedHome()
+ void UpdateAI(const uint32 uiDiff)
{
- if (m_pInstance)
- m_pInstance->SetData(TYPE_BRONJAHM, NOT_STARTED);
+ if (!m_pInstance || m_pInstance->GetData(TYPE_BRONJAHM) != IN_PROGRESS ) m_creature->ForcedDespawn();
+
+ if (m_uiRangeCheck_Timer < uiDiff)
+ {
+ if (pBoss->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ pBoss->CastSpell(pBoss, SPELL_CONSUME_SOUL, false);
+ m_creature->ForcedDespawn();
+ } else m_creature->GetMotionMaster()->MoveChase(pBoss);
+
+ m_uiRangeCheck_Timer = 1000;
+ }
+ else m_uiRangeCheck_Timer -= uiDiff;
}
+
};
CreatureAI* GetAI_boss_bronjahm(Creature* pCreature)
@@ -87,12 +228,23 @@ CreatureAI* GetAI_boss_bronjahm(Creature* pCreature)
return new boss_bronjahmAI(pCreature);
}
+CreatureAI* GetAI_mob_soul_fragment(Creature* pCreature)
+{
+ return new mob_soul_fragmentAI (pCreature);
+}
+
+
void AddSC_boss_bronjahm()
{
- Script* pNewScript;
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_bronjahm";
+ newscript->GetAI = &GetAI_boss_bronjahm;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_soul_fragment";
+ newscript->GetAI = &GetAI_mob_soul_fragment;
+ newscript->RegisterSelf();
- pNewScript = new Script;
- pNewScript->Name = "boss_bronjahm";
- pNewScript->GetAI = &GetAI_boss_bronjahm;
- pNewScript->RegisterSelf();
}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp
index 4ad33e8..d97bc66 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
@@ -16,105 +16,406 @@
/* ScriptData
SDName: boss_devourer_of_souls
-SD%Complete: 0%
-SDComment: Placeholder
+SD%Complete: 100%
+SDComment: MaxXx2021, modified by /dev/rsa
SDCategory: The Forge of Souls
EndScriptData */
#include "precompiled.h"
-#include "forge_of_souls.h"
+#include "def_forge.h"
enum
{
- // TODO, how to change the face on random?, how to know which face is shown, to use the additional entries
- SAY_MALE_1_AGGRO = -1632007,
- SAY_FEMALE_AGGRO = -1632008,
- SAY_MALE_1_SLAY_1 = -1632009,
- SAY_FEMALE_SLAY_1 = -1632010,
- SAY_MALE_2_SLAY_1 = -1632011,
- SAY_MALE_1_SLAY_2 = -1632012,
- SAY_FEMALE_SLAY_2 = -1632013,
- SAY_MALE_2_SLAY_2 = -1632014,
- SAY_MALE_1_DEATH = -1632015,
- SAY_FEMALE_DEATH = -1632016,
- SAY_MALE_2_DEATH = -1632017,
- SAY_MALE_1_SOUL_ATTACK = -1632018,
- SAY_FEMALE_SOUL_ATTACK = -1632019,
- SAY_MALE_2_SOUL_ATTACK = -1632020,
- SAY_MALE_1_DARK_GLARE = -1632021,
- SAY_FEMALE_DARK_GLARE = -1632022,
-
- EMOTE_MIRRORED_SOUL = -1632023,
- EMOTE_UNLEASH_SOULS = -1632024,
- EMOTE_WAILING_SOULS = -1632025,
-
- FACE_NORMAL = 0,
- FACE_UNLEASHING = 1,
- FACE_WAILING = 2,
+ /*Speach*/
+ SAY_DEVOURER_AGGRO_MALE_01 = -1632010,
+ SAY_DEVOURER_SLAY_01_MALE_01 = -1632012,
+ SAY_DEVOURER_SLAY_02_MALE_01 = -1632015,
+ SAY_DEVOURER_DEATH_MALE_01 = -1632018,
+ SAY_DEVOURER_SUMMON_MALE_01 = -1632023,
+ SAY_DEVOURER_DARK_MALE_01 = -1632027,
+ SAY_DEVOURER_MIRRORED_SOUL = -1632021,
+ SAY_DEVOURER_UNLEASHED_SOULS = -1632022,
+ SAY_DEVOURER_WELL_OF_SOULS = -1632026,
+
+ SAY_JAINA_FS09_EXTRO = -1632029,
+ SAY_SYLVANA_FS07_EXTRO = -1632030,
+
+ /*Spell And Visual Effects*/
+ SPELL_PHANTOM_BLAST = 68982,
+ SPELL_MIRRORED_SOUL = 69051,
+ SPELL_WELL_OF_SOULS = 68820,
+ SPELL_UNLEASHED_SOULS = 68939,
+ SPELL_WAILING_SOULS = 68912, //68873
+ SPELL_WELL_OF_SOULS_VIS = 68854,
+ SPELL_WELL_OF_SOUL_DM = 68863,
+
+ /*Units*/
+ NPC_WELL_OF_SOUL = 36536,
+ NPC_UNLEASHED_SOUL = 36595,
+
+ /*Others*/
+ MODEL_FAT = 30149,
+ MODEL_WOMAN = 30150,
+
+ /*Music*/
+ Battle01 = 6077,
+ Battle02 = 6078,
+ Battle03 = 6079,
+
+ MAX_POINTS = 22,
};
-static const int aTexts[6][3] =
+static Locations SpawnLoc[]=
{
- {SAY_MALE_1_AGGRO, SAY_FEMALE_AGGRO, 0}, // 0 - aggro
- {SAY_MALE_1_SLAY_1, SAY_FEMALE_SLAY_1, SAY_MALE_2_SLAY_1}, // 1 - slay1
- {SAY_MALE_1_SLAY_2, SAY_FEMALE_SLAY_2, SAY_MALE_2_SLAY_2}, // 2 - slay2
- {SAY_MALE_1_DEATH, SAY_FEMALE_DEATH, SAY_MALE_2_DEATH}, // 3 - death
- {SAY_MALE_1_SOUL_ATTACK, SAY_FEMALE_SOUL_ATTACK, SAY_MALE_2_SOUL_ATTACK}, // 4 - soul
- {SAY_MALE_1_DARK_GLARE, SAY_FEMALE_DARK_GLARE, 0} // 5 - glare
+{5618.139f, 2451.873f, 705.854f}, //0 - spawn
+{5590.47f, 2427.79f, 705.935f},
+{5593.59f, 2428.34f, 705.935f},
+{5600.81f, 2429.31f, 705.935f},
+{5600.81f, 2421.12f, 705.935f},
+{5601.43f, 2426.53f, 705.935f},
+{5601.55f, 2418.36f, 705.935f},
+{5598.0f, 2429.14f, 705.935f},
+{5594.04f, 2424.87f, 705.935f},
+{5597.89f, 2421.54f, 705.935f},
+{5598.57f, 2434.62f, 705.935f},
+{5585.46f, 2417.99f, 705.935f},
+{5605.81f, 2428.42f, 705.935f},
+{5591.61f, 2412.66f, 705.935f},
+{5593.9f, 2410.64f, 705.935f},
+{5586.76f, 2416.73f, 705.935f},
+{5592.23f, 2419.14f, 705.935f},
+{5594.61f, 2416.87f, 705.935f},
+{5589.77f, 2421.03f, 705.935f},
+{5602.58f, 2435.95f, 705.935f},
+{5606.13f, 2433.16f, 705.935f},
+{5606.12f, 2436.6f, 705.935f}, //21
};
+
+
struct MANGOS_DLL_DECL boss_devourer_of_soulsAI : public ScriptedAI
{
- boss_devourer_of_soulsAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_devourer_of_soulsAI(Creature *pCreature) : ScriptedAI(pCreature)
{
- m_pInstance = (instance_forge_of_souls*)pCreature->GetInstanceData();
- m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
- instance_forge_of_souls* m_pInstance;
- uint8 m_uiFace;
- bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint32 BattleMusicTimer;
+ uint32 PhantomBlastTimer;
+ uint32 SummonTimer;
+ uint32 WellOfSoulTimer;
+ uint32 MirroredTimer;
+ uint32 SoulBeamTimer;
+ uint32 Step;
+ uint32 StepTimer;
+ bool Summon;
void Reset()
{
- m_uiFace = FACE_NORMAL;
+ if(!m_pInstance) return;
+ m_pInstance->SetData(TYPE_DEVOURER, NOT_STARTED);
+ DespawnAllSummons();
+ Summon = false;
+ Step = 0;
+ StepTimer = 100;
+ PhantomBlastTimer = 5000;
+ WellOfSoulTimer = 12000;
+ SummonTimer = 20000;
+ MirroredTimer = 28000;
+ SoulBeamTimer = 33000;
}
- void Aggro(Unit* pWho)
+ void Aggro(Unit *who)
{
- DoScriptText(aTexts[0][m_uiFace], m_creature);
- if (m_pInstance)
- m_pInstance->SetData(TYPE_DECOURER_OF_SOULS, IN_PROGRESS);
+ if(!m_pInstance) return;
+ m_pInstance->SetData(TYPE_DEVOURER, IN_PROGRESS);
+ m_creature->PlayDirectSound(Battle01);
+ BattleMusicTimer = 48000;
+ DoScriptText(SAY_DEVOURER_AGGRO_MALE_01, m_creature);
}
- void KilledUnit(Unit* pVictim)
+ void DespawnAllSummons()
{
- if (pVictim->GetTypeId() != TYPEID_PLAYER)
- return;
+ std::list m_pSouls;
+ GetCreatureListWithEntryInGrid(m_pSouls, m_creature, NPC_UNLEASHED_SOUL, DEFAULT_VISIBILITY_INSTANCE);
+
+ if (!m_pSouls.empty())
+ for(std::list::iterator itr = m_pSouls.begin(); itr != m_pSouls.end(); ++itr)
+ {
+ (*itr)->ForcedDespawn();
+ }
+
+ std::list m_pWells;
+ GetCreatureListWithEntryInGrid(m_pWells, m_creature, NPC_WELL_OF_SOUL, DEFAULT_VISIBILITY_INSTANCE);
- if (urand(0, 1))
- DoScriptText(aTexts[urand(1, 2)][m_uiFace], m_creature);
+ if (!m_pWells.empty())
+ for(std::list::iterator iter = m_pWells.begin(); iter != m_pWells.end(); ++iter)
+ {
+ (*iter)->ForcedDespawn();
+ }
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+
+ Map *map = m_creature->GetMap();
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_MIRRORED_SOUL))
+ m_creature->DealDamage(i->getSource(), uiDamage/2,NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ void SpawnOutro(uint32 guid)
+ {
+ if (Creature *pSummon = m_creature->SummonCreature(guid, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z,0, TEMPSUMMON_TIMED_DESPAWN, 300000))
+ {
+ uint8 i = urand(1,MAX_POINTS);
+
+ pSummon->GetMotionMaster()->MovePoint(i, SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z);
+
+ if (pSummon->GetEntry() == npc_jaina_extro)
+ DoScriptText(SAY_JAINA_FS09_EXTRO, pSummon);
+ else if (pSummon->GetEntry() == npc_sylvana_extro)
+ DoScriptText(SAY_SYLVANA_FS07_EXTRO, pSummon);
+ }
}
void JustDied(Unit* pKiller)
{
- DoScriptText(aTexts[3][m_uiFace], m_creature);
+ if(!m_pInstance) return;
+ m_pInstance->SetData(TYPE_DEVOURER, DONE);
+ DoScriptText(SAY_DEVOURER_DEATH_MALE_01, m_creature);
+ DespawnAllSummons();
- if (m_pInstance)
+ Player* player = (Player*)pKiller;
+
+ if(player->GetTeam() == ALLIANCE)
+ {
+ m_pInstance->SetData64(DATA_LIDER,0);
+ SpawnOutro(npc_jaina_extro);
+ SpawnOutro(npc_jaina_credit);
+ SpawnOutro(npc_mage);
+ SpawnOutro(npc_mage_woman);
+ SpawnOutro(npc_cc_a_01);
+ SpawnOutro(npc_cc_a_02);
+ SpawnOutro(npc_cc_a_03);
+
+ } else
+ {
+ m_pInstance->SetData64(DATA_LIDER,1);
+ SpawnOutro(npc_sylvana_extro);
+ SpawnOutro(npc_sylvana_credit);
+ SpawnOutro(npc_mage);
+ SpawnOutro(npc_mage_woman);
+ SpawnOutro(npc_cc_h_01);
+ SpawnOutro(npc_cc_h_02);
+ SpawnOutro(npc_cc_h_03);
+ };
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ switch (urand(0,1))
{
- m_pInstance->SetData(TYPE_DECOURER_OF_SOULS, DONE);
+ case 0: DoScriptText(SAY_DEVOURER_SLAY_01_MALE_01, m_creature); break;
+ case 1: DoScriptText(SAY_DEVOURER_SLAY_02_MALE_01, m_creature); break;
}
}
- void JustReachedHome()
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(Summon != true)
+ {
+ if (PhantomBlastTimer < diff)
+ {
+ if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(Target, SPELL_PHANTOM_BLAST);
+ PhantomBlastTimer = 8000;
+ }
+ else
+ PhantomBlastTimer -= diff;
+
+ if (WellOfSoulTimer < diff)
+ {
+ if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(Target, SPELL_WELL_OF_SOULS);
+ DoScriptText(SAY_DEVOURER_WELL_OF_SOULS, m_creature);
+ WellOfSoulTimer = urand(12000,24000);
+ }
+ else
+ WellOfSoulTimer -= diff;
+
+ if (SummonTimer < diff)
+ {
+ m_creature->InterruptNonMeleeSpells(false);
+ switch (urand(0,1))
+ {
+ case 0: DoScriptText(SAY_DEVOURER_SUMMON_MALE_01, m_creature); break;
+ case 1: DoScriptText(SAY_DEVOURER_UNLEASHED_SOULS, m_creature); break;
+ }
+ DoCast(m_creature, SPELL_UNLEASHED_SOULS);
+ SummonTimer = 50000;
+ Summon = true;
+ }
+ else
+ SummonTimer -= diff;
+
+ if (MirroredTimer < diff)
+ {
+ if (Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ DoCast(Target, SPELL_MIRRORED_SOUL);
+ DoScriptText(SAY_DEVOURER_MIRRORED_SOUL, m_creature);
+ MirroredTimer = 25000;
+ }
+ }
+ else
+ MirroredTimer -= diff;
+
+ if (SoulBeamTimer < diff)
+ {
+ DoScriptText(SAY_DEVOURER_DARK_MALE_01, m_creature);
+ DoCast(m_creature->getVictim(), SPELL_WAILING_SOULS);
+ SoulBeamTimer = (urand(35000, 45000));
+ }
+ else
+ SoulBeamTimer -= diff;
+
+ }
+
+ if(Summon == true)
+ {
+ if (StepTimer < diff)
+ {
+ switch(Step)
+ {
+ case 0:
+ StepTimer = 900;
+ ++Step;
+ break;
+ case 1:
+ m_creature->SetDisplayId(MODEL_FAT); //this is huck, because this spell (SPELL_UNLEASHED_SOULS) morphed boss into PIG :D
+ StepTimer = 2000;
+ ++Step;
+ break;
+ case 2:
+ Summon = false;
+ Step = 0;
+ StepTimer = 100;
+ break;
+ }
+ } else StepTimer -= diff;
+
+ }
+
+ DoMeleeAttackIfReady();
+
+ if (BattleMusicTimer < diff && m_creature->isAlive())
+ {
+ m_creature->PlayDirectSound(Battle01);
+ BattleMusicTimer = 49000;
+ }
+ else
+ BattleMusicTimer -= diff;
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_well_of_soulAI : public ScriptedAI
+{
+ npc_well_of_soulAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+
+uint32 DamageTimer;
+uint32 DeathTimer;
+
+ void Reset()
+ {
+ m_creature->SetLevel(80);
+ m_creature->setFaction(14);
+ m_creature->SetDisplayId(11686);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DeathTimer = 60000;
+ DoCast(m_creature, SPELL_WELL_OF_SOULS_VIS);
+ DamageTimer = 1000;
+ }
+
+ void AttackStart(Unit* who)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_DEVOURER) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (DeathTimer < diff)
+ {
+ m_creature->ForcedDespawn();
+ } else DeathTimer -= diff;
+
+ if (DamageTimer < diff)
+ {
+ DoCast(m_creature, SPELL_WELL_OF_SOUL_DM);
+ DamageTimer = 1000;
+ } else DamageTimer -= diff;
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_unleashed_soulAI : public ScriptedAI
+{
+ npc_unleashed_soulAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
{
if (m_pInstance)
{
- m_pInstance->SetData(NPC_DEVOURER_OF_SOULS, NOT_STARTED);
- // If we previously failed, set such that possible to try again
- m_pInstance->SetData(TYPE_ACHIEV_PHANTOM_BLAST, IN_PROGRESS);
+ if (Creature* pDevourer = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_DEVOURER)))
+ if (pDevourer && pDevourer->isAlive())
+ AttackStart(pDevourer->getVictim());
}
+
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_DEVOURER) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+
}
};
@@ -123,12 +424,32 @@ CreatureAI* GetAI_boss_devourer_of_souls(Creature* pCreature)
return new boss_devourer_of_soulsAI(pCreature);
}
+CreatureAI* GetAI_npc_well_of_soul(Creature* pCreature)
+{
+ return new npc_well_of_soulAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_unleashed_soul(Creature* pCreature)
+{
+ return new npc_unleashed_soulAI(pCreature);
+}
+
void AddSC_boss_devourer_of_souls()
{
- Script* pNewScript;
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_devourer_of_souls";
+ newscript->GetAI = &GetAI_boss_devourer_of_souls;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_well_of_soul";
+ newscript->GetAI = &GetAI_npc_well_of_soul;
+ newscript->RegisterSelf();
- pNewScript = new Script;
- pNewScript->Name = "boss_devourer_of_souls";
- pNewScript->GetAI = &GetAI_boss_devourer_of_souls;
- pNewScript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "npc_unleashed_soul";
+ newscript->GetAI = &GetAI_npc_unleashed_soul;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/def_forge.h b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/def_forge.h
new file mode 100644
index 0000000..669cafe
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/def_forge.h
@@ -0,0 +1,35 @@
+#ifndef DEF_ICECROWN_FORGE_H
+#define DEF_ICECROWN_FORGE_H
+#include "BSW_ai.h"
+
+enum
+{
+ MAX_ENCOUNTERS = 3,
+
+ TYPE_INTRO = 0,
+ TYPE_BRONJAHM = 1,
+ TYPE_DEVOURER = 2,
+
+ NPC_BRONJAHM = 36497,
+ NPC_DEVOURER = 36502,
+
+ DATA_LIDER = 101,
+
+ npc_jaina = 37597,
+ npc_sylvana = 37596,
+ npc_jaina_extro = 38160,
+ npc_sylvana_extro = 38161,
+ npc_jaina_credit = 36955,
+ npc_sylvana_credit = 37554,
+ npc_mage = 37582,
+ npc_mage_woman = 37774,
+ npc_cc_a_01 = 37497,
+ npc_cc_a_02 = 37496,
+ npc_cc_a_03 = 37498,
+ npc_cc_h_01 = 37588,
+ npc_cc_h_02 = 37584,
+ npc_cc_h_03 = 37587,
+
+};
+
+#endif
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp
new file mode 100644
index 0000000..b6d79b6
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/forge_of_souls.cpp
@@ -0,0 +1,537 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Forge Of The Souls
+SD%Complete: 90%
+SDComment: event script! Need Add 6 Coliseum Champion after devourer death.
+SDCategory: forge_of_the_souls
+SDAuthor: MaxXx2021 aka Mioka
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_forge.h"
+
+enum
+{
+ SAY_JAINA_FS01 = -1632040,
+ SAY_JAINA_FS02 = -1632041,
+ SAY_JAINA_FS03 = -1632042,
+ SAY_JAINA_FS04 = -1632043,
+ SAY_JAINA_FS05 = -1632044,
+ SAY_JAINA_FS06 = -1632045,
+ SAY_JAINA_FS07 = -1632046,
+ SAY_JAINA_FS08 = -1632047,
+ SAY_JAINA_FS09_EXTRO = -1632029,
+
+ SAY_SYLVANA_FS01 = -1632050,
+ SAY_SYLVANA_FS02 = -1632051,
+ SAY_SYLVANA_FS03 = -1632052,
+ SAY_SYLVANA_FS04 = -1632053,
+ SAY_SYLVANA_FS05 = -1632054,
+ SAY_SYLVANA_FS06 = -1632055,
+ SAY_SYLVANA_FS07_EXTRO = -1632030,
+
+ GOSSIP_SPEECHINTRO = 13525,
+};
+
+struct MANGOS_DLL_DECL npc_jaina_and_sylvana_FSintroAI : public ScriptedAI
+{
+ npc_jaina_and_sylvana_FSintroAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+
+uint32 StepTimer;
+uint32 Step;
+bool StartEvent;
+
+ void Reset()
+ {
+ if(m_pInstance)
+ if(m_pInstance->GetData(TYPE_DEVOURER) == DONE)
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Step = 0;
+ StepTimer = 100;
+ if(m_pInstance->GetData(TYPE_INTRO) == DONE)
+ {
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Step = 8;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ DoMeleeAttackIfReady();
+
+ if(!m_pInstance) return;
+
+ if(StartEvent != true) return;
+
+ if(StepTimer < diff)
+ {
+ switch(Step)
+ {
+ case 0:
+ m_pInstance->SetData(TYPE_INTRO, DONE);
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS01, m_creature);
+ StepTimer = 7000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana)
+ StepTimer = 100;
+ ++Step;
+ break;
+ case 1:
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS02, m_creature);
+ StepTimer = 9000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana)
+ {
+ DoScriptText(SAY_SYLVANA_FS01, m_creature);
+ StepTimer = 12000;
+ }
+ ++Step;
+ break;
+ case 2:
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS03, m_creature);
+ StepTimer = 8000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana)
+ {
+ DoScriptText(SAY_SYLVANA_FS02, m_creature);
+ StepTimer = 11000;
+ }
+ ++Step;
+ break;
+ case 3:
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS04, m_creature);
+ StepTimer = 10000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana)
+ {
+ DoScriptText(SAY_SYLVANA_FS03, m_creature);
+ StepTimer = 11000;
+ }
+ ++Step;
+ break;
+ case 4:
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS05, m_creature);
+ StepTimer = 8000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana)
+ {
+ DoScriptText(SAY_SYLVANA_FS04, m_creature);
+ StepTimer = 12000;
+ }
+ ++Step;
+ break;
+ case 5:
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS06, m_creature);
+ StepTimer = 12000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana)
+ {
+ DoScriptText(SAY_SYLVANA_FS05, m_creature);
+ StepTimer = 7000;
+ }
+ ++Step;
+ break;
+ case 6:
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS07, m_creature);
+ StepTimer = 7000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana)
+ {
+ DoScriptText(SAY_SYLVANA_FS06, m_creature);
+ StepTimer = 4000;
+ }
+ ++Step;
+ break;
+ case 7:
+ if(m_creature->GetEntry() == npc_jaina)
+ {
+ DoScriptText(SAY_JAINA_FS08, m_creature);
+ StepTimer = 5000;
+ }
+ ++Step;
+ break;
+ }
+ } else StepTimer -= diff;
+ }
+};
+
+bool GossipHello_npc_jaina_and_sylvana_FSintro(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu( pCreature->GetGUID());
+ switch(pCreature->GetEntry())
+ {
+ case 37597:
+ if(((npc_jaina_and_sylvana_FSintroAI*)pCreature->AI())->StartEvent != true)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "What would you have of me, My Lady?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ break;
+ case 37596:
+ if(((npc_jaina_and_sylvana_FSintroAI*)pCreature->AI())->StartEvent != true)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "What would you have of me, Banshee Queen?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ break;
+ }
+
+ pPlayer->PlayerTalkClass->SendGossipMenu(907,pCreature->GetGUID()); //907
+ return true;
+}
+
+bool GossipSelect_npc_jaina_and_sylvana_FSintro(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ pPlayer->CLOSE_GOSSIP_MENU();
+ ((npc_jaina_and_sylvana_FSintroAI*)pCreature->AI())->StartEvent = true;
+
+ return true;
+}
+
+struct MANGOS_DLL_DECL npc_jaina_and_sylvana_FSextroAI : public ScriptedAI
+{
+ npc_jaina_and_sylvana_FSextroAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+
+uint32 StepTimer;
+uint32 Step;
+uint64 m_uiLiderGUID;
+uint32 uiSummon_counter;
+
+ void Reset()
+ {
+ if (m_pInstance)
+ if (m_pInstance->GetData(TYPE_DEVOURER) != DONE)
+ {
+ m_pInstance->SetData(TYPE_DEVOURER, NOT_STARTED);
+ Step = 0;
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ } else Step = 10;
+ StepTimer = 100;
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ DoMeleeAttackIfReady();
+
+ if (!m_pInstance) return;
+
+ if (m_pInstance->GetData(TYPE_DEVOURER) == DONE)
+ {
+
+ if(m_pInstance->GetData64(DATA_LIDER) == 1 && m_creature->GetEntry() == npc_sylvana_extro) return;
+
+ if(m_pInstance->GetData64(DATA_LIDER) == 2 && m_creature->GetEntry() == npc_jaina_extro) return;
+
+ if(StepTimer < diff)
+ {
+ switch(Step)
+ {
+ case 0:
+ m_creature->SetVisibility(VISIBILITY_ON);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MovePoint(0, 5653.337f, 2496.407f, 708.829f);
+ uiSummon_counter = 0;
+ StepTimer = 400;
+ ++Step;
+ break;
+ case 1:
+ if(m_creature->GetEntry() == npc_jaina_extro)
+ {
+ StepTimer = 100;
+ if (uiSummon_counter < 4)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(npc_cc_a_01,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000))
+ {
+ pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ switch(uiSummon_counter)
+ {
+ case 0:
+ pTemp->GetMotionMaster()->MovePoint(0, 5659.251f, 2472.017f, 708.696f);
+ break;
+ case 1:
+ pTemp->GetMotionMaster()->MovePoint(0, 5627.611f, 2501.972f, 708.696f);
+ break;
+ case 2:
+ pTemp->GetMotionMaster()->MovePoint(0, 5680.920f, 2482.998f, 708.696f);
+ break;
+ case 3:
+ pTemp->GetMotionMaster()->MovePoint(0, 5641.398f, 2523.911f, 708.696f);
+ break;
+ }
+ uiSummon_counter++;
+ }
+ }
+ else
+ {
+ uiSummon_counter = 0;
+ Step++;
+ }
+ }
+ if(m_creature->GetEntry() == npc_sylvana_extro)
+ {
+ StepTimer = 100;
+ if (uiSummon_counter < 4)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(npc_cc_h_01,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000))
+ {
+ pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ switch(uiSummon_counter)
+ {
+ case 0:
+ pTemp->GetMotionMaster()->MovePoint(0, 5659.251f, 2472.017f, 708.696f);
+ break;
+ case 1:
+ pTemp->GetMotionMaster()->MovePoint(0, 5627.611f, 2501.972f, 708.696f);
+ break;
+ case 2:
+ pTemp->GetMotionMaster()->MovePoint(0, 5680.920f, 2482.998f, 708.696f);
+ break;
+ case 3:
+ pTemp->GetMotionMaster()->MovePoint(0, 5641.398f, 2523.911f, 708.696f);
+ break;
+ }
+ uiSummon_counter++;
+ }
+ }
+ else
+ {
+ uiSummon_counter = 0;
+ Step++;
+ }
+ }
+ break;
+ case 2:
+ if(m_creature->GetEntry() == npc_jaina_extro)
+ {
+ StepTimer = 100;
+ if (uiSummon_counter < 4)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(npc_cc_a_02,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000))
+ {
+ pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ switch(uiSummon_counter)
+ {
+ case 0:
+ pTemp->GetMotionMaster()->MovePoint(0, 5661.508f, 2473.066f, 708.696f);
+ break;
+ case 1:
+ pTemp->GetMotionMaster()->MovePoint(0, 5627.146f, 2499.098f, 708.696f);
+ break;
+ case 2:
+ pTemp->GetMotionMaster()->MovePoint(0, 5682.331f, 2485.985f, 708.696f);
+ break;
+ case 3:
+ pTemp->GetMotionMaster()->MovePoint(0, 5639.636f, 2521.228f, 708.696f);
+ break;
+ }
+ uiSummon_counter++;
+ }
+ }
+ else
+ {
+ uiSummon_counter = 0;
+ Step++;
+ }
+ }
+ if(m_creature->GetEntry() == npc_sylvana_extro)
+ {
+ StepTimer = 100;
+ if (uiSummon_counter < 4)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(npc_cc_h_02,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000))
+ {
+ pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ switch(uiSummon_counter)
+ {
+ case 0:
+ pTemp->GetMotionMaster()->MovePoint(0, 5661.508f, 2473.066f, 708.696f);
+ break;
+ case 1:
+ pTemp->GetMotionMaster()->MovePoint(0, 5627.146f, 2499.098f, 708.696f);
+ break;
+ case 2:
+ pTemp->GetMotionMaster()->MovePoint(0, 5682.331f, 2485.985f, 708.696f);
+ break;
+ case 3:
+ pTemp->GetMotionMaster()->MovePoint(0, 5639.636f, 2521.228f, 708.696f);
+ break;
+ }
+ uiSummon_counter++;
+ }
+ }
+ else
+ {
+ uiSummon_counter = 0;
+ Step++;
+ }
+ }
+ break;
+ case 3:
+ if(m_creature->GetEntry() == npc_jaina_extro)
+ {
+ StepTimer = 100;
+ if (uiSummon_counter < 4)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(npc_cc_a_03,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000))
+ {
+ pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ switch(uiSummon_counter)
+ {
+ case 0:
+ pTemp->GetMotionMaster()->MovePoint(0, 5664.265f, 2473.974f, 708.696f);
+ break;
+ case 1:
+ pTemp->GetMotionMaster()->MovePoint(0, 5626.768f, 2496.534f, 708.696f);
+ break;
+ case 2:
+ pTemp->GetMotionMaster()->MovePoint(0, 5683.696f, 2489.598f, 708.696f);
+ break;
+ case 3:
+ pTemp->GetMotionMaster()->MovePoint(0, 5637.580f, 2518.249f, 708.696f);
+ break;
+ }
+ uiSummon_counter++;
+ }
+ }
+ else
+ {
+ uiSummon_counter = 0;
+ StepTimer = 8000;
+ Step++;
+ }
+ }
+ if(m_creature->GetEntry() == npc_sylvana_extro)
+ {
+ StepTimer = 100;
+ if (uiSummon_counter < 4)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(npc_cc_h_03,5623.609f,2457.946f,705.891f,1.37f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000))
+ {
+ pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ switch(uiSummon_counter)
+ {
+ case 0:
+ pTemp->GetMotionMaster()->MovePoint(0, 5664.265f, 2473.974f, 708.696f);
+ break;
+ case 1:
+ pTemp->GetMotionMaster()->MovePoint(0, 5626.768f, 2496.534f, 708.696f);
+ break;
+ case 2:
+ pTemp->GetMotionMaster()->MovePoint(0, 5683.696f, 2489.598f, 708.696f);
+ break;
+ case 3:
+ pTemp->GetMotionMaster()->MovePoint(0, 5637.580f, 2518.249f, 708.696f);
+ break;
+ }
+ uiSummon_counter++;
+ }
+ }
+ else
+ {
+ uiSummon_counter = 0;
+ StepTimer = 8000;
+ Step++;
+ }
+ }
+ break;
+ case 4:
+ if(m_creature->GetEntry() == npc_jaina_extro)
+ {
+ DoScriptText(SAY_JAINA_FS09_EXTRO, m_creature);
+ StepTimer = 6000;
+ }
+ if(m_creature->GetEntry() == npc_sylvana_extro)
+ {
+ DoScriptText(SAY_SYLVANA_FS07_EXTRO, m_creature);
+ StepTimer = 3000;
+ }
+ ++Step;
+ break;
+ case 5:
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ ++Step;
+ break;
+ }
+ } else StepTimer -= diff;
+ }
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_jaina_and_sylvana_FSintro(Creature* pCreature)
+{
+ return new npc_jaina_and_sylvana_FSintroAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_jaina_and_sylvana_FSextro(Creature* pCreature)
+{
+ return new npc_jaina_and_sylvana_FSextroAI(pCreature);
+}
+
+void AddSC_forge_of_souls()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_jaina_and_sylvana_FSintro";
+ newscript->GetAI = &GetAI_npc_jaina_and_sylvana_FSintro;
+ newscript->pGossipHello = &GossipHello_npc_jaina_and_sylvana_FSintro;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_and_sylvana_FSintro;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jaina_and_sylvana_FSextro";
+ newscript->GetAI = &GetAI_npc_jaina_and_sylvana_FSextro;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp
index c600db6..cb2875a 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,237 +1,175 @@
/* 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: instance_forge_of_souls
-SD%Complete: 90%
-SDComment: TODO: Movement of the extro-event is missing, implementation unclear!
-SDCategory: The Forge of Souls
-EndScriptData */
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
#include "precompiled.h"
-#include "forge_of_souls.h"
+#include "def_forge.h"
-instance_forge_of_souls::instance_forge_of_souls(Map* pMap) : ScriptedInstance(pMap),
- m_bCriteriaPhantomBlastFailed(false),
- m_uiTeam(0),
- m_uiBronjahmGUID(0),
- m_uiDevourerOrSoulsGUID(0)
+struct MANGOS_DLL_DECL instance_forge_of_souls : public ScriptedInstance
{
- Initialize();
-}
+ instance_forge_of_souls(Map* pMap) : ScriptedInstance(pMap)
+ {
+ Regular = pMap->IsRegularDifficulty();
+ Initialize();
+ }
-void instance_forge_of_souls::Initialize()
-{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
-}
+ bool Regular;
+ bool needSave;
+ std::string strSaveData;
-void instance_forge_of_souls::OnCreatureCreate(Creature* pCreature)
-{
- switch(pCreature->GetEntry())
+ //Creatures GUID
+ uint32 m_auiEncounter[MAX_ENCOUNTERS+1];
+ uint64 m_uiBronjahmGUID;
+ uint64 m_uiDevourerGUID;
+ uint64 m_uiLiderGUID;
+
+ void OpenDoor(uint64 guid)
{
- case NPC_BRONJAHM: m_uiBronjahmGUID = pCreature->GetGUID(); break;
- case NPC_DEVOURER_OF_SOULS: m_uiDevourerOrSoulsGUID = pCreature->GetGUID(); break;
- case NPC_CORRUPTED_SOUL_FRAGMENT: m_luiSoulFragmentAliveGUIDs.push_back(pCreature->GetGUID()); break;
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_ACTIVE);
}
-}
-void instance_forge_of_souls::OnPlayerEnter(Player* pPlayer)
-{
- if (!m_uiTeam) // very first player to enter
+ void CloseDoor(uint64 guid)
{
- m_uiTeam = pPlayer->GetTeam();
- ProcessEventNpcs(pPlayer, false);
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_READY);
}
-}
-void instance_forge_of_souls::ProcessEventNpcs(Player* pPlayer, bool bChanged)
-{
- if (!pPlayer)
- return;
+ void Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+ m_uiBronjahmGUID =0;
+ m_uiDevourerGUID =0;
+ }
- if (m_auiEncounter[0] != DONE || m_auiEncounter[1] != DONE)
+ void OnCreatureCreate(Creature* pCreature)
{
- // Spawn Begin Mobs
- for (uint8 i = 0; i < sizeof(aEventBeginLocations)/sizeof(sIntoEventNpcSpawnLocations); i++)
+ switch(pCreature->GetEntry())
{
- if (Creature* pSummon = pPlayer->SummonCreature(m_uiTeam == HORDE ? aEventBeginLocations[i].uiEntryHorde : aEventBeginLocations[i].uiEntryAlliance,
- aEventBeginLocations[i].fSpawnX, aEventBeginLocations[i].fSpawnY, aEventBeginLocations[i].fSpawnZ, aEventBeginLocations[i].fSpawnO, TEMPSUMMON_DEAD_DESPAWN, 24*HOUR*IN_MILLISECONDS))
- m_lEventMobGUIDs.push_back(pSummon->GetGUID());
+ case NPC_DEVOURER:
+ m_uiDevourerGUID = pCreature->GetGUID();
+ break;
+ case NPC_BRONJAHM:
+ m_uiBronjahmGUID = pCreature->GetGUID();
+ break;
}
}
- else
+
+ void OnObjectCreate(GameObject* pGo)
{
- // if bChanged, despawn Begin Mobs, spawn End Mobs at Spawn, else spawn EndMobs at End
- if (bChanged)
+ switch(pGo->GetEntry())
{
- for (std::list::const_iterator itr = m_lEventMobGUIDs.begin(); itr != m_lEventMobGUIDs.end(); itr++)
- {
- if (Creature* pSummoned = instance->GetCreature(*itr))
- pSummoned->ForcedDespawn();
- }
-
- for (uint8 i = 0; i < sizeof(aEventEndLocations)/sizeof(sExtroEventNpcLocations); i++)
- {
- pPlayer->SummonCreature(m_uiTeam == HORDE ? aEventEndLocations[i].uiEntryHorde : aEventEndLocations[i].uiEntryAlliance,
- aEventEndLocations[i].fSpawnX, aEventEndLocations[i].fSpawnY, aEventEndLocations[i].fSpawnZ, aEventEndLocations[i].fStartO, TEMPSUMMON_DEAD_DESPAWN, 24*HOUR*IN_MILLISECONDS);
-
- // TODO: Let the NPCs Move along their paths
- }
- }
- else
- { // Summon at end, without event
- for (uint8 i = 0; i < sizeof(aEventEndLocations)/sizeof(sExtroEventNpcLocations); i++)
- {
- pPlayer->SummonCreature(m_uiTeam == HORDE ? aEventEndLocations[i].uiEntryHorde : aEventEndLocations[i].uiEntryAlliance,
- aEventEndLocations[i].fEndX, aEventEndLocations[i].fEndY, aEventEndLocations[i].fEndZ, aEventEndLocations[i].fEndO, TEMPSUMMON_DEAD_DESPAWN, 24*HOUR*IN_MILLISECONDS);
- }
}
}
-}
-
-Player* instance_forge_of_souls::GetPlayer()
-{
- Map::PlayerList const& players = instance->GetPlayers();
-
- if (!players.isEmpty())
+ void SetData(uint32 uiType, uint32 uiData)
{
- for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ switch(uiType)
+ {
+ case TYPE_INTRO: m_auiEncounter[0] = uiData; break;
+ case TYPE_BRONJAHM: m_auiEncounter[1] = uiData; break;
+ case TYPE_DEVOURER: m_auiEncounter[2] = uiData; break;
+ default: break;
+ }
+
+ if (uiData == DONE)
{
- if (Player* plr = itr->getSource())
- return plr;
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ strSaveData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
}
}
- return NULL;
-}
-bool instance_forge_of_souls::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/)
-{
- switch (uiCriteriaId)
+ const char* Save()
{
- case ACHIEV_CRIT_SOUL_POWER:
- return m_luiSoulFragmentAliveGUIDs.size() >= 4;
- case ACHIEV_CRIT_PHANTOM_BLAST:
- return !m_bCriteriaPhantomBlastFailed;
- default:
- return 0;
+ return strSaveData.c_str();
}
-}
-void instance_forge_of_souls::SetData(uint32 uiType, uint32 uiData)
-{
- switch(uiType)
+ uint32 GetData(uint32 uiType)
{
- case TYPE_BRONJAHM:
- m_auiEncounter[0] = uiData;
-
- // Despawn remaining adds and clear list
- for (std::list::const_iterator itr = m_luiSoulFragmentAliveGUIDs.begin(); itr != m_luiSoulFragmentAliveGUIDs.end(); itr++)
- {
- if (Creature* pFragment = instance->GetCreature(*itr))
- pFragment->ForcedDespawn();
- }
- m_luiSoulFragmentAliveGUIDs.clear();
- break;
- case TYPE_DECOURER_OF_SOULS:
- m_auiEncounter[1] = uiData;
- if (uiData == DONE)
- ProcessEventNpcs(GetPlayer(), true);
- break;
- case TYPE_ACHIEV_PHANTOM_BLAST:
- m_bCriteriaPhantomBlastFailed = (uiData == FAIL);
- return;
+ switch(uiType)
+ {
+ case TYPE_INTRO: return m_auiEncounter[0];
+ case TYPE_BRONJAHM: return m_auiEncounter[1];
+ case TYPE_DEVOURER: return m_auiEncounter[2];
+ }
+ return 0;
}
- if (uiData == DONE)
+ uint64 GetData64(uint32 uiData)
{
- OUT_SAVE_INST_DATA;
-
- std::ostringstream saveStream;
- saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1];
-
- strInstData = saveStream.str();
-
- SaveToDB();
- OUT_SAVE_INST_DATA_COMPLETE;
+ switch(uiData)
+ {
+ case NPC_BRONJAHM: return m_uiBronjahmGUID;
+ case NPC_DEVOURER: return m_uiDevourerGUID;
+ case DATA_LIDER: return m_uiLiderGUID;
+ }
+ return 0;
}
-}
-void instance_forge_of_souls::Load(const char* chrIn)
-{
- if (!chrIn)
+ void SetData64(uint32 uiData, uint64 uiGuid)
{
- OUT_LOAD_INST_DATA_FAIL;
- return;
+ switch(uiData)
+ {
+ case DATA_LIDER: m_uiLiderGUID = uiGuid;
+ }
}
- OUT_LOAD_INST_DATA(chrIn);
+ void Load(const char* chrIn)
+ {
+ if (!chrIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
- std::istringstream loadStream(chrIn);
- loadStream >> m_auiEncounter[0] >> m_auiEncounter[1];
+ OUT_LOAD_INST_DATA(chrIn);
- for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- {
- if (m_auiEncounter[i] == IN_PROGRESS)
- m_auiEncounter[i] = NOT_STARTED;
- }
+ std::istringstream loadStream(chrIn);
- OUT_LOAD_INST_DATA_COMPLETE;
-}
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
-uint32 instance_forge_of_souls::GetData(uint32 uiType)
-{
- switch(uiType)
- {
- case TYPE_BRONJAHM:
- return m_auiEncounter[0];
- case TYPE_DECOURER_OF_SOULS:
- return m_auiEncounter[1];
- default:
- return 0;
- }
-}
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
-uint64 instance_forge_of_souls::GetData64(uint32 uiData)
-{
- switch(uiData)
- {
- case NPC_BRONJAHM:
- return m_uiBronjahmGUID;
- case NPC_DEVOURER_OF_SOULS:
- return m_uiDevourerOrSoulsGUID;
- default:
- return 0;
+ OUT_LOAD_INST_DATA_COMPLETE;
}
-}
-
-void instance_forge_of_souls::SetData64(uint32 uiType, uint64 uiData)
-{
- if (uiType == DATA_SOULFRAGMENT_REMOVE)
- m_luiSoulFragmentAliveGUIDs.remove(uiData);
-}
+};
InstanceData* GetInstanceData_instance_forge_of_souls(Map* pMap)
{
return new instance_forge_of_souls(pMap);
}
+
void AddSC_instance_forge_of_souls()
{
Script* pNewScript;
-
pNewScript = new Script;
pNewScript->Name = "instance_forge_of_souls";
pNewScript->GetInstanceData = &GetInstanceData_instance_forge_of_souls;
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_forge_of_souls.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_forge_of_souls.cpp
new file mode 100644
index 0000000..b617e41
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/forge_of_souls/trash_forge_of_souls.cpp
@@ -0,0 +1,594 @@
+/* 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: Trash Mobs
+SD%Complete: 100%
+SDComment:
+SDCategory: The Forge of Souls
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_forge.h"
+
+enum
+{
+ //Spiteful Apparition
+ SPELL_SPITE_N = 68895,
+ SPELL_SPITE_H = 70212,
+
+ //Spectral Warden
+ SPELL_VEIL_OF_SHADOWS = 69633,
+ SPELL_WAIL_OF_SOULS_N = 69148,
+ SPELL_WAIL_OF_SOULS_H = 70210,
+
+ //Soulguard Watchman
+ SPELL_SHROUD_OF_RUNES = 69056,
+ SPELL_UNHOLY_RAGE = 69053,
+
+ //Soulguard Reaper
+ SPELL_FROST_NOVA_N = 69060,
+ SPELL_FROST_NOVA_H = 70209,
+ SPELL_SHADOW_LANCE = 69058,
+
+ //Soulguard Bonecaster
+ SPELL_BONE_VOLLEY_N = 69080,
+ SPELL_BONE_VOLLEY_H = 70206,
+ SPELL_RAISE_DEAD = 69562,
+ SPELL_SHIELD_OF_BONES_N = 69069,
+ SPELL_SHIELD_OF_BONES_H = 70207,
+
+ //Soulguard Animator
+ // Raise dead 69562
+ SPELL_SHADOW_BOLT_N = 69068,
+ SPELL_SHADOW_BOLT_H = 70208,
+ SPELL_SOUL_SICKNESS = 69131,
+ SPELL_SOUL_SIPHON = 69128,
+
+ //Soulguard Adept
+ //Raise dead 69562
+ //Shadow Bolt 69068/70208
+ SPELL_DRAIN_LIFE_N = 69066,
+ SPELL_DRAIN_LIFE_H = 70213,
+ SPELL_SHADOW_MEND_N = 69564,
+ SPELL_SHADOW_MEND_H = 70205,
+
+ //Soul Horror
+ SPELL_SOUL_STRIKE_N = 69088,
+ SPELL_SOUL_STRIKE_H = 70211,
+
+ NPC_SOULGUARD_ADEPT = 36620
+};
+
+struct MANGOS_DLL_DECL npc_soulguard_watchmanAI : public ScriptedAI
+{
+ npc_soulguard_watchmanAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+bool m_bIsRegularMode;
+
+uint32 ShieldTimer;
+
+ void Reset()
+ {
+ ShieldTimer = (urand(2000, 15000));
+ }
+
+ void Aggro(Unit *who)
+ {
+ DoCast(m_creature, SPELL_UNHOLY_RAGE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (ShieldTimer < diff)
+ {
+ DoCast(m_creature, SPELL_SHROUD_OF_RUNES);
+ ShieldTimer = (urand(15000, 25000));
+ }
+ else
+ ShieldTimer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_soulguard_reaperAI : public ScriptedAI
+{
+ npc_soulguard_reaperAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+bool m_bIsRegularMode;
+
+uint32 ShadowBoltTimer;
+uint32 IceNovaTimer;
+uint32 AdeptHealTimer;
+
+ void Reset()
+ {
+ AdeptHealTimer = (urand(2000, 4000));
+ ShadowBoltTimer = (urand(2000, 20000));
+ IceNovaTimer = (urand(15000, 20000));
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (ShadowBoltTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_SHADOW_LANCE);
+ ShadowBoltTimer = (urand(2000, 15000));
+ }
+ else
+ ShadowBoltTimer -= diff;
+
+ if (IceNovaTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_FROST_NOVA_N : SPELL_FROST_NOVA_H);
+ IceNovaTimer = (urand(15000, 20000));
+ }
+ else
+ IceNovaTimer -= diff;
+
+ if(m_creature->GetHealth()*100 < m_creature->GetMaxHealth()*45)
+ {
+ if (AdeptHealTimer < diff)
+ {
+ if (Creature* pAdept = GetClosestCreatureWithEntry(m_creature, NPC_SOULGUARD_ADEPT, 25.0f))
+ {
+ if(pAdept->GetHealth()*100 > pAdept->GetMaxHealth()*45)
+ {
+ pAdept->InterruptNonMeleeSpells(false);
+ pAdept->CastSpell(m_creature, m_bIsRegularMode ? SPELL_SHADOW_MEND_N : SPELL_SHADOW_MEND_H, false);
+ }
+ }
+
+ AdeptHealTimer = (urand(9000, 20000));
+ }
+ else
+ AdeptHealTimer -= diff;
+ }
+
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_soulguard_adeptAI : public ScriptedAI
+{
+ npc_soulguard_adeptAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+bool m_bIsRegularMode;
+
+bool Summon;
+uint32 ShadowBoltTimer;
+uint32 ShadowMendTimer;
+uint32 DrainLifeTimer;
+uint32 SummonTimer;
+uint32 Say;
+
+ void Reset()
+ {
+ Summon = false;
+ ShadowBoltTimer = (urand(2000, 20000));
+ ShadowMendTimer = (urand(1000, 5000));
+ DrainLifeTimer = (urand(1000, 2000));
+ SummonTimer = (urand(1000, 10000));
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (ShadowBoltTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_SHADOW_BOLT_N : SPELL_SHADOW_BOLT_H);
+ ShadowBoltTimer = (urand(2000, 15000));
+ }
+ else
+ ShadowBoltTimer -= diff;
+
+ if(m_creature->GetHealth()*100 < m_creature->GetMaxHealth()*45)
+ {
+ if (ShadowMendTimer < diff)
+ {
+ m_creature->InterruptNonMeleeSpells(false);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SHADOW_MEND_N : SPELL_SHADOW_MEND_H);
+ ShadowMendTimer = (urand(6000, 10000));
+ }
+ else
+ ShadowMendTimer -= diff;
+ }
+
+ if(m_creature->GetHealth()*100 < m_creature->GetMaxHealth()*75)
+ {
+ if (DrainLifeTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_DRAIN_LIFE_N : SPELL_DRAIN_LIFE_H);
+ DrainLifeTimer = (urand(5000, 15000));
+ }
+ else
+ DrainLifeTimer -= diff;
+ }
+
+ if(Summon != true)
+ {
+ if (SummonTimer < diff)
+ {
+ Summon = true;
+ Say = (urand(0, 3));
+ switch(Say)
+ {
+ case 0:
+ m_creature->MonsterSay("Wake up deads!",LANG_UNIVERSAL);
+ break;
+ case 1:
+ m_creature->MonsterSay("Dead hear my call!",LANG_UNIVERSAL);
+ break;
+ case 2:
+ m_creature->MonsterSay("I command power of Dead!",LANG_UNIVERSAL);
+ break;
+ case 3:
+ m_creature->MonsterSay("A raise my servant!",LANG_UNIVERSAL);
+ break;
+ }
+ DoCast(m_creature, SPELL_RAISE_DEAD);
+ }
+ else
+ SummonTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_soulguard_bonecasterAI : public ScriptedAI
+{
+ npc_soulguard_bonecasterAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+bool m_bIsRegularMode;
+
+uint32 BoneTimer;
+uint32 ShieldTimer;
+
+ void Reset()
+ {
+ BoneTimer = (urand(2000, 20000));
+ ShieldTimer = (urand(15000, 20000));
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (BoneTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_BONE_VOLLEY_N : SPELL_BONE_VOLLEY_H);
+ BoneTimer = (urand(2000, 15000));
+ }
+ else
+ BoneTimer -= diff;
+
+ if (ShieldTimer < diff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SHIELD_OF_BONES_N : SPELL_SHIELD_OF_BONES_H);
+ ShieldTimer = (urand(15000, 20000));
+ }
+ else
+ ShieldTimer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_soulguard_animatorAI : public ScriptedAI
+{
+ npc_soulguard_animatorAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+bool m_bIsRegularMode;
+
+uint32 ShadowBoltTimer;
+uint32 SoulSickTimer;
+uint32 SoulSiphTimer;
+uint32 AdeptHealTimer;
+
+ void Reset()
+ {
+ AdeptHealTimer = (urand(1000, 6000));
+ ShadowBoltTimer = (urand(2000, 20000));
+ SoulSickTimer = (urand(15000, 20000));
+ SoulSiphTimer = (urand(7500, 30000));
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (ShadowBoltTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_SHADOW_BOLT_N : SPELL_SHADOW_BOLT_H);
+ ShadowBoltTimer = (urand(2000, 15000));
+ }
+ else
+ ShadowBoltTimer -= diff;
+
+ if (SoulSickTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_SOUL_SICKNESS);
+ SoulSickTimer = (urand(15000, 20000));
+ }
+ else
+ SoulSickTimer -= diff;
+
+ if (SoulSiphTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_SOUL_SIPHON);
+ SoulSiphTimer = (urand(7500, 30000));
+ }
+ else
+ SoulSiphTimer -= diff;
+
+ if(m_creature->GetHealth()*100 < m_creature->GetMaxHealth()*45)
+ {
+ if (AdeptHealTimer < diff)
+ {
+ if (Creature* pAdept = GetClosestCreatureWithEntry(m_creature, NPC_SOULGUARD_ADEPT, 25.0f))
+ {
+ if(pAdept->GetHealth()*100 > pAdept->GetMaxHealth()*45)
+ {
+ pAdept->InterruptNonMeleeSpells(false);
+ pAdept->CastSpell(m_creature, m_bIsRegularMode ? SPELL_SHADOW_MEND_N : SPELL_SHADOW_MEND_H, false);
+ }
+ }
+
+ AdeptHealTimer = (urand(9000, 20000));
+ }
+ else
+ AdeptHealTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_soul_horrorAI : public ScriptedAI
+{
+ npc_soul_horrorAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+bool m_bIsRegularMode;
+
+uint32 SoulStrikeTimer;
+
+ void Reset()
+ {
+ SoulStrikeTimer = (urand(2000, 5000));
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (SoulStrikeTimer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_SOUL_STRIKE_N : SPELL_SOUL_STRIKE_H);
+ SoulStrikeTimer = (urand(2000, 10000));
+ }
+ else
+ SoulStrikeTimer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_spectral_wardenAI : public ScriptedAI
+{
+ npc_spectral_wardenAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ScriptedInstance* m_pInstance;
+bool m_bIsRegularMode;
+
+uint32 ShadowsTimer;
+uint32 SoulsTimer;
+
+ void Reset()
+ {
+ ShadowsTimer = (urand(2000, 5000));
+ SoulsTimer = (urand(10000, 15000));
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_pInstance) return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (ShadowsTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_VEIL_OF_SHADOWS);
+ ShadowsTimer = (urand(10000, 15000));
+ }
+ else
+ ShadowsTimer -= diff;
+
+ if (SoulsTimer < diff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_WAIL_OF_SOULS_N : SPELL_WAIL_OF_SOULS_H);
+ SoulsTimer = (urand(7000, 20000));
+ }
+ else
+ SoulsTimer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_soulguard_watchman(Creature* pCreature)
+{
+ return new npc_soulguard_watchmanAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_soulguard_reaper(Creature* pCreature)
+{
+ return new npc_soulguard_reaperAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_soulguard_adept(Creature* pCreature)
+{
+ return new npc_soulguard_adeptAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_soulguard_bonecaster(Creature* pCreature)
+{
+ return new npc_soulguard_bonecasterAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_soulguard_animator(Creature* pCreature)
+{
+ return new npc_soulguard_animatorAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_soul_horror(Creature* pCreature)
+{
+ return new npc_soul_horrorAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_spectral_warden(Creature* pCreature)
+{
+ return new npc_spectral_wardenAI(pCreature);
+}
+
+void AddSC_trash_forge_of_souls()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_soulguard_watchman";
+ newscript->GetAI = &GetAI_npc_soulguard_watchman;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_soulguard_reaper";
+ newscript->GetAI = &GetAI_npc_soulguard_reaper;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_soulguard_adept";
+ newscript->GetAI = &GetAI_npc_soulguard_adept;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_soulguard_bonecaster";
+ newscript->GetAI = &GetAI_npc_soulguard_bonecaster;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_soulguard_animator";
+ newscript->GetAI = &GetAI_npc_soulguard_animator;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_soul_horror";
+ newscript->GetAI = &GetAI_npc_soul_horror;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_spectral_warden";
+ newscript->GetAI = &GetAI_npc_spectral_warden;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falric.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falric.cpp
new file mode 100644
index 0000000..a5577f7
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_falric.cpp
@@ -0,0 +1,230 @@
+/* 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_falric
+SD%Complete: 70%
+SDComment:
+SDAuthor: /dev/rsa, changed by MaxXx2021 aka Mioka
+SDCategory: Halls of Reflection
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_halls.h"
+
+enum
+{
+ SAY_FALRIC_AGGRO = -1594507,
+ SAY_FALRIC_DEATH = -1594508,
+ SAY_FALRIC_SLAY01 = -1594509,
+ SAY_FALRIC_SLAY02 = -1594510,
+ SAY_FALRIC_SP01 = -1594511,
+ SAY_FALRIC_SP02 = -1594512,
+
+ SPELL_HOPELESSNESS = 72395,
+ SPELL_IMPENDING_DESPAIR = 72426,
+ SPELL_DEFILING_HORROR = 72435,
+ SPELL_QUIVERING_STRIKE = 72422,
+
+ SPELL_BERSERK = 47008
+};
+
+struct MANGOS_DLL_DECL boss_falricAI : public BSWScriptedAI
+{
+ boss_falricAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsCall;
+
+ uint32 m_uiSummonTimer;
+ uint32 m_uiLocNo;
+ uint64 m_uiSummonGUID[16];
+ uint32 m_uiCheckSummon;
+
+ uint8 SummonCount;
+
+ uint64 pSummon;
+
+ void Reset()
+ {
+ SummonCount = 0;
+ m_bIsCall = false;
+ m_uiSummonTimer = 11000;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+
+ void Aggro(Unit* pVictim)
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ DoScriptText(SAY_FALRIC_AGGRO, m_creature);
+ DoCast(m_creature, SPELL_HOPELESSNESS);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch(urand(0,1))
+ {
+ case 0: DoScriptText(SAY_FALRIC_SLAY01, m_creature); break;
+ case 1: DoScriptText(SAY_FALRIC_SLAY02, m_creature); break;
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if(!m_pInstance) return;
+ m_pInstance->SetData(TYPE_MARWYN, SPECIAL);
+ DoScriptText(SAY_FALRIC_DEATH, m_creature);
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if(!m_pInstance) return;
+
+ if(m_pInstance->GetData(TYPE_FALRIC) != IN_PROGRESS)
+ return;
+
+ ScriptedAI::AttackStart(who);
+ }
+
+ void Summon()
+ {
+ m_uiLocNo = 0;
+
+ for(uint8 i = 0; i < 14; i++)
+ {
+ switch(urand(0,3))
+ {
+ case 0:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_1; break;
+ case 2: pSummon = NPC_DARK_3; break;
+ case 3: pSummon = NPC_DARK_6; break;
+ }
+ break;
+ case 1:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_2; break;
+ case 2: pSummon = NPC_DARK_3; break;
+ case 3: pSummon = NPC_DARK_4; break;
+ }
+ break;
+ case 2:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_2; break;
+ case 2: pSummon = NPC_DARK_5; break;
+ case 3: pSummon = NPC_DARK_6; break;
+ }
+ break;
+ case 3:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_1; break;
+ case 2: pSummon = NPC_DARK_5; break;
+ case 3: pSummon = NPC_DARK_4; break;
+ }
+ break;
+ }
+
+ m_uiCheckSummon = 0;
+
+ if(Creature* Summon = m_creature->SummonCreature(pSummon, SpawnLoc[m_uiLocNo].x, SpawnLoc[m_uiLocNo].y, SpawnLoc[m_uiLocNo].z, SpawnLoc[m_uiLocNo].o, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000))
+ {
+ m_uiSummonGUID[i] = Summon->GetGUID();
+ Summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Summon->setFaction(974);
+ }
+ m_uiLocNo++;
+ }
+ }
+
+ void CallFallSoldier()
+ {
+ for(uint8 i = 0; i < 4; i++)
+ {
+ if(Creature* Summon = m_pInstance->instance->GetCreature(m_uiSummonGUID[m_uiCheckSummon]))
+ {
+ Summon->setFaction(14);
+ Summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Summon->SetInCombatWithZone();
+ }
+ m_uiCheckSummon++;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance)
+ return;
+
+ if (m_pInstance->GetData(TYPE_EVENT) == 5)
+ {
+ m_pInstance->SetData(TYPE_EVENT, 6);
+ Summon();
+ }
+
+ if (m_pInstance->GetData(TYPE_FALRIC) == SPECIAL)
+ {
+
+ if (m_uiSummonTimer < uiDiff)
+ {
+ ++SummonCount;
+ if(SummonCount > 4)
+ {
+ m_pInstance->SetData(TYPE_FALRIC, IN_PROGRESS);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWithZone();
+ }
+ else CallFallSoldier();
+ m_uiSummonTimer = 60000;
+ } else m_uiSummonTimer -= uiDiff;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_QUIVERING_STRIKE, uiDiff);
+ timedCast(SPELL_IMPENDING_DESPAIR, uiDiff);
+ timedCast(SPELL_DEFILING_HORROR, uiDiff);
+
+ timedCast(SPELL_BERSERK, uiDiff);
+
+ DoMeleeAttackIfReady();
+
+ }
+};
+
+CreatureAI* GetAI_boss_falric(Creature* pCreature)
+{
+ return new boss_falricAI(pCreature);
+}
+
+void AddSC_boss_falric()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_falric";
+ newscript->GetAI = &GetAI_boss_falric;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_lich_king.cpp
index 0ed1ec9..7ae0902 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
@@ -16,9 +16,663 @@
/* ScriptData
SDName: boss_lich_king
-SD%Complete: 0%
+SD%Complete: 100%
SDComment:
+SDAuthor: MaxXx2021 aka Mioka
SDCategory: Halls of Reflection
EndScriptData */
#include "precompiled.h"
+#include "def_halls.h"
+#include "escort_ai.h"
+
+enum
+{
+ SPELL_WINTER = 69780,
+ SPELL_FURY_OF_FROSTMOURNE = 70063,
+ SPELL_SOUL_REAPER = 73797,
+ SPELL_ICE_PRISON = 69708,
+ SPELL_DARK_ARROW = 70194,
+ SPELL_EMERGE_VISUAL = 50142,
+ SPELL_DESTROY_ICE_WALL_02 = 70224,
+ SPELL_SILENCE = 69413,
+ SPELL_LICH_KING_CAST = 57561,
+ SPELL_GNOUL_JUMP = 70150,
+ SPELL_ABON_STRIKE = 40505,
+
+ // summon spells
+ SPELL_WITCH_DOCTOR = 69836,
+ SPELL_SUMMON_ABOM = 69835,
+ SPELL_RAISE_DEAD = 69818,
+
+ /*SPELLS - Witch Doctor, 36941 */
+ SPELL_COURSE_OF_DOOM = 70144,
+ SPELL_SHADOW_BOLT_VALLEY = 70145,
+ SPELL_SHADOW_BOLT = 70080,
+
+ /*SPELLS - abomination, 37069 */
+ SPELL_CLEAVE = 40505,
+
+ /*SPELLS - raging ghoul, 36940 */
+ SPELL_LEAP = 70150,
+
+ SAY_LICH_KING_WALL_01 = -1594486,
+ SAY_LICH_KING_WALL_02 = -1594491,
+ SAY_LICH_KING_GNOUL = -1594482,
+ SAY_LICH_KING_ABON = -1594483,
+ SAY_LICH_KING_WINTER = -1594481,
+ SAY_LICH_KING_END_DUN = -1594504,
+ SAY_LICH_KING_WIN = -1594485,
+
+ /*INTRO - Lich King Arrive*/
+ SAY_LICH_KING_17 = -1594468,
+ SAY_LICH_KING_18 = -1594469,
+ SAY_LICH_KING_19 = -1594470,
+ SAY_JAINA_20 = -1594471,
+ SAY_SYLVANA_20 = -1594472,
+ SAY_LICH_KING_A_21 = -1594473,
+ SAY_LICH_KING_H_21 = -1594474,
+ SAY_FALRIC_INTRO = -1594475,
+ SAY_MARWYN_INTRO = -1594476,
+ SAY_FALRIC_INTRO2 = -1594505,
+
+ SPELL_TAKE_FROSTMOURNE = 72729,
+ SPELL_FROSTMOURNE_DESPAWN = 72726,
+ SPELL_FROSTMOURNE_SOUNDS = 70667,
+ SPELL_CAST_VISUAL = 65633, //Jaina And Sylavana cast this when summon uther.
+ SPELL_BOSS_SPAWN_AURA = 72712, //Falric and Marwyn
+ SPELL_UTHER_DESPAWN = 70693,
+ SPELL_FROSTMOURNE_VISUAL = 73220,
+
+ /*INTRO - Pre Escape*/
+ SAY_LICH_KING_AGGRO_A = -1594477,
+ SAY_LICH_KING_AGGRO_H = -1594478,
+ SAY_JAINA_AGGRO = -1594479,
+ SAY_SYLVANA_AGGRO = -1594480,
+
+};
+
+struct MANGOS_DLL_DECL boss_lich_king_hrAI : public npc_escortAI
+{
+ boss_lich_king_hrAI(Creature *pCreature) : npc_escortAI(pCreature)
+ {
+ m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ BSWScriptedInstance* m_pInstance;
+ bool StartEscort;
+ bool NonFight;
+ bool Finish;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+ NonFight = false;
+ StartEscort = false;
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, 36942);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (m_pInstance->GetData(TYPE_LICH_KING) == DONE)
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ if (!who || !m_pInstance)
+ return;
+
+ if (who->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player* pPlayer = (Player *)who;
+
+ if (pPlayer->isGameMaster())
+ return;
+
+ if (m_pInstance->GetData(TYPE_PHASE) != 3
+ || m_pInstance->GetData(TYPE_LICH_KING) == DONE
+ || !m_creature->IsWithinDistInMap(who, 50.0f)
+ || m_pInstance->GetData(TYPE_FROST_GENERAL) != DONE)
+ return;
+
+ m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICECROWN_DOOR_2));
+
+ Team team;
+ if (Group* pGroup = pPlayer->GetGroup())
+ {
+ ObjectGuid LeaderGuid = pGroup->GetLeaderGuid();
+ if (!LeaderGuid.IsEmpty())
+ if (Player* pLeader =m_creature->GetMap()->GetPlayer(LeaderGuid))
+ team = pLeader->GetTeam();
+ }
+ else
+ team = ((Player*)who)->GetTeam();
+
+ uint32 newLeader;
+
+ if (team == ALLIANCE)
+ newLeader = NPC_JAINA_OUTRO;
+ else
+ newLeader = NPC_SYLVANA_OUTRO;
+
+ if (Creature* pNewLeader = m_creature->SummonCreature(newLeader,WallLoc[6].x,WallLoc[6].y,WallLoc[6].z,WallLoc[6].o,TEMPSUMMON_MANUAL_DESPAWN,0,true))
+ {
+ pNewLeader->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pNewLeader->SetSpeedRate(MOVE_RUN, 1.0f, true);
+ pNewLeader->SetRespawnDelay(DAY);
+ pNewLeader->SetHealth(pNewLeader->GetMaxHealth()/10);
+ m_pInstance->SetData64(DATA_ESCAPE_LIDER, pNewLeader->GetGUID());
+ }
+ m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICECROWN_DOOR_2));
+ m_pInstance->SetData(TYPE_PHASE, 4);
+ m_pInstance->SetNextEvent(100,GetLeader(),500);
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ switch(i)
+ {
+ case 20:
+ SetEscortPaused(true);
+ Finish = true;
+ DoCast(m_creature, SPELL_LICH_KING_CAST);
+ m_pInstance->SetData(TYPE_LICH_KING, SPECIAL);
+ DoScriptText(SAY_LICH_KING_END_DUN, m_creature);
+ if(Creature* pLider = (m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ESCAPE_LIDER))))
+ {
+ pLider->CastSpell(pLider, SPELL_SILENCE, false);
+ pLider->AddSplineFlag(SPLINEFLAG_FLYING);
+ pLider->SendMonsterMove(pLider->GetPositionX(), pLider->GetPositionY(), pLider->GetPositionZ() + 4, SPLINETYPE_NORMAL , pLider->GetSplineFlags(), 3000);
+ }
+ m_pInstance->SetData(TYPE_PHASE, 6);
+ m_pInstance->SetNextEvent(610,GetLeader(),5000);
+ m_creature->SetActiveObjectState(false);
+ break;
+ }
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!m_pInstance || !who || NonFight)
+ return;
+
+ if (m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS || who->GetTypeId() == TYPEID_PLAYER) return;
+
+ npc_escortAI::AttackStart(who);
+ }
+
+ void SummonedCreatureJustDied(Creature* summoned)
+ {
+ if(!m_pInstance || !summoned)
+ return;
+
+ if (summoned->GetEntry() == NPC_JAINA_OUTRO
+ || summoned->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ m_creature->NearTeleportTo(5572.077f, 2283.1f, 734.976f, 3.89f);
+ if (boss_lich_king_hrAI* pEscortAI = dynamic_cast(m_creature->AI()))
+ pEscortAI->EnterEvadeMode();
+ StartEscort = false;
+ }
+ else
+ m_pInstance->SetData(DATA_SUMMONS, 0);
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if (!m_pInstance || !summoned)
+ return;
+
+ if (summoned->GetEntry() == NPC_JAINA_OUTRO
+ || summoned->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ summoned->SetCreatorGuid(ObjectGuid());
+ summoned->setFaction(2076);
+ summoned->SetPhaseMask(65535, true);
+ m_creature->SetInCombatWith(summoned);
+ summoned->SetInCombatWith(m_creature);
+ }
+ else
+ {
+ summoned->SetPhaseMask(65535, true);
+ summoned->SetInCombatWithZone();
+ summoned->SetActiveObjectState(true);
+
+ m_pInstance->SetData(DATA_SUMMONS, 1);
+
+ if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER)))
+ {
+ summoned->GetMotionMaster()->MoveChase(pLider);
+ summoned->AddThreat(pLider, 100.0f);
+ }
+ }
+ }
+
+ uint32 GetLeader()
+ {
+ if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER)))
+ return pLider->GetEntry();
+ else
+ return 0;
+ }
+
+ void Event()
+ {
+ switch (m_pInstance->GetEvent(m_creature->GetEntry()))
+ {
+// Intro phase
+ case 101:
+ if(GetLeader() == NPC_JAINA_OUTRO)
+ DoScriptText((GetLeader() == NPC_JAINA_OUTRO ? SAY_LICH_KING_AGGRO_A : SAY_LICH_KING_AGGRO_H), m_creature);
+ if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER)))
+ AttackStart(pLider);
+ m_pInstance->SetNextEvent(102,GetLeader(),3000);
+ break;
+
+// Active phase
+ case 200:
+ SetEscortPaused(true);
+ m_pInstance->SetData(DATA_SUMMONS, 3);
+ DoScriptText(SAY_LICH_KING_WALL_01, m_creature);
+ m_pInstance->SetNextEvent(210,m_creature->GetEntry(),2000);
+ break;
+ case 210:
+ m_pInstance->SetNextEvent(220,m_creature->GetEntry(),2000);
+ break;
+ case 220:
+ DoCast(m_creature, SPELL_RAISE_DEAD);
+ DoScriptText(SAY_LICH_KING_GNOUL, m_creature);
+ m_pInstance->SetNextEvent(230,m_creature->GetEntry(),7000);
+ break;
+ case 230:
+ DoScriptText(SAY_LICH_KING_WINTER, m_creature);
+ DoCast(m_creature, SPELL_WINTER);
+ m_creature->SetSpeedRate(MOVE_WALK, 1.3f, true);
+ m_pInstance->SetNextEvent(240,m_creature->GetEntry(),1000);
+ break;
+ case 240:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ SetEscortPaused(false);
+ m_pInstance->SetNextEvent(250,m_creature->GetEntry(),2000);
+ break;
+ case 250:
+ m_pInstance->SetNextEvent(290,GetLeader(),1000);
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ break;
+
+ case 300:
+ SetEscortPaused(true);
+ DoCast(m_creature, SPELL_SUMMON_ABOM);
+ m_pInstance->SetData(DATA_SUMMONS, 3);
+ DoScriptText(SAY_LICH_KING_GNOUL, m_creature);
+ m_pInstance->SetNextEvent(310,m_creature->GetEntry(),500);
+ break;
+ case 310:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(320,m_creature->GetEntry(),500);
+ break;
+ case 320:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(330,m_creature->GetEntry(),5000);
+ break;
+ case 330:
+ DoCast(m_creature, SPELL_RAISE_DEAD);
+ SetEscortPaused(false);
+ m_pInstance->SetNextEvent(390,GetLeader(),1000);
+ break;
+
+ case 400:
+ SetEscortPaused(true);
+ DoCast(m_creature, SPELL_SUMMON_ABOM);
+ m_pInstance->SetData(DATA_SUMMONS, 3);
+ DoScriptText(SAY_LICH_KING_GNOUL, m_creature);
+ m_pInstance->SetNextEvent(410,m_creature->GetEntry(),500);
+ break;
+ case 410:
+ DoScriptText(SAY_LICH_KING_ABON, m_creature);
+ DoCast(m_creature, SPELL_SUMMON_ABOM);
+ m_pInstance->SetNextEvent(420,m_creature->GetEntry(),500);
+ break;
+ case 420:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(430,m_creature->GetEntry(),500);
+ break;
+ case 430:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(440,m_creature->GetEntry(),500);
+ break;
+ case 440:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(450,m_creature->GetEntry(),500);
+ break;
+ case 450:
+ DoCast(m_creature, SPELL_RAISE_DEAD);
+ m_pInstance->SetNextEvent(490,GetLeader(),5000);
+ SetEscortPaused(false);
+ break;
+
+ case 500:
+ m_pInstance->SetData(DATA_SUMMONS, 3);
+ DoScriptText(SAY_LICH_KING_GNOUL, m_creature);
+ DoCast(m_creature, SPELL_SUMMON_ABOM);
+ m_pInstance->SetNextEvent(510,m_creature->GetEntry(),10000);
+ break;
+ case 510:
+ m_creature->SetSpeedRate(MOVE_WALK, 1.3f, true);
+ DoCast(m_creature, SPELL_SUMMON_ABOM);
+ m_pInstance->SetNextEvent(520,m_creature->GetEntry(),500);
+ break;
+ case 520:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(530,m_creature->GetEntry(),500);
+ break;
+ case 530:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(540,m_creature->GetEntry(),500);
+ break;
+ case 540:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(550,m_creature->GetEntry(),500);
+ break;
+ case 550:
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(570,m_creature->GetEntry(),2000);
+ break;
+ case 570:
+ DoScriptText(SAY_LICH_KING_ABON, m_creature);
+ DoCast(m_creature, SPELL_WITCH_DOCTOR);
+ m_pInstance->SetNextEvent(580,m_creature->GetEntry(),5000);
+ break;
+ case 580:
+ DoScriptText(SAY_LICH_KING_ABON, m_creature);
+ DoCast(m_creature, SPELL_RAISE_DEAD);
+ m_pInstance->SetNextEvent(590,GetLeader(),1000);
+ break;
+
+ case 900:
+ if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER)))
+ m_creature->DealDamage(pLider, pLider->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_pInstance->SetData(TYPE_LICH_KING, FAIL);
+ m_creature->SetActiveObjectState(false);
+ m_pInstance->SetData(TYPE_PHASE, 3);
+ m_pInstance->SetNextEvent(0,0);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ void UpdateEscortAI(const uint32 diff)
+ {
+ if(!m_pInstance)
+ return;
+
+ if ( (m_pInstance->GetData(TYPE_PHASE) == 4 || m_pInstance->GetData(TYPE_PHASE) == 5 || m_pInstance->GetData(TYPE_PHASE) == 7)
+ && m_pInstance->GetEventTimer(m_creature->GetEntry(),diff))
+ Event();
+
+ if(m_pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ return;
+ }
+
+ if(m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS && !StartEscort)
+ {
+ StartEscort = true;
+ if(m_creature->HasAura(SPELL_ICE_PRISON))
+ m_creature->RemoveAurasDueToSpell(SPELL_ICE_PRISON);
+ if(m_creature->HasAura(SPELL_DARK_ARROW))
+ m_creature->RemoveAurasDueToSpell(SPELL_DARK_ARROW);
+
+ m_creature->SetActiveObjectState(true);
+
+ NonFight = true;
+ m_creature->AttackStop();
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_WALK, 2.7f, true);
+ if (boss_lich_king_hrAI* pEscortAI = dynamic_cast(m_creature->AI()))
+ pEscortAI->Start();
+ }
+ if (m_pInstance->GetData(TYPE_PHASE) == 5)
+ if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER)))
+ if (pLider->isAlive() && pLider->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ m_pInstance->SetData(TYPE_PHASE,7);
+ SetEscortPaused(true);
+ m_creature->GetMotionMaster()->Clear();
+ DoScriptText(SAY_LICH_KING_WIN, m_creature);
+ m_pInstance->SetNextEvent(900,m_creature->GetEntry(),4000);
+ m_creature->CastSpell(m_creature, SPELL_FURY_OF_FROSTMOURNE, false);
+ };
+
+ return;
+ }
+};
+
+CreatureAI* GetAI_boss_lich_king_hr(Creature* pCreature)
+{
+ return new boss_lich_king_hrAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL boss_lich_king_intro_horAI : public ScriptedAI
+{
+ boss_lich_king_intro_horAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ BSWScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ }
+
+ void AttackStart(Unit* who)
+ {
+ }
+
+ uint32 GetLeader()
+ {
+ if (Creature* pLider = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ESCAPE_LIDER)))
+ return pLider->GetEntry();
+ else
+ return 0;
+ }
+
+ void Event()
+ {
+ switch(m_pInstance->GetEvent(m_creature->GetEntry()))
+ {
+ case 24:
+ m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR));
+ m_pInstance->SetNextEvent(25,GetLeader(),1000);
+ break;
+ case 25:
+ m_creature->GetMotionMaster()->MovePoint(0, 5314.881f, 2012.496f, 709.341f);
+ m_pInstance->SetNextEvent(26,m_creature->GetEntry(),3000);
+ break;
+ case 26:
+ m_pInstance->DoCloseDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR));
+ m_pInstance->SetNextEvent(27,m_creature->GetEntry(),7000);
+ break;
+ case 27:
+ DoScriptText(SAY_LICH_KING_17, m_creature);
+ if (Creature* pUther = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_UTHER))))
+ pUther->CastSpell(pUther, SPELL_UTHER_DESPAWN, false);
+ m_pInstance->SetNextEvent(28,m_creature->GetEntry(),1500);
+ break;
+ case 28:
+ if (Creature* pUther = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_UTHER))))
+ pUther->ForcedDespawn();
+ m_pInstance->SetNextEvent(29,m_creature->GetEntry(),10000);
+ break;
+ case 29:
+ DoScriptText(SAY_LICH_KING_18, m_creature);
+ m_pInstance->SetNextEvent(30,m_creature->GetEntry(),5000);
+ break;
+ case 30:
+ m_creature->CastSpell(m_creature, SPELL_TAKE_FROSTMOURNE, false);
+ m_pInstance->DoCloseDoor(m_pInstance->GetData64(GO_FROSTMOURNE));
+ m_pInstance->SetNextEvent(31,m_creature->GetEntry(),1500);
+ break;
+ case 31:
+ if (GameObject* pFrostmourne = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_FROSTMOURNE)))
+ pFrostmourne->SetPhaseMask(0, true);
+ m_creature->CastSpell(m_creature, SPELL_FROSTMOURNE_VISUAL, false);
+ m_pInstance->SetNextEvent(31,GetLeader(),500);
+ break;
+ case 32:
+ DoScriptText(SAY_LICH_KING_19, m_creature);
+ m_pInstance->SetNextEvent(33,m_creature->GetEntry(),9000);
+ break;
+ case 33:
+ if (Creature* pFalric = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_FALRIC))))
+ {
+ pFalric->SetVisibility(VISIBILITY_ON);
+ pFalric->CastSpell(pFalric, SPELL_BOSS_SPAWN_AURA, false);
+ pFalric->GetMotionMaster()->MovePoint(0, 5283.309f, 2031.173f, 709.319f);
+ }
+ if (Creature* pMarwyn = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MARWYN))))
+ {
+ pMarwyn->SetVisibility(VISIBILITY_ON);
+ pMarwyn->CastSpell(pMarwyn, SPELL_BOSS_SPAWN_AURA, false);
+ pMarwyn->GetMotionMaster()->MovePoint(0, 5335.585f, 1981.439f, 709.319f);
+ }
+ m_creature->GetMotionMaster()->MovePoint(0, 5402.286f, 2104.496f, 707.695f);
+ m_pInstance->SetNextEvent(34,m_creature->GetEntry(),1000);
+ break;
+ case 34:
+ if (Creature* pFalric = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_FALRIC))))
+ DoScriptText(SAY_FALRIC_INTRO, pFalric);
+ if (Creature* pMarwyn = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MARWYN))))
+ DoScriptText(SAY_MARWYN_INTRO, pMarwyn);
+ m_pInstance->SetData(TYPE_EVENT, 5);
+ m_pInstance->SetNextEvent(35,m_creature->GetEntry(),3000);
+ break;
+ case 35:
+ if (GameObject* pGate = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR)))
+ pGate->SetGoState(GO_STATE_ACTIVE);
+ if (Creature* pFalric = (m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_FALRIC))))
+ DoScriptText(SAY_FALRIC_INTRO2, pFalric);
+ m_pInstance->SetData(TYPE_FALRIC, SPECIAL);
+ m_pInstance->SetNextEvent(36,GetLeader(),4000);
+ break;
+ case 37:
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MovePoint(0, 5443.880f, 2147.095f, 707.695f);
+ if (GetLeader() == NPC_JAINA)
+ DoScriptText(SAY_LICH_KING_A_21, m_creature);
+ else if (GetLeader() == NPC_SYLVANA)
+ DoScriptText(SAY_LICH_KING_H_21, m_creature);
+ m_pInstance->SetNextEvent(38,m_creature->GetEntry(),8000);
+ break;
+ case 38:
+ m_pInstance->DoCloseDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR));
+ m_pInstance->SetNextEvent(39,m_creature->GetEntry(),5000);
+ break;
+ case 39:
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ m_pInstance->SetNextEvent(39,GetLeader(),1000);
+ break;
+ case 40:
+ m_pInstance->SetData(TYPE_PHASE, 2);
+ m_pInstance->SetNextEvent(0,0);
+ m_creature->ForcedDespawn();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_pInstance)
+ return;
+
+ if (m_pInstance->GetEventTimer(m_creature->GetEntry(),diff) && m_pInstance->GetData(TYPE_PHASE) == 1)
+ Event();
+
+ }
+};
+
+CreatureAI* GetAI_boss_lich_king_intro_hor(Creature* pCreature)
+{
+ return new boss_lich_king_intro_horAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_undead_horAI : public BSWScriptedAI
+{
+ npc_undead_horAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ }
+
+ void EnterEvadeMode()
+ {
+ if (!m_pInstance)
+ return;
+
+ m_creature->ForcedDespawn();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ doCastAll(uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_undead_hor(Creature* pCreature)
+{
+ return new npc_undead_horAI(pCreature);
+}
+
+void AddSC_boss_lich_king_hr()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_lich_king_hr";
+ newscript->GetAI = &GetAI_boss_lich_king_hr;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_lich_king_intro_hor";
+ newscript->GetAI = &GetAI_boss_lich_king_intro_hor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_undead_hor";
+ newscript->GetAI = &GetAI_npc_undead_hor;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/boss_marwyn.cpp
index b8b5e84..e55de0a 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
@@ -16,9 +16,222 @@
/* ScriptData
SDName: boss_marwyn
-SD%Complete: 0%
+SD%Complete: 60%
SDComment:
+SDAuthor: /dev/rsa, changed by MaxXx2021 aka Mioka
SDCategory: Halls of Reflection
EndScriptData */
#include "precompiled.h"
+#include "def_halls.h"
+
+enum
+{
+ SAY_MARWYN_INTRO = -1594506,
+ SAY_MARWYN_AGGRO = -1594513,
+ SAY_MARWYN_DEATH = -1594514,
+ SAY_MARWYN_SLAY01 = -1594515,
+ SAY_MARWYN_SLAY02 = -1594516,
+ SAY_MARWYN_SP01 = -1594517,
+ SAY_MARWYN_SP02 = -1594518,
+
+ SPELL_OBLITERATE = 72360,
+ SPELL_SHARED_SUFFERING = 72368,
+ SPELL_WELL_OF_CORRUPTION = 72362,
+ SPELL_CORRUPTED_FLESH = 72436,
+
+ SPELL_BERSERK = 47008,
+};
+
+struct MANGOS_DLL_DECL boss_marwynAI : public BSWScriptedAI
+{
+ boss_marwynAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsCall;
+ uint32 m_uiSummonTimer;
+
+ uint32 m_uiLocNo;
+ uint64 m_uiSummonGUID[16];
+ uint32 m_uiCheckSummon;
+
+ uint8 SummonCount;
+
+ uint64 pSummon;
+
+ void Reset()
+ {
+ SummonCount = 0;
+ m_bIsCall = false;
+ m_uiSummonTimer = 15000;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+
+ void Summon()
+ {
+ m_uiLocNo = 14;
+
+ for(uint8 i = 0; i < 14; i++)
+ {
+ switch(urand(0,3))
+ {
+ case 0:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_1; break;
+ case 2: pSummon = NPC_DARK_3; break;
+ case 3: pSummon = NPC_DARK_6; break;
+ }
+ break;
+ case 1:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_2; break;
+ case 2: pSummon = NPC_DARK_3; break;
+ case 3: pSummon = NPC_DARK_4; break;
+ }
+ break;
+ case 2:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_2; break;
+ case 2: pSummon = NPC_DARK_5; break;
+ case 3: pSummon = NPC_DARK_6; break;
+ }
+ break;
+ case 3:
+ switch(urand(1, 3))
+ {
+ case 1: pSummon = NPC_DARK_1; break;
+ case 2: pSummon = NPC_DARK_5; break;
+ case 3: pSummon = NPC_DARK_4; break;
+ }
+ break;
+ }
+
+ m_uiCheckSummon = 0;
+
+ if(Creature* Summon = m_creature->SummonCreature(pSummon, SpawnLoc[m_uiLocNo].x, SpawnLoc[m_uiLocNo].y, SpawnLoc[m_uiLocNo].z, SpawnLoc[m_uiLocNo].o, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000))
+ {
+ m_uiSummonGUID[i] = Summon->GetGUID();
+ Summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Summon->setFaction(974);
+ }
+ m_uiLocNo++;
+ }
+ }
+
+ void CallFallSoldier()
+ {
+ for(uint8 i = 0; i < 4; i++)
+ {
+ if(Creature* Summon = m_pInstance->instance->GetCreature(m_uiSummonGUID[m_uiCheckSummon]))
+ {
+ Summon->setFaction(14);
+ Summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Summon->SetInCombatWithZone();
+ }
+ m_uiCheckSummon++;
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_MARWYN, DONE);
+ m_pInstance->SetData(TYPE_PHASE, 3);
+ }
+
+ DoScriptText(SAY_MARWYN_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch(urand(0,1))
+ {
+ case 0: DoScriptText(SAY_MARWYN_SLAY01, m_creature); break;
+ case 1: DoScriptText(SAY_MARWYN_SLAY02, m_creature); break;
+ }
+ }
+
+ void Aggro(Unit* pVictim)
+ {
+ if (!m_pInstance) return;
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ DoScriptText(SAY_MARWYN_AGGRO, m_creature);
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!m_pInstance) return;
+
+ if (m_pInstance->GetData(TYPE_MARWYN) != IN_PROGRESS)
+ return;
+
+ ScriptedAI::AttackStart(who);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(!m_pInstance) return;
+
+ if (m_pInstance->GetData(TYPE_EVENT) == 6)
+ {
+ m_pInstance->SetData(TYPE_EVENT, 7);
+ Summon();
+ }
+
+ if(m_pInstance->GetData(TYPE_MARWYN) == SPECIAL)
+ {
+ if(m_uiSummonTimer < uiDiff)
+ {
+ ++SummonCount;
+ if(SummonCount == 1)
+ DoScriptText(SAY_MARWYN_INTRO, m_creature);
+
+ if(SummonCount > 4)
+ {
+ m_pInstance->SetData(TYPE_MARWYN, IN_PROGRESS);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetInCombatWithZone();
+ }
+ else CallFallSoldier();
+ m_uiSummonTimer = 60000;
+ } else m_uiSummonTimer -= uiDiff;
+ }
+
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_OBLITERATE, uiDiff);
+ timedCast(SPELL_WELL_OF_CORRUPTION, uiDiff);
+ timedCast(SPELL_SHARED_SUFFERING, uiDiff);
+ timedCast(SPELL_CORRUPTED_FLESH, uiDiff);
+
+ timedCast(SPELL_BERSERK, uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_marwyn(Creature* pCreature)
+{
+ return new boss_marwynAI(pCreature);
+}
+
+void AddSC_boss_marwyn()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_marwyn";
+ newscript->GetAI = &GetAI_boss_marwyn;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/def_halls.h b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/def_halls.h
new file mode 100644
index 0000000..fc93923
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/def_halls.h
@@ -0,0 +1,128 @@
+#ifndef DEF_HALL_OF_REFLECTION_H
+#define DEF_HALL_OF_REFLECTION_H
+#include "BSW_ai.h"
+#include "BSW_instance.h"
+
+enum Data
+{
+ TYPE_PHASE = 0,
+ TYPE_EVENT = 1,
+ TYPE_FALRIC = 2,
+ TYPE_MARWYN = 3,
+ TYPE_FROST_GENERAL = 4,
+ TYPE_LICH_KING = 5,
+ TYPE_HALLS = 6,
+ MAX_ENCOUNTERS,
+
+ DATA_ESCAPE_LIDER = 101,
+ DATA_SUMMONS = 102,
+
+ /*UNITS*/
+ NPC_DARK_1 = 38177, //Shadowy Mercenary
+ NPC_DARK_2 = 38176, //Tortured Rifleman
+ NPC_DARK_3 = 38173, //Spectral Footman
+ NPC_DARK_4 = 38172, //Phantom Mage
+ NPC_DARK_5 = 38567, //Phantom Hallucination
+ NPC_DARK_6 = 38175, //Ghostly Priest
+ NPC_JAINA = 37221,
+ NPC_SYLVANA = 37223,
+ NPC_JAINA_OUTRO = 36955,
+ NPC_SYLVANA_OUTRO = 37554,
+ NPC_ALTAR_TARGET = 37704,
+ NPC_UTHER = 37225,
+ NPC_LICH_KING = 36954,
+ BOSS_LICH_KING = 37226,
+ NPC_ICE_WALL = 37014,
+ NPC_FALRIC = 38112,
+ NPC_MARWYN = 38113,
+ NPC_GHOSTLY_ROGUE = 38177,
+ NPC_GHOSTLY_PRIEST = 38175,
+ NPC_GHOSTLY_MAGE = 38172,
+ NPC_GHOSTLY_FOOTMAN = 38173,
+ NPC_GHOSTLY_RIFLEMAN = 38176,
+ NPC_GLUK = 38567,
+
+ NPC_RAGING_GNOUL = 36940,
+ NPC_RISEN_WITCH_DOCTOR = 36941,
+ NPC_ABON = 37069,
+
+ NPC_FROST_GENERAL = 36723,
+ NPC_SPIRITUAL_REFLECTION = 37068,
+
+// NPC_QUEL_DELAR = 37704,
+ NPC_QUEL_DELAR = 37158,
+
+ GO_ICECROWN_DOOR = 201976, //72802
+ GO_ICECROWN_DOOR_2 = 197342,
+ GO_ICECROWN_DOOR_3 = 197343,
+ GO_IMPENETRABLE_DOOR = 197341, //72801
+ GO_FROSTMOURNE_ALTAR = 202236, //3551
+ GO_FROSTMOURNE = 202302, //364
+
+ GO_ICE_WALL = 201385,
+ GO_CAVE = 201596,
+ GO_PORTAL = 202079,
+
+ GO_CAPTAIN_CHEST_1 = 202212, //3145
+ GO_CAPTAIN_CHEST_2 = 201710, //30357
+ GO_CAPTAIN_CHEST_3 = 202337, //3246
+ GO_CAPTAIN_CHEST_4 = 202336, //3333
+};
+
+struct _Locations
+{
+ float x, y, z, o;
+ uint32 id;
+};
+
+static _Locations SpawnLoc[]=
+{
+ //Wing 01
+ {5277.409f, 1993.161f, 707.694f, 0.05f}, //27
+ {5301.876f, 2041.699f, 707.694f, 4.71f}, //1
+ {5339.830f, 2020.887f, 707.694f, 3.14f}, //13
+ {5311.041f, 2042.935f, 707.694f, 4.71f}, //3
+ {5314.750f, 2039.969f, 707.694f, 4.71f}, //4
+ {5342.823f, 2003.801f, 707.694f, 3.14f}, //10
+ {5311.579f, 1972.823f, 707.694f, 1.62f}, //16
+
+ //Wing 02
+ {5272.491f, 2005.673f, 707.694f, 0.05f}, //23
+ {5302.669f, 1973.050f, 707.694f, 1.62f}, //18
+ {5346.187f, 2008.058f, 707.694f, 3.14f}, //9
+ {5319.752f, 2041.321f, 707.694f, 4.71f}, //5
+ {5344.882f, 1998.714f, 707.694f, 3.14f}, //11
+ {5340.552f, 1994.735f, 707.694f, 3.14f}, //12
+ {5306.441f, 2040.358f, 707.694f, 4.71f}, //2
+
+ //Wing 03
+ {5273.297f, 2014.009f, 707.694f, 0.05f}, //25
+ {5316.062f, 1970.777f, 707.694f, 1.62f}, //15
+ {5322.498f, 2037.415f, 707.694f, 4.71f}, //6
+ {5307.087f, 1970.065f, 707.694f, 1.62f}, //17
+ {5342.460f, 2012.391f, 707.694f, 3.14f}, //8
+ {5297.601f, 1971.420f, 707.694f, 1.62f}, //19
+ {5295.668f, 1975.853f, 707.694f, 1.62f}, //20
+
+ //Wing 04
+ {5273.661f, 1996.767f, 707.694f, 0.05f}, //21
+ {5275.228f, 2001.275f, 707.694f, 0.05f}, //22
+ {5344.153f, 2017.753f, 707.694f, 3.14f}, //7
+ {5275.310f, 2009.686f, 707.694f, 0.05f}, //24
+ {5319.835f, 1975.177f, 707.694f, 1.62f}, //14
+ {5277.445f, 2017.197f, 707.694f, 0.05f}, //26
+ {5298.198f, 2037.762f, 707.694f, 4.71f} //0
+};
+
+static _Locations WallLoc[]=
+{
+ {5540.39f, 2086.48f, 731.066f, 1.00057f},
+ {5494.3f, 1978.27f, 736.689f, 1.0885f},
+ {5434.27f, 1881.12f, 751.303f, 0.923328f},
+ {5323.61f, 1755.85f, 770.305f, 0.784186f},
+ {5239.01f, 1932.64f, 707.695f, 0.8f}, // Spawn point for Jaina && Silvana intro
+ {5266.779785f, 1953.42f, 707.697f, 1.0f},
+ {5547.27002f, 2256.949951f, 733.010986f, 0.9f}, // Spawn point for Jaina && Silvana outro
+};
+
+#endif
\ No newline at end of file
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp
new file mode 100644
index 0000000..17bc8cc
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.cpp
@@ -0,0 +1,1348 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Hall Of Reflection
+SD%Complete: Who knows? :D
+SDComment: event script!
+SDErrors: They have, but i dont know were it! :D
+SDCategory: hall_of_reflection
+SDAuthor: MaxXx2021 aka Mioka
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_halls.h"
+#include "escort_ai.h"
+
+enum
+{
+ /*INTRO - Pre Uther*/
+ SAY_JAINA_INTRO_01 = -1594433,
+ SAY_SYLVANA_INTRO_01 = -1594434,
+ SAY_JAINA_INTRO_02 = -1594435,
+ SAY_JAINA_INTRO_03 = -1594436,
+ SAY_SYLVANA_INTRO_03 = -1594437,
+ SAY_JAINA_INTRO_04 = -1594438,
+ SAY_SYLVANA_INTRO_04 = -1594439,
+
+ /*INTRO - Uther Dialog*/
+ SAY_UTHER_A_01 = -1594440,
+ SAY_UTHER_H_01 = -1594441,
+ SAY_JAINA_02 = -1594442,
+ SAY_SYLVANA_02 = -1594443,
+ SAY_UTHER_A_03 = -1594444,
+ SAY_UTHER_H_03 = -1594445,
+ SAY_JAINA_04 = -1594446,
+ SAY_SYLVANA_04 = -1594447,
+ SAY_UTHER_A_05 = -1594448,
+ SAY_UTHER_H_05 = -1594449,
+ SAY_JAINA_06 = -1594450,
+ SAY_SYLVANA_06 = -1594451,
+ SAY_UTHER_A_07 = -1594452,
+ SAY_UTHER_H_07 = -1594453,
+ SAY_JAINA_08 = -1594454,
+ SAY_SYLVANA_08 = -1594455,
+ SAY_UTHER_A_09 = -1594456,
+ SAY_UTHER_H_09 = -1594457,
+ SAY_JAINA_10 = -1594458,
+ SAY_UTHER_A_11 = -1594459,
+ SAY_UTHER_H_11 = -1594460,
+ SAY_JAINA_12 = -1594461,
+ SAY_SYLVANA_12 = -1594462,
+ SAY_UTHER_A_13 = -1594463,
+ SAY_UTHER_A_14 = -1594464,
+ SAY_JAINA_15 = -1594465,
+
+ /*INTRO - Lich King Arrive*/
+ SAY_UTHER_A_16 = -1594466,
+ SAY_UTHER_H_16 = -1594467,
+ SAY_LICH_KING_17 = -1594468,
+ SAY_LICH_KING_18 = -1594469,
+ SAY_LICH_KING_19 = -1594470,
+ SAY_JAINA_20 = -1594471,
+ SAY_SYLVANA_20 = -1594472,
+ SAY_LICH_KING_A_21 = -1594473,
+ SAY_LICH_KING_H_21 = -1594474,
+ SAY_FALRIC_INTRO = -1594475,
+ SAY_MARWYN_INTRO = -1594476,
+ SAY_FALRIC_INTRO2 = -1594505,
+
+ /*INTRO - Pre Escape*/
+ SAY_LICH_KING_AGGRO_A = -1594477,
+ SAY_LICH_KING_AGGRO_H = -1594478,
+ SAY_JAINA_AGGRO = -1594479,
+ SAY_SYLVANA_AGGRO = -1594480,
+
+ /*ESCAPE*/
+ SAY_JAINA_WALL_01 = -1594487,
+ SAY_SYLVANA_WALL_01 = -1594488,
+ SAY_JAINA_WALL_02 = -1594489,
+ SAY_SYLVANA_WALL_02 = -1594490,
+ SAY_LICH_KING_WALL_02 = -1594491,
+ SAY_LICH_KING_WALL_03 = -1594492,
+ SAY_LICH_KING_WALL_04 = -1594493,
+ SAY_JAINA_WALL_03 = -1594494,
+ SAY_JAINA_WALL_04 = -1594495,
+ SAY_SYLVANA_WALL_03 = -1594496,
+ SAY_SYLVANA_WALL_04 = -1594497,
+ SAY_JAINA_ESCAPE_01 = -1594498,
+ SAY_JAINA_ESCAPE_02 = -1594499,
+ SAY_SYLVANA_ESCAPE_01 = -1594500,
+ SAY_SYLVANA_ESCAPE_02 = -1594501,
+ SAY_JAINA_TRAP = -1594502,
+ SAY_SYLVANA_TRAP = -1594503,
+ SAY_LICH_KING_END_01 = -1594506,
+ SAY_LICH_KING_END_02 = -1594507,
+ SAY_LICH_KING_END_03 = -1594508,
+
+ SAY_ESCAPE_01 = -1594531,
+ SAY_ESCAPE_02 = -1594532,
+ SAY_ESCAPE_03 = -1594533,
+
+
+ /*SPELLS AND VISUAL EFFECTS*/
+ SPELL_TAKE_FROSTMOURNE = 72729,
+ SPELL_FROSTMOURNE_DESPAWN = 72726,
+ SPELL_FROSTMOURNE_SOUNDS = 70667,
+ SPELL_CAST_VISUAL = 65633, //Jaina And Sylavana cast this when summon uther.
+ SPELL_BOSS_SPAWN_AURA = 72712, //Falric and Marwyn
+ SPELL_UTHER_DESPAWN = 70693,
+ SPELL_WINTER = 69780,
+ SPELL_FURY_OF_FROSTMOURNE = 70063,
+ SPELL_SOUL_REAPER = 73797,
+ SPELL_RAISE_DEAD = 69818,
+ SPELL_ICE_PRISON = 69708,
+ SPELL_DARK_ARROW = 70194,
+ SPELL_ICE_BARRIER = 69787,
+ SPELL_DESTROY_ICE_WALL_01 = 69784, //Jaina
+ SPELL_DESTROY_ICE_WALL_02 = 70224,
+ SPELL_DESTROY_ICE_WALL_03 = 70225, //Sylvana
+ SPELL_DESTRUCT_ICE_WALL = 69784,
+ SPELL_SUMMON_ICE_WALL = 69768,
+ SPELL_SYLVANA_JUMP = 68339,
+ SPELL_SYLVANA_STEP = 69087,
+ SPELL_SILENCE = 69413,
+ SPELL_LICH_KING_CAST = 57561,
+ SPELL_FROSTMOURNE_VISUAL = 73220,
+ SPELL_SHIELD_DISRUPTION = 58291,
+
+ FACTION = 2076,
+};
+
+struct MANGOS_DLL_DECL npc_jaina_and_sylvana_HRintroAI : public ScriptedAI
+{
+ npc_jaina_and_sylvana_HRintroAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ BSWScriptedInstance* m_pInstance;
+
+ Creature* pUther;
+ bool Small;
+
+ void Reset()
+ {
+ m_creature->SetPhaseMask(65535, true);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Small = false;
+ }
+
+ void Event()
+ {
+ switch(m_pInstance->GetEvent(m_creature->GetEntry()))
+ {
+ case 1:
+ if (m_pInstance->GetData(TYPE_EVENT) == 2)
+ Small = true;
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ m_pInstance->SetNextEvent(2,m_creature->GetEntry(),2000);
+ break;
+ case 2:
+ if(m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_INTRO_01, m_creature);
+ m_pInstance->SetNextEvent(3,m_creature->GetEntry(),5000);
+ }
+ else if(m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_SYLVANA_INTRO_01, m_creature);
+ m_pInstance->SetNextEvent(3,m_creature->GetEntry(),8000);
+ }
+ break;
+ case 3:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_INTRO_02, m_creature);
+ m_pInstance->SetNextEvent(4,m_creature->GetEntry(),5000);
+ }
+ else if(m_creature->GetEntry() == NPC_SYLVANA)
+ m_pInstance->SetNextEvent(4,m_creature->GetEntry(),500);
+ break;
+ case 4:
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MovePoint(0, 5307.031f, 1997.920f, 709.341f);
+ m_pInstance->SetNextEvent(5,m_creature->GetEntry(),10000);
+ break;
+ case 5:
+ if(Creature* pTarget = m_creature->SummonCreature(NPC_ALTAR_TARGET,5309.374f,2006.788f,711.615f,1.37f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,360000))
+ {
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTarget->GetGUID());
+ pTarget->SetCreatorGuid(ObjectGuid());
+ }
+ m_pInstance->SetNextEvent(6,m_creature->GetEntry(),1000);
+ break;
+ case 6:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_INTRO_03, m_creature);
+ m_pInstance->SetNextEvent(7,m_creature->GetEntry(),5000);
+ }
+ if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_SYLVANA_INTRO_03, m_creature);
+ m_pInstance->SetNextEvent(7,m_creature->GetEntry(),5000);
+ }
+ break;
+ case 7:
+ DoCast(m_creature, SPELL_CAST_VISUAL);
+ if (m_creature->GetEntry() == NPC_JAINA)
+ DoScriptText(SAY_JAINA_INTRO_04, m_creature);
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ DoScriptText(SAY_SYLVANA_INTRO_04, m_creature);
+ m_pInstance->SetNextEvent(8,m_creature->GetEntry(),3000);
+ break;
+ case 8:
+ DoCast(m_creature, SPELL_FROSTMOURNE_SOUNDS);
+ if(GameObject* pFrostmourne = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_FROSTMOURNE)))
+ pFrostmourne->SetGoState(GO_STATE_ACTIVE);
+ if(m_creature->GetEntry() == NPC_JAINA)
+ m_pInstance->SetNextEvent(9,m_creature->GetEntry(),12000);
+ if(m_creature->GetEntry() == NPC_SYLVANA)
+ m_pInstance->SetNextEvent(9,m_creature->GetEntry(),8000);
+ break;
+ case 9:
+ if(Creature* Uther = m_creature->SummonCreature(NPC_UTHER,5308.228f,2003.641f,709.341f,4.17f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,360000))
+ {
+ pUther = Uther;
+ Uther->SetCreatorGuid(ObjectGuid());
+ Uther->SetRespawnDelay(DAY);
+ Uther->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Uther->GetGUID());
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_UTHER_A_01, Uther);
+ m_pInstance->SetNextEvent(10,m_creature->GetEntry(),3000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_UTHER_H_01, Uther);
+ m_pInstance->SetNextEvent(10,m_creature->GetEntry(),10000);
+ }
+ }
+ break;
+ case 10:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_02, m_creature);
+ m_pInstance->SetNextEvent(11,m_creature->GetEntry(),5000);
+ }
+ else if(m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_SYLVANA_02, m_creature);
+ m_pInstance->SetNextEvent(11,m_creature->GetEntry(),3000);
+ }
+ break;
+ case 11:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ {
+ DoScriptText(SAY_UTHER_A_03, pUther);
+ m_pInstance->SetNextEvent(Small ? 24 : 12, m_creature->GetEntry(),7000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA && pUther)
+ {
+ DoScriptText(SAY_UTHER_H_03, pUther);
+ m_pInstance->SetNextEvent(Small ? 24 : 12, m_creature->GetEntry(),6000);
+ }
+ break;
+ case 12:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_04, m_creature);
+ m_pInstance->SetNextEvent(13,m_creature->GetEntry(),2000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_SYLVANA_04, m_creature);
+ m_pInstance->SetNextEvent(13,m_creature->GetEntry(),5000);
+ }
+ break;
+ case 13:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ {
+ DoScriptText(SAY_UTHER_A_05, pUther);
+ m_pInstance->SetNextEvent(14,m_creature->GetEntry(),10000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA && pUther)
+ {
+ DoScriptText(SAY_UTHER_H_05, pUther);
+ m_pInstance->SetNextEvent(14,m_creature->GetEntry(),19000);
+ }
+ break;
+ case 14:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_06, m_creature);
+ m_pInstance->SetNextEvent(15,m_creature->GetEntry(),6000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_SYLVANA_06, m_creature);
+ m_pInstance->SetNextEvent(15,m_creature->GetEntry(),2000);
+ }
+ break;
+ case 15:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ {
+ DoScriptText(SAY_UTHER_A_07, pUther);
+ m_pInstance->SetNextEvent(16,m_creature->GetEntry(),12000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA && pUther)
+ {
+ DoScriptText(SAY_UTHER_H_07, pUther);
+ m_pInstance->SetNextEvent(16,m_creature->GetEntry(),6000);
+ }
+ break;
+ case 16:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_08, m_creature);
+ m_pInstance->SetNextEvent(17,m_creature->GetEntry(),6000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_SYLVANA_08, m_creature);
+ m_pInstance->SetNextEvent(17,m_creature->GetEntry(),3000);
+ }
+ break;
+ case 17:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ {
+ DoScriptText(SAY_UTHER_A_09, pUther);
+ m_pInstance->SetNextEvent(18,m_creature->GetEntry(),12000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA && pUther)
+ {
+ DoScriptText(SAY_UTHER_H_09, pUther);
+ m_pInstance->SetNextEvent(18,m_creature->GetEntry(),11000);
+ }
+ break;
+ case 18:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_10, m_creature);
+ m_pInstance->SetNextEvent(19,m_creature->GetEntry(),12000);
+ }
+ else if(m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ m_pInstance->SetNextEvent(19,m_creature->GetEntry(),500);
+ }
+ break;
+ case 19:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ {
+ DoScriptText(SAY_UTHER_A_11, pUther);
+ m_pInstance->SetNextEvent(20,m_creature->GetEntry(),24000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA && pUther)
+ {
+ DoScriptText(SAY_UTHER_H_11, pUther);
+ m_pInstance->SetNextEvent(20,m_creature->GetEntry(),9000);
+ }
+ break;
+ case 20:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_12, m_creature);
+ m_pInstance->SetNextEvent(21,m_creature->GetEntry(),2000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ DoScriptText(SAY_SYLVANA_12, m_creature);
+ m_pInstance->SetNextEvent(21,m_creature->GetEntry(),2100);
+ }
+ break;
+ case 21:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ {
+ DoScriptText(SAY_UTHER_A_13, pUther);
+ m_pInstance->SetNextEvent(22,m_creature->GetEntry(),5000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ m_pInstance->SetNextEvent(22,m_creature->GetEntry(),500);
+ }
+ break;
+ case 22:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ {
+ DoScriptText(SAY_UTHER_A_14, pUther);
+ m_pInstance->SetNextEvent(23,m_creature->GetEntry(),12000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ m_pInstance->SetNextEvent(23,m_creature->GetEntry(),500);
+ }
+ break;
+ case 23:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ {
+ DoScriptText(SAY_JAINA_15, m_creature);
+ m_pInstance->SetNextEvent(24,m_creature->GetEntry(),2000);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA)
+ {
+ m_pInstance->SetNextEvent(24,m_creature->GetEntry(),500);
+ }
+ break;
+ case 24:
+ if (m_creature->GetEntry() == NPC_JAINA && pUther)
+ DoScriptText(SAY_UTHER_A_16, pUther);
+ else if (m_creature->GetEntry() == NPC_SYLVANA && pUther)
+ DoScriptText(SAY_UTHER_H_16, pUther);
+ if(Creature* LichKing = m_creature->SummonCreature(NPC_LICH_KING,5362.469f,2062.342f,707.695f,3.97f,TEMPSUMMON_MANUAL_DESPAWN,0,true))
+ {
+ LichKing->SetRespawnDelay(DAY);
+ LichKing->SetCreatorGuid(ObjectGuid());
+ }
+ m_pInstance->SetNextEvent(24,NPC_LICH_KING,2000);
+ break;
+ case 25:
+ if (pUther)
+ pUther->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER);
+ m_pInstance->SetNextEvent(25,NPC_LICH_KING,2000);
+ break;
+ case 31:
+ m_creature->RemoveAurasDueToSpell(SPELL_FROSTMOURNE_SOUNDS);
+ m_pInstance->SetNextEvent(32,NPC_LICH_KING,4500);
+ break;
+ case 36:
+ if (m_creature->GetEntry() == NPC_JAINA)
+ DoScriptText(SAY_JAINA_20, m_creature);
+ else if(m_creature->GetEntry() == NPC_SYLVANA)
+ DoScriptText(SAY_SYLVANA_20, m_creature);
+ m_creature->GetMotionMaster()->MovePoint(0, 5443.880f, 2147.095f, 707.695f);
+ m_pInstance->SetNextEvent(37,NPC_LICH_KING,4000);
+ break;
+ case 39:
+ m_pInstance->SetNextEvent(40,NPC_LICH_KING,1000);
+ m_creature->ForcedDespawn();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_pInstance)
+ return;
+
+ if (m_pInstance->GetEventTimer(m_creature->GetEntry(),diff) && m_pInstance->GetData(TYPE_PHASE) == 1)
+ Event();
+
+ return;
+ }
+};
+
+bool GossipHello_npc_jaina_and_sylvana_HRintro(Player* pPlayer, Creature* pCreature)
+{
+ BSWScriptedInstance* m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData();
+
+ if(pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu( pCreature->GetGUID());
+
+ switch(pCreature->GetEntry())
+ {
+ case NPC_JAINA:
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594536, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594537, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ break;
+ case NPC_SYLVANA:
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594538, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594539, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ break;
+ }
+
+ pPlayer->PlayerTalkClass->SendGossipMenu(907,pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_jaina_and_sylvana_HRintro(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ BSWScriptedInstance* m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData();
+
+ if (!m_pInstance) return false;
+
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ m_pInstance->SetData(TYPE_EVENT, 1);
+ m_pInstance->SetData(TYPE_PHASE, 1);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ m_pInstance->SetData(TYPE_EVENT, 2);
+ m_pInstance->SetData(TYPE_PHASE, 1);
+ break;
+ }
+
+ m_pInstance->SetNextEvent(1, pCreature->GetEntry(), 500);
+
+ m_pInstance->SetData64(DATA_ESCAPE_LIDER,pCreature->GetGUID());
+
+ return true;
+}
+
+struct MANGOS_DLL_DECL npc_jaina_and_sylvana_HRextroAI : public npc_escortAI
+{
+ npc_jaina_and_sylvana_HRextroAI(Creature *pCreature) : npc_escortAI(pCreature)
+ {
+ m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ BSWScriptedInstance* m_pInstance;
+
+ uint32 CastTimer;
+ int32 HoldTimer;
+ uint8 m_wallNum;
+ bool Fight;
+ ObjectGuid wallTarget;
+ uint32 m_chestID;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+
+ if(m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS) return;
+
+ HoldTimer = 10000;
+ Fight = true;
+ m_wallNum = 0;
+ wallTarget = ObjectGuid();
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+
+ if(m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ {
+ m_creature->CastSpell(m_creature, SPELL_ICE_BARRIER, false);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2HL);
+ }
+
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (m_creature->GetEntry() != NPC_SYLVANA_OUTRO)
+ return;
+
+ if (m_pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS || Fight != true)
+ return;
+
+ npc_escortAI::AttackStart(who);
+
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if(!m_pInstance)
+ return;
+ DoDestructWall();
+ }
+
+ void DoSummonWall(uint8 wallNum)
+ {
+ if(!m_pInstance || wallNum > 3)
+ return;
+
+ m_wallNum = wallNum+1;
+ HoldTimer = 20000;
+
+ switch (wallNum)
+ {
+ case 0: m_pInstance->SetNextEvent(200,BOSS_LICH_KING,500); break;
+ case 1: m_pInstance->SetNextEvent(300,BOSS_LICH_KING,500); break;
+ case 2: m_pInstance->SetNextEvent(400,BOSS_LICH_KING,500); break;
+ case 3: m_pInstance->SetNextEvent(500,BOSS_LICH_KING,500); break;
+ default:
+ break;
+ }
+
+ if (Creature* pWallTarget = m_creature->SummonCreature(NPC_ICE_WALL,WallLoc[wallNum].x,WallLoc[wallNum].y,WallLoc[wallNum].z,WallLoc[wallNum].o,TEMPSUMMON_MANUAL_DESPAWN,0, true))
+ {
+ pWallTarget->SetPhaseMask(65535, true);
+ pWallTarget->setFaction(114);
+ pWallTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pWallTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ wallTarget = pWallTarget->GetObjectGuid();
+ pWallTarget->CastSpell(pWallTarget, SPELL_SUMMON_ICE_WALL, false);
+ }
+ }
+
+ void DoDestructWall()
+ {
+ m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICE_WALL));
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ {
+ pWallTarget->ForcedDespawn();
+ }
+ wallTarget = ObjectGuid();
+ m_wallNum = 0;
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ switch(i)
+ {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ DoSummonWall(0);
+ break;
+ case 3:
+ break;
+ case 4:
+ if (m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ DoScriptText(SAY_JAINA_WALL_01, m_creature);
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ DoScriptText(SAY_SYLVANA_WALL_01, m_creature);
+ CastTimer = 1000;
+ SetEscortPaused(true);
+ if(m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false);
+ }
+ break;
+ case 5:
+ break;
+ case 6:
+ DoSummonWall(1);
+ break;
+ case 7:
+ break;
+ case 8:
+ if (m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ DoScriptText(SAY_JAINA_WALL_02, m_creature);
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ DoScriptText(SAY_SYLVANA_WALL_02, m_creature);
+ CastTimer = 1000;
+ SetEscortPaused(true);
+ if(m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false);
+ }
+ break;
+ case 9:
+ if (m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ DoScriptText(SAY_JAINA_ESCAPE_01, m_creature);
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ DoScriptText(SAY_SYLVANA_ESCAPE_01, m_creature);
+ DoSummonWall(2);
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ if(m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ DoScriptText(SAY_JAINA_WALL_03, m_creature);
+ if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ DoScriptText(SAY_SYLVANA_WALL_03, m_creature);
+ CastTimer = 1000;
+ SetEscortPaused(true);
+ if(m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false);
+ }
+ break;
+ case 13:
+ if (m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ DoScriptText(SAY_JAINA_ESCAPE_02, m_creature);
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ DoScriptText(SAY_SYLVANA_ESCAPE_02, m_creature);
+ break;
+ case 14:
+ break;
+ case 15:
+ DoSummonWall(3);
+ break;
+ case 16:
+ if (m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ DoScriptText(SAY_JAINA_WALL_04, m_creature);
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ DoScriptText(SAY_SYLVANA_WALL_04, m_creature);
+ CastTimer = 1000;
+ SetEscortPaused(true);
+ if(m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_01, false);
+ }
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_02, false);
+ }
+ break;
+ case 17:
+ break;
+ case 18:
+ break;
+ case 19:
+ if (m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ DoScriptText(SAY_JAINA_TRAP, m_creature);
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ DoScriptText(SAY_SYLVANA_TRAP, m_creature);
+ break;
+ case 20:
+ SetEscortPaused(true);
+ if (m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2HL);
+ else if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void Intro()
+ {
+ switch(m_pInstance->GetEvent(m_creature->GetEntry()))
+ {
+ case 100:
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ {
+ if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ AttackStart(pLichKing);
+ }
+ m_pInstance->SetNextEvent(101,BOSS_LICH_KING,500);
+ break;
+ case 102:
+ if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ Fight = false;
+ m_creature->GetMotionMaster()->MovePoint(0, (m_creature->GetPositionX()-5)+rand()%10, (m_creature->GetPositionY()-5)+rand()%10, m_creature->GetPositionZ());
+ m_pInstance->SetNextEvent(103,m_creature->GetEntry(),3000);
+ }
+ else
+ m_pInstance->SetNextEvent(103,m_creature->GetEntry(),500);
+ break;
+ case 103:
+ if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ Fight = true;
+ m_pInstance->SetNextEvent(104,m_creature->GetEntry(),500);
+ break;
+ case 104:
+ if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ m_creature->CastSpell(pLichKing, SPELL_SYLVANA_STEP, false);
+ m_pInstance->SetNextEvent(105,m_creature->GetEntry(),3000);
+ }
+ else
+ m_pInstance->SetNextEvent(105,m_creature->GetEntry(),500);
+ break;
+ case 105:
+ if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ Fight = false;
+ m_creature->GetMotionMaster()->MovePoint(0, (m_creature->GetPositionX()-5)+rand()%10, (m_creature->GetPositionY()-5)+rand()%10, m_creature->GetPositionZ());
+ m_pInstance->SetNextEvent(106,m_creature->GetEntry(),3000);
+ }
+ else
+ m_pInstance->SetNextEvent(106,m_creature->GetEntry(),12000);
+ break;
+ case 106:
+ Fight = true;
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ m_creature->CastSpell(pLichKing,(m_creature->GetEntry() == NPC_JAINA_OUTRO ? SPELL_ICE_PRISON : SPELL_DARK_ARROW),true);
+ m_pInstance->SetNextEvent(107,m_creature->GetEntry(),2500);
+ break;
+ case 107:
+ if(m_creature->GetEntry() == NPC_JAINA_OUTRO)
+ {
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ if (!pLichKing->HasAura(SPELL_ICE_PRISON))
+ pLichKing->CastSpell(pLichKing,SPELL_ICE_PRISON,true);
+ m_creature->RemoveAurasDueToSpell(SPELL_ICE_BARRIER);
+ DoScriptText(SAY_JAINA_AGGRO, m_creature);
+ }
+ else if(m_creature->GetEntry() == NPC_SYLVANA_OUTRO)
+ {
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ if (!pLichKing->HasAura(SPELL_DARK_ARROW))
+ pLichKing->CastSpell(pLichKing,SPELL_DARK_ARROW,true);
+ DoScriptText(SAY_SYLVANA_AGGRO, m_creature);
+ }
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
+ m_creature->AttackStop();
+ m_pInstance->SetNextEvent(108,m_creature->GetEntry(),3000);
+ break;
+ case 108:
+ m_creature->GetMotionMaster()->MovePoint(0, 5577.187f, 2236.003f, 733.012f);
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_pInstance->GetData64(BOSS_LICH_KING));
+ m_pInstance->SetNextEvent(109,m_creature->GetEntry(),10000);
+ break;
+ case 109:
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+// Count = 1;
+ m_pInstance->SetNextEvent(110,m_creature->GetEntry(),10000);
+ break;
+ }
+ }
+
+ void Outro()
+ {
+ switch(m_pInstance->GetEvent(m_creature->GetEntry()))
+ {
+ case 610:
+ m_creature->CastSpell(m_creature, SPELL_SHIELD_DISRUPTION,false);
+ m_pInstance->SetData(DATA_ESCAPE_LIDER,m_creature->GetEntry());
+ m_creature->SummonGameobject(GO_CAVE, 5275.28f, 1694.23f, 786.147f, 0.981225f, 0);
+ m_pInstance->SetNextEvent(611,m_creature->GetEntry(),6000);
+ break;
+ case 611:
+ if (GameObject* pCave = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CAVE)))
+ pCave->SetGoState(GO_STATE_READY);
+ m_creature->RemoveAurasDueToSpell(SPELL_SILENCE);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING);
+ m_creature->CastSpell(m_creature, SPELL_SHIELD_DISRUPTION,false);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MovePoint(0, 5258.911328f,1652.112f,784.295166f);
+ DoScriptText(SAY_ESCAPE_01, m_creature);
+ m_pInstance->SetNextEvent(612,m_creature->GetEntry(),10000);
+ break;
+ case 612:
+ m_pInstance->SetData(TYPE_LICH_KING, DONE);
+ DoScriptText(SAY_ESCAPE_02, m_creature);
+ m_pInstance->SetNextEvent(613,m_creature->GetEntry(),10000);
+ break;
+ case 613:
+ DoScriptText(SAY_ESCAPE_03, m_creature);
+ m_pInstance->SetNextEvent(614,m_creature->GetEntry(),10000);
+ break;
+ case 614:
+ m_creature->GetMotionMaster()->MovePoint(0, 5240.66f, 1646.93f, 784.302f);
+ m_pInstance->SetNextEvent(615,m_creature->GetEntry(),5000);
+ break;
+ case 615:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
+ m_creature->SetOrientation(0.68f);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ m_pInstance->SetNextEvent(616,m_creature->GetEntry(),5000);
+ break;
+ }
+ }
+
+ void UpdateEscortAI(const uint32 diff)
+ {
+ if(!m_pInstance || m_pInstance->GetData(TYPE_PHASE) < 4)
+ return;
+
+ if (m_pInstance->GetData(TYPE_PHASE) == 6 && m_pInstance->GetEventTimer(m_creature->GetEntry(),diff))
+ {
+ Outro();
+ return;
+ }
+
+ DoMeleeAttackIfReady();
+
+ if (m_pInstance->GetData(TYPE_PHASE) == 4 && m_pInstance->GetEventTimer(m_creature->GetEntry(),diff))
+ {
+ Intro();
+ return;
+ }
+
+ if (m_creature->GetEntry() == NPC_SYLVANA_OUTRO && !wallTarget.IsEmpty() && m_wallNum && CastTimer < diff)
+ {
+ if (Creature* pWallTarget = m_creature->GetMap()->GetCreature(wallTarget))
+ m_creature->CastSpell(pWallTarget, SPELL_DESTROY_ICE_WALL_03, false);
+ CastTimer = 1000;
+ }
+ else
+ CastTimer -= diff;
+
+ if (!wallTarget.IsEmpty() && m_wallNum && m_pInstance->GetData(DATA_SUMMONS) == 0 && HoldTimer < 1000)
+ {
+ m_creature->InterruptNonMeleeSpells(false);
+ SetEscortPaused(false);
+
+ switch(m_wallNum)
+ {
+ case 1:
+ DoDestructWall();
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ DoScriptText(SAY_LICH_KING_WALL_02, pLichKing);
+ break;
+ case 2:
+ DoDestructWall();
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ DoScriptText(SAY_LICH_KING_WALL_03, pLichKing);
+ break;
+ case 3:
+ DoDestructWall();
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ DoScriptText(SAY_LICH_KING_WALL_04, pLichKing);
+ break;
+ case 4:
+ DoDestructWall();
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(BOSS_LICH_KING)))
+ {
+ pLichKing->RemoveAurasDueToSpell(SPELL_WINTER);
+ pLichKing->SetSpeedRate(MOVE_WALK, 2.5f, true);
+ }
+ break;
+ }
+ HoldTimer = 10000;
+ }
+ else
+ {
+ if (HoldTimer <= diff)
+ HoldTimer = 0;
+ else
+ HoldTimer -= diff;
+ }
+ }
+};
+
+bool GossipHello_npc_jaina_and_sylvana_HRextro(Player* pPlayer, Creature* pCreature)
+{
+
+ ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+
+ if(!m_pInstance) return false;
+
+ if(m_pInstance->GetData(TYPE_LICH_KING) == DONE) return false;
+
+ if(pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu( pCreature->GetGUID());
+
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3594540, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_jaina_and_sylvana_HRextro(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance* m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ ((npc_jaina_and_sylvana_HRextroAI*)pCreature->AI())->Start(true);
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ pCreature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+
+ if(m_pInstance)
+ {
+ m_pInstance->SetData64(DATA_ESCAPE_LIDER, pCreature->GetGUID());
+ m_pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS);
+ m_pInstance->SetData(TYPE_PHASE, 5);
+ }
+ return true;
+ break;
+ default: return false;
+ }
+}
+
+CreatureAI* GetAI_npc_jaina_and_sylvana_HRintro(Creature* pCreature)
+{
+ return new npc_jaina_and_sylvana_HRintroAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_jaina_and_sylvana_HRextro(Creature* pCreature)
+{
+ return new npc_jaina_and_sylvana_HRextroAI(pCreature);
+}
+
+enum GENERAL_EVENT
+{
+ SAY_AGGRO = -1594519,
+ SAY_DEATH = -1594520,
+
+ SPELL_SHIELD_THROWN = 69222,
+};
+
+struct MANGOS_DLL_DECL npc_frostworn_generalAI : public ScriptedAI
+{
+ npc_frostworn_generalAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiShieldTimer;
+
+ void Reset()
+ {
+ if (!m_pInstance)
+ return;
+ m_uiShieldTimer = 5000;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+ DoScriptText(SAY_DEATH, m_creature);
+ m_pInstance->SetData(TYPE_FROST_GENERAL, DONE);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+
+ if (m_creature->getVictim())
+ return;
+
+ if (pWho->GetTypeId() != TYPEID_PLAYER
+ || m_pInstance->GetData(TYPE_MARWYN) != DONE
+ || !m_creature->IsWithinDistInMap(pWho, 30.0f)
+ ) return;
+
+ if (Player* pPlayer = (Player*)pWho)
+ if (pPlayer->isGameMaster()) return;
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ AttackStart(pWho);
+ }
+
+ void Aggro(Unit* pVictim)
+ {
+ if (!m_pInstance)
+ return;
+ DoScriptText(SAY_AGGRO, m_creature);
+ m_pInstance->SetData(TYPE_FROST_GENERAL, IN_PROGRESS);
+
+ Map::PlayerList const &pList = m_creature->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i)
+ {
+ if (Player* pPlayer = i->getSource())
+ {
+ if (pPlayer && pPlayer->isAlive() && pPlayer->IsInMap(m_creature))
+ {
+ if (Creature* pMirror = m_creature->SummonCreature(NPC_SPIRITUAL_REFLECTION,0,0,0,0,TEMPSUMMON_DEAD_DESPAWN,0, true))
+ {
+ pMirror->SetPhaseMask(65535, true);
+ pMirror->SetInCombatWith(pPlayer);
+ pMirror->AddThreat(pPlayer, 1000.0f);
+ }
+
+ }
+ }
+ };
+
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiShieldTimer < uiDiff)
+ {
+ if(Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget,SPELL_SHIELD_THROWN);
+ m_uiShieldTimer = urand(4000, 8000);
+ }
+ else m_uiShieldTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_frostworn_general(Creature* pCreature)
+{
+ return new npc_frostworn_generalAI(pCreature);
+}
+
+enum spiritual_reflection
+{
+ SPELL_REFLECTION_GHOST = 69861,
+ SPELL_CLONE = 69828,
+ SPELL_CLONE2 = 69837,
+
+ SPELL_BALEFUL_STRIKE = 69933,
+ SPELL_SPIRIT_BURST = 69900,
+
+};
+
+struct MANGOS_DLL_DECL npc_spiritual_reflectionAI : public BSWScriptedAI
+{
+ npc_spiritual_reflectionAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool isMirror;
+ ObjectGuid victimGuid;
+
+ void Reset()
+ {
+ if (!m_pInstance)
+ return;
+ isMirror = false;
+ victimGuid = ObjectGuid();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void Aggro(Unit* pVictim)
+ {
+ if (!m_pInstance || !pVictim || pVictim->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (victimGuid.IsEmpty())
+ victimGuid = pVictim->GetObjectGuid();
+
+ DoStartMovement(pVictim);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_pInstance || !m_creature )
+ return;
+
+ if (uiDamage >= m_creature->GetHealth())
+ doCast(SPELL_SPIRIT_BURST);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_FROST_GENERAL) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (!isMirror)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit(victimGuid))
+ if (m_creature->IsWithinDistInMap(pVictim, 5.0f))
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pVictim->CastSpell(m_creature, SPELL_CLONE, true);
+ pVictim->CastSpell(m_creature, SPELL_CLONE2, true);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, pVictim->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID));
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, pVictim->GetUInt32Value(PLAYER_VISIBLE_ITEM_17_ENTRYID));
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+2, pVictim->GetUInt32Value(PLAYER_VISIBLE_ITEM_18_ENTRYID));
+ pVictim->CastSpell(m_creature, SPELL_REFLECTION_GHOST, true);
+ isMirror = true;
+ }
+ }
+
+ if (!isMirror)
+ return;
+
+ timedCast(SPELL_BALEFUL_STRIKE,uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_spiritual_reflection(Creature* pCreature)
+{
+ return new npc_spiritual_reflectionAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_queldelar_horAI : public ScriptedAI
+{
+ npc_queldelar_horAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (BSWScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ BSWScriptedInstance* m_pInstance;
+ bool intro;
+ Team team;
+ uint32 newLeader;
+
+ void Reset()
+ {
+ intro = false;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_pInstance || intro)
+ return;
+
+ if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER || !pWho->IsWithinDistInMap(m_creature, 22.0f))
+ return;
+
+ debug_log("HOR event started");
+
+ intro = true;
+
+ if (m_pInstance->GetData(TYPE_LICH_KING) == DONE)
+ return;
+ else if (m_pInstance->GetData(TYPE_FROST_GENERAL) == DONE)
+ {
+ m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR));
+ m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_ICECROWN_DOOR_2));
+ m_pInstance->SetData(TYPE_PHASE, 3);
+ return;
+ }
+ else if (m_pInstance->GetData(TYPE_MARWYN) == DONE)
+ {
+ m_pInstance->DoOpenDoor(m_pInstance->GetData64(GO_IMPENETRABLE_DOOR));
+ return;
+ }
+ else if (m_pInstance->GetData(TYPE_FALRIC) == DONE)
+ {
+ if (Creature* pMarwyn = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MARWYN)))
+ {
+ pMarwyn->SetVisibility(VISIBILITY_ON);
+ pMarwyn->CastSpell(pMarwyn, SPELL_BOSS_SPAWN_AURA, false);
+ m_pInstance->SetData(TYPE_EVENT, 7);
+ m_pInstance->SetData(TYPE_MARWYN, SPECIAL);
+ }
+ return;
+ }
+
+
+ if (Group* pGroup = ((Player*)pWho)->GetGroup())
+ {
+ ObjectGuid LeaderGuid = pGroup->GetLeaderGuid();
+ if (!LeaderGuid.IsEmpty())
+ if (Player* pLeader =m_creature->GetMap()->GetPlayer(LeaderGuid))
+ team = pLeader->GetTeam();
+ }
+ else
+ team = ((Player*)pWho)->GetTeam();
+
+
+ if (team == ALLIANCE)
+ newLeader = NPC_JAINA;
+ else
+ newLeader = NPC_SYLVANA;
+
+ debug_log("HOR event: team %u, leader %u ",team,newLeader);
+
+ if (Creature* pNewLeader = m_creature->SummonCreature(newLeader,WallLoc[4].x,WallLoc[4].y,WallLoc[4].z,WallLoc[4].o,TEMPSUMMON_MANUAL_DESPAWN,0,true))
+ {
+ pNewLeader->SetCreatorGuid(ObjectGuid());
+ pNewLeader->setFaction(35);
+ pNewLeader->SetPhaseMask(65535, true);
+ pNewLeader->GetMotionMaster()->MovePoint(0, WallLoc[5].x,WallLoc[5].y,WallLoc[5].z);
+ pNewLeader->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pNewLeader->SetSpeedRate(MOVE_RUN, 1.0f, true);
+ pNewLeader->SetRespawnDelay(DAY);
+ }
+// m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 63135);
+ }
+
+ void AttackStart(Unit* who)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ }
+};
+CreatureAI* GetAI_npc_queldelar_hor(Creature* pCreature)
+{
+ return new npc_queldelar_horAI(pCreature);
+}
+
+
+void AddSC_halls_of_reflection()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_jaina_and_sylvana_HRintro";
+ newscript->GetAI = &GetAI_npc_jaina_and_sylvana_HRintro;
+ newscript->pGossipHello = &GossipHello_npc_jaina_and_sylvana_HRintro;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_and_sylvana_HRintro;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jaina_and_sylvana_HRextro";
+ newscript->GetAI = &GetAI_npc_jaina_and_sylvana_HRextro;
+ newscript->pGossipHello = &GossipHello_npc_jaina_and_sylvana_HRextro;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_and_sylvana_HRextro;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_frostworn_general";
+ newscript->GetAI = &GetAI_npc_frostworn_general;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_spiritual_reflection";
+ newscript->GetAI = &GetAI_npc_spiritual_reflection;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_queldelar_hor";
+ newscript->GetAI = &GetAI_npc_queldelar_hor;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.h b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.h
new file mode 100644
index 0000000..e592de1
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/halls_of_reflection.h
@@ -0,0 +1,3 @@
+/* Copyright (C) 2006 - 2010 ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
new file mode 100644
index 0000000..eb47fb2
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
@@ -0,0 +1,322 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: instance_halls_of_reflection
+SD%Complete: 70%
+SDComment:
+SDErrors:
+SDCategory: instance script
+SDAuthor: /dev/rsa, modified by MaxXx2021 aka Mioka
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_halls.h"
+#include "World.h"
+
+struct MANGOS_DLL_DECL instance_halls_of_reflection : public BSWScriptedInstance
+{
+ instance_halls_of_reflection(Map* pMap) : BSWScriptedInstance(pMap)
+ {
+ Difficulty = pMap->GetDifficulty();
+ Initialize();
+ }
+
+ uint32 m_auiEncounter[MAX_ENCOUNTERS+1];
+ std::string strSaveData;
+
+ uint8 Difficulty;
+ uint8 m_uiSummons;
+
+ uint32 m_auiLeader;
+
+ uint64 m_uiFalricGUID;
+ uint64 m_uiMarwynGUID;
+ uint64 m_uiLichKingGUID;
+ uint64 m_uiLiderGUID;
+ uint64 m_uiUtherGUID;
+
+ uint64 m_uiQuelDelarGUID;
+
+ uint64 m_uiMainGateGUID;
+ uint64 m_uiExitGateGUID;
+ uint64 m_uiDoor2GUID;
+ uint64 m_uiDoor3GUID;
+
+ uint64 m_uiFrostGeneralGUID;
+ uint64 m_uiCaptainsChestHordeGUID;
+ uint64 m_uiCaptainsChestAllianceGUID;
+ uint64 m_uiFrostmourneGUID;
+ uint64 m_uiFrostmourneAltarGUID;
+ uint64 m_uiPortalGUID;
+ uint64 m_uiIceWallGUID;
+ uint64 m_uiCaveGUID;
+
+ void Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+ m_uiMainGateGUID = 0;
+ m_uiFrostmourneGUID = 0;
+ m_uiFalricGUID = 0;
+ m_uiLiderGUID = 0;
+ m_uiLichKingGUID = 0;
+ m_uiExitGateGUID = 0;
+ m_uiSummons = 0;
+ m_uiIceWallGUID = 0;
+ m_uiCaveGUID = 0;
+ }
+
+ void OnCreatureCreate(Creature* pCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_FALRIC:
+ m_uiFalricGUID = pCreature->GetGUID();
+ break;
+ case NPC_MARWYN:
+ m_uiMarwynGUID = pCreature->GetGUID();
+ break;
+ case BOSS_LICH_KING:
+ m_uiLichKingGUID = pCreature->GetGUID();
+ break;
+ case NPC_FROST_GENERAL:
+ m_uiFrostGeneralGUID = pCreature->GetGUID();
+ break;
+ case NPC_QUEL_DELAR:
+ m_uiQuelDelarGUID = pCreature->GetGUID();
+ break;
+ case NPC_UTHER:
+ m_uiUtherGUID = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void OnObjectCreate(GameObject* pGo)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_IMPENETRABLE_DOOR: m_uiMainGateGUID = pGo->GetGUID();
+ if (GetData(TYPE_MARWYN) == DONE)
+ DoOpenDoor(m_uiMainGateGUID);
+ break;
+ case GO_FROSTMOURNE: m_uiFrostmourneGUID = pGo->GetGUID(); break;
+ case GO_ICECROWN_DOOR: m_uiExitGateGUID = pGo->GetGUID(); break;
+ case GO_ICECROWN_DOOR_2: m_uiDoor2GUID = pGo->GetGUID();
+ if (GetData(TYPE_FROST_GENERAL) == DONE)
+ DoOpenDoor(m_uiDoor2GUID);
+ break;
+ case GO_ICECROWN_DOOR_3: m_uiDoor3GUID = pGo->GetGUID(); break;
+ case GO_PORTAL: m_uiPortalGUID = pGo->GetGUID(); break;
+ case GO_CAPTAIN_CHEST_1:
+ if (Difficulty == RAID_DIFFICULTY_10MAN_NORMAL)
+ m_uiCaptainsChestHordeGUID = pGo->GetGUID();
+ break;
+ case GO_CAPTAIN_CHEST_3:
+ if (Difficulty == RAID_DIFFICULTY_25MAN_NORMAL)
+ m_uiCaptainsChestHordeGUID = pGo->GetGUID();
+ break;
+ case GO_CAPTAIN_CHEST_2:
+ if (Difficulty == RAID_DIFFICULTY_10MAN_NORMAL)
+ m_uiCaptainsChestAllianceGUID = pGo->GetGUID();
+ break;
+ case GO_CAPTAIN_CHEST_4:
+ if (Difficulty == RAID_DIFFICULTY_25MAN_NORMAL)
+ m_uiCaptainsChestAllianceGUID = pGo->GetGUID();
+ break;
+
+ case GO_ICE_WALL: m_uiIceWallGUID = pGo->GetGUID();
+ pGo->SetPhaseMask(65535, true);
+ break;
+ case GO_CAVE: m_uiCaveGUID = pGo->GetGUID();
+ DoOpenDoor(m_uiCaveGUID);
+ break;
+ }
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ switch(uiType)
+ {
+ case TYPE_PHASE: m_auiEncounter[uiType] = uiData; break;
+ case TYPE_EVENT: m_auiEncounter[uiType] = uiData;
+ uiData = NOT_STARTED;
+ break;
+ case TYPE_FALRIC: m_auiEncounter[uiType] = uiData;
+ if (uiData == SPECIAL)
+ DoCloseDoor(m_uiExitGateGUID);
+ else if (uiData == FAIL)
+ DoOpenDoor(m_uiExitGateGUID);
+ break;
+ case TYPE_MARWYN: m_auiEncounter[uiType] = uiData;
+ if (uiData == SPECIAL)
+ DoCloseDoor(m_uiExitGateGUID);
+ else if (uiData == FAIL)
+ DoOpenDoor(m_uiExitGateGUID);
+ else if (uiData == DONE)
+ {
+ DoOpenDoor(m_uiMainGateGUID);
+ DoOpenDoor(m_uiExitGateGUID);
+ }
+ break;
+ case TYPE_FROST_GENERAL: m_auiEncounter[uiType] = uiData;
+ if(uiData == DONE)
+ DoOpenDoor(m_uiDoor2GUID);
+ break;
+ case TYPE_LICH_KING: m_auiEncounter[uiType] = uiData;
+ if(uiData == IN_PROGRESS)
+ DoOpenDoor(m_uiDoor3GUID);
+ if(uiData == DONE)
+ {
+ if (GameObject* pChest = instance->GetGameObject(m_uiCaptainsChestAllianceGUID))
+ if (pChest && !pChest->isSpawned() && GetData(DATA_ESCAPE_LIDER) == NPC_JAINA_OUTRO)
+ {
+ pChest->SetRespawnTime(DAY);
+ }
+ if (GameObject* pChest = instance->GetGameObject(m_uiCaptainsChestHordeGUID))
+ if (pChest && !pChest->isSpawned() && GetData(DATA_ESCAPE_LIDER) == NPC_SYLVANA_OUTRO)
+ {
+ pChest->SetRespawnTime(DAY);
+ };
+ if (GameObject* pPortal = instance->GetGameObject(m_uiPortalGUID))
+ if (pPortal && !pPortal->isSpawned())
+ {
+ pPortal->SetRespawnTime(DAY);
+ };
+ }
+ break;
+ case TYPE_HALLS: m_auiEncounter[uiType] = uiData; break;
+ case DATA_SUMMONS: if (uiData == 3) m_uiSummons = 0;
+ else if (uiData == 1) ++m_uiSummons;
+ else if (uiData == 0) --m_uiSummons;
+ uiData = NOT_STARTED;
+ break;
+ case DATA_ESCAPE_LIDER: m_auiLeader = uiData;
+ uiData = NOT_STARTED;
+ break;
+ default:
+ break;
+ }
+
+ if (uiData == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ strSaveData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ const char* Save()
+ {
+ return strSaveData.c_str();
+ }
+
+ uint32 GetData(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case TYPE_PHASE: return m_auiEncounter[uiType];
+ case TYPE_EVENT: return m_auiEncounter[uiType];
+ case TYPE_FALRIC: return m_auiEncounter[uiType];
+ case TYPE_MARWYN: return m_auiEncounter[uiType];
+ case TYPE_LICH_KING: return m_auiEncounter[uiType];
+ case TYPE_FROST_GENERAL: return m_auiEncounter[uiType];
+ case TYPE_HALLS: return m_auiEncounter[uiType];
+ case DATA_SUMMONS: return m_uiSummons;
+ case DATA_ESCAPE_LIDER: return m_auiLeader;
+ default: return 0;
+ }
+ return 0;
+ }
+
+ void SetData64(uint32 uiData, uint64 uiGuid)
+ {
+ switch(uiData)
+ {
+ case DATA_ESCAPE_LIDER:
+ m_uiLiderGUID = uiGuid;
+ break;
+ }
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case GO_IMPENETRABLE_DOOR: return m_uiMainGateGUID;
+ case GO_FROSTMOURNE: return m_uiFrostmourneGUID;
+ case NPC_FALRIC: return m_uiFalricGUID;
+ case NPC_MARWYN: return m_uiMarwynGUID;
+ case NPC_UTHER: return m_uiUtherGUID;
+ case BOSS_LICH_KING: return m_uiLichKingGUID;
+ case DATA_ESCAPE_LIDER: return m_uiLiderGUID;
+ case NPC_FROST_GENERAL: return m_uiFrostGeneralGUID;
+ case NPC_QUEL_DELAR: return m_uiQuelDelarGUID;
+ case GO_ICECROWN_DOOR: return m_uiExitGateGUID;
+ case GO_ICECROWN_DOOR_2: return m_uiDoor2GUID;
+ case GO_ICECROWN_DOOR_3: return m_uiDoor3GUID;
+ case GO_ICE_WALL: return m_uiIceWallGUID;
+ case GO_CAVE: return m_uiCaveGUID;
+ }
+ return 0;
+ }
+
+ void Load(const char* chrIn)
+ {
+ if (!chrIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(chrIn);
+
+ std::istringstream loadStream(chrIn);
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
+
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+};
+
+InstanceData* GetInstanceData_instance_halls_of_reflection(Map* pMap)
+{
+ return new instance_halls_of_reflection(pMap);
+}
+
+void AddSC_instance_halls_of_reflection()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_halls_of_reflection";
+ newscript->GetInstanceData = &GetInstanceData_instance_halls_of_reflection;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_forgemaster_gafrost.cpp
index edb781e..437ca3f 100644
--- 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
@@ -16,15 +16,48 @@
/* ScriptData
SDName: boss_forgemaster_gafrost
-SD%Complete: 0%
-SDComment:
+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
+/*
+enum saysSD2
{
SAY_AGGRO = -1658014,
SAY_SLAY_1 = -1658015,
@@ -38,8 +71,173 @@ enum
EMOTE_THROW_SARONITE = -1658022,
EMOTE_DEEP_FREEZE = -1658023,
};
+*/
-void AddSC_boss_gafrost()
+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.021, -201.438, 526.699);
+ }
+
+ 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.009, -229.447, 526.847);
+ }
+ 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 b558e18..4493d9c 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
@@ -15,14 +15,156 @@
*/
/* ScriptData
-SDName: boss_krick_and_ick
-SD%Complete: 0%
-SDComment:
+SDName: boss_ick && boss_krick
+SD%Complete: 1%
+SDComment: by ..., modified by /dev/rsa
SDCategory: Pit of Saron
EndScriptData */
#include "precompiled.h"
#include "pit_of_saron.h"
+enum
+{
+ //common
+ SPELL_BERSERK = 47008,
+ //yells
+ //summons
+ NPC_EXPLODING_ORB = 36610,
+ //Abilities
+ SPELL_FEAR = 68950,
+ SPELL_EXPLOSIVE_ORB = 69019,
+ SPELL_EXPLOSIVE = 69012,
+ SPELL_SHADOWBOLT = 69028,
+ SPELL_STRANGULATE = 69413,
+ SPELL_TOXIC = 69024,
+ SPELL_KICK = 69021,
+ SPELL_POISON = 68989,
+ SPELL_POISON_H = 70434,
+ SPELL_PURSUIT = 68987,
+ SPELL_PUSTULANT = 69581,
+ SPELL_CONFUSION = 69029,
+};
+
+struct MANGOS_DLL_DECL boss_krickAI : public ScriptedAI
+{
+ boss_krickAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Regular = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool Regular;
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ if(pInstance) pInstance->SetData(TYPE_KRICK, NOT_STARTED);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(pInstance) pInstance->SetData(TYPE_KRICK, IN_PROGRESS);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(pInstance) pInstance->SetData(TYPE_KRICK, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL boss_ickAI : public ScriptedAI
+{
+ boss_ickAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Regular = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool Regular;
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ }
+
+ void JustDied(Unit *killer)
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_krick(Creature* pCreature)
+{
+ return new boss_krickAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_ick(Creature* pCreature)
+{
+ return new boss_ickAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_exploding_orbAI : public ScriptedAI
+{
+ mob_exploding_orbAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_creature->SetActiveObjectState(true);
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ uint32 ExplodeTimer;
+
+ void Reset()
+ {
+ ExplodeTimer = 18000;
+ }
+
+ void AttackStart(Unit* who)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!pInstance) return;
+
+ if (ExplodeTimer < diff)
+ {
+ DoCast(m_creature, SPELL_EXPLOSIVE_ORB);
+ m_creature->ForcedDespawn();
+ } else ExplodeTimer -= diff;
+ return;
+ }
+
+};
+
+CreatureAI* GetAI_mob_exploding_orb(Creature* pCreature)
+{
+ return new mob_exploding_orbAI(pCreature);
+}
+
enum
{
@@ -55,5 +197,20 @@ enum
void AddSC_boss_krick_and_ick()
{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_krick";
+ newscript->GetAI = &GetAI_boss_krick;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_ick";
+ newscript->GetAI = &GetAI_boss_ick;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_exploding_orb";
+ newscript->GetAI = &GetAI_mob_exploding_orb;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp
index 5338b35..5bffcbd 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
@@ -24,6 +24,16 @@ EndScriptData */
#include "precompiled.h"
#include "pit_of_saron.h"
+enum Spells
+{
+ //common
+ SPELL_BERSERK = 47008,
+ //yells
+ //summons
+ //Abilities
+ SPELL_FEAR = 68950
+};
+
enum
{
SAY_PREFIGHT_1 = -1658050,
@@ -40,7 +50,94 @@ enum
EMOTE_SMASH = -1658060,
};
+
+struct MANGOS_DLL_DECL boss_scourgelord_tyrannusAI : public ScriptedAI
+{
+ boss_scourgelord_tyrannusAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ if(pInstance) pInstance->SetData(TYPE_TYRANNUS, NOT_STARTED);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(pInstance) pInstance->SetData(TYPE_TYRANNUS, IN_PROGRESS);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(pInstance) pInstance->SetData(TYPE_TYRANNUS, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_rimefang_posAI : public ScriptedAI
+{
+ mob_rimefang_posAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ }
+
+ void Aggro(Unit *who)
+ {
+ }
+
+ void JustDied(Unit *killer)
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+
+CreatureAI* GetAI_boss_scourgelord_tyrannus(Creature* pCreature)
+{
+ return new boss_scourgelord_tyrannusAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_rimefang_pos(Creature* pCreature)
+{
+ return new mob_rimefang_posAI(pCreature);
+}
+
+
void AddSC_boss_tyrannus()
{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_scourgelord_tyrannus";
+ newscript->GetAI = &GetAI_boss_scourgelord_tyrannus;
+ newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name="mob_rimefang_pos";
+ newscript->GetAI = &GetAI_mob_rimefang_pos;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp b/scripts/northrend/icecrown_citadel/frozen_halls/pit_of_saron/pit_of_saron.cpp
index d09121c..b56ef56 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
@@ -21,9 +21,6 @@ SD%Complete: 0
SDCategory: Pit of Saron
EndScriptData */
-/* ContentData
-EndContentData */
-
#include "precompiled.h"
#include "pit_of_saron.h"
@@ -59,7 +56,57 @@ enum
SAY_SYLVANAS_OUTRO_2 = -1658067,
};
+struct MANGOS_DLL_DECL npc_jaina_or_sylvanas_POSintroAI : public ScriptedAI
+{
+ npc_jaina_or_sylvanas_POSintroAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ }
+};
+
+struct MANGOS_DLL_DECL npc_jaina_or_sylvanas_POSoutroAI : public ScriptedAI
+{
+ npc_jaina_or_sylvanas_POSoutroAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ }
+};
+
+CreatureAI* GetAI_npc_jaina_or_sylvanas_POSintro(Creature* pCreature)
+{
+ return new npc_jaina_or_sylvanas_POSintroAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_jaina_or_sylvanas_POSoutro(Creature* pCreature)
+{
+ return new npc_jaina_or_sylvanas_POSoutroAI(pCreature);
+}
+
void AddSC_pit_of_saron()
{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="npc_jaina_or_sylvanas_POSintro";
+ newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_POSintro;
+ newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name="npc_jaina_or_sylvana_POSoutro";
+ newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_POSoutro;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp
index b2f817b..8fb3a3c 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp
@@ -16,9 +16,913 @@
/* ScriptData
SDName: blood_prince_council
-SD%Complete: 0%
-SDComment:
+SD%Complete: 90%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need implement true movement for kinetic bomb, correct yells.
#include "precompiled.h"
+#include "def_spire.h"
+
+enum BossSpells
+{
+ SPELL_BERSERK = 47008,
+ SPELL_FAKE_DEATH = 71598,
+
+ //Darkfallen Orb
+ SPELL_INVOCATION_OF_BLOOD_V = 70952, //
+ SPELL_INVOCATION_OF_BLOOD_K = 70981, //
+ SPELL_INVOCATION_OF_BLOOD_T = 70982, //
+ SPELL_INVOCATION_OF_BLOOD_AURA = 70983, // Triggered, override
+
+ //Valanar
+ SPELL_KINETIC_BOMB = 72053,
+ NPC_KINETIC_BOMB_TARGET = 38458,
+ NPC_KINETIC_BOMB = 38454,
+ SPELL_KINETIC_BOMB_EXPLODE = 72052,
+ SPELL_SHOCK_VORTEX = 72037,
+ NPC_SHOCK_VORTEX = 38422,
+ SPELL_SHOCK_VORTEX_AURA = 71945,
+ SPELL_SHOCK_VORTEX_2 = 72039,
+
+ //Taldaram
+ SPELL_GLITTERING_SPARKS = 71807,
+ SPELL_CONJURE_FLAME_1 = 71718,
+ SPELL_SUMMON_FLAME_1 = 71719, //Dummy effect
+ NPC_BALL_OF_FLAMES_1 = 38332,
+ SPELL_CONJURE_FLAME_2 = 72040,
+ SPELL_SUMMON_FLAME_2 = 72041, //Dummy effect
+ NPC_BALL_OF_FLAMES_2 = 38451,
+ SPELL_FLAMES_AURA = 71709,
+ SPELL_FLAMES = 71393,
+
+ //Keleseth
+ SPELL_SHADOW_LANCE = 71405,
+ SPELL_SHADOW_LANCE_2 = 71815,
+ SPELL_SHADOW_RESONANCE = 71943,
+ SPELL_SHADOW_RESONANCE_AURA = 71822,
+ NPC_DARK_NUCLEUS = 38369,
+
+ // Blood orb
+ SPELL_BLOOD_ORB_STATE_VISUAL = 72100,
+
+};
+
+struct MANGOS_DLL_DECL boss_valanar_iccAI : public BSWScriptedAI
+{
+ boss_valanar_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ Creature* pBrother1;
+ Creature* pBrother2;
+ bool invocated;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ resetTimers();
+ invocated = false;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631302,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631303,m_creature,pVictim);
+ break;
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, FAIL);
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ DoScriptText(-1631304,m_creature,pKiller);
+ if (pBrother1 && pBrother2 && !pBrother1->isAlive() && !pBrother2->isAlive())
+ {
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, DONE);
+ m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pBrother1->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pBrother2->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ else m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance) return;
+ pBrother1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_TALDARAM));
+ pBrother2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_KELESETH));
+ if (pBrother1 && !pBrother1->isAlive()) pBrother1->Respawn();
+ if (pBrother2 && !pBrother2->isAlive()) pBrother2->Respawn();
+ if (pBrother1) pBrother1->SetInCombatWithZone();
+ if (pBrother2) pBrother2->SetInCombatWithZone();
+
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, IN_PROGRESS);
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ doCast(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_T : SPELL_INVOCATION_OF_BLOOD_K);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if(pDoneBy->GetGUID() == m_creature->GetGUID()) return;
+
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetHealth() >= uiDamage ? m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH) - uiDamage : 0);
+
+ uiDamage /=3;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_creature->GetHealth() > m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH)/3 &&
+ m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH) != 0)
+ m_creature->SetHealth(m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH)/3);
+
+ if (hasAura(SPELL_INVOCATION_OF_BLOOD_V))
+ {
+ if (!invocated)
+ {
+ DoScriptText(-1631307,m_creature);
+ invocated = true;
+ }
+ if (timedQuery(SPELL_INVOCATION_OF_BLOOD_V, uiDiff))
+ {
+ if (doCast(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_K : SPELL_INVOCATION_OF_BLOOD_T) == CAST_OK)
+ doRemove(SPELL_INVOCATION_OF_BLOOD_V);
+ }
+ timedCast(SPELL_KINETIC_BOMB, uiDiff);
+ timedCast(SPELL_SHOCK_VORTEX_2, uiDiff);
+ } else
+ {
+ invocated = false;
+
+ timedCast(SPELL_KINETIC_BOMB, uiDiff);
+ timedCast(SPELL_SHOCK_VORTEX, uiDiff);
+ }
+
+ if (timedQuery(SPELL_BERSERK, uiDiff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631305,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_valanar_icc(Creature* pCreature)
+{
+ return new boss_valanar_iccAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL boss_taldaram_iccAI : public BSWScriptedAI
+{
+ boss_taldaram_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ Creature* pBrother1;
+ Creature* pBrother2;
+ bool invocated;
+ uint8 ballscount;
+
+
+ void Reset() {
+ if(!m_pInstance) return;
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ resetTimers();
+ invocated = false;
+ ballscount = 0;
+ }
+
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, FAIL);
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ if (pBrother1 && pBrother2 && !pBrother1->isAlive() && !pBrother2->isAlive())
+ {
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, DONE);
+ m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pBrother1->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pBrother2->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ else m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance) return;
+ pBrother1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VALANAR));
+ pBrother2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_KELESETH));
+ if (pBrother1 && !pBrother1->isAlive()) pBrother1->Respawn();
+ if (pBrother2 && !pBrother2->isAlive()) pBrother2->Respawn();
+ if (pBrother1) pBrother1->SetInCombatWithZone();
+ if (pBrother2) pBrother2->SetInCombatWithZone();
+
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, IN_PROGRESS);
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if(pDoneBy->GetGUID() == m_creature->GetGUID()) return;
+
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetHealth() >= uiDamage ? m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH) - uiDamage : 0);
+
+ uiDamage /=3;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_creature->GetHealth() > m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH)/3 &&
+ m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH) != 0)
+ m_creature->SetHealth(m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH)/3);
+
+ if (hasAura(SPELL_INVOCATION_OF_BLOOD_T))
+ {
+ if (!invocated)
+ {
+ DoScriptText(-1631307,m_creature);
+ invocated = true;
+ }
+ if (timedQuery(SPELL_INVOCATION_OF_BLOOD_T, uiDiff))
+ {
+ if (doCast(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_V : SPELL_INVOCATION_OF_BLOOD_K) == CAST_OK)
+ doRemove(SPELL_INVOCATION_OF_BLOOD_T);
+ }
+ if (ballscount > 0 && !m_creature->IsNonMeleeSpellCasted(false))
+ {
+ doCast(SPELL_SUMMON_FLAME_2);
+ --ballscount;
+ };
+ timedCast(SPELL_GLITTERING_SPARKS, uiDiff);
+ if (timedCast(SPELL_CONJURE_FLAME_2, uiDiff) == CAST_OK) ballscount = 1;
+ } else
+ {
+ invocated = false;
+ if (ballscount > 0 && !m_creature->IsNonMeleeSpellCasted(false))
+ {
+ doCast(SPELL_SUMMON_FLAME_1);
+ --ballscount;
+ };
+ timedCast(SPELL_GLITTERING_SPARKS, uiDiff);
+ if (timedCast(SPELL_CONJURE_FLAME_1, uiDiff) == CAST_OK) ballscount = 1;
+ }
+
+
+ if (timedQuery(SPELL_BERSERK, uiDiff)){
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631305,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_taldaram_icc(Creature* pCreature)
+{
+ return new boss_taldaram_iccAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL boss_keleseth_iccAI : public BSWScriptedAI
+{
+ boss_keleseth_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ Creature* pBrother1;
+ Creature* pBrother2;
+ bool invocated;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ resetTimers();
+ invocated = false;
+ }
+
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, FAIL);
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance) return;
+ if (pBrother1 && pBrother2 && !pBrother1->isAlive() && !pBrother2->isAlive())
+ {
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, DONE);
+ m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pBrother1->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pBrother2->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ else m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (!m_pInstance) return;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance) return;
+ pBrother1 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_TALDARAM));
+ pBrother2 = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_VALANAR));
+ if (pBrother1 && !pBrother1->isAlive()) pBrother1->Respawn();
+ if (pBrother2 && !pBrother2->isAlive()) pBrother2->Respawn();
+ if (pBrother1) pBrother1->SetInCombatWithZone();
+ if (pBrother2) pBrother2->SetInCombatWithZone();
+
+ m_pInstance->SetData(TYPE_BLOOD_COUNCIL, IN_PROGRESS);
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetMaxHealth()*3);
+ DoStartMovement(pWho, 30.0f);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if(pDoneBy->GetGUID() == m_creature->GetGUID()) return;
+
+ m_pInstance->SetData(DATA_BLOOD_COUNCIL_HEALTH, m_creature->GetHealth() >= uiDamage ? m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH) - uiDamage : 0);
+
+ uiDamage /=3;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) return;
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_creature->GetHealth() > m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH)/3 &&
+ m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH) != 0)
+ m_creature->SetHealth(m_pInstance->GetData(DATA_BLOOD_COUNCIL_HEALTH)/3);
+
+ if (hasAura(SPELL_INVOCATION_OF_BLOOD_K))
+ {
+ if (!invocated)
+ {
+ DoScriptText(-1631307,m_creature);
+ invocated = true;
+ };
+
+ if (timedQuery(SPELL_INVOCATION_OF_BLOOD_K, uiDiff))
+ {
+ if (doCast(urand(0,1) ? SPELL_INVOCATION_OF_BLOOD_V : SPELL_INVOCATION_OF_BLOOD_T) == CAST_OK)
+ doRemove(SPELL_INVOCATION_OF_BLOOD_K);
+ }
+
+ timedCast(SPELL_SHADOW_LANCE_2, uiDiff);
+ timedCast(SPELL_SHADOW_RESONANCE, uiDiff);
+ } else
+ {
+ invocated = false;
+ timedCast(SPELL_SHADOW_LANCE, uiDiff);
+ timedCast(SPELL_SHADOW_RESONANCE, uiDiff);
+ }
+
+
+ if (timedQuery(SPELL_BERSERK, uiDiff)){
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631305,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_keleseth_icc(Creature* pCreature)
+{
+ return new boss_keleseth_iccAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_dark_nucleusAI : public ScriptedAI
+{
+ mob_dark_nucleusAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_lifetimer;
+ uint32 m_casttimer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetInCombatWithZone();
+ m_lifetimer = 180000;
+ m_casttimer = 2000;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!m_pInstance) return;
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5);
+ SetCombatMovement(true);
+ DoStartMovement(pWho);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_casttimer <= uiDiff)
+ {
+ if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_RESONANCE_AURA) == CAST_OK)
+ m_lifetimer -= 4000;
+
+ m_casttimer = 2000;
+ } else m_casttimer -= uiDiff;
+
+ if (m_lifetimer <= uiDiff)
+ m_creature->ForcedDespawn();
+ else m_lifetimer -= uiDiff;
+
+ }
+};
+
+CreatureAI* GetAI_mob_dark_nucleus(Creature* pCreature)
+{
+ return new mob_dark_nucleusAI (pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_ball_of_flamesAI : public ScriptedAI
+{
+ mob_ball_of_flamesAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 grow_timer;
+ float fPosX, fPosY, fPosZ;
+ float m_Size;
+ float m_Size0;
+ bool finita;
+ bool movementstarted;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetInCombatWithZone();
+ finita = false;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ SetCombatMovement(false);
+ m_creature->GetPosition(fPosX, fPosY, fPosZ);
+ m_creature->GetRandomPoint(fPosX, fPosY, fPosZ, urand(40, 60), fPosX, fPosY, fPosZ);
+ m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ);
+ movementstarted = true;
+ m_Size0 = m_creature->GetObjectScale();
+ m_Size = m_Size0;
+ grow_timer = 500;
+
+ m_creature->SetDisplayId(26767);
+// if (m_creature->GetEntry() == NPC_BALL_OF_FLAMES_2)
+ DoCast(m_creature, SPELL_FLAMES_AURA);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (!m_pInstance || type != POINT_MOTION_TYPE) return;
+ if (id != 1)
+ m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ);
+ else movementstarted = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS || finita)
+ m_creature->ForcedDespawn();
+
+ if (!movementstarted)
+ {
+ DoCast(m_creature, SPELL_FLAMES);
+ finita = true;
+ return;
+ }
+
+ if (m_creature->GetEntry() == NPC_BALL_OF_FLAMES_2)
+ {
+ if (!m_creature->HasAura(SPELL_FLAMES_AURA))
+ DoCast(m_creature, SPELL_FLAMES_AURA);
+
+
+ if (grow_timer <= uiDiff)
+ {
+ m_Size = m_Size*1.03;
+ m_creature->SetObjectScale(m_Size);
+ grow_timer = 500;
+ } else grow_timer -= uiDiff;
+ } else return;
+
+ }
+};
+
+CreatureAI* GetAI_mob_ball_of_flames(Creature* pCreature)
+{
+ return new mob_ball_of_flamesAI (pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_kinetic_bombAI : public ScriptedAI
+{
+ mob_kinetic_bombAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_lifetimer;
+ float fPosX0, fPosY0, fPosZ0;
+ float fPosX1, fPosY1, fPosZ1;
+ bool finita;
+ Creature *owner;
+
+ void Reset()
+ {
+ owner = m_creature->GetMap()->GetCreature(m_creature->GetCreatorGuid());
+
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetInCombatWithZone();
+
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.2f);
+ m_creature->SetSpeedRate(MOVE_WALK, 0.2f);
+ SetCombatMovement(false);
+
+ m_lifetimer = 60000;
+// m_creature->SetDisplayId(31095);
+
+ m_creature->GetPosition(fPosX0, fPosY0, fPosZ0);
+
+ if (!owner) return;
+ owner->GetPosition(fPosX1, fPosY1, fPosZ1);
+
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(1, fPosX1, fPosY1, fPosZ1);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE) return;
+ if ( id ==1 )
+ {
+ finita = true;
+ DoCast(m_creature, SPELL_KINETIC_BOMB_EXPLODE);
+ }
+ else m_creature->GetMotionMaster()->MovePoint(1, fPosX1, fPosY1, fPosZ1);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+/*
+Place shock bomb movement here
+*/
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS || finita)
+ m_creature->ForcedDespawn();
+
+ }
+};
+
+CreatureAI* GetAI_mob_kinetic_bomb(Creature* pCreature)
+{
+ return new mob_kinetic_bombAI (pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_shock_vortexAI : public ScriptedAI
+{
+ mob_shock_vortexAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_lifetimer;
+ bool finita;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetInCombatWithZone();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_lifetimer = 8000;
+ SetCombatMovement(false);
+ DoCast(m_creature, SPELL_SHOCK_VORTEX_AURA);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS || finita)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->HasAura(SPELL_SHOCK_VORTEX_AURA))
+ DoCast(m_creature, SPELL_SHOCK_VORTEX_AURA);
+
+ if (m_lifetimer <= uiDiff)
+ finita = true;
+ else m_lifetimer -= uiDiff;
+
+ }
+};
+
+CreatureAI* GetAI_mob_shock_vortex(Creature* pCreature)
+{
+ return new mob_shock_vortexAI (pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_kinetic_bomb_targetAI : public ScriptedAI
+{
+ mob_kinetic_bomb_targetAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ Creature* bomb;
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(21342);
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ SetCombatMovement(false);
+ bomb = NULL;
+ }
+
+ void SummonedCreatureJustDied(Creature* summoned)
+ {
+ if (!m_pInstance || !summoned) return;
+
+ if (summoned == bomb)
+ m_creature->ForcedDespawn();
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_BLOOD_COUNCIL) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!bomb)
+ bomb = m_creature->SummonCreature(NPC_KINETIC_BOMB,m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()+50.0f,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,60000);
+
+ }
+};
+
+CreatureAI* GetAI_mob_kinetic_bomb_target(Creature* pCreature)
+{
+ return new mob_kinetic_bomb_targetAI (pCreature);
+};
+
+struct MANGOS_DLL_DECL boss_blood_queen_lanathel_introAI : public BSWScriptedAI
+{
+ boss_blood_queen_lanathel_introAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 UpdateTimer;
+
+ void Reset()
+ {
+ if(!pInstance)
+ return;
+
+ if (pInstance->GetData(TYPE_BLOOD_COUNCIL) == IN_PROGRESS)
+ return;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (pInstance->GetData(TYPE_BLOOD_COUNCIL) == DONE)
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+ else
+ {
+ if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_TALDARAM)))
+ doCast(SPELL_FAKE_DEATH,pPrince);
+ if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_KELESETH)))
+ doCast(SPELL_FAKE_DEATH,pPrince);
+ if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALANAR)))
+ doCast(SPELL_FAKE_DEATH,pPrince);
+ pInstance->SetData(TYPE_BLOOD_COUNCIL, NOT_STARTED);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetVisibility(VISIBILITY_ON);
+ }
+ }
+
+ void AttackStart(Unit *who)
+ {
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pInstance)
+ return;
+
+ if (pInstance->GetData(TYPE_BLOOD_COUNCIL) != NOT_STARTED)
+ return;
+
+ if (pWho && pWho->GetTypeId() == TYPEID_PLAYER && pWho->IsWithinDistInMap(m_creature, 50.0f))
+ {
+ pInstance->SetData(TYPE_EVENT, 800);
+ pInstance->SetData(TYPE_BLOOD_COUNCIL,IN_PROGRESS);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (pInstance->GetData(TYPE_BLOOD_COUNCIL) == FAIL)
+ {
+ Reset();
+ return;
+ }
+
+ if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_LANATHEL_INTRO)
+ {
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+ if (UpdateTimer <= diff)
+ {
+ debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT));
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 800:
+ DoScriptText(-1631301, m_creature);
+ UpdateTimer = 15000;
+ pInstance->SetData(TYPE_EVENT,810);
+ break;
+ case 810:
+ DoScriptText(-1631311, m_creature);
+ if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_TALDARAM)))
+ {
+ doRemove(SPELL_FAKE_DEATH,pPrince);
+ }
+ if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_KELESETH)))
+ {
+ doRemove(SPELL_FAKE_DEATH,pPrince);
+ }
+ if (Creature* pPrince = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALANAR)))
+ {
+ doRemove(SPELL_FAKE_DEATH,pPrince);
+ }
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,820);
+ break;
+ case 820:
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,830);
+ break;
+ default:
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+ }
+
+ }
+};
+
+CreatureAI* GetAI_boss_blood_queen_lanathel_intro(Creature* pCreature)
+{
+ return new boss_blood_queen_lanathel_introAI(pCreature);
+}
+
+void AddSC_blood_prince_council()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_taldaram_icc";
+ newscript->GetAI = &GetAI_boss_taldaram_icc;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_keleseth_icc";
+ newscript->GetAI = &GetAI_boss_keleseth_icc;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_valanar_icc";
+ newscript->GetAI = &GetAI_boss_valanar_icc;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_nucleus";
+ newscript->GetAI = &GetAI_mob_dark_nucleus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ball_of_flames";
+ newscript->GetAI = &GetAI_mob_ball_of_flames;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_kinetic_bomb";
+ newscript->GetAI = &GetAI_mob_kinetic_bomb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_shock_vortex";
+ newscript->GetAI = &GetAI_mob_shock_vortex;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_kinetic_bomb_target";
+ newscript->GetAI = &GetAI_mob_kinetic_bomb_target;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_blood_queen_lanathel_intro";
+ newscript->GetAI = &GetAI_boss_blood_queen_lanathel_intro;
+ newscript->RegisterSelf();
+
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_blood_queen_lanathel.cpp
index ce11b79..867d6f2 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
@@ -16,9 +16,425 @@
/* ScriptData
SDName: boss_blood_queen_lanathel
-SD%Complete: 0%
-SDComment:
+SD%Complete: 70%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need correct work of spells and timers
#include "precompiled.h"
+#include "def_spire.h"
+
+enum BossSpells
+{
+ SPELL_BERSERK = 47008,
+ SPELL_SHROUD_OF_SORROW = 72981,
+ SPELL_DELRIOUS_SLASH = 71623,
+ SPELL_BLOOD_MIRROR_1 = 70821,
+ SPELL_BLOOD_MIRROR_2 = 71510,
+ SPELL_VAMPIRIC_BITE = 71726,
+ SPELL_ESSENCE_OF_BLOOD_QWEEN = 70867,
+ SPELL_FRENZIED_BLOODTHIRST = 70877,
+ SPELL_UNCONTROLLABLE_FRENZY = 70923,
+ SPELL_PACT_OF_DARKFALLEN = 71340,
+ SPELL_PACT_OF_DARKFALLEN_1 = 71341,
+ SPELL_SWARMING_SHADOWS = 71264,
+ SPELL_TWILIGHT_BLOODBOLT = 71446,
+ SPELL_BLOODBOLT_WHIRL = 71772,
+ SPELL_PRESENCE_OF_DARKFALLEN = 71952,
+
+ NPC_SWARMING_SHADOWS = 38163,
+ SPELL_SWARMING_SHADOWS_VISUAL = 71267,
+ QUEST_24756 = 72934,
+};
+
+static Locations SpawnLoc[]=
+{
+ {4595.640137f, 2769.195557f, 400.137054f}, // 0 Phased
+ {4595.904785f, 2769.315918f, 421.838623f}, // 1 Fly
+};
+
+
+struct MANGOS_DLL_DECL boss_blood_queen_lanathelAI : public BSWScriptedAI
+{
+ boss_blood_queen_lanathelAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+ uint8 nextPoint;
+ uint8 bloodbolts;
+ uint32 UpdateTimer;
+ bool movementstarted;
+ Unit* MirrorMarked;
+ Unit* MirrorTarget;
+ Unit* Darkfallen[5];
+ uint8 darkfallened;
+ uint32 MirrorDamage;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ if (m_creature->isAlive()) pInstance->SetData(TYPE_LANATHEL, NOT_STARTED);
+ stage = 0;
+ UpdateTimer = 1000;
+ bloodbolts = 0;
+ movementstarted = false;
+ MirrorMarked = NULL;
+ MirrorTarget = NULL;
+ resetTimers();
+ memset(&Darkfallen, 0, sizeof(Darkfallen));
+ darkfallened = 0;
+ MirrorDamage = 0;
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance) pInstance->SetData(TYPE_LANATHEL, FAIL);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631330,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631331,m_creature,pVictim);
+ break;
+ }
+
+ if (pVictim && pVictim->HasAura(SPELL_BLOOD_MIRROR_1))
+ doRemove(SPELL_BLOOD_MIRROR_1,pVictim);
+
+ if (pVictim && pVictim->HasAura(SPELL_BLOOD_MIRROR_2))
+ doRemove(SPELL_BLOOD_MIRROR_2,pVictim);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || !movementstarted) return;
+ if (id == nextPoint)
+ {
+ movementstarted = false;
+ m_creature->GetMotionMaster()->MovementExpired();
+ }
+ }
+
+ void StartMovement(uint32 id)
+ {
+ nextPoint = id;
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
+ movementstarted = true;
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_LANATHEL, IN_PROGRESS);
+
+ doCast(SPELL_SHROUD_OF_SORROW);
+
+ DoScriptText(-1631321,m_creature,who);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+ doBloodMirror(false);
+ pInstance->SetData(TYPE_LANATHEL, DONE);
+ DoScriptText(-1631333,m_creature,killer);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ for (uint8 i = 0; i < 5; ++i)
+ {
+ if (Unit* pPlayer = doSelectRandomPlayer(SPELL_ESSENCE_OF_BLOOD_QWEEN, true, 100.0f))
+ {
+ doCast(QUEST_24756, pPlayer);
+ doRemove(SPELL_ESSENCE_OF_BLOOD_QWEEN, pPlayer);
+ }
+ }
+ }
+
+ void doPactOfDarkfallen(bool command)
+ {
+ if (command)
+ {
+ uint8 num = urand(3,5);
+ for(uint8 i = 0; i <= num; ++i)
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_PACT_OF_DARKFALLEN, false, 60.0f))
+ {
+ if (doCast(SPELL_PACT_OF_DARKFALLEN,pTarget) == CAST_OK)
+ {
+ Darkfallen[i] = pTarget;
+ ++darkfallened;
+ };
+ };
+ }
+ else if (darkfallened > 0)
+ {
+ for(uint8 i = 0; i < darkfallened; ++i)
+ if (Darkfallen[i])
+ {
+ if (hasAura(SPELL_PACT_OF_DARKFALLEN,Darkfallen[i]))
+ {
+ for(uint8 j = 0; j < darkfallened; ++j)
+ if (j != i && Darkfallen[j])
+ {
+ if(Darkfallen[j])
+ {
+ if (hasAura(SPELL_PACT_OF_DARKFALLEN,Darkfallen[j]))
+ {
+ if (!Darkfallen[j]->IsWithinDistInMap(Darkfallen[i], 5.0f)) return;
+ } else Darkfallen[j] = NULL;
+ }
+ }
+ } else Darkfallen[i] = NULL;
+ }
+ for(uint8 i = 0; i < darkfallened; ++i)
+ if (hasAura(SPELL_PACT_OF_DARKFALLEN,Darkfallen[i]))
+ doRemove(SPELL_PACT_OF_DARKFALLEN, Darkfallen[i]);
+ darkfallened = 0;
+ };
+ }
+
+ void doBloodMirror(bool command)
+ {
+ if (command)
+ {
+ if (MirrorMarked)
+ if (!hasAura(SPELL_BLOOD_MIRROR_1,MirrorMarked))
+ MirrorMarked = NULL;
+
+ if (MirrorTarget)
+ if (!hasAura(SPELL_BLOOD_MIRROR_2,MirrorTarget))
+ MirrorTarget = NULL;
+
+ if (!MirrorMarked && m_creature->getVictim())
+ {
+ MirrorMarked = m_creature->getVictim();
+ if (MirrorMarked)
+ doCast(SPELL_BLOOD_MIRROR_1, MirrorMarked);
+ }
+
+ if (!MirrorTarget)
+ {
+ MirrorTarget = doSelectRandomPlayer(SPELL_BLOOD_MIRROR_1, false, 40.0f);
+ if (MirrorTarget)
+ doCast(SPELL_BLOOD_MIRROR_2, MirrorTarget);
+ }
+ } else
+ {
+ if (MirrorMarked)
+ if (hasAura(SPELL_BLOOD_MIRROR_1,MirrorMarked))
+ {
+ doRemove(SPELL_BLOOD_MIRROR_1, MirrorMarked);
+ MirrorMarked = NULL;
+ }
+
+ if (MirrorTarget)
+ if (hasAura(SPELL_BLOOD_MIRROR_2,MirrorTarget))
+ {
+ doRemove(SPELL_BLOOD_MIRROR_2, MirrorTarget);
+ MirrorTarget = NULL;
+ }
+ }
+
+ }
+
+ void doMirrorDamage()
+ {
+ uint32 tempdamage = MirrorDamage;
+
+ if (MirrorTarget)
+ if (MirrorTarget->isAlive())
+ m_creature->DealDamage(MirrorTarget, tempdamage, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false);
+ MirrorDamage -= tempdamage;
+ }
+
+ void DamageDeal(Unit* target, uint32 &damage)
+ {
+ if (target)
+ if (MirrorMarked)
+ if (MirrorMarked->isAlive())
+ if (target == MirrorMarked)
+ MirrorDamage += damage;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(stage)
+ {
+ case 0:
+
+ timedCast(SPELL_SWARMING_SHADOWS, diff);
+
+ if (timedQuery(SPELL_TWILIGHT_BLOODBOLT, diff)) bloodbolts = 1;
+
+ if (timedQuery(SPELL_DELRIOUS_SLASH, diff))
+ if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
+ doCast(SPELL_DELRIOUS_SLASH, pTarget);
+
+ if (timedQuery(SPELL_PACT_OF_DARKFALLEN, diff))
+ doPactOfDarkfallen(true);
+
+ timedCast(SPELL_SWARMING_SHADOWS, diff);
+
+ if (timedQuery(SPELL_VAMPIRIC_BITE,diff))
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631322,m_creature);
+ break;
+ case 1:
+ DoScriptText(-1631323,m_creature);
+ break;
+ }
+ doCast(SPELL_VAMPIRIC_BITE);
+ }
+
+ if (timedQuery(SPELL_BLOODBOLT_WHIRL,diff) && m_creature->GetHealthPercent() > 10.0f)
+ {
+ stage = 1;
+ };
+
+ doBloodMirror(true);
+
+ DoMeleeAttackIfReady();
+
+ break;
+ case 1: // Go in fly phase
+ m_creature->AttackStop();
+ SetCombatMovement(false);
+ StartMovement(1);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ doBloodMirror(false);
+ stage = 2;
+ break;
+ case 2:
+ if (movementstarted) return;
+ DoScriptText(-1631327,m_creature);
+ doCast(SPELL_BLOODBOLT_WHIRL);
+ stage = 3;
+ return;
+ case 3:
+ if (m_creature->IsNonMeleeSpellCasted(false))
+ return;
+ if (timedQuery(SPELL_TWILIGHT_BLOODBOLT,diff) || m_creature->GetHealthPercent() < 10.0f)
+ {
+ stage = 4;
+// DoScriptText(-1631325,m_creature);
+ bloodbolts = 3;
+ };
+ break;
+ case 4: // Go in grownd phase
+ m_creature->AttackStop();
+ StartMovement(0);
+ stage = 5;
+ break;
+ case 5:
+ if (movementstarted) return;
+ DoScriptText(-1631325,m_creature);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING);
+ stage = 0;
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ return;
+ default:
+ break;
+ }
+
+ doPactOfDarkfallen(false);
+
+ doMirrorDamage();
+
+ if (bloodbolts > 0)
+ {
+ doCast(SPELL_TWILIGHT_BLOODBOLT);
+ --bloodbolts;
+ };
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631332,m_creature);
+ };
+
+ }
+};
+
+
+CreatureAI* GetAI_boss_blood_queen_lanathel(Creature* pCreature)
+{
+ return new boss_blood_queen_lanathelAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_swarming_shadowsAI : public ScriptedAI
+{
+ mob_swarming_shadowsAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_lifetimer;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(11686);
+ m_creature->SetRespawnDelay(7*DAY);
+ SetCombatMovement(false);
+ m_creature->SetInCombatWithZone();
+ m_lifetimer = 10000;
+ DoCast(m_creature, SPELL_SWARMING_SHADOWS_VISUAL);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_LANATHEL) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->HasAura(SPELL_SWARMING_SHADOWS_VISUAL))
+ DoCast(m_creature, SPELL_SWARMING_SHADOWS_VISUAL);
+
+ if (m_lifetimer <= uiDiff)
+ m_creature->ForcedDespawn();
+ else m_lifetimer -= uiDiff;
+
+ }
+};
+
+CreatureAI* GetAI_mob_swarming_shadows(Creature* pCreature)
+{
+ return new mob_swarming_shadowsAI (pCreature);
+}
+
+
+void AddSC_boss_blood_queen_lanathel()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_blood_queen_lanathel";
+ newscript->GetAI = &GetAI_boss_blood_queen_lanathel;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_swarming_shadows";
+ newscript->GetAI = &GetAI_mob_swarming_shadows;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp
index 2ebf1be..6467439 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_deathbringer_saurfang.cpp
@@ -16,9 +16,297 @@
/* ScriptData
SDName: boss_deathbringer_saurfang
-SD%Complete: 0%
-SDComment:
+SD%Complete: 75%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
#include "precompiled.h"
+#include "def_spire.h"
+
+enum
+{
+ //common
+ SPELL_BERSERK = 47008,
+ //yells
+ //summons
+ NPC_BLOOD_BEASTS = 38508,
+ //Abilities
+ SPELL_BLOOD_LINK = 72178,
+ SPELL_BLOOD_POWER = 72371,
+ SPELL_MARK = 72293,
+ SPELL_MARK_SELF = 72256,
+ SPELL_FRENZY = 72737,
+ SPELL_BOILING_BLOOD = 72385,
+ SPELL_BLOOD_NOVA = 72380,
+ SPELL_RUNE_OF_BLOOD = 72408,
+ SPELL_CALL_BLOOD_BEAST_1 = 72172,
+ SPELL_CALL_BLOOD_BEAST_2 = 72173,
+ SPELL_CALL_BLOOD_BEAST_3 = 72356,
+ SPELL_CALL_BLOOD_BEAST_4 = 72357,
+ SPELL_CALL_BLOOD_BEAST_5 = 72358,
+
+ SPELL_SCENT_OF_BLOOD = 72769,
+ SPELL_RESISTANT_SKIN = 72723,
+ SPELL_BLOOD_LINK_BEAST = 72176,
+
+ SPELL_ZERO_REGEN = 72242,
+
+};
+
+enum Equipment
+{
+ EQUIP_MAIN = 50798,
+ EQUIP_OFFHAND = 50798,
+ EQUIP_RANGED = EQUIP_NO_CHANGE,
+ EQUIP_DONE = EQUIP_NO_CHANGE,
+};
+
+struct MANGOS_DLL_DECL boss_deathbringer_saurfangAI : public BSWScriptedAI
+{
+ boss_deathbringer_saurfangAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 beasts;
+ int32 oldPower;
+
+ void Reset()
+ {
+ if(!pInstance)
+ return;
+ m_creature->SetRespawnDelay(7*DAY);
+ if (m_creature->isAlive())
+ pInstance->SetData(TYPE_SAURFANG, NOT_STARTED);
+ setStage(0);
+ beasts = 0;
+ resetTimers();
+ m_creature->SetPower(m_creature->getPowerType(), 0);
+ doCast(SPELL_ZERO_REGEN);
+ oldPower = 0;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pInstance) return;
+
+ if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER) return;
+
+ if (!m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 20.0f))
+ {
+ m_creature->setFaction(21);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
+ AttackStart(pWho);
+ }
+
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance)
+ return;
+
+ pInstance->SetData(TYPE_SAURFANG, IN_PROGRESS);
+ SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
+ DoScriptText(-1631100,m_creature);
+ doCast(SPELL_BLOOD_LINK);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance)
+ pInstance->SetData(TYPE_SAURFANG, FAIL);
+ }
+
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1))
+ {
+ case 0:
+ DoScriptText(-1631103,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631104,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned)
+ return;
+
+ summoned->SetOwnerGuid(m_creature->GetObjectGuid());
+
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) )
+ {
+ summoned->AddThreat(pTarget, 100.0f);
+ summoned->GetMotionMaster()->MoveChase(pTarget);
+ }
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance)
+ return;
+ pInstance->SetData(TYPE_SAURFANG, DONE);
+ DoScriptText(-1631106,m_creature);
+ doRemoveFromAll(SPELL_MARK);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (!m_creature->HasAura(SPELL_BLOOD_POWER))
+ doCast(SPELL_BLOOD_POWER);
+
+ if (!m_creature->HasAura(SPELL_BLOOD_LINK))
+ doCast(SPELL_BLOOD_LINK);
+
+ if (!m_creature->HasAura(SPELL_MARK_SELF))
+ doCast(SPELL_MARK_SELF);
+
+ switch(getStage())
+ {
+ case 0:
+ if (m_creature->GetHealthPercent() <= 30.0f) setStage(1);
+ break;
+
+ case 1:
+ doCast(SPELL_FRENZY);
+ setStage(2);
+ DoScriptText(-1631101,m_creature);
+ break;
+
+ case 2:
+ break;
+
+ default:
+ break;
+ }
+
+ if (timedQuery(SPELL_MARK, diff))
+ {
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_MARK,false,120.0f))
+ doCast(SPELL_MARK, pTarget);
+ }
+
+ timedCast(SPELL_BLOOD_NOVA, diff);
+
+ timedCast(SPELL_BOILING_BLOOD, diff);
+
+ timedCast(SPELL_RUNE_OF_BLOOD, diff);
+
+ if (timedQuery(SPELL_CALL_BLOOD_BEAST_1, diff))
+ {
+ beasts = getSpellData(SPELL_CALL_BLOOD_BEAST_1);
+ DoScriptText(-1631102,m_creature);
+ };
+
+ if (beasts > 0)
+ {
+ CanCastResult res = CAST_FAIL_OTHER;
+ switch (beasts)
+ {
+ case 1: res = doCast(SPELL_CALL_BLOOD_BEAST_1); break;
+ case 2: res = doCast(SPELL_CALL_BLOOD_BEAST_2); break;
+ case 3: res = doCast(SPELL_CALL_BLOOD_BEAST_3); break;
+ case 4: res = doCast(SPELL_CALL_BLOOD_BEAST_4); break;
+ case 5: res = doCast(SPELL_CALL_BLOOD_BEAST_5); break;
+ default: break;
+ };
+
+ if ( res == CAST_OK)
+ {
+ --beasts;
+ };
+ };
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631108,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_deathbringer_saurfang(Creature* pCreature)
+{
+ return new boss_deathbringer_saurfangAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_blood_beastAI : public BSWScriptedAI
+{
+ mob_blood_beastAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ Creature* pOwner;
+ bool scentcasted;
+
+ void Reset()
+ {
+ pOwner = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_DEATHBRINGER_SAURFANG));
+ resetTimers();
+ scentcasted = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_SAURFANG) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (!m_creature->HasAura(SPELL_BLOOD_LINK_BEAST))
+ doCast(SPELL_BLOOD_LINK_BEAST);
+
+ if (!m_creature->HasAura(SPELL_RESISTANT_SKIN))
+ doCast(SPELL_RESISTANT_SKIN);
+
+ if (!scentcasted && (m_creature->GetHealthPercent() <= 20.0f))
+ {
+ if (urand(0,1)) //50%
+ doCast(SPELL_SCENT_OF_BLOOD);
+ scentcasted = true;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_blood_beast(Creature* pCreature)
+{
+ return new mob_blood_beastAI(pCreature);
+}
+
+void AddSC_boss_deathbringer_saurfang()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_deathbringer_saurfang";
+ newscript->GetAI = &GetAI_boss_deathbringer_saurfang;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_blood_beast";
+ newscript->GetAI = &GetAI_mob_blood_beast;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
index 1156afd..ec4e05c 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
@@ -16,9 +16,457 @@
/* ScriptData
SDName: boss_festergut
-SD%Complete: 0%
-SDComment:
+SD%Complete: 90%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need correct timers
#include "precompiled.h"
+#include "def_spire.h"
+
+enum BossSpells
+{
+ SPELL_GASEOUS_BLIGHT_1 = 69157,
+ SPELL_GASEOUS_BLIGHT_2 = 69162,
+ SPELL_GASEOUS_BLIGHT_3 = 69164,
+ SPELL_BLIGHT_VISUAL_1 = 69126,
+ SPELL_BLIGHT_VISUAL_2 = 69152,
+ SPELL_BLIGHT_VISUAL_3 = 69154,
+ SPELL_INHALE_BLIGHT = 69165,
+ SPELL_INHALED_BLIGHT = 69166,
+ SPELL_PUNGENT_BLIGHT = 69195,
+ SPELL_GAS_SPORE = 69278,
+ SPELL_SPORE_AURA_0 = 69279,
+ SPELL_SPORE_AURA_1 = 69290,
+ SPELL_INOCULATE = 69291,
+ SPELL_REMOVE_UNOCULATE = 69298,
+ SPELL_GASTRIC_BLOAT = 72219,
+ SPELL_GASTRIC_EXPLOSION = 72227,
+ SPELL_VILE_GAS = 72272,
+ SPELL_VILE_GAS_AURA = 69244,
+ SPELL_VILE_GAS_AURA_0 = 69248,
+ SPELL_BERSERK = 47008,
+
+ SPELL_GASEOUS_SPIGOT = 71379,
+
+ SPELL_SUMMON_VILE_STALKER = 72287,
+
+ NPC_VILE_GAS_STALKER = 38548,
+ NPC_BLIGHT_STALKER = 36659,
+ NPC_PUDDLE_STALKER = 37013,
+ MAX_SPORE_TARGETS = 6,
+};
+
+static Locations SpawnLoc[]=
+{
+ {4267.9399f, 3137.32f, 360.385986f, 0.0f}, // 0 (start point)
+ {4317.067383f, 3136.99f, 360.385590f, 3.21f}, // 1 right
+ {4220.801758f, 3136.99f, 360.385590f, 0.39f}, // 2 left
+ {4269.084473f, 3186.306641f, 360.385590f, 4.72f}, // 3 rear
+};
+struct MANGOS_DLL_DECL boss_festergutAI : public BSWScriptedAI
+{
+ boss_festergutAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool intro;
+ bool pet;
+ uint64 blightTargetGUID;
+// uint64 pPuddleStalkerGUID[3];
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ resetTimers();
+ if (m_creature->isAlive())
+ pInstance->SetData(TYPE_FESTERGUT, NOT_STARTED);
+ setStage(0);
+ intro = false;
+ pet = false;
+/* for(uint8 i = 0; i < 3; ++i)
+ if (!pPuddleStalkerGUID[i])
+ {
+ Unit* pTemp = doSummon(NPC_PUDDLE_STALKER,SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z, TEMPSUMMON_MANUAL_DESPAWN);
+ if (pTemp)
+ {
+ pPuddleStalkerGUID[i] = pTemp->GetGUID();
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+ }
+*/
+ Creature* pBlightTarget = doSelectNearestCreature(NPC_BLIGHT_STALKER,60.0f);
+ if (pBlightTarget && !pBlightTarget->isAlive())
+ pBlightTarget->Respawn();
+ if (pBlightTarget)
+ {
+ blightTargetGUID = pBlightTarget->GetGUID();
+ pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget);
+ doCast(SPELL_BLIGHT_VISUAL_2,pBlightTarget);
+ doCast(SPELL_BLIGHT_VISUAL_3,pBlightTarget);
+ }
+
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ ScriptedAI::MoveInLineOfSight(pWho);
+ if(!pInstance || intro) return;
+ if (pWho->GetTypeId() != TYPEID_PLAYER) return;
+
+ pInstance->SetData(TYPE_EVENT, 500);
+ debug_log("EventMGR: creature %u send signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT));
+ intro = true;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631204,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631205,m_creature,pVictim);
+ break;
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance) return;
+ pInstance->SetData(TYPE_FESTERGUT, FAIL);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_1);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_3);
+ if (Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID))
+ {
+ doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget);
+ }
+ }
+
+ void Aggro(Unit *pWho)
+ {
+ if(!pInstance) return;
+ if (pWho->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID);
+
+ pInstance->SetData(TYPE_FESTERGUT, IN_PROGRESS);
+ DoScriptText(-1631203,m_creature,pWho);
+ if (pBlightTarget && !pBlightTarget->isAlive())
+ pBlightTarget->Respawn();
+ if (pBlightTarget)
+ {
+ pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pBlightTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ doRemove(SPELL_BLIGHT_VISUAL_1,pBlightTarget);
+ doRemove(SPELL_BLIGHT_VISUAL_2,pBlightTarget);
+ doRemove(SPELL_BLIGHT_VISUAL_3,pBlightTarget);
+ doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget);
+ }
+ doCast(SPELL_GASEOUS_BLIGHT_1);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_3);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_1);
+/* for(uint8 i = 0; i < 3; ++i)
+ if (pPuddleStalkerGUID[i])
+ doCast(SPELL_GASEOUS_SPIGOT, m_creature->GetMap()->GetCreature(pPuddleStalkerGUID[i]));
+*/
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (!pInstance) return;
+ pInstance->SetData(TYPE_FESTERGUT, DONE);
+ pInstance->SetData(TYPE_EVENT, 550);
+ DoScriptText(-1631206,m_creature);
+ Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_1);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_3);
+ if (pBlightTarget)
+ {
+ doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget);
+ }
+/* for(uint8 i = 0; i < 3; ++i)
+ if (pPuddleStalkerGUID[i])
+ {
+ Creature* pTemp = m_creature->GetMap()->GetCreature(pPuddleStalkerGUID[i]);
+ if (pTemp) pTemp->ForcedDespawn();
+ pPuddleStalkerGUID[i] = NULL;
+ }
+*/
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if(!pInstance) return;
+
+ if (!pet)
+ {
+ if (Creature* pGuard = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_STINKY)))
+ if (!pGuard->isAlive())
+ {
+ pet = true;
+ if (pInstance->GetData(TYPE_STINKY) == NOT_STARTED)
+ {
+ DoScriptText(-1631209,m_creature);
+ pInstance->SetData(TYPE_STINKY,DONE);
+ }
+ }
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ Creature* pBlightTarget = m_creature->GetMap()->GetCreature(blightTargetGUID);
+
+ switch(getStage())
+ {
+ case 0:
+ if (timedQuery(SPELL_GASEOUS_BLIGHT_2, diff))
+ setStage(1);
+ break;
+ case 1:
+ switch (urand(0,2))
+ {
+ case 0: DoScriptText(-1631210,m_creature); break;
+ case 1: DoScriptText(-1631211,m_creature); break;
+ case 2: DoScriptText(-1631212,m_creature); break;
+ }
+ doCast(SPELL_INHALE_BLIGHT);
+ setStage(2);
+ break;
+ case 2:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ if (pBlightTarget)
+ {
+ doRemove(SPELL_GASEOUS_BLIGHT_1);
+ doRemove(SPELL_BLIGHT_VISUAL_1,pBlightTarget);
+ doRemove(SPELL_BLIGHT_VISUAL_1,m_creature);
+ doCast(SPELL_GASEOUS_BLIGHT_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_3);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_1);
+ }
+ setStage(3);
+ break;
+ case 3:
+ if (timedQuery(SPELL_GASEOUS_BLIGHT_3, diff))
+ setStage(4);
+ break;
+ case 4:
+ switch (urand(0,2))
+ {
+ case 0: DoScriptText(-1631210,m_creature); break;
+ case 1: DoScriptText(-1631211,m_creature); break;
+ case 2: DoScriptText(-1631212,m_creature); break;
+ }
+ doCast(SPELL_INHALE_BLIGHT);
+ setStage(5);
+ break;
+ case 5:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ if (pBlightTarget)
+ {
+ doRemove(SPELL_GASEOUS_BLIGHT_2);
+ doRemove(SPELL_BLIGHT_VISUAL_2,pBlightTarget);
+ doRemove(SPELL_BLIGHT_VISUAL_2,m_creature);
+ doCast(SPELL_GASEOUS_BLIGHT_3);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_3);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_1);
+ }
+ setStage(6);
+ break;
+ case 6:
+ if (timedQuery(SPELL_GASEOUS_BLIGHT_3, diff))
+ setStage(7);
+ break;
+ case 7:
+ switch (urand(0,2))
+ {
+ case 0: DoScriptText(-1631210,m_creature); break;
+ case 1: DoScriptText(-1631211,m_creature); break;
+ case 2: DoScriptText(-1631212,m_creature); break;
+ }
+ doCast(SPELL_INHALE_BLIGHT);
+ setStage(8);
+ break;
+ case 8:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ if (pBlightTarget)
+ {
+ doRemove(SPELL_GASEOUS_BLIGHT_3);
+ doRemove(SPELL_BLIGHT_VISUAL_3,pBlightTarget);
+ doRemove(SPELL_BLIGHT_VISUAL_3,m_creature);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_3);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_1);
+ }
+ setStage(9);
+ break;
+ case 9:
+ if (timedQuery(SPELL_PUNGENT_BLIGHT, diff))
+ {
+ DoScriptText(-1631208,m_creature);
+ doCast(SPELL_PUNGENT_BLIGHT);
+ setStage(10);
+ }
+ break;
+ case 10:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ if (pBlightTarget)
+ {
+ doCast(SPELL_BLIGHT_VISUAL_1,pBlightTarget);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_3);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_2);
+ doRemoveFromAll(SPELL_BLIGHT_VISUAL_1);
+ }
+ m_creature->RemoveAurasDueToSpell(SPELL_INHALED_BLIGHT);
+ setStage(0);
+ break;
+ }
+
+
+ timedCast(SPELL_GAS_SPORE, diff);
+
+ timedCast(SPELL_GASTRIC_BLOAT, diff);
+
+ if (auraCount(SPELL_GASTRIC_BLOAT,m_creature->getVictim(),EFFECT_INDEX_1) > 9)
+ {
+ m_creature->getVictim()->RemoveAurasDueToSpell(SPELL_GASTRIC_BLOAT);
+ doCast(SPELL_GASTRIC_EXPLOSION,m_creature->getVictim());
+ };
+
+ if (timedQuery(SPELL_VILE_GAS, diff))
+ {
+ float fPosX, fPosY, fPosZ;
+ m_creature->GetPosition(fPosX, fPosY, fPosZ);
+ m_creature->GetRandomPoint(fPosX, fPosY, fPosZ, 30.0f, fPosX, fPosY, fPosZ);
+ if (Unit* pTemp = doSummon(NPC_VILE_GAS_STALKER,fPosX, fPosY, fPosZ))
+ doCast(SPELL_VILE_GAS, pTemp);
+ DoScriptText(-1631213,m_creature);
+ };
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631207,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+
+CreatureAI* GetAI_boss_festergut(Creature* pCreature)
+{
+ return new boss_festergutAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_vile_gas_stalkerAI : public ScriptedAI
+{
+ mob_vile_gas_stalkerAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 m_lifetimer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWithZone();
+ SetCombatMovement(false);
+ m_creature->SetDisplayId(11686);
+ m_lifetimer = 12000;
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_FESTERGUT) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_lifetimer <= uiDiff)
+ m_creature->ForcedDespawn();
+ else m_lifetimer -= uiDiff;
+
+ }
+};
+
+CreatureAI* GetAI_mob_vile_gas_stalker(Creature* pCreature)
+{
+ return new mob_vile_gas_stalkerAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_orange_gas_stalkerAI : public ScriptedAI
+{
+ mob_orange_gas_stalkerAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ m_creature->SetDisplayId(11686);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+// if (!pInstance || pInstance->GetData(TYPE_FESTERGUT) != IN_PROGRESS)
+// m_creature->ForcedDespawn();
+ }
+};
+
+CreatureAI* GetAI_mob_orange_gas_stalker(Creature* pCreature)
+{
+ return new mob_orange_gas_stalkerAI(pCreature);
+}
+
+void AddSC_boss_festergut()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_festergut";
+ newscript->GetAI = &GetAI_boss_festergut;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_vile_gas_stalker";
+ newscript->GetAI = &GetAI_mob_vile_gas_stalker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_orange_gas_stalker";
+ newscript->GetAI = &GetAI_mob_orange_gas_stalker;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp
index 8df083c..2628640 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lady_deathwhisper.cpp
@@ -16,9 +16,520 @@
/* ScriptData
SDName: boss_lady_deathwhisper
-SD%Complete: 0%
-SDComment:
+SD%Complete: 80%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need correct spells on adds and timers
#include "precompiled.h"
+#include "def_spire.h"
+enum BossSpells
+{
+ //common
+ SPELL_BERSERK = 47008,
+ //yells
+ //summons
+ NPC_VENGEFUL_SHADE = 38222,
+ NPC_FANATIC = 37890,
+ NPC_REANIMATED_FANATIC = 38009,
+ NPC_ADHERENT = 37949,
+ NPC_REANIMATED_ADHERENT = 38010,
+ //Abilities
+ SPELL_MANA_BARRIER = 70842,
+ SPELL_SHADOW_BOLT = 71254,
+ SPELL_DEATH_AND_DECAY = 71001,
+ SPELL_DARK_EMPOWERMENT = 70901,
+ SPELL_FROSTBOLT = 71420,
+ SPELL_INSIGNIFICANCE = 71204,
+
+ SPELL_DOMINATE_MIND = 71289,
+
+ SPELL_VENGEFUL_BLAST = 71494,
+ SPELL_VENGEFUL_BLAST_0 = 71544,
+ // summons
+ SPELL_FROST_FEVER = 71129,
+ SPELL_DEATHCHILL_BOLT = 70594,
+ SPELL_DEATHCHILL_BLAST = 70906,
+ SPELL_DARK_MARTYRDROM = 70903,
+ SPELL_CURSE_OF_TOPOR = 71237,
+ SPELL_SHORUD_OF_THE_OCCULUT = 70768,
+ SPELL_ADHERENTS_DETERMINIATION = 71234,
+ SPELL_SUMMON_VISUAL = 41236,
+
+ SPELL_NECROTIC_STRIKE = 70659,
+ SPELL_SHADOW_CLEAVE = 70670,
+ SPELL_VAMPIRIC_MIGHT = 70674,
+};
+
+static Locations SpawnLoc[]=
+{
+ {-623.055481f, 2211.326660f, 51.764259f}, // 0 Lady's stay point
+ {-620.197449f, 2272.062256f, 50.848679f}, // 1 Right Door 1
+ {-598.636353f, 2272.062256f, 50.848679f}, // 2 Right Door 2
+ {-578.495728f, 2272.062256f, 50.848679f}, // 3 Right Door 3
+ {-578.495728f, 2149.211182f, 50.848679f}, // 4 Left Door 1
+ {-598.636353f, 2149.211182f, 50.848679f}, // 5 Left Door 2
+ {-620.197449f, 2149.211182f, 50.848679f}, // 6 Left Door 3
+ {-517.652466f, 2216.611328f, 62.823681f}, // 7 Upper marsh 1
+ {-517.652466f, 2211.611328f, 62.823681f}, // 8 Upper marsh 2
+ {-517.652466f, 2206.611328f, 62.823681f}, // 9 Upper marsh 3
+};
+
+struct MANGOS_DLL_DECL boss_lady_deathwhisperAI : public BSWScriptedAI
+{
+ boss_lady_deathwhisperAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+ bool MovementStarted;
+ bool intro;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ if (m_creature->isAlive()) pInstance->SetData(TYPE_DEATHWHISPER, NOT_STARTED);
+ stage = 0;
+ MovementStarted = false;
+ intro = false;
+ resetTimers();
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (m_creature->CanInitiateAttack() && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
+ {
+ if (m_creature->IsWithinDistInMap(pWho, m_creature->GetAttackDistance(pWho)) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ AttackStart(pWho);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho);
+ }
+ }
+ }
+ if (stage) return;
+ else intro = true;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631029,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631030,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance) pInstance->SetData(TYPE_DEATHWHISPER, FAIL);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if(!pInstance) return;
+ if(type != POINT_MOTION_TYPE) return;
+ if(MovementStarted && id != 1)
+ {
+ m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z);
+ }
+ else {
+ m_creature->GetMotionMaster()->MovementExpired();
+ MovementStarted = false;
+ SetCombatMovement(false);
+ }
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(pInstance) pInstance->SetData(TYPE_DEATHWHISPER, IN_PROGRESS);
+ doCast(SPELL_MANA_BARRIER );
+ MovementStarted = true;
+ SetCombatMovement(false);
+ DoScriptText(-1631023,m_creature);
+ m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(pInstance) pInstance->SetData(TYPE_DEATHWHISPER, DONE);
+ DoScriptText(-1631032,m_creature,killer);
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned) return;
+
+ if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ) {
+ summoned->AddThreat(pTarget, 100.0f);
+ }
+ }
+
+ void CallGuard(uint8 place)
+ {
+ if (place < 2)
+ {
+ doSummon(urand(0,1) ? NPC_FANATIC : NPC_ADHERENT, SpawnLoc[3*place+1].x, SpawnLoc[3*place+1].y, SpawnLoc[3*place+1].z);
+ doSummon(urand(0,1) ? NPC_FANATIC : NPC_ADHERENT, SpawnLoc[3*place+3].x, SpawnLoc[3*place+3].y, SpawnLoc[3*place+3].z);
+ }
+ doSummon(urand(0,1) ? NPC_FANATIC : NPC_ADHERENT, SpawnLoc[3*place+2].x, SpawnLoc[3*place+2].y, SpawnLoc[3*place+2].z);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if (hasAura(SPELL_MANA_BARRIER, m_creature)) {
+ if (m_creature->GetPower(POWER_MANA) > uiDamage) {
+ m_creature->SetPower(POWER_MANA,m_creature->GetPower(POWER_MANA)-uiDamage);
+ uiDamage = 0;
+ }
+ else {
+ m_creature->SetPower(POWER_MANA,0);
+ doRemove(SPELL_MANA_BARRIER);
+ };
+ } else return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (intro && timedQuery(SPELL_SHADOW_BOLT,diff))
+ switch (stage) {
+ case 0:
+ DoScriptText(-1631020,m_creature);
+ stage = 1;
+ break;
+ case 1:
+ DoScriptText(-1631021,m_creature);
+ stage = 2;
+ break;
+ case 2:
+ DoScriptText(-1631022,m_creature);
+ stage = 3;
+ break;
+ default:
+ break;
+ }
+
+ if (hasAura(SPELL_MANA_BARRIER, m_creature)) {
+ if(m_creature->GetHealth() <= m_creature->GetMaxHealth()) {
+ if (m_creature->GetPower(POWER_MANA) > (m_creature->GetMaxHealth() - m_creature->GetHealth()))
+ {
+ m_creature->SetPower(POWER_MANA,m_creature->GetPower(POWER_MANA)-(m_creature->GetMaxHealth() - m_creature->GetHealth()));
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ }
+ else m_creature->SetPower(POWER_MANA,0);
+ }
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (MovementStarted) return;
+
+ switch(stage)
+ {
+ case 3: {
+ if (IsCombatMovement())
+ SetCombatMovement(false);
+
+ timedCast(SPELL_SHADOW_BOLT,diff);
+
+ if (timedQuery(NPC_FANATIC, diff))
+ {
+ DoScriptText(-1631028,m_creature);
+ switch (currentDifficulty) {
+ case RAID_DIFFICULTY_10MAN_NORMAL:
+ CallGuard(urand(0,1));
+ break;
+ case RAID_DIFFICULTY_10MAN_HEROIC:
+ CallGuard(urand(0,1));
+ if (urand(0,1)) CallGuard(2);
+ break;
+ case RAID_DIFFICULTY_25MAN_NORMAL:
+ CallGuard(0);
+ CallGuard(1);
+ if (urand(0,1)) CallGuard(2);
+ break;
+ case RAID_DIFFICULTY_25MAN_HEROIC:
+ CallGuard(0);
+ CallGuard(1);
+ CallGuard(2);
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ if (timedQuery(SPELL_DARK_EMPOWERMENT ,diff))
+ {
+ switch (urand(0,1)) {
+ case 0:
+ if(Creature *pGuard = GetClosestCreatureWithEntry(m_creature, NPC_FANATIC, 100.0f))
+ {
+ doCast(SPELL_DARK_EMPOWERMENT, pGuard);
+ DoScriptText(-1631026,m_creature);
+ };
+ break;
+ case 1:
+ if(Creature *pGuard = GetClosestCreatureWithEntry(m_creature, NPC_ADHERENT, 100.0f))
+ {
+ doCast(SPELL_DARK_EMPOWERMENT, pGuard);
+ DoScriptText(-1631027,m_creature);
+ };
+ break;
+ }
+ }
+
+ break;}
+
+ case 4: {
+ timedCast(SPELL_FROSTBOLT, diff);
+
+ timedCast(SPELL_INSIGNIFICANCE, diff);
+
+ timedCast(NPC_VENGEFUL_SHADE, diff);
+
+ if (is25()) timedCast(SPELL_DOMINATE_MIND, diff);
+
+ if (timedQuery(NPC_FANATIC, diff))
+ {
+ switch (currentDifficulty) {
+ case RAID_DIFFICULTY_10MAN_HEROIC:
+ CallGuard(urand(0,1));
+ if (urand(0,1)) CallGuard(2);
+ break;
+ case RAID_DIFFICULTY_25MAN_HEROIC:
+ CallGuard(0);
+ CallGuard(1);
+ CallGuard(2);
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ break;}
+ }
+
+ timedCast(SPELL_DEATH_AND_DECAY, diff);
+
+
+ if (!hasAura(SPELL_MANA_BARRIER, m_creature) && stage == 3)
+ {
+ stage = 4;
+ DoScriptText(-1631024,m_creature);
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ }
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631031,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_lady_deathwhisper(Creature* pCreature)
+{
+ return new boss_lady_deathwhisperAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_vengeful_shadeAI : public BSWScriptedAI
+{
+ mob_vengeful_shadeAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetInCombatWithZone();
+ if (Unit* pTarget= m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ) {
+ m_creature->AddThreat(pTarget, 1000.0f);
+ m_creature->GetMotionMaster()->MoveChase(pTarget);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5);
+ }
+ doCast(SPELL_VENGEFUL_BLAST);
+ }
+
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance && m_pInstance->GetData(TYPE_DEATHWHISPER) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (timedQuery(SPELL_VENGEFUL_BLAST_0, uiDiff))
+ {
+ if (m_creature->IsWithinDist(m_creature->getVictim(), 1.0f, false))
+ {
+ doCast(SPELL_VENGEFUL_BLAST_0);
+ m_creature->ForcedDespawn();
+ }
+ else
+ {
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5);
+ }
+ }
+ }
+
+};
+
+CreatureAI* GetAI_mob_vengeful_shade(Creature* pCreature)
+{
+ return new mob_vengeful_shadeAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_cult_adherentAI : public BSWScriptedAI
+{
+ mob_cult_adherentAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool bone;
+
+ void Reset()
+ {
+ resetTimers();
+ m_creature->SetRespawnDelay(DAY);
+ doCast(SPELL_SUMMON_VISUAL);
+ bone = false;
+ }
+
+ void Aggro(Unit *who)
+ {
+ doCast(SPELL_SHORUD_OF_THE_OCCULUT);
+ DoStartMovement(who, 20.0f);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_DEATHWHISPER) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_FROST_FEVER, uiDiff);
+
+ timedCast(SPELL_DEATHCHILL_BOLT, uiDiff);
+
+ timedCast( SPELL_DEATHCHILL_BLAST, uiDiff);
+
+ if (m_creature->GetHealthPercent() < 15.0f && !bone)
+ {
+ if (!urand(0,3)) doCast(SPELL_DARK_MARTYRDROM); //30%
+ bone = true;
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_cult_adherent(Creature* pCreature)
+{
+ return new mob_cult_adherentAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_cult_fanaticAI : public BSWScriptedAI
+{
+ mob_cult_fanaticAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool bone;
+
+ void Reset()
+ {
+ resetTimers();
+ m_creature->SetRespawnDelay(DAY);
+ bone = false;
+ }
+
+ void Aggro(Unit *who)
+ {
+ doCast(SPELL_VAMPIRIC_MIGHT);
+ DoStartMovement(who);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_DEATHWHISPER) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_NECROTIC_STRIKE, uiDiff);
+
+ timedCast(SPELL_SHADOW_CLEAVE, uiDiff);
+
+ if (m_creature->GetHealthPercent() < 15.0f && !bone)
+ {
+ if (!urand(0,3)) doCast(SPELL_DARK_MARTYRDROM); //30%
+ bone = true;
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_cult_fanatic(Creature* pCreature)
+{
+ return new mob_cult_fanaticAI(pCreature);
+}
+
+void AddSC_boss_lady_deathwhisper()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_lady_deathwhisper";
+ newscript->GetAI = &GetAI_boss_lady_deathwhisper;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_vengeful_shade";
+ newscript->GetAI = &GetAI_mob_vengeful_shade;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_cult_adherent";
+ newscript->GetAI = &GetAI_mob_cult_adherent;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_cult_fanatic";
+ newscript->GetAI = &GetAI_mob_cult_fanatic;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp
index 1bd579d..8f3e2a8 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_lord_marrowgar.cpp
@@ -16,9 +16,417 @@
/* ScriptData
SDName: boss_lord_marrowgar
-SD%Complete: 0%
-SDComment:
+SD%Complete: 85%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
#include "precompiled.h"
+#include "def_spire.h"
+enum
+{
+ //common
+ SPELL_BERSERK = 47008,
+ //yells
+ //summons
+ NPC_BONE_SPIKE = 38711,
+ NPC_COLD_FLAME = 36672,
+ //Abilities
+ SPELL_SABER_LASH = 71021,
+ SPELL_CALL_COLD_FLAME = 69138,
+ SPELL_CALL_COLD_FLAME_1 = 71580,
+ SPELL_COLD_FLAME = 69146,
+ SPELL_COLD_FLAME_0 = 69145,
+ SPELL_COLD_FLAME_1 = 69147,
+ SPELL_BONE_STRIKE = 69057,
+ SPELL_BONE_STORM = 69076,
+ SPELL_BONE_STRIKE_IMPALE = 69065,
+ SPELL_VEHICLE_HARDCODED = 46598,
+ SPELL_BONE_STORM_STRIKE = 69075,
+};
+
+struct MANGOS_DLL_DECL boss_lord_marrowgarAI : public BSWScriptedAI
+{
+ boss_lord_marrowgarAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool intro;
+
+ void Reset()
+ {
+ if (!pInstance) return;
+ if (m_creature->isAlive()) pInstance->SetData(TYPE_MARROWGAR, NOT_STARTED);
+ resetTimers();
+ m_creature->SetSpeedRate(MOVE_RUN, 1);
+ m_creature->SetSpeedRate(MOVE_WALK, 1);
+// m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ ScriptedAI::MoveInLineOfSight(pWho);
+ if (intro) return;
+ DoScriptText(-1631000,m_creature);
+ intro = true;
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned) return;
+ summoned->SetCreatorGuid(m_creature->GetObjectGuid());
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance) pInstance->SetData(TYPE_MARROWGAR, FAIL);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_MARROWGAR, IN_PROGRESS);
+ DoScriptText(-1631001,m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631006,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631007,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(pInstance) pInstance->SetData(TYPE_MARROWGAR, DONE);
+ DoScriptText(-1631009,m_creature);
+ }
+
+ void doSummonSpike(Unit* pTarget)
+ {
+ if (!pTarget || !pTarget->isAlive()) return;
+ float fPosX, fPosY, fPosZ;
+ pTarget->GetPosition(fPosX, fPosY, fPosZ);
+ if (Unit* pSpike = doSummon(NPC_BONE_SPIKE, fPosX, fPosY, fPosZ + 0.5f))
+ {
+ pSpike->SetOwnerGuid(m_creature->GetObjectGuid());
+ pSpike->SetInCombatWith(pTarget);
+ pSpike->AddThreat(pTarget, 1000.0f);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(getStage())
+ {
+ case 0:
+ if (timedQuery(SPELL_BONE_STRIKE, diff))
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_BONE_STRIKE_IMPALE, false, 60.0f))
+ if (doCast(SPELL_BONE_STRIKE, pTarget) == CAST_OK)
+ {
+ doSummonSpike(pTarget);
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631003,m_creature,pTarget);
+ break;
+ case 1:
+ DoScriptText(-1631004,m_creature,pTarget);
+ break;
+ case 2:
+ DoScriptText(-1631005,m_creature,pTarget);
+ break;
+ };
+
+ };
+
+ if (timedQuery(SPELL_BONE_STORM, diff)) setStage(1);
+
+ if (timedQuery(SPELL_CALL_COLD_FLAME, diff))
+ {
+ if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME);
+ else doCast(SPELL_CALL_COLD_FLAME_1);
+
+ if (m_creature->GetHealthPercent() <= 30.0f)
+ {
+ if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME);
+ else doCast(SPELL_CALL_COLD_FLAME_1);
+ }
+ }
+
+ timedCast(SPELL_SABER_LASH, diff);
+
+ DoMeleeAttackIfReady();
+
+ break;
+ case 1:
+ m_creature->InterruptNonMeleeSpells(true);
+ doCast(SPELL_BONE_STORM);
+ setStage(2);
+ DoScriptText(-1631002,m_creature);
+ DoResetThreat();
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_RUN, 3);
+ m_creature->SetSpeedRate(MOVE_WALK, 3);
+ break;
+ case 2:
+ if (!m_creature->IsNonMeleeSpellCasted(false)) setStage(3);
+ break;
+ case 3:
+ if (isHeroic())
+ if (timedQuery(SPELL_BONE_STRIKE, diff, true))
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_BONE_STRIKE_IMPALE, false, 60.0f))
+ doSummonSpike(pTarget);
+
+ if (timedQuery(SPELL_CALL_COLD_FLAME, diff, true)
+ && m_creature->IsWithinDistInMap(m_creature->getVictim(),2.0f))
+ {
+ pInstance->SetData(DATA_DIRECTION, (uint32)(1000*2.0f*M_PI_F*((float)urand(1,16)/16.0f)));
+// if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME);
+// else doCast(SPELL_CALL_COLD_FLAME_1);
+ float fPosX, fPosY, fPosZ;
+ m_creature->GetPosition(fPosX, fPosY, fPosZ);
+ doSummon(NPC_COLD_FLAME, fPosX, fPosY, fPosZ);
+ DoResetThreat();
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(60.0f))
+ AttackStart(pTarget);
+ }
+ if (!hasAura(SPELL_BONE_STORM_STRIKE, m_creature) && !hasAura(SPELL_BONE_STORM, m_creature)) setStage(4);
+ break;
+ case 4:
+ pInstance->SetData(DATA_DIRECTION, 0);
+ m_creature->SetSpeedRate(MOVE_RUN, 1);
+ m_creature->SetSpeedRate(MOVE_WALK, 1);
+// m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ setStage(0);
+ break;
+ default:
+ break;
+ }
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631008,m_creature);
+ }
+
+
+ }
+};
+
+struct MANGOS_DLL_DECL mob_coldflameAI : public BSWScriptedAI
+{
+ mob_coldflameAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool isFirst;
+ bool isXmode;
+ float m_direction;
+ float x, y, radius;
+ bool isCreator;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+// m_creature->SetDisplayId(10045);
+ m_creature->SetRespawnDelay(7*DAY);
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ setStage(0);
+ isCreator = false;
+
+ SetCombatMovement(false);
+ doCast(SPELL_COLD_FLAME_0);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!m_pInstance || !summoned) return;
+ summoned->SetCreatorGuid(m_creature->GetObjectGuid());
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance && m_pInstance->GetData(TYPE_MARROWGAR) != IN_PROGRESS)
+ {
+ m_creature->ForcedDespawn();
+ }
+
+ if (m_creature->GetCreatorGuid().IsEmpty()) return;
+
+ if (!isCreator)
+ {
+ if (m_creature->GetCreatorGuid() == m_pInstance->GetData64(NPC_LORD_MARROWGAR))
+ {
+ isFirst = true;
+ uint32 m_tmpDirection = m_pInstance->GetData(DATA_DIRECTION);
+ m_pInstance->SetData(DATA_DIRECTION,0);
+ if (m_tmpDirection)
+ {
+ m_direction = m_tmpDirection/1000.0f;
+ isXmode = true;
+ }
+ else
+ {
+ m_direction = 2.0f*M_PI_F*((float)urand(1,16)/16.0f);
+ isXmode = false;
+ }
+ } else isFirst = false;
+ isCreator = true;
+ }
+
+ if (timedQuery(SPELL_COLD_FLAME_0, uiDiff) && !isFirst)
+ m_creature->ForcedDespawn();
+
+ if (isFirst && timedQuery(SPELL_COLD_FLAME_1, uiDiff, true))
+ {
+ if (getStage() < getSpellData(SPELL_COLD_FLAME_0))
+ {
+ setStage(getStage()+1);
+ radius = getStage()*5;
+ m_creature->GetNearPoint2D(x, y, radius, m_direction);
+ doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1));
+ if (isXmode)
+ {
+ m_creature->GetNearPoint2D(x, y, radius, m_direction+M_PI_F/2);
+ doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1));
+ m_creature->GetNearPoint2D(x, y, radius, m_direction+M_PI_F);
+ doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1));
+ m_creature->GetNearPoint2D(x, y, radius, m_direction+M_PI_F*1.5f);
+ doSummon(NPC_COLD_FLAME, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, getSpellData(SPELL_COLD_FLAME_1));
+ }
+ } else m_creature->ForcedDespawn();
+ } else timedCast(SPELL_COLD_FLAME, uiDiff);
+
+ }
+};
+
+struct MANGOS_DLL_DECL mob_bone_spikeAI : public BSWScriptedAI
+{
+ mob_bone_spikeAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ ObjectGuid victimGuid;
+
+ void Reset()
+ {
+ SetCombatMovement(false);
+ m_creature->SetRespawnDelay(7*DAY);
+ victimGuid = ObjectGuid();
+ m_creature->SetInCombatWithZone();
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (victimGuid.IsEmpty() && pWho && pWho->GetTypeId() == TYPEID_PLAYER)
+ {
+ victimGuid = pWho->GetObjectGuid();
+ m_creature->SetInCombatWith(pWho);
+ doCast(SPELL_BONE_STRIKE_IMPALE,pWho);
+ doCast(SPELL_VEHICLE_HARDCODED,pWho);
+ }
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth())
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid))
+ doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ }
+
+ void KilledUnit(Unit* _Victim)
+ {
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid))
+ if (pVictim->GetObjectGuid() == victimGuid)
+ doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim);
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid))
+ doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance && m_pInstance->GetData(TYPE_MARROWGAR) != IN_PROGRESS)
+ {
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid))
+ doRemove(SPELL_BONE_STRIKE_IMPALE,pVictim);
+ m_creature->ForcedDespawn();
+ }
+
+ if (victimGuid.IsEmpty())
+ return;
+
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGuid))
+ {
+ if(!pVictim->isAlive())
+ m_creature->ForcedDespawn();
+ }
+ else
+ m_creature->ForcedDespawn();
+ }
+};
+
+CreatureAI* GetAI_mob_bone_spike(Creature* pCreature)
+{
+ return new mob_bone_spikeAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_coldflame(Creature* pCreature)
+{
+ return new mob_coldflameAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_lord_marrowgar(Creature* pCreature)
+{
+ return new boss_lord_marrowgarAI(pCreature);
+}
+
+void AddSC_boss_lord_marrowgar()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_lord_marrowgar";
+ newscript->GetAI = &GetAI_boss_lord_marrowgar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_coldflame";
+ newscript->GetAI = &GetAI_mob_coldflame;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_bone_spike";
+ newscript->GetAI = &GetAI_mob_bone_spike;
+ newscript->RegisterSelf();
+
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp
index 21a1cb9..eccc914 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_professor_putricide.cpp
@@ -15,10 +15,755 @@
*/
/* ScriptData
-SDName: boss_professor_putricide
-SD%Complete: 0%
-SDComment:
+SDName: boss_proffesor_putricide
+SD%Complete: 70%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need implement model (aura?) for phase 2 and visual effects
+// I don't know how do mutated_abomination :(
#include "precompiled.h"
+#include "def_spire.h"
+
+enum BossSpells
+{
+ SPELL_UNSTABLE_EXPERIMENT = 70351, // Script effect not work on 10154. Spawn manually.
+ SPELL_TEAR_GAS = 71617,
+ SPELL_TEAR_GAS_1 = 71615,
+ SPELL_TEAR_GAS_2 = 71618,
+ SPELL_CREATE_CONCOCTION = 71621,
+ SPELL_MALLEABLE_GOO = 70852,
+ SPELL_GUZZLE_POTIONS = 71893,
+ SPELL_MUTATED_STRENGTH = 71603,
+ SPELL_MUTATED_PLAGUE = 72672,
+ SPELL_OOZE_THROW = 70342, // is triggered spell
+//
+ SPELL_GREEN_BOTTLE_0 = 71826,
+ SPELL_ORANGE_BOTTLE_0 = 71827,
+ SPELL_GREEN_BOTTLE_1 = 71702,
+ SPELL_ORANGE_BOTTLE_1 = 71703,
+//
+ SPELL_THROW_BOTTLE_1 = 71273,
+ SPELL_THROW_BOTTLE_2 = 71275,
+ SPELL_THROW_BOTTLE_3 = 71276,
+//
+ NPC_GAS_CLOUD = 37562,
+ SPELL_GASEOUS_BLOAT = 70672,
+ SPELL_EXPUNGED_GAS = 70701,
+ SPELL_SOUL_FEAST = 71203,
+//
+ NPC_VOLATILE_OOZE = 37697,
+ SPELL_OOZE_ADHESIVE = 70447,
+ SPELL_OOZE_ERUPTION = 70492,
+//
+ SPELL_OOZE_GAS_PROTECTION = 70812,
+ SPELL_OOZE_BEAM_PROTECTION = 71530,
+ SPELL_OOZE_TANK_PROTECTION = 71770,
+//
+ NPC_MUTATED_ABOMINATION = 37672,
+ SPELL_MUTATED_TRANSFORMATION = 70311,
+ SPELL_EAT_OOZE = 72527,
+ SPELL_REGURGITATED_OOZE = 70539,
+ SPELL_MUTATED_SLASH = 70542,
+ SPELL_MUTATED_AURA = 70405,
+//
+ NPC_CHOKING_GAS_BOMB = 38159,
+ SPELL_CHOKING_GAS = 71259,
+ SPELL_CHOKING_GAS_AURA = 71278,
+ SPELL_CHOKING_GAS_EXPLODE = 71279,
+ SPELL_CHOKING_GAS_EXPLODE_TRIGGER = 71280,
+ SPELL_ORANGE_RADIATION = 45857, //Additional visual
+//
+ NPC_OOZE_PUDDLE = 37690,
+ SPELL_SLIME_PUDDLE = 70343,
+ SPELL_SLIME_PUDDLE_AURA = 70346,
+
+ SPELL_BERSERK = 47008,
+ QUEST_24749 = 71518,
+//
+ VIEW_1 = 30881,
+ VIEW_2 = 30881,
+ VIEW_3 = 30993,
+};
+
+static Locations SpawnLoc[]=
+{
+ {4356.779785f, 3263.510010f, 389.398010f, 1.586f}, // 0 Putricide start point o=1.586
+ {4295.081055f, 3188.883545f, 389.330261f, 4.270f}, // 1 Puticide Festergut say, o=4.27
+ {4417.302246f, 3188.219971f, 389.332520f, 5.102f}, // 2 Putricide Rotface say o=5.102
+};
+
+struct MANGOS_DLL_DECL boss_proffesor_putricideAI : public BSWScriptedAI
+{
+ boss_proffesor_putricideAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+ bool intro;
+ uint32 UpdateTimer;
+ bool movementstarted;
+ uint8 nextPoint;
+ uint8 slimetype;
+
+ void Reset()
+ {
+ if (!pInstance) return;
+ if (m_creature->isAlive()) pInstance->SetData(TYPE_PUTRICIDE, NOT_STARTED);
+ stage = 0;
+ slimetype = 0;
+ intro = false;
+ movementstarted = false;
+ UpdateTimer = 1000;
+ resetTimers();
+ m_creature->SetRespawnDelay(7*DAY);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ ScriptedAI::MoveInLineOfSight(pWho);
+
+ if (!pInstance || intro) return;
+ if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_PROFESSOR_PUTRICIDE
+ || !pWho->IsWithinDistInMap(m_creature, 60.0f)) return;
+
+ DoScriptText(-1631240,m_creature, pWho);
+ intro = true;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631241,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631242,m_creature,pVictim);
+ break;
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || !movementstarted) return;
+ if (id == nextPoint)
+ {
+ movementstarted = false;
+ m_creature->GetMotionMaster()->MovementExpired();
+ }
+ }
+
+ void Aggro(Unit *pWho)
+ {
+ if (!pInstance) return;
+ if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ pInstance->SetData(TYPE_PUTRICIDE, IN_PROGRESS);
+ DoScriptText(-1631249,m_creature, pWho);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (!pInstance) return;
+ pInstance->SetData(TYPE_PUTRICIDE, DONE);
+ DoScriptText(-1631243,m_creature, killer);
+ for (uint8 i = 0; i < 5; i++)
+ {
+ if (Unit* pPlayer = doSelectRandomPlayer(SPELL_MUTATED_PLAGUE, true, 100.0f))
+ {
+ doCast(QUEST_24749, pPlayer);
+ doRemove(SPELL_MUTATED_PLAGUE, pPlayer);
+ }
+ }
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned) return;
+
+ if ( summoned->GetEntry() == NPC_VOLATILE_OOZE
+ || summoned->GetEntry() == NPC_GAS_CLOUD)
+ if (Unit* pTarget = doSelectRandomPlayer())
+ {
+ summoned->SetInCombatWith(pTarget);
+ summoned->AddThreat(pTarget, 100.0f);
+ }
+
+ }
+
+ void StartMovement(uint32 id)
+ {
+ nextPoint = id;
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
+ movementstarted = true;
+ }
+
+ void CallOoze()
+ {
+ if (doCast(SPELL_UNSTABLE_EXPERIMENT) == CAST_OK)
+ switch(slimetype)
+ {
+ case 0:
+ doSummon(NPC_VOLATILE_OOZE);
+ slimetype = 1;
+ break;
+ case 1:
+ doSummon(NPC_GAS_CLOUD);
+ slimetype = 0;
+ break;
+
+ default: break;
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance) pInstance->SetData(TYPE_PUTRICIDE, FAIL);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_PROFESSOR_PUTRICIDE)
+ {
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+ if (UpdateTimer <= diff)
+ {
+ debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT));
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 500:
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->NearTeleportTo(SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, SpawnLoc[1].o);
+ DoScriptText(-1631201, m_creature);
+ UpdateTimer = 60000;
+ pInstance->SetData(TYPE_EVENT,510);
+ break;
+ case 510:
+ UpdateTimer = 5000;
+ if (pInstance->GetData(TYPE_FESTERGUT) == DONE)
+ pInstance->SetData(TYPE_EVENT,550);
+ if (pInstance->GetData(TYPE_FESTERGUT) == FAIL)
+ pInstance->SetData(TYPE_EVENT,630);
+ break;
+ case 550:
+ DoScriptText(-1631202, m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,630);
+ break;
+ case 600:
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->NearTeleportTo(SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z, SpawnLoc[2].o);
+ DoScriptText(-1631220, m_creature);
+ UpdateTimer = 60000;
+ pInstance->SetData(TYPE_EVENT,610);
+ break;
+ case 610:
+ UpdateTimer = 5000;
+ if (pInstance->GetData(TYPE_ROTFACE) == DONE)
+ pInstance->SetData(TYPE_EVENT,620);
+ if (pInstance->GetData(TYPE_ROTFACE) == FAIL)
+ pInstance->SetData(TYPE_EVENT,630);
+ break;
+ case 620:
+ DoScriptText(-1631202, m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,630);
+ break;
+ case 630:
+ m_creature->NearTeleportTo(SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, SpawnLoc[0].o);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,690);
+ break;
+ default:
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(stage)
+ {
+ case 0:
+
+ if (timedQuery(SPELL_UNSTABLE_EXPERIMENT, diff))
+ CallOoze();
+
+ timedCast(SPELL_OOZE_THROW, diff);
+
+ if (timedQuery(SPELL_MALLEABLE_GOO, diff))
+ {
+ doCast(SPELL_MALLEABLE_GOO);
+ }
+
+ DoMeleeAttackIfReady();
+
+ if (m_creature->GetHealthPercent() < 80.0f ) stage = 1;
+
+ break;
+ case 1:
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->AttackStop();
+ SetCombatMovement(false);
+ doCast(SPELL_TEAR_GAS_1);
+ DoScriptText(-1631245,m_creature);
+ StartMovement(0);
+ stage = 2;
+ break;
+ case 2:
+ if (movementstarted) return;
+ doCast(SPELL_CREATE_CONCOCTION);
+ stage = 3;
+ break;
+ case 3:
+ if (m_creature->IsNonMeleeSpellCasted(true,false,false) ||
+ !doSelectRandomPlayer(SPELL_TEAR_GAS_1, false)) return;
+ DoScriptText(-1631246,m_creature);
+ m_creature->SetDisplayId(VIEW_2);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ SetCombatMovement(true);
+ stage = 4;
+ break;
+ case 4:
+
+ if (timedQuery(SPELL_UNSTABLE_EXPERIMENT, diff))
+ CallOoze();
+
+ if (timedQuery(SPELL_THROW_BOTTLE_1, diff))
+ switch(urand(0,2))
+ {
+ case 0:
+ doCast(SPELL_THROW_BOTTLE_1);
+ break;
+ case 1:
+ doCast(SPELL_THROW_BOTTLE_2);
+ break;
+ case 2:
+ doCast(SPELL_THROW_BOTTLE_3);
+ break;
+ default: break;
+ }
+
+ timedCast(SPELL_OOZE_THROW, diff);
+
+ timedCast(SPELL_MALLEABLE_GOO, diff);
+
+ if (timedQuery(SPELL_MALLEABLE_GOO, diff))
+ {
+ doCast(SPELL_MALLEABLE_GOO);
+ }
+
+ if (m_creature->GetDisplayId() != VIEW_2)
+ m_creature->SetDisplayId(VIEW_2);
+
+ DoMeleeAttackIfReady();
+
+ if (m_creature->GetHealthPercent() < 35.0f ) stage = 5;
+
+ break;
+ case 5:
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->AttackStop();
+ SetCombatMovement(false);
+ doCast(SPELL_TEAR_GAS_1);
+ DoScriptText(-1631245,m_creature);
+ StartMovement(0);
+ stage = 6;
+ break;
+ case 6:
+ if (movementstarted) return;
+ doCast(SPELL_GUZZLE_POTIONS);
+ stage = 7;
+ break;
+ case 7:
+ if (m_creature->IsNonMeleeSpellCasted(true,false,false)) return;
+ if (m_creature->GetDisplayId() != VIEW_3)
+ m_creature->SetDisplayId(VIEW_3);
+ if (!doSelectRandomPlayer(SPELL_TEAR_GAS_1, false)) return;
+ DoScriptText(-1631247,m_creature);
+ m_creature->SetDisplayId(VIEW_3);
+ doCast(SPELL_MUTATED_STRENGTH);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ SetCombatMovement(true);
+ stage = 8;
+ break;
+ case 8:
+ timedCast(SPELL_MUTATED_PLAGUE, diff);
+ if (m_creature->GetDisplayId() != VIEW_3)
+ m_creature->SetDisplayId(VIEW_3);
+ DoMeleeAttackIfReady();
+
+ break;
+ default:
+ break;
+ }
+
+ if (timedQuery(SPELL_BERSERK, diff)){
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631244,m_creature);
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_proffesor_putricide(Creature* pCreature)
+{
+ return new boss_proffesor_putricideAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_icc_gas_cloudAI : public BSWScriptedAI
+{
+ mob_icc_gas_cloudAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ Unit* pTarget;
+ bool expunded;
+ uint32 delay;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_WALK, 0.5f);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.2f);
+ pTarget = NULL;
+ expunded = false;
+ delay = 10000;
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (!m_pInstance) return;
+ if (pTarget && pTarget->isAlive())
+ doRemove(SPELL_GASEOUS_BLOAT, pTarget);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance || who->GetTypeId() != TYPEID_PLAYER) return;
+
+ if (!pTarget || pTarget != who ) pTarget = who;
+ else return;
+
+ delay = 10000;
+
+ if (pTarget)
+ {
+ doAura(SPELL_GASEOUS_BLOAT, pTarget);
+ }
+ DoStartMovement(who);
+ }
+
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_creature->ForcedDespawn();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (!m_pInstance ) return;
+
+ if(m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (expunded) m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (!pTarget) Aggro(m_creature->getVictim());
+
+ if (timedQuery(SPELL_SOUL_FEAST, uiDiff))
+ {
+ doCast(SPELL_SOUL_FEAST);
+ }
+
+ if (delay <= uiDiff)
+ {
+ if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, 3.0f))
+ {
+ doCast(SPELL_EXPUNGED_GAS, pTarget);
+ doRemove(SPELL_GASEOUS_BLOAT, pTarget);
+ expunded = true;
+ };
+ } else delay -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_icc_gas_cloud(Creature* pCreature)
+{
+ return new mob_icc_gas_cloudAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_icc_volatile_oozeAI : public BSWScriptedAI
+{
+ mob_icc_volatile_oozeAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ Unit* pTarget;
+ bool finita;
+ uint32 delay;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_WALK, 0.5f);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.2f);
+ pTarget = NULL;
+ finita = false;
+ delay = 10000;
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (!m_pInstance) return;
+ if (pTarget && pTarget->isAlive())
+ doRemove(SPELL_OOZE_ADHESIVE, pTarget);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (!m_pInstance || !who || who->GetTypeId() != TYPEID_PLAYER) return;
+
+ if (!pTarget || pTarget != who ) pTarget = who;
+ else return;
+
+ delay = 10000;
+
+ if (pTarget)
+ {
+ doAura(SPELL_OOZE_ADHESIVE, pTarget);
+ }
+ DoStartMovement(pTarget);
+ }
+
+ void JustReachedHome()
+ {
+ if (!m_pInstance) return;
+ m_creature->ForcedDespawn();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance ) return;
+
+ if ((m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS) || finita)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (!pTarget) Aggro(m_creature->getVictim());
+
+ if (timedQuery(SPELL_SOUL_FEAST, uiDiff))
+ {
+ doCast(SPELL_SOUL_FEAST);
+ }
+
+ if (delay <= uiDiff)
+ {
+ if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, 3.0f))
+ {
+ doCast(SPELL_OOZE_ERUPTION);
+ doRemove(SPELL_OOZE_ADHESIVE, pTarget);
+ finita = true;
+ };
+ } else delay -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_icc_volatile_ooze(Creature* pCreature)
+{
+ return new mob_icc_volatile_oozeAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_choking_gas_bombAI : public ScriptedAI
+{
+ mob_choking_gas_bombAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool finita;
+ uint32 copy_timer;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetInCombatWithZone();
+ m_creature->SetDisplayId(11686);
+ SetCombatMovement(false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->CastSpell(m_creature, SPELL_ORANGE_RADIATION, false);
+ finita = false;
+ copy_timer = 8000;
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void JustReachedHome()
+ {
+ return;
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (finita) return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) return;
+
+ if (m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->HasAura(SPELL_CHOKING_GAS))
+ m_creature->CastSpell(m_creature, SPELL_CHOKING_GAS, false);
+
+ if (!finita && m_creature->HasAura(SPELL_CHOKING_GAS_EXPLODE_TRIGGER))
+ {
+// m_creature->CastSpell(m_creature,SPELL_CHOKING_GAS_EXPLODE,false);
+ finita = true;
+ }
+
+ if (!finita)
+ {
+ if (copy_timer <= uiDiff)
+ {
+ float fPosX, fPosY, fPosZ;
+ m_creature->GetPosition(fPosX, fPosY, fPosZ);
+ if (Creature* pCopy = m_creature->SummonCreature(m_creature->GetEntry(), fPosX, fPosY, fPosZ, 0, TEMPSUMMON_TIMED_DESPAWN, 11200))
+ pCopy->CastSpell(pCopy, SPELL_CHOKING_GAS_EXPLODE_TRIGGER, false);
+ copy_timer = 3600000;
+ } else copy_timer -= uiDiff;
+ }
+
+ }
+
+};
+
+CreatureAI* GetAI_mob_choking_gas_bomb(Creature* pCreature)
+{
+ return new mob_choking_gas_bombAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_ooze_puddleAI : public ScriptedAI
+{
+ mob_ooze_puddleAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+ float m_Size;
+ float m_Size0;
+ uint32 grow_timer;
+
+ void Reset()
+ {
+ if(!m_pInstance) return;
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetDisplayId(11686);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetInCombatWithZone();
+ SetCombatMovement(false);
+ m_Size0 = m_creature->GetObjectScale();
+ if (m_Size0 > 1.0f)
+ {
+ m_creature->SetObjectScale(1.0f);
+ m_Size0 = 1.0f;
+ }
+ m_Size = m_Size0;
+ grow_timer = 500;
+ }
+
+ void AttackStart(Unit *who)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance) return;
+
+ if (m_pInstance->GetData(TYPE_PUTRICIDE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->HasAura(SPELL_SLIME_PUDDLE))
+ m_creature->CastSpell(m_creature, SPELL_SLIME_PUDDLE, false);
+
+ // Override especially for clean core
+ if (m_Size / m_Size0 >= 2.6f) m_creature->ForcedDespawn();
+
+ if (grow_timer <= uiDiff)
+ {
+ m_Size = m_Size*1.01;
+ m_creature->SetObjectScale(m_Size);
+ grow_timer = 500;
+ } else grow_timer -= uiDiff;
+ }
+
+};
+
+CreatureAI* GetAI_mob_ooze_puddle(Creature* pCreature)
+{
+ return new mob_ooze_puddleAI(pCreature);
+}
+
+void AddSC_boss_proffesor_putricide()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_proffesor_putricide";
+ newscript->GetAI = &GetAI_boss_proffesor_putricide;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_icc_volatile_ooze";
+ newscript->GetAI = &GetAI_mob_icc_volatile_ooze;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_icc_gas_cloud";
+ newscript->GetAI = &GetAI_mob_icc_gas_cloud;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_choking_gas_bomb";
+ newscript->GetAI = &GetAI_mob_choking_gas_bomb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ooze_puddle";
+ newscript->GetAI = &GetAI_mob_ooze_puddle;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp
index 12939b8..3082050 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_rotface.cpp
@@ -16,9 +16,425 @@
/* ScriptData
SDName: boss_rotface
-SD%Complete: 0%
-SDComment:
+SD%Complete: 80%
+SDComment: by /dev/rsa. Need correct timers && infection logic
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need correct timers
#include "precompiled.h"
+#include "def_spire.h"
+
+enum BossSpells
+{
+ SPELL_OOZE_FLOOD = 69789,
+ SPELL_OOZE_FLOOD_0 = 69788,
+ SPELL_OOZE_FLOOD_1 = 69783,
+ SPELL_SLIME_SPRAY = 69508,
+ SPELL_MUTATED_INFECTION_AURA = 69674,
+ SPELL_MUTATED_INFECTION = 70003,
+ SPELL_BERSERK = 47008,
+
+ SPELL_STICKY_OOZE = 69774,
+ SPELL_STICKY_AURA = 69776,
+ SPELL_MERGE_OOZE = 69889,
+ SPELL_RADIATING_OOZE = 69750,
+ SPELL_RADIATING_OOZE_1 = 69760,
+ SPELL_UNSTABLE_OOZE = 69644,
+ SPELL_UNSTABLE_OOZE_AURA = 69558,
+ SPELL_OOZE_EXPLODE = 69839,
+ SPELL_OOZE_EXPLODE_AURA = 69840,
+
+ NPC_BIG_OOZE = 36899,
+ NPC_SMALL_OOZE = 36897,
+ NPC_STICKY_OOZE = 37006,
+ NPC_OOZE_SPRAY_STALKER = 37986,
+ NPC_OOZE_STALKER = 37013,
+ NPC_OOZE_EXPLODE_STALKER = 38107,
+};
+
+static Locations SpawnLoc[]=
+{
+ {4471.821289f, 3162.986084f, 360.38501f}, // 0
+ {4471.821289f, 3110.452148f, 360.38501f}, // 1
+ {4418.825684f, 3110.452148f, 360.38501f}, // 2
+ {4418.825684f, 3162.986084f, 360.38501f}, // 3
+};
+
+
+struct MANGOS_DLL_DECL boss_rotfaceAI : public BSWScriptedAI
+{
+ boss_rotfaceAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+ bool intro;
+ bool pet;
+ bool nexttick;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ if (m_creature->isAlive()) pInstance->SetData(TYPE_ROTFACE, NOT_STARTED);
+ stage = 0;
+ intro = false;
+ pet = false;
+ nexttick = false;
+ resetTimers();
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ ScriptedAI::MoveInLineOfSight(pWho);
+ if(!pInstance || intro) return;
+ if (pWho->GetTypeId() != TYPEID_PLAYER) return;
+
+ pInstance->SetData(TYPE_EVENT, 600);
+ debug_log("EventMGR: creature %u send signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT));
+ intro = true;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631222,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631223,m_creature,pVictim);
+ break;
+ }
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_ROTFACE, IN_PROGRESS);
+ DoScriptText(-1631221,m_creature,who);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_ROTFACE, DONE);
+ DoScriptText(-1631224,m_creature, killer);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if(!pInstance) return;
+
+ if (!pet)
+ {
+ if (Creature* pGuard = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_PRECIOUS)))
+ if (!pGuard->isAlive())
+ {
+ pet = true;
+ if (pInstance->GetData(TYPE_PRECIOUS) == NOT_STARTED)
+ {
+ DoScriptText(-1631228,m_creature);
+ pInstance->SetData(TYPE_PRECIOUS,DONE);
+ }
+ }
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (nexttick)
+ {
+ doCast(SPELL_OOZE_FLOOD_1);
+ DoScriptText(-1631227,m_creature);
+ nexttick = false;
+ };
+
+ if (timedQuery(SPELL_OOZE_FLOOD_1, diff))
+ {
+ uint8 i = urand(0,3);
+ if (Unit* pTemp = doSummon(NPC_OOZE_STALKER,SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z, TEMPSUMMON_TIMED_DESPAWN, 15000))
+ {
+ doCast(SPELL_OOZE_FLOOD, pTemp);
+ nexttick = true;
+ }
+ };
+
+ if (timedQuery(SPELL_SLIME_SPRAY, diff))
+ if (doSummon(NPC_OOZE_SPRAY_STALKER))
+ doCast(SPELL_SLIME_SPRAY);
+
+ if (timedQuery(SPELL_MUTATED_INFECTION, diff))
+ {
+ for(uint8 i = 0; i < getSpellData(SPELL_MUTATED_INFECTION); ++i)
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_MUTATED_INFECTION_AURA, false, 60.0f))
+ doCast(SPELL_MUTATED_INFECTION, pTarget);
+ DoScriptText(-1631226,m_creature);
+ }
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631225,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+
+CreatureAI* GetAI_boss_rotface(Creature* pCreature)
+{
+ return new boss_rotfaceAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_small_oozeAI : public BSWScriptedAI
+{
+ mob_small_oozeAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ resetTimers();
+ m_creature->SetRespawnDelay(7*DAY);
+ doCast(SPELL_RADIATING_OOZE);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5);
+ m_creature->SetSpeedRate(MOVE_WALK, 0.5);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_STICKY_OOZE, uiDiff);
+
+ if (Creature* pTemp = doSelectNearestCreature(m_creature->GetEntry(),7.0f))
+ {
+ doCast(SPELL_MERGE_OOZE, pTemp);
+ doSummon(NPC_BIG_OOZE);
+ pTemp->ForcedDespawn();
+ m_creature->ForcedDespawn();
+ };
+ }
+};
+
+CreatureAI* GetAI_mob_small_ooze(Creature* pCreature)
+{
+ return new mob_small_oozeAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_big_oozeAI : public BSWScriptedAI
+{
+ mob_big_oozeAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool exploded;
+
+ void Reset()
+ {
+ resetTimers();
+ m_creature->SetRespawnDelay(7*DAY);
+ doCast(SPELL_UNSTABLE_OOZE);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5);
+ m_creature->SetSpeedRate(MOVE_WALK, 0.5);
+ exploded = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_STICKY_OOZE, uiDiff);
+
+ if (Creature* pSmall = doSelectNearestCreature(NPC_SMALL_OOZE,5.0f))
+ {
+ pSmall->ForcedDespawn();
+ doCast(SPELL_UNSTABLE_OOZE);
+ };
+
+ if (Creature* pBig = doSelectNearestCreature(NPC_BIG_OOZE, 8.0f))
+ {
+ pBig->ForcedDespawn();
+ doCast(SPELL_UNSTABLE_OOZE);
+ }
+
+ if ( auraCount(SPELL_UNSTABLE_OOZE_AURA) > 4 && !exploded)
+ {
+ doCast(SPELL_OOZE_EXPLODE);
+ exploded = true;
+ }
+
+ }
+};
+
+CreatureAI* GetAI_mob_big_ooze(Creature* pCreature)
+{
+ return new mob_big_oozeAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_sticky_oozeAI : public ScriptedAI
+{
+ mob_sticky_oozeAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(11686);
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->CastSpell(m_creature, SPELL_STICKY_AURA, true);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWithZone();
+ SetCombatMovement(false);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ }
+};
+
+CreatureAI* GetAI_mob_sticky_ooze(Creature* pCreature)
+{
+ return new mob_sticky_oozeAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_ooze_explode_stalkerAI : public BSWScriptedAI
+{
+ mob_ooze_explode_stalkerAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ Creature* creator;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(11686);
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ m_creature->SetInCombatWithZone();
+ doCast(SPELL_OOZE_EXPLODE_AURA);
+ creator = doSelectNearestCreature(NPC_BIG_OOZE, 20.0f);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (creator && creator->isAlive())
+ creator->ForcedDespawn();
+
+ if (timedQuery(SPELL_OOZE_EXPLODE_AURA, uiDiff))
+ m_creature->ForcedDespawn();
+
+ }
+};
+
+CreatureAI* GetAI_mob_ooze_explode_stalker(Creature* pCreature)
+{
+ return new mob_ooze_explode_stalkerAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_ooze_spray_stalkerAI : public ScriptedAI
+{
+ mob_ooze_spray_stalkerAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ SetCombatMovement(false);
+ m_creature->SetDisplayId(11686);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_ROTFACE) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+ }
+};
+
+CreatureAI* GetAI_mob_ooze_spray_stalker(Creature* pCreature)
+{
+ return new mob_ooze_spray_stalkerAI(pCreature);
+}
+
+void AddSC_boss_rotface()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_rotface";
+ newscript->GetAI = &GetAI_boss_rotface;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_small_ooze";
+ newscript->GetAI = &GetAI_mob_small_ooze;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_big_ooze";
+ newscript->GetAI = &GetAI_mob_big_ooze;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_sticky_ooze";
+ newscript->GetAI = &GetAI_mob_sticky_ooze;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ooze_explode_stalker";
+ newscript->GetAI = &GetAI_mob_ooze_explode_stalker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ooze_spray_stalker";
+ newscript->GetAI = &GetAI_mob_ooze_spray_stalker;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp
index 9aa17a3..50129c9 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_sindragosa.cpp
@@ -16,9 +16,651 @@
/* ScriptData
SDName: boss_sindragosa
-SD%Complete: 0%
-SDComment:
+SD%Complete: 80%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need correct timers and models
#include "precompiled.h"
+#include "def_spire.h"
+
+enum BossSpells
+{
+// Sindragosa
+ SPELL_FROST_AURA_1 = 70084,
+ SPELL_CLEAVE_1 = 19983,
+ SPELL_TAIL_SMASH = 71077,
+ SPELL_FROST_BREATH_1 = 69649,
+ SPELL_PERMEATING_CHILL = 70107,
+ SPELL_UNCHAINED_MAGIC = 69762,
+ SPELL_INSTABILITY = 69766,
+ SPELL_ICY_GRIP = 70117,
+ SPELL_BLISTERING_COLD = 70123,
+
+ SPELL_FROST_BEACON = 70126,
+ SPELL_ICY_TOMB = 70157,
+ SPELL_ASPHYXATION = 71665,
+ SPELL_FROST_BOMB = 71053,
+ SPELL_FROST_BOMB_TRIGGER = 69846,
+ SPELL_FROST_BOMB_VISUAL = 64624,
+ SPELL_FROST_BOMB_VISUAL2 = 69016,
+ SPELL_ICE_TOMB_TRIGGER = 69675,
+ SPELL_MYSTIC_BUFFET = 70128,
+
+ NPC_ICE_TOMB = 36980,
+ NPC_FROST_BOMB = 37186,
+
+ QUEST_24757 = 72289,
+ SPELL_BERSERK = 47008,
+
+// Rimefang
+ SPELL_FROST_AURA = 71387,
+ SPELL_FROST_BREATH = 71386,
+ SPELL_ICY_BLAST = 71376,
+// Spinestalker
+ SPELL_BELLOWING_ROAR = 36922,
+ SPELL_CLEAVE = 40505,
+ SPELL_TAIL_SWEEP = 71369,
+};
+
+static Locations SpawnLoc[]=
+{
+ {4408.052734f, 2484.825439f, 203.374207f}, // 0 Sindragosa spawn
+ {4474.239746f, 2484.243896f, 231.0f}, // 1 Sindragosa fly o=3.11
+ {4474.239746f, 2484.243896f, 203.380402f}, // 2 Sindragosa fly - ground point o=3.11
+};
+
+struct MANGOS_DLL_DECL boss_sindragosaAI : public BSWScriptedAI
+{
+ boss_sindragosaAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+ uint8 icecount;
+ bool MovementStarted;
+ Unit* marked[5];
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ resetTimers();
+ stage = 0;
+ memset(&marked, 0, sizeof(marked));
+
+ m_creature->SetRespawnDelay(7*DAY);
+ switch (currentDifficulty) {
+ case RAID_DIFFICULTY_10MAN_NORMAL:
+ icecount = 2;
+ break;
+ case RAID_DIFFICULTY_10MAN_HEROIC:
+ icecount = 2;
+ break;
+ case RAID_DIFFICULTY_25MAN_NORMAL:
+ icecount = 5;
+ break;
+ case RAID_DIFFICULTY_25MAN_HEROIC:
+ icecount = 5;
+ break;
+ default:
+ icecount = 2;
+ break;
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631421,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631422,m_creature,pVictim);
+ break;
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance)
+ return;
+ pInstance->SetData(TYPE_SINDRAGOSA, FAIL);
+ doRemoveFromAll(SPELL_ICY_TOMB);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_RIMEFANG)))
+ pTemp->Respawn();
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SPINESTALKER)))
+ pTemp->Respawn();
+ DoScriptText(-1631422,m_creature);
+ m_creature->ForcedDespawn();
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ DoScriptText(-1631420,m_creature,who);
+ doCast(SPELL_FROST_AURA_1);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (!pInstance)
+ return;
+ doRemoveFromAll(SPELL_ICY_TOMB);
+ pInstance->SetData(TYPE_SINDRAGOSA, DONE);
+ DoScriptText(-1631423,m_creature,killer);
+ doCast(QUEST_24757);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (!pInstance)
+ return;
+
+ if (type != POINT_MOTION_TYPE || !MovementStarted) return;
+
+ if (id == 1) {
+ m_creature->GetMotionMaster()->MovementExpired();
+ MovementStarted = false;
+ }
+ }
+
+ void doBlisteringCold()
+ {
+ doCast(SPELL_ICY_GRIP);
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &pList = pMap->GetPlayers();
+ if (pList.isEmpty()) return;
+
+ for (Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i)
+ if (Player* player = i->getSource())
+ if (player->isAlive() && player->IsWithinDistInMap(m_creature, 30.0f))
+ {
+ float fPosX, fPosY, fPosZ;
+ m_creature->GetPosition(fPosX, fPosY, fPosZ);
+ m_creature->GetRandomPoint(fPosX, fPosY, fPosZ, 1.0f, fPosX, fPosY, fPosZ);
+ player->NearTeleportTo(fPosX, fPosY, fPosZ+1.0f, (float)(urand(0,6)), true);
+ }
+ doCast(SPELL_BLISTERING_COLD);
+ }
+
+ void IceMark()
+ {
+ memset(&marked, 0, sizeof(marked));
+
+ for (uint8 i = 0; i < icecount; i++)
+ if (marked[i] = doSelectRandomPlayer(SPELL_FROST_BEACON, false, 200.0f))
+ doCast(SPELL_FROST_BEACON, marked[i]);
+ }
+
+ void IceBlock()
+ {
+ for (uint8 i = 0; i < icecount; i++)
+ if (marked[i] && marked[i]->isAlive())
+ {
+ doCast(SPELL_ICY_TOMB, marked[i]);
+ marked[i]->RemoveAurasDueToSpell(SPELL_FROST_BEACON);
+ float fPosX, fPosY, fPosZ;
+ marked[i]->GetPosition(fPosX, fPosY, fPosZ);
+ if (Unit* pTemp1 = doSummon(NPC_ICE_TOMB,fPosX, fPosY, fPosZ))
+ pTemp1->AddThreat(marked[i], 1000.0f);
+ };
+
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(stage)
+ {
+ case 0:
+ timedCast(SPELL_CLEAVE_1, diff);
+ timedCast(SPELL_TAIL_SMASH, diff);
+ timedCast(SPELL_FROST_BREATH_1, diff);
+ timedCast(SPELL_PERMEATING_CHILL, diff);
+
+ timedCast(SPELL_UNCHAINED_MAGIC, diff);
+
+ if (timedQuery(SPELL_ICY_GRIP, diff))
+ {
+ DoScriptText(-1631426,m_creature);
+ doBlisteringCold();
+ }
+
+ if (timedQuery(SPELL_FROST_BEACON, diff) && m_creature->GetHealthPercent() < 85.0f) stage = 1;
+
+ if (m_creature->GetHealthPercent() < 35.0f)
+ {
+ doCast(SPELL_MYSTIC_BUFFET);
+ stage = 9;
+ DoScriptText(-1631429,m_creature);
+ }
+ break;
+ case 1:
+ DoScriptText(-1631425,m_creature);
+ IceMark();
+ stage = 2;
+ MovementStarted = true;
+ SetCombatMovement(false);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_UP);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ break;
+ case 2:
+ if (!MovementStarted) {
+ stage = 3;
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_FLY_FALL);
+ };
+ break;
+ case 3:
+ stage = 4;
+ IceBlock();
+ m_creature->SetOrientation(3.1f);
+ break;
+ case 4:
+ if (timedQuery(SPELL_FROST_BOMB, diff))
+ if (Unit* pTemp = doSelectRandomPlayerAtRange(300.0f))
+ doCast(SPELL_FROST_BOMB_TRIGGER, pTemp);
+
+ timedCast(SPELL_FROST_BREATH_1, diff);
+
+ if (timedQuery(SPELL_FROST_BEACON, diff)) {
+ stage = 5;
+ }
+ break;
+ case 5:
+ MovementStarted = true;
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MovePoint(1, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z);
+ stage = 6;
+ m_creature->HandleEmoteCommand(EMOTE_STATE_FLY_SIT_GROUND);
+ break;
+ case 6:
+ if (!MovementStarted) {
+ stage = 0;
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING);
+ };
+ break;
+
+ case 9:
+ timedCast(SPELL_CLEAVE_1, diff);
+ timedCast(SPELL_TAIL_SMASH, diff);
+ timedCast(SPELL_FROST_BREATH_1, diff);
+ timedCast(SPELL_PERMEATING_CHILL, diff);
+ timedCast(SPELL_UNCHAINED_MAGIC, diff);
+
+ if (timedQuery(SPELL_ICY_GRIP, diff))
+ {
+ DoScriptText(-1631426,m_creature);
+ doBlisteringCold();
+ }
+
+ break;
+ default: break;
+ }
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631424,m_creature);
+ };
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+
+CreatureAI* GetAI_boss_sindragosa(Creature* pCreature)
+{
+ return new boss_sindragosaAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_ice_tombAI : public BSWScriptedAI
+{
+ mob_ice_tombAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint64 victimGUID;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ victimGUID = 0;
+ m_creature->SetRespawnDelay(7*DAY);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!victimGUID && pWho && pWho->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (pWho->HasAura(SPELL_ICY_TOMB))
+ {
+ victimGUID = pWho->GetGUID();
+ m_creature->SetInCombatWith(pWho);
+ }
+ else if (Unit* pTarget = doSelectRandomPlayer(SPELL_ICY_TOMB,true,3.0f))
+ {
+ victimGUID = pTarget->GetGUID();
+ m_creature->SetInCombatWith(pTarget);
+ }
+
+ }
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth())
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID))
+ doRemove(SPELL_ICY_TOMB, pVictim);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ }
+
+ void KilledUnit(Unit* _Victim)
+ {
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID))
+ doRemove(SPELL_ICY_TOMB,pVictim);
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID))
+ doRemove(SPELL_ICY_TOMB,pVictim);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if ((m_pInstance && m_pInstance->GetData(TYPE_SINDRAGOSA) != IN_PROGRESS)
+ || (victimGUID && !m_creature->GetMap()->GetPlayer(victimGUID)->HasAura(SPELL_ICY_TOMB)))
+ {
+ if (Player* pVictim = m_creature->GetMap()->GetPlayer(victimGUID))
+ doRemove(SPELL_ICY_TOMB,pVictim);
+ m_creature->ForcedDespawn();
+ }
+ }
+
+};
+
+CreatureAI* GetAI_mob_ice_tomb(Creature* pCreature)
+{
+ return new mob_ice_tombAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_frost_bombAI : public ScriptedAI
+{
+ mob_frost_bombAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+ uint32 boom_timer;
+ uint32 visual_timer;
+ bool finita;
+
+ void Reset()
+ {
+ SetCombatMovement(false);
+ m_creature->SetRespawnDelay(7*DAY);
+ visual_timer = 6000;
+ boom_timer = 9000;
+ finita = false;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance && m_pInstance->GetData(TYPE_SINDRAGOSA) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (finita)
+ {
+ m_creature->CastSpell(m_creature, SPELL_FROST_BOMB, true);
+ m_creature->ForcedDespawn();
+ }
+
+ if (visual_timer <= uiDiff)
+ {
+ m_creature->CastSpell(m_creature, SPELL_FROST_BOMB_VISUAL, true);
+ visual_timer= DAY;
+ }
+ else visual_timer -= uiDiff;
+
+ if (boom_timer <= uiDiff)
+ {
+ m_creature->CastSpell(m_creature,SPELL_FROST_BOMB_VISUAL2,false);
+ finita = true;
+ }
+ else boom_timer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_frost_bomb(Creature* pCreature)
+{
+ return new mob_frost_bombAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_rimefangAI : public BSWScriptedAI
+{
+ mob_rimefangAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ Creature* pBrother;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE)
+ pInstance->SetData(TYPE_SINDRAGOSA, NOT_STARTED);
+ resetTimers();
+ m_creature->SetRespawnDelay(30*MINUTE);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pInstance || !pWho) return;
+
+ if (pWho->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (!m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 60.0f))
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
+ m_creature->GetMotionMaster()->MovementExpired();
+ AttackStart(pWho);
+ SetCombatMovement(true);
+ }
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance)
+ if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE)
+ pInstance->SetData(TYPE_SINDRAGOSA, FAIL);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) pInstance->SetData(TYPE_SINDRAGOSA, IN_PROGRESS);
+ pBrother = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SPINESTALKER));
+ if (pBrother && !pBrother->isAlive()) pBrother->Respawn();
+ if (pBrother) pBrother->SetInCombatWithZone();
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+ if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE) return;
+ if (pBrother && !pBrother->isAlive())
+ m_creature->SummonCreature(NPC_SINDRAGOSA, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 3.17f, TEMPSUMMON_MANUAL_DESPAWN, DESPAWN_TIME);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!pInstance || !m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE)
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->ForcedDespawn();
+ return;
+ }
+
+ doCastAll(diff);
+ DoMeleeAttackIfReady();
+ }
+};
+
+
+CreatureAI* GetAI_mob_rimefang(Creature* pCreature)
+{
+ return new mob_rimefangAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_spinestalkerAI : public BSWScriptedAI
+{
+ mob_spinestalkerAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ Creature* pBrother;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE)
+ pInstance->SetData(TYPE_SINDRAGOSA, NOT_STARTED);
+ resetTimers();
+ m_creature->SetRespawnDelay(30*MINUTE);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pInstance || !pWho) return;
+
+ if (pWho->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (!m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 60.0f))
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
+ m_creature->GetMotionMaster()->MovementExpired();
+ AttackStart(pWho);
+ SetCombatMovement(true);
+ }
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance)
+ if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE)
+ pInstance->SetData(TYPE_SINDRAGOSA, FAIL);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ if (pInstance->GetData(TYPE_SINDRAGOSA) != DONE) pInstance->SetData(TYPE_SINDRAGOSA, IN_PROGRESS);
+ pBrother = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_RIMEFANG));
+ if (pBrother && !pBrother->isAlive()) pBrother->Respawn();
+ if (pBrother) pBrother->SetInCombatWithZone();
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (!pInstance) return;
+ if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE) return;
+ if (pBrother && !pBrother->isAlive())
+ m_creature->SummonCreature(NPC_SINDRAGOSA, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 3.17f, TEMPSUMMON_MANUAL_DESPAWN, DESPAWN_TIME);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (!pInstance || !m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (pInstance->GetData(TYPE_SINDRAGOSA) == DONE)
+ {
+ m_creature->SetRespawnDelay(DAY);
+ m_creature->ForcedDespawn();
+ return;
+ }
+
+ doCastAll(diff);
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_spinestalker(Creature* pCreature)
+{
+ return new mob_spinestalkerAI(pCreature);
+}
+
+void AddSC_boss_sindragosa()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_sindragosa";
+ newscript->GetAI = &GetAI_boss_sindragosa;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_rimefang";
+ newscript->GetAI = &GetAI_mob_rimefang;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_spinestalker";
+ newscript->GetAI = &GetAI_mob_spinestalker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ice_tomb";
+ newscript->GetAI = &GetAI_mob_ice_tomb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_bomb";
+ newscript->GetAI = &GetAI_mob_frost_bomb;
+ newscript->RegisterSelf();
+
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_the_lich_king.cpp
index d51e2e5..f61d9c1 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
@@ -16,9 +16,1210 @@
/* ScriptData
SDName: boss_the_lich_king
-SD%Complete: 0%
-SDComment:
+SD%Complete: 70%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need implement "in sword" phase
#include "precompiled.h"
+#include "def_spire.h"
+
+enum BossSpells
+{
+ SPELL_INFEST = 70541,
+ SPELL_NECROTIC_PLAGUE = 70337,
+ SPELL_PLAGUE_SIPHON = 74074,
+ SPELL_SOUL_REAPER = 69409,
+ SPELL_SPAWN_DEFILE = 72762,
+ SPELL_HARVEST_SOUL = 68980,
+ SPELL_HARVEST_SOUL_TELEPORT = 71372,
+//
+ SPELL_CHANNEL_KING = 71769,
+ SPELL_BROKEN_FROSTMOURNE = 72398,
+ SPELL_BOOM_VISUAL = 72726,
+ SPELL_ICEBLOCK_TRIGGER = 71614,
+ SPELL_TIRION_LIGHT = 71797,
+ SPELL_FROSTMOURNE_TRIGGER = 72405,
+ SPELL_SUMMON_BROKEN_FROSTMOURNE = 72406,
+ SPELL_SUMMON_BROKEN_FROSTMOURNE_2 = 73017,
+ SPELL_DISENGAGE = 61508,
+ SPELL_FURY_OF_FROSTMOURNE = 70063,
+ SPELL_REVIVE_VISUAL = 37755, //Override?
+ SPELL_REVIVE = 51918,
+ SPELL_CLONE_PLAYER = 57507,
+ SPELL_BERSERK = 47008,
+
+//Transition phase
+ SPELL_REMORSELESS_WINTER = 68981,
+ SPELL_PAIN_AND_SUFFERING = 72133,
+ SPELL_QUAKE = 72262,
+
+//Raging spirit
+// SPELL_SUMMON_RAGING_SPIRIT = 69201, // triggered
+ SPELL_SUMMON_RAGING_SPIRIT = 69200,
+ SPELL_SOUL_SHRIEK = 69242,
+
+//Ice sphere
+ SPELL_SUMMON_ICE_SPHERE = 69103,
+ SPELL_ICE_PULSE = 69099,
+ SPELL_ICE_BURST = 69108,
+ SPELL_ICE_SPHERE_VISUAL = 69090,
+
+//Drudge ghouls
+ SPELL_SUMMON_DRUDGE_GHOULS = 70358,
+
+//Shambling horror
+ SPELL_SUMMON_SHAMBLING_HORROR = 70372,
+ SPELL_SHOCKWAVE = 72149,
+ SPELL_HORROR_ENRAGE = 72143,
+
+//Vile spirits
+ SPELL_SUMMON_VILE_SPIRITS = 70498,
+ SPELL_SPIRITS_BURST = 70503,
+
+//Valkyr
+ SPELL_SUMMON_VALKYR = 69037,
+ NPC_VALKYR = 36609,
+ SPELL_WINGS_OF_THE_DAMNED = 74352,
+
+//Defile
+ SPELL_DEFILE = 72743,
+
+// Menethil
+ SPELL_REVALL = 26687,
+//
+ NPC_ICE_SPHERE = 36633,
+ NPC_DEFILER = 38757,
+ NPC_RAGING_SPIRIT = 36701,
+ NPC_VILE_SPIRIT = 37799,
+ NPC_STRANGULATE_VEHICLE = 36598,
+
+};
+
+enum Common
+{
+ FINAL_ARTHAS_MOVIE = 16,
+};
+
+static Locations SpawnLoc[]=
+{
+ {459.93689f, -2124.638184f, 1040.860107f}, // 0 Lich King Intro
+ {503.15652f, -2124.516602f, 1040.860107f}, // 1 Lich king move end
+ {491.27118f, -2124.638184f, 1040.860107f}, // 2 Tirion 1
+ {481.69797f, -2124.638184f, 1040.860107f}, // 3 Tirion 2
+ {498.00448f, -2201.573486f, 1046.093872f}, // 4 Valkyrs?
+ {517.48291f, -2124.905762f, 1040.861328f}, // 5 Tirion?
+ {529.85302f, -2124.709961f, 1040.859985f}, // 6 Lich king final, o=3.1146
+ {520.311f, -2124.709961f, 1040.859985f}, // 7 Frostmourne
+};
+
+struct MANGOS_DLL_DECL boss_the_lich_king_iccAI : public BSWScriptedAI
+{
+ boss_the_lich_king_iccAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (instance_icecrown_spire*)pCreature->GetInstanceData();
+ oldflag = 0;
+ Reset();
+ }
+
+ instance_icecrown_spire* pInstance;
+ uint8 stage;
+ uint32 nextEvent;
+ uint32 nextPoint;
+ uint32 UpdateTimer;
+ uint32 oldflag;
+ bool movementstarted;
+ bool battlestarted;
+ bool finalphase;
+ Creature* pTirion;
+ Creature* pFrostmourne;
+ std::list mobsGUIDList;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ resetTimers();
+ mobsGUIDList.clear();
+ stage = 0;
+ nextEvent = 0;
+ nextPoint = 0;
+ movementstarted = false;
+ battlestarted = false;
+ finalphase = false;
+ m_creature->SetOrientation(0.0f);
+ pInstance->CloseDoor(pInstance->GetData64(GO_ICESHARD_1));
+ pInstance->CloseDoor(pInstance->GetData64(GO_ICESHARD_2));
+ pInstance->CloseDoor(pInstance->GetData64(GO_ICESHARD_3));
+ pInstance->CloseDoor(pInstance->GetData64(GO_ICESHARD_4));
+ if (oldflag)
+ if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM)))
+ {
+ pGoFloor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
+ pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,oldflag);
+ }
+ pInstance->CloseDoor(pInstance->GetData64(GO_FROSTY_WIND));
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ }
+
+ void EnterEvadeMode()
+ {
+ if (!pInstance) return;
+ if (finalphase && pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS) return;
+
+ DespawnMobs();
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ if (m_creature->isAlive())
+ m_creature->GetMotionMaster()->MoveTargetedHome();
+
+ m_creature->SetLootRecipient(NULL);
+
+ Reset();
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || !movementstarted) return;
+ if (id == nextPoint)
+ {
+ movementstarted = false;
+ pInstance->SetData(TYPE_EVENT,nextEvent);
+ m_creature->GetMotionMaster()->MovementExpired();
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+
+ if (!battlestarted) return;
+
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631519,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631517,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance) return;
+ pInstance->SetData(TYPE_LICH_KING, FAIL);
+ stage = 0;
+ battlestarted = false;
+ finalphase = false;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+
+ void StartMovement(uint32 id, uint32 _nextEvent)
+ {
+ nextPoint = id;
+ nextEvent = _nextEvent;
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
+ pInstance->SetData(TYPE_EVENT,0);
+ movementstarted = true;
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned) return;
+
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(60.0f))
+ {
+ summoned->SetInCombatWith(pTarget);
+ summoned->AddThreat(pTarget,100.0f);
+ }
+ mobsGUIDList.push_back(summoned->GetGUID());
+ }
+
+ void DespawnMobs()
+ {
+ if (mobsGUIDList.empty())
+ return;
+
+ for(std::list::iterator itr = mobsGUIDList.begin(); itr != mobsGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ if (pTemp->isAlive())
+ {
+ pTemp->DeleteThreatList();
+ pTemp->CombatStop(true);
+ pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+ mobsGUIDList.clear();
+ }
+
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+ pInstance->SetData(TYPE_LICH_KING, DONE);
+ DoScriptText(-1631528,m_creature,killer);
+
+ pInstance->SetData(TYPE_EVENT,14010);
+ DespawnMobs();
+
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if(!pInstance) return;
+
+ if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_LICH_KING)
+ {
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+ if (UpdateTimer <= diff)
+ {
+ debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT));
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 12000:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ StartMovement(0,12020);
+ break;
+ case 12020:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
+ DoScriptText(-1631501, m_creature);
+ UpdateTimer = 12000;
+ pInstance->SetData(TYPE_EVENT,12030);
+ break;
+ case 12040:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
+ DoScriptText(-1631503, m_creature);
+ UpdateTimer = 8000;
+ pInstance->SetData(TYPE_EVENT,12041);
+ break;
+ case 12041:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LAUGH);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,12042);
+ break;
+ case 12042:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_ONESHOT_POINT_NOSHEATHE);
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,12043);
+ break;
+ case 12043:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_ONESHOT_NONE);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,12050);
+ break;
+ case 12060:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
+ DoScriptText(-1631505, m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,12080);
+ break;
+ case 12080:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_STATE_READY2H);
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,12100);
+ break;
+ case 12100:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_ONESHOT_NONE);
+ UpdateTimer = 6000;
+ pInstance->SetData(TYPE_EVENT,12120);
+ break;
+ case 12120:
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(true);
+ m_creature->SetInCombatWithZone();
+ battlestarted = true;
+ pInstance->SetData(TYPE_EVENT,12200);
+ UpdateTimer = 10000;
+ break;
+ case 12200:
+ DoScriptText(-1631506, m_creature);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,12220);
+ break;
+ case 13000:
+ m_creature->SetOrientation(3.1146f);
+ DoScriptText(-1631507, m_creature);
+ UpdateTimer = 12000;
+ finalphase = true;
+ doCast(SPELL_FURY_OF_FROSTMOURNE);
+ pInstance->SetData(TYPE_EVENT,13020);
+ if (pTirion = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_TIRION))) {
+ m_creature->SetInCombatWith(pTirion);
+ pTirion->AddThreat(m_creature, 1000.0f);
+ }
+ m_creature->SetInCombatWithZone();
+ break;
+ case 13020:
+ DoScriptText(-1631508, m_creature);
+ UpdateTimer = 12000;
+ pInstance->SetData(TYPE_EVENT,13060);
+ break;
+ case 13060:
+ DoScriptText(-1631509, m_creature);
+ UpdateTimer = 15000;
+ pInstance->SetData(TYPE_EVENT,13100);
+ break;
+ case 13100:
+ DoScriptText(-1631510, m_creature);
+ UpdateTimer = 15000;
+ pInstance->SetData(TYPE_EVENT,13110);
+ doCast(SPELL_CHANNEL_KING);
+ break;
+ case 13120:
+ DoScriptText(-1631511, m_creature);
+ UpdateTimer = 12000;
+ pInstance->SetData(TYPE_EVENT,13130);
+ break;
+ case 13140:
+ UpdateTimer = 6000;
+ doRemove(SPELL_CHANNEL_KING);
+ pInstance->SetData(TYPE_EVENT,13150);
+ m_creature->CastSpell(m_creature, SPELL_SUMMON_BROKEN_FROSTMOURNE, false);
+ break;
+ case 13160:
+ UpdateTimer = 6000;
+ pInstance->SetData(TYPE_EVENT,13170);
+ m_creature->CastSpell(m_creature, SPELL_SUMMON_BROKEN_FROSTMOURNE_2, false);
+ break;
+ case 13180:
+ UpdateTimer = 12000;
+ pInstance->SetData(TYPE_EVENT,13190);
+ if (pFrostmourne = m_creature->SummonCreature(NPC_FROSTMOURNE_HOLDER, SpawnLoc[7].x, SpawnLoc[7].y, SpawnLoc[7].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 5000))
+ {
+ pFrostmourne->CastSpell(pFrostmourne, SPELL_BROKEN_FROSTMOURNE, false);
+ pFrostmourne->CastSpell(pFrostmourne, SPELL_FROSTMOURNE_TRIGGER, false);
+ pFrostmourne->GetMotionMaster()->MoveChase(m_creature);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ }
+ break;
+ case 13200:
+ DoScriptText(-1631512, m_creature);
+ m_creature->RemoveAurasDueToSpell(SPELL_SUMMON_BROKEN_FROSTMOURNE);
+ m_creature->RemoveAllAuras();
+ pFrostmourne->RemoveAurasDueToSpell(SPELL_FROSTMOURNE_TRIGGER);
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,13210);
+ break;
+ case 13280:
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,13290);
+ stage = 13;
+ if (pFrostmourne) pFrostmourne->ForcedDespawn();
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_FROSTMOURNE_TRIGGER)))
+ pTemp->ForcedDespawn();
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_FROSTMOURNE_HOLDER)))
+ pTemp->ForcedDespawn();
+ SetCombatMovement(true);
+ battlestarted = true;
+ break;
+ default:
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+ }
+
+ if (battlestarted && !m_creature->SelectHostileTarget() && !finalphase)
+ {
+ battlestarted = false;
+ pInstance->SetData(TYPE_LICH_KING, FAIL);
+ pInstance->SetData(TYPE_EVENT,0);
+ EnterEvadeMode();
+ return;
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(stage)
+ {
+ case 0: // Phase 1
+// timedCast(SPELL_SHOCKWAVE, diff);
+ timedCast(SPELL_INFEST, diff);
+ timedCast(SPELL_SUMMON_DRUDGE_GHOULS, diff);
+ timedCast(SPELL_PLAGUE_SIPHON, diff);
+ timedCast(SPELL_SUMMON_SHAMBLING_HORROR, diff);
+ timedCast(SPELL_NECROTIC_PLAGUE, diff);
+
+ DoMeleeAttackIfReady();
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631518,m_creature);
+ };
+
+ if (m_creature->GetHealthPercent() < 70.0f)
+ {
+ stage = 1;
+ DoScriptText(-1631515,m_creature);
+ }
+ break;
+ case 1: // Go in transition phase
+ m_creature->AttackStop();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ StartMovement(1,0);
+ stage = 2;
+ break;
+ case 2:
+ if (movementstarted) return;
+ doCast(SPELL_REMORSELESS_WINTER);
+ stage = 3;
+ break;
+ case 3:
+ timedCast(SPELL_SUMMON_RAGING_SPIRIT, diff);
+ timedCast(SPELL_SUMMON_ICE_SPHERE, diff);
+ timedCast(SPELL_PAIN_AND_SUFFERING, diff);
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631518,m_creature);
+ };
+
+ if (timedQuery(SPELL_REMORSELESS_WINTER, diff))
+ {
+ doCast(SPELL_QUAKE);
+ stage = 4;
+ DoScriptText(-1631524, m_creature);
+ pInstance->OpenDoor(pInstance->GetData64(GO_SNOW_EDGE));
+ };
+ break;
+ case 4: // Platform destruct
+ if (timedQuery(SPELL_QUAKE, diff))
+ {
+ pInstance->OpenDoor(pInstance->GetData64(GO_ICESHARD_1));
+ pInstance->OpenDoor(pInstance->GetData64(GO_ICESHARD_2));
+ pInstance->OpenDoor(pInstance->GetData64(GO_ICESHARD_3));
+ pInstance->OpenDoor(pInstance->GetData64(GO_ICESHARD_4));
+ if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM)))
+ {
+ pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
+ oldflag = pGoFloor->GetUInt32Value(GAMEOBJECT_BYTES_1);
+ pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449);
+ }
+ pInstance->CloseDoor(pInstance->GetData64(GO_FROSTY_WIND));
+ pInstance->CloseDoor(pInstance->GetData64(GO_SNOW_EDGE));
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(true);
+ stage = 5;
+ }
+ break;
+ case 5: // Phase 2
+
+ if (timedQuery(SPELL_SPAWN_DEFILE, diff))
+ {
+ doCast(SPELL_SPAWN_DEFILE);
+ DoScriptText(-1631531,m_creature);
+ }
+ if (timedQuery(SPELL_SUMMON_VALKYR, diff))
+ {
+ doCast(SPELL_SUMMON_VALKYR);
+ DoScriptText(-1631527,m_creature);
+ }
+
+ timedCast(SPELL_SOUL_REAPER, diff);
+ timedCast(SPELL_INFEST, diff);
+
+ DoMeleeAttackIfReady();
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631518,m_creature);
+ };
+
+ if (m_creature->GetHealthPercent() < 40.0f)
+ {
+ stage = 6;
+ DoScriptText(-1631523,m_creature);
+ }
+ break;
+ case 6: // Go in transition phase
+ m_creature->AttackStop();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ StartMovement(1,0);
+ stage = 7;
+ break;
+ case 7: // Platform restore
+ if (movementstarted) return;
+ if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM)))
+ {
+ pGoFloor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
+ pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,oldflag);
+ }
+ pInstance->OpenDoor(pInstance->GetData64(GO_FROSTY_WIND));
+ doCast(SPELL_REMORSELESS_WINTER);
+ stage = 8;
+ break;
+ case 8:
+ timedCast(SPELL_SUMMON_RAGING_SPIRIT, diff);
+ timedCast(SPELL_SUMMON_ICE_SPHERE, diff);
+ timedCast(SPELL_PAIN_AND_SUFFERING, diff);
+
+ if (timedQuery(SPELL_BERSERK, diff))
+ {
+ doCast(SPELL_BERSERK);
+ DoScriptText(-1631518,m_creature);
+ };
+
+ if (timedQuery(SPELL_REMORSELESS_WINTER, diff))
+ {
+ DoScriptText(-1631524, m_creature);
+ doCast(SPELL_SUMMON_VILE_SPIRITS);
+ for (uint8 i = 0; i < getSpellData(SPELL_SUMMON_VILE_SPIRITS); ++i)
+ doCast(NPC_VILE_SPIRIT);
+ doCast(SPELL_QUAKE);
+ stage = 9;
+ pInstance->OpenDoor(pInstance->GetData64(GO_SNOW_EDGE));
+ };
+
+ break;
+ case 9: // Platform destruct
+ if (timedQuery(SPELL_QUAKE, diff))
+ {
+ if (GameObject* pGoFloor = pInstance->instance->GetGameObject(pInstance->GetData64(GO_ARTHAS_PLATFORM)))
+ {
+ pGoFloor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
+ oldflag = pGoFloor->GetUInt32Value(GAMEOBJECT_BYTES_1);
+ pGoFloor->SetUInt32Value(GAMEOBJECT_BYTES_1,8449);
+ }
+ pInstance->CloseDoor(pInstance->GetData64(GO_SNOW_EDGE));
+ pInstance->CloseDoor(pInstance->GetData64(GO_FROSTY_WIND));
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(true);
+ stage = 10;
+ }
+ break;
+ case 10: // Phase 3
+ if (timedQuery(SPELL_SPAWN_DEFILE, diff))
+ {
+ doCast(SPELL_SPAWN_DEFILE);
+// DoScriptText(-1631527,m_creature);
+ }
+ timedCast(SPELL_SOUL_REAPER, diff);
+
+ if (timedQuery(SPELL_HARVEST_SOUL, diff))
+ {
+ doCast(SPELL_HARVEST_SOUL);
+ DoScriptText(-1631520,m_creature);
+ }
+
+ timedCast(SPELL_SOUL_REAPER, diff);
+ timedCast(SPELL_INFEST, diff);
+
+ DoMeleeAttackIfReady();
+
+ if (m_creature->GetHealthPercent() < 10.0f)
+ {
+ stage = 11;
+ DoScriptText(-1631513,m_creature);
+ }
+ break;
+ case 11: // Ending Phase start
+ m_creature->AttackStop();
+ SetCombatMovement(false);
+ StartMovement(6,13000);
+ stage = 12;
+ battlestarted = false;
+ break;
+ case 12:
+ break;
+ case 13:
+ DoMeleeAttackIfReady();
+ break;
+ }
+ }
+};
+
+
+CreatureAI* GetAI_boss_the_lich_king_icc(Creature* pCreature)
+{
+ return new boss_the_lich_king_iccAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL boss_tirion_iccAI : public ScriptedAI
+{
+ boss_tirion_iccAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 UpdateTimer;
+ uint32 nextEvent;
+ uint32 nextPoint;
+ bool movementstarted;
+ uint64 MenethilGUID;
+
+ void EnterEvadeMode()
+ {
+ if (!pInstance) return;
+ if (pInstance->GetData(TYPE_LICH_KING) == IN_PROGRESS) return;
+ ScriptedAI::EnterEvadeMode();
+ }
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ movementstarted = false;
+ m_creature->RemoveAurasDueToSpell(SPELL_ICEBLOCK_TRIGGER);
+ m_creature->SetOrientation(M_PI_F);
+ }
+
+ void StartMovement(uint32 id, uint32 _nextEvent)
+ {
+ nextPoint = id;
+ nextEvent = _nextEvent;
+ m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
+ pInstance->SetData(TYPE_EVENT,0);
+ movementstarted = true;
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || !movementstarted) return;
+ if (id == nextPoint)
+ {
+ movementstarted = false;
+ pInstance->SetData(TYPE_EVENT,nextEvent);
+ m_creature->GetMotionMaster()->MovementExpired();
+ }
+ }
+
+ void doSendCinematic()
+ {
+ Map::PlayerList const &pList = m_creature->GetMap()->GetPlayers();
+ if (pList.isEmpty()) return;
+ for (Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i)
+ if (Player* pPlayer = i->getSource())
+ if (pPlayer && pPlayer->isAlive() && pPlayer->IsInMap(m_creature))
+ pPlayer->SendMovieStart(FINAL_ARTHAS_MOVIE);
+ }
+
+ void doRevivePlayers()
+ {
+ Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID);
+ Map::PlayerList const &pList = pMenethil->GetMap()->GetPlayers();
+ if (pList.isEmpty()) return;
+ for (Map::PlayerList::const_iterator i = pList.begin(); i != pList.end(); ++i)
+ {
+ if (Player* pPlayer = i->getSource())
+ {
+ if (pPlayer && !pPlayer->isAlive() && pPlayer->IsInMap(pMenethil))
+ {
+ pMenethil->CastSpell(pPlayer, SPELL_REVALL, true);
+ pPlayer->ResurrectPlayer(100, false);
+ }
+ }
+ };
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (pInstance->GetData(TYPE_LICH_KING) == FAIL && m_creature->HasAura(SPELL_ICEBLOCK_TRIGGER))
+ {
+ m_creature->RemoveAurasDueToSpell(SPELL_ICEBLOCK_TRIGGER);
+ m_creature->GetMotionMaster()->MoveTargetedHome();
+ Reset();
+ }
+
+ if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_TIRION)
+ {
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+ if (UpdateTimer <= diff)
+ {
+ debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT));
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+ case 12030:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
+ DoScriptText(-1631552, m_creature);
+ UpdateTimer = 9000;
+ pInstance->SetData(TYPE_EVENT,12040);
+ break;
+ case 12050:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_POINT_NOSHEATHE);
+ DoScriptText(-1631554, m_creature);
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,12051);
+ break;
+ case 12051:
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ UpdateTimer = 1000;
+ pInstance->SetData(TYPE_EVENT,12052);
+ break;
+ case 12052:
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ StartMovement(3,12053);
+ break;
+ case 12053:
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,12060);
+ m_creature->CastSpell(m_creature, SPELL_ICEBLOCK_TRIGGER, true);
+ break;
+ case 13110:
+ DoScriptText(-1631555, m_creature);
+ UpdateTimer = 6000;
+ m_creature->CastSpell(m_creature, SPELL_TIRION_LIGHT, false);
+ pInstance->SetData(TYPE_EVENT,13120);
+ break;
+ case 13130:
+ SetCombatMovement(false);
+ m_creature->RemoveAurasDueToSpell(SPELL_ICEBLOCK_TRIGGER);
+ UpdateTimer = 500;
+ m_creature->SetOrientation(0.0f);
+ pInstance->SetData(TYPE_EVENT,13131);
+ break;
+ case 13131:
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ StartMovement(2,13132);
+ break;
+ case 13132:
+ StartMovement(5,13140);
+ DoScriptText(-1631556, m_creature);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
+ break;
+ case 13150:
+ UpdateTimer = 1000;
+ pInstance->SetData(TYPE_EVENT,13160);
+ break;
+ case 13170:
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,13180);
+ break;
+ case 13190:
+ UpdateTimer = 500;
+ pInstance->SetData(TYPE_EVENT,13200);
+ break;
+ case 13210:
+ UpdateTimer = 3000;
+ pInstance->SetData(TYPE_EVENT,13230);
+ break;
+ case 13230:
+ UpdateTimer = 12000;
+ {
+ Creature* pMenethil = m_creature->SummonCreature(NPC_MENETHIL, m_creature->GetPositionX()+5, m_creature->GetPositionY()+5, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ MenethilGUID = pMenethil->GetGUID();
+ }
+ pInstance->SetData(TYPE_EVENT,13250);
+ DoScriptText(-1631560, m_creature->GetMap()->GetCreature(MenethilGUID));
+ break;
+ case 13250:
+ UpdateTimer = 6000;
+ pInstance->SetData(TYPE_EVENT,13270);
+ {
+ Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID);
+ DoScriptText(-1631561, pMenethil);
+ pMenethil->CastSpell(pMenethil, SPELL_REVIVE_VISUAL, false);
+ }
+ doRevivePlayers();
+ break;
+ case 13270:
+ UpdateTimer = 6000;
+ pInstance->SetData(TYPE_EVENT,13280);
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LICH_KING)))
+ {
+ m_creature->SetInCombatWith(pLichKing);
+ pLichKing->SetInCombatWith(m_creature);
+ pLichKing->AddThreat(m_creature, 1000.0f);
+ m_creature->AI()->AttackStart(pLichKing);
+ Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID);
+ pMenethil->AI()->AttackStart(pLichKing);
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(pLichKing);
+ };
+ break;
+ case 13290:
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,13310);
+ DoScriptText(-1631590,m_creature->GetMap()->GetCreature(MenethilGUID));
+ break;
+ case 13310:
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,13330);
+ DoScriptText(-1631591, m_creature);
+ break;
+ case 13330:
+ UpdateTimer = 5000;
+ pInstance->SetData(TYPE_EVENT,13350);
+ DoScriptText(-1631592, m_creature->GetMap()->GetCreature(MenethilGUID));
+ break;
+ case 13350:
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,13370);
+ DoScriptText(-1631593, m_creature);
+ break;
+ case 14010:
+ m_creature->AttackStop();
+ SetCombatMovement(false);
+ UpdateTimer =90000;
+ pInstance->SetData(TYPE_EVENT,14030);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LICH_KING)))
+ pLichKing->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ doSendCinematic();
+ break;
+ case 14030:
+ UpdateTimer = 20000;
+ pInstance->SetData(TYPE_EVENT,14030);
+ DoScriptText(-1631594, m_creature);
+ {
+ if (Creature* pMenethil = m_creature->GetMap()->GetCreature(MenethilGUID))
+ if (pMenethil->isAlive())
+ pMenethil->ForcedDespawn();
+ if (Creature* pLichKing = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_LICH_KING)))
+ pLichKing->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ pInstance->SetData(TYPE_EVENT,0);
+ EnterEvadeMode();
+ break;
+ default:
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+ DoMeleeAttackIfReady();
+ }
+
+
+};
+
+bool GossipHello_boss_tirion_icc(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance* pInstance;
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+
+ if (pInstance->GetData(TYPE_LICH_KING) != NOT_STARTED &&
+ pInstance->GetData(TYPE_LICH_KING) != FAIL )
+ {
+ pPlayer->PlayerTalkClass->SendGossipMenu(721002, pCreature->GetGUID());
+ return true;
+ };
+
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_CHAT, -3631608, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->PlayerTalkClass->SendGossipMenu(721001, pCreature->GetGUID());
+ return true;
+};
+
+bool GossipSelect_boss_tirion_icc(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance* pInstance;
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ if (!pInstance) return false;
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS);
+ pInstance->SetData(TYPE_EVENT,12000);
+ return true;
+ } else return false;
+};
+
+CreatureAI* GetAI_boss_tirion_icc(Creature* pCreature)
+{
+ return new boss_tirion_iccAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_ice_sphere_iccAI : public BSWScriptedAI
+{
+ mob_ice_sphere_iccAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ resetTimers();
+ doCast(SPELL_ICE_SPHERE_VISUAL);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!hasAura(SPELL_ICE_SPHERE_VISUAL))
+ doCast(SPELL_ICE_SPHERE_VISUAL);
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ {
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(120.0f))
+ {
+ m_creature->SetInCombatWith(pTarget);
+ m_creature->AddThreat(pTarget,100.0f);
+ }
+ return;
+ }
+
+ if (m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ timedCast(SPELL_ICE_PULSE, uiDiff);
+
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 1.0f))
+ timedCast(SPELL_ICE_BURST,uiDiff);
+ }
+};
+
+CreatureAI* GetAI_mob_ice_sphere_icc(Creature* pCreature)
+{
+ return new mob_ice_sphere_iccAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_defiler_iccAI : public BSWScriptedAI
+{
+ mob_defiler_iccAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+ uint32 life_timer;
+ float m_Size0;
+ float m_Size;
+
+ void Reset()
+ {
+ SetCombatMovement(false);
+ life_timer = 30000;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->CastSpell(m_creature, SPELL_DEFILE, true);
+ m_Size0 = m_creature->GetFloatValue(OBJECT_FIELD_SCALE_X);
+ m_Size = m_Size0;
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ bool doSearchPlayers()
+ {
+ if(doSelectRandomPlayerAtRange(m_Size * 3.0f)) return true;
+ else return false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance && m_pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (life_timer <= uiDiff)
+ m_creature->ForcedDespawn();
+ else life_timer -= uiDiff;
+
+ if (doSearchPlayers() && m_Size <= m_Size0 * 6.0f) {
+ m_Size = m_Size*1.01;
+ m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_Size);
+ }
+
+ }
+
+};
+
+CreatureAI* GetAI_mob_defiler_icc(Creature* pCreature)
+{
+ return new mob_defiler_iccAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_strangulate_vehicleAI : public ScriptedAI
+{
+ mob_strangulate_vehicleAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+
+ void Reset()
+ {
+ SetCombatMovement(false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ m_creature->ForcedDespawn();
+ }
+
+};
+
+CreatureAI* GetAI_mob_strangulate_vehicle(Creature* pCreature)
+{
+ return new mob_strangulate_vehicleAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_vile_spiritAI : public BSWScriptedAI
+{
+ mob_vile_spiritAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool movementstarted;
+
+ void Reset()
+ {
+ resetTimers();
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(120.0f))
+ {
+ m_creature->SetInCombatWith(pTarget);
+ m_creature->AddThreat(pTarget,1000.0f);
+ }
+ SetCombatMovement(false);
+ movementstarted = false;
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (timedQuery(SPELL_SPIRITS_BURST, uiDiff) && !movementstarted)
+ {
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ movementstarted = true;
+ }
+
+ if (m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 1.0f))
+ {
+ doCast(SPELL_SPIRITS_BURST);
+ m_creature->ForcedDespawn();
+ };
+ }
+};
+
+CreatureAI* GetAI_mob_vile_spirit(Creature* pCreature)
+{
+ return new mob_vile_spiritAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_raging_spiritAI : public BSWScriptedAI
+{
+ mob_raging_spiritAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ resetTimers();
+ m_creature->SetDisplayId(10771);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_LICH_KING) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ timedCast(SPELL_SOUL_SHRIEK, uiDiff);
+ }
+};
+
+CreatureAI* GetAI_mob_raging_spirit(Creature* pCreature)
+{
+ return new mob_raging_spiritAI(pCreature);
+}
+
+void AddSC_boss_lich_king_icc()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_the_lich_king_icc";
+ newscript->GetAI = &GetAI_boss_the_lich_king_icc;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_tirion_icc";
+ newscript->GetAI = &GetAI_boss_tirion_icc;
+ newscript->pGossipHello = &GossipHello_boss_tirion_icc;
+ newscript->pGossipSelect = &GossipSelect_boss_tirion_icc;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ice_sphere_icc";
+ newscript->GetAI = &GetAI_mob_ice_sphere_icc;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_defiler_icc";
+ newscript->GetAI = &GetAI_mob_defiler_icc;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_strangulate_vehicle";
+ newscript->GetAI = &GetAI_mob_strangulate_vehicle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_vile_spirit";
+ newscript->GetAI = &GetAI_mob_vile_spirit;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_raging_spirit";
+ newscript->GetAI = &GetAI_mob_raging_spirit;
+ newscript->RegisterSelf();
+
+};
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp
index 5adb40e..2d4fd7b 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_valithria_dreamwalker.cpp
@@ -16,9 +16,513 @@
/* ScriptData
SDName: boss_valithria
-SD%Complete: 0%
-SDComment:
+SD%Complete: 70%
+SDComment: by /dev/rsa
SDCategory: Icecrown Citadel
EndScriptData */
-
+// Need move emerald dream to phase 32, correct timers and other
#include "precompiled.h"
+#include "def_spire.h"
+
+static Locations SpawnLoc[]=
+{
+ {4203.470215f, 2484.500000f, 364.872009f}, // 0 Valithria
+ {4166.216797f, 2564.197266f, 364.873047f}, // 1 Valithria Room 1
+ {4240.688477f, 2405.794678f, 364.868591f}, // 2 Valithria Room 2
+ {4165.112305f, 2405.872559f, 364.872925f}, // 3 Valithria Room 3
+ {4239.579102f, 2566.753418f, 364.868439f}, // 4 Valithria Room 4
+ {4228.589844f, 2469.110107f, 364.868988f}, // 5 Mob 1
+ {4236.000000f, 2479.500000f, 364.869995f}, // 6 Mob 2
+ {4235.410156f, 2489.300049f, 364.872009f}, // 7 Mob 3
+ {4228.509766f, 2500.310059f, 364.876007f}, // 8 Mob 4
+};
+
+enum BossSpells
+{
+// SPELL_NIGHTMARE_PORTAL = 72481, // Not worked yet. Use 71977 (visual effect) instead?
+ SPELL_NIGHTMARE_PORTAL = 71977,
+ SPELL_EMERALD_VIGOR = 70873,
+ SPELL_DREAMWALKER_RAGE = 71189,
+ SPELL_IMMUNITY = 72724,
+ SPELL_CORRUPTION = 70904,
+ SPELL_DREAM_SLIP = 71196,
+ SPELL_ICE_SPIKE = 70702,
+
+// Summons
+ NPC_RISEN_ARCHMAGE = 37868,
+ NPC_SUPPRESSOR = 37863,
+ NPC_BLASING_SKELETON = 36791,
+ NPC_BLISTERING_ZOMBIE = 37934,
+ NPC_GLUTTONOUS_ABOMINATION = 37886,
+ NPC_NIGHTMARE_PORTAL = 38429, // Not realized yet
+ // Mana void
+ NPC_MANA_VOID = 38068, // Bugged, need override
+ SPELL_VOID_BUFF = 71085,
+};
+
+struct MANGOS_DLL_DECL boss_valithria_dreamwalkerAI : public BSWScriptedAI
+{
+ boss_valithria_dreamwalkerAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (instance_icecrown_spire*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ instance_icecrown_spire* pInstance;
+ bool battlestarted;
+ bool intro;
+ uint8 currentDoor;
+ uint8 currentDoor2;
+ int8 portalscount;
+ std::list mobsGUIDList;
+ uint32 speedK;
+ Creature* dummyTarget;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetHealth(m_creature->GetMaxHealth()/2.0f);
+ if (pInstance->GetData(TYPE_VALITHRIA) != DONE)
+ pInstance->SetData(TYPE_VALITHRIA, NOT_STARTED);
+ else m_creature->ForcedDespawn();
+ resetTimers();
+ SetCombatMovement(false);
+ setStage(0);
+ speedK = 0;
+ portalscount = 0;
+ battlestarted = false;
+ intro = false;
+ currentDoor = 0;
+ currentDoor2 = 0;
+ mobsGUIDList.clear();
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALITHRIA_QUEST)))
+ if (pTemp->GetVisibility() == VISIBILITY_ON)
+ pTemp->SetVisibility(VISIBILITY_OFF);
+ doCast(SPELL_CORRUPTION);
+ }
+
+ uint64 GetDoor(uint8 doornum)
+ {
+ switch (doornum) {
+ case 1:
+ return pInstance->GetData64(GO_VALITHRIA_DOOR_1);
+ break;
+ case 2:
+ return pInstance->GetData64(GO_VALITHRIA_DOOR_2);
+ break;
+ case 3:
+ return pInstance->GetData64(GO_VALITHRIA_DOOR_3);
+ break;
+ case 4:
+ return pInstance->GetData64(GO_VALITHRIA_DOOR_4);
+ break;
+ default:
+ return 0;
+ break;
+ };
+ }
+
+ void CallMobs(uint8 door)
+ {
+ if(!door) return;
+ uint8 mobs;
+ uint32 randommob;
+
+ switch (currentDifficulty) {
+ case RAID_DIFFICULTY_10MAN_NORMAL:
+ mobs = urand(1,3);
+ break;
+ case RAID_DIFFICULTY_10MAN_HEROIC:
+ mobs = urand(2,4);
+ break;
+ case RAID_DIFFICULTY_25MAN_NORMAL:
+ mobs = urand(2,5);
+ break;
+ case RAID_DIFFICULTY_25MAN_HEROIC:
+ mobs = urand(3,5);
+ break;
+ default:
+ mobs = urand(1,5);
+ break;
+ }
+
+ for(uint8 i = 0; i <= mobs; ++i)
+ {
+ switch (urand(0,4)) {
+ case 0: randommob = NPC_RISEN_ARCHMAGE; break;
+ case 1: randommob = NPC_SUPPRESSOR; break;
+ case 2: randommob = NPC_BLASING_SKELETON; break;
+ case 3: randommob = NPC_BLISTERING_ZOMBIE; break;
+ case 4: randommob = NPC_GLUTTONOUS_ABOMINATION;break;
+ default: randommob = NPC_RISEN_ARCHMAGE; break;
+ }
+ if (Unit* pTemp = doSummon(randommob, SpawnLoc[door].x, SpawnLoc[door].y, SpawnLoc[door].z, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000))
+ mobsGUIDList.push_back(pTemp->GetGUID());
+ }
+ }
+
+ void QueryEvadeMode()
+ {
+
+ if ( m_creature->GetHealthPercent() > 1.0f ) {
+ Map* pMap = m_creature->GetMap();
+ Map::PlayerList const &players = pMap->GetPlayers();
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ {
+ if(Player* pPlayer = i->getSource())
+ if(pPlayer->isAlive() && !pPlayer->isGameMaster()
+ && pPlayer->IsWithinDistInMap(m_creature, 90.0f)) return;
+ }
+ }
+ pInstance->SetData(TYPE_VALITHRIA, FAIL);
+ DoScriptText(-1631409,m_creature);
+ DespawnMobs();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->LoadCreatureAddon();
+ if (m_creature->isAlive())
+ m_creature->GetMotionMaster()->MoveTargetedHome();
+ m_creature->SetLootRecipient(NULL);
+ pInstance->CloseDoor(GetDoor(currentDoor));
+ pInstance->CloseDoor(GetDoor(currentDoor2));
+ Reset();
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pInstance || ( intro && battlestarted)) return;
+
+ if (pWho->GetTypeId() != TYPEID_PLAYER) return;
+
+ if (!intro)
+ {
+ DoScriptText(-1631401,m_creature,pWho);
+ intro = true;
+ doCast(SPELL_IMMUNITY);
+ }
+ if (!battlestarted && pWho->isAlive() && pWho->IsWithinDistInMap(m_creature, 40.0f))
+ {
+ DoScriptText(-1631401,m_creature,pWho);
+ battlestarted = true;
+ pInstance->SetData(TYPE_VALITHRIA, IN_PROGRESS);
+ m_creature->SetHealth(m_creature->GetMaxHealth()/2.0f);
+ dummyTarget = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_COMBAT_TRIGGER));
+ if (!dummyTarget)
+ dummyTarget = m_creature->SummonCreature(NPC_COMBAT_TRIGGER, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 1000);
+ if (!dummyTarget->isAlive())
+ dummyTarget->Respawn();
+ if (dummyTarget)
+ {
+ dummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ dummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ dummyTarget->GetMotionMaster()->MoveIdle();
+ dummyTarget->StopMoving();
+ }
+ m_creature->SetInCombatWith(dummyTarget);
+ m_creature->SetHealth(m_creature->GetMaxHealth()/2.0f);
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(!pInstance) return;
+
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1631403,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631404,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned || !battlestarted) return;
+
+ if ( summoned->GetEntry() != NPC_NIGHTMARE_PORTAL ) {
+ m_creature->SetInCombatWithZone();
+ m_creature->SetInCombatWith(summoned);
+ summoned->SetInCombatWith(m_creature);
+ summoned->AddThreat(m_creature, 100.0f);
+ summoned->GetMotionMaster()->MoveChase(m_creature);
+ }
+
+ }
+
+ void DespawnMobs()
+ {
+ if (mobsGUIDList.empty())
+ return;
+
+ for(std::list::iterator itr = mobsGUIDList.begin(); itr != mobsGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ if (pTemp->isAlive())
+ {
+ pTemp->DeleteThreatList();
+ pTemp->CombatStop(true);
+ pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+ mobsGUIDList.clear();
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return
+ pInstance->SetData(TYPE_VALITHRIA, FAIL);
+ DoScriptText(-1631409,m_creature);
+ DespawnMobs();
+ m_creature->Respawn();
+ Reset();
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if (uiDamage >= m_creature->GetHealth()) uiDamage = 0;
+ }
+
+ void AttackStart(Unit *who)
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (!hasAura(SPELL_CORRUPTION,m_creature) && getStage() == 0)
+ doCast(SPELL_CORRUPTION);
+
+ if (!battlestarted) return;
+
+ QueryEvadeMode();
+
+ switch(getStage())
+ {
+ case 0:
+ if ( m_creature->GetHealthPercent() > 90.0f ) setStage(2);
+ if ( m_creature->GetHealthPercent() < 10.0f ) setStage(3);
+ break;
+ case 1:
+ if ( m_creature->GetHealthPercent() < 90.0f && m_creature->GetHealthPercent() > 10.0f ) setStage(0);
+ if ( m_creature->GetHealthPercent() > 99.9f ) setStage(5);
+ break;
+ case 2:
+ DoScriptText(-1631407,m_creature);
+ setStage(1);
+ break;
+ case 3:
+ DoScriptText(-1631406,m_creature);
+ setStage(1);
+ break;
+ case 4:
+ break;
+ case 5:
+ DoScriptText(-1631408,m_creature);
+ if (hasAura(SPELL_CORRUPTION,m_creature)) doRemove(SPELL_CORRUPTION);
+ setStage(6);
+ return;
+ break;
+ case 6:
+ if (timedQuery(SPELL_CORRUPTION, diff)) setStage(7);
+ return;
+ break;
+ case 7:
+ doCast(SPELL_DREAMWALKER_RAGE);
+ setStage(8);
+ return;
+ break;
+ case 8:
+ if (timedQuery(SPELL_CORRUPTION, diff))
+ {
+ setStage(9);
+ DespawnMobs();
+ }
+ return;
+ break;
+ case 9:
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_VALITHRIA_QUEST)))
+ {
+ pTemp->SetPhaseMask(65535,true);
+ if (pTemp->HasAura(SPELL_CORRUPTION))
+ pTemp->RemoveAurasDueToSpell(SPELL_CORRUPTION);
+ if (pTemp->GetVisibility() == VISIBILITY_OFF)
+ pTemp->SetVisibility(VISIBILITY_ON);
+ }
+ pInstance->SetData(TYPE_VALITHRIA, DONE);
+ setStage(10);
+ m_creature->ForcedDespawn();
+ break;
+ default:
+ break;
+ }
+
+
+ if (timedQuery(NPC_RISEN_ARCHMAGE, (uint32)(diff + diff*(speedK/100)))) {
+ if (urand(0,1) == 1) DoScriptText(-1631402,m_creature);
+ speedK = speedK+10;
+ if (currentDifficulty == RAID_DIFFICULTY_25MAN_NORMAL
+ || currentDifficulty == RAID_DIFFICULTY_25MAN_HEROIC) {
+ pInstance->CloseDoor(GetDoor(currentDoor2));
+ currentDoor2 = urand(1,2);
+ pInstance->OpenDoor(GetDoor(currentDoor2));
+ CallMobs(currentDoor2);
+
+ pInstance->CloseDoor(GetDoor(currentDoor));
+ currentDoor = urand(3,4);
+ pInstance->OpenDoor(GetDoor(currentDoor));
+ CallMobs(currentDoor);
+ } else {
+ pInstance->CloseDoor(GetDoor(currentDoor));
+ currentDoor = urand(1,4);
+ pInstance->OpenDoor(GetDoor(currentDoor));
+ CallMobs(currentDoor);
+ }
+ };
+
+ if (timedQuery(SPELL_NIGHTMARE_PORTAL, diff) || portalscount > 0)
+ {
+ if (!portalscount) {
+ portalscount = 3;
+ DoScriptText(-1631405,m_creature);
+ };
+ doCast(SPELL_NIGHTMARE_PORTAL);
+ --portalscount;
+ };
+
+ timedCast(SPELL_ICE_SPIKE, diff);
+
+ return;
+ }
+};
+
+CreatureAI* GetAI_boss_valithria_dreamwalker(Creature* pCreature)
+{
+ return new boss_valithria_dreamwalkerAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_nightmare_portalAI : public BSWScriptedAI
+{
+ mob_nightmare_portalAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool portalcasted;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MoveRandom();
+ m_creature->SetDisplayId(29352);
+ portalcasted = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_pInstance || portalcasted) return;
+
+ if (pWho->isAlive() && pWho->GetTypeId() == TYPEID_PLAYER && pWho->IsWithinDistInMap(m_creature, 2.0f))
+ {
+ doCast(SPELL_EMERALD_VIGOR);
+ portalcasted = true;
+ }
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_VALITHRIA) != IN_PROGRESS || portalcasted)
+ if (timedQuery(SPELL_EMERALD_VIGOR, uiDiff))
+ m_creature->ForcedDespawn();
+
+ }
+
+};
+
+CreatureAI* GetAI_mob_nightmare_portal(Creature *pCreature)
+{
+ return new mob_nightmare_portalAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_mana_voidAI : public ScriptedAI
+{
+ mob_mana_voidAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_ui_Timer;
+
+ void Reset()
+ {
+// m_creature->SetDisplayId(29308);
+ SetCombatMovement(false);
+// m_creature->GetMotionMaster()->MoveRandom();
+ m_creature->CastSpell(m_creature, SPELL_VOID_BUFF, false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_ui_Timer = 30000;
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void JustDied(Unit *killer)
+ {
+ m_creature->RemoveCorpse();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_pInstance || m_pInstance->GetData(TYPE_VALITHRIA) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_ui_Timer < uiDiff)
+ m_creature->ForcedDespawn();
+ else m_ui_Timer -= uiDiff;
+ }
+
+};
+
+CreatureAI* GetAI_mob_mana_void(Creature *pCreature)
+{
+ return new mob_mana_voidAI(pCreature);
+};
+
+void AddSC_boss_valithria_dreamwalker()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_valithria_dreamwalker";
+ newscript->GetAI = &GetAI_boss_valithria_dreamwalker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_nightmare_portal";
+ newscript->GetAI = &GetAI_mob_nightmare_portal;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_mana_void";
+ newscript->GetAI = &GetAI_mob_mana_void;
+ newscript->RegisterSelf();
+
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h b/scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h
new file mode 100644
index 0000000..bd9c469
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/def_spire.h
@@ -0,0 +1,273 @@
+/* Copyright (C) 2010 by /dev/rsa for ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_ICECROWN_SPIRE_H
+#define DEF_ICECROWN_SPIRE_H
+#include "BSW_ai.h"
+
+enum
+{
+
+ TYPE_TELEPORT = 0,
+ TYPE_MARROWGAR = 1,
+ TYPE_DEATHWHISPER = 2,
+ TYPE_FLIGHT_WAR = 3,
+ TYPE_SAURFANG = 4,
+ TYPE_FESTERGUT = 5,
+ TYPE_ROTFACE = 6,
+ TYPE_PUTRICIDE = 7,
+ TYPE_BLOOD_COUNCIL = 8,
+ TYPE_LANATHEL = 9,
+ TYPE_VALITHRIA = 10,
+ TYPE_SINDRAGOSA = 11,
+ TYPE_KINGS_OF_ICC = 12,
+ TYPE_LICH_KING = 13,
+ TYPE_ICECROWN_QUESTS = 14,
+ TYPE_COUNT = 15,
+ MAX_ENCOUNTERS,
+
+ TYPE_STINKY,
+ TYPE_PRECIOUS,
+
+ NPC_LORD_MARROWGAR = 36612,
+ NPC_LADY_DEATHWHISPER = 36855,
+ NPC_DEATHBRINGER_SAURFANG = 37813,
+ NPC_FESTERGUT = 36626,
+ NPC_ROTFACE = 36627,
+ NPC_PROFESSOR_PUTRICIDE = 36678,
+ NPC_TALDARAM = 37973,
+ NPC_VALANAR = 37970,
+ NPC_KELESETH = 37972,
+ NPC_LANATHEL = 37955,
+ NPC_VALITHRIA = 36789,
+ NPC_VALITHRIA_QUEST = 38589,
+ NPC_SINDRAGOSA = 36853,
+ NPC_LICH_KING = 36597,
+
+ NPC_LANATHEL_INTRO = 38004,
+ NPC_BLOOD_ORB_CONTROL = 38008,
+
+ NPC_MURADIN = 36948,
+
+ NPC_TIRION = 38995,
+ NPC_MENETHIL = 38579,
+ NPC_SPIRIT_WARDEN = 38579,
+
+ NPC_FROSTMOURNE_TRIGGER = 38584,
+ NPC_FROSTMOURNE_HOLDER = 27880,
+
+ NPC_STINKY = 37025,
+ NPC_PRECIOUS = 37217,
+
+ NPC_RIMEFANG = 37533,
+ NPC_SPINESTALKER = 37534,
+
+ NPC_COMBAT_TRIGGER = 38752,
+
+ GO_TELEPORT_GOSSIP_MESSAGE = 99323,
+ TELEPORT_GOSSIP_MESSAGE = 99322,
+
+ GO_ICEWALL_1 = 201911,
+ GO_ICEWALL_2 = 201910,
+
+ GO_ORATORY_DOOR = 201563,
+ GO_DEATHWHISPER_ELEVATOR = 202220, //5653
+
+ GO_SAURFANG_DOOR = 201825,
+
+ GO_GAS_RELEASE_VALVE = 201616, //72479
+
+ GO_ORANGE_PLAGUE = 201371, //72536
+ GO_GREEN_PLAGUE = 201370, //72537
+
+ GO_SCIENTIST_DOOR_GREEN = 201614, //72530
+ GO_SCIENTIST_DOOR_ORANGE = 201613, //72531
+ GO_SCIENTIST_DOOR_COLLISION = 201612,
+ GO_SCIENTIST_DOOR = 201372, //72541
+
+ GO_BLOODWING_DOOR = 201920, //72532
+ GO_CRIMSON_HALL_DOOR = 201376, //72532
+ GO_COUNCIL_DOOR_1 = 201377, //72533
+ GO_COUNCIL_DOOR_2 = 201378, //72534
+
+ GO_FROSTWING_DOOR = 201919,
+ GO_GREEN_DRAGON_DOOR_1 = 201375, //1202
+ GO_GREEN_DRAGON_DOOR_2 = 201374, //1200
+ GO_VALITHRIA_DOOR_1 = 201380, //1618
+ GO_VALITHRIA_DOOR_2 = 201382, //1482
+ GO_VALITHRIA_DOOR_3 = 201383, //1335
+ GO_VALITHRIA_DOOR_4 = 201381, //1558
+
+ GO_SINDRAGOSA_DOOR_1 = 201369, //1619
+ GO_SINDRAGOSA_DOOR_2 = 201379,
+
+ GO_FROZENTRONE_TR = 202223, //72061
+
+ GO_SAURFANG_CACHE_10 = 202239,
+ GO_SAURFANG_CACHE_25 = 202240,
+ GO_SAURFANG_CACHE_10_H = 202238,
+ GO_SAURFANG_CACHE_25_H = 202241,
+
+ GO_GUNSHIP_ARMORY_A_10 = 201872, //
+ GO_GUNSHIP_ARMORY_A_25 = 201873, //
+ GO_GUNSHIP_ARMORY_A_10H = 201874, //
+ GO_GUNSHIP_ARMORY_A_25H = 201875, //
+
+ GO_GUNSHIP_ARMORY_H_10 = 202177, //
+ GO_GUNSHIP_ARMORY_H_25 = 202178, //
+ GO_GUNSHIP_ARMORY_H_10H = 202179, //
+ GO_GUNSHIP_ARMORY_H_25H = 202180, //
+
+ GO_DREAMWALKER_CACHE_10 = 201959, //
+ GO_DREAMWALKER_CACHE_25 = 202339, //
+ GO_DREAMWALKER_CACHE_10_H = 202338, //
+ GO_DREAMWALKER_CACHE_25_H = 202340, //
+
+ GO_PLAGUE_SIGIL = 202182,
+ GO_FROSTWING_SIGIL = 202181,
+ GO_BLOODWING_SIGIL = 202183,
+
+ GO_ICESHARD_1 = 202142, //8304
+ GO_ICESHARD_2 = 202141, //8364
+ GO_ICESHARD_3 = 202143, //8310
+ GO_ICESHARD_4 = 202144, //9007
+
+ GO_FROSTY_WIND = 202188, //
+ GO_FROSTY_EDGE = 202189, //
+ GO_SNOW_EDGE = 202190, //
+ GO_ARTHAS_PLATFORM = 202161, //
+ GO_ARTHAS_PRECIPICE = 202078, //
+
+ TYPE_EVENT_TIMER = 99,
+ TYPE_EVENT = 100,
+ TYPE_EVENT_NPC = 101,
+ MAP_NUM = 631,
+ DATA_DIRECTION = 1001,
+ DATA_BLOOD_COUNCIL_HEALTH = 1002,
+ DATA_BLOOD_INVOCATION = 1003,
+ DESPAWN_TIME = 300000,
+
+};
+
+class MANGOS_DLL_DECL instance_icecrown_spire : public ScriptedInstance
+{
+public:
+ instance_icecrown_spire(Map* pMap);
+ ~instance_icecrown_spire() {}
+
+ void Initialize();
+
+ void OnObjectCreate(GameObject* pGo);
+ void OnCreatureCreate(Creature* pCreature);
+
+ void OpenDoor(uint64 guid);
+ void CloseDoor(uint64 guid);
+ void OpenAllDoors();
+ void OnPlayerEnter(Player* pPlayer);
+ bool IsEncounterInProgress() const;
+
+ void SetData(uint32 uiType, uint32 uiData);
+ uint32 GetData(uint32 uiType);
+ uint64 GetData64(uint32 uiType);
+
+ const char* Save() { return strSaveData.c_str(); }
+ void Load(const char* chrIn);
+
+private:
+
+ uint8 Difficulty;
+ bool needSave;
+ std::string strSaveData;
+
+ //Creatures GUID
+ uint32 m_auiEncounter[MAX_ENCOUNTERS+1];
+ uint64 m_uiMarrogwarGUID;
+ uint64 m_uiDeathWhisperGUID;
+ uint64 m_uiSaurfangGUID;
+ uint64 m_uiRotfaceGUID;
+ uint64 m_uiFestergutGUID;
+ uint64 m_uiPutricideGUID;
+ uint64 m_uiTaldaramGUID;
+ uint64 m_uiValanarGUID;
+ uint64 m_uiKelesethGUID;
+ uint64 m_uiLanathelGUID;
+ uint64 m_uiLanathelintroGUID;
+ uint64 m_uiValithriaGUID;
+ uint64 m_uiValithriaQuestGUID;
+ uint64 m_uiSindragosaGUID;
+ uint64 m_uiLichKingGUID;
+ uint64 m_uiGasReleaseValveGUID;
+ uint64 m_uiBloodOrbCtrlGUID;
+
+ uint64 m_uiRimefangGUID;
+ uint64 m_uiSpinestalkerGUID;
+
+ uint64 m_uiStinkyGUID;
+ uint64 m_uiPreciousGUID;
+
+ uint64 m_uidummyTargetGUID;
+
+ uint64 m_uiIcewall1GUID;
+ uint64 m_uiIcewall2GUID;
+ uint64 m_uiSaurfangDoorGUID;
+ uint64 m_uiOratoryDoorGUID;
+ uint64 m_uiDeathWhisperElevatorGUID;
+ uint64 m_uiOrangePlagueGUID;
+ uint64 m_uiGreenPlagueGUID;
+ uint64 m_uiSDoorGreenGUID;
+ uint64 m_uiSDoorOrangeGUID;
+ uint64 m_uiSDoorCollisionGUID;
+ uint64 m_uiScientistDoorGUID;
+ uint64 m_uiCrimsonDoorGUID;
+ uint64 m_uiBloodwingDoorGUID;
+ uint64 m_uiCounsilDoor1GUID;
+ uint64 m_uiCounsilDoor2GUID;
+ uint64 m_uiGreenDragonDoor1GUID;
+ uint64 m_uiGreenDragonDoor2GUID;
+ uint64 m_uiFrostwingDoorGUID;
+
+ uint64 m_uiValithriaDoor1GUID;
+ uint64 m_uiValithriaDoor2GUID;
+ uint64 m_uiValithriaDoor3GUID;
+ uint64 m_uiValithriaDoor4GUID;
+
+ uint64 m_uiSindragosaDoor1GUID;
+ uint64 m_uiSindragosaDoor2GUID;
+
+ uint64 m_uiIceShard1GUID;
+ uint64 m_uiIceShard2GUID;
+ uint64 m_uiIceShard3GUID;
+ uint64 m_uiIceShard4GUID;
+
+ uint64 m_uiFrostyWindGUID;
+ uint64 m_uiFrostyEdgeGUID;
+ uint64 m_uiSnowEdgeGUID;
+ uint64 m_uiArthasPlatformGUID;
+ uint64 m_uiArthasPrecipiceGUID;
+
+ uint64 m_uiFrostmourneGUID;
+ uint64 m_uiFrostmourneTriggerGUID;
+ uint64 m_uiFrostmourneHolderGUID;
+
+ uint64 m_uiSaurfangCacheGUID;
+ uint64 m_uiGunshipArmoryAGUID;
+ uint64 m_uiGunshipArmoryHGUID;
+ uint64 m_uiValitriaCacheGUID;
+
+ uint64 m_uiGunshipArmoryH_ID;
+ uint64 m_uiGunshipArmoryA_ID;
+
+ uint32 m_uiDataCouncilHealth;
+ uint32 m_uiCouncilInvocation;
+
+ uint32 m_auiEvent;
+ uint32 m_auiEventTimer;
+ uint32 m_uiDirection;
+
+ uint32 m_uiStinkystate;
+ uint32 m_uiPreciousstate;
+
+};
+
+#endif
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp
index 39d9f43..905c401 100644
--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/gunship_battle.cpp
@@ -22,3 +22,7 @@ SDCategory: Icecrown Citadel
EndScriptData */
#include "precompiled.h"
+
+void AddSC_gunship_battle()
+{
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h
new file mode 100644
index 0000000..e592de1
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h
@@ -0,0 +1,3 @@
+/* Copyright (C) 2006 - 2010 ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp
new file mode 100644
index 0000000..c4bd4a4
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_spire.cpp
@@ -0,0 +1,174 @@
+/* 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: icecrown_spire
+SD%Complete: 100%
+SDComment: by /dev/rsa
+SDCategory: Icecrown Citadel - mobs
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_spire.h"
+enum
+{
+ SPELL_BERSERK = 47008,
+ SPELL_FROST_BREATH = 70116,
+ SPELL_BLIZZARD = 70362,
+ SPELL_SOUL_FEAST = 71203,
+ SPELL_CLEAVE = 70361,
+
+ SPELL_STOMP = 64652,
+ SPELL_DEATH_PLAGUE = 72865,
+};
+
+struct MANGOS_DLL_DECL mob_spire_frostwyrmAI : public BSWScriptedAI
+{
+ mob_spire_frostwyrmAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ stage = 0;
+ resetTimers();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(stage)
+ {
+ case 0: {
+ timedCast(SPELL_SOUL_FEAST, diff);
+ break;}
+ case 1: {
+ doCast(SPELL_BERSERK);
+ stage = 2;
+ break;}
+ case 2: {
+ break;}
+ }
+
+ timedCast(SPELL_CLEAVE, diff);
+ timedCast(SPELL_BLIZZARD, diff);
+ timedCast(SPELL_FROST_BREATH, diff);
+
+ if (m_creature->GetHealthPercent() < 10.0f && stage == 0) stage = 1;
+
+ timedCast(SPELL_BERSERK, diff);
+
+ DoMeleeAttackIfReady();
+
+ }
+};
+
+CreatureAI* GetAI_mob_spire_frostwyrm(Creature* pCreature)
+{
+ return new mob_spire_frostwyrmAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_frost_giantAI : public BSWScriptedAI
+{
+ mob_frost_giantAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 stage;
+
+ void Aggro(Unit *who)
+ {
+ if(pInstance) pInstance->SetData(TYPE_FLIGHT_WAR, IN_PROGRESS);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+ if (killer->GetTypeId() == TYPEID_PLAYER)
+ pInstance->SetData(TYPE_FLIGHT_WAR, DONE);
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance) pInstance->SetData(TYPE_FLIGHT_WAR, FAIL);
+ }
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(7*DAY);
+ stage = 0;
+ resetTimers();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(stage)
+ {
+ case 0: {
+ timedCast(SPELL_SOUL_FEAST, diff);
+ break;}
+ case 1: {
+ doCast(SPELL_BERSERK);
+ stage = 2;
+ break;}
+ case 2: {
+ break;}
+ }
+ timedCast(SPELL_STOMP, diff);
+ timedCast(SPELL_DEATH_PLAGUE, diff);
+
+ if (m_creature->GetHealthPercent() < 2.0f && stage == 0) stage = 1;
+
+ timedCast(SPELL_BERSERK, diff);
+
+ DoMeleeAttackIfReady();
+
+ }
+};
+
+CreatureAI* GetAI_mob_frost_giant(Creature* pCreature)
+{
+ return new mob_frost_giantAI(pCreature);
+}
+
+void AddSC_icecrown_spire()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "mob_spire_frostwyrm";
+ newscript->GetAI = &GetAI_mob_spire_frostwyrm;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_giant";
+ newscript->GetAI = &GetAI_mob_frost_giant;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp
new file mode 100644
index 0000000..f4b1ce8
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_teleport.cpp
@@ -0,0 +1,146 @@
+/* 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: icecrown_teleport
+SD%Complete: 100%
+SDComment: by /dev/rsa
+SDCategory: Icecrown Citadel
+EndScriptData */
+#include "precompiled.h"
+#include "def_spire.h"
+
+enum
+{
+PORTALS_COUNT = 7
+};
+
+struct t_Locations
+{
+ int textNum;
+ uint32 map_num;
+ float x, y, z, o;
+ uint32 spellID;
+ bool state;
+ bool active;
+ uint32 encounter;
+};
+
+static t_Locations PortalLoc[]=
+{
+{-3631600,MAP_NUM,-17.1928f, 2211.44f, 30.1158f,3.14f,70856,true,true,TYPE_TELEPORT}, //
+{-3631601,MAP_NUM,-503.62f, 2211.47f, 62.8235f,3.14f,70856,false,true,TYPE_MARROWGAR}, //
+{-3631602,MAP_NUM,-615.145f, 2211.47f, 199.972f,0,70857,false,true,TYPE_DEATHWHISPER}, //
+{-3631603,MAP_NUM,-549.131f, 2211.29f, 539.291f,0,70858,false,true,TYPE_FLIGHT_WAR}, //
+{-3631604,MAP_NUM,4198.42f, 2769.22f, 351.065f,0,70859,false,true,TYPE_SAURFANG}, //
+{-3631606,MAP_NUM,4356.580078f, 2565.75f, 220.401993f,4.90f,70861,false,true,TYPE_VALITHRIA}, //
+{-3631607,MAP_NUM,528.767273f, -2124.845947f, 1043.1f,3.14f, 70860,false,true,TYPE_KINGS_OF_ICC}, //
+};
+
+
+bool GOGossipSelect_go_icecrown_teleporter(Player *pPlayer, GameObject* pGo, uint32 sender, uint32 action)
+{
+ if(sender != GOSSIP_SENDER_MAIN) return false;
+
+ if(!pPlayer->getAttackers().empty()) return false;
+
+ if(action >= 0 && action < PORTALS_COUNT)
+ pPlayer->TeleportTo(PortalLoc[action].map_num, PortalLoc[action].x, PortalLoc[action].y, PortalLoc[action].z, PortalLoc[action].o);
+ if (PortalLoc[action].spellID != 0 )
+ pPlayer->_AddAura(PortalLoc[action].spellID, 2000);
+
+ pPlayer->CLOSE_GOSSIP_MENU();
+ return true;
+}
+
+bool GOGossipHello_go_icecrown_teleporter(Player *pPlayer, GameObject* pGo)
+{
+ ScriptedInstance *pInstance = (ScriptedInstance *) pGo->GetInstanceData();
+
+ if (!pInstance || !pPlayer) return false;
+ if (pPlayer->isInCombat()) return true;
+
+ for(uint8 i = 0; i < PORTALS_COUNT; i++) {
+ if (PortalLoc[i].active == true && (PortalLoc[i].state == true || pInstance->GetData(PortalLoc[i].encounter) == DONE || pPlayer->isGameMaster()))
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_TAXI, PortalLoc[i].textNum, GOSSIP_SENDER_MAIN, i);
+ };
+ pPlayer->SEND_GOSSIP_MENU(TELEPORT_GOSSIP_MESSAGE, pGo->GetGUID());
+ return true;
+}
+
+bool GOHello_go_plague_sigil(Player *player, GameObject* pGo)
+{
+ instance_icecrown_spire* pInstance = (instance_icecrown_spire*)pGo->GetInstanceData();
+ if(!pInstance) return false;
+
+ if (pInstance->GetData(TYPE_FESTERGUT) == DONE
+ && pInstance->GetData(TYPE_ROTFACE) == DONE)
+ {
+ pInstance->OpenDoor(pInstance->GetData64(GO_SCIENTIST_DOOR_ORANGE));
+ pInstance->OpenDoor(pInstance->GetData64(GO_SCIENTIST_DOOR_GREEN));
+ pInstance->OpenDoor(pInstance->GetData64(GO_SCIENTIST_DOOR_COLLISION));
+ };
+ return true;
+}
+
+bool GOHello_go_bloodwing_sigil(Player *player, GameObject* pGo)
+{
+ instance_icecrown_spire* pInstance = (instance_icecrown_spire*)pGo->GetInstanceData();
+ if(!pInstance) return false;
+
+ if (pInstance->GetData(TYPE_SAURFANG) == DONE)
+ pInstance->OpenDoor(pInstance->GetData64(GO_BLOODWING_DOOR));
+
+ return true;
+}
+
+bool GOHello_go_frostwing_sigil(Player *player, GameObject* pGo)
+{
+ instance_icecrown_spire* pInstance = (instance_icecrown_spire*)pGo->GetInstanceData();
+ if(!pInstance) return false;
+
+ if (pInstance->GetData(TYPE_SAURFANG) == DONE)
+ pInstance->OpenDoor(pInstance->GetData64(GO_FROSTWING_DOOR));
+
+ return true;
+}
+
+
+void AddSC_icecrown_teleporter()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "go_icecrown_teleporter";
+ newscript->pGOGossipHello = &GOGossipHello_go_icecrown_teleporter;
+ newscript->pGOGossipSelect = &GOGossipSelect_go_icecrown_teleporter;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_plague_sigil";
+ newscript->pGOHello = &GOHello_go_plague_sigil;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_bloodwing_sigil";
+ newscript->pGOHello = &GOHello_go_bloodwing_sigil;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_frostwing_sigil";
+ newscript->pGOHello = &GOHello_go_frostwing_sigil;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp
new file mode 100644
index 0000000..d2346d4
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp
@@ -0,0 +1,28 @@
+/* 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: instance_icecrown_citadel
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Icecrown Citadel
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_instance_icecrown_citadel()
+{
+}
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_spire.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_spire.cpp
new file mode 100644
index 0000000..be74c68
--- /dev/null
+++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_spire.cpp
@@ -0,0 +1,828 @@
+/* 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: instance_icecrown_spire
+SD%Complete: 90%
+SDComment: by /dev/rsa
+SDCategory: Icecrown Citadel
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_spire.h"
+#include "World.h"
+
+static Locations SpawnLoc[]=
+{
+ {-446.788971f, 2003.362915f, 191.233948f}, // 0 Horde ship enter
+ {-428.140503f, 2421.336914f, 191.233078f}, // 1 Alliance ship enter
+};
+
+ instance_icecrown_spire::instance_icecrown_spire(Map* pMap) : ScriptedInstance(pMap)
+ {
+ Difficulty = pMap->GetDifficulty();
+ Initialize();
+ }
+
+ void instance_icecrown_spire::OpenDoor(uint64 guid)
+ {
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ }
+
+ void instance_icecrown_spire::CloseDoor(uint64 guid)
+ {
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_READY);
+ }
+
+ void instance_icecrown_spire::OpenAllDoors()
+ {
+ if (m_auiEncounter[1] == DONE) {
+ OpenDoor(m_uiIcewall1GUID);
+ OpenDoor(m_uiIcewall2GUID);
+ OpenDoor( m_uiOratoryDoorGUID);
+ };
+ if (m_auiEncounter[2] == DONE) {
+ if (GameObject* pGO = instance->GetGameObject(m_uiDeathWhisperElevatorGUID))
+ {
+ pGO->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
+ pGO->SetGoState(GO_STATE_READY);
+ }
+ };
+ if (m_auiEncounter[4] == DONE) {
+ OpenDoor(m_uiSaurfangDoorGUID);
+ OpenDoor(m_uiBloodwingDoorGUID);
+ OpenDoor(m_uiFrostwingDoorGUID);
+ };
+ if (m_auiEncounter[5] == DONE) OpenDoor(m_uiSDoorOrangeGUID);
+ if (m_auiEncounter[6] == DONE) OpenDoor(m_uiSDoorGreenGUID);
+ if (m_auiEncounter[6] == DONE && m_auiEncounter[5] == DONE) OpenDoor(m_uiSDoorCollisionGUID);
+ if (m_auiEncounter[8] == DONE) {
+ OpenDoor(m_uiCounsilDoor1GUID);
+ OpenDoor(m_uiCounsilDoor2GUID);
+ };
+ if (m_auiEncounter[10] == DONE)
+ {
+ OpenDoor(m_uiValithriaDoor2GUID);
+ OpenDoor(m_uiSindragosaDoor2GUID);
+ OpenDoor(m_uiSindragosaDoor1GUID);
+ };
+
+ }
+
+ void instance_icecrown_spire::Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ m_auiEncounter[0] = 0;
+
+ m_uiMarrogwarGUID = 0;
+ m_uiDeathWhisperGUID = 0;
+ m_uiSaurfangGUID = 0;
+ m_uiSaurfangCacheGUID = 0;
+ m_uiGunshipArmoryAGUID = 0;
+ m_uiGunshipArmoryHGUID = 0;
+ m_uiIcewall1GUID = 0;
+ m_uiIcewall2GUID = 0;
+ m_uiSDoorOrangeGUID = 0;
+ m_uiSDoorGreenGUID = 0;
+ m_uiBloodwingDoorGUID = 0;
+ m_uiSDoorCollisionGUID = 0;
+ m_auiEvent = 0;
+ m_auiEventTimer = 1000;
+ m_uiCouncilInvocation = 0;
+ m_uiDirection = 0;
+ m_uiStinkystate = NOT_STARTED;
+ m_uiPreciousstate = NOT_STARTED;
+
+ switch (Difficulty) {
+ case RAID_DIFFICULTY_10MAN_NORMAL:
+ m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_10;
+ m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_10;
+ break;
+ case RAID_DIFFICULTY_10MAN_HEROIC:
+ m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_10H;
+ m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_10H;
+ break;
+ case RAID_DIFFICULTY_25MAN_NORMAL:
+ m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_25;
+ m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_25;
+ break;
+ case RAID_DIFFICULTY_25MAN_HEROIC:
+ m_uiGunshipArmoryH_ID = GO_GUNSHIP_ARMORY_H_25H;
+ m_uiGunshipArmoryA_ID = GO_GUNSHIP_ARMORY_A_25H;
+ break;
+ default:
+ m_uiGunshipArmoryH_ID = 0;
+ m_uiGunshipArmoryA_ID = 0;
+ break;
+ };
+ }
+
+ bool instance_icecrown_spire::IsEncounterInProgress() const
+ {
+ for(uint8 i = 1; i < MAX_ENCOUNTERS-2 ; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void instance_icecrown_spire::OnPlayerEnter(Player *pPlayer)
+ {
+ OpenAllDoors();
+
+ enum PhaseControl
+ {
+ HORDE_CONTROL_PHASE_SHIFT_1 = 55773,
+ HORDE_CONTROL_PHASE_SHIFT_2 = 60028,
+ ALLIANCE_CONTROL_PHASE_SHIFT_1 = 55774,
+ ALLIANCE_CONTROL_PHASE_SHIFT_2 = 60027,
+ };
+/*
+
+ if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP)) return;
+
+ switch (pPlayer->GetTeam())
+ {
+ case ALLIANCE:
+ if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(HORDE_CONTROL_PHASE_SHIFT_1))
+ pPlayer->RemoveAurasDueToSpell(HORDE_CONTROL_PHASE_SHIFT_1);
+ pPlayer->CastSpell(pPlayer, HORDE_CONTROL_PHASE_SHIFT_2, false);
+ break;
+ case HORDE:
+ if (pPlayer && pPlayer->IsInWorld() && pPlayer->HasAura(ALLIANCE_CONTROL_PHASE_SHIFT_1))
+ pPlayer->RemoveAurasDueToSpell(ALLIANCE_CONTROL_PHASE_SHIFT_1);
+ pPlayer->CastSpell(pPlayer, ALLIANCE_CONTROL_PHASE_SHIFT_2, false);
+ break;
+ };
+*/
+ };
+
+ void instance_icecrown_spire::OnCreatureCreate(Creature* pCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_LORD_MARROWGAR:
+ m_uiMarrogwarGUID = pCreature->GetGUID();
+ break;
+ case NPC_LADY_DEATHWHISPER:
+ m_uiDeathWhisperGUID = pCreature->GetGUID();
+ break;
+ case NPC_DEATHBRINGER_SAURFANG:
+ m_uiSaurfangGUID = pCreature->GetGUID();
+ break;
+ case NPC_FESTERGUT:
+ m_uiFestergutGUID = pCreature->GetGUID();
+ break;
+ case NPC_ROTFACE:
+ m_uiRotfaceGUID = pCreature->GetGUID();
+ break;
+ case NPC_PROFESSOR_PUTRICIDE:
+ m_uiPutricideGUID = pCreature->GetGUID();
+ break;
+ case NPC_TALDARAM:
+ m_uiTaldaramGUID = pCreature->GetGUID();
+ break;
+ case NPC_VALANAR:
+ m_uiValanarGUID = pCreature->GetGUID();
+ break;
+ case NPC_KELESETH:
+ m_uiKelesethGUID = pCreature->GetGUID();
+ break;
+ case NPC_LANATHEL:
+ m_uiLanathelGUID = pCreature->GetGUID();
+ break;
+ case NPC_LANATHEL_INTRO:
+ m_uiLanathelintroGUID = pCreature->GetGUID();
+ break;
+ case NPC_VALITHRIA:
+ m_uiValithriaGUID = pCreature->GetGUID();
+ break;
+ case NPC_VALITHRIA_QUEST:
+ m_uiValithriaQuestGUID = pCreature->GetGUID();
+ break;
+ case NPC_SINDRAGOSA:
+ m_uiSindragosaGUID = pCreature->GetGUID();
+ break;
+ case NPC_LICH_KING:
+ m_uiLichKingGUID = pCreature->GetGUID();
+ break;
+ case NPC_RIMEFANG:
+ m_uiRimefangGUID = pCreature->GetGUID();
+ break;
+ case NPC_SPINESTALKER:
+ m_uiSpinestalkerGUID = pCreature->GetGUID();
+ break;
+ case NPC_STINKY:
+ m_uiStinkyGUID = pCreature->GetGUID();
+ break;
+ case NPC_PRECIOUS:
+ m_uiPreciousGUID = pCreature->GetGUID();
+ break;
+ case NPC_COMBAT_TRIGGER:
+ m_uidummyTargetGUID = pCreature->GetGUID();
+ break;
+ case NPC_FROSTMOURNE_TRIGGER:
+ m_uiFrostmourneTriggerGUID = pCreature->GetGUID(); break;
+ case NPC_FROSTMOURNE_HOLDER:
+ m_uiFrostmourneHolderGUID = pCreature->GetGUID(); break;
+ }
+ }
+
+ void instance_icecrown_spire::OnObjectCreate(GameObject* pGo)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_ICEWALL_1:
+ m_uiIcewall1GUID = pGo->GetGUID();
+ break;
+ case GO_ICEWALL_2:
+ m_uiIcewall2GUID = pGo->GetGUID();
+ break;
+ case GO_ORATORY_DOOR:
+ m_uiOratoryDoorGUID = pGo->GetGUID();
+ break;
+ case GO_DEATHWHISPER_ELEVATOR:
+ m_uiDeathWhisperElevatorGUID = pGo->GetGUID();
+ break;
+ case GO_SAURFANG_DOOR:
+ m_uiSaurfangDoorGUID = pGo->GetGUID();
+ break;
+ case GO_ORANGE_PLAGUE:
+ m_uiOrangePlagueGUID = pGo->GetGUID();
+ break;
+ case GO_GREEN_PLAGUE:
+ m_uiGreenPlagueGUID = pGo->GetGUID();
+ break;
+ case GO_SCIENTIST_DOOR_GREEN:
+ m_uiSDoorGreenGUID = pGo->GetGUID();
+ break;
+ case GO_SCIENTIST_DOOR_ORANGE:
+ m_uiSDoorOrangeGUID = pGo->GetGUID();
+ break;
+ case GO_SCIENTIST_DOOR_COLLISION:
+ m_uiSDoorCollisionGUID = pGo->GetGUID();
+ break;
+ case GO_SCIENTIST_DOOR:
+ m_uiScientistDoorGUID = pGo->GetGUID();
+ break;
+ case GO_CRIMSON_HALL_DOOR:
+ m_uiCrimsonDoorGUID = pGo->GetGUID();
+ break;
+ case GO_BLOODWING_DOOR:
+ m_uiBloodwingDoorGUID = pGo->GetGUID();
+ break;
+ case GO_COUNCIL_DOOR_1:
+ m_uiCounsilDoor1GUID = pGo->GetGUID();
+ break;
+ case GO_COUNCIL_DOOR_2:
+ m_uiCounsilDoor2GUID = pGo->GetGUID();
+ break;
+ case GO_FROSTWING_DOOR:
+ m_uiFrostwingDoorGUID = pGo->GetGUID();
+ break;
+ case GO_GREEN_DRAGON_DOOR_1:
+ m_uiGreenDragonDoor1GUID = pGo->GetGUID();
+ break;
+ case GO_GREEN_DRAGON_DOOR_2:
+ m_uiGreenDragonDoor2GUID = pGo->GetGUID();
+ break;
+ case GO_VALITHRIA_DOOR_1:
+ m_uiValithriaDoor1GUID = pGo->GetGUID();
+ break;
+ case GO_VALITHRIA_DOOR_2:
+ m_uiValithriaDoor2GUID = pGo->GetGUID();
+ break;
+ case GO_VALITHRIA_DOOR_3:
+ m_uiValithriaDoor3GUID = pGo->GetGUID();
+ break;
+ case GO_VALITHRIA_DOOR_4:
+ m_uiValithriaDoor4GUID = pGo->GetGUID();
+ break;
+ case GO_SINDRAGOSA_DOOR_1:
+ m_uiSindragosaDoor1GUID = pGo->GetGUID();
+ break;
+ case GO_SINDRAGOSA_DOOR_2:
+ m_uiSindragosaDoor2GUID = pGo->GetGUID();
+ break;
+ case GO_SAURFANG_CACHE_10:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL)
+ m_uiSaurfangCacheGUID = pGo->GetGUID();
+ break;
+ case GO_SAURFANG_CACHE_25:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL)
+ m_uiSaurfangCacheGUID = pGo->GetGUID();
+ break;
+ case GO_SAURFANG_CACHE_10_H:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC)
+ m_uiSaurfangCacheGUID = pGo->GetGUID();
+ break;
+ case GO_SAURFANG_CACHE_25_H:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+ m_uiSaurfangCacheGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_A_10:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL)
+ m_uiGunshipArmoryAGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_A_25:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL)
+ m_uiGunshipArmoryAGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_A_10H:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC)
+ m_uiGunshipArmoryAGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_A_25H:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+ m_uiGunshipArmoryAGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_H_10:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL)
+ m_uiGunshipArmoryHGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_H_25:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL)
+ m_uiGunshipArmoryHGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_H_10H:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC)
+ m_uiGunshipArmoryHGUID = pGo->GetGUID();
+ break;
+ case GO_GUNSHIP_ARMORY_H_25H:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+ m_uiGunshipArmoryHGUID = pGo->GetGUID();
+ break;
+ case GO_DREAMWALKER_CACHE_10:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL)
+ m_uiValitriaCacheGUID = pGo->GetGUID();
+ break;
+ case GO_DREAMWALKER_CACHE_25:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_NORMAL)
+ m_uiValitriaCacheGUID = pGo->GetGUID();
+ break;
+ case GO_DREAMWALKER_CACHE_10_H:
+ if(Difficulty == RAID_DIFFICULTY_10MAN_HEROIC)
+ m_uiValitriaCacheGUID = pGo->GetGUID();
+ break;
+ case GO_DREAMWALKER_CACHE_25_H:
+ if(Difficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+ m_uiValitriaCacheGUID = pGo->GetGUID();
+ break;
+ case GO_ICESHARD_1:
+ m_uiIceShard1GUID = pGo->GetGUID();
+ break;
+ case GO_ICESHARD_2:
+ m_uiIceShard2GUID = pGo->GetGUID();
+ break;
+ case GO_ICESHARD_3:
+ m_uiIceShard3GUID = pGo->GetGUID();
+ break;
+ case GO_ICESHARD_4:
+ m_uiIceShard4GUID = pGo->GetGUID();
+ break;
+ case GO_FROSTY_WIND:
+ m_uiFrostyWindGUID = pGo->GetGUID();
+ break;
+ case GO_FROSTY_EDGE:
+ m_uiFrostyEdgeGUID = pGo->GetGUID();
+ break;
+ case GO_SNOW_EDGE:
+ m_uiSnowEdgeGUID = pGo->GetGUID();
+ break;
+ case GO_ARTHAS_PLATFORM:
+ m_uiArthasPlatformGUID = pGo->GetGUID();
+ break;
+ case GO_ARTHAS_PRECIPICE:
+ m_uiArthasPrecipiceGUID = pGo->GetGUID();
+ break;
+ case GO_GAS_RELEASE_VALVE:
+ m_uiGasReleaseValveGUID = pGo->GetGUID();
+ break;
+ case NPC_BLOOD_ORB_CONTROL:
+ m_uiBloodOrbCtrlGUID = pGo->GetGUID();
+ break;
+ }
+ OpenAllDoors();
+ }
+
+ void instance_icecrown_spire::SetData(uint32 uiType, uint32 uiData)
+ {
+ switch(uiType)
+ {
+ case TYPE_TELEPORT:
+ break;
+ case TYPE_MARROWGAR:
+ m_auiEncounter[TYPE_MARROWGAR] = uiData;
+ if (uiData == DONE)
+ {
+ OpenDoor(m_uiIcewall1GUID);
+ OpenDoor(m_uiIcewall2GUID);
+ OpenDoor( m_uiOratoryDoorGUID);
+ }
+ break;
+ case TYPE_DEATHWHISPER:
+ m_auiEncounter[TYPE_DEATHWHISPER] = uiData;
+ if (uiData == DONE) {
+ if (GameObject* pGO = instance->GetGameObject(m_uiDeathWhisperElevatorGUID))
+ {
+ pGO->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
+ pGO->SetGoState(GO_STATE_READY);
+ }
+ }
+ break;
+ case TYPE_FLIGHT_WAR:
+ if (uiData == DONE && m_auiEncounter[TYPE_FLIGHT_WAR] != DONE ) {
+ if (GameObject* pChest = instance->GetGameObject(m_uiGunshipArmoryAGUID))
+ if (pChest && !pChest->isSpawned()) {
+ pChest->SetRespawnTime(7*DAY);
+ };
+
+ if (GameObject* pChest = instance->GetGameObject(m_uiGunshipArmoryHGUID))
+ if (pChest && !pChest->isSpawned()) {
+ pChest->SetRespawnTime(7*DAY);
+ };
+ };
+ m_auiEncounter[3] = uiData;
+ break;
+ case TYPE_SAURFANG:
+ m_auiEncounter[TYPE_SAURFANG] = uiData;
+ if (uiData == DONE)
+ {
+ OpenDoor(m_uiSaurfangDoorGUID);
+ OpenDoor(m_uiBloodwingDoorGUID);
+ OpenDoor(m_uiFrostwingDoorGUID);
+
+ if (GameObject* pChest = instance->GetGameObject(m_uiSaurfangCacheGUID))
+ if (pChest && !pChest->isSpawned())
+ {
+ pChest->SetRespawnTime(7*DAY);
+ };
+ };
+ break;
+ case TYPE_FESTERGUT:
+ m_auiEncounter[TYPE_FESTERGUT] = uiData;
+ if (uiData == IN_PROGRESS) CloseDoor(m_uiOrangePlagueGUID);
+ else OpenDoor(m_uiOrangePlagueGUID);
+ if (uiData == DONE) {
+ OpenDoor(m_uiSDoorOrangeGUID);
+ if (m_auiEncounter[TYPE_ROTFACE] == DONE)
+ {
+ OpenDoor(m_uiSDoorCollisionGUID);
+ OpenDoor(m_uiGreenPlagueGUID);
+ }
+ }
+ break;
+ case TYPE_ROTFACE:
+ m_auiEncounter[TYPE_ROTFACE] = uiData;
+ if (uiData == IN_PROGRESS)
+ CloseDoor(m_uiGreenPlagueGUID);
+ else
+ OpenDoor(m_uiGreenPlagueGUID);
+ if (uiData == DONE)
+ {
+ OpenDoor(m_uiSDoorGreenGUID);
+ if (m_auiEncounter[TYPE_FESTERGUT] == DONE)
+ {
+ OpenDoor(m_uiSDoorOrangeGUID);
+ OpenDoor(m_uiSDoorCollisionGUID);
+ }
+ }
+ break;
+ case TYPE_PUTRICIDE:
+ m_auiEncounter[TYPE_PUTRICIDE] = uiData;
+ if (uiData == IN_PROGRESS)
+ CloseDoor(m_uiScientistDoorGUID);
+ else
+ OpenDoor(m_uiScientistDoorGUID);
+ if (uiData == DONE)
+ {
+ if (m_auiEncounter[TYPE_SINDRAGOSA] == DONE
+ && m_auiEncounter[TYPE_LANATHEL] == DONE)
+ m_auiEncounter[TYPE_KINGS_OF_ICC] = DONE;
+ }
+ break;
+ case TYPE_BLOOD_COUNCIL:
+ m_auiEncounter[TYPE_BLOOD_COUNCIL] = uiData;
+
+ if (uiData == IN_PROGRESS)
+ CloseDoor(m_uiCrimsonDoorGUID);
+ else
+ OpenDoor(m_uiCrimsonDoorGUID);
+
+ if (uiData == DONE)
+ {
+ OpenDoor(m_uiCounsilDoor1GUID);
+ OpenDoor(m_uiCounsilDoor2GUID);
+ }
+ break;
+ case TYPE_LANATHEL:
+ m_auiEncounter[TYPE_LANATHEL] = uiData;
+ if (uiData == DONE)
+ {
+ if (m_auiEncounter[TYPE_PUTRICIDE] == DONE
+ && m_auiEncounter[TYPE_SINDRAGOSA] == DONE)
+ m_auiEncounter[TYPE_KINGS_OF_ICC] = DONE;
+ }
+ break;
+ case TYPE_VALITHRIA:
+ m_auiEncounter[TYPE_VALITHRIA] = uiData;
+
+ if (uiData == IN_PROGRESS)
+ CloseDoor(m_uiGreenDragonDoor1GUID);
+ else
+ OpenDoor(m_uiGreenDragonDoor1GUID);
+
+ if (uiData == DONE)
+ {
+ OpenDoor(m_uiGreenDragonDoor2GUID);
+ OpenDoor(m_uiSindragosaDoor1GUID);
+ OpenDoor(m_uiSindragosaDoor2GUID);
+ if (GameObject* pChest = instance->GetGameObject(m_uiValitriaCacheGUID))
+ if (pChest && !pChest->isSpawned())
+ {
+ pChest->SetRespawnTime(7*DAY);
+ };
+ };
+ break;
+ case TYPE_SINDRAGOSA:
+ m_auiEncounter[TYPE_SINDRAGOSA] = uiData;
+ if (uiData == DONE)
+ {
+ if (m_auiEncounter[TYPE_PUTRICIDE] == DONE
+ && m_auiEncounter[TYPE_LANATHEL] == DONE)
+ m_auiEncounter[TYPE_KINGS_OF_ICC] = DONE;
+ }
+ break;
+ case TYPE_LICH_KING:
+ m_auiEncounter[TYPE_LICH_KING] = uiData;
+ break;
+ case TYPE_ICECROWN_QUESTS:
+ m_auiEncounter[TYPE_ICECROWN_QUESTS] = uiData;
+ break;
+ case TYPE_COUNT:
+ m_auiEncounter[TYPE_COUNT] = uiData;
+ uiData = NOT_STARTED;
+ break;
+ case DATA_BLOOD_COUNCIL_HEALTH: m_uiDataCouncilHealth = uiData;
+ uiData = NOT_STARTED;
+ break;
+ case DATA_BLOOD_INVOCATION: m_uiCouncilInvocation = uiData;
+ uiData = NOT_STARTED;
+ break;
+ case DATA_DIRECTION: m_uiDirection = uiData;
+ uiData = NOT_STARTED;
+ break;
+ case TYPE_EVENT: m_auiEvent = uiData; uiData = NOT_STARTED; break;
+ case TYPE_EVENT_TIMER: m_auiEventTimer = uiData; uiData = NOT_STARTED; break;
+ case TYPE_STINKY: m_uiStinkystate = uiData; uiData = NOT_STARTED; break;
+ case TYPE_PRECIOUS: m_uiPreciousstate = uiData; uiData = NOT_STARTED; break;
+ }
+
+ if (uiData == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ strSaveData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint32 instance_icecrown_spire::GetData(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case TYPE_TELEPORT:
+ case TYPE_MARROWGAR:
+ case TYPE_DEATHWHISPER:
+ case TYPE_FLIGHT_WAR:
+ case TYPE_SAURFANG:
+ case TYPE_FESTERGUT:
+ case TYPE_ROTFACE:
+ case TYPE_PUTRICIDE:
+ case TYPE_BLOOD_COUNCIL:
+ case TYPE_LANATHEL:
+ case TYPE_VALITHRIA:
+ case TYPE_SINDRAGOSA:
+ case TYPE_KINGS_OF_ICC:
+ case TYPE_LICH_KING:
+ case TYPE_ICECROWN_QUESTS:
+ case TYPE_COUNT:
+ return m_auiEncounter[uiType];
+
+ case DATA_DIRECTION: return m_uiDirection;
+ case DATA_BLOOD_COUNCIL_HEALTH: return m_uiDataCouncilHealth;
+ case DATA_BLOOD_INVOCATION: return m_uiCouncilInvocation;
+ case TYPE_STINKY: return m_uiStinkystate;
+ case TYPE_PRECIOUS: return m_uiPreciousstate;
+ case TYPE_EVENT: return m_auiEvent;
+ case TYPE_EVENT_TIMER: return m_auiEventTimer;
+ case TYPE_EVENT_NPC: switch (m_auiEvent)
+ {
+ case 12030:
+ case 12050:
+ case 12051:
+ case 12052:
+ case 12053:
+ case 12070:
+ case 12090:
+ case 12110:
+ case 12130:
+ case 12150:
+ case 12170:
+ case 13110:
+ case 13130:
+ case 13131:
+ case 13132:
+ case 13150:
+ case 13170:
+ case 13190:
+ case 13210:
+ case 13230:
+ case 13250:
+ case 13270:
+ case 13290:
+ case 13310:
+ case 13330:
+ case 13350:
+ case 13370:
+ case 14010:
+ case 14030:
+ case 14050:
+ case 14070:
+ return NPC_TIRION;
+ break;
+
+ case 12000:
+ case 12020:
+ case 12040:
+ case 12041:
+ case 12042:
+ case 12043:
+ case 12060:
+ case 12080:
+ case 12100:
+ case 12120:
+ case 12200:
+ case 13000:
+ case 13020:
+ case 13040:
+ case 13060:
+ case 13080:
+ case 13100:
+ case 13120:
+ case 13140:
+ case 13160:
+ case 13180:
+ case 13200:
+ case 13220:
+ case 13240:
+ case 13260:
+ case 13280:
+ case 13300:
+ case 14000:
+ return NPC_LICH_KING;
+ break;
+ case 500:
+ case 510:
+ case 550:
+ case 560:
+ case 570:
+ case 580:
+ case 590:
+ case 600:
+ case 610:
+ case 620:
+ case 630:
+ case 640:
+ case 650:
+ case 660:
+ return NPC_PROFESSOR_PUTRICIDE;
+ break;
+
+ case 800:
+ case 810:
+ case 820:
+ return NPC_LANATHEL_INTRO;
+ break;
+
+ default:
+ break;
+ };
+
+ }
+ return 0;
+ }
+
+ uint64 instance_icecrown_spire::GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case NPC_LORD_MARROWGAR: return m_uiMarrogwarGUID;
+ case NPC_LADY_DEATHWHISPER: return m_uiDeathWhisperGUID;
+ case NPC_DEATHBRINGER_SAURFANG: return m_uiSaurfangGUID;
+ case NPC_FESTERGUT: return m_uiFestergutGUID;
+ case NPC_ROTFACE: return m_uiRotfaceGUID;
+ case NPC_PROFESSOR_PUTRICIDE: return m_uiPutricideGUID;
+ case NPC_TALDARAM: return m_uiTaldaramGUID;
+ case NPC_VALANAR: return m_uiValanarGUID;
+ case NPC_KELESETH: return m_uiKelesethGUID;
+ case NPC_LANATHEL: return m_uiLanathelGUID;
+ case NPC_LANATHEL_INTRO: return m_uiLanathelintroGUID;
+ case NPC_VALITHRIA: return m_uiValithriaGUID;
+ case NPC_VALITHRIA_QUEST: return m_uiValithriaQuestGUID;
+ case NPC_SINDRAGOSA: return m_uiSindragosaGUID;
+ case NPC_LICH_KING: return m_uiLichKingGUID;
+ case NPC_RIMEFANG: return m_uiRimefangGUID;
+ case NPC_SPINESTALKER: return m_uiSpinestalkerGUID;
+ case NPC_STINKY: return m_uiStinkyGUID;
+ case NPC_PRECIOUS: return m_uiPreciousGUID;
+ case GO_SCIENTIST_DOOR_ORANGE: return m_uiSDoorOrangeGUID;
+ case GO_SCIENTIST_DOOR_GREEN: return m_uiSDoorGreenGUID;
+ case GO_SCIENTIST_DOOR_COLLISION: return m_uiSDoorCollisionGUID;
+ case GO_BLOODWING_DOOR: return m_uiBloodwingDoorGUID;
+ case GO_FROSTWING_DOOR: return m_uiFrostwingDoorGUID;
+ case GO_VALITHRIA_DOOR_1: return m_uiValithriaDoor1GUID;
+ case GO_VALITHRIA_DOOR_2: return m_uiValithriaDoor2GUID;
+ case GO_VALITHRIA_DOOR_3: return m_uiValithriaDoor3GUID;
+ case GO_VALITHRIA_DOOR_4: return m_uiValithriaDoor4GUID;
+ case GO_ICESHARD_1: return m_uiIceShard1GUID;
+ case GO_ICESHARD_2: return m_uiIceShard2GUID;
+ case GO_ICESHARD_3: return m_uiIceShard3GUID;
+ case GO_ICESHARD_4: return m_uiIceShard4GUID;
+ case GO_FROSTY_WIND: return m_uiFrostyWindGUID;
+ case GO_FROSTY_EDGE: return m_uiFrostyEdgeGUID;
+ case GO_SNOW_EDGE: return m_uiSnowEdgeGUID;
+ case GO_ARTHAS_PLATFORM: return m_uiArthasPlatformGUID;
+ case GO_ARTHAS_PRECIPICE: return m_uiArthasPrecipiceGUID;
+ case NPC_FROSTMOURNE_TRIGGER: return m_uiFrostmourneTriggerGUID;
+ case NPC_FROSTMOURNE_HOLDER: return m_uiFrostmourneHolderGUID;
+ case NPC_COMBAT_TRIGGER: return m_uidummyTargetGUID;
+ case GO_GAS_RELEASE_VALVE: return m_uiGasReleaseValveGUID;
+ case NPC_BLOOD_ORB_CONTROL: return m_uiBloodOrbCtrlGUID;
+ }
+ return 0;
+ }
+
+ void instance_icecrown_spire::Load(const char* chrIn)
+ {
+ if (!chrIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(chrIn);
+
+ std::istringstream loadStream(chrIn);
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
+
+ if (m_auiEncounter[i] == IN_PROGRESS && i >= 1)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ OpenAllDoors();
+ }
+
+InstanceData* GetInstanceData_instance_icecrown_spire(Map* pMap)
+{
+ return new instance_icecrown_spire(pMap);
+}
+
+
+void AddSC_instance_icecrown_spire()
+{
+ Script* pNewScript;
+ pNewScript = new Script;
+ pNewScript->Name = "instance_icecrown_spire";
+ pNewScript->GetInstanceData = &GetInstanceData_instance_icecrown_spire;
+ pNewScript->RegisterSelf();
+}
diff --git a/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp b/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp
new file mode 100644
index 0000000..215ca48
--- /dev/null
+++ b/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp
@@ -0,0 +1,28 @@
+/* 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_malygos
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Eye of Eternity
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_boss_malygos()
+{
+}
diff --git a/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h b/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h
new file mode 100644
index 0000000..dc0d78d
--- /dev/null
+++ b/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h
@@ -0,0 +1,13 @@
+#ifndef DEF_EYE_OF_ETERNITY_H
+#define DEF_EYE_OF_ETERNITY_H
+
+enum eTypes
+{
+ MAX_ENCOUNTER = 1,
+
+ TYPE_MALYGOS = 0,
+ DATA_MALIGOS = 10,
+ NPC_MALYGOS = 28859
+};
+
+#endif
diff --git a/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp b/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp
new file mode 100644
index 0000000..d3a1d8b
--- /dev/null
+++ b/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp
@@ -0,0 +1,109 @@
+#include "precompiled.h"
+#include "eye_of_eternity.h"
+
+enum eGameObjects
+{
+ GO_Malygos_CHEST_HERO = 193967,
+ GO_Malygos_CHEST = 193905
+};
+
+struct MANGOS_DLL_DECL instance_eye_of_eternity : public ScriptedInstance
+{
+ instance_eye_of_eternity(Map* pMap) : ScriptedInstance(pMap), MalygosChest(NULL) { Initialize(); };
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+
+ uint64 m_uiMalygosGUID;
+
+ uint64 MalygosChest;
+
+ void Initialize()
+ {
+ m_uiMalygosGUID = 0;
+ MalygosChest = 0;
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ }
+
+ void OnCreatureCreate(Creature* pCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_MALYGOS:
+ m_uiMalygosGUID = pCreature->GetGUID();
+ break;
+ }
+
+ }
+
+ void OnObjectCreate(GameObject* pGo)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_Malygos_CHEST_HERO:
+ MalygosChest = pGo->GetGUID();
+ if (m_auiEncounter[TYPE_MALYGOS] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ break;
+ case GO_Malygos_CHEST:
+ MalygosChest = pGo->GetGUID();
+ if (m_auiEncounter[TYPE_MALYGOS] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case TYPE_MALYGOS:
+ m_auiEncounter[TYPE_MALYGOS] = data;
+ if (data == DONE && MalygosChest)
+ DoRespawnGameObject(MalygosChest, 30*MINUTE);
+ break;
+ }
+
+ if (data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint64 GetData64(uint32 data)
+ {
+ switch(data)
+ {
+ case TYPE_MALYGOS:
+ return m_uiMalygosGUID;
+ }
+
+ return 0;
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case TYPE_MALYGOS:
+ return m_auiEncounter[type];
+ }
+
+ return 0;
+ }
+};
+
+InstanceData* GetInstanceData_instance_eye_of_eternity(Map* pMap)
+{
+ return new instance_eye_of_eternity(pMap);
+}
+
+void AddSC_instance_eye_of_eternity()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_eye_of_eternity";
+ newscript->GetInstanceData = &GetInstanceData_instance_eye_of_eternity;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/nexus/nexus/boss_keristrasza.cpp b/scripts/northrend/nexus/nexus/boss_keristrasza.cpp
index ed956c6..2121fc9 100644
--- a/scripts/northrend/nexus/nexus/boss_keristrasza.cpp
+++ b/scripts/northrend/nexus/nexus/boss_keristrasza.cpp
@@ -78,7 +78,6 @@ struct MANGOS_DLL_DECL boss_keristraszaAI : public ScriptedAI
m_bIsEnraged = false;
-
if (!m_pInstance)
return;
diff --git a/scripts/northrend/nexus/oculus/boss_drakos.cpp b/scripts/northrend/nexus/oculus/boss_drakos.cpp
new file mode 100644
index 0000000..71c809e
--- /dev/null
+++ b/scripts/northrend/nexus/oculus/boss_drakos.cpp
@@ -0,0 +1,227 @@
+/* Copyright (C) 2008 - 2010 TrinityCore
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: Boss_Drakos
+SD%Complete: 80%
+SDComment:
+SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa
+SDCategory: Oculus
+EndScriptData */
+
+#include "precompiled.h"
+#include "oculus.h"
+
+enum
+{
+ SAY_AGGRO = -1578000,
+ SAY_KILL_1 = -1578001,
+ SAY_KILL_2 = -1578002,
+ SAY_KILL_3 = -1578003,
+ SAY_DEATH = -1578004,
+ SAY_PULL_1 = -1578005,
+ SAY_PULL_2 = -1578006,
+ SAY_PULL_3 = -1578007,
+ SAY_PULL_4 = -1578008,
+ SAY_STOMP_1 = -1578009,
+ SAY_STOMP_2 = -1578010,
+ SAY_STOMP_3 = -1578011,
+
+ SPELL_MAGIC_PULL = 51336,
+ SPELL_MAGIC_PULL_EFFECT = 50770,
+ SPELL_THUNDERING_STOMP_N = 50774,
+ SPELL_THUNDERING_STOMP_H = 59370,
+ SPELL_UNSTABLE_SPHERE_PASSIVE = 50756,
+ SPELL_UNSTABLE_SPHERE_PULSE = 50757,
+ SPELL_UNSTABLE_SPHERE_TIMER = 50758,
+ SPELL_UNSTABLE_SPHERE_EXPLODE = 50759,
+
+ NPC_UNSTABLE_SPHERE = 28166
+};
+
+#define CENTER_X 960.120f
+#define CENTER_Y 1049.413f
+
+struct MANGOS_DLL_DECL boss_drakosAI : public ScriptedAI
+{
+ boss_drakosAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiMagicPullTimer ;
+ uint32 m_uiStompTimer ;
+ uint32 m_uiBombSummonTimer ;
+
+ void Reset()
+ {
+ m_uiMagicPullTimer = urand(12000, 15000);
+ m_uiStompTimer = urand(3000, 6000);
+ m_uiBombSummonTimer = 7000;
+ if (m_pInstance && m_creature->isAlive())
+ m_pInstance->SetData(TYPE_DRAKOS, NOT_STARTED);
+ }
+
+ void Aggro(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_DRAKOS, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_DRAKOS, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ switch (urand(0, 2))
+ {
+ case 0: DoScriptText(SAY_KILL_1, m_creature); break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature); break;
+ case 2: DoScriptText(SAY_KILL_3, m_creature); break;
+ }
+ }
+
+ void SpellHitTarget(Unit *target, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_MAGIC_PULL)
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ DoCast(target, SPELL_MAGIC_PULL_EFFECT, true);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiBombSummonTimer < diff)
+ {
+ m_creature->SummonCreature(NPC_UNSTABLE_SPHERE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000);
+ m_creature->SummonCreature(NPC_UNSTABLE_SPHERE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000);
+ m_uiBombSummonTimer = 3000;
+ }
+ else
+ m_uiBombSummonTimer -= diff;
+
+ if (m_uiMagicPullTimer < diff)
+ {
+ DoCast(m_creature, SPELL_MAGIC_PULL);
+ m_uiMagicPullTimer = urand(15000, 25000);
+ switch (urand(0, 3))
+ {
+ case 0: DoScriptText(SAY_PULL_1, m_creature); break;
+ case 1: DoScriptText(SAY_PULL_2, m_creature); break;
+ case 2: DoScriptText(SAY_PULL_3, m_creature); break;
+ case 3: DoScriptText(SAY_PULL_4, m_creature); break;
+ }
+ }
+ else
+ m_uiMagicPullTimer -= diff;
+
+ if (m_uiStompTimer < diff)
+ {
+ DoCast(m_creature, SPELL_THUNDERING_STOMP_N);
+ m_uiStompTimer = urand(11000, 18000);
+ switch (urand(0, 2))
+ {
+ case 0: DoScriptText(SAY_STOMP_1, m_creature); break;
+ case 1: DoScriptText(SAY_STOMP_2, m_creature); break;
+ case 2: DoScriptText(SAY_STOMP_3, m_creature); break;
+ }
+ }
+ else
+ m_uiStompTimer -= diff ;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_drakos(Creature* pCreature)
+{
+ return new boss_drakosAI (pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_unstable_sphereAI : public ScriptedAI
+{
+ npc_unstable_sphereAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_uiPulseTimer;
+
+ void Reset()
+ {
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ m_creature->GetMotionMaster()->MovePoint(0, (CENTER_X-35)+rand()%70, (CENTER_Y-35)+rand()%70, m_creature->GetPositionZ());
+ m_creature->SetSpeedRate(MOVE_RUN, 2, true);
+ m_creature->setFaction(14);
+ DoCast(m_creature, SPELL_UNSTABLE_SPHERE_PASSIVE, true);
+ DoCast(m_creature, SPELL_UNSTABLE_SPHERE_TIMER, true);
+ m_uiPulseTimer = 3000;
+ m_creature->ForcedDespawn(19000);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (m_pInstance && m_pInstance->GetData(TYPE_DRAKOS) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_uiPulseTimer < diff)
+ {
+ DoCast(m_creature, SPELL_UNSTABLE_SPHERE_PULSE, true);
+ m_uiPulseTimer = 3000;
+ }
+ else
+ m_uiPulseTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_npc_unstable_sphere(Creature* pCreature)
+{
+ return new npc_unstable_sphereAI (pCreature);
+}
+
+void AddSC_boss_drakos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_drakos";
+ newscript->GetAI = &GetAI_boss_drakos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_unstable_sphere";
+ newscript->GetAI = &GetAI_npc_unstable_sphere;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/nexus/oculus/boss_eregos.cpp b/scripts/northrend/nexus/oculus/boss_eregos.cpp
new file mode 100644
index 0000000..f830b1b
--- /dev/null
+++ b/scripts/northrend/nexus/oculus/boss_eregos.cpp
@@ -0,0 +1,320 @@
+/* Copyright (C) 2008 - 2010 TrinityCore
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: Boss_Eregos
+SD%Complete: 60%
+SDComment:
+SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa
+SDCategory: Oculus
+EndScriptData */
+
+#include "precompiled.h"
+#include "oculus.h"
+
+enum Spells
+{
+ SAY_AGGRO = -1578030,
+ SAY_KILL_1 = -1578031,
+ SAY_KILL_2 = -1578032,
+ SAY_KILL_3 = -1578033,
+ SAY_DEATH = -1578034,
+ SAY_ARCANE_SHIELD = -1578035,
+ SAY_FIRE_SHIELD = -1578036,
+ SAY_NATURE_SHIELD = -1578037,
+ SAY_FRENZY = -1578038,
+ SAY_SPAWN = -1578039,
+
+ SPELL_ARCANE_BARRAGE_N = 50804,
+ SPELL_ARCANE_BARRAGE_H = 59381,
+ SPELL_ARCANE_VOLLEY_N = 51153,
+ SPELL_ARCANE_VOLLEY_H = 59382,
+ SPELL_ENRAGED_ASSAULT = 51170,
+ SPELL_SUMMON_DRAKE = 51175,
+ SPELL_PLANAR_ANOMALIES = 57959,
+ SPELL_PLANAR_ANOMALIES_SUMMON = 57963, //need spell script on m_creature 27656
+ SPELL_PLANAR_ANOMALIES_VISUAL = 57971,
+ SPELL_PLANAR_SHIFT = 51162,
+ SPELL_PLANAR_ANOMALIES_DMG = 57976,
+
+ NPC_PLANAR_ANOMALY = 30879,
+ NPC_DRAGON = 28276
+};
+
+struct MANGOS_DLL_DECL boss_eregosAI : public ScriptedAI
+{
+ boss_eregosAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 uiArcaneBarrageTimer;
+ uint32 uiArcaneVolleyTimer;
+ uint32 uiEnragedAssaultTimer;
+ uint32 uiSummonTimer;
+
+ uint8 m_uiSummonCount;
+
+ bool m_bIsMove;
+
+ void Reset()
+ {
+ m_creature->SetVisibility(VISIBILITY_ON);
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_EREGOS, NOT_STARTED);
+ if(m_pInstance->GetData(TYPE_UROM) == DONE)
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ else
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ }
+
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ uiArcaneBarrageTimer = 12000;
+ uiArcaneVolleyTimer = 17000;
+ uiEnragedAssaultTimer = 24000;
+ uiSummonTimer = 15000;
+ m_uiSummonCount = 0;
+ m_bIsMove = true;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if(pWho->GetTypeId() == TYPEID_PLAYER
+ && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)
+ && !((Player*)pWho)->isGameMaster()
+ && m_creature->IsWithinDistInMap(pWho, 100.0f)
+ && pWho->GetVehicle()
+ && m_pInstance->GetData(TYPE_UROM) == DONE)
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void Aggro(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_EREGOS, IN_PROGRESS);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ uint8 uiText = urand(0, 2);
+ switch (uiText)
+ {
+ case 0: DoScriptText(SAY_KILL_1, m_creature); break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature); break;
+ case 2: DoScriptText(SAY_KILL_3, m_creature); break;
+ }
+ }
+
+ void JustDied(Unit* killer)
+ {
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()-100.0f, 0);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()-100.0f, SPLINETYPE_NORMAL , m_creature->GetSplineFlags(), 6000);
+ DoScriptText(SAY_DEATH, m_creature);
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_EREGOS, DONE);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &damage)
+ {
+ if(m_creature->HasAura(SPELL_PLANAR_SHIFT))
+ damage = 0;
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if(pSummoned->GetEntry() == NPC_PLANAR_ANOMALY)
+ {
+ pSummoned->SetDisplayId(11686);
+ pSummoned->SetInCombatWithZone();
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pSummoned->AI()->AttackStart(pTarget);
+ }
+
+ if(pSummoned->GetEntry() == NPC_DRAGON)
+ {
+ pSummoned->SetInCombatWithZone();
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pSummoned->AI()->AttackStart(pTarget);
+ }
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ ScriptedAI::AttackStart(who);
+ }
+
+ void SummonAnomalies()
+ {
+ std::list t_list = m_creature->getThreatManager().getThreatList();
+ if (t_list.size())
+ {
+ for (std::list::iterator itr = t_list.begin(); itr != t_list.end(); ++itr)
+ {
+ Unit *pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());
+ if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
+ DoCast(m_creature, SPELL_PLANAR_ANOMALIES_SUMMON, true);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_creature->GetHealthPercent() < 50.0f && m_uiSummonCount == 0)
+ {
+ SummonAnomalies();
+ m_uiSummonCount = 1;
+ m_creature->CastSpell(m_creature, SPELL_PLANAR_SHIFT,true);
+ }
+
+ if(m_creature->GetHealthPercent() < 25.0f && m_uiSummonCount == 1)
+ {
+ SummonAnomalies();
+ m_uiSummonCount = 2;
+ m_creature->CastSpell(m_creature, SPELL_PLANAR_SHIFT,true);
+ }
+
+ if(m_creature->GetDistance2d(m_creature->getVictim()) > 35.0f && !m_bIsMove)
+ {
+ m_bIsMove = true;
+ SetCombatMovement(m_bIsMove);
+ if(Unit* pTarget = m_creature->getVictim())
+ m_creature->GetMotionMaster()->MoveChase(pTarget);
+ }
+
+ if(m_creature->GetDistance2d(m_creature->getVictim()) < 20.0f && m_bIsMove)
+ {
+ m_bIsMove = false;
+ SetCombatMovement(m_bIsMove);
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->StopMoving();
+ }
+
+ if(uiArcaneBarrageTimer <= diff)
+ {
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_ARCANE_BARRAGE_N : SPELL_ARCANE_BARRAGE_H);
+ uiArcaneBarrageTimer = 3000;
+ } else uiArcaneBarrageTimer -= diff;
+
+ if(uiSummonTimer <= diff)
+ {
+ for(uint8 i = 1; i < 3; i++)
+ DoCast(m_creature, SPELL_SUMMON_DRAKE, true);
+ uiSummonTimer = 15000;
+ } else uiSummonTimer -= diff;
+
+ if(uiArcaneVolleyTimer <= diff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ARCANE_VOLLEY_N : SPELL_ARCANE_VOLLEY_H);
+ uiArcaneVolleyTimer = 17000;
+ } else uiArcaneVolleyTimer -= diff;
+
+ if(uiEnragedAssaultTimer <= diff)
+ {
+ DoCast(m_creature, SPELL_ENRAGED_ASSAULT, true);
+ uiEnragedAssaultTimer = 44000;
+ } else uiEnragedAssaultTimer -= diff;
+ }
+};
+
+struct MANGOS_DLL_DECL npc_planar_anomalyAI : public ScriptedAI
+{
+ npc_planar_anomalyAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 uiPulseTimer;
+ uint32 uiDeathTimer;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(11686);
+ m_creature->SetObjectScale(2.0f);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ m_creature->SetSpeedRate(MOVE_RUN, 1.5, true);
+ m_creature->setFaction(14);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(m_creature, SPELL_PLANAR_ANOMALIES_VISUAL, true);
+ uiDeathTimer = 20500;
+ uiPulseTimer = 19000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiPulseTimer < diff)
+ {
+ m_creature->RemoveAurasDueToSpell(SPELL_PLANAR_ANOMALIES_VISUAL);
+ m_creature->CastSpell(m_creature, SPELL_PLANAR_ANOMALIES_DMG, true);
+ uiPulseTimer = 6000;
+ } else uiPulseTimer -= diff;
+
+ if (uiDeathTimer < diff)
+ m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else uiDeathTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_eregos(Creature* pCreature)
+{
+ return new boss_eregosAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_planar_anomaly(Creature* pCreature)
+{
+ return new npc_planar_anomalyAI (pCreature);
+}
+
+void AddSC_boss_eregos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_eregos";
+ newscript->GetAI = &GetAI_boss_eregos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_planar_anomaly";
+ newscript->GetAI = &GetAI_npc_planar_anomaly;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/nexus/oculus/boss_urom.cpp b/scripts/northrend/nexus/oculus/boss_urom.cpp
new file mode 100644
index 0000000..e8623cc
--- /dev/null
+++ b/scripts/northrend/nexus/oculus/boss_urom.cpp
@@ -0,0 +1,378 @@
+/* Copyright (C) 2008 - 2010 TrinityCore
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/* ScriptData
+SDName: Boss_Urom
+SD%Complete: 70%
+SDComment:
+SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa
+SDCategory: Oculus
+EndScriptData */
+
+#include "precompiled.h"
+#include "oculus.h"
+
+enum
+{
+ SAY_AGGRO = -1578012,
+ SAY_KILL_1 = -1578013,
+ SAY_KILL_2 = -1578014,
+ SAY_KILL_3 = -1578015,
+ SAY_DEATH = -1578016,
+ SAY_EXPLOSION_1 = -1578017,
+ SAY_EXPLOSION_2 = -1578018,
+ SAY_SUMMON_1 = -1578019,
+ SAY_SUMMON_2 = -1578020,
+ SAY_SUMMON_3 = -1578021,
+
+ SPELL_ARCANE_BARRIER = 53813, //Dummy --> Channeled, shields the caster from damage.
+ SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110,
+ SPELL_EMPOWERED_ARCANE_EXPLOSION_2 = 59377,
+ SPELL_FROSTBOMB = 51103, //Urom throws a bomb, hitting its target with the highest aggro which inflict directly 650 frost damage and drops a frost zone on the ground. This zone deals 650 frost damage per second and reduce the movement speed by 35%. Lasts 1 minute.
+ SPELL_SUMMON_MENAGERIE = 50476, //Summons an assortment of creatures and teleports the caster to safety.
+ SPELL_SUMMON_MENAGERIE_2 = 50495,
+ SPELL_SUMMON_MENAGERIE_3 = 50496,
+ SPELL_TELEPORT = 51112, //Teleports to the center of Oculus
+ SPELL_TIME_BOMB = 51121, //Deals arcane damage to a random player, and after 6 seconds, deals zone damage to nearby equal to the health missing of the target afflicted by the debuff.
+ SPELL_TIME_BOMB_2 = 59376,
+
+ //NPCs
+ NPC_PHANTASMAL_MAMMOTH = 27642,
+ NPC_PHANTASMAL_WOLF = 27644,
+ NPC_PHANTASMAL_CLOUDSCRAPER = 27645,
+ NPC_PHANTASMAL_OGRE = 27647,
+ NPC_PHANTASMAL_NAGA = 27648,
+ NPC_PHANTASMAL_MURLOC = 27649,
+ NPC_PHANTASMAL_AIR = 27650,
+ NPC_PHANTASMAL_FIRE = 27651,
+ NPC_PHANTASMAL_WATER = 27653
+};
+/*
+struct Locations
+{
+ float x, y, z, o;
+ uint32 id;
+};
+*/
+struct Locations Teleport[]=
+{
+ {1177.469f, 937.721f, 527.405f, 2.21f}, //first platform
+ {968.5880f, 1042.58f, 527.321f, 0.13f}, //second platform
+ {1163.671f, 1171.02f, 527.321f, 4.19f}, //third platform
+ {1116.765f, 1075.93f, 508.361f, 4.26f}, //middle platform
+ {1103.659f, 1049.88f, 518.148f, 5.80f} //oculus center
+};
+
+struct MANGOS_DLL_DECL boss_uromAI : public BSWScriptedAI
+{
+ boss_uromAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiFrostBombTimer;
+ uint32 m_uiLiveBombTimer;
+ uint32 m_uiTeleportTimer;
+ uint32 m_uiArcaneExplodeTimer;
+ uint32 m_uiRelocateTimer;
+ uint32 m_uiBackTimer;
+ uint32 m_uiCheckTimer;
+
+ bool m_bIsTeleported;
+ bool m_bIsTalk;
+
+ void Reset()
+ {
+ m_uiFrostBombTimer = 9000;
+ m_uiLiveBombTimer = 14000;
+ m_uiTeleportTimer = 30000;
+ m_uiRelocateTimer = 31500;
+ m_uiBackTimer = 9000;
+ m_uiCheckTimer = 2000;
+ m_uiArcaneExplodeTimer = 1000;
+
+ m_bIsTeleported = false;
+ m_bIsTalk = false;
+
+ if (m_pInstance && m_pInstance->GetData(TYPE_UROM) != IN_PROGRESS)
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_pInstance->SetData(TYPE_UROM, NOT_STARTED);
+ if(m_pInstance->GetData(TYPE_VAROS) == DONE)
+ {
+ m_creature->RemoveAurasDueToSpell(SPELL_ARCANE_BARRIER);
+ m_creature->InterruptNonMeleeSpells(false);
+// m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ else
+ {
+ DoCast(m_creature, SPELL_ARCANE_BARRIER);
+ }
+ }
+ }
+
+ void DoSummon(uint32 Entry01, uint32 Entry02, uint32 Entry03, uint32 Entry04, uint32 Entry05 = 0)
+ {
+ m_creature->SummonCreature(Entry01, m_creature->GetPositionX() - (10.0f) * cos(M_PI / 2), m_creature->GetPositionY() - (10.0f) * sin(M_PI / 2), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000);
+ m_creature->SummonCreature(Entry02, m_creature->GetPositionX() - (10.0f) * cos(M_PI * 2), m_creature->GetPositionY() - (10.0f) * sin(M_PI * 2), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000);
+ m_creature->SummonCreature(Entry03, m_creature->GetPositionX() - (10.0f) * cos(M_PI + M_PI / 2), m_creature->GetPositionY() - (10.0f) * sin(M_PI + M_PI / 2), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000);
+ m_creature->SummonCreature(Entry04, m_creature->GetPositionX() - (10.0f) * cos(M_PI), m_creature->GetPositionY() - (10.0f) * sin(M_PI), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000);
+ if(Entry05 != 0)
+ m_creature->SummonCreature(Entry05, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000);
+ }
+
+ void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
+ {
+ if(pSpell->Id == SPELL_SUMMON_MENAGERIE) //|| pSpell->Id == SPELL_SUMMON_MENAGERIE_2 || pSpell->Id == SPELL_SUMMON_MENAGERIE_3)
+ m_bIsTalk = false;
+ if(pSpell->Id == SPELL_SUMMON_MENAGERIE_2)
+ m_bIsTalk = false;
+ if(pSpell->Id == SPELL_SUMMON_MENAGERIE_3)
+ m_bIsTalk = false;
+ }
+
+ void TeleportBoss(float X, float Y, float Z, float O)
+ {
+ m_creature->GetMap()->CreatureRelocation(m_creature, X, Y, Z, O);
+ m_creature->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL, SPLINEFLAG_DONE, 0);
+ m_creature->Relocate(X, Y, Z, O);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+
+ if(m_pInstance->GetData(TYPE_UROM_PHASE) < 3)
+ return;
+
+ if (m_bIsTeleported)
+ return;
+
+ ScriptedAI::AttackStart(pWho);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_pInstance)
+ return;
+
+ if(pWho->GetTypeId() == TYPEID_PLAYER
+ && !((Player*)pWho)->isGameMaster()
+ && m_creature->IsWithinDistInMap(pWho, 30.0f)
+ && !pWho->GetVehicle()
+ && m_pInstance->GetData(TYPE_VAROS) == DONE
+ && !m_bIsTalk)
+ {
+ switch(m_pInstance->GetData(TYPE_UROM_PHASE))
+ {
+ case 0:
+ m_bIsTalk = true;
+ SetCombatMovement(false);
+ m_pInstance->SetData(TYPE_UROM, IN_PROGRESS);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->RemoveAurasDueToSpell(53813);
+ DoScriptText(SAY_SUMMON_1, m_creature);
+ DoSummon(NPC_PHANTASMAL_FIRE, NPC_PHANTASMAL_FIRE, NPC_PHANTASMAL_AIR, NPC_PHANTASMAL_WATER);
+ DoCast(m_creature, SPELL_SUMMON_MENAGERIE);
+ m_pInstance->SetData(TYPE_UROM_PHASE, 1);
+ break;
+ case 1:
+ m_bIsTalk = true;
+ DoScriptText(SAY_SUMMON_2, m_creature);
+ DoSummon(NPC_PHANTASMAL_OGRE, NPC_PHANTASMAL_OGRE, NPC_PHANTASMAL_NAGA, NPC_PHANTASMAL_MURLOC);
+ DoCast(m_creature, SPELL_SUMMON_MENAGERIE_2);
+ m_pInstance->SetData(TYPE_UROM_PHASE, 2);
+ break;
+ case 2:
+ m_bIsTalk = true;
+ DoScriptText(SAY_SUMMON_3, m_creature);
+ DoSummon(NPC_PHANTASMAL_MAMMOTH, NPC_PHANTASMAL_WOLF, NPC_PHANTASMAL_WOLF, NPC_PHANTASMAL_CLOUDSCRAPER, NPC_PHANTASMAL_CLOUDSCRAPER);
+ DoCast(m_creature, SPELL_SUMMON_MENAGERIE_3);
+ m_pInstance->SetData(TYPE_UROM_PHASE, 3);
+ break;
+ case 3:
+ m_bIsTalk = true;
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(true);
+ AttackStart(pWho);
+ break;
+ default:
+ break;
+ }
+ }
+
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if(pWho->GetTypeId() != TYPEID_PLAYER)
+ EnterEvadeMode();
+ else DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!m_pInstance || !summoned) return;
+
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(100.0f))
+ {
+ summoned->SetInCombatWith(pTarget);
+ summoned->AddThreat(pTarget,100.0f);
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+
+ if (!m_pInstance)
+ return;
+
+ if( m_pInstance->GetData(TYPE_UROM_PHASE) < 3)
+ {
+ Map::PlayerList const &pList = m_creature->GetMap()->GetPlayers();
+ if (!pList.isEmpty())
+ return;
+ }
+ m_pInstance->SetData(TYPE_UROM, FAIL);
+ m_pInstance->SetData(TYPE_UROM_PHASE, 1);
+ ScriptedAI::EnterEvadeMode();
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_UROM, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ uint8 uiText = urand(0, 2);
+ switch (uiText)
+ {
+ case 0: DoScriptText(SAY_KILL_1, m_creature); break;
+ case 1: DoScriptText(SAY_KILL_2, m_creature); break;
+ case 2: DoScriptText(SAY_KILL_3, m_creature); break;
+ }
+ }
+
+ void CheckVehicle()
+ {
+ Map *map = m_creature->GetMap();
+ if(map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if(PlayerList.isEmpty())
+ return;
+
+ for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if(i->getSource()->isAlive() && i->getSource()->GetVehicle())
+ EnterEvadeMode();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(!m_bIsTeleported)
+ {
+ if(m_uiFrostBombTimer < uiDiff)
+ {
+ m_creature->CastSpell(m_creature->getVictim(), SPELL_FROSTBOMB, false);
+ m_uiFrostBombTimer = urand(5000, 7000);
+ } else m_uiFrostBombTimer -= uiDiff;
+
+ if(m_uiLiveBombTimer < uiDiff)
+ {
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_TIME_BOMB : SPELL_TIME_BOMB_2);
+ m_uiLiveBombTimer = urand(15000, 25000);
+ } else m_uiLiveBombTimer -= uiDiff;
+
+ if(m_uiTeleportTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_TELEPORT);
+ m_uiTeleportTimer = 31500;
+ } else m_uiTeleportTimer -= uiDiff;
+
+ if(m_uiCheckTimer < uiDiff)
+ {
+ CheckVehicle();
+ m_uiCheckTimer = 2000;
+ } else m_uiCheckTimer -= uiDiff;
+
+ if(m_uiRelocateTimer < uiDiff)
+ {
+ m_bIsTeleported = true;
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->StopMoving();
+ TeleportBoss(Teleport[4].x,Teleport[4].y,Teleport[4].z,Teleport[4].o);
+ m_uiRelocateTimer = 31500;
+ } else m_uiRelocateTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+ else
+ {
+ if(m_uiArcaneExplodeTimer < uiDiff)
+ {
+ DoScriptText(urand(0,1) ? SAY_EXPLOSION_1 : SAY_EXPLOSION_2, m_creature);
+ DoCast(m_creature, SPELL_EMPOWERED_ARCANE_EXPLOSION);
+ m_uiArcaneExplodeTimer = 32000;
+ } else m_uiArcaneExplodeTimer -= uiDiff;
+
+ if(m_uiBackTimer < uiDiff)
+ {
+ TeleportBoss((m_creature->getVictim())->GetPositionX(),(m_creature->getVictim())->GetPositionY(),(m_creature->getVictim())->GetPositionZ(),(m_creature->getVictim())->GetOrientation());
+ m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING);
+ if(m_creature->getVictim())
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_uiBackTimer = 9000;
+ m_bIsTeleported = false;
+ m_uiArcaneExplodeTimer = 1000;
+ } else m_uiBackTimer -= uiDiff;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_urom(Creature* pCreature)
+{
+ return new boss_uromAI (pCreature);
+}
+
+void AddSC_boss_urom()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_urom";
+ newscript->GetAI = &GetAI_boss_urom;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/nexus/oculus/boss_varos.cpp b/scripts/northrend/nexus/oculus/boss_varos.cpp
new file mode 100644
index 0000000..e430478
--- /dev/null
+++ b/scripts/northrend/nexus/oculus/boss_varos.cpp
@@ -0,0 +1,470 @@
+/* Copyright (C) 2008 - 2010 TrinityCore
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: Boss_Varos
+SD%Complete: 70%
+SDComment:
+SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa
+SDCategory: Oculus
+EndScriptData */
+
+#include "precompiled.h"
+#include "oculus.h"
+
+enum
+{
+ SAY_AGGRO = -1578022,
+ SAY_KILL_1 = -1578023,
+ SAY_KILL_2 = -1578024,
+ SAY_DEATH = -1578025,
+ SAY_STRIKE_1 = -1578026,
+ SAY_STRIKE_2 = -1578027,
+ SAY_STRIKE_3 = -1578028,
+
+ SPELL_ARCANE_SHIELD = 50053,
+ SPELL_ENERGIZE_CORES = 50785, //Damage 5938 to 6562, effec2 Triggers 54069, effect3 Triggers 56251
+ SPELL_ENERGIZE_CORES_TRIGGER_1 = 54069,
+ SPELL_ENERGIZE_CORES_TRIGGER_2 = 56251,
+ SPELL_ENERGIZE_CORES_2 = 59372, //Damage 9025 to 9975, effect2 Triggers 54069, effect 56251
+ SPELL_CALL_AZURE_RING_CAPTAIN = 51002, //Effect Send Event (12229)
+ SPELL_CALL_AZURE_RING_CAPTAIN_2 = 51006, //Effect Send Event (10665)
+ SPELL_CALL_AZURE_RING_CAPTAIN_3 = 51007, //Effect Send Event (18454)
+ SPELL_CALL_AZURE_RING_CAPTAIN_4 = 51008, //Effect Send Event (18455)
+ SPELL_CALL_AMPLIFY_MAGIC = 51054,
+ SPELL_CALL_AMPLIFY_MAGIC_2 = 59371,
+
+ NPC_AZURE_CAPTAIN = 28236,
+ NPC_BEAM = 28239,
+ NPC_VAROS_CORE = 28183,
+
+ SPELL_CORE_VISUAL = 50798,
+ SPELL_CORE_MISSILE = 61407, //need core fix max target 4, and spell script on 28183
+ SPELL_BEAM = 51024, //need spell scrip on 28239
+ SPELL_BEAM_DMG_AURA = 51019,
+ SPELL_BEAM_VISUAL_SOUND = 51022, //need script target 28239
+ SPELL_SUMMON_BEAM = 51017
+};
+
+struct dLocations
+{
+ float x1, y1, x2, y2;
+ uint32 id;
+};
+
+struct dLocations Regions[]=
+{
+ {0, 0, 0},
+ {1323.0f, 1056.0f, 1333.0f, 1066.0f}, //first orb 1
+ {1319.3f, 1084.0f, 1329.5f, 1094.0f}, //second orb 2
+ {1288.3f, 1108.8f, 1298.3f, 1118.8f}, //third orb 3
+ {1260.3f, 1104.2f, 1270.3f, 1114.2f}, //four orb 4
+ {1237.7f, 1074.5f, 1247.7f, 1084.5f}, //fifth orb 5
+ {1241.8f, 1046.1f, 1251.8f, 1056.1f}, // 6
+ {1272.0f, 1022.1f, 1282.0f, 1032.1f}, // 7
+ {1300.5f, 1026.2f, 1310.5f, 1036.2f} // 8
+};
+
+struct MANGOS_DLL_DECL boss_varosAI : public ScriptedAI
+{
+ boss_varosAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint8 MinOrb;
+ uint8 MaxOrb;
+
+ uint32 m_uiCoreTimer;
+ uint32 m_uiOrbCast;
+ uint32 m_uiDragonAttackTimer;
+ uint32 m_uiDragonMoveTimer;
+ uint32 m_uiCheckTimer;
+
+ uint64 m_uiAzureDrakeGUID;
+
+ bool m_bIsCastChain;
+
+ float angle01;
+ float angle02;
+
+ void Reset()
+ {
+ MinOrb = 1;
+ MaxOrb = 4;
+ angle01 = 0;
+ angle02 = 0;
+ m_uiOrbCast = 7000;
+ m_uiCheckTimer = 2000;
+ m_uiDragonAttackTimer = 10000;
+ m_uiCoreTimer = urand(7000, 15000);
+ m_uiDragonMoveTimer = 16000;
+ m_bIsCastChain = false;
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_VAROS, NOT_STARTED);
+ if(m_pInstance->GetData(TYPE_ROBOTS) == 0)
+ {
+ m_creature->RemoveAurasDueToSpell(SPELL_ARCANE_SHIELD);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ else
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(m_creature, SPELL_ARCANE_SHIELD);
+ }
+ if(Creature* Dragon = m_pInstance->instance->GetCreature(m_uiAzureDrakeGUID))
+ Dragon->DealDamage(Dragon, Dragon->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ m_uiAzureDrakeGUID = 0;
+ }
+
+ void CheckVehicle()
+ {
+ Map* map = m_creature->GetMap();
+ if(map && map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if(PlayerList.isEmpty())
+ return;
+
+ for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if(i->getSource()->isAlive() && i->getSource()->GetVehicle())
+ EnterEvadeMode();
+ }
+ }
+ }
+
+ void Aggro(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_VAROS, IN_PROGRESS);
+
+ if(Creature* Dragon = m_creature->SummonCreature(NPC_AZURE_CAPTAIN, (m_creature->GetPositionX()-45)+rand()%90, (m_creature->GetPositionY()-45)+rand()%90, m_creature->GetPositionZ() + 30.0f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 100))
+ {
+ Dragon->AddSplineFlag(SPLINEFLAG_FLYING);
+ Dragon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_uiAzureDrakeGUID = Dragon->GetGUID();
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if(m_pInstance)
+ if(m_pInstance->GetData(TYPE_ROBOTS) != 0)
+ return;
+
+ ScriptedAI::AttackStart(pWho);
+
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_VAROS, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ DoScriptText(urand(0,1) ? SAY_KILL_1 : SAY_KILL_2, m_creature);
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if(pSummoned->GetEntry() == NPC_BEAM)
+ {
+ pSummoned->setFaction(14);
+ pSummoned->SetDisplayId(11686);
+ pSummoned->CastSpell(pSummoned, SPELL_BEAM_VISUAL_SOUND, false);
+ pSummoned->CastSpell(pSummoned, SPELL_BEAM_DMG_AURA, false);
+ pSummoned->SetInCombatWithZone();
+ if(Unit* pTarget = pSummoned->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pSummoned->AI()->AttackStart(pTarget);
+ if(m_pInstance)
+ if(Creature* Dragon = m_pInstance->instance->GetCreature(m_uiAzureDrakeGUID))
+ {
+ Dragon->GetMotionMaster()->MovementExpired(false);
+ Dragon->GetMotionMaster()->Clear(false);
+ Dragon->CastSpell(pSummoned, SPELL_BEAM, true);
+ }
+ }
+ }
+
+ void SelectFourOrb() //huck work perfecly
+ {
+ MinOrb = MinOrb+2;
+ MaxOrb = MaxOrb+2;
+ if(MinOrb > 8)
+ MinOrb = 1;
+ if(MaxOrb > 8)
+ MaxOrb = 2;
+
+ std::list m_pSpheres;
+ GetCreatureListWithEntryInGrid(m_pSpheres, m_creature, NPC_VAROS_CORE, DEFAULT_VISIBILITY_INSTANCE);
+
+ if(!m_pSpheres.empty())
+ for(std::list::iterator iter = m_pSpheres.begin(); iter != m_pSpheres.end(); ++iter)
+ {
+ for(uint8 i = 1; i < 9; i++)
+ if((i <= MaxOrb && i >= MinOrb) || (MinOrb == 7 && (i <= MaxOrb || i >= MinOrb)))
+ if((*iter)->GetPositionX() > Regions[i].x1 && (*iter)->GetPositionX() < Regions[i].x2)
+ if((*iter)->GetPositionY() > Regions[i].y1 && (*iter)->GetPositionY() < Regions[i].y2)
+ if(SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_CORE_MISSILE))
+ {
+ pTempSpell->EffectImplicitTargetA[0] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[0] = 0;
+ pTempSpell->EffectImplicitTargetA[1] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[1] = 0;
+ pTempSpell->EffectImplicitTargetA[2] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[2] = 0;
+ (*iter)->CastSpell(m_creature, pTempSpell, true);
+ }
+ }
+ }
+
+ void CastEnergy()
+ {
+ std::list m_pSpheres;
+ GetCreatureListWithEntryInGrid(m_pSpheres, m_creature, NPC_VAROS_CORE, DEFAULT_VISIBILITY_INSTANCE);
+
+ if(!m_pSpheres.empty())
+ for(std::list::iterator iter = m_pSpheres.begin(); iter != m_pSpheres.end(); ++iter)
+ {
+ for(uint8 i = 1; i < 9; i++)
+ if((i <= MaxOrb && i >= MinOrb) || (MinOrb == 7 && (i <= MaxOrb || i >= MinOrb)))
+ if((*iter)->GetPositionX() > Regions[i].x1 && (*iter)->GetPositionX() < Regions[i].x2)
+ if((*iter)->GetPositionY() > Regions[i].y1 && (*iter)->GetPositionY() < Regions[i].y2)
+ {
+ if(SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_ENERGIZE_CORES_TRIGGER_1))
+ {
+ pTempSpell->EffectImplicitTargetA[0] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[0] = 0;
+ pTempSpell->EffectImplicitTargetA[1] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[1] = 0;
+ pTempSpell->EffectImplicitTargetA[2] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[2] = 0;
+ (*iter)->CastSpell(m_creature, pTempSpell, true);
+ }
+
+ if(i == MinOrb)
+ angle01 = m_creature->GetAngle((*iter));
+ if(i == MaxOrb)
+ angle02 = m_creature->GetAngle((*iter));
+
+ Map *map = m_creature->GetMap();
+ if(map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if(PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive())
+ {
+ float pAngle = m_creature->GetAngle(i->getSource());
+ if(angle01 < angle02)
+ if(pAngle < angle02 && pAngle > angle01)
+ DoEnergy(i->getSource());
+ if(angle01 > angle02)
+ if(pAngle < angle02 || pAngle > angle01)
+ DoEnergy(i->getSource());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void DoEnergy(Unit* pTarget)
+ {
+ if(SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(m_bIsRegularMode ? SPELL_ENERGIZE_CORES : SPELL_ENERGIZE_CORES_2))
+ {
+ pTempSpell->EffectImplicitTargetA[0] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[0] = 0;
+ pTempSpell->EffectImplicitTargetA[1] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[1] = 0;
+ pTempSpell->EffectImplicitTargetA[2] = TARGET_EFFECT_SELECT;
+ pTempSpell->EffectImplicitTargetB[2] = 0;
+ m_creature->CastSpell(pTarget, pTempSpell, true);
+ }
+
+ }
+
+ /*void SpellHitTarget(Unit *target, const SpellEntry *spell)
+ {
+ if(spell->Id == (m_bIsRegularMode ? SPELL_ENERGIZE_CORES : SPELL_ENERGIZE_CORES_2) && target->GetTypeId() == TYPEID_PLAYER)
+ {
+ int32 uiDmg = m_bIsRegularMode ? urand(5938, 6562) : urand(9025, 9975);
+ m_creature->DealDamage(target, uiDmg,NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, NULL, false);
+ }
+ }*/
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiCheckTimer < uiDiff)
+ {
+ CheckVehicle();
+ m_uiCheckTimer = 2000;
+ } else m_uiCheckTimer -= uiDiff;
+
+ if(m_uiDragonAttackTimer <= uiDiff)
+ {
+ DoCast(m_creature, SPELL_SUMMON_BEAM, true);
+ m_uiDragonAttackTimer = 25000;
+ m_uiDragonMoveTimer = 16000;
+ uint8 uiText = urand(0, 2);
+ switch (uiText)
+ {
+ case 0: DoScriptText(SAY_STRIKE_1, m_creature); break;
+ case 1: DoScriptText(SAY_STRIKE_2, m_creature); break;
+ case 2: DoScriptText(SAY_STRIKE_3, m_creature); break;
+ }
+ } else m_uiDragonAttackTimer -= uiDiff;
+
+ if(m_uiDragonMoveTimer <= uiDiff)
+ {
+ if(m_pInstance)
+ if(Creature* Dragon = m_pInstance->instance->GetCreature(m_uiAzureDrakeGUID))
+ {
+ Dragon->GetMotionMaster()->MovementExpired(false);
+ Dragon->GetMotionMaster()->Clear(false);
+ Dragon->GetMotionMaster()->MovePoint(0, (m_creature->GetPositionX()-45)+rand()%90, (m_creature->GetPositionY()-45)+rand()%90, m_creature->GetPositionZ() + 30.0f);
+ }
+ m_uiDragonMoveTimer = 25000;
+ } else m_uiDragonMoveTimer -= uiDiff;
+
+ if(!m_bIsCastChain)
+ {
+ if(m_uiOrbCast <= uiDiff)
+ {
+ m_uiOrbCast = 1000;
+ m_bIsCastChain = true;
+ SelectFourOrb();
+ m_uiCoreTimer = 5000;
+ } else m_uiOrbCast -= uiDiff;
+ }
+ else
+ {
+ if(m_uiCoreTimer <= uiDiff)
+ {
+ m_uiCoreTimer = 5000;
+ m_bIsCastChain = false;
+ CastEnergy();
+ m_uiOrbCast = 1000;
+ } else m_uiCoreTimer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL npc_varos_orbAI : public ScriptedAI
+{
+ npc_varos_orbAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->setFaction(14);
+ DoCast(m_creature, SPELL_CORE_VISUAL, true);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ }
+};
+
+struct MANGOS_DLL_DECL npc_varos_beam_targetAI : public ScriptedAI
+{
+ npc_varos_beam_targetAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+ uint32 uiDeathTimer;
+
+ void Reset()
+ {
+ m_creature->SetSpeedRate(MOVE_RUN, 0.5f, true);
+ uiDeathTimer = 15000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiDeathTimer < diff)
+ m_creature->ForcedDespawn();
+ else uiDeathTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_varos(Creature* pCreature)
+{
+ return new boss_varosAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_varos_orb(Creature* pCreature)
+{
+ return new npc_varos_orbAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_varos_beam_target(Creature* pCreature)
+{
+ return new npc_varos_beam_targetAI (pCreature);
+}
+
+void AddSC_boss_varos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_varos";
+ newscript->GetAI = &GetAI_boss_varos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_varos_orb";
+ newscript->GetAI = &GetAI_npc_varos_orb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_varos_beam_target";
+ newscript->GetAI = &GetAI_npc_varos_beam_target;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/nexus/oculus/instance_oculus.cpp b/scripts/northrend/nexus/oculus/instance_oculus.cpp
new file mode 100644
index 0000000..95219b7
--- /dev/null
+++ b/scripts/northrend/nexus/oculus/instance_oculus.cpp
@@ -0,0 +1,240 @@
+/* Copyright (C) 2008 - 2010 TrinityCore
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: instance_oculus
+SD%Complete: 70%
+SDComment:
+SDAuthor: originally from TC, reworked by MaxXx2021 Aka Mioka, corrected by /dev/rsa
+SDCategory: Oculus
+EndScriptData */
+
+#include "precompiled.h"
+#include "oculus.h"
+
+/* The Occulus encounters:
+0 - Drakos the Interrogator
+1 - Varos Cloudstrider
+2 - Mage-Lord Urom
+3 - Ley-Guardian Eregos */
+
+enum
+{
+ SAY_VAROS_SPAWN = -1578029,
+};
+
+struct MANGOS_DLL_DECL instance_oculus : public ScriptedInstance
+{
+ instance_oculus(Map* pMap) : ScriptedInstance(pMap)
+ {
+ m_bIsRegularMode = pMap->IsRegularDifficulty();
+ Initialize();
+ };
+
+ uint64 uiDrakos;
+ uint64 m_uiVarosGUID;
+ uint64 m_uiUromGUID;
+ uint64 m_uiEregosGUID;
+ uint64 uiProect;
+ uint64 uiCacheEregosGUID;
+ uint64 uiCacheEregosHGUID;
+ uint64 m_uiSpotLightGUID;
+
+ uint32 m_auiEncounter[MAX_ENCOUNTERS+1];
+
+ std::string strSaveData;
+ bool m_bIsRegularMode;
+
+ void Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTERS+1; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ uiCacheEregosGUID = 0;
+ m_uiSpotLightGUID = 0;
+ uiProect = 0;
+ m_uiVarosGUID = 0;
+ m_uiUromGUID = 0;
+ m_uiEregosGUID = 0;
+ m_auiEncounter[TYPE_ROBOTS] = 10;
+ m_auiEncounter[TYPE_UROM_PHASE] = 0;
+ }
+
+ void OnObjectCreate(GameObject* pGO)
+ {
+ switch(pGO->GetEntry())
+ {
+ case GO_EREGOS_CACHE:
+ uiCacheEregosGUID = pGO->GetGUID();
+ break;
+ case GO_EREGOS_CACHE_H:
+ uiCacheEregosHGUID = pGO->GetGUID();
+ break;
+ case GO_SPOTLIGHT:
+ m_uiSpotLightGUID = pGO->GetGUID();
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* pCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_DRAKOS:
+ uiDrakos = pCreature->GetGUID();
+ break;
+ case NPC_VAROS:
+ m_uiVarosGUID = pCreature->GetGUID();
+ break;
+ case NPC_UROM:
+ m_uiUromGUID = pCreature->GetGUID();
+ break;
+ case NPC_EREGOS:
+ m_uiEregosGUID = pCreature->GetGUID();
+ break;
+ case NPC_BALGAR_IMAGE:
+ uiProect = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case TYPE_DRAKOS:
+ case TYPE_VAROS:
+ case TYPE_UROM:
+ m_auiEncounter[type] = data;
+ break;
+ case TYPE_EREGOS:
+ m_auiEncounter[type] = data;
+ if (data == DONE)
+ {
+ DoRespawnGameObject((m_bIsRegularMode ? uiCacheEregosGUID : uiCacheEregosHGUID), HOUR);
+ DoRespawnGameObject(m_uiSpotLightGUID, HOUR);
+ }
+ break;
+ case TYPE_ROBOTS:
+ m_auiEncounter[type] = m_auiEncounter[type] - data;
+ if(m_auiEncounter[type] == 0)
+ {
+ if(Creature* pVaros = instance->GetCreature(m_uiVarosGUID))
+ {
+ DoScriptText(SAY_VAROS_SPAWN, pVaros);
+ pVaros->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pVaros->InterruptNonMeleeSpells(false);
+ pVaros->RemoveAurasDueToSpell(50053);
+ }
+ }
+ data = NOT_STARTED;
+ break;
+ case TYPE_UROM_PHASE:
+ m_auiEncounter[type] = data;
+ data = NOT_STARTED;
+ break;
+ }
+
+ if (data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ strSaveData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case TYPE_DRAKOS:
+ case TYPE_VAROS:
+ case TYPE_UROM:
+ case TYPE_EREGOS:
+ case TYPE_ROBOTS:
+ case TYPE_UROM_PHASE:
+ return m_auiEncounter[type];
+ default:
+ return 0;
+ }
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_DRAKOS: return uiDrakos;
+ case NPC_VAROS: return m_uiVarosGUID;
+ case NPC_UROM: return m_uiUromGUID;
+ case NPC_EREGOS: return m_uiEregosGUID;
+ }
+ return 0;
+ }
+
+ const char* Save()
+ {
+ return strSaveData.c_str();
+ }
+
+ void Load(const char* chrIn)
+ {
+ if (!chrIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(chrIn);
+
+ std::istringstream loadStream(chrIn);
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
+
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ m_auiEncounter[TYPE_ROBOTS] = 10;
+ m_auiEncounter[TYPE_UROM_PHASE] = 0;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_oculus(Map* pMap)
+{
+ return new instance_oculus(pMap);
+}
+
+void AddSC_instance_oculus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_oculus";
+ newscript->GetInstanceData = &GetInstanceData_instance_oculus;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/nexus/oculus/oculus.cpp b/scripts/northrend/nexus/oculus/oculus.cpp
new file mode 100644
index 0000000..9a37579
--- /dev/null
+++ b/scripts/northrend/nexus/oculus/oculus.cpp
@@ -0,0 +1,232 @@
+/* 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: oculus
+SD%Complete: ?%
+SDComment: by /dev/rsa
+SDCategory: Oculus - mobs and special
+EndScriptData */
+
+#include "precompiled.h"
+#include "oculus.h"
+enum Spells
+{
+ SPELL_GREEN_SEAT = 49346,
+ SPELL_YELLOW_SEAT = 49460,
+ SPELL_RED_SEAT = 49464,
+};
+
+enum NPC
+{
+ NPC_GREEN_DRAGON = 27692,
+ NPC_YELLOW_DRAGON = 27755,
+ NPC_RED_DRAGON = 27756,
+};
+
+struct MANGOS_DLL_DECL mob_oculus_dragonAI : public ScriptedAI
+{
+ mob_oculus_dragonAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ bool Active;
+ ObjectGuid ownerGUID;
+ uint32 seatSpell;
+ uint32 StartTimer;
+
+ void Reset()
+ {
+ Active = false;
+ ownerGUID = 0;
+ StartTimer = 2000;
+ switch (m_creature->GetEntry())
+ {
+ case NPC_GREEN_DRAGON:
+ seatSpell = SPELL_GREEN_SEAT;
+ break;
+ case NPC_RED_DRAGON:
+ seatSpell = SPELL_RED_SEAT;
+ break;
+ case NPC_YELLOW_DRAGON:
+ seatSpell = SPELL_YELLOW_SEAT;
+ break;
+ default:
+ seatSpell = 0;
+ break;
+ }
+ ownerGUID = m_creature->GetCreatorGuid();
+
+ if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID))
+ owner->RemoveAurasDueToSpell(53797);
+ }
+
+ void AttackStart(Unit *) {}
+ void MoveInLineOfSight(Unit*) {}
+
+ void JustSummoned()
+ {
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (!m_creature || m_creature->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ if (ownerGUID.IsEmpty())
+ ownerGUID = m_creature->GetCreatorGuid();
+
+ Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID);
+
+ if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ owner->RemoveAurasDueToSpell(seatSpell);
+ owner->RemoveAurasDueToSpell(53797);
+ m_creature->SetCreatorGuid(ObjectGuid());
+ }
+
+ void MovementInform(uint32 uiType, uint32 uiPointId)
+ {
+ if (uiType != POINT_MOTION_TYPE && uiPointId == 0)
+ return;
+
+ if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID))
+ {
+ m_creature->setFaction(owner->getFaction());
+ owner->CastSpell(m_creature, seatSpell, true);
+ owner->CastSpell(owner, 53797, true);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (ownerGUID.IsEmpty())
+ ownerGUID = m_creature->GetCreatorGuid();
+
+ if (!ownerGUID.IsEmpty())
+ {
+ if (StartTimer < uiDiff && !Active)
+ {
+ if (Unit* owner = m_creature->GetMap()->GetUnit(ownerGUID))
+ {
+ float x, y, z;
+ owner->GetClosePoint(x, y, z, owner->GetObjectBoundingRadius(), 1.0f, owner->GetAngle(m_creature));
+ m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
+ Active = true;
+ }
+ }
+ else
+ StartTimer -= uiDiff;
+ }
+ else
+ if (StartTimer < uiDiff)
+ m_creature->ForcedDespawn();
+ }
+};
+
+CreatureAI* GetAI_mob_oculus_dragon(Creature* pCreature)
+{
+ return new mob_oculus_dragonAI(pCreature);
+}
+
+/*#####
+# npc_robot
+#####*/
+
+struct MANGOS_DLL_DECL npc_oculus_robotAI : public ScriptedAI
+{
+ npc_oculus_robotAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_ROBOTS, 1);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_oculus_robot(Creature* pCreature)
+{
+ return new npc_oculus_robotAI (pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_belgar_imageAI : public ScriptedAI
+{
+ npc_belgar_imageAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ }
+};
+
+CreatureAI* GetAI_npc_belgar_image(Creature* pCreature)
+{
+ return new npc_belgar_imageAI (pCreature);
+}
+
+void AddSC_oculus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "mob_oculus_dragon";
+ newscript->GetAI = &GetAI_mob_oculus_dragon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_oculus_robot";
+ newscript->GetAI = &GetAI_npc_oculus_robot;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_belgar_image";
+ newscript->GetAI = &GetAI_npc_belgar_image;
+ newscript->RegisterSelf();
+
+}
diff --git a/scripts/northrend/nexus/oculus/oculus.h b/scripts/northrend/nexus/oculus/oculus.h
new file mode 100644
index 0000000..4affa6b
--- /dev/null
+++ b/scripts/northrend/nexus/oculus/oculus.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 2010 by /dev/rsa for ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_OCULUS_H
+#define DEF_OCULUS_H
+#include "BSW_ai.h"
+#include "BSW_instance.h"
+
+enum
+{
+ TYPE_DRAKOS,
+ TYPE_VAROS,
+ TYPE_UROM,
+ TYPE_EREGOS,
+ TYPE_ROBOTS,
+ TYPE_UROM_PHASE,
+ MAX_ENCOUNTERS,
+
+ DATA_DRAKOS,
+ DATA_VAROS,
+ DATA_UROM,
+ DATA_EREGOS,
+
+ NPC_ROBOT = 27641,
+ NPC_BALGAR_IMAGE = 28012,
+ NPC_DRAKOS = 27654,
+ NPC_VAROS = 27447,
+ NPC_UROM = 27655,
+ NPC_EREGOS = 27656,
+//
+ GO_DRAGON_CAGE_DOOR = 193995,
+ GO_EREGOS_CACHE = 191349,
+ GO_EREGOS_CACHE_H = 193603,
+ GO_SPOTLIGHT = 191351,
+
+ BELGAR_TEXT_0 = 13267,
+ BELGAR_TEXT_1 = 13268,
+ BELGAR_TEXT_2 = 13269,
+
+};
+
+#endif
diff --git a/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp b/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp
index 023781c..ebf6318 100644
--- a/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp
+++ b/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp
@@ -16,8 +16,8 @@
/* ScriptData
SDName: Boss Sartharion
-SD%Complete: 70%
-SDComment: Flame wave, achievement and portal events need to be implemented
+SD%Complete: 100%
+SDComment: It's alive! ;) Now this is script is alive realy! (c) MaxXx2021 and PSZ
SDCategory: Obsidian Sanctum
EndScriptData */
@@ -58,12 +58,14 @@ enum
SPELL_TAIL_LASH_H = 58957, // A sweeping tail strike hits all enemies behind the caster, inflicting 4375 to 5625 damage and stunning them for 2 sec.
SPELL_WILL_OF_SARTHARION = 61254, // Sartharion's presence bolsters the resolve of the Twilight Drakes, increasing their total health by 25%. This effect also increases Sartharion's health by 25%.
SPELL_LAVA_STRIKE = 57571, // (Real spell casted should be 57578) 57571 then trigger visual missile, then summon Lava Blaze on impact(spell 57572)
+ SPELL_CYCLONE_AURA_2 = 57598,
SPELL_TWILIGHT_REVENGE = 60639,
SPELL_PYROBUFFET = 56916, // currently used for hard enrage after 15 minutes
SPELL_PYROBUFFET_RANGE = 58907, // possibly used when player get too far away from dummy creatures (2x creature entry 30494)
SPELL_TWILIGHT_SHIFT_ENTER = 57620, // enter phase. Player get this when click GO
+ SPELL_TWILIGHT_SHIFT_DMG = 57874, // damage during being in twilight realm
SPELL_TWILIGHT_SHIFT_REMOVAL = 61187, // leave phase
SPELL_TWILIGHT_SHIFT_REMOVAL_ALL = 61190, // leave phase (probably version to make all leave)
@@ -103,6 +105,8 @@ enum
SPELL_HATCH_EGGS_EFFECT_H = 59190,
SPELL_HATCH_EGGS_EFFECT = 58685,
+ NPC_TWILIGHT_EGG = 30882,
+
//Whelps
NPC_TWILIGHT_WHELP = 30890,
NPC_SHARTHARION_TWILIGHT_WHELP = 31214,
@@ -112,9 +116,12 @@ enum
SPELL_FLAME_TSUNAMI = 57494, // the visual dummy
SPELL_FLAME_TSUNAMI_LEAP = 60241, // SPELL_EFFECT_138 some leap effect, causing caster to move in direction
SPELL_FLAME_TSUNAMI_DMG_AURA = 57492, // periodic damage, npc has this aura
+ SPELL_FLAME_TSUNAMI_DMG = 57491, // damage players
+ SPELL_FLAME_TSUNAMI_BUFF = 60430, // buff Lava Blazes
NPC_FLAME_TSUNAMI = 30616, // for the flame waves
NPC_LAVA_BLAZE = 30643, // adds spawning from flame strike
+ NPC_FIRE_CYCLONE = 30648,
//using these custom points for dragons start and end
POINT_ID_INIT = 100,
@@ -156,6 +163,21 @@ Waypoint m_aDragonCommon[]=
{3209.969f, 566.523f, 98.652f}
};
+float m_afTsunamiStartLoc[5][4]=
+{
+ //left to right
+ {3201.0f, 487.75f, 58.6f, 6.23f},
+ {3201.0f, 533.54f, 58.6f, 6.23f},
+ {3201.0f, 579.14f, 58.6f, 6.23f},
+ //right to left
+ {3287.5f, 552.53f, 58.6f, 3.19f},
+ {3287.5f, 511.10f, 58.6f, 3.19f},
+};
+
+uint64 m_uiAcolyteShadronGUID;
+uint64 m_uiAcolyteVesperonGUID;
+std::list m_lEggsGUIDList;
+
/*######
## Boss Sartharion
######*/
@@ -166,6 +188,9 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
{
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ m_bTenebronHelpedInFight = false;
+ m_bShadronHelpedInFight = false;
+ m_bVesperonHelpedInFight = false;
Reset();
}
@@ -186,11 +211,25 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
uint32 m_uiFlameBreathTimer;
uint32 m_uiTailSweepTimer;
uint32 m_uiCleaveTimer;
- uint32 m_uiLavaStrikeTimer;
+ uint32 m_uiCycloneAuraTimer;
bool m_bHasCalledTenebron;
bool m_bHasCalledShadron;
bool m_bHasCalledVesperon;
+ bool m_bTenebronHelpedInFight;
+ bool m_bShadronHelpedInFight;
+ bool m_bVesperonHelpedInFight;
+
+ bool bCanUseWill;
+ bool bFirstWill;
+ uint32 m_uiSarthHealth;
+ uint32 m_uiTeneHealth;
+ uint32 m_uiShadHealth;
+ uint32 m_uiVespHealth;
+
+ uint32 m_uiCheckTwilightTimer;
+
+ std::list m_lFireCyclones;
void Reset()
{
@@ -206,16 +245,59 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
m_uiFlameTsunamiTimer = 30000;
m_uiFlameBreathTimer = 20000;
- m_uiTailSweepTimer = 20000;
+ m_uiTailSweepTimer = 5000;
m_uiCleaveTimer = 7000;
- m_uiLavaStrikeTimer = 5000;
+ m_uiCycloneAuraTimer = 10000;
m_bHasCalledTenebron = false;
m_bHasCalledShadron = false;
m_bHasCalledVesperon = false;
- if (m_creature->HasAura(SPELL_TWILIGHT_REVENGE))
- m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_REVENGE);
+ 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));
+
+ if (m_bTenebronHelpedInFight && pTene)
+ {
+ if (pTene->isDead())
+ pTene->Respawn();
+ else
+ pTene->AI()->EnterEvadeMode();
+ }
+
+ if (m_bShadronHelpedInFight && pShad)
+ {
+ if (pShad->isDead())
+ pShad->Respawn();
+ else
+ pShad->AI()->EnterEvadeMode();
+ }
+
+ if (m_bVesperonHelpedInFight && pVesp)
+ {
+ if (pVesp->isDead())
+ pVesp->Respawn();
+ else
+ pVesp->AI()->EnterEvadeMode();
+ }
+ }
+
+ m_lFireCyclones.clear();
+ GetCreatureListWithEntryInGrid(m_lFireCyclones, m_creature, NPC_FIRE_CYCLONE, 100.0f);
+
+ m_bTenebronHelpedInFight = false;
+ m_bShadronHelpedInFight = false;
+ m_bVesperonHelpedInFight = false;
+
+ m_creature->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SAR);
+ m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_REVENGE);
}
void JustReachedHome()
@@ -237,9 +319,26 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
}
}
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth())
+ {
+ uint8 uiHardMode = 0;
+ if (m_bTenebronHelpedInFight)
+ ++uiHardMode;
+ if (m_bShadronHelpedInFight)
+ ++uiHardMode;
+ if (m_bVesperonHelpedInFight)
+ ++uiHardMode;
+
+ if (uiHardMode)
+ m_creature->UpdateEntry(m_creature->GetEntry()*10+uiHardMode);
+ }
+ }
+
void JustDied(Unit* pKiller)
{
- DoScriptText(SAY_SARTHARION_DEATH,m_creature);
+ DoScriptText(SAY_SARTHARION_DEATH, m_creature);
if (m_pInstance)
m_pInstance->SetData(TYPE_SARTHARION_EVENT, DONE);
@@ -247,7 +346,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
void KilledUnit(Unit* pVictim)
{
- switch(urand(0, 2))
+ switch (urand(0, 2))
{
case 0: DoScriptText(SAY_SARTHARION_SLAY_1, m_creature); break;
case 1: DoScriptText(SAY_SARTHARION_SLAY_2, m_creature); break;
@@ -262,11 +361,12 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
Creature* pVesp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_VESPERON));
//if at least one of the dragons are alive and are being called
- bool bCanUseWill = false;
-
if (pTene && pTene->isAlive() && !pTene->getVictim())
{
bCanUseWill = true;
+ pTene->CastSpell(pTene, SPELL_POWER_OF_TENEBRON, false);
+ pTene->AddSplineFlag(SPLINEFLAG_FLYING);
+ pTene->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
pTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ);
if (!pTene->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
@@ -276,6 +376,9 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
if (pShad && pShad->isAlive() && !pShad->getVictim())
{
bCanUseWill = true;
+ pShad->CastSpell(pShad, SPELL_POWER_OF_SHADRON, false);
+ pShad->AddSplineFlag(SPLINEFLAG_FLYING);
+ pShad->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
pShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ);
if (!pShad->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
@@ -285,6 +388,9 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
if (pVesp && pVesp->isAlive() && !pVesp->getVictim())
{
bCanUseWill = true;
+ pVesp->CastSpell(pVesp, SPELL_POWER_OF_VESPERON, false);
+ pVesp->AddSplineFlag(SPLINEFLAG_FLYING);
+ pVesp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
pVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ);
if (!pVesp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
@@ -292,7 +398,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
}
if (bCanUseWill)
- DoCastSpellIfCan(m_creature, SPELL_WILL_OF_SARTHARION);
+ DoCast(m_creature, SPELL_WILL_OF_SARTHARION);
}
void CallDragon(uint32 uiDataId)
@@ -303,27 +409,41 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
if (pTemp && pTemp->isAlive() && !pTemp->getVictim())
{
- if (pTemp->HasSplineFlag(SPLINEFLAG_WALKMODE))
- pTemp->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if (pTemp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_uiSarthHealth = m_creature->GetHealth();
+ DoCast(m_creature, SPELL_WILL_OF_SARTHARION, false);
+ bCanUseWill = true;
int32 iTextId = 0;
- switch(pTemp->GetEntry())
+ Creature* pAdd = NULL;
+ pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_TENEBRON));
+ if (pAdd)
+ m_uiTeneHealth = pAdd->GetHealth();
+ pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_SHADRON));
+ if (pAdd)
+ m_uiShadHealth = pAdd->GetHealth();
+ pAdd = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_VESPERON));
+ if (pAdd)
+ m_uiVespHealth = pAdd->GetHealth();
+
+ switch (pTemp->GetEntry())
{
case NPC_TENEBRON:
iTextId = SAY_SARTHARION_CALL_TENEBRON;
pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aTene[1].m_fX, m_aTene[1].m_fY, m_aTene[1].m_fZ);
+ m_bTenebronHelpedInFight = true;
break;
case NPC_SHADRON:
iTextId = SAY_SARTHARION_CALL_SHADRON;
pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aShad[1].m_fX, m_aShad[1].m_fY, m_aShad[1].m_fZ);
+ m_bShadronHelpedInFight = true;
break;
case NPC_VESPERON:
iTextId = SAY_SARTHARION_CALL_VESPERON;
pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aVesp[1].m_fX, m_aVesp[1].m_fY, m_aVesp[1].m_fZ);
+ m_bVesperonHelpedInFight = true;
break;
}
@@ -345,10 +465,19 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (i->getSource()->isAlive())
- DoScriptText(WHISPER_LAVA_CHURN, m_creature,i->getSource());
+ DoScriptText(WHISPER_LAVA_CHURN, m_creature, i->getSource());
}
}
}
+
+ uint8 uiTsunamiDirection = urand(0, 1);
+ uint8 uiTsunamiWavesAmount = 3;
+ if (uiTsunamiDirection)
+ uiTsunamiWavesAmount = 2;
+ for (uint8 i = uiTsunamiDirection*3; i < uiTsunamiDirection*3+uiTsunamiWavesAmount; ++i)
+ {
+ m_creature->SummonCreature(NPC_FLAME_TSUNAMI, m_afTsunamiStartLoc[i][0], m_afTsunamiStartLoc[i][1], m_afTsunamiStartLoc[i][2], m_afTsunamiStartLoc[i][3], TEMPSUMMON_TIMED_DESPAWN, 18000);
+ }
}
void UpdateAI(const uint32 uiDiff)
@@ -357,18 +486,57 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ if (bCanUseWill)
+ {
+ if (bFirstWill)
+ {
+ m_creature->SetHealth(m_creature->GetHealth()*1.25);
+ }
+ else
+ {
+ m_creature->SetHealth(m_uiSarthHealth);
+ Creature* pTemp = NULL;
+ pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_TENEBRON));
+ if (pTemp && pTemp->isAlive())
+ pTemp->SetHealth(m_uiTeneHealth);
+ pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_SHADRON));
+ if (pTemp && pTemp->isAlive())
+ pTemp->SetHealth(m_uiShadHealth);
+ pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_VESPERON));
+ if (pTemp && pTemp->isAlive())
+ pTemp->SetHealth(m_uiVespHealth);
+ }
+ bCanUseWill = false;
+ bFirstWill = false;
+ }
+
//spell will target dragons, if they are still alive at 35%
- if (!m_bIsBerserk && m_creature->GetHealthPercent() < 35.0f)
+ if (!m_bIsBerserk && m_creature->GetHealthPercent() <= 35.0f)
{
DoScriptText(SAY_SARTHARION_BERSERK, m_creature);
- DoCastSpellIfCan(m_creature, SPELL_BERSERK);
+ //DoCast(m_creature, SPELL_BERSERK);
+ Creature* pTemp = NULL;
+ pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_TENEBRON));
+ if (pTemp && pTemp->isAlive())
+ pTemp->CastSpell(pTemp, 27680, true);
+ pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SHADRON));
+ if (pTemp && pTemp->isAlive())
+ pTemp->CastSpell(pTemp, 27680, true);
+ pTemp = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_VESPERON));
+ if (pTemp && pTemp->isAlive())
+ pTemp->CastSpell(pTemp, 27680, true);
+
m_bIsBerserk = true;
}
//soft enrage
if (!m_bIsSoftEnraged && m_creature->GetHealthPercent() <= 10.0f)
{
- // TODO
+ if (!m_lFireCyclones.empty())
+ for (std::list::iterator iter = m_lFireCyclones.begin(); iter != m_lFireCyclones.end(); ++iter)
+ if (*iter)
+ (*iter)->CastSpell(*iter, SPELL_CYCLONE_AURA_2, true);
+
m_bIsSoftEnraged = true;
}
@@ -377,7 +545,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
{
if (m_uiEnrageTimer < uiDiff)
{
- DoCastSpellIfCan(m_creature, SPELL_PYROBUFFET, CAST_TRIGGERED);
+ DoCast(m_creature, SPELL_PYROBUFFET, true);
m_bIsHardEnraged = true;
}
else
@@ -388,6 +556,14 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
if (m_uiFlameTsunamiTimer < uiDiff)
{
SendFlameTsunami();
+ switch(urand(0, 3))
+ {
+ case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break;
+ case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break;
+ case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break;
+ case 3: DoScriptText(SAY_SARTHARION_SPECIAL_4, m_creature); break;
+ }
+
m_uiFlameTsunamiTimer = 30000;
}
else
@@ -397,7 +573,7 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
if (m_uiFlameBreathTimer < uiDiff)
{
DoScriptText(SAY_SARTHARION_BREATH, m_creature);
- DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H);
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H);
m_uiFlameBreathTimer = urand(25000, 35000);
}
else
@@ -406,8 +582,8 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
// Tail Sweep
if (m_uiTailSweepTimer < uiDiff)
{
- DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H);
- m_uiTailSweepTimer = urand(15000, 20000);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H);
+ m_uiTailSweepTimer = urand(5000, 7000);
}
else
m_uiTailSweepTimer -= uiDiff;
@@ -415,30 +591,38 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
// Cleave
if (m_uiCleaveTimer < uiDiff)
{
- DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE);
+ DoCast(m_creature->getVictim(), SPELL_CLEAVE);
m_uiCleaveTimer = urand(7000, 10000);
}
else
m_uiCleaveTimer -= uiDiff;
// Lavas Strike
- if (m_uiLavaStrikeTimer < uiDiff)
+ if (m_uiCycloneAuraTimer < uiDiff)
{
- if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ if (!m_lFireCyclones.empty())
{
- DoCastSpellIfCan(pTarget, SPELL_LAVA_STRIKE);
-
- switch(urand(0, 15))
+ std::list::iterator iter = m_lFireCyclones.begin();
+ advance(iter, urand(0, m_lFireCyclones.size()-1));
+ if (*iter)
{
- case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break;
- case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break;
- case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break;
+ (*iter)->CastSpell(*iter, SPELL_CYCLONE_AURA_2, true);
+
+ switch(urand(0, 15))
+ {
+ case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break;
+ case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break;
+ case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break;
+ }
}
}
- m_uiLavaStrikeTimer = urand(5000, 20000);
+ if (m_bIsSoftEnraged)
+ m_uiCycloneAuraTimer = 10000;
+ else
+ m_uiCycloneAuraTimer = urand(20000, 25000);
}
else
- m_uiLavaStrikeTimer -= uiDiff;
+ m_uiCycloneAuraTimer -= uiDiff;
// call tenebron
if (!m_bHasCalledTenebron && m_uiTenebronTimer < uiDiff)
@@ -467,6 +651,61 @@ struct MANGOS_DLL_DECL boss_sartharionAI : public ScriptedAI
else
m_uiVesperonTimer -= uiDiff;
+ if (m_uiCheckTwilightTimer < uiDiff)
+ {
+ bool bNoAliveTwilightRealm = true;
+ if (m_pInstance)
+ {
+ if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID))
+ {
+ if (pAcolyte->isAlive())
+ {
+ bNoAliveTwilightRealm = false;
+ }
+ }
+ if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID))
+ {
+ if (pAcolyte->isAlive())
+ {
+ bNoAliveTwilightRealm = false;
+ }
+ }
+ if (!m_lEggsGUIDList.empty())
+ {
+ for (std::list::iterator itr = m_lEggsGUIDList.begin(); itr != m_lEggsGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ {
+ if (pTemp->isAlive())
+ {
+ bNoAliveTwilightRealm = false;
+ break;
+ }
+ }
+ }
+ }
+ if (bNoAliveTwilightRealm)
+ {
+ Map* pMap = m_creature->GetMap();
+
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+
+ if (!PlayerList.isEmpty())
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive())
+ i->getSource()->CastSpell(i->getSource(), SPELL_TWILIGHT_SHIFT_REMOVAL, true);
+ }
+ }
+ }
+ }
+ m_uiCheckTwilightTimer = 2000;
+ }
+ else
+ m_uiCheckTwilightTimer -= uiDiff;
+
DoMeleeAttackIfReady();
EnterEvadeIfOutOfCombatArea(uiDiff);
@@ -529,20 +768,38 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI
uint32 m_uiWaypointId;
uint32 m_uiMoveNextTimer;
- int32 m_iPortalRespawnTime;
bool m_bCanMoveFree;
void Reset()
{
- if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_uiWaypointId = 0;
m_uiMoveNextTimer = 500;
- m_iPortalRespawnTime = 30000;
m_bCanMoveFree = false;
}
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho || m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+
+ if (IsCombatMovement())
+ m_creature->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void JustReachedHome()
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ }
+
void MovementInform(uint32 uiType, uint32 uiPointId)
{
if (!m_pInstance || uiType != POINT_MOTION_TYPE)
@@ -562,6 +819,7 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI
{
m_creature->GetMotionMaster()->Clear();
m_bCanMoveFree = false;
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
m_creature->SetInCombatWithZone();
return;
}
@@ -601,98 +859,206 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI
}
}
+ //Removes debuff from players
+ void RemoveDebuff(uint32 uiSpellId)
+ {
+ Map* pMap = m_creature->GetMap();
+
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ i->getSource()->RemoveAurasDueToSpell(uiSpellId);
+ if (uiSpellId == SPELL_TWILIGHT_SHIFT_ENTER)
+ i->getSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_DMG);
+ }
+ }
+ }
+
//"opens" the portal and does the "opening" whisper
void OpenPortal()
{
int32 iTextId = 0;
+ int32 iPortalRespawnTime = 0;
//there are 4 portal spawn locations, each are expected to be spawned with negative spawntimesecs in database
//using a grid search here seem to be more efficient than caching all four guids
//in instance script and calculate range to each.
- GameObject* pPortal = GetClosestGameObjectWithEntry(m_creature,GO_TWILIGHT_PORTAL,50.0f);
-
- switch(m_creature->GetEntry())
+ if (GameObject* pPortal = GetClosestGameObjectWithEntry(m_creature, GO_TWILIGHT_PORTAL, 100.0f))
{
- case NPC_TENEBRON:
- iTextId = WHISPER_HATCH_EGGS;
- break;
- case NPC_SHADRON:
- case NPC_VESPERON:
- iTextId = WHISPER_OPEN_PORTAL;
- break;
- }
+ Creature* pAcolyte = NULL;
+ switch(m_creature->GetEntry())
+ {
+ case NPC_TENEBRON:
+ iTextId = WHISPER_HATCH_EGGS;
+ m_lEggsGUIDList.clear();
+ for (uint8 i=0; i<6; ++i)
+ {
+ if (Creature* pEgg = m_creature->SummonCreature(NPC_TWILIGHT_EGG, pPortal->GetPositionX()-10+urand(0, 20), pPortal->GetPositionY()-10+urand(0, 20), pPortal->GetPositionZ()+1.0f, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000))
+ {
+ pEgg->SetPhaseMask(16, true);
+ m_lEggsGUIDList.push_back(pEgg->GetGUID());
+ }
+ }
+ iPortalRespawnTime = 20;
+ break;
+ case NPC_SHADRON:
+ iTextId = WHISPER_OPEN_PORTAL;
+ if (m_pInstance)
+ {
+ pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID);
+ if (!pAcolyte || (pAcolyte && pAcolyte->isDead()))
+ {
+ pAcolyte = NULL;
+ if (pAcolyte = m_creature->SummonCreature(NPC_ACOLYTE_OF_SHADRON, pPortal->GetPositionX()-10+urand(0, 20), pPortal->GetPositionY()-10+urand(0, 20), pPortal->GetPositionZ()+1.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))
+ {
+ m_uiAcolyteShadronGUID = pAcolyte->GetGUID();
+ pAcolyte->SetPhaseMask(16, true);
+ }
+ }
+ if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ {
+ if (Creature* pSarth = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SARTHARION)))
+ pSarth->CastSpell(pSarth, SPELL_GIFT_OF_TWILIGTH_SAR, true);
+ }
+ else
+ {
+ if (Creature* pShad = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SHADRON)))
+ pShad->CastSpell(pShad, SPELL_GIFT_OF_TWILIGTH_SHA, true);
+ }
+ }
+ iPortalRespawnTime = 60;
+ break;
+ case NPC_VESPERON:
+ iTextId = WHISPER_OPEN_PORTAL;
+ if (m_pInstance)
+ {
+ uint32 uiTempSpell;
+ if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ uiTempSpell = 58835;
+ else
+ uiTempSpell = 57935;
+
+ SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(uiTempSpell);
+ if (pTempSpell)
+ {
+ pTempSpell->StackAmount = 1;
+ pTempSpell->procCharges = 0;
+ m_creature->CastSpell(m_creature, pTempSpell, true);
+ }
+
+ pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID);
+ if (!pAcolyte || (pAcolyte && pAcolyte->isDead()))
+ {
+ pAcolyte = NULL;
+ if (pAcolyte = m_creature->SummonCreature(NPC_ACOLYTE_OF_VESPERON, pPortal->GetPositionX()-10+urand(0, 20), pPortal->GetPositionY()-10+urand(0, 20), pPortal->GetPositionZ()+1.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))
+ {
+ m_uiAcolyteVesperonGUID = pAcolyte->GetGUID();
+ pAcolyte->SetPhaseMask(16, true);
+ }
+ }
+ }
+ iPortalRespawnTime = 60;
+ break;
+ }
- DoRaidWhisper(iTextId);
+ DoRaidWhisper(iTextId);
- //By using SetRespawnTime() we will actually "spawn" the object with our defined time.
- //Once time is up, portal will disappear again.
- if (pPortal && !pPortal->isSpawned())
- {
- pPortal->SetRespawnTime(m_iPortalRespawnTime);
- pPortal->Refresh();
- }
+ //By using SetRespawnTime() we will actually "spawn" the object with our defined time.
+ //Once time is up, portal will disappear again.
+
+ pPortal->SetRespawnTime(iPortalRespawnTime);
+ pPortal->UpdateObjectVisibility();
- //Unclear what are expected to happen if one drake has a portal open already
- //Refresh respawnTime so time again are set to 30secs?
+ //Unclear what are expected to happen if one drake has a portal open already
+ //Refresh respawnTime so time again are set to 30secs?
+ }
}
- //Removes each drakes unique debuff from players
- void RemoveDebuff(uint32 uiSpellId)
- {
- Map* pMap = m_creature->GetMap();
- if (pMap && pMap->IsDungeon())
+ void CheckTwilightRealm()
+ {
+ bool bNoAliveTwilightRealm = true;
+ if (m_pInstance)
{
- Map::PlayerList const &PlayerList = pMap->GetPlayers();
-
- if (PlayerList.isEmpty())
- return;
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (i->getSource()->isAlive() && i->getSource()->HasAura(uiSpellId))
- i->getSource()->RemoveAurasDueToSpell(uiSpellId);
- }
+ if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID))
+ if (pAcolyte->isAlive())
+ bNoAliveTwilightRealm = false;
+ if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID))
+ if (pAcolyte->isAlive())
+ bNoAliveTwilightRealm = false;
+ if (!m_lEggsGUIDList.empty())
+ for (std::list::iterator itr = m_lEggsGUIDList.begin(); itr != m_lEggsGUIDList.end(); ++itr)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( *itr))
+ if (pTemp->isAlive())
+ {
+ bNoAliveTwilightRealm = false;
+ break;
+ }
+ if (bNoAliveTwilightRealm)
+ RemoveDebuff(SPELL_TWILIGHT_SHIFT_ENTER);
}
}
void JustDied(Unit* pKiller)
{
int32 iTextId = 0;
- uint32 uiSpellId = 0;
switch(m_creature->GetEntry())
{
case NPC_TENEBRON:
+ {
iTextId = SAY_TENEBRON_DEATH;
- uiSpellId = SPELL_POWER_OF_TENEBRON;
+
+ if (!m_lEggsGUIDList.empty())
+ for (std::list::iterator itr = m_lEggsGUIDList.begin(); itr != m_lEggsGUIDList.end(); ++itr)
+ if (Creature* pEgg = m_creature->GetMap()->GetCreature( *itr))
+ pEgg->ForcedDespawn();
break;
+ }
case NPC_SHADRON:
+ {
iTextId = SAY_SHADRON_DEATH;
- uiSpellId = SPELL_POWER_OF_SHADRON;
+
+ if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteShadronGUID))
+ pAcolyte->DealDamage(pAcolyte, pAcolyte->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
break;
+ }
case NPC_VESPERON:
+ {
iTextId = SAY_VESPERON_DEATH;
- uiSpellId = SPELL_POWER_OF_VESPERON;
+
+ if (Creature* pAcolyte = m_pInstance->instance->GetCreature(m_uiAcolyteVesperonGUID))
+ pAcolyte->DealDamage(pAcolyte, pAcolyte->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
break;
+ }
}
DoScriptText(iTextId, m_creature);
- RemoveDebuff(uiSpellId);
-
if (m_pInstance)
{
// not if solo mini-boss fight
if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
+ {
+ RemoveDebuff(SPELL_TWILIGHT_SHIFT_ENTER);
return;
+ }
// Twilight Revenge to main boss
if (Creature* pSartharion = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_SARTHARION)))
{
if (pSartharion->isAlive())
- m_creature->CastSpell(pSartharion,SPELL_TWILIGHT_REVENGE,true);
+ m_creature->CastSpell(pSartharion, SPELL_TWILIGHT_REVENGE, true);
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
}
}
@@ -721,23 +1087,30 @@ struct MANGOS_DLL_DECL dummy_dragonAI : public ScriptedAI
struct MANGOS_DLL_DECL mob_tenebronAI : public dummy_dragonAI
{
- mob_tenebronAI(Creature* pCreature) : dummy_dragonAI(pCreature) { Reset(); }
+ mob_tenebronAI(Creature* pCreature) : dummy_dragonAI(pCreature)
+ {
+ Reset();
+ }
uint32 m_uiShadowBreathTimer;
uint32 m_uiShadowFissureTimer;
uint32 m_uiHatchEggTimer;
+ uint32 m_uiCheckTimer;
+ uint32 m_uiTailSweepTimer;
void Reset()
{
- m_uiShadowBreathTimer = 20000;
- m_uiShadowFissureTimer = 5000;
- m_uiHatchEggTimer = 30000;
+ m_uiShadowBreathTimer = 10000;
+ m_uiShadowFissureTimer = 8000;
+ m_uiHatchEggTimer = 15000;
+ m_uiCheckTimer = 2000;
+ m_uiTailSweepTimer = 5000;
+ m_lEggsGUIDList.clear();
}
void Aggro(Unit* pWho)
{
DoScriptText(SAY_TENEBRON_AGGRO, m_creature);
- DoCastSpellIfCan(m_creature, SPELL_POWER_OF_TENEBRON);
}
void KilledUnit(Unit* pVictim)
@@ -758,9 +1131,9 @@ struct MANGOS_DLL_DECL mob_tenebronAI : public dummy_dragonAI
if (m_uiShadowFissureTimer < uiDiff)
{
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
- DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H);
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H);
- m_uiShadowFissureTimer = urand(15000, 20000);
+ m_uiShadowFissureTimer = urand(8000, 10000);
}
else
m_uiShadowFissureTimer -= uiDiff;
@@ -769,12 +1142,36 @@ struct MANGOS_DLL_DECL mob_tenebronAI : public dummy_dragonAI
if (m_uiShadowBreathTimer < uiDiff)
{
DoScriptText(SAY_TENEBRON_BREATH, m_creature);
- DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H);
- m_uiShadowBreathTimer = urand(20000, 25000);
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H);
+ m_uiShadowBreathTimer = urand(10000, 30000);
}
else
m_uiShadowBreathTimer -= uiDiff;
+ if (m_uiTailSweepTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H);
+ m_uiTailSweepTimer = urand(5000, 7000);
+ }
+ else
+ m_uiTailSweepTimer -= uiDiff;
+
+ if (m_uiHatchEggTimer < uiDiff)
+ {
+ OpenPortal();
+ m_uiHatchEggTimer = 45000;
+ }
+ else
+ m_uiHatchEggTimer -= uiDiff;
+
+ if (m_uiCheckTimer < uiDiff && m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
+ {
+ CheckTwilightRealm();
+ m_uiCheckTimer = 2000;
+ }
+ else
+ m_uiCheckTimer -= uiDiff;
+
DoMeleeAttackIfReady();
}
};
@@ -790,29 +1187,30 @@ CreatureAI* GetAI_mob_tenebron(Creature* pCreature)
struct MANGOS_DLL_DECL mob_shadronAI : public dummy_dragonAI
{
- mob_shadronAI(Creature* pCreature) : dummy_dragonAI(pCreature) { Reset(); }
+ mob_shadronAI(Creature* pCreature) : dummy_dragonAI(pCreature)
+ {
+ Reset();
+ }
uint32 m_uiShadowBreathTimer;
uint32 m_uiShadowFissureTimer;
uint32 m_uiAcolyteShadronTimer;
+ uint32 m_uiCheckTimer;
+ uint32 m_uiTailSweepTimer;
void Reset()
{
- m_uiShadowBreathTimer = 20000;
- m_uiShadowFissureTimer = 5000;
- m_uiAcolyteShadronTimer = 60000;
-
- if (m_creature->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
- m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
-
- if (m_creature->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
- m_creature->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA);
+ m_uiShadowBreathTimer = 10000;
+ m_uiShadowFissureTimer = 8000;
+ m_uiAcolyteShadronTimer = 15000;
+ m_uiCheckTimer = 2000;
+ m_uiTailSweepTimer = 5000;
+ m_uiAcolyteShadronGUID = 0;
}
void Aggro(Unit* pWho)
{
DoScriptText(SAY_SHADRON_AGGRO,m_creature);
- DoCastSpellIfCan(m_creature, SPELL_POWER_OF_SHADRON);
}
void KilledUnit(Unit* pVictim)
@@ -833,9 +1231,9 @@ struct MANGOS_DLL_DECL mob_shadronAI : public dummy_dragonAI
if (m_uiShadowFissureTimer < uiDiff)
{
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
- DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H);
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H);
- m_uiShadowFissureTimer = urand(15000, 20000);
+ m_uiShadowFissureTimer = urand(8000, 10000);
}
else
m_uiShadowFissureTimer -= uiDiff;
@@ -844,12 +1242,36 @@ struct MANGOS_DLL_DECL mob_shadronAI : public dummy_dragonAI
if (m_uiShadowBreathTimer < uiDiff)
{
DoScriptText(SAY_SHADRON_BREATH, m_creature);
- DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H);
- m_uiShadowBreathTimer = urand(20000, 25000);
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H);
+ m_uiShadowBreathTimer = urand(10000, 30000);
}
else
m_uiShadowBreathTimer -= uiDiff;
+ if (m_uiTailSweepTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H);
+ m_uiTailSweepTimer = urand(5000, 7000);
+ }
+ else
+ m_uiTailSweepTimer -= uiDiff;
+
+ if (m_uiAcolyteShadronTimer < uiDiff)
+ {
+ OpenPortal();
+ m_uiAcolyteShadronTimer = 60000;
+ }
+ else
+ m_uiAcolyteShadronTimer -= uiDiff;
+
+ if (m_uiCheckTimer < uiDiff && m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
+ {
+ CheckTwilightRealm();
+ m_uiCheckTimer = 2000;
+ }
+ else
+ m_uiCheckTimer -= uiDiff;
+
DoMeleeAttackIfReady();
}
};
@@ -865,23 +1287,30 @@ CreatureAI* GetAI_mob_shadron(Creature* pCreature)
struct MANGOS_DLL_DECL mob_vesperonAI : public dummy_dragonAI
{
- mob_vesperonAI(Creature* pCreature) : dummy_dragonAI(pCreature) { Reset(); }
+ mob_vesperonAI(Creature* pCreature) : dummy_dragonAI(pCreature)
+ {
+ Reset();
+ }
uint32 m_uiShadowBreathTimer;
uint32 m_uiShadowFissureTimer;
uint32 m_uiAcolyteVesperonTimer;
+ uint32 m_uiCheckTimer;
+ uint32 m_uiTailSweepTimer;
void Reset()
{
- m_uiShadowBreathTimer = 20000;
- m_uiShadowFissureTimer = 5000;
- m_uiAcolyteVesperonTimer = 60000;
+ m_uiShadowBreathTimer = 10000;
+ m_uiShadowFissureTimer = 8000;
+ m_uiAcolyteVesperonTimer = 15000;
+ m_uiCheckTimer = 2000;
+ m_uiTailSweepTimer = 5000;
+ m_uiAcolyteVesperonGUID = 0;
}
void Aggro(Unit* pWho)
{
DoScriptText(SAY_VESPERON_AGGRO,m_creature);
- DoCastSpellIfCan(m_creature, SPELL_POWER_OF_VESPERON);
}
void KilledUnit(Unit* pVictim)
@@ -902,9 +1331,9 @@ struct MANGOS_DLL_DECL mob_vesperonAI : public dummy_dragonAI
if (m_uiShadowFissureTimer < uiDiff)
{
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
- DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H);
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_SHADOW_FISSURE : SPELL_SHADOW_FISSURE_H);
- m_uiShadowFissureTimer = urand(15000, 20000);
+ m_uiShadowFissureTimer = urand(8000, 10000);
}
else
m_uiShadowFissureTimer -= uiDiff;
@@ -913,12 +1342,36 @@ struct MANGOS_DLL_DECL mob_vesperonAI : public dummy_dragonAI
if (m_uiShadowBreathTimer < uiDiff)
{
DoScriptText(SAY_VESPERON_BREATH, m_creature);
- DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H);
- m_uiShadowBreathTimer = urand(20000, 25000);
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOW_BREATH : SPELL_SHADOW_BREATH_H);
+ m_uiShadowBreathTimer = urand(10000, 30000);
}
else
m_uiShadowBreathTimer -= uiDiff;
+ if (m_uiTailSweepTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H);
+ m_uiTailSweepTimer = urand(5000, 7000);
+ }
+ else
+ m_uiTailSweepTimer -= uiDiff;
+
+ if (m_uiAcolyteVesperonTimer < uiDiff)
+ {
+ OpenPortal();
+ m_uiAcolyteVesperonTimer = 60000;
+ }
+ else
+ m_uiAcolyteVesperonTimer -= uiDiff;
+
+ if (m_uiCheckTimer < uiDiff && m_pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
+ {
+ CheckTwilightRealm();
+ m_uiCheckTimer = 2000;
+ }
+ else
+ m_uiCheckTimer -= uiDiff;
+
DoMeleeAttackIfReady();
}
};
@@ -944,14 +1397,6 @@ struct MANGOS_DLL_DECL mob_acolyte_of_shadronAI : public ScriptedAI
void Reset()
{
- if (m_pInstance)
- {
- //if not solo figth, buff main boss, else place debuff on mini-boss. both spells TARGET_SCRIPT
- if (m_pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
- DoCastSpellIfCan(m_creature, SPELL_GIFT_OF_TWILIGTH_SAR);
- else
- DoCastSpellIfCan(m_creature, SPELL_GIFT_OF_TWILIGTH_SHA);
- }
}
void JustDied(Unit* killer)
@@ -1009,18 +1454,25 @@ struct MANGOS_DLL_DECL mob_acolyte_of_vesperonAI : public ScriptedAI
void Reset()
{
- DoCastSpellIfCan(m_creature, SPELL_TWILIGHT_TORMENT_VESP_ACO);
}
void JustDied(Unit* pKiller)
{
- // remove twilight torment on Vesperon
- if (m_pInstance)
+ // remove twilight torment
+ Map* pMap = m_creature->GetMap();
+
+ if (pMap && pMap->IsDungeon())
{
- Creature* pVesperon = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_VESPERON));
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
- if (pVesperon && pVesperon->isAlive() && pVesperon->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
- pVesperon->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ i->getSource()->RemoveAurasDueToSpell(57935);
+ i->getSource()->RemoveAurasDueToSpell(58835);
+ }
}
}
@@ -1046,12 +1498,36 @@ struct MANGOS_DLL_DECL mob_twilight_eggsAI : public ScriptedAI
{
mob_twilight_eggsAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); }
+ uint32 m_uiSummonWhelpTimer;
+
void Reset()
+ {
+ m_uiSummonWhelpTimer = 20000;
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
{
}
- void AttackStart(Unit* pWho) { }
- void MoveInLineOfSight(Unit* pWho) { }
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiSummonWhelpTimer < uiDiff)
+ {
+ if (Creature* pWhelp = DoSpawnCreature(NPC_TWILIGHT_WHELP, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pWhelp->SetPhaseMask(1, true);
+ pWhelp->SetInCombatWithZone();
+ }
+ m_uiSummonWhelpTimer = 20000;
+ m_creature->ForcedDespawn();
+ }
+ else
+ m_uiSummonWhelpTimer -= uiDiff;
+ }
};
CreatureAI* GetAI_mob_twilight_eggs(Creature* pCreature)
@@ -1083,7 +1559,7 @@ struct MANGOS_DLL_DECL mob_twilight_whelpAI : public ScriptedAI
// twilight torment
if (m_uiFadeArmorTimer < uiDiff)
{
- DoCastSpellIfCan(m_creature->getVictim(), SPELL_FADE_ARMOR);
+ DoCast(m_creature->getVictim(), SPELL_FADE_ARMOR);
m_uiFadeArmorTimer = urand(5000, 10000);
}
else
@@ -1098,6 +1574,221 @@ CreatureAI* GetAI_mob_twilight_whelp(Creature* pCreature)
return new mob_twilight_whelpAI(pCreature);
}
+/*######
+## Mob Fire Cyclone
+######*/
+
+struct MANGOS_DLL_DECL mob_fire_cycloneAI : public ScriptedAI
+{
+ mob_fire_cycloneAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 m_uiLavaStrikeTimer;
+ uint8 m_uiLavaStrikesCount;
+ bool m_bLavaStrikeAllowed;
+
+
+ void Reset()
+ {
+ m_bLavaStrikeAllowed = false;
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ }
+
+ void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_CYCLONE_AURA_2)
+ {
+ DoCast(m_creature, 57560, true);
+ m_bLavaStrikeAllowed = true;
+ m_uiLavaStrikeTimer = 0;
+ m_uiLavaStrikesCount = 0;
+ }
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if (pSummoned->GetEntry() == NPC_LAVA_BLAZE)
+ if (urand(0, 3)) //25% to stay
+ pSummoned->ForcedDespawn();
+ else
+ pSummoned->SetInCombatWithZone();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (m_bLavaStrikeAllowed)
+ {
+ if (m_uiLavaStrikeTimer < uiDiff)
+ {
+ m_creature->CastSpell(urand(3220, 3275), urand(486, 575), 58.8f, SPELL_LAVA_STRIKE, true);
+ m_uiLavaStrikeTimer = 1000;
+ ++m_uiLavaStrikesCount;
+ if (m_uiLavaStrikesCount>=5)
+ m_bLavaStrikeAllowed = false;
+ }
+ else
+ m_uiLavaStrikeTimer -= uiDiff;
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_fire_cyclone(Creature* pCreature)
+{
+ return new mob_fire_cycloneAI(pCreature);
+}
+
+/*######
+## Mob Flame Tsunami
+######*/
+
+struct MANGOS_DLL_DECL mob_flame_tsunamiAI : public ScriptedAI
+{
+ mob_flame_tsunamiAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiTickTimer;
+ uint32 m_uiMovementStartTimer;
+ uint64 m_uiDummyDamagerGUID;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(11686);
+ DoCast(m_creature, SPELL_FLAME_TSUNAMI, true);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_uiMovementStartTimer = 4000;
+ m_uiTickTimer = 1000;
+ m_uiDummyDamagerGUID = 0;
+ if (Creature* pDummyDamager = DoSpawnCreature(31103, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 18000))
+ {
+ pDummyDamager->SetDisplayId(11686);
+ pDummyDamager->setFaction(14);
+ pDummyDamager->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ pDummyDamager->SetSpeedRate(MOVE_RUN, m_creature->GetSpeedRate(MOVE_RUN));
+ m_uiDummyDamagerGUID = pDummyDamager->GetGUID();
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiMovementStartTimer < uiDiff)
+ {
+ int8 uiDirection = 1;
+ if (m_creature->GetPositionX() > 3240.0f)
+ uiDirection = -1;
+ m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+uiDirection*86.5f, m_creature->GetPositionY(), m_creature->GetPositionZ());
+ if (m_pInstance)
+ if (Creature* pDummyDamager = m_pInstance->instance->GetCreature(m_uiDummyDamagerGUID))
+ pDummyDamager->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+uiDirection*86.5f, m_creature->GetPositionY(), m_creature->GetPositionZ());
+ m_uiMovementStartTimer = 30000;
+ }
+ else
+ m_uiMovementStartTimer -= uiDiff;
+
+ if (m_uiTickTimer < uiDiff)
+ {
+ if (m_pInstance)
+ if (Creature* pDummyDamager = m_pInstance->instance->GetCreature(m_uiDummyDamagerGUID))
+ pDummyDamager->CastSpell(pDummyDamager, SPELL_FLAME_TSUNAMI_DMG, false);
+
+ std::list lLavaBlazes;
+ GetCreatureListWithEntryInGrid(lLavaBlazes, m_creature, NPC_LAVA_BLAZE, 6.0f);
+ if (!lLavaBlazes.empty())
+ {
+ SpellEntry* pTempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_FLAME_TSUNAMI_BUFF);
+ if (pTempSpell)
+ {
+ pTempSpell->EffectImplicitTargetA[0] = TARGET_SELF;
+ pTempSpell->EffectImplicitTargetB[0] = 0;
+ pTempSpell->EffectImplicitTargetA[1] = TARGET_SELF;
+ pTempSpell->EffectImplicitTargetB[1] = 0;
+ pTempSpell->EffectImplicitTargetA[2] = TARGET_SELF;
+ pTempSpell->EffectImplicitTargetB[2] = 0;
+ for (std::list::iterator iter = lLavaBlazes.begin(); iter != lLavaBlazes.end(); ++iter)
+ {
+ (*iter)->CastSpell(*iter, pTempSpell, false);
+ (*iter)->SetHealth((*iter)->GetHealth()*4);
+ }
+ }
+ }
+
+ Map* pMap = m_creature->GetMap();
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+
+ if (!PlayerList.isEmpty())
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()) <= 5.0f)
+ {
+ i->getSource()->SetOrientation(m_creature->GetOrientation());
+ i->getSource()->CastSpell(i->getSource(), SPELL_FLAME_TSUNAMI_LEAP, true);
+ }
+ }
+
+ m_uiTickTimer = 1000;
+ }
+ else
+ m_uiTickTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_flame_tsunami(Creature* pCreature)
+{
+ return new mob_flame_tsunamiAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_lava_blazeAI : public ScriptedAI
+{
+ mob_lava_blazeAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_lava_blaze(Creature* pCreature)
+{
+ return new mob_lava_blazeAI(pCreature);
+};
+
void AddSC_boss_sartharion()
{
Script *newscript;
@@ -1141,4 +1832,19 @@ void AddSC_boss_sartharion()
newscript->Name = "mob_twilight_whelp";
newscript->GetAI = &GetAI_mob_twilight_whelp;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_fire_cyclone";
+ newscript->GetAI = &GetAI_mob_fire_cyclone;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_flame_tsunami";
+ newscript->GetAI = &GetAI_mob_flame_tsunami;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_lava_blaze";
+ newscript->GetAI = &GetAI_mob_lava_blaze;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/ruby_sanctum/boss_baltharus.cpp b/scripts/northrend/ruby_sanctum/boss_baltharus.cpp
index 8574ab9..44d3452 100644
--- a/scripts/northrend/ruby_sanctum/boss_baltharus.cpp
+++ b/scripts/northrend/ruby_sanctum/boss_baltharus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2010 /dev/rsa for ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -16,9 +16,338 @@
/* ScriptData
SDName: boss_baltharus
-SD%Complete:
-SDComment: placeholder
-SDCategory: Ruby Sanctum
+SD%Complete: 90%
+SDComment: by notagain and /dev/rsa
+SDCategory: ruby_sanctum
EndScriptData */
+// Not fully offlike clone work, but Blizz idea is intact.
+// Need correct timers
#include "precompiled.h"
+#include "ruby_sanctum.h"
+
+static Locations SpawnLoc[]=
+{
+ {3152.329834f, 359.41757f, 85.301605f}, // Baltharus target point
+ {3153.06f, 389.486f, 86.2596f}, // Baltharus initial point
+};
+
+enum Equipment
+{
+ EQUIP_MAIN = 49888,
+ EQUIP_OFFHAND = EQUIP_NO_CHANGE,
+ EQUIP_RANGED = EQUIP_NO_CHANGE,
+ EQUIP_DONE = EQUIP_NO_CHANGE,
+};
+
+enum BossSpells
+{
+ SPELL_BLADE_TEMPEST = 75125, // every 22 secs
+ SPELL_ENERVATING_BRAND = 74502, // friendlys in 12yards = 74505
+ SPELL_REPELLING_WAVE = 74509, // once if call clone
+ SPELL_SABER_LASH = 40504, // every 10-15 secs
+ SPELL_SUMMON_CLONE = 74511, // summons npc 39899 (Clone)
+ SPELL_CHANNEL_SPELL = 76221, // Channeling dummy spell
+};
+
+/*######
+## boss_baltharus
+######*/
+
+struct MANGOS_DLL_DECL boss_baltharusAI : public BSWScriptedAI
+{
+ boss_baltharusAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ Creature* pDummyTarget;
+ Creature* pClone;
+ bool inCombat;
+ bool intro;
+
+ void Reset()
+ {
+ if(!pInstance)
+ return;
+
+ if (m_creature->isAlive()) pInstance->SetData(TYPE_BALTHARUS, NOT_STARTED);
+ m_creature->SetRespawnDelay(7*DAY);
+ resetTimers();
+ setStage(0);
+ pClone = NULL;
+ inCombat = false;
+ intro = false;
+ if (pDummyTarget = m_creature->GetMap()->GetCreature( pInstance->GetData64(NPC_BALTHARUS_TARGET)))
+ {
+ if (!pDummyTarget->isAlive()) pDummyTarget->Respawn();
+
+ pDummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pDummyTarget->GetMotionMaster()->MoveIdle();
+ }
+ else if (pDummyTarget = m_creature->SummonCreature(NPC_BALTHARUS_TARGET, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 1000))
+ {
+ pDummyTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pDummyTarget->GetMotionMaster()->MoveIdle();
+ }
+
+ if(Creature* pTarget = m_creature->GetMap()->GetCreature( pInstance->GetData64(NPC_XERESTRASZA)))
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pTarget->GetGUID());
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance) return;
+
+ pInstance->SetData(TYPE_BALTHARUS, FAIL);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ ScriptedAI::MoveInLineOfSight(pWho);
+ if(!pInstance || intro ||
+ pWho->GetTypeId() != TYPEID_PLAYER ||
+ !pWho->IsWithinDistInMap(m_creature, 60.0f)) return;
+
+ pInstance->SetData(TYPE_EVENT, 10);
+ DoScriptText(-1666305,m_creature);
+ intro = true;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!pInstance) return;
+
+ if (pDummyTarget) pDummyTarget->ForcedDespawn();
+ DoScriptText(-1666303,m_creature);
+ pInstance->SetData(TYPE_BALTHARUS, DONE);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1666301,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1666302,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned) return;
+
+ if ( summoned->GetEntry() != NPC_BALTHARUS_TARGET )
+ {
+ if (!pClone) pClone = summoned;
+ else if (!pClone->isAlive()) pClone = summoned;
+ pClone->SetInCombatWithZone();
+ }
+ }
+
+ void SummonedCreatureJustDied(Creature* summoned)
+ {
+ if (!pInstance || !summoned) return;
+
+ if (summoned == pClone) pClone = NULL;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!pInstance) return;
+ if (pWho->GetTypeId() != TYPEID_PLAYER) return;
+
+ if (pDummyTarget) pDummyTarget->ForcedDespawn();
+
+ SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
+
+ inCombat = true;
+ m_creature->InterruptNonMeleeSpells(true);
+ SetCombatMovement(true);
+ pInstance->SetData(TYPE_BALTHARUS, IN_PROGRESS);
+ DoScriptText(-1666300,m_creature);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (!pInstance) return;
+
+ if (!m_creature || !m_creature->isAlive())
+ return;
+
+ if(pDoneBy->GetGUID() == m_creature->GetGUID())
+ return;
+
+ if (pClone && pClone->isAlive())
+ {
+ pDoneBy->DealDamage(pClone, uiDamage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ uiDamage = 0;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance) return;
+
+ if (!inCombat && !m_creature->IsNonMeleeSpellCasted(false))
+ timedCast(SPELL_CHANNEL_SPELL, uiDiff, pDummyTarget);
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch (getStage())
+ {
+ case 0:
+ if ( m_creature->GetHealthPercent() <= 66.0f) setStage(1);
+ break;
+
+ case 1:
+ m_creature->InterruptNonMeleeSpells(true);
+ if (is25())
+ doCast(SPELL_SUMMON_CLONE);
+ setStage(2);
+ break;
+
+ case 2:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ doCast(SPELL_REPELLING_WAVE);
+ setStage(3);
+
+ case 3:
+ if ( m_creature->GetHealthPercent() <= 50.0f) setStage(4);
+ break;
+
+ case 4:
+ m_creature->InterruptNonMeleeSpells(true);
+ if (!is25())
+ doCast(SPELL_SUMMON_CLONE);
+ setStage(5);
+ break;
+
+ case 5:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ doCast(SPELL_REPELLING_WAVE);
+ setStage(6);
+
+ case 6:
+ if ( m_creature->GetHealthPercent() <= 33.0f) setStage(7);
+ break;
+
+ case 7:
+ m_creature->InterruptNonMeleeSpells(true);
+ if (is25())
+ doCast(SPELL_SUMMON_CLONE);
+ setStage(8);
+ break;
+
+ case 8:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ doCast(SPELL_REPELLING_WAVE);
+ setStage(9);
+
+ case 9:
+ default:
+ break;
+ }
+
+// timedCast(SPELL_BLADE_TEMPEST, uiDiff);
+ timedCast(SPELL_ENERVATING_BRAND, uiDiff);
+ timedCast(SPELL_SABER_LASH, uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_baltharus(Creature* pCreature)
+{
+ return new boss_baltharusAI(pCreature);
+}
+
+/*######
+## mob_baltharus_clone
+######*/
+
+struct MANGOS_DLL_DECL mob_baltharus_cloneAI : public BSWScriptedAI
+{
+ mob_baltharus_cloneAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ resetTimers();
+ m_creature->SetRespawnDelay(7*DAY);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1666301,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1666302,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!pInstance) return;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!pInstance) return;
+
+ SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
+
+ m_creature->SetInCombatWithZone();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (!pInstance) return;
+
+ if (pInstance->GetData(TYPE_BALTHARUS) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ doCastAll(uiDiff);
+
+ DoMeleeAttackIfReady();
+
+ }
+};
+
+CreatureAI* GetAI_mob_baltharus_clone(Creature* pCreature)
+{
+ return new mob_baltharus_cloneAI(pCreature);
+}
+
+
+void AddSC_boss_baltharus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_baltharus";
+ newscript->GetAI = &GetAI_boss_baltharus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_baltharus_clone";
+ newscript->GetAI = &GetAI_mob_baltharus_clone;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/ruby_sanctum/boss_halion.cpp b/scripts/northrend/ruby_sanctum/boss_halion.cpp
index 04969e6..d2af455 100644
--- a/scripts/northrend/ruby_sanctum/boss_halion.cpp
+++ b/scripts/northrend/ruby_sanctum/boss_halion.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2010 /dev/rsa for ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -16,9 +16,1238 @@
/* ScriptData
SDName: boss_halion
-SD%Complete:
-SDComment: placeholder
-SDCategory: Ruby Sanctum
+SD%Complete: 80%
+SDComment: by notagain, corrected by /dev/rsa
+SDCategory: ruby_sanctum
EndScriptData */
+// TODO: correct timers, Add twilight interorbs connection, sql spells, TESTING
+// Attention please! This script required some core modification.
+
#include "precompiled.h"
+#include "ruby_sanctum.h"
+
+enum
+{
+ //SPELLS
+ //All
+ SPELL_TWILIGHT_PRECISION = 78243, // Increases Halion's chance to hit by 5% and decreases all players' chance to dodge by 20%
+ SPELL_BERSERK = 26663, // Increases the caster's attack and movement speeds by 150% and all damage it deals by 500% for 5 min. Also grants immunity to Taunt effects.
+ SPELL_START_PHASE2 = 74808, // Phases the caster into the Twilight realm, leaving behind a large rift.
+ SPELL_TWILIGHT_ENTER = 74807, // Phases the caster into the Twilight realm - phase 32
+ SPELL_TWILIGHT_ENTER2 = 74812, //
+ SPELL_SUMMON_TWILIGHT_PORTAL = 74809, //
+
+ //NEED SCRIPT
+ SPELL_TAIL_LASH = 74531, // A sweeping tail strike hits all enemies behind the caster, inflicting 3063 to 3937 damage and stunning them for 2 sec.
+ SPELL_TWILIGHT_DIVISION = 75063, // Phases the caster, allowing him to exist and act simultaneously in both the material and Twilight realms.
+ SPELL_TWILIGHT_CUTTER = 77844, // Inflicts 13,875 to 16,125 Shadow damage every second to players touched by the shadow beam
+ //CORPOREALITY
+ SPELL_CORPOREALITY_EVEN = 74826, // Deals & receives normal damage
+ SPELL_CORPOREALITY_20I = 74827, // Damage dealt increased by 10% & Damage taken increased by 15%
+ SPELL_CORPOREALITY_40I = 74828, // Damage dealt increased by 30% & Damage taken increased by 50%
+ SPELL_CORPOREALITY_60I = 74829, // Damage dealt increased by 60% & Damage taken increased by 100%
+ SPELL_CORPOREALITY_80I = 74830, // Damage dealt increased by 100% & Damage taken increased by 200%
+ SPELL_CORPOREALITY_100I = 74831, // Damage dealt increased by 200% & Damage taken increased by 400%
+ SPELL_CORPOREALITY_20D = 74832, // Damage dealt reduced by 10% & Damage taken reduced by 15%
+ SPELL_CORPOREALITY_40D = 74833, // Damage dealt reduced by 30% & Damage taken reduced by 50%
+ SPELL_CORPOREALITY_60D = 74834, // Damage dealt reduced by 60% & Damage taken reduced by 100%
+ SPELL_CORPOREALITY_80D = 74835, // Damage dealt reduced by 100% & Damage taken reduced by 200%
+ SPELL_CORPOREALITY_100D = 74836, // Damage dealt reduced by 200% & Damage taken reduced by 400%
+ //METEOR STRIKE
+ SPELL_METEOR = 74637, // Script Start (summon NPC_METEOR_STRIKE)
+ SPELL_METEOR_IMPACT = 74641, // IMPACT ZONE FOR METEOR
+ SPELL_METEOR_STRIKE = 74648, // Inflicts 18,750 to 21,250 Fire damage to enemies within 12 yards of the targeted area. Takes about 5 seconds to land.
+ SPELL_METEOR_FLAME = 74718, // FLAME FROM METEOR
+ //N10
+ SPELL_FLAME_BREATH = 74525, // Inflicts 17,500 to 22,500 Fire damage to players in front of Halion
+ SPELL_DARK_BREATH = 74806, // Inflicts 17,500 to 22,500 Shadow damage to players in front of Halion
+ SPELL_DUSK_SHROUD = 75484, // Inflicts 3,000 Shadow damage every 2 seconds to everyone in the Twilight Realm
+ //Combustion
+ NPC_COMBUSTION = 40001,
+ SPELL_MARK_OF_COMBUSTION = 74567, // Dummy effect only
+ SPELL_FIERY_COMBUSTION = 74562, // Inflicts 4,000 Fire damage every 2 seconds for 30 seconds to a random raider. Every time Fiery Combustion does damage, it applies a stackable Mark of Combustion.
+ SPELL_COMBUSTION_EXPLODE = 74607,
+ SPELL_COMBUSTION_AURA = 74629,
+ //Consumption
+ NPC_CONSUMPTION = 40135,
+ SPELL_MARK_OF_CONSUMPTION = 74795, // Dummy effect only
+ SPELL_SOUL_CONSUMPTION = 74792, // Inflicts 4,000 Shadow damage every 2 seconds for 30 seconds to a random raider. Every time Soul Consumption does damage, it applies a stackable Mark of Consumption.
+ SPELL_CONSUMPTION_EXPLODE = 74799,
+ SPELL_CONSUMPTION_AURA = 74803,
+ //Summons
+ NPC_METEOR_STRIKE = 40029, //casts "impact zone" then meteor
+ NPC_METEOR_STRIKE_1 = 40041,
+ NPC_METEOR_STRIKE_2 = 40042,
+
+ FR_RADIUS = 45,
+
+ //SAYS
+ SAY_HALION_SPAWN = -1666100, //17499 Meddlesome insects, you're too late! The Ruby Sanctum is lost.
+ SAY_HALION_AGGRO = -1666101, //17500 Your world teeters on the brink of annihilation. You will all bear witness to the coming of a new age of destruction!
+ SAY_HALION_SLAY_1 = -1666102, //17501 Another hero falls.
+ SAY_HALION_SLAY_2 = -1666103, //17502 Ha Ha Ha!
+ SAY_HALION_DEATH = -1666104, //17503 Relish this victory mortals, for it will be your last. This world will burn with the Master's return!
+ SAY_HALION_BERSERK = -1666105, //17504 Not good enough!
+ SAY_HALION_SPECIAL_1 = -1666106, //17505 The heavens burn!
+ SAY_HALION_SPECIAL_2 = -1666107, //17506 Beware the shadow!
+ SAY_HALION_PHASE_2 = -1666108, //17507 You will find only suffering within the realm of Twilight. Enter if you dare.
+ SAY_HALION_PHASE_3 = -1666109, //17508 I am the light AND the darkness! Cower mortals before the Herald of Deathwing!
+ EMOTE_WARNING = -1666110, //orbs charge warning
+ EMOTE_REAL = -1666111, // To real world message
+ EMOTE_TWILIGHT = -1666112, // To twilight world message
+ EMOTE_NEITRAL = -1666113, // Halion reveal HP message
+};
+
+static Locations SpawnLoc[]=
+{
+ {3154.99f, 535.637f, 72.8887f}, // 0 - Halion spawn point (center)
+};
+
+/*######
+## boss_halion_real (Physical version)
+######*/
+struct MANGOS_DLL_DECL boss_halion_realAI : public BSWScriptedAI
+{
+ boss_halion_realAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ bool intro;
+ uint8 nextPoint;
+ bool MovementStarted;
+
+ void Reset()
+ {
+ if(!pInstance)
+ return;
+ m_creature->SetRespawnDelay(7*DAY);
+
+ if (m_creature->isAlive())
+ {
+ pInstance->SetData(TYPE_HALION, NOT_STARTED);
+ pInstance->SetData(TYPE_HALION_EVENT, FAIL);
+ }
+
+ resetTimers();
+ setStage(0);
+ nextPoint = 0;
+ intro = false;
+ SetCombatMovement(true);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_1)))
+ pGoPortal->Delete();
+ if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_2)))
+ pGoPortal->Delete();
+ if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_3)))
+ pGoPortal->Delete();
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pInstance) return;
+
+ if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER) return;
+
+ if (!intro && pWho->IsWithinDistInMap(m_creature, 60.0f))
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
+ DoScriptText(-1666100,m_creature);
+ intro = true;
+ m_creature->SetActiveObjectState(true);
+ }
+
+ if (intro && !m_creature->isInCombat() && pWho->IsWithinDistInMap(m_creature, 20.0f))
+ AttackStart(pWho);
+
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance) return;
+
+ if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL) return
+
+ ScriptedAI::JustReachedHome();
+
+// pInstance->SetData(TYPE_HALION, FAIL);
+
+ m_creature->SetActiveObjectState(false);
+ }
+
+ void EnterEvadeMode()
+ {
+
+ if (!pInstance) return;
+
+ if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL) return;
+
+ ScriptedAI::EnterEvadeMode();
+
+ m_creature->SetActiveObjectState(false);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!pInstance)
+ return;
+ m_creature->SetActiveObjectState(false);
+
+ DoScriptText(-1666104,m_creature);
+
+ if (Creature* pclone = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_TWILIGHT)))
+ {
+ if (!pclone->isAlive())
+ {
+ pInstance->SetData(TYPE_HALION, DONE);
+ m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pInstance->SetData(TYPE_COUNTER, 0);
+ }
+ else
+ {
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1))
+ {
+ case 0:
+ DoScriptText(-1631006,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631007,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!pInstance)
+ return;
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ doCast(SPELL_TWILIGHT_PRECISION);
+ m_creature->SetInCombatWithZone();
+ pInstance->SetData(TYPE_HALION, IN_PROGRESS);
+ DoScriptText(-1666101,m_creature);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (!pInstance) return;
+
+ if (type != POINT_MOTION_TYPE || !MovementStarted) return;
+
+ if (id == nextPoint) {
+ m_creature->GetMotionMaster()->MovementExpired();
+ MovementStarted = false;
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
+ }
+ }
+
+ void StartMovement(uint32 id)
+ {
+ nextPoint = id;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
+ MovementStarted = true;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance)
+ return;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch (getStage())
+ {
+ case 0: //PHASE 1 PHYSICAL REALM
+ timedCast(SPELL_FLAME_BREATH, uiDiff);
+ timedCast(SPELL_FIERY_COMBUSTION, uiDiff);
+ timedCast(SPELL_METEOR, uiDiff);
+ if (m_creature->GetHealthPercent() < 75.0f) setStage(1);
+ break;
+
+ case 1: // Switch to phase 2
+ m_creature->AttackStop();
+ m_creature->InterruptNonMeleeSpells(true);
+ DoScriptText(-1666108,m_creature);
+ pInstance->SetData(TYPE_HALION_EVENT, NOT_STARTED);
+ SetCombatMovement(false);
+ StartMovement(0);
+ {
+ Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL));
+ if (!pControl)
+ pControl = m_creature->SummonCreature(NPC_HALION_CONTROL, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 1000);
+ else if (!pControl->isAlive())
+ pControl->Respawn();
+ pControl->SetActiveObjectState(true);
+ pControl->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWith(pControl);
+ pControl->SetInCombatWith(m_creature);
+ }
+ setStage(2);
+ break;
+
+ case 2:
+ if (MovementStarted) return;
+ doCast(SPELL_SUMMON_TWILIGHT_PORTAL);
+ setStage(3);
+ if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_1)))
+ pGoPortal->SetPhaseMask(31,true);
+ if (GameObject* pGoRing = pInstance->instance->GetGameObject(pInstance->GetData64(GO_FLAME_RING)))
+ pGoRing->SetPhaseMask(65535,true);
+ break;
+
+ case 3:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ m_creature->SetActiveObjectState(true);
+ doCast(SPELL_START_PHASE2);
+ setStage(4);
+ break;
+
+ case 4:
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ if (Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL)))
+ {
+ m_creature->SetInCombatWith(pControl);
+ pControl->SetInCombatWith(m_creature);
+ }
+ Creature* pTwilight = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_TWILIGHT));
+ if (!pTwilight)
+ pTwilight = m_creature->SummonCreature(NPC_HALION_TWILIGHT, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 1000);
+ else if (!pTwilight->isAlive())
+ pTwilight->Respawn();
+ pTwilight->SetCreatorGuid(ObjectGuid());
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ setStage(5);
+ }
+ break;
+
+ case 5: // HALION awaiting end battle in TWILIGHT REALM
+ if (pInstance->GetData(TYPE_HALION_EVENT) == IN_PROGRESS)
+ {
+// pInstance->SetData(TYPE_HALION_EVENT, SPECIAL);
+ doRemove(SPELL_START_PHASE2);
+ if (Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL)))
+ {
+ m_creature->SetInCombatWith(pControl);
+ pControl->SetInCombatWith(m_creature);
+ }
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetHealth(m_creature->GetMaxHealth()/2);
+ m_creature->SetInCombatWithZone();
+ setStage(6);
+ }
+ return;
+
+ case 6: // Switch to phase 3
+// doCast(SPELL_TWILIGHT_DIVISION);
+ DoScriptText(-1666109,m_creature);
+ pInstance->SetData(TYPE_HALION_EVENT, SPECIAL);
+ setStage(7);
+ break;
+
+ case 7:
+ if (m_creature->IsNonMeleeSpellCasted(false)) return;
+ if (m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return;
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ setStage(8);
+ break;
+
+ case 8: //PHASE 3 BOTH REALMS
+ timedCast(SPELL_FLAME_BREATH, uiDiff);
+ timedCast(SPELL_FIERY_COMBUSTION, uiDiff);
+ timedCast(SPELL_METEOR, uiDiff);
+ break;
+
+ default:
+ break;
+ }
+
+ timedCast(SPELL_BERSERK, uiDiff);
+
+ DoMeleeAttackIfReady();
+
+ }
+};
+
+CreatureAI* GetAI_boss_halion_real(Creature* pCreature)
+{
+ return new boss_halion_realAI(pCreature);
+}
+
+/*######
+## boss_halion_twilight (Twilight version)
+######*/
+
+struct MANGOS_DLL_DECL boss_halion_twilightAI : public BSWScriptedAI
+{
+ boss_halion_twilightAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ uint8 stage;
+ bool intro;
+
+ void Reset()
+ {
+ if(!pInstance)
+ return;
+ m_creature->SetRespawnDelay(7*DAY);
+ setStage(0);
+ intro = false;
+ resetTimers();
+ m_creature->SetInCombatWithZone();
+ if (Creature* pControl = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_CONTROL)))
+ {
+ m_creature->SetInCombatWith(pControl);
+ pControl->SetInCombatWith(m_creature);
+ }
+ Creature* pFocus = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ORB_ROTATION_FOCUS));
+ if (!pFocus )
+ pFocus = m_creature->SummonCreature(NPC_ORB_ROTATION_FOCUS, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 1000);
+ else if (!pFocus->isAlive())
+ pFocus->Respawn();
+
+ if (Creature* pReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL)))
+ if (pReal->isAlive())
+ m_creature->SetHealth(pReal->GetHealth());
+ if (!hasAura(SPELL_TWILIGHT_ENTER))
+ doCast(SPELL_TWILIGHT_ENTER);
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance) return;
+
+ if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL || getStage() == 0)
+ return;
+
+ ScriptedAI::JustReachedHome();
+ }
+
+ void EnterEvadeMode()
+ {
+
+ if (!pInstance) return;
+
+ if (pInstance->GetData(TYPE_HALION_EVENT) != FAIL || getStage() == 0)
+ return;
+
+ ScriptedAI::EnterEvadeMode();
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pInstance) return;
+
+ if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER) return;
+
+ if (!intro && pWho->IsWithinDistInMap(m_creature, 20.0f))
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
+ intro = true;
+ AttackStart(pWho);
+ setStage(1);
+ doCast(SPELL_TWILIGHT_PRECISION);
+ if (Creature* pReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL)))
+ if (pReal->isAlive())
+ m_creature->SetHealth(pReal->GetHealth());
+
+
+ }
+
+ ScriptedAI::MoveInLineOfSight(pWho);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!pInstance)
+ return;
+ DoScriptText(-1666104,m_creature);
+ doRemoveFromAll(SPELL_TWILIGHT_ENTER);
+ if (Creature* pReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL)))
+ if (!pReal->isAlive())
+ {
+ pInstance->SetData(TYPE_HALION, DONE);
+ pReal->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pInstance->SetData(TYPE_COUNTER, 0);
+ }
+ m_creature->ForcedDespawn();
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1))
+ {
+ case 0:
+ DoScriptText(-1631006,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1631007,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (!pInstance)
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (!hasAura(SPELL_TWILIGHT_ENTER))
+ doCast(SPELL_TWILIGHT_ENTER);
+
+ if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS || pInstance->GetData(TYPE_HALION_EVENT) == FAIL)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+
+ switch (getStage())
+ {
+ case 1: //SPAWNED - Twilight realm
+// doCast(SPELL_TWILIGHT_DIVISION);
+ timedCast(SPELL_DUSK_SHROUD, uiDiff);
+ timedCast(SPELL_DARK_BREATH, uiDiff);
+ timedCast(SPELL_SOUL_CONSUMPTION, uiDiff);
+ if (m_creature->GetHealthPercent() < 50.0f) setStage(2);
+ break;
+
+ case 2: //To two realms
+ pInstance->SetData(TYPE_HALION_EVENT, IN_PROGRESS);
+ DoScriptText(-1666109,m_creature);
+ m_creature->SummonGameobject(GO_HALION_PORTAL_3, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0, 0);
+ if (GameObject* pGoPortal = pInstance->instance->GetGameObject(pInstance->GetData64(GO_HALION_PORTAL_3)))
+ pGoPortal->SetPhaseMask(32,true);
+ doCast(SPELL_TWILIGHT_DIVISION);
+ setStage(3);
+ break;
+
+ case 3: //PHASE 3 BOTH REALMS
+ timedCast(SPELL_DUSK_SHROUD, uiDiff);
+ timedCast(SPELL_DARK_BREATH, uiDiff);
+ timedCast(SPELL_SOUL_CONSUMPTION, uiDiff);
+ break;
+
+ default:
+ break;
+ }
+
+ timedCast(SPELL_BERSERK, uiDiff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_halion_twilight(Creature* pCreature)
+{
+ return new boss_halion_twilightAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_halion_meteorAI : public BSWScriptedAI
+{
+ mob_halion_meteorAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ float direction;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(11686);
+ m_creature->SetRespawnDelay(7*DAY);
+ SetCombatMovement(false);
+ setStage(0);
+ m_creature->SetInCombatWithZone();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ switch (getStage())
+ {
+ case 0:
+ if (timedCast(SPELL_METEOR_IMPACT, diff) == CAST_OK) setStage(1);
+ break;
+
+ case 1:
+ if (timedCast(SPELL_METEOR_STRIKE, diff) == CAST_OK) setStage(2);
+ break;
+
+ case 2:
+ // Place summon flames there
+ {
+ direction = 2.0f*M_PI_F*((float)urand(0,15)/16.0f);
+ float x, y, radius;
+ radius = 0.0f;
+ for(uint8 i = 0; i < getSpellData(SPELL_METEOR_STRIKE); ++i)
+ {
+ radius = radius + 5.0f;
+ m_creature->GetNearPoint2D(x, y, radius, direction);
+ doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000);
+ m_creature->GetNearPoint2D(x, y, radius, direction+M_PI_F);
+ doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000);
+ }
+ };
+ {
+ direction = direction + M_PI_F/4;
+ float x, y, radius;
+ radius = 0.0f;
+ for(uint8 i = 0; i < getSpellData(SPELL_METEOR_STRIKE); ++i)
+ {
+ radius = radius + 5.0f;
+ m_creature->GetNearPoint2D(x, y, radius, direction);
+ doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000);
+ m_creature->GetNearPoint2D(x, y, radius, direction+M_PI_F);
+ doSummon(NPC_METEOR_STRIKE_1, x, y, m_creature->GetPositionZ(), TEMPSUMMON_TIMED_DESPAWN, 20000);
+ }
+
+ };
+ setStage(3);
+ break;
+
+ case 3:
+ if (timedQuery(SPELL_METEOR_IMPACT, diff)) m_creature->ForcedDespawn();
+ break;
+
+ default:
+ break;
+ }
+
+ }
+};
+
+CreatureAI* GetAI_mob_halion_meteor(Creature* pCreature)
+{
+ return new mob_halion_meteorAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_halion_flameAI : public BSWScriptedAI
+{
+ mob_halion_flameAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetDisplayId(11686);
+ m_creature->SetRespawnDelay(7*DAY);
+ SetCombatMovement(false);
+ m_creature->SetInCombatWithZone();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!hasAura(SPELL_METEOR_FLAME))
+ doCast(SPELL_METEOR_FLAME);
+
+ }
+
+};
+
+CreatureAI* GetAI_mob_halion_flame(Creature* pCreature)
+{
+ return new mob_halion_flameAI(pCreature);
+};
+
+struct HalionBuffLine
+{
+ float diff; // Health diff in percent
+ uint32 real, twilight; // Buff pair
+};
+
+static HalionBuffLine Buff[]=
+{
+ {-10.0f,SPELL_CORPOREALITY_100I, SPELL_CORPOREALITY_100D},
+ {-8.0f,SPELL_CORPOREALITY_80I, SPELL_CORPOREALITY_80D},
+ {-6.0f,SPELL_CORPOREALITY_60I, SPELL_CORPOREALITY_60D},
+ {-4.0f,SPELL_CORPOREALITY_40I, SPELL_CORPOREALITY_40D},
+ {-2.0f,SPELL_CORPOREALITY_20I, SPELL_CORPOREALITY_20D},
+ {-1.0f,SPELL_CORPOREALITY_EVEN, SPELL_CORPOREALITY_EVEN},
+ {1.0f,SPELL_CORPOREALITY_EVEN, SPELL_CORPOREALITY_EVEN},
+ {2.0f,SPELL_CORPOREALITY_20D, SPELL_CORPOREALITY_20I},
+ {4.0f,SPELL_CORPOREALITY_40D, SPELL_CORPOREALITY_40I},
+ {6.0f,SPELL_CORPOREALITY_60D, SPELL_CORPOREALITY_60I},
+ {8.0f,SPELL_CORPOREALITY_80D, SPELL_CORPOREALITY_80I},
+ {10.0f,SPELL_CORPOREALITY_100D, SPELL_CORPOREALITY_100I},
+};
+
+struct MANGOS_DLL_DECL mob_halion_controlAI : public BSWScriptedAI
+{
+ mob_halion_controlAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ Creature* pHalionReal;
+ Creature* pHalionTwilight;
+ uint32 m_lastBuffReal, m_lastBuffTwilight;
+ bool m_detectplayers;
+
+ void Reset()
+ {
+ if (!pInstance) return;
+ resetTimers();
+ m_detectplayers = true;
+ m_creature->SetDisplayId(11686);
+ m_creature->SetPhaseMask(65535, true);
+// m_creature->SetDisplayId(10045);
+ m_creature->SetRespawnDelay(7*DAY);
+ SetCombatMovement(false);
+ m_lastBuffReal = 0;
+ m_lastBuffTwilight = 0;
+ m_creature->SetActiveObjectState(true);
+ pInstance->SetData(TYPE_COUNTER, 0);
+ pInstance->SetData(TYPE_HALION_EVENT, NOT_STARTED);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!pInstance) return;
+
+ if (timedQuery(SPELL_CORPOREALITY_EVEN, diff))
+ {
+ if (!doSelectRandomPlayerAtRange(80.0f))
+ {
+ debug_log("ruby_sanctum: cannot detect players in range! ");
+ if (!m_detectplayers)
+ {
+ pInstance->SetData(TYPE_HALION_EVENT, FAIL);
+ pInstance->SetData(TYPE_HALION, FAIL);
+ m_creature->ForcedDespawn();
+ } else m_detectplayers = false;
+ } else m_detectplayers = true;
+
+ if (pInstance->GetData(TYPE_HALION_EVENT) != SPECIAL) return;
+
+ pHalionReal = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL));
+ pHalionTwilight = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_TWILIGHT));
+
+ float p_RealHP = (pHalionReal && pHalionReal->isAlive()) ? pHalionReal->GetHealthPercent() : 0.0f;
+ float p_TwilightHP = (pHalionTwilight && pHalionTwilight->isAlive()) ? pHalionTwilight->GetHealthPercent() : 0.0f;
+
+ float m_diff = (p_RealHP - p_TwilightHP);
+
+ uint8 buffnum;
+ if (m_diff <= Buff[0].diff) buffnum = 0;
+ else for (uint8 i = 0; i < 11; i++)
+ if (m_diff >= Buff[i].diff)
+ buffnum = i+1;
+ else break;
+
+ if (!m_lastBuffReal || m_lastBuffReal != Buff[buffnum].real)
+ {
+ if (m_lastBuffReal) doRemove(m_lastBuffReal, pHalionReal);
+ doCast(Buff[buffnum].real, pHalionReal);
+ m_lastBuffReal = Buff[buffnum].real;
+ }
+
+ if (!m_lastBuffTwilight || m_lastBuffTwilight != Buff[buffnum].twilight)
+ {
+ if (m_lastBuffTwilight) doRemove(m_lastBuffTwilight, pHalionReal);
+ doCast(Buff[buffnum].twilight, pHalionTwilight);
+ m_lastBuffTwilight = Buff[buffnum].twilight;
+ }
+
+ debug_log("ruby_sanctum: Buff num = %u, m_diff = %d ", buffnum, m_diff);
+
+ pInstance->SetData(TYPE_COUNTER, 50 + (int)Buff[buffnum].diff);
+
+ }
+
+ }
+
+};
+
+CreatureAI* GetAI_mob_halion_control(Creature* pCreature)
+{
+ return new mob_halion_controlAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_orb_rotation_focusAI : public ScriptedAI
+{
+ mob_orb_rotation_focusAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ uint32 m_timer;
+ float m_direction, m_nextdirection;
+ bool m_warning;
+
+ void Reset()
+ {
+ m_creature->SetDisplayId(11686);
+// m_creature->SetDisplayId(10045);
+ m_creature->SetRespawnDelay(7*DAY);
+ m_creature->SetPhaseMask(65535, true);
+ SetCombatMovement(false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_direction = 0.0f;
+ m_nextdirection = 0.0f;
+ m_timer = 30000;
+ m_warning = false;
+
+ Creature* pPulsar1 = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SHADOW_PULSAR_N));
+ if (!pPulsar1 )
+ {
+ float x,y;
+ m_creature->GetNearPoint2D(x, y, FR_RADIUS, m_direction);
+ pPulsar1 = m_creature->SummonCreature(NPC_SHADOW_PULSAR_N, x, y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ } else if (!pPulsar1->isAlive())
+ pPulsar1->Respawn();
+
+ Creature* pPulsar2 = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_SHADOW_PULSAR_S));
+ if (!pPulsar2)
+ {
+ float x,y;
+ m_creature->GetNearPoint2D(x, y, FR_RADIUS, m_direction + M_PI_F);
+ pPulsar2 = m_creature->SummonCreature(NPC_SHADOW_PULSAR_S, x, y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ } else if (!pPulsar2->isAlive())
+ pPulsar2->Respawn();
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (pInstance->GetData(DATA_ORB_S) == DONE && pInstance->GetData(DATA_ORB_N) == DONE)
+ {
+ m_direction = m_nextdirection;
+ m_nextdirection = (m_direction - M_PI_F/64.0f);
+ if (m_nextdirection < 0.0f ) m_nextdirection = m_nextdirection + 2.0f*M_PI_F;
+ pInstance->SetData(DATA_ORB_DIRECTION, (uint32)(m_nextdirection*1000));
+ pInstance->SetData(DATA_ORB_N, SPECIAL);
+ pInstance->SetData(DATA_ORB_S, SPECIAL);
+ debug_log("EventMGR: creature %u send direction %u ",m_creature->GetEntry(),pInstance->GetData(DATA_ORB_DIRECTION));
+ }
+
+ if (m_timer - 6000 <= uiDiff && !m_warning)
+ {
+ DoScriptText(-1666110,m_creature);
+ m_warning = true;
+ }
+
+ if (m_timer <= uiDiff)
+ {
+ float x,y;
+ m_creature->GetNearPoint2D(x, y, FR_RADIUS, m_nextdirection);
+ m_creature->SummonCreature(NPC_ORB_CARRIER, x, y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 5000);
+ m_timer = 30000;
+ m_warning = false;
+ } else m_timer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_orb_rotation_focus(Creature* pCreature)
+{
+ return new mob_orb_rotation_focusAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_halion_orbAI : public BSWScriptedAI
+{
+ mob_halion_orbAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ float m_direction,m_delta;
+ uint32 m_flag;
+ uint32 m_flag1;
+ bool MovementStarted;
+ Creature* focus;
+ uint32 nextPoint;
+
+ void Reset()
+ {
+ if (!pInstance) return;
+ m_creature->SetRespawnDelay(7*DAY);
+ SetCombatMovement(false);
+ m_creature->SetPhaseMask(32, true);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ if (m_creature->GetEntry() == NPC_SHADOW_PULSAR_N)
+ {
+ m_flag = DATA_ORB_N;
+ m_delta = 0.0f;
+ } else if (m_creature->GetEntry() == NPC_SHADOW_PULSAR_S)
+ {
+ m_flag = DATA_ORB_S;
+ m_delta = M_PI_F;
+ };
+ m_direction = 0.0f;
+ nextPoint = 0;
+ MovementStarted = false;
+ pInstance->SetData(m_flag, DONE);
+ debug_log("EventMGR: creature %u assume m_flag %u ",m_creature->GetEntry(),m_flag);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (!pInstance) return;
+
+ if (type != POINT_MOTION_TYPE || !MovementStarted) return;
+
+ if (id == nextPoint) {
+ m_creature->GetMotionMaster()->MovementExpired();
+ MovementStarted = false;
+ pInstance->SetData(m_flag, DONE);
+ }
+ }
+
+ void StartMovement(uint32 id)
+ {
+ if (!pInstance) return;
+ nextPoint = id;
+ float x,y;
+ pInstance->SetData(m_flag, IN_PROGRESS);
+ MovementStarted = true;
+ m_direction = ((float)pInstance->GetData(DATA_ORB_DIRECTION)/1000 + m_delta);
+ if (m_direction > 2.0f*M_PI_F) m_direction = m_direction - 2.0f*M_PI_F;
+ if (focus = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ORB_ROTATION_FOCUS)))
+ focus->GetNearPoint2D(x, y, FR_RADIUS, m_direction);
+ else m_creature->ForcedDespawn();
+// debug_log("EventMGR: creature %u go to move point %u ",m_creature->GetEntry(),id);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(id, x, y, m_creature->GetPositionZ());
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(2.0f))
+ doCast(SPELL_TWILIGHT_CUTTER, pTarget);
+
+ if (!MovementStarted && pInstance->GetData(m_flag) == SPECIAL)
+ {
+// debug_log("EventMGR: creature %u get direction %u ",m_creature->GetEntry(),pInstance->GetData(DATA_ORB_DIRECTION));
+ StartMovement(1);
+ }
+
+ }
+};
+
+CreatureAI* GetAI_mob_halion_orb(Creature* pCreature)
+{
+ return new mob_halion_orbAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_orb_carrierAI : public BSWScriptedAI
+{
+ mob_orb_carrierAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ bool MovementStarted;
+
+ void Reset()
+ {
+// m_creature->SetDisplayId(10045);
+ m_creature->SetRespawnDelay(7*DAY);
+ SetCombatMovement(false);
+ m_creature->SetPhaseMask(32, true);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ MovementStarted = false;
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_RUN, 6.0f);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (!pInstance) return;
+
+ if (type != POINT_MOTION_TYPE || !MovementStarted) return;
+
+ if (id == 1) {
+ m_creature->GetMotionMaster()->MovementExpired();
+ MovementStarted = false;
+ m_creature->ForcedDespawn();
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!pInstance || pInstance->GetData(TYPE_HALION) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(2.0f))
+ doCast(SPELL_TWILIGHT_CUTTER, pTarget);
+
+ if (!MovementStarted)
+ {
+ float x,y;
+ float m_direction = ((float)pInstance->GetData(DATA_ORB_DIRECTION)/1000.0f + M_PI_F - M_PI_F/32.0f);
+ if (m_direction > 2.0f*M_PI_F) m_direction = m_direction - 2.0f*M_PI_F;
+ if (Creature* focus = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_ORB_ROTATION_FOCUS)))
+ focus->GetNearPoint2D(x, y, FR_RADIUS, m_direction);
+ else m_creature->ForcedDespawn();
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(1, x, y, m_creature->GetPositionZ());
+ MovementStarted = true;
+ }
+
+ }
+
+};
+
+CreatureAI* GetAI_mob_orb_carrier(Creature* pCreature)
+{
+ return new mob_orb_carrierAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_soul_consumptionAI : public BSWScriptedAI
+{
+ mob_soul_consumptionAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ float m_Size0;
+ float m_Size;
+
+ void Reset()
+ {
+ if (!isHeroic()) m_creature->SetPhaseMask(32,true);
+ else m_creature->SetPhaseMask(65535,true);
+ SetCombatMovement(false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ doCast(SPELL_CONSUMPTION_AURA);
+ m_Size0 = m_creature->GetObjectScale();
+ m_Size = m_Size0;
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance && m_pInstance->GetData(TYPE_HALION) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+// if (!hasAura(SPELL_TWILIGHT_ENTER))
+// doCast(SPELL_TWILIGHT_ENTER);
+
+ if (timedQuery(SPELL_CONSUMPTION_AURA, uiDiff))
+ m_creature->ForcedDespawn();
+
+ if (doSelectRandomPlayerAtRange(m_Size * 3.0f) && m_Size <= m_Size0 * 3.0f) {
+ m_Size = m_Size*1.01;
+ m_creature->SetObjectScale(m_Size);
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_soul_consumption(Creature* pCreature)
+{
+ return new mob_soul_consumptionAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_fiery_combustionAI : public BSWScriptedAI
+{
+ mob_fiery_combustionAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ float m_Size0;
+ float m_Size;
+
+ void Reset()
+ {
+ if (!isHeroic()) m_creature->SetPhaseMask(31,true);
+ else m_creature->SetPhaseMask(65535,true);
+ SetCombatMovement(false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ doCast(SPELL_COMBUSTION_AURA);
+ m_Size0 = m_creature->GetObjectScale();
+ m_Size = m_Size0;
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance && m_pInstance->GetData(TYPE_HALION) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (timedQuery(SPELL_COMBUSTION_AURA, uiDiff))
+ m_creature->ForcedDespawn();
+
+ if (doSelectRandomPlayerAtRange(m_Size * 3.0f) && m_Size <= m_Size0 * 3.0f) {
+ m_Size = m_Size*1.01;
+ m_creature->SetObjectScale(m_Size);
+ }
+ }
+
+};
+
+CreatureAI* GetAI_mob_fiery_combustion(Creature* pCreature)
+{
+ return new mob_fiery_combustionAI(pCreature);
+};
+
+
+bool GOHello_go_halion_portal_twilight(Player *player, GameObject* pGo)
+{
+ ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData();
+ if(!pInstance) return false;
+ player->CastSpell(player,SPELL_TWILIGHT_ENTER,false);
+ return true;
+}
+
+bool GOHello_go_halion_portal_real(Player *player, GameObject* pGo)
+{
+ ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData();
+ if(!pInstance) return false;
+ player->RemoveAurasDueToSpell(SPELL_TWILIGHT_ENTER);
+ return true;
+}
+
+void AddSC_boss_halion()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_halion_real";
+ newscript->GetAI = &GetAI_boss_halion_real;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_halion_twilight";
+ newscript->GetAI = &GetAI_boss_halion_twilight;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_halion_meteor";
+ newscript->GetAI = &GetAI_mob_halion_meteor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_halion_flame";
+ newscript->GetAI = &GetAI_mob_halion_flame;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_halion_orb";
+ newscript->GetAI = &GetAI_mob_halion_orb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_halion_control";
+ newscript->GetAI = &GetAI_mob_halion_control;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_orb_rotation_focus";
+ newscript->GetAI = &GetAI_mob_orb_rotation_focus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_orb_carrier";
+ newscript->GetAI = &GetAI_mob_orb_carrier;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_soul_consumption";
+ newscript->GetAI = &GetAI_mob_soul_consumption;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_fiery_combustion";
+ newscript->GetAI = &GetAI_mob_fiery_combustion;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_halion_portal_twilight";
+ newscript->pGOHello = &GOHello_go_halion_portal_twilight;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_halion_portal_real";
+ newscript->pGOHello = &GOHello_go_halion_portal_real;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/ruby_sanctum/boss_saviana.cpp b/scripts/northrend/ruby_sanctum/boss_saviana.cpp
index abef372..03580fe 100644
--- a/scripts/northrend/ruby_sanctum/boss_saviana.cpp
+++ b/scripts/northrend/ruby_sanctum/boss_saviana.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2010 /dev/rsa for ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,10 +15,308 @@
*/
/* ScriptData
-SDName: boss_saviana
-SD%Complete:
-SDComment: placeholder
-SDCategory: Ruby Sanctum
+SDName: boss_ragefire
+SD%Complete: 90%
+SDComment: by notagain && /dev/rsa
+SDCategory: ruby_sanctum
EndScriptData */
#include "precompiled.h"
+#include "ruby_sanctum.h"
+
+enum BossSpells
+{
+ SPELL_ENRAGE = 78722, //soft enrage + fire nova
+ SPELL_FLAME_BREATH = 74404,
+ SPELL_BEACON = 74453, //mark for conflag, in enter to fly phase, 2 in 10, 5 in 25
+ SPELL_CONFLAGATION = 74452, // after fly up
+ SPELL_CONFLAGATION_1 = 74455, // Triggered?
+ SPELL_CONFLAGATION_2 = 74456, // Aura
+
+ MAX_BEACON_TARGETS = 5,
+};
+
+static Locations SpawnLoc[]=
+{
+ {3151.3898f, 636.8519f, 78.7396f}, // 0 Saviana start point
+ {3149.635f, 668.9644f, 90.507f}, // 1 Saviana fly phase, o=4,69
+};
+
+struct MANGOS_DLL_DECL boss_ragefireAI : public BSWScriptedAI
+{
+ boss_ragefireAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ uint8 nextPoint;
+ Unit* marked[MAX_BEACON_TARGETS];
+ bool MovementStarted;
+ bool conflagated;
+
+ void Reset()
+ {
+ if(!pInstance)
+ return;
+ m_creature->SetRespawnDelay(7*DAY);
+ if (m_creature->isAlive()) pInstance->SetData(TYPE_RAGEFIRE, NOT_STARTED);
+ resetTimers();
+ setStage(0);
+ nextPoint = 0;
+ conflagated = false;
+ for (uint8 i = 0; i < MAX_BEACON_TARGETS; ++i)
+ marked[i] = NULL;
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (!pInstance) return;
+
+ if (type != POINT_MOTION_TYPE || !MovementStarted) return;
+
+ if (id == nextPoint) {
+ m_creature->GetMotionMaster()->MovementExpired();
+ MovementStarted = false;
+ }
+ }
+
+ void SetFly(bool command = false)
+ {
+ if (command)
+ {
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_UP);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+ }
+ else
+ {
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_FLYING);
+ }
+ }
+
+ void StartMovement(uint32 id)
+ {
+ nextPoint = id;
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
+ MovementStarted = true;
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1666401,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1666402,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance)
+ pInstance->SetData(TYPE_RAGEFIRE, FAIL);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+
+ pInstance->SetData(TYPE_RAGEFIRE, IN_PROGRESS);
+ m_creature->SetInCombatWithZone();
+ DoScriptText(-1666400,m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+
+ pInstance->SetData(TYPE_RAGEFIRE, DONE);
+ DoScriptText(-1666403,m_creature);
+ }
+
+ void doBeacon(bool command = false)
+ {
+ if (command)
+ {
+ for(uint8 i = 0; i < getSpellData(SPELL_BEACON); ++i)
+ {
+ if (Unit* pTarget = doSelectRandomPlayer(SPELL_BEACON, false, 100.0f))
+ {
+ if (doCast(SPELL_BEACON, pTarget) == CAST_OK)
+ marked[i] = pTarget;
+ else marked[i] = NULL;
+ }
+ }
+ conflagated = true;
+ }
+ else
+ {
+ m_creature->InterruptNonMeleeSpells(true);
+ for(uint8 i = 0; i < getSpellData(SPELL_BEACON); ++i)
+ {
+ if (marked[i])
+ doCast(SPELL_CONFLAGATION_2, marked[i]);
+ marked[i] = NULL;
+ }
+ doCast(SPELL_CONFLAGATION_1);
+ conflagated = false;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch (getStage())
+ {
+ case 0: //GROUND
+ timedCast(SPELL_FLAME_BREATH, diff);
+ timedCast(SPELL_ENRAGE, diff);
+ if ( m_creature->GetHealthPercent() <= 80.0f) setStage(1);
+ break;
+
+ case 1: //Air phase start
+ SetCombatMovement(false);
+ m_creature->InterruptNonMeleeSpells(true);
+ SetFly(true);
+ doBeacon(true);
+ StartMovement(1);
+ setStage(2);
+ break;
+
+ case 2: // Wait for movement
+ if (MovementStarted) return;
+ doCast(SPELL_CONFLAGATION);
+ DoScriptText(-1666404,m_creature);
+ setStage(3);
+ break;
+
+ case 3: // Wait for cast finish
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ doBeacon(false);
+ setStage(4);
+ };
+ break;
+
+ case 4: // Air phase
+ timedCast(SPELL_FLAME_BREATH, diff);
+ if (timedQuery(SPELL_BEACON, diff))
+ {
+ doBeacon(true);
+ doCast(SPELL_CONFLAGATION);
+ };
+ if (conflagated && timedQuery(SPELL_CONFLAGATION_1, diff))
+ {
+ doBeacon(false);
+ };
+ if ( m_creature->GetHealthPercent() <= 60.0f) setStage(5);
+ break;
+
+ case 5: //Air phase end
+ StartMovement(0);
+ setStage(6);
+ break;
+
+ case 6: // Wait for movement
+ if (MovementStarted) return;
+ SetFly(false);
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ setStage(7);
+ break;
+
+ case 7: //GROUND
+ timedCast(SPELL_FLAME_BREATH, diff);
+ timedCast(SPELL_ENRAGE, diff);
+ if ( m_creature->GetHealthPercent() <= 40.0f) setStage(8);
+ break;
+
+ case 8: //Air phase start
+ SetCombatMovement(false);
+ m_creature->InterruptNonMeleeSpells(true);
+ SetFly(true);
+ doBeacon(true);
+ StartMovement(1);
+ setStage(9);
+ break;
+
+ case 9: // Wait for movement
+ if (MovementStarted) return;
+ doCast(SPELL_CONFLAGATION);
+ DoScriptText(-1666404,m_creature);
+ setStage(10);
+ break;
+
+ case 10: // Wait for cast finish
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ doBeacon(false);
+ setStage(11);
+ };
+ break;
+
+ case 11: // Air phase
+ timedCast(SPELL_FLAME_BREATH, diff);
+ if (timedQuery(SPELL_BEACON, diff))
+ {
+ doBeacon(true);
+ doCast(SPELL_CONFLAGATION);
+ };
+ if (conflagated && timedQuery(SPELL_CONFLAGATION_1, diff))
+ {
+ doBeacon(false);
+ };
+ if ( m_creature->GetHealthPercent() <= 20.0f) setStage(12);
+ break;
+
+ case 12: //Air phase end
+ StartMovement(0);
+ setStage(13);
+ break;
+
+ case 13: // Wait for movement
+ if (MovementStarted) return;
+ SetFly(false);
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ setStage(14);
+ break;
+
+ case 14: //GROUND
+ timedCast(SPELL_FLAME_BREATH, diff);
+ timedCast(SPELL_ENRAGE, diff*2);
+ break;
+
+ default:
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_ragefire(Creature* pCreature)
+{
+ return new boss_ragefireAI(pCreature);
+}
+
+void AddSC_boss_ragefire()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_ragefire";
+ newscript->GetAI = &GetAI_boss_ragefire;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/ruby_sanctum/boss_zarithrian.cpp b/scripts/northrend/ruby_sanctum/boss_zarithrian.cpp
new file mode 100644
index 0000000..880bc7b
--- /dev/null
+++ b/scripts/northrend/ruby_sanctum/boss_zarithrian.cpp
@@ -0,0 +1,219 @@
+/* Copyright (C) 2010 /dev/rsa for ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* ScriptData
+SDName: boss_zarithian
+SD%Complete: 90%
+SDComment: by /dev/rsa && notagain
+SDCategory: ruby_sanctum
+EndScriptData */
+
+// Need correct timers
+
+#include "precompiled.h"
+#include "ruby_sanctum.h"
+
+enum BossSpells
+{
+ SPELL_CALL_FLAMECALLER = 74398,
+ SPELL_CLEAVE_ARMOR = 74367,
+ SPELL_IMTIMIDATING_ROAR = 74384,
+ SPELL_LAVA_GOUT = 74394,
+ SPELL_BLAST_NOVA = 74392,
+
+ NPC_FLAMECALLER = 39814,
+};
+
+enum Equipment
+{
+ EQUIP_MAIN = 47156,
+ EQUIP_OFFHAND = 51812,
+ EQUIP_RANGED = EQUIP_NO_CHANGE,
+ EQUIP_DONE = EQUIP_NO_CHANGE,
+};
+
+static Locations SpawnLoc[]=
+{
+ {3008.552734f, 530.471680f, 89.195290f}, // 0 - Zarithian start point, o = 6,16
+ {3014.313477f, 486.453735f, 89.255096f}, // 1 - Mob spawn 1
+ {3025.324951f, 580.588501f, 88.593185f}, // 2 - Mob spawn 2
+};
+
+struct MANGOS_DLL_DECL boss_zarithianAI : public BSWScriptedAI
+{
+ boss_zarithianAI(Creature* pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ if(!pInstance)
+ return;
+
+ if (m_creature->isAlive())
+ {
+ pInstance->SetData(TYPE_ZARITHIAN, NOT_STARTED);
+ resetTimers();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ setStage(0);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (getStage())
+ ScriptedAI::MoveInLineOfSight(pWho);
+
+ if (!getStage() &&
+ pInstance->GetData(TYPE_XERESTRASZA) == DONE &&
+ pInstance->GetData(TYPE_BALTHARUS) == DONE &&
+ pInstance->GetData(TYPE_RAGEFIRE) == DONE)
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ setStage(1);
+ };
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch (urand(0,1)) {
+ case 0:
+ DoScriptText(-1666201,m_creature,pVictim);
+ break;
+ case 1:
+ DoScriptText(-1666202,m_creature,pVictim);
+ break;
+ };
+ }
+
+ void JustReachedHome()
+ {
+ if (!pInstance) return;
+ pInstance->SetData(TYPE_ZARITHIAN, FAIL);
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(!pInstance || !summoned) return;
+
+ summoned->SetInCombatWithZone();
+ if (Unit* pTarget = doSelectRandomPlayerAtRange(60.0f))
+ {
+ summoned->AddThreat(pTarget, 100.0f);
+ summoned->GetMotionMaster()->MoveChase(pTarget);
+ }
+
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(!pInstance) return;
+
+ SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
+ pInstance->SetData(TYPE_ZARITHIAN, IN_PROGRESS);
+ DoScriptText(-1666200,m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(!pInstance) return;
+
+ pInstance->SetData(TYPE_ZARITHIAN, DONE);
+ DoScriptText(-1666203,m_creature);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (timedQuery(SPELL_CALL_FLAMECALLER, diff))
+ {
+ doSummon(NPC_FLAMECALLER, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z);
+ doSummon(NPC_FLAMECALLER, SpawnLoc[2].x, SpawnLoc[2].y, SpawnLoc[2].z);
+
+// if (currentDifficulty == RAID_DIFFICULTY_25MAN_NORMAL
+// || currentDifficulty == RAID_DIFFICULTY_25MAN_HEROIC)
+// doCast(SPELL_CALL_FLAMECALLER);
+
+ DoScriptText(-1666204,m_creature);
+ }
+
+ timedCast(SPELL_CLEAVE_ARMOR, diff);
+ timedCast(SPELL_IMTIMIDATING_ROAR, diff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_zarithian(Creature* pCreature)
+{
+ return new boss_zarithianAI(pCreature);
+};
+
+struct MANGOS_DLL_DECL mob_flamecaller_rubyAI : public BSWScriptedAI
+{
+ mob_flamecaller_rubyAI(Creature *pCreature) : BSWScriptedAI(pCreature)
+ {
+ pInstance = ((ScriptedInstance*)pCreature->GetInstanceData());
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ resetTimers();
+ m_creature->SetRespawnDelay(7*DAY);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ if (pInstance && pInstance->GetData(TYPE_ZARITHIAN) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ doCastAll(diff);
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_flamecaller_ruby(Creature* pCreature)
+{
+ return new mob_flamecaller_rubyAI(pCreature);
+};
+
+void AddSC_boss_zarithrian()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_zarithian";
+ newscript->GetAI = &GetAI_boss_zarithian;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_flamecaller_ruby";
+ newscript->GetAI = &GetAI_mob_flamecaller_ruby;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/ruby_sanctum/instance_ruby_sanctum.cpp b/scripts/northrend/ruby_sanctum/instance_ruby_sanctum.cpp
new file mode 100644
index 0000000..deb17c2
--- /dev/null
+++ b/scripts/northrend/ruby_sanctum/instance_ruby_sanctum.cpp
@@ -0,0 +1,404 @@
+/* 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: instance_ruby_sanctum
+SD%Complete: 50%
+SDComment: by notagain, corrected by /dev/rsa
+SDCategory: ruby_sanctum
+EndScriptData */
+
+//TODO: Trash mobs, spawn and removal of fire ring/walls, spawn of halion
+
+#include "precompiled.h"
+#include "ruby_sanctum.h"
+
+struct MANGOS_DLL_DECL instance_ruby_sanctum : public ScriptedInstance
+{
+ instance_ruby_sanctum(Map* pMap) : ScriptedInstance(pMap)
+ {
+ Initialize();
+ }
+
+ bool needSave;
+ std::string strSaveData;
+
+ //Creatures GUID
+ uint32 m_auiEncounter[MAX_ENCOUNTERS+1];
+
+ uint32 m_auiEventTimer;
+ uint32 m_auiHalionEvent;
+
+ uint32 m_auiOrbDirection;
+ uint32 m_auiOrbNState;
+ uint32 m_auiOrbSState;
+
+ uint64 m_uiHalion_pGUID;
+ uint64 m_uiHalion_tGUID;
+ uint64 m_uiHalionControlGUID;
+ uint64 m_uiRagefireGUID;
+ uint64 m_uiZarithianGUID;
+ uint64 m_uiBaltharusGUID;
+ uint64 m_uiCloneGUID;
+ uint64 m_uiXerestraszaGUID;
+
+ uint64 m_uiOrbNGUID;
+ uint64 m_uiOrbSGUID;
+ uint64 m_uiOrbFocusGUID;
+ uint64 m_uiOrbCarrierGUID;
+
+ //object GUID
+ uint64 m_uiHalionPortal1GUID;
+ uint64 m_uiHalionPortal2GUID;
+ uint64 m_uiHalionPortal3GUID;
+ uint64 m_uiHalionFireWallSGUID;
+ uint64 m_uiHalionFireWallMGUID;
+ uint64 m_uiHalionFireWallLGUID;
+ uint64 m_uiBaltharusTargetGUID;
+
+ uint64 m_uiFireFieldGUID;
+ uint64 m_uiFlameWallsGUID;
+ uint64 m_uiFlameRingGUID;
+
+ void OpenDoor(uint64 guid)
+ {
+ if(!guid)
+ return;
+
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo)
+ pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ }
+
+ void CloseDoor(uint64 guid)
+ {
+ if(!guid)
+ return;
+
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo)
+ pGo->SetGoState(GO_STATE_READY);
+ }
+
+ void Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ m_auiEventTimer = 1000;
+
+ m_uiHalion_pGUID = 0;
+ m_uiHalion_tGUID = 0;
+ m_uiRagefireGUID = 0;
+ m_uiZarithianGUID = 0;
+ m_uiBaltharusGUID = 0;
+ m_uiCloneGUID = 0;
+ m_uiHalionPortal1GUID = 0;
+ m_uiHalionPortal2GUID = 0;
+ m_uiHalionPortal3GUID = 0;
+ m_uiXerestraszaGUID = 0;
+ m_uiHalionFireWallSGUID = 0;
+ m_uiHalionFireWallMGUID = 0;
+ m_uiHalionFireWallLGUID = 0;
+ m_uiBaltharusTargetGUID = 0;
+ m_auiOrbDirection = 0;
+ m_uiOrbNGUID = 0;
+ m_uiOrbSGUID = 0;
+ m_uiOrbFocusGUID = 0;
+ m_auiOrbNState = NOT_STARTED;
+ m_auiOrbSState = NOT_STARTED;
+
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for(uint8 i = 1; i < MAX_ENCOUNTERS ; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ return true;
+
+ return false;
+ }
+
+ void UpdateWorldState(bool command, uint32 value)
+ {
+ Map::PlayerList const &players = instance->GetPlayers();
+
+ if (command)
+ {
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ if(Player* pPlayer = i->getSource())
+ if(pPlayer->isAlive())
+ {
+ pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,0);
+ if (pPlayer->HasAura(74807))
+ pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_COUNT_T, 100 - value);
+ else pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_COUNT_R, value);
+ pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,1);
+ }
+ }
+ else
+ {
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ if(Player* pPlayer = i->getSource())
+ if(pPlayer->isAlive())
+ pPlayer->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,0);
+ }
+ }
+
+ void OpenAllDoors()
+ {
+ if (m_auiEncounter[TYPE_RAGEFIRE] == DONE &&
+ m_auiEncounter[TYPE_BALTHARUS] == DONE &&
+ m_auiEncounter[TYPE_XERESTRASZA] == DONE)
+ OpenDoor(m_uiFlameWallsGUID);
+ else CloseDoor(m_uiFlameWallsGUID);
+ }
+
+ void OnCreatureCreate(Creature* pCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_HALION_REAL: m_uiHalion_pGUID = pCreature->GetGUID(); break;
+ case NPC_HALION_TWILIGHT: m_uiHalion_tGUID = pCreature->GetGUID(); break;
+ case NPC_HALION_CONTROL: m_uiHalionControlGUID = pCreature->GetGUID(); break;
+ case NPC_RAGEFIRE: m_uiRagefireGUID = pCreature->GetGUID(); break;
+ case NPC_ZARITHIAN: m_uiZarithianGUID = pCreature->GetGUID(); break;
+ case NPC_BALTHARUS: m_uiBaltharusGUID = pCreature->GetGUID(); break;
+ case NPC_BALTHARUS_TARGET: m_uiBaltharusTargetGUID = pCreature->GetGUID(); break;
+ case NPC_CLONE: m_uiCloneGUID = pCreature->GetGUID(); break;
+ case NPC_XERESTRASZA: m_uiXerestraszaGUID = pCreature->GetGUID(); break;
+ case NPC_SHADOW_PULSAR_N: m_uiOrbNGUID = pCreature->GetGUID(); break;
+ case NPC_SHADOW_PULSAR_S: m_uiOrbSGUID = pCreature->GetGUID(); break;
+ case NPC_ORB_ROTATION_FOCUS: m_uiOrbFocusGUID = pCreature->GetGUID(); break;
+ case NPC_ORB_CARRIER: m_uiOrbCarrierGUID = pCreature->GetGUID(); break;
+ }
+ }
+
+ void OnObjectCreate(GameObject* pGo)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_HALION_PORTAL_1: m_uiHalionPortal1GUID = pGo->GetGUID(); break;
+ case GO_HALION_PORTAL_2: m_uiHalionPortal2GUID = pGo->GetGUID(); break;
+ case GO_HALION_PORTAL_3: m_uiHalionPortal3GUID = pGo->GetGUID(); break;
+ case GO_FLAME_WALLS: m_uiFlameWallsGUID = pGo->GetGUID(); break;
+ case GO_FLAME_RING: m_uiFlameRingGUID = pGo->GetGUID(); break;
+ case GO_FIRE_FIELD: m_uiFireFieldGUID = pGo->GetGUID(); break;
+ }
+ OpenAllDoors();
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ switch(uiType)
+ {
+ case TYPE_EVENT: m_auiEncounter[uiType] = uiData; uiData = NOT_STARTED; break;
+ case TYPE_RAGEFIRE: m_auiEncounter[uiType] = uiData;
+ OpenAllDoors();
+ break;
+ case TYPE_BALTHARUS: m_auiEncounter[uiType] = uiData;
+ OpenAllDoors();
+ break;
+ case TYPE_XERESTRASZA: m_auiEncounter[uiType] = uiData;
+ if (uiData == IN_PROGRESS)
+ OpenDoor(m_uiFireFieldGUID);
+ else if (uiData == NOT_STARTED)
+ {
+ CloseDoor(m_uiFireFieldGUID);
+ OpenAllDoors();
+ }
+ else if (uiData == DONE)
+ {
+ OpenAllDoors();
+ if (m_auiEncounter[TYPE_ZARITHIAN] == DONE)
+ {
+ m_auiEncounter[TYPE_EVENT] = 200;
+ m_auiEventTimer = 30000;
+ };
+ }
+ break;
+ case TYPE_ZARITHIAN: m_auiEncounter[uiType] = uiData;
+ if (uiData == DONE)
+ {
+ OpenDoor(m_uiFlameWallsGUID);
+ m_auiEncounter[TYPE_EVENT] = 200;
+ m_auiEventTimer = 30000;
+ }
+ else if (uiData == IN_PROGRESS)
+ CloseDoor(m_uiFlameWallsGUID);
+ else if (uiData == FAIL)
+ OpenDoor(m_uiFlameWallsGUID);
+ break;
+ case TYPE_HALION: m_auiEncounter[uiType] = uiData;
+ if (uiData == IN_PROGRESS)
+ {
+ CloseDoor(m_uiFlameRingGUID);
+ }
+ else
+ {
+ OpenDoor(m_uiFlameRingGUID);
+ }
+ break;
+ case TYPE_HALION_EVENT: m_auiHalionEvent = uiData; uiData = NOT_STARTED; break;
+ case TYPE_EVENT_TIMER: m_auiEventTimer = uiData; uiData = NOT_STARTED; break;
+
+ case DATA_ORB_DIRECTION: m_auiOrbDirection = uiData; uiData = NOT_STARTED; break;
+ case DATA_ORB_N: m_auiOrbNState = uiData; uiData = NOT_STARTED; break;
+ case DATA_ORB_S: m_auiOrbSState = uiData; uiData = NOT_STARTED; break;
+ case TYPE_COUNTER:
+ if (uiData == 0)
+ UpdateWorldState(false,0);
+ else UpdateWorldState(true,uiData);
+ uiData = NOT_STARTED;
+ break;
+ }
+
+ if (uiData == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ strSaveData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ const char* Save()
+ {
+ return strSaveData.c_str();
+ }
+
+ uint32 GetData(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case TYPE_RAGEFIRE: return m_auiEncounter[uiType];
+ case TYPE_BALTHARUS: return m_auiEncounter[uiType];
+ case TYPE_XERESTRASZA: return m_auiEncounter[uiType];
+ case TYPE_ZARITHIAN: return m_auiEncounter[uiType];
+ case TYPE_HALION: return m_auiEncounter[uiType];
+
+ case TYPE_EVENT: return m_auiEncounter[uiType];
+
+ case TYPE_HALION_EVENT: return m_auiHalionEvent;
+
+ case TYPE_EVENT_TIMER: return m_auiEventTimer;
+ case TYPE_EVENT_NPC: switch (m_auiEncounter[TYPE_EVENT])
+ {
+ case 10:
+ case 20:
+ case 30:
+ case 40:
+ case 50:
+ case 60:
+ case 70:
+ case 80:
+ case 90:
+ case 100:
+ case 110:
+ case 200:
+ case 210:
+ return NPC_XERESTRASZA;
+ break;
+ default:
+ break;
+ };
+ return 0;
+
+ case DATA_ORB_DIRECTION: return m_auiOrbDirection;
+ case DATA_ORB_N: return m_auiOrbNState;
+ case DATA_ORB_S: return m_auiOrbSState;
+
+ }
+ return 0;
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case NPC_BALTHARUS: return m_uiBaltharusGUID;
+ case NPC_CLONE: return m_uiCloneGUID;
+ case NPC_ZARITHIAN: return m_uiZarithianGUID;
+ case NPC_RAGEFIRE: return m_uiRagefireGUID;
+ case NPC_HALION_REAL: return m_uiHalion_pGUID;
+ case NPC_HALION_TWILIGHT: return m_uiHalion_tGUID;
+ case NPC_HALION_CONTROL: return m_uiHalionControlGUID;
+ case NPC_XERESTRASZA: return m_uiXerestraszaGUID;
+ case NPC_BALTHARUS_TARGET: return m_uiBaltharusTargetGUID;
+
+ case GO_FLAME_WALLS: return m_uiFlameWallsGUID;
+ case GO_FLAME_RING: return m_uiFlameRingGUID;
+ case GO_FIRE_FIELD: return m_uiFireFieldGUID;
+
+ case GO_HALION_PORTAL_1: return m_uiHalionPortal1GUID;
+ case GO_HALION_PORTAL_2: return m_uiHalionPortal2GUID;
+ case GO_HALION_PORTAL_3: return m_uiHalionPortal3GUID;
+
+ case NPC_SHADOW_PULSAR_N: return m_uiOrbNGUID;
+ case NPC_SHADOW_PULSAR_S: return m_uiOrbSGUID;
+ case NPC_ORB_ROTATION_FOCUS: return m_uiOrbFocusGUID;
+ case NPC_ORB_CARRIER: return m_uiOrbCarrierGUID;
+ }
+ return 0;
+ }
+
+ void Load(const char* chrIn)
+ {
+ if (!chrIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(chrIn);
+
+ std::istringstream loadStream(chrIn);
+
+ for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
+
+ if (m_auiEncounter[i] == IN_PROGRESS
+ || m_auiEncounter[i] == FAIL)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ m_auiEncounter[TYPE_XERESTRASZA] = NOT_STARTED;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ OpenAllDoors();
+ }
+};
+
+InstanceData* GetInstanceData_instance_ruby_sanctum(Map* pMap)
+{
+ return new instance_ruby_sanctum(pMap);
+}
+
+void AddSC_instance_ruby_sanctum()
+{
+ Script* pNewScript;
+ pNewScript = new Script;
+ pNewScript->Name = "instance_ruby_sanctum";
+ pNewScript->GetInstanceData = &GetInstanceData_instance_ruby_sanctum;
+ pNewScript->RegisterSelf();
+}
diff --git a/scripts/northrend/ruby_sanctum/ruby_sanctum.cpp b/scripts/northrend/ruby_sanctum/ruby_sanctum.cpp
new file mode 100644
index 0000000..0e314d9
--- /dev/null
+++ b/scripts/northrend/ruby_sanctum/ruby_sanctum.cpp
@@ -0,0 +1,226 @@
+/* Copyright (C) 2010 /dev/rsa for ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* ScriptData
+SDName: ruby_sanctum mobs
+SD%Complete: 10%
+SDComment: by notagain, corrected by /dev/rsa
+SDCategory: ruby_sanctum
+EndScriptData */
+
+#include "precompiled.h"
+#include "ruby_sanctum.h"
+
+static Locations SpawnLoc[]=
+{
+ {3155.540039f, 342.391998f, 84.596802f}, // 0 - start point
+ {3152.329834f, 359.41757f, 85.301605f}, // 1 - second say
+ {3152.078369f, 383.939178f, 86.337875f}, // 2 - other says and staying
+ {3154.99f, 535.637f, 72.8887f}, // 3 - Halion spawn point
+};
+
+struct MANGOS_DLL_DECL mob_xerestraszaAI : public ScriptedAI
+{
+ mob_xerestraszaAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ uint32 nextEvent;
+ uint32 nextPoint;
+ uint32 UpdateTimer;
+ bool movementstarted;
+ bool onSessionEvent;
+
+ void Reset()
+ {
+ if(!pInstance) return;
+ nextEvent = 0;
+ nextPoint = 0;
+ movementstarted = false;
+ UpdateTimer = 2000;
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ pInstance->SetData(TYPE_XERESTRASZA, NOT_STARTED);
+ m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSpeedRate(MOVE_WALK, 0.8f);
+ m_creature->SetRespawnDelay(7*DAY);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || !movementstarted) return;
+ if (id == nextPoint)
+ {
+ movementstarted = false;
+ pInstance->SetData(TYPE_EVENT,nextEvent);
+ m_creature->GetMotionMaster()->MovementExpired();
+ }
+ }
+
+ void StartMovement(uint32 id, uint32 _nextEvent)
+ {
+ nextPoint = id;
+ nextEvent = _nextEvent;
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
+ pInstance->SetData(TYPE_EVENT,0);
+ movementstarted = true;
+ }
+
+ void AttackStart(Unit *who)
+ {
+ //ignore all attackstart commands
+ return;
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if(!pInstance || !who || who->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (pInstance->GetData(TYPE_BALTHARUS) != DONE
+ || pInstance->GetData(TYPE_XERESTRASZA) != NOT_STARTED) return;
+
+ if(!who->IsWithinDistInMap(m_creature, 60.0f)) return;
+
+ pInstance->SetData(TYPE_XERESTRASZA, IN_PROGRESS);
+ pInstance->SetData(TYPE_EVENT, 30);
+ onSessionEvent = true;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!pInstance) return;
+
+ if (pInstance->GetData(TYPE_EVENT_NPC) == NPC_XERESTRASZA)
+ {
+ UpdateTimer = pInstance->GetData(TYPE_EVENT_TIMER);
+ if (UpdateTimer <= diff)
+ {
+ debug_log("EventMGR: creature %u received signal %u ",m_creature->GetEntry(),pInstance->GetData(TYPE_EVENT));
+ switch (pInstance->GetData(TYPE_EVENT))
+ {
+// Xerestrasza intro
+ case 10:
+ UpdateTimer = 7000;
+ pInstance->SetData(TYPE_EVENT, 20);
+ break;
+ case 20:
+ DoScriptText(-1666000,m_creature);
+ pInstance->SetData(TYPE_EVENT,0);
+ break;
+// Xerestrasza event
+ case 30:
+ m_creature->SetActiveObjectState(true);
+ DoScriptText(-1666001,m_creature);
+ StartMovement(1,40);
+ break;
+ case 40:
+ DoScriptText(-1666002,m_creature);
+ StartMovement(2,50);
+ break;
+ case 50:
+ DoScriptText(-1666003,m_creature);
+ UpdateTimer = 12000;
+ pInstance->SetData(TYPE_EVENT,60);
+ break;
+ case 60:
+ DoScriptText(-1666004,m_creature);
+ UpdateTimer = 12000;
+ pInstance->SetData(TYPE_EVENT,70);
+ break;
+ case 70:
+ DoScriptText(-1666005,m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,80);
+ break;
+ case 80:
+ DoScriptText(-1666006,m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,90);
+ break;
+ case 90:
+ DoScriptText(-1666007,m_creature);
+ UpdateTimer = 10000;
+ pInstance->SetData(TYPE_EVENT,100);
+ break;
+ case 100:
+ DoScriptText(-1666008,m_creature);
+ UpdateTimer = 4000;
+ pInstance->SetData(TYPE_EVENT,110);
+ break;
+ case 110:
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,0);
+ pInstance->SetData(TYPE_XERESTRASZA, DONE);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ m_creature->SetActiveObjectState(false);
+ break;
+// Halion spawn
+ case 200:
+ m_creature->SetActiveObjectState(true);
+ {
+ Creature* pHalion = m_creature->GetMap()->GetCreature(pInstance->GetData64(NPC_HALION_REAL));
+ if (pInstance->GetData(TYPE_BALTHARUS) == DONE &&
+ pInstance->GetData(TYPE_RAGEFIRE) == DONE &&
+ pInstance->GetData(TYPE_XERESTRASZA) == DONE &&
+ pInstance->GetData(TYPE_ZARITHIAN) == DONE &&
+ pInstance->GetData(TYPE_HALION) != DONE)
+ {
+ if (!pHalion)
+ pHalion = m_creature->SummonCreature(NPC_HALION_REAL, SpawnLoc[3].x, SpawnLoc[3].y, SpawnLoc[3].z, 6.23f, TEMPSUMMON_MANUAL_DESPAWN, HOUR*IN_MILLISECONDS);
+ if (pHalion && !pHalion->isAlive())
+ pHalion->Respawn();
+ if (pHalion)
+ pHalion->SetCreatorGuid(ObjectGuid());
+ }
+ }
+ UpdateTimer = 4000;
+ pInstance->SetData(TYPE_EVENT,210);
+ break;
+ case 210:
+ m_creature->SetActiveObjectState(false);
+ UpdateTimer = 2000;
+ pInstance->SetData(TYPE_EVENT,0);
+ break;
+
+ default:
+ break;
+ }
+ } else UpdateTimer -= diff;
+ pInstance->SetData(TYPE_EVENT_TIMER, UpdateTimer);
+ }
+
+ }
+};
+
+CreatureAI* GetAI_mob_xerestrasza(Creature* pCreature)
+{
+ return new mob_xerestraszaAI(pCreature);
+}
+
+void AddSC_ruby_sanctum()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "mob_xerestrasza";
+ newscript->GetAI = &GetAI_mob_xerestrasza;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/ruby_sanctum/ruby_sanctum.h b/scripts/northrend/ruby_sanctum/ruby_sanctum.h
new file mode 100644
index 0000000..fc96765
--- /dev/null
+++ b/scripts/northrend/ruby_sanctum/ruby_sanctum.h
@@ -0,0 +1,71 @@
+/* Copyright (C) 2010 by /dev/rsa for ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_RUBY_SANCTUM_H
+#define DEF_RUBY_SANCTUM_H
+#include "BSW_ai.h"
+
+enum
+{
+ MAX_ENCOUNTERS = 6,
+
+ TYPE_EVENT = 0,
+ TYPE_RAGEFIRE = 1,
+ TYPE_BALTHARUS = 2,
+ TYPE_XERESTRASZA = 3,
+ TYPE_ZARITHIAN = 4,
+ TYPE_HALION = 5,
+
+ TYPE_COUNTER = 6, // for WorldUpdateState
+ TYPE_HALION_EVENT = 7,
+
+ TYPE_EVENT_TIMER = 50,
+ TYPE_EVENT_NPC = 51,
+
+ NPC_HALION_REAL = 39863, // Halion Physical Realm NPC
+ NPC_HALION_TWILIGHT = 40142, // Halion Twilight Realm NPC
+ NPC_HALION_CONTROL = 40146,
+
+ NPC_BALTHARUS = 39751,
+ NPC_CLONE = 39899,
+ NPC_ZARITHIAN = 39746,
+ NPC_RAGEFIRE = 39747,
+
+ NPC_XERESTRASZA = 40429,
+
+ NPC_BALTHARUS_TARGET = 39900,
+ NPC_ZARITHIAN_SPAWN_STALKER = 39794,
+
+ // Orb rotation
+ NPC_SHADOW_PULSAR_N = 40083, //spinning orb N spawn
+ NPC_SHADOW_PULSAR_S = 40100, //spinning orb S spawn
+ NPC_ORB_CARRIER = 40081,
+ NPC_ORB_ROTATION_FOCUS = 40091,
+
+
+ GO_HALION_PORTAL_1 = 202794, //1327 ENTRY
+ GO_HALION_PORTAL_2 = 202795, //1327 ENTRY
+ GO_HALION_PORTAL_3 = 202796, //1327 EXIT
+
+ GO_FIRE_FIELD = 203005,
+ GO_FLAME_WALLS = 203006,
+ GO_FLAME_RING = 203007,
+
+ DATA_EVENT_TIMER = 101,
+ DATA_EVENT = 102,
+
+ DATA_ORB_DIRECTION = 110,
+ DATA_ORB_S = 111,
+ DATA_ORB_N = 112,
+
+};
+
+enum uiWorldStates
+{
+ UPDATE_STATE_UI_COUNT_R = 5049,
+ UPDATE_STATE_UI_COUNT_T = 5050,
+ UPDATE_STATE_UI_SHOW = 5051,
+};
+
+#endif
diff --git a/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp
index b4d6aa1..bf9203e 100644
--- a/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp
+++ b/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp
@@ -188,6 +188,8 @@ struct MANGOS_DLL_DECL boss_ionarAI : public ScriptedAI
if (pSpark->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
pSpark->GetMotionMaster()->MovementExpired();
+ pSpark->SetSpeedRate(MOVE_RUN,2);
+
pSpark->GetMotionMaster()->MovePoint(POINT_CALLBACK, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
}
}
@@ -236,7 +238,7 @@ struct MANGOS_DLL_DECL boss_ionarAI : public ScriptedAI
m_bIsSplitPhase = false;
}
// Lightning effect and restore Ionar
- else if (m_uiSparkAtHomeCount == MAX_SPARKS)
+ else
{
m_creature->SetVisibility(VISIBILITY_ON);
m_creature->CastSpell(m_creature, SPELL_SPARK_DESPAWN, false);
diff --git a/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp
index 9e88b3b..5d56820 100644
--- a/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp
+++ b/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp
@@ -24,6 +24,7 @@ EndScriptData */
#include "precompiled.h"
#include "halls_of_lightning.h"
+
enum
{
SAY_AGGRO = -1602018,
@@ -125,7 +126,7 @@ struct MANGOS_DLL_DECL boss_lokenAI : public ScriptedAI
if (m_bIsAura)
{
// workaround for PULSING_SHOCKWAVE
- /*if (m_uiPulsingShockwave_Timer < uiDiff)
+ if (m_uiPulsingShockwave_Timer < uiDiff)
{
Map *map = m_creature->GetMap();
if (map->IsDungeon())
@@ -144,13 +145,13 @@ struct MANGOS_DLL_DECL boss_lokenAI : public ScriptedAI
if (m_fDist <= 1.0f) // Less than 1 yard
dmg = (m_bIsRegularMode ? 800 : 850); // need to correct damage
else // Further from 1 yard
- dmg = round((m_bIsRegularMode ? 200 : 250) * m_fDist) + (m_bIsRegularMode ? 800 : 850); // need to correct damage
+ dmg = int32((m_bIsRegularMode ? 200 : 250) * m_fDist) + (m_bIsRegularMode ? 800 : 850); // need to correct damage
m_creature->CastCustomSpell(i->getSource(), (m_bIsRegularMode ? 52942 : 59837), &dmg, 0, 0, false);
}
}
m_uiPulsingShockwave_Timer = 2000;
- }else m_uiPulsingShockwave_Timer -= uiDiff;*/
+ }else m_uiPulsingShockwave_Timer -= uiDiff;
}
else
{
diff --git a/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp b/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp
index e4f1444..9aaf055 100644
--- a/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp
+++ b/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp
@@ -329,8 +329,7 @@ bool EffectDummyCreature_npc_volkhan_anvil(Unit* pCaster, uint32 uiSpellId, Spel
if (pCaster->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
pCaster->GetMotionMaster()->MovementExpired();
- ((Creature*)pCaster)->GetMap()->CreatureRelocation((Creature*)pCaster, fX, fY, fZ, pCreatureTarget->GetOrientation());
- ((Creature*)pCaster)->SendMonsterMove(fX, fY, fZ, SPLINETYPE_NORMAL, ((Creature*)pCaster)->GetSplineFlags(), 1);
+ ((Creature*)pCaster)->MonsterMove(fX, fY, fZ, 1);
pCreatureTarget->CastSpell(pCaster, SPELL_TEMPER_DUMMY, false);
diff --git a/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp b/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp
new file mode 100644
index 0000000..7546133
--- /dev/null
+++ b/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp
@@ -0,0 +1,175 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss Krystallus
+SDAuthor: ckegg
+SD%Complete: 0%
+SDComment:
+SDCategory: Halls of Stone
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_halls_of_stone.h"
+
+enum
+{
+ SAY_AGGRO = -1599000,
+ SAY_KILL = -1599001,
+ SAY_DEATH = -1599002,
+ SAY_SHATTER = -1599003,
+
+ SPELL_BOULDER_TOSS = 50843,
+ SPELL_BOULDER_TOSS_H = 59742,
+ SPELL_GROUND_SPIKE = 59750,
+ SPELL_GROUND_SLAM = 50827,
+ SPELL_SHATTER = 50810,
+ SPELL_SHATTER_H = 61546,
+ SPELL_STOMP = 50868,
+ SPELL_STOMP_H = 59744,
+
+};
+
+/*######
+## boss_krystallus
+######*/
+
+struct MANGOS_DLL_DECL boss_krystallusAI : public ScriptedAI
+{
+ boss_krystallusAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bIsRegularMode;
+ bool m_bIsSlam;
+
+ uint32 m_uiToss_Timer;
+ uint32 m_uiSpike_Timer;
+ uint32 m_uiSlam_Timer;
+ uint32 m_uiShatter_Timer;
+ uint32 m_uiStomp_Timer;
+
+ void Reset()
+ {
+ m_bIsSlam = false;
+ m_uiToss_Timer = 3000 + rand()%6000;
+ m_uiSpike_Timer = 9000 + rand()%5000;
+ m_uiSlam_Timer = 15000 + rand()%3000;
+ m_uiStomp_Timer = 20000 + rand()%9000;
+ m_uiShatter_Timer = 0;
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KRYSTALLUS, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ DoScriptText(SAY_AGGRO,m_creature);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KRYSTALLUS, IN_PROGRESS);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ DoScriptText(SAY_KILL, m_creature);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_KRYSTALLUS, DONE);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiToss_Timer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_BOULDER_TOSS_H : SPELL_BOULDER_TOSS);
+ m_uiToss_Timer = 9000 + rand()%6000;
+ }
+ else
+ m_uiToss_Timer -= uiDiff;
+
+ if (m_uiSpike_Timer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_GROUND_SPIKE);
+ m_uiSpike_Timer = 12000 + rand()%5000;
+ }
+ else
+ m_uiSpike_Timer -= uiDiff;
+
+ if (m_uiStomp_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_STOMP_H : SPELL_STOMP);
+ m_uiStomp_Timer = 20000 + rand()%9000;
+ }
+ else
+ m_uiStomp_Timer -= uiDiff;
+
+ if (m_uiSlam_Timer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_GROUND_SLAM);
+ m_bIsSlam = true;
+ m_uiShatter_Timer = 10000;
+ m_uiSlam_Timer = 15000 + rand()%3000;
+ }
+ else
+ m_uiSlam_Timer -= uiDiff;
+
+ if (m_bIsSlam)
+ {
+ if (m_uiShatter_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SHATTER_H : SPELL_SHATTER);
+ m_bIsSlam = false;
+ m_uiShatter_Timer = 0;
+ }
+ else
+ m_uiShatter_Timer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_krystallus(Creature* pCreature)
+{
+ return new boss_krystallusAI (pCreature);
+}
+
+void AddSC_boss_krystallus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_krystallus";
+ newscript->GetAI = &GetAI_boss_krystallus;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp b/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
index 0b28902..ef8072c 100644
--- a/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
+++ b/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -16,13 +16,13 @@
/* ScriptData
SDName: Boss_Maiden_of_Grief
-SD%Complete: 60%
+SD%Complete: 20%
SDComment:
SDCategory: Halls of Stone
EndScriptData */
#include "precompiled.h"
-#include "halls_of_stone.h"
+#include "def_halls_of_stone.h"
enum
{
@@ -34,16 +34,13 @@ enum
SAY_STUN = -1599010,
SAY_DEATH = -1599011,
- SPELL_STORM_OF_GRIEF = 50752,
- SPELL_STORM_OF_GRIEF_H = 59772,
-
- SPELL_SHOCK_OF_SORROW = 50760,
- SPELL_SHOCK_OF_SORROW_H = 59726,
-
+ SPELL_PARTING_SORROW = 59723,
SPELL_PILLAR_OF_WOE = 50761,
SPELL_PILLAR_OF_WOE_H = 59727,
-
- SPELL_PARTING_SORROW = 59723
+ SPELL_SHOCK_OF_SORROW = 50760,
+ SPELL_SHOCK_OF_SORROW_H = 59726,
+ SPELL_STORM_OF_GRIEF = 50752,
+ SPELL_STORM_OF_GRIEF_H = 59772,
};
/*######
@@ -62,25 +59,33 @@ struct MANGOS_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
- uint32 m_uiStormTimer;
- uint32 m_uiShockTimer;
- uint32 m_uiPillarTimer;
+ uint32 m_uiPartingSorrow_Timer;
+ uint32 m_uiPillarWoe_Timer;
+ uint32 m_uiShockSorrow_Timer;
+ uint32 m_uiStorm_Timer;
void Reset()
{
- m_uiStormTimer = 5000;
- m_uiShockTimer = 10000;
- m_uiPillarTimer = 15000;
+ m_uiPartingSorrow_Timer = 9000 + rand()%5000;
+ m_uiPillarWoe_Timer = 3000 + rand()%4000;
+ m_uiStorm_Timer = 10000 + rand()%5000;
+ m_uiShockSorrow_Timer = 20000 + rand()%5000;
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_GRIEF, NOT_STARTED);
}
void Aggro(Unit* pWho)
{
DoScriptText(SAY_AGGRO, m_creature);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_GRIEF, IN_PROGRESS);
}
void KilledUnit(Unit* pVictim)
{
- switch(urand(0, 3))
+ switch(rand()%4)
{
case 0: DoScriptText(SAY_SLAY_1, m_creature); break;
case 1: DoScriptText(SAY_SLAY_2, m_creature); break;
@@ -94,7 +99,7 @@ struct MANGOS_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI
DoScriptText(SAY_DEATH, m_creature);
if (m_pInstance)
- m_pInstance->SetData(TYPE_MAIDEN, DONE);
+ m_pInstance->SetData(TYPE_GRIEF, DONE);
}
void UpdateAI(const uint32 uiDiff)
@@ -102,35 +107,40 @@ struct MANGOS_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
- if (m_uiStormTimer < uiDiff)
+ if (m_uiPartingSorrow_Timer < uiDiff)
{
- if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_STORM_OF_GRIEF : SPELL_STORM_OF_GRIEF_H) == CAST_OK)
- m_uiStormTimer = 20000;
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_PARTING_SORROW);
+ m_uiPartingSorrow_Timer = 12000 + rand()%5000;
}
else
- m_uiStormTimer -= uiDiff;
+ m_uiPartingSorrow_Timer -= uiDiff;
- if (m_uiPillarTimer < uiDiff)
+ if (m_uiPillarWoe_Timer < uiDiff)
{
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
- {
- if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_PILLAR_OF_WOE : SPELL_PILLAR_OF_WOE_H) == CAST_OK)
- m_uiPillarTimer = 10000;
- }
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_PILLAR_OF_WOE_H : SPELL_PILLAR_OF_WOE);
+ m_uiPillarWoe_Timer = 9000 + rand()%4000;
+ }
+ else
+ m_uiPillarWoe_Timer -= uiDiff;
+
+ if (m_uiStorm_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_STORM_OF_GRIEF_H : SPELL_STORM_OF_GRIEF);
+ m_uiStorm_Timer = 20000 + rand()%5000;
}
else
- m_uiPillarTimer -= uiDiff;
+ m_uiStorm_Timer -= uiDiff;
- if (m_uiShockTimer < uiDiff)
+ if (m_uiShockSorrow_Timer < uiDiff)
{
- if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHOCK_OF_SORROW : SPELL_SHOCK_OF_SORROW_H) == CAST_OK)
- {
- DoScriptText(SAY_STUN, m_creature);
- m_uiShockTimer = 35000;
- }
+ DoScriptText(SAY_STUN, m_creature);
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHOCK_OF_SORROW_H : SPELL_SHOCK_OF_SORROW);
+ m_uiShockSorrow_Timer = 20000 + rand()%5000;
}
else
- m_uiShockTimer -= uiDiff;
+ m_uiShockSorrow_Timer -= uiDiff;
DoMeleeAttackIfReady();
}
diff --git a/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp b/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp
index b9f30e9..21a50f2 100644
--- a/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp
+++ b/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -22,47 +22,45 @@ SDCategory: Halls of Stone
EndScriptData */
#include "precompiled.h"
-#include "halls_of_stone.h"
+#include "def_halls_of_stone.h"
enum
{
- SAY_AGGRO = -1599000,
- SAY_SLAY_1 = -1599001,
- SAY_SLAY_2 = -1599002,
- SAY_SLAY_3 = -1599003,
- SAY_DEATH = -1599004,
- EMOTE_GENERIC_FRENZY = -1000002,
-
- SPELL_FRENZY = 28747,
-
- SPELL_CHAIN_LIGHTNING = 50830,
- SPELL_CHAIN_LIGHTNING_H = 59844,
-
- SPELL_STATIC_CHARGE = 50834,
- SPELL_STATIC_CHARGE_H = 59846,
-
- SPELL_LIGHTNING_SHIELD = 50831,
- SPELL_LIGHTNING_SHIELD_H = 59845,
-
- SPELL_LIGHTNING_RING = 50840,
- SPELL_LIGHTNING_RING_H = 59848,
-
- SPELL_SUMMON_IRON_DWARF = 50789, // periodic dummy aura, tick each 30sec or each 20sec in heroic
- SPELL_SUMMON_IRON_DWARF_H = 59860, // left/right 50790,50791
-
- SPELL_SUMMON_IRON_TROGG = 50792, // periodic dummy aura, tick each 10sec or each 7sec in heroic
- SPELL_SUMMON_IRON_TROGG_H = 59859, // left/right 50793,50794
-
- SPELL_SUMMON_MALFORMED_OOZE = 50801, // periodic dummy aura, tick each 5sec or each 3sec in heroic
- SPELL_SUMMON_MALFORMED_OOZE_H = 59858, // left/right 50802,50803
+ SAY_AGGRO = -1599000,
+ SAY_SLAY_1 = -1599001,
+ SAY_SLAY_2 = -1599002,
+ SAY_SLAY_3 = -1599003,
+ SAY_DEATH = -1599004,
+ EMOTE_GENERIC_FRENZY = -1000002,
+
+ SPELL_CHAIN_LIGHTING = 50830,
+ SPELL_CHAIN_LIGHTING_H = 59844,
+ SPELL_FRENZY = 28747,
+ SPELL_LIGHTING_SHIELD = 50831,
+ SPELL_LIGHTING_SHIELD_H = 59845,
+ SPELL_STATIC_CHARGE = 50834, //Periodic Trigger 2s interval, spell =50835
+ SPELL_STATIC_CHARGE_H = 59846, //Periodic Trigger 2s interval, spell =50847
+
+ SPELL_LIGHTING_RING = 51849,
+ SPELL_LIGHTING_RING_H = 59861,
+ SPELL_LIGHTING_RING1 = 50840,
+ SPELL_LIGHTING_RING1_H = 59848,
+
+ NPC_FORGED_IRON_TROGG = 27979,
+ NPC_MALFORMED_OOZE = 27981,
+ NPC_FORGED_IRON_DWARF = 27982,
+};
- SPELL_SUMMON_IRON_SLUDGE = 50747, // instakill TARGET_SCRIPT
- SPELL_IRON_SLUDGE_SPAWN_VISUAL = 50777,
+struct Locations
+{
+ float x, y, z;
+ uint32 id;
+};
- NPC_IRON_TROGG = 27979,
- NPC_IRON_DWARF = 27982,
- NPC_MALFORMED_OOZE = 27981,
- NPC_IRON_SLUDGE = 28165
+static Locations PipeLoc[]=
+{
+ {1295.44f, 734.07f, 200.3f}, // left
+ {1297.7f, 595.6f, 199.9f}, // right
};
/*######
@@ -80,37 +78,46 @@ struct MANGOS_DLL_DECL boss_sjonnirAI : public ScriptedAI
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
+ bool m_bIsFrenzy;
+
+ std::list m_lDwarfGUIDList;
+ uint32 m_uiChainLightning_Timer;
+ uint32 m_uiLightningShield_Timer;
+ uint32 m_uiStaticCharge_Timer;
+ uint32 m_uiLightningRing_Timer;
+ uint32 m_uiSummon_Timer;
+ uint32 m_uiFrenzy_Timer;
void Reset()
{
- if (m_creature->isAlive())
- m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_SHIELD : SPELL_LIGHTNING_SHIELD_H, false);
- }
+ m_bIsFrenzy = false;
- void Aggro(Unit* pWho)
- {
- DoScriptText(SAY_AGGRO, m_creature);
+ m_uiChainLightning_Timer = 3000 + rand()%5000;
+ m_uiLightningShield_Timer = 20000 + rand()%5000;
+ m_uiStaticCharge_Timer = 20000 + rand()%5000;
+ m_uiLightningRing_Timer = 30000 + rand()%5000;
+ m_uiSummon_Timer = 5000;
+ m_uiFrenzy_Timer = 300000;
- m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_SUMMON_IRON_DWARF : SPELL_SUMMON_IRON_DWARF_H, true);
- m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_SUMMON_IRON_TROGG : SPELL_SUMMON_IRON_TROGG_H, true);
- }
+ DespawnDwarf();
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_GRIEF, NOT_STARTED);
+ }
- void JustSummoned(Creature* pSummoned)
+ void Aggro(Unit* pWho)
{
- if (pSummoned->GetEntry() == NPC_IRON_TROGG || pSummoned->GetEntry() == NPC_IRON_DWARF || pSummoned->GetEntry() == NPC_MALFORMED_OOZE)
- {
- float fX, fY, fZ;
- pSummoned->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 10.0f, fX, fY, fZ);
+ DoScriptText(SAY_AGGRO, m_creature);
- pSummoned->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
- pSummoned->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
- }
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_GRIEF, IN_PROGRESS);
+// pSummoned->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+// pSummoned->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
}
void KilledUnit(Unit* pVictim)
{
- switch(urand(0, 2))
+ switch(rand()%3)
{
case 0: DoScriptText(SAY_SLAY_1, m_creature); break;
case 1: DoScriptText(SAY_SLAY_2, m_creature); break;
@@ -121,6 +128,37 @@ struct MANGOS_DLL_DECL boss_sjonnirAI : public ScriptedAI
void JustDied(Unit* pKiller)
{
DoScriptText(SAY_DEATH, m_creature);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_GRIEF, DONE);
+ }
+
+ void DespawnDwarf()
+ {
+ if (m_lDwarfGUIDList.empty())
+ return;
+
+ for(std::list::iterator itr = m_lDwarfGUIDList.begin(); itr != m_lDwarfGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ {
+ if (pTemp->isAlive())
+ pTemp->ForcedDespawn();
+ }
+ }
+
+ m_lDwarfGUIDList.clear();
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ m_lDwarfGUIDList.push_back(pSummoned->GetGUID());
+
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pSummoned->AddThreat(pTarget, 0.0f);
+ pSummoned->AI()->AttackStart(pTarget);
+ }
}
void UpdateAI(const uint32 uiDiff)
@@ -128,6 +166,66 @@ struct MANGOS_DLL_DECL boss_sjonnirAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
+ if (m_uiChainLightning_Timer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTING_H : SPELL_CHAIN_LIGHTING);
+ m_uiChainLightning_Timer = 10000 + rand()%5000;
+ }
+ else
+ m_uiChainLightning_Timer -= uiDiff;
+
+ if (m_uiLightningShield_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTING_SHIELD_H : SPELL_LIGHTING_SHIELD);
+ m_uiLightningShield_Timer = 20000 + rand()%5000;
+ }
+ else
+ m_uiLightningShield_Timer -= uiDiff;
+
+ if (m_uiStaticCharge_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_STATIC_CHARGE_H : SPELL_STATIC_CHARGE);
+ m_uiStaticCharge_Timer = 20000 + rand()%5000;
+ }
+ else
+ m_uiStaticCharge_Timer -= uiDiff;
+
+ if (m_uiLightningRing_Timer < uiDiff)
+ {
+ if (m_creature->IsNonMeleeSpellCasted(false))
+ m_creature->InterruptNonMeleeSpells(false);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTING_RING_H : SPELL_LIGHTING_RING);
+ m_uiLightningRing_Timer = 30000 + rand()%5000;
+ }
+ else
+ m_uiLightningRing_Timer -= uiDiff;
+
+ if (m_uiSummon_Timer < uiDiff)
+ {
+ uint32 SummonPipe = rand()%2;
+ uint32 SummonEntry = 0;
+ switch(rand()%3)
+ {
+ case 0: SummonEntry = NPC_FORGED_IRON_TROGG; break;
+ case 1: SummonEntry = NPC_MALFORMED_OOZE; break;
+ case 2: SummonEntry = NPC_FORGED_IRON_DWARF; break;
+ }
+ m_creature->SummonCreature(SummonEntry, PipeLoc[SummonPipe].x, PipeLoc[SummonPipe].y, PipeLoc[SummonPipe].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ m_uiSummon_Timer = 20000;
+ }
+ else
+ m_uiSummon_Timer -= uiDiff;
+
+ if (!m_bIsFrenzy && m_uiFrenzy_Timer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_FRENZY);
+ m_bIsFrenzy = true;
+ m_uiFrenzy_Timer = 0;
+ }
+ else
+ m_uiFrenzy_Timer -= uiDiff;
+
DoMeleeAttackIfReady();
}
};
diff --git a/scripts/northrend/ulduar/halls_of_stone/def_halls_of_stone.h b/scripts/northrend/ulduar/halls_of_stone/def_halls_of_stone.h
new file mode 100644
index 0000000..1b06148
--- /dev/null
+++ b/scripts/northrend/ulduar/halls_of_stone/def_halls_of_stone.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_HALLS_OF_STONE_H
+#define DEF_HALLS_OF_STONE_H
+
+enum
+{
+ MAX_ENCOUNTER = 4,
+
+ DATA_KRYSTALLUS = 1,
+ DATA_GRIEF = 2,
+ DATA_BRANN = 3,
+ DATA_SJONNIR = 4,
+
+ DATA_KADDRAK = 5,
+ DATA_ABEDNEUM = 6,
+ DATA_MARNAK = 7,
+
+ DATA_GO_TRIBUNAL_CONSOLE = 8,
+ DATA_GO_SKY_FLOOR = 9,
+ DATA_GO_KADDRAK = 10,
+ DATA_GO_ABEDNEUM = 11,
+ DATA_GO_MARNAK = 12,
+
+ TYPE_KRYSTALLUS = 20,
+ TYPE_GRIEF = 21,
+ TYPE_BRANN = 22,
+ TYPE_SJONNIR = 23,
+
+ NPC_KRYSTALLUS = 27977,
+ NPC_GRIEF = 27975,
+ NPC_BRANN = 28070,
+ NPC_SJONNIR = 27978,
+
+ NPC_KADDRAK = 30898, // left
+ NPC_ABEDNEUM = 30899, // middle
+ NPC_MARNAK = 30897, // right
+
+ GO_GRIEF_DOOR = 191292,
+ GO_BRANN_DOOR = 191293,
+ GO_SJONNIR_DOOR = 191296,
+
+ GO_KADDRAK = 191671, // left
+ GO_ABEDNEUM = 191669, // middle
+ GO_MARNAK = 191670, // right
+
+ GO_TRIBUNAL_CONSOLE = 193907,
+ GO_TRIBUNAL_CHEST = 190586,
+ GO_TRIBUNAL_CHEST_H = 193996,
+ GO_TRIBUNAL_SKY_FLOOR = 191527,
+};
+
+#endif
diff --git a/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp b/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp
index 8731713..0f733c9 100644
--- a/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp
+++ b/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -22,8 +22,8 @@ SDCategory: Halls of Stone
EndScriptData */
#include "precompiled.h"
-#include "halls_of_stone.h"
#include "escort_ai.h"
+#include "def_halls_of_stone.h"
enum
{
@@ -91,12 +91,180 @@ enum
SAY_ENTRANCE_MEET = -1599064,
TEXT_ID_START = 13100,
- TEXT_ID_PROGRESS = 13101
+ TEXT_ID_PROGRESS = 13101,
+
+ NPC_TRIBUNAL_OF_THE_AGES = 28234,
+ NPC_BRANN_BRONZEBEARD = 28070,
+ SPELL_STEALTH = 58506,
+
+ // KADDRAK
+ SPELL_GLARE_OF_THE_TRIBUNAL = 50988,
+ SPELL_GLARE_OF_THE_TRIBUNAL_H = 59870,
+
+ // MARNAK
+ SPELL_DARK_MATTER = 51012,
+ SPELL_DARK_MATTER_H = 59868,
+ NPC_DARK_MATTER_TARGET = 28237,
+
+ // ABEDNEUM
+ SPELL_SEARING_GAZE = 51136,
+ SPELL_SEARING_GAZE_H = 59867,
+ NPC_SEARING_GAZE_TARGET = 28265,
+
+ NPC_DARK_RUNE_PROTECTOR = 27983,
+ NPC_DARK_RUNE_STORMCALLER = 27984,
+ NPC_IRON_GOLEM_CUSTODIAN = 27985,
+
+ QUEST_HALLS_OF_STONE = 13207,
};
#define GOSSIP_ITEM_START "Brann, it would be our honor!"
#define GOSSIP_ITEM_PROGRESS "Let's move Brann, enough of the history lessons!"
+struct Locations
+{
+ float x, y, z;
+ uint32 id;
+};
+
+static Locations SpawnLoc[]=
+{
+ {946.992f, 397.016f, 208.374f},
+ {960.748f, 382.944f, 208.374f},
+};
+
+
+/*######
+## mob_tribuna_controller
+######*/
+
+struct MANGOS_DLL_DECL mob_tribuna_controllerAI : public ScriptedAI
+{
+ mob_tribuna_controllerAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ std::list m_lKaddrakGUIDList;
+ //std::list m_lMarnakGUIDList;
+ //std::list m_lAbedneumGUIDList;
+
+ bool m_bIsActivateKaddrak;
+ bool m_bIsActivateMarnak;
+ bool m_bIsActivateAbedneum;
+
+ uint32 m_uiKaddrak_Encounter_timer;
+ uint32 m_uiMarnak_Encounter_timer;
+ uint32 m_uiAbedneum_Encounter_timer;
+
+ void Reset()
+ {
+ m_bIsActivateKaddrak = false;
+ m_bIsActivateMarnak = false;
+ m_bIsActivateAbedneum = false;
+
+ m_uiKaddrak_Encounter_timer = 1500;
+ m_uiMarnak_Encounter_timer = 10000;
+ m_uiAbedneum_Encounter_timer = 10000;
+
+ m_lKaddrakGUIDList.clear();
+ //m_lMarnakGUIDList.clear();
+ //m_lAbedneumGUIDList.clear();
+ }
+
+ void UpdateFacesList()
+ {
+ GetCreatureListWithEntryInGrid(m_lKaddrakGUIDList, m_creature, NPC_KADDRAK, 50.0f);
+ if (!m_lKaddrakGUIDList.empty())
+ {
+ uint32 uiPositionCounter = 0;
+ for(std::list::iterator itr = m_lKaddrakGUIDList.begin(); itr != m_lKaddrakGUIDList.end(); ++itr)
+ {
+ if (!(*itr)) continue;
+
+ if (Creature* c = (Creature *)(*itr))
+ {
+ if (c->isAlive())
+ {
+ if (uiPositionCounter == 0)
+ {
+ c->GetMap()->CreatureRelocation((*itr), 927.265f, 333.200f, 218.780f, (*itr)->GetOrientation());
+ c->MonsterMove(927.265f, 333.200f, 218.780f, 1);
+ }
+ else
+ {
+ c->GetMap()->CreatureRelocation((*itr), 921.745f, 328.076f, 218.780f, (*itr)->GetOrientation());
+ c->MonsterMove(921.745f, 328.076f, 218.780f, 1);
+ }
+ }
+ ++uiPositionCounter;
+ }
+ }
+ }
+ //GetCreatureListWithEntryInGrid(m_lMarnakGUIDList, m_creature, NPC_MARNAK, 50.0f);
+ //GetCreatureListWithEntryInGrid(m_lAbedneumGUIDList, m_creature, NPC_ABEDNEUM, 50.0f);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_bIsActivateKaddrak)
+ {
+ if (m_uiKaddrak_Encounter_timer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ if (!m_lKaddrakGUIDList.empty())
+ for(std::list::iterator itr = m_lKaddrakGUIDList.begin(); itr != m_lKaddrakGUIDList.end(); ++itr)
+ if ((*itr)->isAlive())
+ (*itr)->CastSpell(pTarget, m_bIsRegularMode ? SPELL_GLARE_OF_THE_TRIBUNAL_H : SPELL_GLARE_OF_THE_TRIBUNAL, true);
+
+ m_uiKaddrak_Encounter_timer = 1500;
+ }
+ else
+ m_uiKaddrak_Encounter_timer -= uiDiff;
+ }
+ if (m_bIsActivateMarnak)
+ {
+ if (m_uiMarnak_Encounter_timer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ if (Creature* pTemp = m_creature->SummonCreature(NPC_DARK_MATTER_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000))
+ {
+ pTemp->SetDisplayId(11686);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->CastSpell(pTarget, m_bIsRegularMode ? SPELL_DARK_MATTER_H : SPELL_DARK_MATTER, true);
+ }
+
+ m_uiMarnak_Encounter_timer = 30000 + rand()%1000;
+ }
+ else
+ m_uiMarnak_Encounter_timer -= uiDiff;
+ }
+ if (m_bIsActivateAbedneum)
+ {
+ if (m_uiAbedneum_Encounter_timer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ if (Creature* pTemp = m_creature->SummonCreature(NPC_SEARING_GAZE_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000))
+ {
+ pTemp->SetDisplayId(11686);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->CastSpell(pTemp, m_bIsRegularMode ? SPELL_SEARING_GAZE_H : SPELL_SEARING_GAZE, true);
+ }
+
+ m_uiAbedneum_Encounter_timer = 30000 + rand()%1000;
+ }
+ else
+ m_uiAbedneum_Encounter_timer -= uiDiff;
+ }
+ }
+};
+
/*######
## npc_brann_hos
######*/
@@ -112,18 +280,87 @@ struct MANGOS_DLL_DECL npc_brann_hosAI : public npc_escortAI
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
+ bool m_bIsBattle;
+ bool m_bIsLowHP;
+
+ uint32 m_uiStep;
+ uint32 m_uiPhase_timer;
+
+ uint64 m_uiControllerGUID;
+ std::list m_lDwarfGUIDList;
void Reset()
{
+ if (!HasEscortState(STATE_ESCORT_ESCORTING))
+ {
+ m_bIsLowHP = false;
+ m_bIsBattle = false;
+
+ m_uiStep = 0;
+ m_uiPhase_timer = 0;
+
+ m_uiControllerGUID = 0;
+
+ DespawnDwarf();
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_BRANN, NOT_STARTED);
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (!m_bIsBattle)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho, 0.0f);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho);
+ }
}
void WaypointReached(uint32 uiPointId)
{
+ switch(uiPointId)
+ {
+ case 7:
+ if (Creature* pCreature = GetClosestCreatureWithEntry(m_creature, NPC_TRIBUNAL_OF_THE_AGES, 100.0f))
+ {
+ if (!pCreature->isAlive())
+ pCreature->Respawn();
+ ((mob_tribuna_controllerAI*)pCreature->AI())->UpdateFacesList();
+ m_uiControllerGUID = pCreature->GetGUID();
+ }
+ break;
+ case 13:
+ DoScriptText(SAY_EVENT_INTRO_1, m_creature);
+ SetEscortPaused(true);
+ SetRun(true);
+ JumpToNextStep(20000);
+ break;
+ case 17:
+ DoScriptText(SAY_EVENT_INTRO_2, m_creature);
+ if (m_pInstance)
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_TRIBUNAL_CONSOLE));
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ SetEscortPaused(true);
+ JumpToNextStep(8500);
+ break;
+ case 18:
+ SetEscortPaused(true);
+ break;
+ }
}
void KilledUnit(Unit* pVictim)
{
- switch(urand(0, 2))
+ switch(rand()%3)
{
case 0: DoScriptText(SAY_KILL_1, m_creature); break;
case 1: DoScriptText(SAY_KILL_2, m_creature); break;
@@ -136,23 +373,367 @@ struct MANGOS_DLL_DECL npc_brann_hosAI : public npc_escortAI
DoScriptText(SAY_DEATH, m_creature);
}
- void UpdateEscortAI(const uint32 uiDiff)
+ void DespawnDwarf()
{
- if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ if (m_lDwarfGUIDList.empty())
return;
- DoMeleeAttackIfReady();
+ for(std::list::iterator itr = m_lDwarfGUIDList.begin(); itr != m_lDwarfGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ {
+ if (pTemp->isAlive())
+ pTemp->ForcedDespawn();
+ }
+ }
+
+ m_lDwarfGUIDList.clear();
+ }
+
+ void SpawnDwarf(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case 1:
+ {
+ uint32 uiSpawnNumber = (m_bIsRegularMode ? 3 : 2);
+ for (uint8 i = 0; i < uiSpawnNumber; ++i)
+ m_creature->SummonCreature(NPC_DARK_RUNE_PROTECTOR, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ m_creature->SummonCreature(NPC_DARK_RUNE_STORMCALLER, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ break;
+ }
+ case 2:
+ for (uint8 i = 0; i < 2; ++i)
+ m_creature->SummonCreature(NPC_DARK_RUNE_STORMCALLER, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ break;
+ case 3:
+ m_creature->SummonCreature(NPC_IRON_GOLEM_CUSTODIAN, SpawnLoc[1].x, SpawnLoc[1].y, SpawnLoc[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ break;
+ }
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ m_lDwarfGUIDList.push_back(pSummoned->GetGUID());
+ pSummoned->AddThreat(m_creature, 0.0f);
+ pSummoned->AI()->AttackStart(m_creature);
+ }
+
+ void JumpToNextStep(uint32 uiTimer)
+ {
+ m_uiPhase_timer = uiTimer;
+ m_uiStep++;
+ }
+
+ void UpdateEscortAI(const uint32 uiDiff)
+ {
+ if (m_uiPhase_timer < uiDiff)
+ {
+ switch(m_uiStep)
+ {
+ case 0: // unused
+ break;
+ case 1:
+ if (m_pInstance)
+ {
+ if (m_pInstance->GetData(TYPE_BRANN) != NOT_STARTED)
+ return;
+
+ m_pInstance->SetData(TYPE_BRANN, IN_PROGRESS);
+ }
+ m_bIsBattle = false;
+ DoScriptText(SAY_ESCORT_START, m_creature);
+ JumpToNextStep(0);
+ break;
+ case 3:
+ SetEscortPaused(false);
+ JumpToNextStep(0);
+ break;
+ case 5:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_INTRO_3_ABED, pTemp);
+ JumpToNextStep(8500);
+ break;
+ case 6:
+ DoScriptText(SAY_EVENT_A_1, m_creature);
+ JumpToNextStep(6500);
+ break;
+ case 7:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_A_2_KADD, pTemp);
+ JumpToNextStep(12500);
+ break;
+ case 8:
+ DoScriptText(SAY_EVENT_A_3, m_creature);
+ if (m_pInstance)
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_KADDRAK));
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID))
+ ((mob_tribuna_controllerAI*)pTemp->AI())->m_bIsActivateKaddrak = true;
+ JumpToNextStep(5000);
+ break;
+ case 9:
+ SpawnDwarf(1);
+ JumpToNextStep(20000);
+ break;
+ case 10:
+ DoScriptText(SAY_EVENT_B_1, m_creature);
+ JumpToNextStep(6000);
+ break;
+ case 11:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_B_2_MARN, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(20000);
+ break;
+ case 12:
+ DoScriptText(SAY_EVENT_B_3, m_creature);
+ if (m_pInstance)
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_MARNAK));
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID))
+ ((mob_tribuna_controllerAI*)pTemp->AI())->m_bIsActivateMarnak = true;
+ JumpToNextStep(10000);
+ break;
+ case 13:
+ SpawnDwarf(1);
+ JumpToNextStep(10000);
+ break;
+ case 14:
+ SpawnDwarf(2);
+ JumpToNextStep(20000);
+ break;
+ case 15:
+ DoScriptText(SAY_EVENT_C_1, m_creature);
+ SpawnDwarf(1);
+ JumpToNextStep(10000);
+ break;
+ case 16:
+ SpawnDwarf(2);
+ JumpToNextStep(20000);
+ break;
+ case 17:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_C_2_ABED, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(20000);
+ break;
+ case 18:
+ DoScriptText(SAY_EVENT_C_3, m_creature);
+ if (m_pInstance)
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_ABEDNEUM));
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID))
+ ((mob_tribuna_controllerAI*)pTemp->AI())->m_bIsActivateAbedneum = true;
+ JumpToNextStep(5000);
+ break;
+ case 19:
+ SpawnDwarf(2);
+ JumpToNextStep(10000);
+ break;
+ case 20:
+ SpawnDwarf(1);
+ JumpToNextStep(15000);
+ break;
+ case 21:
+ DoScriptText(SAY_EVENT_D_1, m_creature);
+ SpawnDwarf(3);
+ JumpToNextStep(20000);
+ break;
+ case 22:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_D_2_ABED, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(5000);
+ break;
+ case 23:
+ SpawnDwarf(2);
+ JumpToNextStep(15000);
+ break;
+ case 24:
+ DoScriptText(SAY_EVENT_D_3, m_creature);
+ SpawnDwarf(3);
+ JumpToNextStep(5000);
+ break;
+ case 25:
+ SpawnDwarf(1);
+ JumpToNextStep(5000);
+ break;
+ case 26:
+ SpawnDwarf(2);
+ JumpToNextStep(10000);
+ break;
+ case 27:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_D_4_ABED, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(10000);
+ break;
+ case 28:
+ DoScriptText(SAY_EVENT_END_01, m_creature);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ if (m_pInstance)
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_SKY_FLOOR));
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_uiControllerGUID))
+ pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_bIsBattle = true;
+ SetEscortPaused(false);
+ JumpToNextStep(3500);
+ break;
+ case 29:
+ DoScriptText(SAY_EVENT_END_02, m_creature);
+ JumpToNextStep(3500);
+ break;
+ case 30:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_03_ABED, pTemp);
+ JumpToNextStep(4500);
+ break;
+ case 31:
+ DoScriptText(SAY_EVENT_END_04, m_creature);
+ JumpToNextStep(6500);
+ break;
+ case 32:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_05_ABED, pTemp);
+ JumpToNextStep(6500);
+ break;
+ case 33:
+ DoScriptText(SAY_EVENT_END_06, m_creature);
+ JumpToNextStep(2500);
+ break;
+ case 34:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_07_ABED, pTemp);
+ JumpToNextStep(10500);
+ break;
+ case 35:
+ DoScriptText(SAY_EVENT_END_08, m_creature);
+ JumpToNextStep(4500);
+ break;
+ case 36:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_END_09_KADD, pTemp);
+ JumpToNextStep(7500);
+ break;
+ case 37:
+ DoScriptText(SAY_EVENT_END_10, m_creature);
+ JumpToNextStep(2500);
+ break;
+ case 38:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_END_11_KADD, pTemp);
+ JumpToNextStep(10500);
+ break;
+ case 39:
+ DoScriptText(SAY_EVENT_END_12, m_creature);
+ JumpToNextStep(2500);
+ break;
+ case 40:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_END_13_KADD, pTemp);
+ JumpToNextStep(9500);
+ break;
+ case 41:
+ DoScriptText(SAY_EVENT_END_14, m_creature);
+ JumpToNextStep(5500);
+ break;
+ case 42:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_END_15_MARN, pTemp);
+ JumpToNextStep(3500);
+ break;
+ case 43:
+ DoScriptText(SAY_EVENT_END_16, m_creature);
+ JumpToNextStep(3500);
+ break;
+ case 44:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_END_17_MARN, pTemp);
+ JumpToNextStep(11500);
+ break;
+ case 45:
+ DoScriptText(SAY_EVENT_END_18, m_creature);
+ JumpToNextStep(10500);
+ break;
+ case 46:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_END_19_MARN, pTemp);
+ JumpToNextStep(2500);
+ break;
+ case 47:
+ DoScriptText(SAY_EVENT_END_20, m_creature);
+ JumpToNextStep(4500);
+ break;
+ case 48:
+ if (m_pInstance)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_21_ABED, pTemp);
+ JumpToNextStep(3500);
+ break;
+ case 49:
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_KADDRAK));
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_MARNAK));
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_ABEDNEUM));
+ m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(DATA_GO_SKY_FLOOR));
+ m_pInstance->SetData(TYPE_BRANN, DONE);
+ }
+
+ Player* pPlayer = GetPlayerForEscort();
+ if (pPlayer)
+ pPlayer->GroupEventHappens(QUEST_HALLS_OF_STONE, m_creature);
+
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+
+ JumpToNextStep(180000);
+ break;
+ }
+ case 50:
+ SetEscortPaused(false);
+ break;
+ }
+ }
+ else m_uiPhase_timer -= uiDiff;
+
+ if (!m_bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 30)
+ {
+ DoScriptText(SAY_LOW_HEALTH, m_creature);
+ m_bIsLowHP = true;
+ }
+ else if (m_bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 30)
+ m_bIsLowHP = false;
}
};
bool GossipHello_npc_brann_hos(Player* pPlayer, Creature* pCreature)
{
+ ScriptedInstance* m_pInstance;
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
- pPlayer->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID());
+if (m_pInstance->GetData(TYPE_BRANN) != DONE)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID());
+
//pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_PROGRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
//pPlayer->SEND_GOSSIP_MENU(TEXT_ID_PROGRESS, pCreature->GetGUID());
return true;
@@ -161,7 +742,11 @@ bool GossipHello_npc_brann_hos(Player* pPlayer, Creature* pCreature)
bool GossipSelect_npc_brann_hos(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1 || uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
pPlayer->CLOSE_GOSSIP_MENU();
+ ((npc_brann_hosAI*)pCreature->AI())->m_uiStep = 1;
+ ((npc_brann_hosAI*)pCreature->AI())->Start(false, pPlayer->GetGUID());
+ }
return true;
}
@@ -171,14 +756,24 @@ CreatureAI* GetAI_npc_brann_hos(Creature* pCreature)
return new npc_brann_hosAI(pCreature);
}
+CreatureAI* GetAI_mob_tribuna_controller(Creature* pCreature)
+{
+ return new mob_tribuna_controllerAI (pCreature);
+}
+
void AddSC_halls_of_stone()
{
- Script* pNewScript;
-
- pNewScript = new Script;
- pNewScript->Name = "npc_brann_hos";
- pNewScript->GetAI = &GetAI_npc_brann_hos;
- pNewScript->pGossipHello = &GossipHello_npc_brann_hos;
- pNewScript->pGossipSelect = &GossipSelect_npc_brann_hos;
- pNewScript->RegisterSelf();
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_brann_hos";
+ newscript->GetAI = &GetAI_npc_brann_hos;
+ newscript->pGossipHello = &GossipHello_npc_brann_hos;
+ newscript->pGossipSelect = &GossipSelect_npc_brann_hos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_tribuna_controller";
+ newscript->GetAI = &GetAI_mob_tribuna_controller;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp b/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp
index 27ba40f..31ee069 100644
--- a/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp
+++ b/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -16,62 +16,108 @@
/* ScriptData
SDName: Instance_Halls_of_Stone
-SD%Complete: 10%
+SD%Complete: 0%
SDComment:
SDCategory: Halls of Stone
EndScriptData */
#include "precompiled.h"
-#include "halls_of_stone.h"
+#include "def_halls_of_stone.h"
+
+/* Halls of Lightning encounters:
+0 - Krystallus
+1 - Maiden of Grief
+2 - Brann Bronzebeard
+3 - Sjonnir The Ironshaper
+*/
struct MANGOS_DLL_DECL instance_halls_of_stone : public ScriptedInstance
{
- instance_halls_of_stone(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+ instance_halls_of_stone(Map* pMap) : ScriptedInstance(pMap) {
+ Regular = pMap->IsRegularDifficulty();
+ Initialize();
+ };
uint32 m_auiEncounter[MAX_ENCOUNTER];
+ bool Regular;
+ std::string strSaveData;
+ uint64 m_uiKrystallusGUID;
+ uint64 m_uiGriefGUID;
uint64 m_uiBrannGUID;
+ uint64 m_uiSjonnirGUID;
+
uint64 m_uiKaddrakGUID;
uint64 m_uiAbedneumGUID;
uint64 m_uiMarnakGUID;
+ uint64 m_uiGriefDoorGUID;
+ uint64 m_uiBrannDoorGUID;
uint64 m_uiSjonnirDoorGUID;
- uint64 m_uiTribunalDoorGUID;
- uint64 m_uiTribunalChestGUID;
- uint64 m_uiTribunalHeadRightGUID;
- uint64 m_uiTribunalHeadCenterGUID;
- uint64 m_uiTribunalHeadLeftGUID;
- uint64 m_uiTribunalConsoleGUID;
- uint64 m_uiTribunalFloorGUID;
- uint64 m_uiSjonnirConsoleGUID;
+
+ uint64 m_uiGoTribunalConsoleGUID;
+ uint64 m_uiGoTribunalChestGUID;
+ uint64 m_uiGoTribunalSkyFloorGUID;
+ uint64 m_uiGoKaddrakGUID;
+ uint64 m_uiGoAbedneumGUID;
+ uint64 m_uiGoMarnakGUID;
+
+ void OpenDoor(uint64 guid)
+ {
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_ACTIVE);
+ }
+
+ void CloseDoor(uint64 guid)
+ {
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_READY);
+ }
void Initialize()
{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
-
- m_uiBrannGUID = 0;
- m_uiKaddrakGUID = 0;
- m_uiAbedneumGUID = 0;
- m_uiMarnakGUID = 0;
-
- m_uiSjonnirDoorGUID = 0;
- m_uiTribunalDoorGUID = 0;
- m_uiTribunalChestGUID = 0;
- m_uiTribunalHeadRightGUID = 0;
- m_uiTribunalHeadCenterGUID = 0;
- m_uiTribunalHeadLeftGUID = 0;
- m_uiTribunalConsoleGUID = 0;
- m_uiTribunalFloorGUID = 0;
- m_uiSjonnirConsoleGUID = 0;
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ m_auiEncounter[i]=NOT_STARTED;
+
+ m_uiKrystallusGUID = 0;
+ m_uiGriefGUID = 0;
+ m_uiBrannGUID = 0;
+ m_uiSjonnirGUID = 0;
+
+ m_uiKaddrakGUID = 0;
+ m_uiAbedneumGUID = 0;
+ m_uiMarnakGUID = 0;
+
+ m_uiGriefDoorGUID = 0;
+ m_uiBrannDoorGUID = 0;
+ m_uiSjonnirDoorGUID = 0;
+
+ m_uiGoTribunalConsoleGUID = 0;
+ m_uiGoTribunalChestGUID = 0;
+ m_uiGoTribunalSkyFloorGUID = 0;
+ m_uiGoKaddrakGUID = 0;
+ m_uiGoAbedneumGUID = 0;
+ m_uiGoMarnakGUID = 0;
}
void OnCreatureCreate(Creature* pCreature)
{
switch(pCreature->GetEntry())
{
+ case NPC_KRYSTALLUS:
+ m_uiKrystallusGUID = pCreature->GetGUID();
+ break;
+ case NPC_GRIEF:
+ m_uiGriefGUID = pCreature->GetGUID();
+ break;
case NPC_BRANN:
m_uiBrannGUID = pCreature->GetGUID();
break;
+ case NPC_SJONNIR:
+ m_uiSjonnirGUID = pCreature->GetGUID();
+ break;
case NPC_KADDRAK:
m_uiKaddrakGUID = pCreature->GetGUID();
break;
@@ -88,67 +134,114 @@ struct MANGOS_DLL_DECL instance_halls_of_stone : public ScriptedInstance
{
switch(pGo->GetEntry())
{
- case GO_DOOR_SJONNIR:
+ case GO_GRIEF_DOOR:
+ m_uiGriefDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[0] != DONE)
+ CloseDoor(m_uiGriefDoorGUID);
+ else OpenDoor(m_uiGriefDoorGUID);
+ break;
+ case GO_BRANN_DOOR:
+ m_uiBrannDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[1] != DONE)
+ CloseDoor(m_uiBrannDoorGUID);
+ else OpenDoor(m_uiBrannDoorGUID);
+ break;
+ case GO_SJONNIR_DOOR:
m_uiSjonnirDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[2] != DONE)
+ CloseDoor(m_uiSjonnirDoorGUID);
+ else OpenDoor(m_uiSjonnirDoorGUID);
break;
- case GO_DOOR_TRIBUNAL:
- m_uiTribunalDoorGUID = pGo->GetGUID();
+ case GO_TRIBUNAL_CONSOLE:
+ m_uiGoTribunalConsoleGUID = pGo->GetGUID();
break;
case GO_TRIBUNAL_CHEST:
- case GO_TRIBUNAL_CHEST_H:
- m_uiTribunalChestGUID = pGo->GetGUID();
- break;
- case GO_TRIBUNAL_HEAD_RIGHT:
- m_uiTribunalHeadRightGUID = pGo->GetGUID();
+ if (Regular) m_uiGoTribunalChestGUID = pGo->GetGUID();
break;
- case GO_TRIBUNAL_HEAD_CENTER:
- m_uiTribunalHeadCenterGUID = pGo->GetGUID();
+ case GO_TRIBUNAL_CHEST_H:
+ if (!Regular) m_uiGoTribunalChestGUID = pGo->GetGUID();
break;
- case GO_TRIBUNAL_HEAD_LEFT:
- m_uiTribunalHeadLeftGUID = pGo->GetGUID();
+ case GO_TRIBUNAL_SKY_FLOOR:
+ m_uiGoTribunalSkyFloorGUID = pGo->GetGUID();
break;
- case GO_TRIBUNAL_CONSOLE:
- m_uiTribunalConsoleGUID = pGo->GetGUID();
+ case GO_KADDRAK:
+ m_uiGoKaddrakGUID = pGo->GetGUID();
break;
- case GO_TRIBUNAL_FLOOR:
- m_uiTribunalFloorGUID = pGo->GetGUID();
+ case GO_ABEDNEUM:
+ m_uiGoAbedneumGUID = pGo->GetGUID();
break;
- case GO_SJONNIR_CONSOLE:
- m_uiSjonnirConsoleGUID = pGo->GetGUID();
+ case GO_MARNAK:
+ m_uiGoMarnakGUID = pGo->GetGUID();
break;
}
}
+ void OnPlayerEnter(Unit* pPlayer)
+ {
+ if (m_auiEncounter[0] != DONE)
+ CloseDoor(m_uiGriefDoorGUID);
+ else OpenDoor(m_uiGriefDoorGUID);
+ if (m_auiEncounter[1] != DONE)
+ CloseDoor(m_uiBrannDoorGUID);
+ else OpenDoor(m_uiBrannDoorGUID);
+ if (m_auiEncounter[2] != DONE)
+ CloseDoor(m_uiSjonnirDoorGUID);
+ else OpenDoor(m_uiSjonnirDoorGUID);
+ }
+
void SetData(uint32 uiType, uint32 uiData)
{
switch(uiType)
{
- case TYPE_TRIBUNAL:
- m_auiEncounter[0] = uiData;
+ case TYPE_KRYSTALLUS:
if (uiData == DONE)
- DoRespawnGameObject(m_uiTribunalChestGUID);
+ OpenDoor(m_uiGriefDoorGUID);
+ m_auiEncounter[0] = uiData;
break;
- case TYPE_MAIDEN:
+ case TYPE_GRIEF:
+ if (uiData == DONE)
+ OpenDoor(m_uiBrannDoorGUID);
m_auiEncounter[1] = uiData;
break;
- case TYPE_KRYSTALLUS:
+ case TYPE_BRANN:
+ if (uiData == DONE)
+ {
+ OpenDoor(m_uiSjonnirDoorGUID);
+ DoRespawnGameObject(m_uiGoTribunalChestGUID);
+ OpenDoor(m_uiGoTribunalChestGUID);
+ }
m_auiEncounter[2] = uiData;
break;
case TYPE_SJONNIR:
m_auiEncounter[3] = uiData;
break;
}
+ if (uiData == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ saveStream << m_auiEncounter[i] << " ";
+
+ strSaveData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+
}
uint32 GetData(uint32 uiType)
{
switch(uiType)
{
- case TYPE_TRIBUNAL:
+ case TYPE_KRYSTALLUS:
return m_auiEncounter[0];
- case TYPE_MAIDEN:
+ case TYPE_GRIEF:
return m_auiEncounter[1];
- case TYPE_KRYSTALLUS:
+ case TYPE_BRANN:
return m_auiEncounter[2];
case TYPE_SJONNIR:
return m_auiEncounter[3];
@@ -160,36 +253,62 @@ struct MANGOS_DLL_DECL instance_halls_of_stone : public ScriptedInstance
{
switch(uiData)
{
- case NPC_BRANN:
+ case DATA_KRYSTALLUS:
+ return m_uiKrystallusGUID;
+ case DATA_GRIEF:
+ return m_uiGriefGUID;
+ case DATA_BRANN:
return m_uiBrannGUID;
- case NPC_KADDRAK:
+ case DATA_SJONNIR:
+ return m_uiSjonnirGUID;
+ case DATA_KADDRAK:
return m_uiKaddrakGUID;
- case NPC_ABEDNEUM:
+ case DATA_ABEDNEUM:
return m_uiAbedneumGUID;
- case NPC_MARNAK:
+ case DATA_MARNAK:
return m_uiMarnakGUID;
- case GO_DOOR_SJONNIR:
- return m_uiSjonnirDoorGUID;
- case GO_DOOR_TRIBUNAL:
- return m_uiTribunalDoorGUID;
- case GO_TRIBUNAL_CHEST:
- case GO_TRIBUNAL_CHEST_H:
- return m_uiTribunalChestGUID;
- case GO_TRIBUNAL_HEAD_RIGHT:
- return m_uiTribunalHeadRightGUID;
- case GO_TRIBUNAL_HEAD_CENTER:
- return m_uiTribunalHeadCenterGUID;
- case GO_TRIBUNAL_HEAD_LEFT:
- return m_uiTribunalHeadLeftGUID;
- case GO_TRIBUNAL_CONSOLE:
- return m_uiTribunalConsoleGUID;
- case GO_TRIBUNAL_FLOOR:
- return m_uiTribunalFloorGUID;
- case GO_SJONNIR_CONSOLE:
- return m_uiSjonnirConsoleGUID;
+ case DATA_GO_TRIBUNAL_CONSOLE:
+ return m_uiGoTribunalConsoleGUID;
+ case DATA_GO_SKY_FLOOR:
+ return m_uiGoTribunalSkyFloorGUID;
+ case DATA_GO_KADDRAK:
+ return m_uiGoKaddrakGUID;
+ case DATA_GO_ABEDNEUM:
+ return m_uiGoAbedneumGUID;
+ case DATA_GO_MARNAK:
+ return m_uiGoMarnakGUID;
}
return 0;
}
+
+ const char* Save()
+ {
+ return strSaveData.c_str();
+ }
+
+ void Load(const char* chrIn)
+ {
+ if (!chrIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(chrIn);
+
+ std::istringstream loadStream(chrIn);
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ loadStream >> m_auiEncounter[i];
+
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
};
InstanceData* GetInstanceData_instance_halls_of_stone(Map* pMap)
@@ -205,3 +324,4 @@ void AddSC_instance_halls_of_stone()
newscript->GetInstanceData = &GetInstanceData_instance_halls_of_stone;
newscript->RegisterSelf();
}
+
diff --git a/scripts/northrend/ulduar/ulduar/boss_algalon.cpp b/scripts/northrend/ulduar/ulduar/boss_algalon.cpp
index 9758b5e..7a3d729 100644
--- a/scripts/northrend/ulduar/ulduar/boss_algalon.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_algalon.cpp
@@ -1,58 +1,921 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_algalon
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: cosmic smash, phase punch, black hole phasing need some core support
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_INTRO_1 = -1603106,
- SAY_INTRO_2 = -1603107,
- SAY_INTRO_3 = -1603108,
+ SAY_INTRO1 = -1603270,
+ SAY_INTRO2 = -1603271,
+ SAY_INTRO3 = -1603272,
+ SAY_ENGAGE = -1603141,
+ SAY_AGGRO = -1603140,
+ SAY_SLAY1 = -1603145,
+ SAY_SLAY2 = -1603146,
+ SAY_SUMMON_STAR = -1603148,
+ SAY_BIGBANG1 = -1603142,
+ SAY_BIGBANG2 = -1603143,
+ SAY_PHASE2 = -1603144,
+ SAY_BERSERK = -1603147,
+ SAY_DESPAWN1 = -1603273,
+ SAY_DESPAWN2 = -1603274,
+ SAY_DESPAWN3 = -1603275,
+ SAY_OUTRO1 = -1603276,
+ SAY_OUTRO2 = -1603277,
+ SAY_OUTRO3 = -1603278,
+ SAY_OUTRO4 = -1603149,
+ SAY_OUTRO5 = -1603279,
- SAY_ENGAGE = -1603109,
- SAY_AGGRO = -1603110,
- SAY_SLAY_1 = -1603111,
- SAY_SLAY_2 = -1603112,
- SAY_SUMMON_STAR = -1603113,
- SAY_BIG_BANG_1 = -1603114,
- SAY_BIG_BANG_2 = -1603115,
- SAY_PHASE_2 = -1603116,
- SAY_BERSERK = -1603117,
+ ITEM_PLANETARIUM_KEY = 45796,
+ ITEM_PLANETARIUM_KEY_H = 45798,
- SAY_DESPAWN_1 = -1603118,
- SAY_DESPAWN_2 = -1603119,
- SAY_DESPAWN_3 = -1603120,
+ SPELL_ALGALON_EVENT_BEAM = 64367,
+ SPELL_ALGALON_EVENT_CLIMAX = 64580, // This spells are used for environment
- SAY_OUTRO_1 = -1603121,
- SAY_OUTRO_2 = -1603122,
- SAY_OUTRO_3 = -1603123,
- SAY_OUTRO_4 = -1603124,
- SAY_OUTRO_5 = -1603125,
+ //spells to be casted
+ SPELL_QUANTUM_STRIKE = 64395, //Normal Quantum Strike
+ SPELL_QUANTUM_STRIKE_H = 64592, //Heroic Quantum Strike
+ SPELL_PHASE_PUNCH = 64412, //Phase punch
+ SPELL_PHASE_PUNCH_SHIFT = 64417,
+ SPELL_CONSTELLATION_TRIGGER = 65508, // this should make the space effect
+ SPELL_COSMIC_SMASH = 62301, //Normal Cosmic Smash
+ SPELL_COSMIC_SMASH_H = 64598, //Heroic Cosmic Smash
+ SPELL_COSMIC_SMASH_MISSILE = 62304,
+ SPELL_BIG_BANG = 64443, //Normal Big Bang
+ SPELL_BIG_BANG_H = 64584, //Heroic Big Bang
+ SPELL_ASCEND = 64487, //Ascend to the Heavens
+ SPELL_BERSERK = 47008, //Berserk
+ NPC_SMASH_TARGET_DUMMY = 33105,
+ // mobs
+ NPC_COLLAPSING_STAR = 32955, // they lose 1%hp per sec & cast black hole explosion when they die -> leave a black hole
+ SPELL_BLACK_HOLE_EXPLOSION = 64122,
+ SPELL_BLACK_HOLE_EXPLOSION_H = 65108,
+ SPELL_BLACK_HOLE_DESPAWN = 64391, // dummy spell
+ SPELL_SUMMON_BLACK_HOLE = 62189,
+ SPELL_BLACK_HOLE_VISUAL = 64135,
+ SPELL_BLACK_HOLE_SPAWN = 62003,
+ SPELL_BLACK_HOLE_TRIGG = 62185, // shifts the phase
+ SPELL_BLACK_HOLE_SHIFT = 62168,
+ SPELL_BLACK_HOLE_DMG = 62169,
+
+ NPC_BLACK_HOLE = 32953, // players must stay inside to avoid big bang
+
+ NPC_LIVING_CONSTELLATION = 33052, // if one enters a black hole they are despawned
+ SPELL_ARCANE_BARRAGE = 64599, //Arcane Barage
+ SPELL_ARCANE_BARRAGE_H = 64607, //Heroic Arcane Barage?
+
+ NPC_DARK_MATTER = 33089, // populates the black holes
+ NPC_UNLEASHED_DARK_MATTER = 34097, // summoned by black holes in phase 2
+ NPC_COSMIC_SMASH = 33104,
+
+ ACHIEV_FEED_TEARS = 3004,
+ ACHIEV_FEED_TEARS_H = 3005, // nobody dies in the raid lockout
+ ACHIEV_HERALD_OF_TITANS = 3316,
+ ACHIEV_OBSERVED = 3036,
+ ACHIEV_OBSERVED_H = 3037,
+ ACHIEV_SUPERMASSIVE = 3003,
+ ACHIEV_SUPERMASSIVE_H = 3002,
+
+ UI_STATE_ALGALON_TIMER_ON = 4132,
+ UI_STATE_ALGALON_TIMER_COUNT = 4131,
};
-void AddSC_boss_algalon()
+//Positional defines
+struct LocationsXY
+{
+ float x, y;
+ uint32 id;
+};
+
+static LocationsXY PositionLoc[]=
+{
+ {1620, -320.75f},
+ {1620, -290.75f },
+ {1645.5f, -290.75f },
+ {1645.5f, -320.75f },
+};
+
+//Black hole
+struct MANGOS_DLL_DECL mob_black_holeAI : public ScriptedAI
+{
+ mob_black_holeAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bHasAura;
+ uint32 m_uiRaidCheckTimer;
+ bool m_bIsPhase2;
+ uint32 m_uiSummonTimer;
+
+ void Reset()
+ {
+ m_bHasAura = false;
+ m_uiRaidCheckTimer = 1000;
+ m_bIsPhase2 = false;
+ m_uiSummonTimer = 5000;
+ DoCast(m_creature, SPELL_BLACK_HOLE_SPAWN);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // summon unleashed dark matter in phase 2
+ if (m_uiSummonTimer < uiDiff && m_bIsPhase2)
+ {
+ if(Creature* pTemp = m_creature->SummonCreature(NPC_UNLEASHED_DARK_MATTER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ pTemp->SetInCombatWithZone();
+ m_uiSummonTimer = urand(10000, 15000);
+ }
+ else m_uiSummonTimer -= uiDiff;
+
+ // phase players into the void
+ if (m_uiRaidCheckTimer < uiDiff && !m_bIsPhase2)
+ {
+ if(!m_bHasAura)
+ {
+ DoCast(m_creature, SPELL_BLACK_HOLE_TRIGG);
+ m_bHasAura = true;
+ }
+
+ if(Creature *pConstellation = GetClosestCreatureWithEntry(m_creature, NPC_LIVING_CONSTELLATION, 2))
+ {
+ pConstellation->DealDamage(pConstellation, pConstellation->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ m_uiRaidCheckTimer = 500;
+ }
+ else m_uiRaidCheckTimer -= uiDiff;
+ }
+};
+
+//Algalon
+struct MANGOS_DLL_DECL boss_algalonAI : public ScriptedAI
+{
+ boss_algalonAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bHasStarted = false; // flag used to check if the encounter has been started from the console
+ m_bIsInProgress = false; // flag used for time counter
+ m_bIsFirstTime = true; // flag used to show if this is the first aggro
+ m_uiDespawnTimer = 3600000; // 1h;
+ m_uiLastTimer = 3600000; // 1h;
+ m_bFeedOnTears = true; // flag used to check the Fead on Tears achiev
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiBerserk_Timer;
+ uint32 m_uiBigBang_Timer;
+ uint32 m_uiCosmicSmash_Timer;
+ uint32 m_uiPhasePunch_Timer;
+ uint32 m_uiQuantumStrike_Timer;
+ uint32 m_uiCollapsingStar_Timer;
+ uint32 m_uiLivingConstellationTimer;
+ uint32 m_uiRaidCheckTimer;
+ uint32 m_uiDarkMaterTimer;
+ uint32 m_uiDespawnTimer;
+ uint32 m_uiLastTimer;
+
+ // intro & outro
+ bool m_bIsOutro;
+ uint32 m_uiOutroTimer;
+ uint32 m_uiOutroStep;
+ bool m_bIsIntro;
+ uint32 m_uiIntroTimer;
+ uint32 m_uiIntroStep;
+
+ bool m_bHasStarted;
+ bool m_bIsFirstTime;
+ bool m_bIsInProgress;
+
+ uint8 m_uiCombatPhase;
+ bool m_bIsPhase2;
+
+ bool m_bIsDespawned;
+ bool m_bFeedOnTears;
+
+ void Reset()
+ {
+ m_uiQuantumStrike_Timer = 4000 + rand()%10000;
+ m_uiBerserk_Timer = 360000; //6 minutes
+ m_uiCollapsingStar_Timer = urand(15000, 20000); //Spawns between 15 to 20 seconds
+ m_uiLivingConstellationTimer = 60000;
+ m_uiBigBang_Timer = 90000;
+ m_uiDarkMaterTimer = 90000;
+ m_uiPhasePunch_Timer = 8000;
+ m_uiCosmicSmash_Timer = urand(30000, 60000);
+ m_uiRaidCheckTimer = 1000;
+
+ m_uiCombatPhase = 0; // it's 0 for idle, 1 for intro and 2 for combat
+ m_bIsPhase2 = false; // flag used below 30% hp
+
+ m_uiOutroTimer = 10000;
+ m_uiOutroStep = 1;
+ m_bIsIntro = true;
+ m_uiIntroTimer = 10000;
+ m_uiIntroStep = 1;
+ m_bIsOutro = false;
+
+ m_bIsDespawned = false; // flaged used to show that time has run out
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ switch(urand(0, 1))
+ {
+ case 0: DoScriptText(SAY_SLAY1, m_creature); break;
+ case 1: DoScriptText(SAY_SLAY2, m_creature); break;
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_ALGALON, NOT_STARTED);
+ m_bIsFirstTime = false;
+ }
+
+ void DoOutro()
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_ALGALON, DONE);
+ m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_ON, 0);
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_OBSERVED : ACHIEV_OBSERVED_H);
+
+ if(m_bFeedOnTears)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_FEED_TEARS : ACHIEV_FEED_TEARS_H);
+ }
+
+ m_creature->ForcedDespawn();
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if(!m_bIsInProgress)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(pWho) &&
+ pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40) && m_uiCombatPhase == 0 && m_bHasStarted && m_bIsFirstTime)
+ m_uiCombatPhase = 1;
+ }
+
+ void StartEncounter()
+ {
+ m_creature->SetVisibility(VISIBILITY_ON);
+ m_bIsFirstTime = true;
+ m_bHasStarted = true;
+ m_bIsInProgress = false;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(m_creature->GetHealthPercent() < 1.0f)
+ {
+ uiDamage = 0;
+ m_bIsOutro = true;
+ }
+ }
+
+ void SummonCreature(uint32 m_uiCreatureEntry)
+ {
+ float angle = (float) rand()*360/RAND_MAX + 1;
+ float homeX = 1630.475f + urand(15, 30)*cos(angle*(M_PI/180));
+ float homeY = -286.989f + urand(15, 30)*sin(angle*(M_PI/180));
+ if(Creature* pTemp = m_creature->SummonCreature(m_uiCreatureEntry, homeX, homeY, 417.32f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->SetInCombatWithZone();
+ if(pTemp->GetEntry() == NPC_DARK_MATTER)
+ pTemp->CastSpell(pTemp, SPELL_BLACK_HOLE_SHIFT, false);
+ }
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ // set combat phase
+ m_uiCombatPhase = 2;
+
+ if(m_bIsFirstTime)
+ {
+ m_bIsInProgress = true;
+ DoScriptText(SAY_ENGAGE, m_creature);
+ if(m_pInstance)
+ {
+ m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_ON, 1);
+ m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_COUNT, m_uiDespawnTimer / 60000);
+ }
+ }
+ else
+ DoScriptText(SAY_AGGRO, m_creature);
+
+ m_creature->SetInCombatWithZone();
+ DoCast(m_creature, SPELL_CONSTELLATION_TRIGGER);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_ALGALON, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ // despawn timer
+ if(m_uiDespawnTimer < uiDiff && !m_bIsDespawned && m_bIsInProgress)
+ {
+ m_bIsDespawned = true;
+ m_bIsOutro = true;
+ m_bIsInProgress = false;
+ }
+ else m_uiDespawnTimer -= uiDiff;
+
+ // update world state
+ if(m_uiDespawnTimer < m_uiLastTimer - 60000 && !m_bIsDespawned)
+ {
+ m_uiLastTimer = m_uiDespawnTimer;
+ uint32 tMinutes = m_uiDespawnTimer / 60000;
+ if(m_pInstance)
+ m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_COUNT, tMinutes);
+ }
+
+ if(!m_bIsOutro)
+ {
+ // intro
+ if(m_uiCombatPhase == 1)
+ {
+ if(m_bIsIntro && m_bIsFirstTime)
+ {
+ switch(m_uiIntroStep)
+ {
+ case 1:
+ DoScriptText(SAY_INTRO1, m_creature);
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 8000;
+ break;
+ case 3:
+ DoScriptText(SAY_INTRO2, m_creature);
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 6000;
+ break;
+ case 5:
+ DoScriptText(SAY_INTRO3, m_creature);
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 10000;
+ break;
+ case 7:
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bIsIntro = false;
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 10000;
+ break;
+ }
+ }
+ else return;
+
+ if (m_uiIntroTimer <= uiDiff)
+ {
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 330000;
+ } m_uiIntroTimer -= uiDiff;
+ }
+
+ // combat
+ if(m_uiCombatPhase == 2)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // spells
+ if(m_uiQuantumStrike_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_QUANTUM_STRIKE : SPELL_QUANTUM_STRIKE_H);
+ m_uiQuantumStrike_Timer = 4000 + rand()%10000;
+ }else m_uiQuantumStrike_Timer -= uiDiff;
+
+ if(m_uiBigBang_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_BIG_BANG : SPELL_BIG_BANG_H);
+ m_uiBigBang_Timer = 90000;
+ m_uiDarkMaterTimer = 1000;
+ }else m_uiBigBang_Timer -= uiDiff;
+
+ if(m_uiCosmicSmash_Timer < uiDiff)
+ {
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_COSMIC_SMASH : SPELL_COSMIC_SMASH_H);
+ m_uiCosmicSmash_Timer = urand(30000, 60000);
+ }else m_uiCosmicSmash_Timer -= uiDiff;
+
+ if(m_uiPhasePunch_Timer < uiDiff)
+ {
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget,SPELL_PHASE_PUNCH);
+ m_uiPhasePunch_Timer = 15000;
+ }else m_uiPhasePunch_Timer -= uiDiff;
+
+ // hack, phase punch needs core support
+ // PLEASE REMOVE FOR REVISION!
+ if(m_uiRaidCheckTimer < uiDiff)
+ {
+ Map *map = m_creature->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_PHASE_PUNCH, EFFECT_INDEX_0))
+ {
+ Aura *phasePunch = i->getSource()->GetAura(SPELL_PHASE_PUNCH, EFFECT_INDEX_0);
+ if(phasePunch->GetStackAmount() > 4)
+ {
+ i->getSource()->RemoveAurasDueToSpell(SPELL_PHASE_PUNCH);
+ i->getSource()->CastSpell(i->getSource(), SPELL_PHASE_PUNCH_SHIFT, false);
+ }
+ }
+ if (!i->getSource()->isAlive())
+ m_bFeedOnTears = false;
+ }
+ }
+ m_uiRaidCheckTimer = 1000;
+ }else m_uiRaidCheckTimer -= uiDiff;
+
+ // berserk
+ if(m_uiBerserk_Timer < uiDiff)
+ {
+ DoScriptText(SAY_BERSERK, m_creature);
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserk_Timer = 360000;
+ }else m_uiBerserk_Timer -= uiDiff;
+
+ // summons
+ if(m_uiCollapsingStar_Timer < uiDiff && !m_bIsPhase2)
+ {
+ DoScriptText(SAY_SUMMON_STAR, m_creature);
+ SummonCreature(NPC_COLLAPSING_STAR);
+ m_uiCollapsingStar_Timer = urand(15000, 20000);
+ }else m_uiCollapsingStar_Timer -= uiDiff;
+
+ if(m_uiLivingConstellationTimer < uiDiff && !m_bIsPhase2)
+ {
+ for(uint8 i = 0; i < urand (1, 3); i++)
+ SummonCreature(NPC_LIVING_CONSTELLATION);
+ m_uiLivingConstellationTimer = 30000;
+ }else m_uiLivingConstellationTimer -= uiDiff;
+
+ if(m_uiDarkMaterTimer < uiDiff && !m_bIsPhase2)
+ {
+ for(uint8 i = 0; i < 7; i++)
+ SummonCreature(NPC_DARK_MATTER);
+ m_uiDarkMaterTimer = 90000;
+ }else m_uiDarkMaterTimer -= uiDiff;
+
+ // hp check -> start phase 2
+ if(!m_bIsPhase2 && m_creature->GetHealthPercent() < 20)
+ {
+ DoScriptText(SAY_PHASE2, m_creature);
+ m_bIsPhase2 = true;
+
+ std::list lAdds;
+ GetCreatureListWithEntryInGrid(lAdds, m_creature, NPC_COLLAPSING_STAR, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lAdds, m_creature, NPC_BLACK_HOLE, DEFAULT_VISIBILITY_INSTANCE);
+
+ if (!lAdds.empty())
+ {
+ for(std::list::iterator iter = lAdds.begin(); iter != lAdds.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->ForcedDespawn();
+ }
+ }
+
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ if(Creature* pTemp = m_creature->SummonCreature(NPC_BLACK_HOLE, PositionLoc[i].x, PositionLoc[i].y, m_creature->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 0))
+ ((mob_black_holeAI*)pTemp->AI())->m_bIsPhase2 = true;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+
+ EnterEvadeIfOutOfCombatArea(uiDiff);
+ }
+ }
+ // outro: both for defeat and despawn
+ if(m_bIsOutro)
+ {
+ switch(m_uiOutroStep)
+ {
+ case 1:
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->GetMotionMaster()->MovePoint(0, 1631.970f, -302.635f, 417.321f);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 5000;
+ break;
+ case 3:
+ // make boss kneel
+ m_creature->SetSplineFlags(SPLINEFLAG_UNKNOWN12);
+ if(m_bIsDespawned)
+ {
+ DoScriptText(SAY_DESPAWN1, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 15000;
+ }
+ else
+ {
+ DoScriptText(SAY_OUTRO1, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 37000;
+ }
+ break;
+ case 5:
+ if(m_bIsDespawned)
+ {
+ DoScriptText(SAY_DESPAWN2, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 8000;
+ }
+ else
+ {
+ DoScriptText(SAY_OUTRO2, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 17000;
+ }
+ break;
+ case 7:
+ if(m_bIsDespawned)
+ {
+ DoScriptText(SAY_DESPAWN3, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 7000;
+ }
+ else
+ {
+ DoScriptText(SAY_OUTRO3, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 12000;
+ }
+ break;
+ case 9:
+ if(m_bIsDespawned)
+ {
+ DoCast(m_creature, SPELL_ASCEND);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 5000;
+ }
+ else
+ {
+ DoScriptText(SAY_OUTRO4, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 11000;
+ }
+ break;
+ case 11:
+ if(m_bIsDespawned)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->DoUpdateWorldState(UI_STATE_ALGALON_TIMER_ON, 0);
+ m_pInstance->SetData(TYPE_ALGALON, FAIL);
+ }
+ m_creature->ForcedDespawn();
+ }
+ else
+ {
+ DoScriptText(SAY_OUTRO5, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 13000;
+ }
+ break;
+ case 13:
+ DoOutro();
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 10000;
+ break;
+ }
+ }
+ else
+ return;
+
+ if (m_uiOutroTimer <= uiDiff)
+ {
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 330000;
+ } m_uiOutroTimer -= uiDiff;
+ }
+};
+
+//Collapsing Star
+struct MANGOS_DLL_DECL mob_collapsing_starAI : public ScriptedAI
+{
+ mob_collapsing_starAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiHealthTimer;
+ uint32 m_uiDieTimer;
+ uint32 m_uiSummonTimer;
+
+ void Reset()
+ {
+ m_uiHealthTimer = 1000;
+ m_uiDieTimer = 600000;
+ m_uiSummonTimer = 600000;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if(uiDamage > m_creature->GetHealth())
+ {
+ uiDamage = 0;
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_uiDieTimer = 1500;
+ m_uiSummonTimer = 1000;
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_BLACK_HOLE_EXPLOSION : SPELL_BLACK_HOLE_EXPLOSION_H);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSummonTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_SUMMON_BLACK_HOLE);
+ m_uiSummonTimer = 60000;
+ }
+ else m_uiSummonTimer -= uiDiff;
+
+ if (m_uiDieTimer < uiDiff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else
+ m_uiDieTimer -= uiDiff;
+
+ // movement should be improved
+ // npc should ignore threat tables
+ if(m_uiHealthTimer < uiDiff && m_creature->GetHealthPercent() > 1.0f)
+ {
+ m_creature->GetMotionMaster()->MoveConfused();
+ m_creature->DealDamage(m_creature, (m_creature->GetMaxHealth() * 0.01), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_uiHealthTimer = 1000;
+ }else m_uiHealthTimer -= uiDiff;
+ }
+};
+
+//Living constellation
+struct MANGOS_DLL_DECL mob_living_constellationAI : public ScriptedAI
+{
+ mob_living_constellationAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiArcaneBarrageTimer;
+
+ void Reset()
+ {
+ m_uiArcaneBarrageTimer = 15000;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiArcaneBarrageTimer < uiDiff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)){
+ DoCast(target, m_bIsRegularMode ? SPELL_ARCANE_BARRAGE : SPELL_ARCANE_BARRAGE_H);
+ }
+ m_uiArcaneBarrageTimer = 15000;
+ }else m_uiArcaneBarrageTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL mob_cosmic_smash_targetAI : public ScriptedAI
+{
+ mob_cosmic_smash_targetAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pCreature->SetDisplayId(11686); // make invisible
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiSpellTimer;
+
+ void Reset()
+ {
+ m_uiSpellTimer = 5000;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_ALGALON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpellTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_COSMIC_SMASH_MISSILE);
+ m_uiSpellTimer = 60000;
+ }else m_uiSpellTimer -= uiDiff;
+ }
+};
+
+
+bool GOHello_go_celestial_acces(Player* pPlayer, GameObject* pGo)
+{
+ ScriptedInstance* m_pInstance = (ScriptedInstance*)pGo->GetInstanceData();
+ bool m_bIsRegularMode = pGo->GetMap()->IsRegularDifficulty();
+ bool m_bHasItem = false;
+
+ // check if the player has the key
+ if (m_bIsRegularMode)
+ {
+ if(pPlayer->HasItemCount(ITEM_PLANETARIUM_KEY, 1) || pPlayer->HasItemCount(ITEM_PLANETARIUM_KEY_H, 1))
+ m_bHasItem = true;
+ }
+ else
+ {
+ if(pPlayer->HasItemCount(ITEM_PLANETARIUM_KEY_H, 1))
+ m_bHasItem = true;
+ }
+
+ if(!m_bHasItem)
+ return false;
+
+ if (!m_pInstance)
+ return false;
+
+ // disable if encounter is already done
+ if (m_pInstance->GetData(TYPE_ALGALON) == DONE)
+ {
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ return false;
+ }
+
+ // start encounter
+ if (Creature* pAlgalon = pGo->GetMap()->GetCreature(m_pInstance->GetData64(NPC_ALGALON)))
+ {
+ if(pAlgalon->isAlive())
+ {
+ ((boss_algalonAI*)pAlgalon->AI())->StartEncounter();
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+
+ // open celestial door
+ if(GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_CELESTIAL_DOOR)))
+ m_pInstance->DoUseDoorOrButton(pDoor->GetGUID());
+ }
+ }
+
+ return false;
+}
+
+CreatureAI* GetAI_boss_algalon(Creature* pCreature)
+{
+ return new boss_algalonAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_collapsing_star(Creature* pCreature)
{
+ return new mob_collapsing_starAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_living_constellation(Creature* pCreature)
+{
+ return new mob_living_constellationAI(pCreature);
+}
+CreatureAI* GetAI_mob_cosmic_smash_target(Creature* pCreature)
+{
+ return new mob_cosmic_smash_targetAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_black_hole(Creature* pCreature)
+{
+ return new mob_black_holeAI(pCreature);
}
+
+void AddSC_boss_algalon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_algalon";
+ newscript->GetAI = &GetAI_boss_algalon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_collapsing_star";
+ newscript->GetAI = &GetAI_mob_collapsing_star;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_living_constellation";
+ newscript->GetAI = &GetAI_mob_living_constellation;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_cosmic_smash_target";
+ newscript->GetAI = &GetAI_mob_cosmic_smash_target;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_black_hole";
+ newscript->GetAI = &GetAI_mob_black_hole;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_celestial_acces";
+ newscript->pGOHello = &GOHello_go_celestial_acces;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp b/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp
index 95b0c7a..c6f129c 100644
--- a/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp
@@ -1,41 +1,564 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_auriaya
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: need correct setstack for feral defender buff
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_AGGRO = -1603079,
- SAY_SLAY_1 = -1603080,
- SAY_SLAY_2 = -1603081,
- SAY_BERSERK = -1603082,
- SAY_DEATH = -1603083,
- EMOTE_SCREECH = -1603084,
- EMOTE_DEFENDER = -1603085,
+ //yells
+ SAY_AGGRO = -1603070,
+ SAY_SLAY1 = -1603071,
+ SAY_SLAY2 = -1603072,
+ SAY_BERSERK = -1603073,
+ SAY_DEATH = -1603074,
+ EMOTE_SCREECH = -1603358,
+ EMOTE_DEFENDER = -1603359,
+
+ //auriaya
+ SPELL_BERSERK = 47008,
+ SPELL_GUARDIAN_SWARM = 64396, // broken
+ SPELL_SENTINEL_BLAST = 64389,
+ SPELL_SENTINEL_BLAST_H = 64678,
+ SPELL_SONIC_SCREECH = 64422,
+ SPELL_SONIC_SCREECH_H = 64688,
+ SPELL_FEAR = 64386,
+
+ //feral defender
+ SPELL_FEIGN_DEATH = 57685,
+ SPELL_FERAL_ESSENCE = 64455,
+ SPELL_FERAL_POUNCE = 64478,
+ SPELL_FERAL_POUNCE_H = 64669,
+ SPELL_FERAL_RUSH = 64496,
+ SPELL_FERAL_RUSH_H = 64674,
+
+ //sanctum sentry
+ SPELL_RIP_FLESH = 64375,
+ SPELL_RIP_FLESH_H = 64667,
+ SPELL_SAVAGE_POUNCE = 64666,
+ SPELL_SAVAGE_POUNCE_H = 64374,
+ SPELL_STRENGHT_OF_PACK = 64369,
+ //seeping feral essence
+ AURA_VOID_ZONE = 64458,
+ AURA_VOID_ZONE_H = 64676,
+ //NPC ids
+ MOB_VOID_ZONE = 34098,
+ MOB_FERAL_DEFENDER = 34035,
+ MOB_GUARDIAN_SWARN = 34034,
+
+ ACHIEV_CRAZY_CAT_LADY = 3006,
+ ACHIEV_CRAZY_CAT_LADY_H = 3007,
+
+ ACHIEV_NINE_LIVES = 3076,
+ ACHIEV_NINE_LIVES_H = 3077,
};
-void AddSC_boss_auriaya()
+bool m_bCrazyCatLady;
+bool m_bNineLives;
+
+// Seeping Feral Essence
+struct MANGOS_DLL_DECL mob_seeping_feral_essenceAI : public ScriptedAI
{
+ mob_seeping_feral_essenceAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ pCreature->setFaction(14);
+ pCreature->SetDisplayId(11686); // make invisible
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(m_creature, m_bIsRegularMode ? AURA_VOID_ZONE : AURA_VOID_ZONE_H);
+ m_creature->SetRespawnDelay(DAY);
+ }
+ void UpdateAI(const uint32 diff)
+ {
+ }
+};
+
+CreatureAI* GetAI_mob_seeping_feral_essence(Creature* pCreature)
+{
+ return new mob_seeping_feral_essenceAI(pCreature);
}
+
+// Sanctum Sentry
+struct MANGOS_DLL_DECL mob_sanctum_sentryAI : public ScriptedAI
+{
+ mob_sanctum_sentryAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiRip_Flesh_Timer;
+ uint32 m_uiJump_Timer;
+
+ std::list lSentrys;
+
+ void Reset()
+ {
+ m_uiRip_Flesh_Timer = 13000;
+ m_uiJump_Timer = 0;
+
+ lSentrys.clear();
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_AURIAYA)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ }
+
+ GetCreatureListWithEntryInGrid(lSentrys, m_creature, NPC_SANCTUM_SENTRY, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lSentrys.empty())
+ {
+ for(std::list::iterator iter = lSentrys.begin(); iter != lSentrys.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->SetInCombatWithZone();
+ }
+ }
+
+ DoCast(m_creature, SPELL_STRENGHT_OF_PACK);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_bCrazyCatLady = false;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ {
+ // they should follow Auriaya, but this looks ugly!
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_AURIAYA)))
+ {
+ if (pTemp->isAlive())
+ {
+ m_creature->GetMotionMaster()->MoveFollow(pTemp,0.0f,0.0f);
+ m_creature->GetMap()->CreatureRelocation(m_creature, pTemp->GetPositionX(), pTemp->GetPositionY(), pTemp->GetPositionZ(), 0.0f);
+ }
+ }
+ }
+
+ if (m_uiRip_Flesh_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_RIP_FLESH : SPELL_RIP_FLESH_H);
+ m_uiRip_Flesh_Timer = 13000;
+ }else m_uiRip_Flesh_Timer -= diff;
+
+ if (m_uiJump_Timer < diff)
+ {
+ if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 25))
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SAVAGE_POUNCE : SPELL_SAVAGE_POUNCE_H);
+ m_uiJump_Timer = 1000;
+ }else m_uiJump_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_sanctum_sentry(Creature* pCreature)
+{
+ return new mob_sanctum_sentryAI(pCreature);
+}
+
+// Feral Defender
+struct MANGOS_DLL_DECL mob_feral_defenderAI : public ScriptedAI
+{
+ mob_feral_defenderAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiPounce_Timer;
+ uint32 m_uiRush_Start_Timer;
+ uint32 m_uiRush_Finish_Timer;
+ uint32 m_uiRush_Delay;
+ uint32 m_uiRevive_Delay;
+
+ bool m_bIsRush;
+ bool m_bIsDead;
+
+ bool m_bHasAura;
+
+ void Reset()
+ {
+ m_uiPounce_Timer = 5000;
+ m_uiRush_Start_Timer = 9000;
+ m_bIsRush = false;
+ m_bIsDead = false;
+ m_bHasAura = false;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ DoCast(m_creature, SPELL_FERAL_ESSENCE);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_bNineLives = true;
+ }
+
+ // feign death
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth())
+ {
+ uiDamage = 0;
+ m_creature->CastStop();
+ m_creature->RemoveArenaAuras(true);
+ m_creature->SummonCreature(MOB_VOID_ZONE, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
+ DoCast(m_creature, SPELL_FEIGN_DEATH);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (m_creature->HasAura(SPELL_FERAL_ESSENCE))
+ {
+ // remove 1 stack of the aura
+ if(SpellAuraHolder* strenght = m_creature->GetSpellAuraHolder(SPELL_FERAL_ESSENCE))
+ {
+ if(strenght->ModStackAmount(-1))
+ m_creature->RemoveAurasDueToSpell(SPELL_FERAL_ESSENCE);
+ }
+
+ m_uiRevive_Delay = 35000;
+ m_bIsDead = true;
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_AURIAYA) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // hacky way of stacking aura, needs fixing
+ if(SpellAuraHolder* essence = m_creature->GetSpellAuraHolder(SPELL_FERAL_ESSENCE))
+ {
+ if(essence->GetStackAmount() < 9 && !m_bHasAura)
+ {
+ m_bHasAura = true;
+ essence->SetStackAmount(9);
+ }
+ }
+
+ if (m_uiPounce_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ DoCast(target, m_bIsRegularMode ? SPELL_FERAL_POUNCE : SPELL_FERAL_POUNCE_H);
+ m_creature->AddThreat(target,0.0f);
+ m_creature->AI()->AttackStart(target);
+ }
+ m_uiPounce_Timer = 5000;
+ }else m_uiPounce_Timer -= diff;
+
+ if (m_uiRush_Start_Timer < diff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ DoCast(target, m_bIsRegularMode ? SPELL_FERAL_RUSH : SPELL_FERAL_RUSH_H);
+ m_creature->AddThreat(target,0.0f);
+ m_creature->AI()->AttackStart(target);
+ }
+ m_uiRush_Start_Timer = 35000;
+ m_uiRush_Finish_Timer = m_bIsRegularMode ? 2500 : 5000;
+ m_uiRush_Delay = 500;
+ m_bIsRush = true;
+ }else m_uiRush_Start_Timer -= diff;
+
+ if (m_uiRush_Delay < diff && m_bIsRush)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ DoCast(target, m_bIsRegularMode ? SPELL_FERAL_RUSH : SPELL_FERAL_RUSH_H);
+ m_creature->AddThreat(target,0.0f);
+ m_creature->AI()->AttackStart(target);
+ }
+ m_uiRush_Delay = 500;
+ }else m_uiRush_Delay -= diff;
+
+ if (m_uiRush_Finish_Timer < diff)
+ m_bIsRush = false;
+ else m_uiRush_Finish_Timer -= diff;
+
+ if (m_uiRevive_Delay < diff && m_bIsDead)
+ {
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bIsDead = false;
+ }else m_uiRevive_Delay -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_feral_defender(Creature* pCreature)
+{
+ return new mob_feral_defenderAI(pCreature);
+}
+
+// Auriaya
+struct MANGOS_DLL_DECL boss_auriayaAI : public ScriptedAI
+{
+ boss_auriayaAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiEnrage_Timer;
+ uint32 m_uiSwarm_Timer;
+ uint32 m_uiSonic_Screech_Timer;
+ uint32 m_uiSentinel_Blast_Timer;
+ uint32 m_uiFear_Timer;
+ uint32 m_uiSummon_Timer;
+ uint8 m_uiSwarmcount;
+
+ std::list lSentrys;
+
+ bool m_bHasBerserk;
+ bool m_bIsDefender;
+
+ void Reset()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_uiEnrage_Timer = 600000;
+ m_uiSwarm_Timer = urand(50000, 60000);
+ m_uiSonic_Screech_Timer = urand(90000, 100000);
+ m_uiSentinel_Blast_Timer = 62000;
+ m_uiFear_Timer = 60000;
+ m_uiSummon_Timer = urand(60000, 70000);
+ m_uiSwarmcount = 10;
+ m_bHasBerserk = false;
+ m_bIsDefender = false;
+
+ lSentrys.clear();
+
+ // achievs
+ m_bCrazyCatLady = true;
+ m_bNineLives = false;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ //death yell
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_AURIAYA, DONE);
+
+ // hacky way to complete achievements; use only if you have this function
+ if (m_bCrazyCatLady)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CRAZY_CAT_LADY : ACHIEV_CRAZY_CAT_LADY_H);
+ }
+
+ if (m_bNineLives)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_NINE_LIVES : ACHIEV_NINE_LIVES_H);
+ }
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_AURIAYA, IN_PROGRESS);
+
+ GetCreatureListWithEntryInGrid(lSentrys, m_creature, NPC_SANCTUM_SENTRY, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lSentrys.empty())
+ {
+ for(std::list::iterator iter = lSentrys.begin(); iter != lSentrys.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->SetInCombatWithZone();
+ }
+ }
+
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_SLAY2, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_AURIAYA, FAIL);
+
+ GetCreatureListWithEntryInGrid(lSentrys, m_creature, NPC_SANCTUM_SENTRY, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lSentrys.empty())
+ {
+ for(std::list::iterator iter = lSentrys.begin(); iter != lSentrys.end(); ++iter)
+ {
+ if ((*iter) && !(*iter)->isAlive())
+ (*iter)->Respawn();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiFear_Timer < uiDiff)
+ {
+ DoScriptText(EMOTE_SCREECH, m_creature);
+ m_creature->InterruptNonMeleeSpells(true);
+ DoCast(m_creature, SPELL_FEAR);
+ m_uiFear_Timer = 35000;
+ m_uiSentinel_Blast_Timer = 2500;
+ }else m_uiFear_Timer -= uiDiff;
+
+ if (m_uiSentinel_Blast_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SENTINEL_BLAST : SPELL_SENTINEL_BLAST_H);
+ m_uiSentinel_Blast_Timer = urand(30000, 40000);
+ }else m_uiSentinel_Blast_Timer -= uiDiff;
+
+ if (m_uiSummon_Timer < uiDiff && !m_bIsDefender)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(MOB_FERAL_DEFENDER, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTemp->AddThreat(pTarget,0.0f);
+ pTemp->AI()->AttackStart(pTarget);
+ }
+ DoScriptText(EMOTE_DEFENDER, m_creature);
+ m_bIsDefender = true;
+ }
+ }else m_uiSummon_Timer -= uiDiff;
+
+ if (m_uiSonic_Screech_Timer < uiDiff)
+ {
+ m_creature->InterruptNonMeleeSpells(true);
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SONIC_SCREECH : SPELL_SONIC_SCREECH_H);
+ m_uiSonic_Screech_Timer = 27000;
+ }else m_uiSonic_Screech_Timer -= uiDiff;
+
+ // summon swarm, spell needs core fix
+ if (m_uiSwarm_Timer < uiDiff)
+ {
+ for(int i = 0; i < 10; i++)
+ {
+ float angle = (float) rand()*360/RAND_MAX + 1;
+ float homeX = m_creature->GetPositionX() + 10*cos(angle*(M_PI/180));
+ float homeY = m_creature->GetPositionY() + 10*sin(angle*(M_PI/180));
+ if (Creature* pTemp = m_creature->SummonCreature(MOB_GUARDIAN_SWARN, homeX, homeY, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ DoCast(pTarget, SPELL_GUARDIAN_SWARM);
+ pTemp->AddThreat(pTarget, 100.0f);
+ pTemp->SetInCombatWithZone();
+ }
+ }
+ }
+ m_uiSwarm_Timer = 35000;
+ }else m_uiSwarm_Timer -= uiDiff;
+
+ if (m_uiEnrage_Timer < uiDiff && !m_bHasBerserk)
+ {
+ DoScriptText(SAY_BERSERK, m_creature);
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_BERSERK);
+ m_bHasBerserk = true;
+ }else m_uiEnrage_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_auriaya(Creature* pCreature)
+{
+ return new boss_auriayaAI(pCreature);
+}
+
+void AddSC_boss_auriaya()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_auriaya";
+ NewScript->GetAI = GetAI_boss_auriaya;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_seeping_feral_essence";
+ NewScript->GetAI = &GetAI_mob_seeping_feral_essence;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_sanctum_sentry";
+ NewScript->GetAI = &GetAI_mob_sanctum_sentry;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_feral_defender";
+ NewScript->GetAI = &GetAI_mob_feral_defender;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_freya.cpp b/scripts/northrend/ulduar/ulduar/boss_freya.cpp
index 4857334..816b4fe 100644
--- a/scripts/northrend/ulduar/ulduar/boss_freya.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_freya.cpp
@@ -1,64 +1,1509 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_freya
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: aura stacking need core support after the recent aura changes
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_AGGRO = -1603000,
- SAY_AGGRO_HARD = -1603001,
- SAY_ADDS_CONSERVATOR = -1603002,
- SAY_ADDS_TRIO = -1603003,
- SAY_ADDS_LASHER = -1603004,
- SAY_SLAY_1 = -1603005,
- SAY_SLAY_2 = -1603006,
- SAY_DEATH = -1603007,
- SAY_BERSERK = -1603008,
- SAY_HELP_YOGG = -1603009,
-
- EMOTE_ALLIES_NATURE = -1603010,
- EMOTE_LIFEBINDER = -1603011,
- EMOTE_TREMOR = -1603012,
- EMOTE_IRON_ROOTS = -1603013,
-
- SAY_AGGRO_BRIGHT = -1603014,
- SAY_SLAY_1_BRIGHT = -1603015,
- SAY_SLAY_2_BRIGHT = -1603016,
- SAY_DEATH_BRIGHT = -1603017,
-
- SAY_AGGRO_IRON = -1603018,
- SAY_SLAY_1_IRON = -1603019,
- SAY_SLAY_2_IRON = -1603020,
- SAY_DEATH_IRON = -1603021,
-
- SAY_AGGRO_STONE = -1603022,
- SAY_SLAY_1_STONE = -1603023,
- SAY_SLAY_2_STONE = -1603024,
- SAY_DEATH_STONE = -1603025,
+ /* YELLS */
+ // freya
+ SAY_AGGRO = -1603000,
+ SAY_AGGRO_HARD = -1603001,
+ SAY_SUMMON1 = -1603002,
+ SAY_SUMMON2 = -1603003,
+ SAY_SUMMON3 = -1603004,
+ SAY_SLAY1 = -1603005,
+ SAY_SLAY2 = -1603006,
+ SAY_DEATH = -1603007,
+ SAY_BERSERK = -1603008,
+ EMOTE_ALLIES_NATURE = -1603362,
+ EMOTE_LIFEBINDERS_GIFT = -1603363,
+ EMOTE_GROUND_TREMMOR = -1603364,
+ EMOTE_IRON_ROOTS = -1603365,
+ //brightleaf
+ SAY_BRIGHTLEAF_AGGRO = -1603160,
+ SAY_BRIGHTLEAF_SLAY1 = -1603161,
+ SAY_BRIGHTLEAF_SLAY2 = -1603162,
+ SAY_BRIGHTLEAF_DEATH = -1603163,
+ //Ironbranch
+ SAY_IRONBRANCH_AGGRO = -1603170,
+ SAY_IRONBRANCH_SLAY1 = -1603171,
+ SAY_IRONBRANCH_SLAY2 = -1603172,
+ SAY_IRONBRANCH_DEATH = -1603173,
+ //Stonebark
+ SAY_STONEBARK_AGGRO = -1603180,
+ SAY_STONEBARK_SLAY1 = -1603181,
+ SAY_STONEBARK_SLAY2 = -1603182,
+ SAY_STONEBARK_DEATH = -1603183,
+
+ /* BOSS SPELLS */
+ SPELL_ATTUNED_TO_NATURE = 62519, //increases healing, start at 150 stacks
+ SPELL_ATTUNED_10_STACKS = 62525,
+ SPELL_ATTUNED_2_STACKS = 62524,
+ SPELL_ATTUNED_25_STACKS = 62521,
+ SPELL_TOUCH_OF_EONAR = 62528, //heals Freya, 6k per second
+ SPELL_TOUCH_OF_EONAR_H = 62892, //heals Freya, 24k per second
+ SPELL_SUNBEAM = 62623,
+ SPELL_SUNBEAM_H = 62872,
+ SPELL_BERSERK = 47008, // 10 min
+
+ /* HARD MODE SPELLS */
+ SPELL_DRAINED_OF_POWER = 62467,
+ // brightleaf
+ SPELL_UNSTABLE_ENERGY_FREYA = 62451,
+ SPELL_UNSTABLE_ENERGY_FREYA_H = 62865,
+ SPELL_BRIGHTLEAFS_ESSENCE = 62968, //62385,
+ SPELL_EFFECT_BRIGHTLEAF = 63294,
+ // ironbrach
+ SPELL_STRENGHTEN_IRON_ROOTS = 63601,
+ NPC_STRENGHENED_IRON_ROOTS = 33168,
+ SPELL_IRON_ROOTS_FREYA = 62438,
+ SPELL_IRON_ROOTS_FREYA_H = 62861,
+ SPELL_IRONBRANCH_ESSENCE = 62713, //62387,
+ SPELL_EFFECT_IRONBRANCH = 63292,
+ // stonebark
+ SPELL_GROUND_TREMOR_FREYA = 62437,
+ SPELL_GROUND_TREMOR_FREYA_H = 62859,
+ SPELL_STONEBARKS_ESSENCE = 65590, //62386,
+ SPELL_EFFECT_STONEBARK = 63295,
+
+ NPC_SUN_BEAM = 33170,
+ NPC_UNSTABLE_SUN_BEAM = 33050,
+
+ // sanctuary adds
+ NPC_EONARS_GIFT = 33228,
+ SPELL_LIFEBINDERS_GIFT = 62584, // after 12 secs, heals Freya & her allies for 30%
+ SPELL_LIFEBINDERS_GIFT_H = 64185, // the same but for 60%
+ SPELL_PHEROMONES = 62619, // protects from conservators grip
+ NPC_HEALTHY_SPORE = 33215,
+
+ /* ADDS */
+ // 6 waves of adds. 1 of the 3 each min
+ NPC_DETONATING_LASHER = 32918, // recude 2 stacks
+ // spells
+ SPELL_FLAME_LASH = 62608,
+ SPELL_DETONATE = 62598,
+ SPELL_DETONATE_H = 62937,
+
+ NPC_ANCIENT_CONSERVATOR = 33203, // reduce 30 stacks
+ //spells
+ SPELL_CONSERVATORS_GRIP = 62532,
+ SPELL_NATURES_FURY = 62589,
+ SPELL_NATURES_FURY_H = 63571,
+
+ /* elemental adds */ // each one reduces 10 stacks
+ NPC_WATER_SPIRIT = 33202,
+ // spells
+ SPELL_TIDAL_WAVE = 62653,
+ SPELL_TIDAL_WAVE_H = 62935,
+
+ NPC_STORM_LASHER = 32919,
+ // spells
+ SPELL_STORMBOLT = 62649,
+ SPELL_STORMBOLT_H = 62938,
+ SPELL_LIGHTNING_LASH = 62648, // 3 targets
+ SPELL_LIGHTNING_LASH_H = 62939, // 5 targets
+
+ NPC_SNAPLASHER = 32916,
+ // spells
+ SPELL_HARDENED_BARK = 62663,
+ SPELL_HARDENED_BARK_H = 64190,
+
+ // nature bomb
+ NPC_NATURE_BOMB = 34129,
+ GO_NATURE_BOMB = 194902,
+ SPELL_NATURE_BOMB = 64587,
+ SPELL_NATURE_BOMB_H = 64650,
+
+ /* ELDERS */ // used in phase 1
+ ELDER_BRIGHTLEAF = 32915,
+ ELDER_IRONBRANCH = 32913,
+ ELDER_STONEBARK = 32914,
+
+ // brightleaf spells
+ SPELL_BRIGHTLEAF_FLUX = 62262,
+ SPELL_SOLAR_FLARE = 62240,
+ SPELL_SOLAR_FLARE_H = 62920,
+ SPELL_UNSTABLE_SUN_BEAM = 62211,
+ SPELL_UNSTABLE_SUN_BEAM_A = 62243,
+ SPELL_UNSTABLE_ENERGY = 62217, // cancels sun bean
+ SPELL_UNSTABLE_ENERGY_H = 62922,
+ SPELL_PHOTOSYNTHESIS = 62209,
+
+ // ironbrach spells
+ SPELL_IMPALE = 62310,
+ SPELL_IMPALE_H = 62928,
+ SPELL_IRON_ROOTS = 62283,
+ SPELL_IRON_ROOTS_H = 62930,
+ NPC_IRON_ROOTS = 33088,
+ SPELL_THORM_SWARM = 62285,
+ SPELL_THORM_SWARM_H = 62931,
+
+ // stonebark spells
+ SPELL_FIST_OF_STONE = 62344,
+ SPELL_BROKEN_BONES = 62356,
+ SPELL_GROUND_TREMOR = 62325,
+ SPELL_GROUND_TREMOR_H = 62932,
+ SPELL_PETRIFIED_BARK = 62337,
+ SPELL_PETRIFIED_BARK_H = 62933,
+
+ // not used because summoned chest doesn't despawn after looted
+ SPELL_SUMMON_CHEST_1 = 62950,
+ SPELL_SUMMON_CHEST_2 = 62952,
+ SPELL_SUMMON_CHEST_3 = 62953,
+ SPELL_SUMMON_CHEST_4 = 62954,
+ SPELL_SUMMON_CHEST_5 = 62955,
+ SPELL_SUMMON_CHEST_6 = 62956,
+ SPELL_SUMMON_CHEST_7 = 62957,
+ SPELL_SUMMON_CHEST_8 = 62958,
+
+ SPELL_SUMMON_ALLIES_OF_NATURE = 62678, //better do that in sd2
+ SPELL_SUMMON_LASHERS = 62688, // lashers - broken
+ SPELL_SUMMON_ELEMENTALS = 62686, // elementals -> better in sd2
+ SPELL_SUMMON_CONSERVATOR = 62685, // conservator
+ SPELL_LIFEBINDERS_GIFT_SUMMON = 62869,
+ SPELL_NATURE_BOMB_SUMMON = 64606,
+
+ SPELL_SPORE_SUMMON_NE = 62591,
+ SPELL_SPORE_SUMMON_SE = 62592,
+ SPELL_SPORE_SUMMON_SW = 62593,
+ SPELL_SPORE_SUMMON_NW = 62582,
+
+ SPELL_HEALTHY_SPORE_VISUAL = 62538,
+ SPELL_NATURE_BOMB_VISUAL = 64604,
+ SPELL_LIFEBINDERS_VISUAL = 62579,
+ SPELL_LIFEBINDER_GROW = 44833,
+
+ SPELL_PHEROMONES_LG = 62619,
+ SPELL_POTENT_PHEROMONES = 62541,
+
+ ACHIEV_BACK_TO_NATURE = 2982,
+ ACHIEV_BACK_TO_NATURE_H = 2983,
+ ACHIEV_KNOCK_WOOD = 3177,
+ ACHIEV_KNOCK_WOOD_H = 3185,
+ ACHIEV_KNOCK_KNOCK_WOOD = 3178,
+ ACHIEV_KNOCK_KNOCK_WOOD_H = 3186,
+ ACHIEV_KNOCK_KNOCK_KNOCK_WOOD = 3179,
+ ACHIEV_KNOCK_KNOCK_KNOCK_WOOD_H = 3187,
+};
+
+// Iron roots & stranghned iron roots
+struct MANGOS_DLL_DECL mob_iron_rootsAI : public ScriptedAI
+{
+ mob_iron_rootsAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint64 m_uiVictimGUID;
+ uint32 m_uiCreatureEntry;
+
+ void Reset()
+ {
+ m_uiVictimGUID = 0;
+ m_uiCreatureEntry = m_creature->GetEntry();
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth())
+ {
+ if (m_uiVictimGUID)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit(m_uiVictimGUID))
+ {
+ switch(m_uiCreatureEntry)
+ {
+ case NPC_IRON_ROOTS:
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H);
+ break;
+ case NPC_STRENGHENED_IRON_ROOTS:
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim)
+ {
+ switch(m_uiCreatureEntry)
+ {
+ case NPC_IRON_ROOTS:
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H);
+ break;
+ case NPC_STRENGHENED_IRON_ROOTS:
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H);
+ break;
+ }
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit(m_uiVictimGUID))
+ {
+ switch(m_uiCreatureEntry)
+ {
+ case NPC_IRON_ROOTS:
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H);
+ break;
+ case NPC_STRENGHENED_IRON_ROOTS:
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H);
+ break;
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiuiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+ }
+};
+
+// Elder Brightleaf
+struct MANGOS_DLL_DECL boss_elder_brightleafAI : public ScriptedAI
+{
+ boss_elder_brightleafAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiBrightleafFluxTimer;
+ uint32 m_uiSolarFlareTimer;
+ uint32 m_uiUnstableSunBeanTimer;
+ uint32 m_uiUnstabelEnergyTimer;
+ uint32 m_uiSunbeamStacks;
+ uint32 m_uiHealTimer;
+ bool m_bHasSunbeam;
+
+ void Reset()
+ {
+ m_uiBrightleafFluxTimer = 5000;
+ m_uiSolarFlareTimer = 10000 + urand(1000, 5000);
+ m_uiUnstableSunBeanTimer = 15000;
+ m_uiUnstabelEnergyTimer = 30000;
+ m_uiSunbeamStacks = 1;
+ m_bHasSunbeam = false;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ DoScriptText(SAY_BRIGHTLEAF_AGGRO, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_BRIGHTLEAF_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_BRIGHTLEAF_SLAY2, m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ DoScriptText(SAY_BRIGHTLEAF_DEATH, m_creature);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // this needs core suport
+ if(m_uiBrightleafFluxTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_BRIGHTLEAF_FLUX);
+ m_uiBrightleafFluxTimer = 5000;
+ }
+ else m_uiBrightleafFluxTimer -= uiDiff;
+
+ if(m_uiSolarFlareTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_SOLAR_FLARE : SPELL_SOLAR_FLARE_H);
+ m_uiSolarFlareTimer = 10000 + urand(1000, 5000);
+ }
+ else m_uiSolarFlareTimer -= uiDiff;
+
+ // also the following spells need some core support -> hacky way of use
+ // PLEASE FIX FOR REVISION!
+ if(m_uiUnstableSunBeanTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_UNSTABLE_SUN_BEAM);
+ m_bHasSunbeam = true;
+ m_uiHealTimer = 1000;
+ m_uiUnstableSunBeanTimer = urand(7000, 12000);
+ }
+ else m_uiUnstableSunBeanTimer -= uiDiff;
+
+ // cast after the unstable sun bean
+ if (m_uiHealTimer < uiDiff && m_bHasSunbeam)
+ {
+ DoCast(m_creature, SPELL_PHOTOSYNTHESIS);
+ m_bHasSunbeam = false;
+ }
+ else m_uiHealTimer -= uiDiff;
+
+ // removes photosynthesis when standing inside
+ if(m_uiUnstabelEnergyTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY: SPELL_UNSTABLE_ENERGY_H);
+ m_creature->RemoveAurasDueToSpell(SPELL_UNSTABLE_SUN_BEAM_A);
+ m_creature->RemoveAurasDueToSpell(SPELL_PHOTOSYNTHESIS);
+ m_uiSunbeamStacks = 1;
+ m_uiUnstabelEnergyTimer = urand(20000, 30000);
+ }
+ else m_uiUnstabelEnergyTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_elder_brightleaf(Creature* pCreature)
+{
+ return new boss_elder_brightleafAI(pCreature);
+}
+
+// Elder Ironbranch
+struct MANGOS_DLL_DECL boss_elder_ironbranchAI : public ScriptedAI
+{
+ boss_elder_ironbranchAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiImpaleTimer;
+ uint32 m_uiIronrootsTimer;
+ uint32 m_uiThornSwarmTimer;
+
+ void Reset()
+ {
+ m_uiImpaleTimer = 10000 + urand (1000, 5000);
+ m_uiIronrootsTimer = 20000 + urand (1000, 7000);
+ m_uiThornSwarmTimer = 30000;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ DoScriptText(SAY_IRONBRANCH_AGGRO, m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ DoScriptText(SAY_IRONBRANCH_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_IRONBRANCH_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_IRONBRANCH_SLAY2, m_creature);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiImpaleTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_IMPALE : SPELL_IMPALE_H);
+ m_uiImpaleTimer = 10000 + urand (1000, 5000);
+ }
+ else m_uiImpaleTimer -= uiDiff;
+
+ if(m_uiIronrootsTimer < uiDiff)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ DoCast(target, m_bIsRegularMode ? SPELL_IRON_ROOTS : SPELL_IRON_ROOTS_H);
+ m_uiIronrootsTimer = 20000 + urand (1000, 7000);
+ }
+ else m_uiIronrootsTimer -= uiDiff;
+
+ if(m_uiThornSwarmTimer < uiDiff)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ DoCast(target, m_bIsRegularMode ? SPELL_THORM_SWARM : SPELL_THORM_SWARM_H);
+ m_uiThornSwarmTimer = 30000;
+ }
+ else m_uiThornSwarmTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_elder_ironbranch(Creature* pCreature)
+{
+ return new boss_elder_ironbranchAI(pCreature);
+}
+
+// Stonebark
+struct MANGOS_DLL_DECL boss_elder_stonebarkAI : public ScriptedAI
+{
+ boss_elder_stonebarkAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiFistsOfStoneTimer;
+ uint32 m_uiGroundTremorTimer;
+ uint32 m_uiPetrifiedBarkTimer;
+
+ void Reset()
+ {
+ m_uiFistsOfStoneTimer = 20000;
+ m_uiGroundTremorTimer = 15000;
+ m_uiPetrifiedBarkTimer = 25000;
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ DoScriptText(SAY_STONEBARK_AGGRO, m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ DoScriptText(SAY_STONEBARK_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_STONEBARK_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_STONEBARK_SLAY2, m_creature);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiFistsOfStoneTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_FIST_OF_STONE);
+ m_uiFistsOfStoneTimer = 30000;
+ }
+ else m_uiFistsOfStoneTimer -= uiDiff;
+
+ if(m_uiGroundTremorTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_GROUND_TREMOR : SPELL_GROUND_TREMOR_H);
+ m_uiGroundTremorTimer = 15000 + urand (1000, 5000);
+ }
+ else m_uiGroundTremorTimer -= uiDiff;
+
+ if(m_uiPetrifiedBarkTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_PETRIFIED_BARK : SPELL_PETRIFIED_BARK_H);
+ m_uiPetrifiedBarkTimer = 20000 + urand (1000, 5000);
+ }
+ else m_uiPetrifiedBarkTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_elder_stonebark(Creature* pCreature)
+{
+ return new boss_elder_stonebarkAI(pCreature);
+}
+
+// Freya
+struct MANGOS_DLL_DECL boss_freyaAI : public ScriptedAI
+{
+ boss_freyaAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiSummonTimer;
+ uint32 m_uiWaveNumber;
+ uint32 m_uiWaveType;
+ uint32 m_uiWaveTypeInc;
+ uint32 m_uiSunbeamTimer;
+ uint32 m_uiEnrageTimer;
+
+ bool m_bIsHardMode;
+ bool m_bHasAura;
+
+ uint32 m_uiNatureBombTimer;
+ uint32 m_uiLifebindersGiftTimer;
+
+ bool m_bIsOutro;
+ uint32 m_uiOutroTimer;
+ uint32 m_uiStep;
+
+ // hard mode timers
+ uint32 m_uiUnstableEnergyTimer;
+ uint32 m_uiStrenghtenIronRootsTimer;
+ uint32 m_uiGroundTremorTimer;
+
+ uint32 m_uiThreeWaveCheckTimer;
+ bool m_bWaveCheck;
+ uint64 m_uiWaterSpiritGUID;
+ uint64 m_uiStormLasherGUID;
+ uint64 m_uiSnapLasherGUID;
+
+ bool m_bIsBrightleafAlive;
+ bool m_bIsIronbranchAlive;
+ bool m_bIsStonebarkAlive;
+
+ uint32 m_uiAchievProgress;
+ bool m_bNature;
+
+ void Reset()
+ {
+ m_uiSummonTimer = 15000;
+ m_uiWaveNumber = 0;
+ m_uiWaveType = irand(0,2);
+ m_uiWaveTypeInc = irand(1,2);
+ m_uiSunbeamTimer = rand()%10000;
+ m_uiEnrageTimer = 600000; //10 minutes
+ m_bIsHardMode = false;
+ m_uiLifebindersGiftTimer = 30000;
+ m_uiUnstableEnergyTimer = 25000;
+ m_uiStrenghtenIronRootsTimer = 25000 + urand(1000, 5000);
+ m_uiGroundTremorTimer = 20000;
+ m_uiNatureBombTimer = 7000;
+ m_uiThreeWaveCheckTimer = 1000;
+ m_uiAchievProgress = 10000;
+ m_bWaveCheck = false;
+ m_uiWaterSpiritGUID = 0;
+ m_uiStormLasherGUID = 0;
+ m_uiSnapLasherGUID = 0;
+
+ m_uiOutroTimer = 10000;
+ m_uiStep = 1;
+ m_bIsOutro = false;
+
+ m_uiAchievProgress = 0;
+ m_bNature = false;
+ m_bHasAura = false;
+
+ if(m_pInstance)
+ {
+ // remove elder auras
+ if (Creature* pBrightleaf = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRIGHTLEAF)))
+ {
+ if (pBrightleaf->isAlive())
+ pBrightleaf->RemoveAllAuras();
+ }
+ if (Creature* pIronbranch = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IRONBRACH)))
+ {
+ if (pIronbranch->isAlive())
+ pIronbranch->RemoveAllAuras();
+ }
+ if (Creature* pStonebark = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STONEBARK)))
+ {
+ if (pStonebark->isAlive())
+ pStonebark->RemoveAllAuras();
+ }
+ }
+ }
+
+ void Aggro(Unit *who)
+ {
+ // aura should stack up to 150 when casted, need core support
+ DoCast(m_creature, SPELL_ATTUNED_TO_NATURE);
+
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_FREYA, IN_PROGRESS);
+
+ // check brightleaf
+ if (Creature* pBrightleaf = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRIGHTLEAF)))
+ {
+ if (pBrightleaf->isAlive())
+ {
+ pBrightleaf->CastSpell(pBrightleaf, SPELL_DRAINED_OF_POWER, false);
+ pBrightleaf->CastSpell(m_creature, SPELL_EFFECT_BRIGHTLEAF, false);
+ m_bIsBrightleafAlive = true;
+ m_uiAchievProgress += 1;
+ }
+ else
+ m_bIsBrightleafAlive = false;
+ }
+
+ // check ironbranch
+ if (Creature* pIronbranch = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IRONBRACH)))
+ {
+ if (pIronbranch->isAlive())
+ {
+ pIronbranch->CastSpell(pIronbranch, SPELL_DRAINED_OF_POWER, false);
+ pIronbranch->CastSpell(m_creature, SPELL_EFFECT_IRONBRANCH, false);
+ m_bIsIronbranchAlive = true;
+ m_uiAchievProgress += 1;
+ }
+ else
+ m_bIsIronbranchAlive = false;
+ }
+
+ // check stonebark
+ if (Creature* pStonebark = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STONEBARK)))
+ {
+ if (pStonebark->isAlive())
+ {
+ pStonebark->CastSpell(pStonebark, SPELL_DRAINED_OF_POWER, false);
+ pStonebark->CastSpell(m_creature, SPELL_EFFECT_STONEBARK, false);
+ m_bIsStonebarkAlive = true;
+ m_uiAchievProgress += 1;
+ }
+ else
+ m_bIsStonebarkAlive = false;
+ }
+ }
+
+ m_bIsHardMode = CheckHardMode();
+
+ if(!m_bIsHardMode)
+ DoScriptText(SAY_AGGRO, m_creature);
+ else
+ DoScriptText(SAY_AGGRO_HARD, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_FREYA, FAIL);
+ }
+
+ void DoOutro()
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_FREYA_HARD, 0);
+
+ // hacky way to complete achievements; use only if you have this function
+ if(m_uiAchievProgress == 1)
+ {
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_KNOCK_WOOD : ACHIEV_KNOCK_WOOD_H);
+ m_pInstance->SetData(TYPE_FREYA_HARD, 1);
+ }
+ else if (m_uiAchievProgress == 2)
+ {
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_KNOCK_KNOCK_WOOD : ACHIEV_KNOCK_KNOCK_WOOD_H);
+ m_pInstance->SetData(TYPE_FREYA_HARD, 2);
+ }
+ else if (m_uiAchievProgress == 3)
+ {
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_KNOCK_KNOCK_KNOCK_WOOD : ACHIEV_KNOCK_KNOCK_KNOCK_WOOD_H);
+ m_pInstance->SetData(TYPE_FREYA_HARD, 3);
+ }
+
+ if (m_bNature)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_BACK_TO_NATURE : ACHIEV_BACK_TO_NATURE_H);
+
+ m_pInstance->SetData(TYPE_FREYA, DONE);
+ }
+
+ m_creature->ForcedDespawn();
+ }
+
+ // for debug only!
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_FREYA, DONE);
+ if(m_bIsHardMode)
+ m_pInstance->SetData(TYPE_FREYA_HARD, DONE);
+ }
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(m_creature->GetHealthPercent() < 1.0f)
+ {
+ uiDamage = 0;
+ m_bIsOutro = true;
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_SLAY2, m_creature);
+ }
+
+ // summon 12 Lashers. Should be done by a spell which needs core fix
+ void SummonLashers()
+ {
+ DoScriptText(SAY_SUMMON3, m_creature);
+ int i;
+ float x,y;
+ for(i = 0; i < 12; ++i)
+ {
+ x = (rand_norm() * 30.0f) - 15.0f;
+ y = (rand_norm() * 30.0f) - 15.0f;
+ if(Creature* pLasher = DoSpawnCreature(NPC_DETONATING_LASHER, x, y, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ {
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pLasher->AddThreat(pTarget, 1.0f);
+ }
+ }
+ }
+
+ // summon conservator. Should be done by a spell which needs core fix
+ void SummonConservator()
+ {
+ DoScriptText(SAY_SUMMON1, m_creature);
+ float x = (rand_norm() * 30.0f) - 15.0f;
+ float y = (rand_norm() * 30.0f) - 15.0f;
+ if(Creature* pAdd = DoSpawnCreature(NPC_ANCIENT_CONSERVATOR, x, y, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ {
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pAdd->AddThreat(pTarget, 1.0f);
+ }
+ }
+
+ // summmon the 3 elementals. Should be done by a spell which needs core fix.
+ void SummonElementals()
+ {
+ DoScriptText(SAY_SUMMON2, m_creature);
+ m_bWaveCheck = true;
+ m_uiThreeWaveCheckTimer = 2000;
+
+ if(Creature* pSpirit = DoSpawnCreature(NPC_WATER_SPIRIT, 0, 0, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ {
+ m_uiWaterSpiritGUID = pSpirit->GetGUID();
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pSpirit->AddThreat(pTarget, 1.0f);
+ }
+
+ if(Creature* pStormLasher = DoSpawnCreature(NPC_STORM_LASHER, 0, 0, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ {
+ m_uiStormLasherGUID = pStormLasher->GetGUID();
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pStormLasher->AddThreat(pTarget, 1.0f);
+ }
+
+ if(Creature* pSnapLasher = DoSpawnCreature(NPC_SNAPLASHER, 0, 0, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ {
+ m_uiSnapLasherGUID = pSnapLasher->GetGUID();
+ if(Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pSnapLasher->AddThreat(pTarget, 1.0f);
+ }
+ }
+
+ bool CheckHardMode()
+ {
+ if(m_bIsBrightleafAlive && m_bIsIronbranchAlive && m_bIsStonebarkAlive)
+ return true;
+ return false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(!m_bIsOutro)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // hacky way of stacking aura. Please remove when fixed in core!
+ if(SpellAuraHolder* natureAura = m_creature->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE))
+ {
+ if(natureAura->GetStackAmount() < 150 && !m_bHasAura)
+ {
+ m_bHasAura = true;
+ natureAura->SetStackAmount(150);
+ }
+ }
+
+ if(!m_creature->HasAura(m_bIsRegularMode ? SPELL_TOUCH_OF_EONAR : SPELL_TOUCH_OF_EONAR_H))
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_TOUCH_OF_EONAR : SPELL_TOUCH_OF_EONAR_H);
+
+ // check if the 3 elementals die at the same time
+ if(m_uiThreeWaveCheckTimer < uiDiff && m_bWaveCheck)
+ {
+ Creature* pWaterSpirit = m_pInstance->instance->GetCreature(m_uiWaterSpiritGUID);
+ Creature* pStormLasher = m_pInstance->instance->GetCreature(m_uiStormLasherGUID);
+ Creature* pSnapLasher = m_pInstance->instance->GetCreature(m_uiSnapLasherGUID);
+
+ if(pWaterSpirit && pStormLasher && pSnapLasher)
+ {
+ if(!pWaterSpirit->isAlive() && !pStormLasher->isAlive() && !pSnapLasher->isAlive())
+ {
+ m_bWaveCheck = false;
+ if(SpellAuraHolder* natureAura = m_creature->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE))
+ {
+ if(natureAura->ModStackAmount(-30))
+ m_creature->RemoveAurasDueToSpell(SPELL_ATTUNED_TO_NATURE);
+ }
+ }
+ else
+ {
+ // respawn the dead ones
+ if(!pWaterSpirit->isAlive())
+ pWaterSpirit->Respawn();
+ if(!pSnapLasher->isAlive())
+ pSnapLasher->Respawn();
+ if(!pStormLasher->isAlive())
+ pStormLasher->Respawn();
+ }
+ }
+ m_uiThreeWaveCheckTimer = 2000;
+ }
+ else
+ m_uiThreeWaveCheckTimer -= uiDiff;
+
+ // Hardmode
+ if(m_bIsBrightleafAlive)
+ {
+ if(!m_creature->HasAura(SPELL_BRIGHTLEAFS_ESSENCE, EFFECT_INDEX_0))
+ DoCast(m_creature, SPELL_BRIGHTLEAFS_ESSENCE);
+
+ // hacky way, should be done by spell
+ if(m_uiUnstableEnergyTimer < uiDiff)
+ {
+ //DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY_FREYA : SPELL_UNSTABLE_ENERGY_FREYA_H);
+ for(int8 i = 0; i < 3; ++i)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ {
+ float x = target->GetPositionX();
+ float y = target->GetPositionY();
+ float z = target->GetPositionZ();
+ m_creature->SummonCreature(NPC_SUN_BEAM, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 20000);
+ }
+ }
+ m_uiUnstableEnergyTimer = urand(25000, 30000);
+ }
+ else m_uiUnstableEnergyTimer -= uiDiff;
+ }
+
+ if(m_bIsIronbranchAlive)
+ {
+ if(!m_creature->HasAura(SPELL_IRONBRANCH_ESSENCE, EFFECT_INDEX_0))
+ DoCast(m_creature, SPELL_IRONBRANCH_ESSENCE);
+
+ if(m_uiStrenghtenIronRootsTimer < uiDiff)
+ {
+ if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ {
+ DoScriptText(EMOTE_IRON_ROOTS, m_creature, target);
+ DoCast(target, m_bIsRegularMode ? SPELL_IRON_ROOTS_FREYA : SPELL_IRON_ROOTS_FREYA_H);
+ }
+ m_uiStrenghtenIronRootsTimer = 50000 + urand(10000, 20000);
+ }
+ else m_uiStrenghtenIronRootsTimer -= uiDiff;
+ }
+
+ if(m_bIsStonebarkAlive)
+ {
+ // aura doesn't work. Needs core fix
+ if(!m_creature->HasAura(SPELL_STONEBARKS_ESSENCE, EFFECT_INDEX_0))
+ DoCast(m_creature, SPELL_STONEBARKS_ESSENCE);
+
+ if(m_uiGroundTremorTimer < uiDiff)
+ {
+ DoScriptText(EMOTE_GROUND_TREMMOR, m_creature);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_GROUND_TREMOR_FREYA : SPELL_GROUND_TREMOR_FREYA_H);
+ m_uiGroundTremorTimer = 20000;
+ }
+ else m_uiGroundTremorTimer -= uiDiff;
+ }
+
+ //Phase 1, waves of adds
+ if(m_uiWaveNumber < 6)
+ {
+ if(m_uiSummonTimer < uiDiff)
+ {
+ DoScriptText(EMOTE_ALLIES_NATURE, m_creature);
+ switch(m_uiWaveType)
+ {
+ case 0: SummonLashers(); break;
+ case 1: SummonConservator(); break;
+ case 2: SummonElementals(); break;
+ }
+ m_uiWaveType = (m_uiWaveType + m_uiWaveTypeInc) % 3;
+ ++m_uiWaveNumber;
+ m_uiSummonTimer = 60000;
+ }
+ else m_uiSummonTimer -= uiDiff;
+ }
+ // Phase 2
+ else
+ {
+ // nature bomb. Should be done by spell, not by summon.
+ if(m_uiNatureBombTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_NATURE_BOMB_VISUAL);
+ DoCast(m_creature, SPELL_NATURE_BOMB_SUMMON);
+
+ int8 count = urand(8,10);
+ for(int8 i = 0; i < count; ++i)
+ {
+ float radius = 30* rand_norm_f();
+ float angle = 2.0f * M_PI_F * rand_norm_f();
+ float x = m_creature->GetPositionX() + cos(angle) * radius;
+ float y = m_creature->GetPositionY() + sin(angle) * radius;
+ float z = m_creature->GetTerrain()->GetHeight(x, y, MAX_HEIGHT);
+ m_creature->SummonCreature(NPC_NATURE_BOMB, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 20000);
+ }
+ m_uiNatureBombTimer = urand(7000, 12000);
+ }
+ else m_uiNatureBombTimer -= uiDiff;
+ }
+
+ //All phases
+ if(m_uiSunbeamTimer < uiDiff)
+ {
+ if( Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_SUNBEAM : SPELL_SUNBEAM_H);
+ m_uiSunbeamTimer = 6000 + rand()%10000;
+ }
+ else m_uiSunbeamTimer -= uiDiff;
+
+ if(m_uiLifebindersGiftTimer < uiDiff)
+ {
+ DoScriptText(EMOTE_LIFEBINDERS_GIFT, m_creature);
+ if(Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_LIFEBINDERS_GIFT_SUMMON);
+ m_uiLifebindersGiftTimer = 30000;
+ }
+ else m_uiLifebindersGiftTimer -= uiDiff;
+
+ if(m_uiEnrageTimer < uiDiff)
+ {
+ DoScriptText(SAY_BERSERK, m_creature);
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiEnrageTimer = 30000;
+ }
+ else m_uiEnrageTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ // outro
+ if(m_bIsOutro)
+ {
+ switch(m_uiStep)
+ {
+ case 1:
+ if(m_creature->HasAura(SPELL_ATTUNED_TO_NATURE, EFFECT_INDEX_0))
+ {
+ if(m_creature->GetAura(SPELL_ATTUNED_TO_NATURE, EFFECT_INDEX_0)->GetStackAmount() >= 25)
+ m_bNature = true;
+ }
+ m_creature->setFaction(35);
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->GetMotionMaster()->MovePoint(0, 2359.40f, -52.39f, 425.64f);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ ++m_uiStep;
+ m_uiOutroTimer = 7000;
+ break;
+ case 3:
+ DoScriptText(SAY_DEATH, m_creature);
+ ++m_uiStep;
+ m_uiOutroTimer = 10000;
+ break;
+ case 5:
+ DoOutro();
+ ++m_uiStep;
+ m_uiOutroTimer = 10000;
+ break;
+ }
+ }
+ else return;
+
+ if (m_uiOutroTimer <= uiDiff)
+ {
+ ++m_uiStep;
+ m_uiOutroTimer = 330000;
+ } m_uiOutroTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_boss_freya(Creature* pCreature)
+{
+ return new boss_freyaAI(pCreature);
+}
+
+// Script for all the npcs found on the ground during Freya encounter
+struct MANGOS_DLL_DECL mob_freya_groundAI : public ScriptedAI
+{
+ mob_freya_groundAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiNatureBomb_Timer;
+ uint32 m_uiDieTimer;
+ uint32 m_uiEonarsGift_Timer;
+ uint32 m_uiNonSelectable_Timer;
+ uint32 m_uiGrow_Timer;
+ uint32 m_uiSunBeamDespawn_Timer;
+ uint32 m_uiUnstableEnergy_Timer;
+ uint32 m_uiHealthyGrow_Timer;
+ uint64 m_uiNatureBombGUID;
+ float m_fSize;
+
+ bool m_bNpcNatureBomb;
+ bool m_bNpcEonarsGift;
+ bool m_bNpcHealthySpore;
+ bool m_bNpcSunBeamFreya;
+ bool m_bNpcSunBeamBright;
+
+ bool m_bHasGrow;
+
+ void Reset()
+ {
+ m_uiNatureBomb_Timer = urand(9000,11000);
+ m_uiDieTimer = 60000;
+ m_uiEonarsGift_Timer = urand(11000,13000);
+ m_uiNonSelectable_Timer = 5000;
+ m_uiUnstableEnergy_Timer = 1000;
+ m_uiGrow_Timer = 0;
+ m_uiSunBeamDespawn_Timer = urand(10000,11000);
+ m_bHasGrow = true;
+ m_uiHealthyGrow_Timer = urand(3000,12000);
+ m_bNpcNatureBomb = false;
+ m_bNpcEonarsGift = false;
+ m_bNpcHealthySpore = false;
+ m_bNpcSunBeamFreya = false;
+ m_bNpcSunBeamBright = false;
+
+ // the invisible displayIds should be set in DB.
+ switch(m_creature->GetEntry())
+ {
+ case NPC_NATURE_BOMB:
+ m_bNpcNatureBomb = true;
+ m_creature->setFaction(14);
+ m_fSize = 1;
+ m_creature->SetDisplayId(25865); // invisible
+ DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL);
+ break;
+ case NPC_EONARS_GIFT:
+ m_bNpcEonarsGift = true;
+ m_fSize = float(0.1);
+ DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL);
+ break;
+ case NPC_HEALTHY_SPORE:
+ m_bNpcHealthySpore = true;
+ DoCast(m_creature, SPELL_HEALTHY_SPORE_VISUAL);
+ DoCast(m_creature, SPELL_POTENT_PHEROMONES);
+ break;
+ case NPC_SUN_BEAM:
+ m_bNpcSunBeamFreya = true;
+ m_creature->SetDisplayId(25865); // invisible
+ DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY_FREYA : SPELL_UNSTABLE_ENERGY_FREYA_H);
+ break;
+ case NPC_UNSTABLE_SUN_BEAM:
+ m_bNpcSunBeamBright = true;
+ m_creature->SetDisplayId(25865); // invisible
+ DoCast(m_creature, SPELL_LIFEBINDERS_VISUAL);
+ //DoCast(m_creature, SPELL_PHOTOSYNTHESIS); // spell needs core fix, should be casted on Brighleaf!
+ break;
+ }
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_FREYA) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if(!m_creature->isAlive())
+ return;
+
+ // NATURE BOMB
+ if(m_bNpcNatureBomb)
+ {
+ if(m_uiNatureBomb_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_NATURE_BOMB : SPELL_NATURE_BOMB_H);
+ m_uiDieTimer = 500;
+ m_uiNatureBomb_Timer = 10000;
+ }else m_uiNatureBomb_Timer -= uiDiff;
+
+ if(m_uiDieTimer < uiDiff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false);
+ else m_uiDieTimer -= uiDiff;
+ }
+
+ // EONAR GIFT
+ if(m_bNpcEonarsGift)
+ {
+ if (m_uiGrow_Timer > 500 && m_fSize < 1.5)
+ {
+ m_fSize += float(m_uiGrow_Timer)/8000;
+ m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fSize);
+ m_uiGrow_Timer = 0;
+ }else m_uiGrow_Timer += uiDiff;
+
+ if(m_uiEonarsGift_Timer < uiDiff)
+ {
+ if (Creature* pFreya = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_FREYA)))
+ DoCast(pFreya, m_bIsRegularMode ? SPELL_LIFEBINDERS_GIFT : SPELL_LIFEBINDERS_GIFT_H);
+ m_uiEonarsGift_Timer = 1000;
+ }else m_uiEonarsGift_Timer -= uiDiff;
+
+ if(m_uiNonSelectable_Timer < uiDiff && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_PHEROMONES_LG);
+ }else m_uiNonSelectable_Timer -= uiDiff;
+ }
+
+ // HEALTHY SPORE
+ if(m_bNpcHealthySpore)
+ {
+ if(!m_bHasGrow && m_fSize < 0.25)
+ m_creature->ForcedDespawn();
+
+ if(m_uiHealthyGrow_Timer < uiDiff)
+ {
+ if(m_bHasGrow)
+ {
+ m_fSize = float(urand(150,225))/100;
+ m_bHasGrow = false;
+ }
+ else
+ m_fSize = float(urand(1,300))/100;
+ if(m_fSize < 1)
+ m_fSize = 0.1f;
+ m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fSize);
+ m_uiHealthyGrow_Timer = urand(3000,5000);
+ }else m_uiHealthyGrow_Timer -= uiDiff;
+ }
+
+ // SUN BEAM
+ if(m_bNpcSunBeamBright)
+ {
+ if(m_uiUnstableEnergy_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_UNSTABLE_ENERGY : SPELL_UNSTABLE_ENERGY_H);
+ m_uiUnstableEnergy_Timer = 1000;
+ }else m_uiUnstableEnergy_Timer -= uiDiff;
+ }
+
+ if(m_bNpcSunBeamFreya || m_bNpcSunBeamBright)
+ {
+ if(m_uiSunBeamDespawn_Timer < uiDiff)
+ m_creature->ForcedDespawn();
+ else m_uiSunBeamDespawn_Timer -= uiDiff;
+ }
+ }
+};
+
+// Script for Freya's adds
+struct MANGOS_DLL_DECL mob_freya_spawnedAI : public ScriptedAI
+{
+ mob_freya_spawnedAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ bool m_bAncientConservator;
+ bool m_bDetonatingLasher;
+ bool m_bAncientWaterSpirit;
+ bool m_bStormLasher;
+ bool m_bSnaplasher;
+ bool m_bHasExploded;
+
+ uint32 m_uiDeathCountdown;
+ uint32 m_uiTidalWave_Timer;
+ uint32 m_uiStormbolt_Timer;
+ uint32 m_uiLightningLash_Timer;
+ uint32 m_uiFlameLash_Timer;
+ uint32 m_uiNaturesFury_Timer;
+ uint32 m_uiWave3_DeathCountdown;
+ uint32 m_uiRespawnSpores_Timer;
+ uint32 m_uiDieTimer;
+ uint8 m_uiHealthMultiplier;
+
+ void Reset()
+ {
+ m_bAncientWaterSpirit = false;
+ m_bStormLasher = false;
+ m_bSnaplasher = false;
+ m_bAncientConservator = false;
+ m_bDetonatingLasher = false;
+ m_bHasExploded = false;
+ m_uiDieTimer = 120000;
+ m_uiDeathCountdown = 10000;
+ m_uiTidalWave_Timer = urand(2000,4000);
+ m_uiStormbolt_Timer = 1000;
+ m_uiLightningLash_Timer = urand(11000,14000);
+ m_uiFlameLash_Timer = urand(5000,10000);
+ m_uiNaturesFury_Timer = urand(8000,10000);
+ m_uiRespawnSpores_Timer = 5000;
+ m_uiHealthMultiplier = 1;
+
+ switch(m_creature->GetEntry())
+ {
+ // The Conservator's Grip needs core fix. It should be canceled by pheronomes!
+ case NPC_ANCIENT_CONSERVATOR:
+ m_bAncientConservator = true;
+ //DoCast(m_creature, SPELL_CONSERVATORS_GRIP); //spell disabled because it isn't negated by pheronomes
+ DoSpores(10);
+ break;
+ case NPC_DETONATING_LASHER:
+ m_bDetonatingLasher = true;
+ break;
+ case NPC_WATER_SPIRIT:
+ m_bAncientWaterSpirit = true;
+ break;
+ case NPC_SNAPLASHER:
+ m_bSnaplasher = true;
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_HARDENED_BARK : SPELL_HARDENED_BARK_H);
+ break;
+ case NPC_STORM_LASHER:
+ m_bStormLasher = true;
+ break;
+ }
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ // remove some stacks from Freya's aura
+ // hacky way. Should be done by spell which needs core support
+ if (m_bAncientConservator)
+ {
+ if (Creature* pFreya = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_FREYA)))
+ {
+ if(SpellAuraHolder* natureAura = pFreya->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE))
+ {
+ if(natureAura->ModStackAmount(-25))
+ m_creature->RemoveAurasDueToSpell(SPELL_ATTUNED_TO_NATURE);
+ }
+ }
+ }
+
+ if (m_bDetonatingLasher)
+ {
+ if (Creature* pFreya = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_FREYA)))
+ {
+ if(SpellAuraHolder* natureAura = pFreya->GetSpellAuraHolder(SPELL_ATTUNED_TO_NATURE))
+ {
+ if(natureAura->ModStackAmount(-2))
+ m_creature->RemoveAurasDueToSpell(SPELL_ATTUNED_TO_NATURE);
+ }
+ }
+ }
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if (m_bDetonatingLasher && uiDamage > m_creature->GetHealth() && !m_bHasExploded)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_DETONATE : SPELL_DETONATE_H);
+ uiDamage = 0;
+ m_bHasExploded = true;
+ m_uiDieTimer = 500;
+ }
+ }
+
+ void DoSpores(int8 times)
+ {
+ for(int8 i = 0; i < times; ++i)
+ {
+ for(int8 itr = 0; i < 3; ++i)
+ DoCast(m_creature, SPELL_SPORE_SUMMON_NE + itr);
+ DoCast(m_creature, SPELL_SPORE_SUMMON_NW);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_FREYA) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if(!m_creature->isAlive())
+ return;
+
+ // DETONATING LASHERS
+ if(m_bDetonatingLasher)
+ {
+ if(m_uiFlameLash_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_FLAME_LASH);
+ m_uiFlameLash_Timer = urand(5000,10000);
+ }else m_uiFlameLash_Timer -= uiDiff;
+
+ if(m_uiDieTimer < uiDiff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false);
+ else m_uiDieTimer -= uiDiff;
+ }
+
+ // CONSERVATOR
+ if(m_bAncientConservator)
+ {
+ if(m_uiNaturesFury_Timer < uiDiff)
+ {
+ DoCast(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0), m_bIsRegularMode ? SPELL_NATURES_FURY : SPELL_NATURES_FURY_H);
+ m_uiNaturesFury_Timer = urand(5000,6000);
+ }else m_uiNaturesFury_Timer -= uiDiff;
+
+ if(m_uiRespawnSpores_Timer < uiDiff)
+ {
+ DoSpores(3);
+ m_uiRespawnSpores_Timer = 5000;
+ }else m_uiRespawnSpores_Timer -= uiDiff;
+ }
+
+ // ELEMENTAL ADDS
+ // waterspirit
+ if(m_bAncientWaterSpirit && m_uiTidalWave_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_TIDAL_WAVE : SPELL_TIDAL_WAVE_H);
+ m_uiTidalWave_Timer = urand(7000,9000);
+ }else m_uiTidalWave_Timer -= uiDiff;
+
+ // stormlasher
+ if(m_bStormLasher)
+ {
+ if (m_uiLightningLash_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_LIGHTNING_LASH : SPELL_LIGHTNING_LASH_H);
+ m_uiLightningLash_Timer = urand(11000,14000);
+ }
+ else
+ {
+ m_uiLightningLash_Timer -= uiDiff;
+ if (m_uiStormbolt_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_STORMBOLT : SPELL_STORMBOLT_H);
+ m_uiStormbolt_Timer = 2000;
+ }else m_uiStormbolt_Timer -= uiDiff;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
};
+CreatureAI* GetAI_mob_freya_ground(Creature* pCreature)
+{
+ return new mob_freya_groundAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_freya_spawned(Creature* pCreature)
+{
+ return new mob_freya_spawnedAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_iron_roots(Creature* pCreature)
+{
+ return new mob_iron_rootsAI(pCreature);
+}
+
void AddSC_boss_freya()
{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_freya";
+ newscript->GetAI = &GetAI_boss_freya;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_elder_brightleaf";
+ newscript->GetAI = &GetAI_boss_elder_brightleaf;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_elder_ironbranch";
+ newscript->GetAI = &GetAI_boss_elder_ironbranch;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_elder_stonebark";
+ newscript->GetAI = &GetAI_boss_elder_stonebark;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_freya_ground";
+ newscript->GetAI = &GetAI_mob_freya_ground;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_freya_spawned";
+ newscript->GetAI = &GetAI_mob_freya_spawned;
+ newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "mob_iron_roots";
+ newscript->GetAI = &GetAI_mob_iron_roots;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/ulduar/ulduar/boss_hodir.cpp b/scripts/northrend/ulduar/ulduar/boss_hodir.cpp
index 8cc7e64..77fb44d 100644
--- a/scripts/northrend/ulduar/ulduar/boss_hodir.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_hodir.cpp
@@ -1,45 +1,1098 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_hodir
-SD%Complete: 0%
-SDComment:
+SD%Complete: 60%
+SDComment:Auras needs core fix
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_AGGRO = -1603086,
- SAY_SLAY_1 = -1603087,
- SAY_SLAY_2 = -1603088,
- SAY_FLASH_FREEZE = -1603089,
- SAY_FROZEN_BLOWS = -1603090,
- SAY_DEATH = -1603091,
- SAY_BERSERK = -1603092,
- SAY_HELP_YOGG = -1603093,
+ SPELL_ENRAGE = 26662,
+
+ SPELL_FROZEN_BLOWS = 62478,
+ SPELL_FROZEN_BLOWS_H = 63512,
+ SPELL_FREEZE = 62469,
+ SPELL_BITTER_COLD = 62038, // SPELL BROKEN!!!!
+ SPELL_ICICLE = 62460, // full spell -> needs core fix
+ SPELL_ICE_SHARDS = 65370, // icicle damage -> 14k
+ SPELL_ICICLE_DUMMY = 62453,
+ SPELL_SNOWDRIFT = 62463,
+ SPELL_FLASH_FREEZE = 61968,
+ SPELL_FLASH_FREEZE_VIS = 62148,
+ SPELL_FLASH_FREEZE_STUN = 64175,
+ SPELL_FLASH_FREEZE_KILL = 62226,
+ SPELL_FLASH_FREEZE_NPC_STUN = 61990, // used to freeze npcs
+
+ NPC_SNOWDRIFT_TARGET = 33174,
+ NPC_ICICLE = 33169,
+ NPC_SNOW_ICICLE = 33173,
+ NPC_FLASH_FREEZE = 32926,
+ NPC_FLASH_FREEZE_NPC = 32938,
+
+ SAY_AGGRO = -1603085,
+ SAY_DEATH = -1603084,
+ SAY_SLAY01 = -1603083,
+ SAY_SLAY02 = -1603082,
+ SAY_FLASH_FREEZE = -1603081,
+ SAY_FROZEN_BLOWS = -1603080,
+ SAY_BERSERK = -1603087,
+ EMOTE_FLASH_FREEZE = -1603360,
+ EMOTE_FROZEN_BLOWS = -1603361,
+
+ ACHIEV_RARE_CACHE = 3182,
+ ACHIEV_RARE_CACHE_H = 3184,
+ ACHIEV_COOLEST_FRIEND = 2963,
+ ACHIEV_COOLEST_FRIEND_H = 2965,
+ ACHIEV_GETTING_COLD = 2967,
+ ACHIEV_GETTING_COLD_H = 2968,
+ ACHIEV_CHEESE_FREEZE = 2961,
+ ACHIEV_CHEESE_FREEZE_H = 2962,
+
+ // helper npcs
+ // druid
+ SPELL_WRATH = 62793,
+ SPELL_STARLIGHT = 62807, // friendly
+
+ // shaman
+ SPELL_LAVA_BURST = 61924,
+ SPELL_STORM_CLOUD = 65123, // friendly
+ SPELL_STORM_CLOUD_H = 65133,
+ SPELL_STORM_POWER = 65134, // friendly
+
+ // mage
+ SPELL_FIREBALL = 61909,
+ SPELL_TOASTY_FIRE = 62823, // friendly -> summon
+ NPC_TOASTY_FIRE = 33342,
+ SPELL_TOASTY_FIRE_A = 62821,
+ SPELL_MELT_ICE = 64528,
+ SPELL_SIGNED = 65280,
+
+ // priest
+ SPELL_SMITE = 61923,
+ SPELL_GREAT_HEAL = 62809, //friendly
+ SPELL_DISPEL_MAGIC = 63499, //friendly
- EMOTE_FLASH_FREEZE = -1603094,
- EMOTE_FROZEN_BLOWS = -1603095,
};
-void AddSC_boss_hodir()
+#define CENTER_X 2000.0f
+#define CENTER_Y -234.21f
+
+bool m_bCoolestFriend;
+
+// script for Flash freeze
+struct MANGOS_DLL_DECL mob_flashFreezeAI : public ScriptedAI
+{
+ mob_flashFreezeAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pCreature->SetDisplayId(11686); // make invisible
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ uint64 m_uiVictimGUID;
+
+ void Reset()
+ {
+ m_uiVictimGUID = 0;
+ if(m_bIsRegularMode)
+ m_creature->SetMaxHealth(35000);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoCast(pWho, SPELL_FLASH_FREEZE_STUN);
+ pWho->CastSpell(pWho, SPELL_FLASH_FREEZE_STUN, false);
+ m_uiVictimGUID = pWho->GetGUID();
+ // kill targets that are frozen
+ if(pWho->HasAura(SPELL_FREEZE, EFFECT_INDEX_0))
+ {
+ pWho->CastSpell(pWho, SPELL_FLASH_FREEZE_KILL, false);
+ m_creature->ForcedDespawn();
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim)
+ pVictim->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_STUN);
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID))
+ pVictim->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_STUN);
+
+ if (Killer)
+ Killer->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_STUN);
+ }
+
+ void UpdateAI(const uint32 diff) {}
+};
+
+// script for Icicles
+struct MANGOS_DLL_DECL mob_icicleAI : public ScriptedAI
+{
+ mob_icicleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ SetCombatMovement(false);
+ pCreature->setFaction(14);
+ Reset();
+ }
+
+ uint32 m_uiSpellDelayTimer;
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_ICICLE);
+ m_uiSpellDelayTimer = 500;
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(m_uiSpellDelayTimer < diff)
+ {
+ DoCast(m_creature, SPELL_ICICLE_DUMMY);
+ m_uiSpellDelayTimer = 30000;
+ }
+ else m_uiSpellDelayTimer -= diff;
+ }
+};
+
+// Toasty fire. Used by mage
+struct MANGOS_DLL_DECL mob_toasty_fireAI : public ScriptedAI
+{
+ mob_toasty_fireAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pCreature->SetDisplayId(11686); // make invisible
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_TOASTY_FIRE_A);
+ }
+
+ void UpdateAI(const uint32 diff) {}
+};
+
+// Script for the Flash freeze which is enchasing the npcs in ice at the begginign of the fight
+// this needs some fixing on spells
+struct MANGOS_DLL_DECL mob_npc_flashFreezeAI : public ScriptedAI
+{
+ mob_npc_flashFreezeAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetDisplayId(25865); // invisible
+ pCreature->GetMotionMaster()->MoveIdle();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ std::list lVictims;
+
+ void Reset()
+ {
+ lVictims.clear();
+ SetVictim();
+ DoCast(m_creature, SPELL_FLASH_FREEZE_NPC_STUN);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if (Creature* pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f))
+ {
+ pHodir->AI()->AttackStart(who);
+ pHodir->AddThreat(who, 0.0f);
+ }
+ }
+
+ void SetVictim()
+ {
+ // druids
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33325, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32901, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32941, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33333, 2.0f);
+ // shamys
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33328, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32900, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33332, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32950, 2.0f);
+ // mages
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32893, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33327, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33331, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32946, 2.0f);
+ // priests
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32897, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33326, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 32948, 2.0f);
+ GetCreatureListWithEntryInGrid(lVictims, m_creature, 33330, 2.0f);
+ if (!lVictims.empty())
+ {
+ for(std::list::iterator iter = lVictims.begin(); iter != lVictims.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive() && !(*iter)->HasAura(SPELL_FLASH_FREEZE_NPC_STUN, EFFECT_INDEX_0))
+ (*iter)->CastSpell((*iter), SPELL_FLASH_FREEZE_NPC_STUN, false);
+ }
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (!lVictims.empty())
+ {
+ for(std::list::iterator iter = lVictims.begin(); iter != lVictims.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive() && (*iter)->HasAura(SPELL_FLASH_FREEZE_NPC_STUN, EFFECT_INDEX_0))
+ {
+ (*iter)->RemoveAurasDueToSpell(SPELL_FLASH_FREEZE_NPC_STUN);
+ if (Creature* pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f))
+ (*iter)->AddThreat(pHodir, 100.0f);
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ { }
+};
+
+// Hodir
+struct MANGOS_DLL_DECL boss_hodirAI : public ScriptedAI
+{
+ boss_hodirAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ // hard mode timer
+ uint32 m_uiSpeedKillTimer;
+
+ uint32 m_uiEnrageTimer;
+ uint32 m_uiFlashFreezeTimer;
+ uint32 m_uiFlashFreezeCastTimer;
+ uint32 m_uiFrozenBlowsTimer;
+ uint32 m_uiFreezeTimer;
+ uint32 m_uiIcicleTimer;
+ uint8 m_uiIcicleCount;
+ bool m_bIsCheese;
+
+ bool m_bIsOutro;
+ uint32 m_uiOutroTimer;
+ uint32 m_uiStep;
+
+ std::list lFriends;
+
+ void Reset()
+ {
+ m_uiSpeedKillTimer = 0;
+ m_bCoolestFriend = true;
+ m_uiEnrageTimer = 480000;
+ m_uiFlashFreezeTimer = 50000;
+ m_uiFlashFreezeCastTimer= 90000;
+ m_uiFrozenBlowsTimer = 60000;
+ m_uiFreezeTimer = urand(15000, 20000);
+ m_uiIcicleTimer = 10000;
+ m_uiIcicleCount = 0;
+ m_uiOutroTimer = 10000;
+ m_uiStep = 1;
+ m_bIsOutro = false;
+ m_bIsCheese = true;
+
+ // respawn friendly npcs
+ // druids
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33325, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32901, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32941, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33333, DEFAULT_VISIBILITY_INSTANCE);
+ // shamys
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33328, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32900, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33332, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32950, DEFAULT_VISIBILITY_INSTANCE);
+ // mages
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32893, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33327, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33331, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32946, DEFAULT_VISIBILITY_INSTANCE);
+ // priests
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32897, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33326, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32948, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 33330, DEFAULT_VISIBILITY_INSTANCE);
+ // flash freeze for them:
+ GetCreatureListWithEntryInGrid(lFriends, m_creature, 32938, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lFriends.empty())
+ {
+ for(std::list::iterator iter = lFriends.begin(); iter != lFriends.end(); ++iter)
+ {
+ if ((*iter) && !(*iter)->isAlive())
+ (*iter)->Respawn();
+ }
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_HODIR, NOT_STARTED);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_HODIR, IN_PROGRESS);
+
+ DoScriptText(SAY_AGGRO, m_creature);
+
+ DoCast(m_creature, SPELL_BITTER_COLD);
+ }
+
+ void DoOutro()
+ {
+ if(m_pInstance)
+ {
+ if(m_uiSpeedKillTimer < 180000)
+ {
+ m_pInstance->SetData(TYPE_HODIR_HARD, DONE);
+ m_pInstance->SetData(TYPE_HODIR, DONE);
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_RARE_CACHE : ACHIEV_RARE_CACHE_H);
+ }
+ else
+ m_pInstance->SetData(TYPE_HODIR, DONE);
+
+ // hacky way to complete achievements; use only if you have this function
+ if (m_bCoolestFriend)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_COOLEST_FRIEND : ACHIEV_COOLEST_FRIEND_H);
+
+ if (m_bIsCheese)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHEESE_FREEZE : ACHIEV_CHEESE_FREEZE_H);
+ }
+ m_creature->ForcedDespawn();
+ }
+
+ // for debug only
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_HODIR, DONE);
+ if(m_uiSpeedKillTimer > 0)
+ m_pInstance->SetData(TYPE_HODIR_HARD, DONE);
+ }
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(m_creature->GetHealthPercent() < 1.0f)
+ {
+ uiDamage = 0;
+ m_bIsOutro = true;
+ }
+ }
+
+ void KilledUnit(Unit *who)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY01, m_creature);
+ else
+ DoScriptText(SAY_SLAY02, m_creature);
+ }
+
+ // Flash freeze. Hacky way, needs core support
+ // PLEASE REMOVE FOR REVISION!
+ void DoFlashFreeze()
+ {
+ std::list lSnowdrift;
+ GetCreatureListWithEntryInGrid(lSnowdrift, m_creature, NPC_SNOWDRIFT_TARGET, DEFAULT_VISIBILITY_INSTANCE);
+
+ Map* pMap = m_creature->GetMap();
+ if(pMap)
+ {
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ if (!lPlayers.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ if (Player* pPlayer = itr->getSource())
+ {
+ if(pPlayer && pPlayer->isAlive())
+ {
+ if (!lSnowdrift.empty())
+ {
+ for(std::list::iterator iter = lSnowdrift.begin(); iter != lSnowdrift.end(); ++iter)
+ {
+ if ((*iter) && pPlayer->GetDistance2d((*iter)) > 5.0f)
+ {
+ if(Creature* pTemp = m_creature->SummonCreature(NPC_FLASH_FREEZE, pPlayer->GetPositionX(), pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000))
+ pTemp->AddThreat(pPlayer, 100.0f);
+ // don't complete achievement
+ m_bIsCheese = false;
+ }
+ }
+ }
+ else
+ {
+ if(Creature* pTemp = m_creature->SummonCreature(NPC_FLASH_FREEZE, pPlayer->GetPositionX(), pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000))
+ pTemp->AddThreat(pPlayer, 100.0f);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(!m_bIsOutro)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // reset if fighting only the npcs
+ // this gets bugged if some of the npcs get top aggro
+ if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER)
+ EnterEvadeMode();
+
+ // hard mode check
+ m_uiSpeedKillTimer += uiDiff;
+
+ // Flash freeze visual
+ if(m_uiFlashFreezeTimer < uiDiff)
+ {
+ DoScriptText(EMOTE_FLASH_FREEZE, m_creature);
+ DoScriptText(SAY_FLASH_FREEZE, m_creature);
+ DoCast(m_creature, SPELL_FLASH_FREEZE);
+ m_uiFlashFreezeTimer = 50000;
+ m_uiFlashFreezeCastTimer = 9000;
+ }
+ else m_uiFlashFreezeTimer -= uiDiff;
+
+ // hacky way for flash freeze
+ if (m_uiFlashFreezeCastTimer < uiDiff)
+ {
+ DoFlashFreeze();
+ DoCast(m_creature, SPELL_FLASH_FREEZE_VIS);
+ m_uiFlashFreezeCastTimer = 90000;
+ }
+ else m_uiFlashFreezeCastTimer -= uiDiff;
+
+ // icicles
+ // should be done be spell
+ if(m_uiIcicleTimer < uiDiff)
+ {
+ float angle = (float) rand()*360/RAND_MAX + 1;
+ float homeX = CENTER_X + urand(0, 30)*cos(angle*(M_PI/180));
+ float homeY = CENTER_Y + urand(0, 30)*sin(angle*(M_PI/180));
+ m_creature->SummonCreature(NPC_ICICLE, homeX, homeY, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 3000);
+ m_uiIcicleTimer = urand(2000, 5000);
+ }
+ else m_uiIcicleTimer -= uiDiff;
+
+ // frozen blows
+ if(m_uiFrozenBlowsTimer < uiDiff)
+ {
+ DoScriptText(SAY_FROZEN_BLOWS, m_creature);
+ DoScriptText(EMOTE_FROZEN_BLOWS, m_creature);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_FROZEN_BLOWS : SPELL_FROZEN_BLOWS_H);
+ m_uiFrozenBlowsTimer = urand(50000, 60000);
+ }
+ else m_uiFrozenBlowsTimer -= uiDiff;
+
+ // freeze
+ if(m_uiFreezeTimer < uiDiff)
+ {
+ if(Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_FREEZE);
+ m_uiFreezeTimer = urand(5000, 10000);
+ }
+ else m_uiFreezeTimer -= uiDiff;
+
+ // enrage
+ if(m_uiEnrageTimer < uiDiff)
+ {
+ DoScriptText(SAY_BERSERK, m_creature);
+ DoCast(m_creature, SPELL_ENRAGE);
+ m_uiEnrageTimer = 30000;
+ }
+ else m_uiEnrageTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+ // outro
+ if(m_bIsOutro)
+ {
+ switch(m_uiStep)
+ {
+ case 1:
+ m_creature->setFaction(35);
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MovePoint(0, 1984.64f, -206.37f, 432.68f);
+ ++m_uiStep;
+ m_uiOutroTimer = 10000;
+ break;
+ case 3:
+ DoScriptText(SAY_DEATH, m_creature);
+ ++m_uiStep;
+ m_uiOutroTimer = 5000;
+ break;
+ case 5:
+ DoOutro();
+ ++m_uiStep;
+ m_uiOutroTimer = 10000;
+ break;
+ }
+ }
+ else return;
+
+ if (m_uiOutroTimer <= uiDiff)
+ {
+ ++m_uiStep;
+ m_uiOutroTimer = 330000;
+ } m_uiOutroTimer -= uiDiff;
+ }
+};
+
+// Helper npcs
+struct MANGOS_DLL_DECL npc_hodir_druidAI : public ScriptedAI
+{
+ npc_hodir_druidAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ uint32 spellTimer;
+ std::list FriendlyList;
+
+ void Reset()
+ {
+ spellTimer = 5000;
+ FriendlyList.clear();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_bCoolestFriend = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ // friendly list
+ if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true))
+ FriendlyList.push_back(pWho->GetGUID());
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho, 20.0f);
+ }
+ }
+
+ uint64 SelectRandomPlayer()
+ {
+ //This should not appear!
+ if (FriendlyList.empty()){
+ spellTimer = 5000;
+ return m_creature->GetGUID();
+ }
+
+ std::list::iterator iter = FriendlyList.begin();
+ advance(iter, urand(0, FriendlyList.size()-1));
+
+ return *iter;
+ }
+
+ bool ListContains(std::list &plist, uint64 element)
+ {
+ if (plist.empty())
+ return false;
+
+ std::list::iterator i;
+ for (i = plist.begin(); i!=plist.end(); ++i)
+ {
+ if ((*i) == element)
+ return true;
+ }
+ return false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (spellTimer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f))
+ DoCast(pHodir, SPELL_WRATH);
+ break;
+ case 1:
+ Unit *pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer()));
+ if (pTemp && pTemp->isAlive() && m_creature->GetDistance(pTemp) < 40)
+ DoCast(pTemp, SPELL_STARLIGHT);
+ break;
+ }
+ spellTimer = urand(2000, 5000);
+ }else spellTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_hodir_druid(Creature* pCreature)
+{
+ return new npc_hodir_druidAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_hodir_shamanAI : public ScriptedAI
+{
+ npc_hodir_shamanAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance *pInstance;
+
+ uint32 spellTimer;
+ std::list FriendlyList;
+
+ void Reset()
+ {
+ spellTimer = 5000;
+ FriendlyList.clear();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_bCoolestFriend = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ // friendly list
+ if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true))
+ FriendlyList.push_back(pWho->GetGUID());
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho, 20.0f);
+ }
+ }
+
+ uint64 SelectRandomPlayer()
+ {
+ //This should not appear!
+ if (FriendlyList.empty()){
+ spellTimer = 5000;
+ return m_creature->GetGUID();
+ }
+
+ std::list::iterator iter = FriendlyList.begin();
+ advance(iter, urand(0, FriendlyList.size()-1));
+
+ return *iter;
+ }
+
+ bool ListContains(std::list &plist, uint64 element)
+ {
+ if (plist.empty())
+ return false;
+
+ std::list::iterator i;
+ for (i = plist.begin(); i!=plist.end(); ++i)
+ {
+ if ((*i) == element)
+ return true;
+ }
+ return false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (spellTimer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f))
+ DoCast(pHodir, SPELL_LAVA_BURST);
+ break;
+ case 1:
+ Unit *pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer()));
+ if (pTemp && pTemp->isAlive() && m_creature->GetDistance(pTemp) < 40)
+ DoCast(pTemp, m_bIsRegularMode ? SPELL_STORM_CLOUD : SPELL_STORM_CLOUD_H);
+ break;
+ }
+ spellTimer = urand(2000,5000);
+ }else spellTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_hodir_shaman(Creature* pCreature)
+{
+ return new npc_hodir_shamanAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_hodir_mageAI : public ScriptedAI
+{
+ npc_hodir_mageAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ uint32 spellTimer;
+ std::list FriendlyList;
+
+ void Reset()
+ {
+ spellTimer = 5000;
+ FriendlyList.clear();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_bCoolestFriend = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ // friendly list
+ if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true))
+ FriendlyList.push_back(pWho->GetGUID());
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho, 20.0f);
+ }
+ }
+
+ uint64 SelectRandomPlayer()
+ {
+ //This should not appear!
+ if (FriendlyList.empty()){
+ spellTimer = 5000;
+ return m_creature->GetGUID();
+ }
+
+ std::list::iterator iter = FriendlyList.begin();
+ advance(iter, urand(0, FriendlyList.size()-1));
+
+ return *iter;
+ }
+
+ bool ListContains(std::list &plist, uint64 element)
+ {
+ if (plist.empty())
+ return false;
+
+ std::list::iterator i;
+ for (i = plist.begin(); i!=plist.end(); ++i)
+ {
+ if ((*i) == element)
+ return true;
+ }
+ return false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (spellTimer < uiDiff)
+ {
+ switch(urand(0, 4))
+ {
+ case 0:
+ if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f))
+ DoCast(pHodir, SPELL_FIREBALL);
+ break;
+ case 1:
+ case 2:
+ if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f))
+ DoCast(pHodir, SPELL_SIGNED);
+ break;
+ case 3:
+ if(Creature *pTemp = GetClosestCreatureWithEntry(m_creature, NPC_FLASH_FREEZE, 50.0f))
+ DoCast(pTemp, SPELL_MELT_ICE);
+ break;
+ case 4:
+ Unit *pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer()));
+ if (pTemp && pTemp->isAlive() && m_creature->GetDistance(pTemp) < 40)
+ DoCast(pTemp, SPELL_TOASTY_FIRE);
+ break;
+ }
+ spellTimer = urand(2000,5000);
+ }else spellTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_hodir_mage(Creature* pCreature)
+{
+ return new npc_hodir_mageAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_hodir_priestAI : public ScriptedAI
+{
+ npc_hodir_priestAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ uint32 spellTimer;
+ std::list FriendlyList;
+
+ void Reset()
+ {
+ spellTimer = 5000;
+ FriendlyList.clear();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_bCoolestFriend = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ // friendly list
+ if (!m_creature->IsHostileTo(pWho) && !ListContains(FriendlyList, pWho->GetGUID()) && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 40, true))
+ FriendlyList.push_back(pWho->GetGUID());
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho, 20.0f);
+ }
+ }
+
+ uint64 SelectRandomPlayer()
+ {
+ //This should not appear!
+ if (FriendlyList.empty()){
+ spellTimer = 5000;
+ return m_creature->GetGUID();
+ }
+
+ std::list::iterator iter = FriendlyList.begin();
+ advance(iter, urand(0, FriendlyList.size()-1));
+
+ return *iter;
+ }
+
+ bool ListContains(std::list &plist, uint64 element)
+ {
+ if (plist.empty())
+ return false;
+
+ std::list::iterator i;
+ for (i = plist.begin(); i!=plist.end(); ++i)
+ {
+ if ((*i) == element)
+ return true;
+ }
+ return false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (spellTimer < uiDiff)
+ {
+ switch(urand(0, 4))
+ {
+ case 0:
+ if(Creature *pHodir = GetClosestCreatureWithEntry(m_creature, NPC_HODIR, 100.0f))
+ DoCast(pHodir, SPELL_SMITE);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ if (Unit* pHealTarget = DoSelectLowestHpFriendly(40.0f))
+ DoCast(pHealTarget, SPELL_GREAT_HEAL);
+ break;
+ case 4:
+ if (Unit* pTemp = m_creature->GetMap()->GetUnit((SelectRandomPlayer())))
+ DoCast(m_creature, SPELL_DISPEL_MAGIC);
+ break;
+ }
+ spellTimer = urand(2000,5000);
+ }else spellTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_hodir_priest(Creature* pCreature)
+{
+ return new npc_hodir_priestAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_hodir(Creature* pCreature)
{
+ return new boss_hodirAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_flashFreeze(Creature* pCreature)
+{
+ return new mob_flashFreezeAI(pCreature);
+}
+CreatureAI* GetAI_mob_icicle(Creature* pCreature)
+{
+ return new mob_icicleAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_toasty_fire(Creature* pCreature)
+{
+ return new mob_toasty_fireAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_npc_flashFreeze(Creature* pCreature)
+{
+ return new mob_npc_flashFreezeAI(pCreature);
}
+
+void AddSC_boss_hodir()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_hodir";
+ newscript->GetAI = &GetAI_boss_hodir;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_flashFreeze";
+ newscript->GetAI = &GetAI_mob_flashFreeze;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_npc_flashFreeze";
+ newscript->GetAI = &GetAI_mob_npc_flashFreeze;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_icicle";
+ newscript->GetAI = &GetAI_mob_icicle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_toasty_fire";
+ newscript->GetAI = &GetAI_mob_toasty_fire;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_hodir_priest";
+ newscript->GetAI = &GetAI_npc_hodir_priest;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_hodir_mage";
+ newscript->GetAI = &GetAI_npc_hodir_mage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_hodir_druid";
+ newscript->GetAI = &GetAI_npc_hodir_druid;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_hodir_shaman";
+ newscript->GetAI = &GetAI_npc_hodir_shaman;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_ignis.cpp b/scripts/northrend/ulduar/ulduar/boss_ignis.cpp
index ea98109..9655367 100644
--- a/scripts/northrend/ulduar/ulduar/boss_ignis.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_ignis.cpp
@@ -1,45 +1,529 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_ignis
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: slag pot damage missing
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_AGGRO = -1603026,
- SAY_SCORCH_1 = -1603027,
- SAY_SCORCH_2 = -1603028,
- SAY_SLAGPOT = -1603029,
- SAY_ADDS = -1603030,
- SAY_SLAY_1 = -1603031,
- SAY_SLAY_2 = -1603032,
- SAY_BERSERK = -1603033,
- SAY_DEATH = -1603034,
-
- EMOTE_FLAME_JETS = -1603035,
+ //yells
+ SAY_AGGRO = -1603010,
+ SAY_SCORCH1 = -1603011,
+ SAY_SCORCH2 = -1603012,
+ SAY_SLAGPOT = -1603013,
+ EMOTE_FLAMEJETS = -1603014,
+ SAY_SUMMON = -1603015,
+ SAY_SLAY1 = -1603016,
+ SAY_SLAY2 = -1603017,
+ SAY_BERSERK = -1603018,
+ SAY_DEATH = -1603019,
+
+ //ignis the furnace master
+ SPELL_FLAME_JETS = 62680,
+ SPELL_FLAME_JETS_H = 63472,
+ SPELL_SLAG_POT = 62717,
+ SPELL_SLAG_POT_H = 63477,
+ SPELL_SLAG_POT_DMG = 65722,
+ SPELL_SLAG_POT_DMG_H = 65723,
+ SPELL_SCORCH = 62546,
+ SPELL_SCORCH_H = 63474,
+ BUFF_STRENGHT_OF_CREATOR = 64473,
+ SPELL_STRENGHT_OF_CREATOR2 = 64474,
+ SPELL_STRENGHT_OF_CREATOR3 = 64475,
+ SPELL_HASTE = 66045,
+ SPELL_ENRAGE = 26662,
+ //iron construct
+ SPELL_HEAT = 65667,
+ SPELL_MOLTEN = 62373,
+ SPELL_BRITTLE = 62382,
+ SPELL_SHATTER = 62383,
+ //scorch target
+ AURA_SCORCH = 62548,
+ AURA_SCORCH_H = 63476,
+ AURA_HEAT = 65667,
+ SPELL_FREEZE_ANIM = 16245,
+ //NPC ids
+ MOB_IRON_CONSTRUCT = 33121,
+ MOB_SCORCH_TARGET = 33221,
+
+ ACHIEV_STOKIN_THE_FURNACE = 2930,
+ ACHIEV_STOKIN_THE_FURNACE_H = 2929,
+ ACHIEV_SHATTERED = 2925,
+ ACHIEV_SHATTERED_H = 2926,
};
-void AddSC_boss_ignis()
+#define HOME_X 586.747009f
+#define HOME_Y 381.997986f
+
+// scorch target
+struct MANGOS_DLL_DECL mob_scorch_targetAI : public ScriptedAI
+{
+ mob_scorch_targetAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiDeath_Timer;
+
+ void Reset()
+ {
+ m_uiDeath_Timer = 55000;
+ m_creature->SetDisplayId(11686);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(m_creature, m_bIsRegularMode ? AURA_SCORCH : AURA_SCORCH_H);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+ if (m_uiDeath_Timer < diff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDeath_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_scorch_target(Creature* pCreature)
+{
+ return new mob_scorch_targetAI(pCreature);
+}
+
+// iron construct
+struct MANGOS_DLL_DECL mob_iron_constructAI : public ScriptedAI
+{
+ mob_iron_constructAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiDeath_Timer;
+ uint32 m_uiAura_Check_Timer;
+ uint32 m_uiScorchTimer;
+ uint32 m_uiMoltenTimer;
+ uint32 m_uiBrittleTimer;
+ bool m_bIsBrittle;
+ bool m_bIsShatter;
+ bool m_bIsMolten;
+ bool m_bIsInCombat;
+
+ uint32 m_uiWaterCheckTimer;
+
+ void Reset()
+ {
+ m_bIsShatter = false;
+ m_bIsBrittle = false;
+ m_bIsMolten = false;
+ m_bIsInCombat = false;
+ m_uiWaterCheckTimer = 1000;
+ m_uiScorchTimer = 5000;
+ m_uiAura_Check_Timer = 1000;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_FREEZE_ANIM);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ // remove 1 stack of the buff from Ignis, hacky way, should be done by spell
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IGNIS)))
+ {
+ if (pTemp->isAlive())
+ {
+ if (pTemp->HasAura(BUFF_STRENGHT_OF_CREATOR))
+ {
+ if(SpellAuraHolder* strenght = pTemp->GetSpellAuraHolder(BUFF_STRENGHT_OF_CREATOR))
+ {
+ if(strenght->ModStackAmount(-1))
+ pTemp->RemoveAurasDueToSpell(BUFF_STRENGHT_OF_CREATOR);
+ }
+ }
+ }
+ }
+ }
+
+ // shatter if is brittle
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if (m_bIsBrittle)
+ {
+ if (uiDamage > 5000)
+ {
+ DoCast(m_creature, SPELL_SHATTER);
+ m_bIsShatter = true;
+ m_bIsBrittle = false;
+ m_uiDeath_Timer = 500;
+ }
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if(!m_bIsInCombat)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho);
+ }
+ }
+
+ // set in combat
+ void GetInCombat()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ if (m_creature->HasAura(SPELL_FREEZE_ANIM, EFFECT_INDEX_0))
+ m_creature->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
+ m_bIsInCombat = true;
+
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_IGNIS)))
+ {
+ if (pTemp->isAlive())
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->GetMotionMaster()->MovePoint(0, pTemp->GetPositionX(), pTemp->GetPositionY(), pTemp->GetPositionZ());
+
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ m_creature->AddThreat(pTarget,100.0f);
+ m_creature->AI()->AttackStart(pTarget);
+ m_creature->SetInCombatWithZone();
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // death after casted shatter
+ if (m_uiDeath_Timer < uiDiff && m_bIsShatter)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDeath_Timer -= uiDiff;
+
+ // check for aura
+ if (m_uiAura_Check_Timer < uiDiff && !m_bIsMolten)
+ {
+ if(Aura* aura = m_creature->GetAura(SPELL_HEAT,EFFECT_INDEX_0))
+ {
+ if(aura->GetStackAmount() > 9)
+ {
+ DoCast(m_creature, SPELL_MOLTEN);
+ m_creature->RemoveAurasDueToSpell(SPELL_HEAT);
+ m_uiMoltenTimer = 30000;
+ m_bIsMolten = true;
+ }
+ }
+ m_uiAura_Check_Timer = 1000;
+ }else m_uiAura_Check_Timer -= uiDiff;
+
+ //Water checks
+ if(m_bIsMolten)
+ {
+ // should work with Vmaps3
+ if (m_uiWaterCheckTimer <= uiDiff)
+ {
+ if(m_creature->IsInWater())
+ {
+ DoCast(m_creature, SPELL_BRITTLE);
+ m_bIsBrittle = true;
+ m_bIsMolten = false;
+ }
+ // workaround
+ /* else use workaround
+ if( m_creature->GetDistance2d(524.15f, 277.0f) < 18 || m_creature->GetDistance2d(648.5f, 277.0f) < 18)
+ {
+ DoCast(m_creature, SPELL_BRITTLE);
+ m_creature->RemoveAurasDueToSpell(SPELL_MOLTEN);
+ m_bIsBrittle = true;
+ m_bIsMolten = false;
+ }*/
+ m_uiWaterCheckTimer = 500;
+ }else m_uiWaterCheckTimer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_iron_construct(Creature* pCreature)
{
+ return new mob_iron_constructAI(pCreature);
+}
+
+//ignis the furnace master
+struct MANGOS_DLL_DECL boss_ignisAI : public ScriptedAI
+{
+ boss_ignisAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ std::list m_lIronConstructGUIDList;
+ uint32 m_uiFlame_Jets_Timer;
+ uint32 m_uiSlag_Pot_Timer;
+ uint32 m_uiSlag_Pot_Dmg_Timer;
+ uint32 m_uiScorch_Timer;
+ uint32 m_uiSummon_Timer;
+ uint32 m_uiPotDmgCount;
+ uint32 m_uiEnrageTimer;
+
+ uint64 m_uiPotTargetGUID;
+ std::list lConstructs;
+
+ uint32 m_uiEncounterTimer;
+ bool m_bHasSlagPotCasted;
+
+ void Reset()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+
+ m_uiFlame_Jets_Timer = 20000;
+ m_uiSlag_Pot_Timer = 25000;
+ m_uiSlag_Pot_Dmg_Timer = 26000;
+ m_uiScorch_Timer = 13000;
+ m_uiSummon_Timer = 10000;
+ m_uiEnrageTimer = 600000; // 10 MIN
+ m_uiPotDmgCount = 0;
+ m_uiPotTargetGUID = 0;
+ m_lIronConstructGUIDList.clear();
+
+ m_uiEncounterTimer = 0;
+ m_bHasSlagPotCasted = false;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_IGNIS, DONE);
+
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if (m_uiEncounterTimer < 240000)
+ {
+ // hacky way to complete achievements; use only if you have this function
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_STOKIN_THE_FURNACE : ACHIEV_STOKIN_THE_FURNACE_H);
+ }
+ }
+
+ Creature* SelectRandomConstruct(float fRange)
+ {
+ std::list lConstructList;
+ GetCreatureListWithEntryInGrid(lConstructList, m_creature, MOB_IRON_CONSTRUCT, fRange);
+
+ if (lConstructList.empty()){
+ m_uiSummon_Timer = 5000;
+ return NULL;
+ }
+
+ std::list::iterator iter = lConstructList.begin();
+ advance(iter, urand(0, lConstructList.size()-1));
+
+ if((*iter)->isAlive())
+ return *iter;
+ else
+ {
+ m_uiSummon_Timer = 500;
+ return NULL;
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_SLAY2, m_creature);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_IGNIS, IN_PROGRESS);
+
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_IGNIS, FAIL);
+
+ // respawn constructs
+ GetCreatureListWithEntryInGrid(lConstructs, m_creature, MOB_IRON_CONSTRUCT, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lConstructs.empty())
+ {
+ for(std::list::iterator iter = lConstructs.begin(); iter != lConstructs.end(); ++iter)
+ {
+ if ((*iter) && !(*iter)->isAlive())
+ (*iter)->Respawn();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ m_uiEncounterTimer += uiDiff;
+
+ // enrage
+ if(m_uiEnrageTimer < uiDiff)
+ {
+ DoScriptText(SAY_BERSERK, m_creature);
+ DoCast(m_creature, SPELL_ENRAGE);
+ m_uiEnrageTimer = 30000;
+ }
+ else m_uiEnrageTimer -= uiDiff;
+
+ if (m_uiFlame_Jets_Timer < uiDiff)
+ {
+ DoScriptText(EMOTE_FLAMEJETS, m_creature);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_JETS : SPELL_FLAME_JETS_H);
+ m_uiFlame_Jets_Timer = 35000;
+ }else m_uiFlame_Jets_Timer -= uiDiff;
+
+ // need vehicle support!!!
+ if (m_uiSlag_Pot_Timer < uiDiff)
+ {
+ DoScriptText(SAY_SLAGPOT, m_creature);
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ {
+ DoCast(target, m_bIsRegularMode ? SPELL_SLAG_POT : SPELL_SLAG_POT_H);
+ m_uiPotTargetGUID = target->GetGUID();
+ }
+ m_uiSlag_Pot_Timer = 30000;
+ m_uiSlag_Pot_Dmg_Timer = 1000;
+ m_bHasSlagPotCasted = true;
+ m_uiPotDmgCount = 0;
+ }else m_uiSlag_Pot_Timer -= uiDiff;
+
+ // hacky way of doing damage
+ if (m_uiSlag_Pot_Dmg_Timer < uiDiff && m_bHasSlagPotCasted)
+ {
+ if (Unit* pPotTarget = m_creature->GetMap()->GetUnit( m_uiPotTargetGUID))
+ {
+ if (m_uiPotDmgCount < 10)
+ DoCast(pPotTarget, m_bIsRegularMode ? SPELL_SLAG_POT_DMG : SPELL_SLAG_POT_DMG_H);
+ else if (m_uiPotDmgCount == 10)
+ {
+ if(pPotTarget->isAlive())
+ pPotTarget->CastSpell(pPotTarget, SPELL_HASTE, false);
+ m_bHasSlagPotCasted = false;
+ }
+ }
+ ++m_uiPotDmgCount;
+ m_uiSlag_Pot_Dmg_Timer = 1000;
+ }else m_uiSlag_Pot_Dmg_Timer -= uiDiff;
+
+ // call the golems
+ if (m_uiSummon_Timer < uiDiff)
+ {
+ DoScriptText(SAY_SUMMON, m_creature);
+
+ if(Creature* pConstruct = SelectRandomConstruct(200.0f))
+ {
+ ((mob_iron_constructAI*)pConstruct->AI())->GetInCombat();
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pConstruct->AddThreat(target, 100.0f);
+ }
+
+ m_uiSummon_Timer = 40000;
+
+ m_creature->InterruptNonMeleeSpells(true);
+ DoCast(m_creature, BUFF_STRENGHT_OF_CREATOR);
+ }else m_uiSummon_Timer -= uiDiff;
+
+ if (m_uiScorch_Timer < uiDiff)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SCORCH1, m_creature);
+ else
+ DoScriptText(SAY_SCORCH2, m_creature);
+
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SCORCH : SPELL_SCORCH_H);
+ if (Creature* pTemp = m_creature->SummonCreature(MOB_SCORCH_TARGET, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), m_creature->getVictim()->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ pTemp->AddThreat(m_creature->getVictim(),0.0f);
+ pTemp->AI()->AttackStart(m_creature->getVictim());
+ }
+ m_uiScorch_Timer = 28000;
+ }else m_uiScorch_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ if (m_creature->GetDistance2d(HOME_X, HOME_Y) > 200)
+ EnterEvadeMode();
+ }
+};
+
+CreatureAI* GetAI_boss_ignis(Creature* pCreature)
+{
+ return new boss_ignisAI(pCreature);
}
+
+void AddSC_boss_ignis()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_ignis";
+ NewScript->GetAI = GetAI_boss_ignis;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_scorch_target";
+ NewScript->GetAI = &GetAI_mob_scorch_target;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_iron_construct";
+ NewScript->GetAI = &GetAI_mob_iron_construct;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_iron_council.cpp b/scripts/northrend/ulduar/ulduar/boss_iron_council.cpp
new file mode 100644
index 0000000..eb5b292
--- /dev/null
+++ b/scripts/northrend/ulduar/ulduar/boss_iron_council.cpp
@@ -0,0 +1,1209 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_iron_council
+SD%Complete:
+SDComment: Supercharge is bugged
+SDCategory: Ulduar
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ulduar.h"
+
+enum
+{
+ //yells
+ SAY_MOLGEIM_AGGRO = -1603040,
+ SAY_MOLGEIM_DEATH1 = -1603041,
+ SAY_MOLGEIM_DEATH2 = -1603042,
+ SAY_MOLGEIM_DEATH_RUNE = -1603043,
+ SAY_MOLGEIM_SUMMON = -1603044,
+ SAY_MOLGEIM_SLAY1 = -1603045,
+ SAY_MOLGEIM_SLAY2 = -1603046,
+ SAY_MOLGEIM_BERSERK = -1603047,
+
+ SAY_STEEL_AGGRO = -1603050,
+ SAY_STEEL_DEATH1 = -1603051,
+ SAY_STEEL_DEATH2 = -1603052,
+ SAY_STEEL_SLAY1 = -1603053,
+ SAY_STEEL_SLAY2 = -1603054,
+ SAY_STEEL_OVERWHELMING = -1603055,
+ SAY_STEEL_BERSERK = -1603056,
+
+ SAY_BRUNDIR_AGGR0 = -1603060,
+ SAY_BRUNDIR_WHIRL = -1603062,
+ SAY_BRUNDIR_DEATH1 = -1603063,
+ SAY_BRUNDIR_DEATH2 = -1603064,
+ SAY_BRUNDIR_SLAY1 = -1603065,
+ SAY_BRUNDIR_SLAY2 = -1603066,
+ SAY_BRUNDIR_BERSERK = -1603067,
+ SAY_BRUNDIR_FLY = -1603068,
+
+ //all
+ SPELL_BERSERK = 47008,
+ SPELL_SUPERCHARGE = 61920, // spell is bugged. Should be cast on other bosses not on players!!!
+ //steelbreaker
+ SPELL_HIGH_VOLTAGE = 61890,
+ SPELL_HIGH_VOLTAGE_H = 63498,
+ SPELL_FUSION_PUNCH = 61903,
+ SPELL_FUSION_PUNCH_H = 63493,
+ SPELL_STATIC_DISRUPTION = 44008,
+ SPELL_STATIC_DISRUPTION_H = 63494,
+ SPELL_POWER = 64637,
+ SPELL_POWER_H = 61888,
+ SPELL_ELECTRICAL_CHARGE = 61902,
+ //runemaster molgeim
+ SPELL_SHIELD = 62274,
+ SPELL_SHIELD_H = 63489,
+ SPELL_RUNE_OF_POWER = 63513,
+ SPELL_RUNE_OF_DEATH = 62269,
+ SPELL_RUNE_OF_DEATH_H = 63490,
+ SPELL_RUNE_OF_SUMMONING = 62273,
+ //rune of power
+ AURA_RUNE_OF_POWER = 61974,
+ //rune of summoning
+ AURA_RUNE_OF_SUMMONING = 62019,
+ //lightning elemental
+ SPELL_LIGHTNING_BLAST = 62054,
+ SPELL_LIGHTNING_BLAST_H = 63491,
+ //stormcaller brundir
+ SPELL_CHAIN_LIGHTNING = 61879,
+ SPELL_CHAIN_LIGHTNING_H = 63479,
+ SPELL_OVERLOAD = 61869,
+ SPELL_LIGHTNING_WHIRL = 61915,
+ SPELL_LIGHTNING_WHIRL_H = 63483,
+ SPELL_STORMSHIELD = 64187,
+ SPELL_LIGHTNING_TENDRILS = 61887,
+ SPELL_LIGHTNING_TENDRILS_H = 63486,
+ LIGHTNING_TENDRILS_VISUAL = 61883,
+ //NPC ids
+ MOB_LIGHTNING_ELEMENTAL = 32958,
+
+ ACHIEV_ON_YOUR_SIDE = 2945,
+ ACHIEV_ON_YOUR_SIDE_H = 2946,
+ SPELL_IRON_BOOT_AURA = 58501,
+
+ ACHIEV_CHOOSE_BRUNDIR = 2940,
+ ACHIEV_CHOOSE_BRUNDIR_H = 2943,
+ ACHIEV_CHOOSE_MOLGEIM = 2939,
+ ACHIEV_CHOOSE_MOLGEIM_H = 2942,
+ ACHIEV_CHOOSE_STEELBREAKER = 2941,
+ ACHIEV_CHOOSE_STEELBREAKER_H= 2944,
+};
+
+// Rune of Power
+struct MANGOS_DLL_DECL mob_rune_of_powerAI : public ScriptedAI
+{
+ mob_rune_of_powerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ uint32 m_uiDeath_Timer;
+
+ void Reset()
+ {
+ m_uiDeath_Timer = 60000;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(m_creature, AURA_RUNE_OF_POWER);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_uiDeath_Timer < diff)
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }else m_uiDeath_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_rune_of_power(Creature* pCreature)
+{
+ return new mob_rune_of_powerAI(pCreature);
+}
+
+// Lightning Elemental
+struct MANGOS_DLL_DECL mob_ulduar_lightning_elementalAI : public ScriptedAI
+{
+ mob_ulduar_lightning_elementalAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiDeath_Timer;
+ uint32 m_uiCheck_Timer;
+ bool m_bWillExplode;
+
+ void Reset()
+ {
+ m_bWillExplode = false;
+ m_uiCheck_Timer = 1000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiDeath_Timer < diff && m_bWillExplode)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDeath_Timer -= diff;
+
+ if (m_uiCheck_Timer < diff)
+ {
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 15))
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_BLAST : SPELL_LIGHTNING_BLAST_H);
+ m_bWillExplode = true;
+ m_uiDeath_Timer = 500;
+ m_uiCheck_Timer = 5000;
+ }
+ m_uiCheck_Timer = 1000;
+ }else m_uiCheck_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_ulduar_lightning_elemental(Creature* pCreature)
+{
+ return new mob_ulduar_lightning_elementalAI(pCreature);
+}
+
+// Rune of Summoning
+struct MANGOS_DLL_DECL mob_rune_of_summoningAI : public ScriptedAI
+{
+ mob_rune_of_summoningAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiDeath_Timer;
+ uint32 m_uiSummon_Timer;
+ uint32 m_uiSummonNum;
+
+ void Reset()
+ {
+ m_uiDeath_Timer = 0;
+ m_uiSummon_Timer = 5000;
+ m_uiSummonNum = 0;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(m_creature, AURA_RUNE_OF_SUMMONING);
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ pSummoned->SetInCombatWithZone();
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ pSummoned->AddThreat(pTarget, 100.0f);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_uiSummon_Timer < diff)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(MOB_LIGHTNING_ELEMENTAL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ ++m_uiSummonNum;
+
+ if (m_uiSummonNum > 9)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+ m_uiSummon_Timer = 500;
+ } else m_uiSummon_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_rune_of_summoning(Creature* pCreature)
+{
+ return new mob_rune_of_summoningAI(pCreature);
+}
+
+//Stormcaller Brundir
+struct MANGOS_DLL_DECL boss_brundirAI : public ScriptedAI
+{
+ boss_brundirAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiChain_Lightning_Timer;
+ uint32 m_uiOverload_Timer;
+ uint32 m_uiWhirl_Timer;
+ uint32 m_uiTendrils_start_Timer;
+ uint32 m_uiTendrils_Change;
+ uint32 m_uiTendrils_end_Timer;
+ uint32 m_uiDie_delay;
+ uint32 m_uiEnrage_Timer;
+ uint32 m_uiCheckTimer;
+
+ bool m_bHasSupercharge1;
+ bool m_bHasSupercharge2;
+ bool m_bIsTendrils;
+ bool m_bMustDie;
+ bool m_bIsSteelbreakerDead;
+ bool m_bIsMolgeimDead;
+ bool m_bIsEnrage;
+
+ void Reset()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_uiChain_Lightning_Timer = 0;
+ m_uiOverload_Timer = 35000;
+ m_uiEnrage_Timer = 900000;
+ m_uiCheckTimer = 1000;
+ m_bIsEnrage = false;
+ m_bHasSupercharge1 = false;
+ m_bHasSupercharge2 = false;
+ m_bIsTendrils = false;
+ m_bIsSteelbreakerDead = false;
+ m_bIsMolgeimDead = false;
+ m_bMustDie = false;
+ if (m_creature->HasAura(SPELL_SUPERCHARGE))
+ m_creature->RemoveAurasDueToSpell(SPELL_SUPERCHARGE);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth() && !m_bMustDie)
+ {
+ uiDamage = 0;
+ m_creature->CastStop();
+ m_creature->RemoveAllAuras();
+ DoCast(m_creature, SPELL_SUPERCHARGE);
+ m_uiDie_delay = 500;
+ m_bMustDie = true;
+ }
+ }
+
+ void OnYourSide()
+ {
+ /* hacky way to complete achievements; use only if you have this function
+ Map* pMap = m_creature->GetMap();
+ AchievementEntry const *AchievYourSide = GetAchievementStore()->LookupEntry(m_bIsRegularMode ? ACHIEV_ON_YOUR_SIDE : ACHIEV_ON_YOUR_SIDE_H);
+ if(AchievYourSide && pMap)
+ {
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ if (!lPlayers.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ if (Player* pPlayer = itr->getSource())
+ {
+ if(pPlayer->HasAura(SPELL_IRON_BOOT_AURA, EFFECT_INDEX_0))
+ pPlayer->CompletedAchievement(AchievYourSide);
+ }
+ }
+ }
+ }
+ */
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ // if all of them are dead
+ if (m_pInstance)
+ {
+ // remove supercharge from players -> spell bug
+ //m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SUPERCHARGE);
+ // if the others are dead then give loot
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (!pTemp->isAlive())
+ {
+ if (Creature* p2Temp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (!p2Temp->isAlive())
+ {
+ m_pInstance->SetData(TYPE_ASSEMBLY, DONE);
+ // only the current one has loot, because loot modes are implemented in sql
+ m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ // I'm on your side
+ OnYourSide();
+
+ // ChooseBrundir
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHOOSE_BRUNDIR : ACHIEV_CHOOSE_BRUNDIR_H);
+ }
+ }
+ }
+ }
+
+ // else make them full hp
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetHealth(pTemp->GetMaxHealth());
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetHealth(pTemp->GetMaxHealth());
+ }
+ }
+
+ if(irand(0,1))
+ DoScriptText(SAY_BRUNDIR_DEATH1, m_creature);
+ else
+ DoScriptText(SAY_BRUNDIR_DEATH2, m_creature);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ if (m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_ASSEMBLY) != IN_PROGRESS)
+ m_pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS);
+ }
+
+ DoScriptText(SAY_BRUNDIR_AGGR0, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ if (m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_ASSEMBLY) != FAIL)
+ m_pInstance->SetData(TYPE_ASSEMBLY, FAIL);
+ }
+ }
+
+ void KilledUnit(Unit *who)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_BRUNDIR_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_BRUNDIR_SLAY2, m_creature);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // level 1 spells
+ if (m_uiChain_Lightning_Timer < uiDiff && !m_bIsTendrils)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H);
+ m_uiChain_Lightning_Timer = 2000;
+ }else m_uiChain_Lightning_Timer -= uiDiff;
+
+ if (m_uiOverload_Timer < uiDiff && !m_bIsTendrils)
+ {
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_OVERLOAD);
+ m_uiOverload_Timer = 40000;
+ }else m_uiOverload_Timer -= uiDiff;
+
+ // level 2 spells
+ if (m_uiWhirl_Timer < uiDiff && !m_bIsTendrils && m_bHasSupercharge1)
+ {
+ m_creature->CastStop();
+ DoScriptText(SAY_BRUNDIR_WHIRL, m_creature);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_WHIRL : SPELL_LIGHTNING_WHIRL_H);
+ m_uiWhirl_Timer = 15000;
+ }else m_uiWhirl_Timer -= uiDiff;
+
+ // level 3 spells
+ // boss doesn't fly during tendrils, needs fixing!
+ if (m_uiTendrils_start_Timer < uiDiff && m_bHasSupercharge2)
+ {
+ if (!m_bIsTendrils)
+ {
+ DoScriptText(SAY_BRUNDIR_FLY, m_creature);
+ m_creature->CastStop();
+ DoCast(m_creature, LIGHTNING_TENDRILS_VISUAL);
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ m_creature->AddThreat(pTarget,0.0f);
+ m_creature->AI()->AttackStart(pTarget);
+ }
+ m_bIsTendrils = true;
+ m_creature->SetSpeedRate(MOVE_RUN, 0.8f);
+ m_uiTendrils_start_Timer = 3000;
+ m_uiTendrils_end_Timer = 40000;
+ m_uiTendrils_Change = 5000;
+ }
+ else
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_TENDRILS : SPELL_LIGHTNING_TENDRILS_H);
+ m_uiTendrils_start_Timer = 90000;
+ }
+ }else m_uiTendrils_start_Timer -= uiDiff;
+
+ if (m_uiTendrils_Change < uiDiff && m_bIsTendrils)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ m_creature->AddThreat(pTarget,0.0f);
+ m_creature->AI()->AttackStart(pTarget);
+ }
+ m_uiTendrils_Change = 6000;
+ }else m_uiTendrils_Change -= uiDiff;
+
+ if (m_uiTendrils_end_Timer < uiDiff && m_bIsTendrils)
+ {
+ if (m_creature->HasAura(SPELL_LIGHTNING_TENDRILS))
+ m_creature->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS);
+ if (m_creature->HasAura(SPELL_LIGHTNING_TENDRILS_H))
+ m_creature->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS_H);
+ if (m_creature->HasAura(LIGHTNING_TENDRILS_VISUAL))
+ m_creature->RemoveAurasDueToSpell(LIGHTNING_TENDRILS_VISUAL);
+ m_uiTendrils_start_Timer = 90000;
+ m_creature->SetSpeedRate(MOVE_RUN, 1.8f);
+ m_bIsTendrils = false;
+ m_uiChain_Lightning_Timer = 5000;
+ m_uiOverload_Timer = 35000;
+ m_uiWhirl_Timer = 10000;
+ }else m_uiTendrils_end_Timer -= uiDiff;
+
+ // die after casting supercharge
+ if (m_uiDie_delay < uiDiff && m_bMustDie)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDie_delay -= uiDiff;
+
+ if (m_uiEnrage_Timer < uiDiff && !m_bIsEnrage)
+ {
+ DoScriptText(SAY_BRUNDIR_BERSERK, m_creature);
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_BERSERK);
+ m_bIsEnrage = true;
+ }else m_uiEnrage_Timer -= uiDiff;
+
+ // check if the others are dead
+ if (m_uiCheckTimer < uiDiff && !m_bHasSupercharge2)
+ {
+ if (!m_bIsSteelbreakerDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (!pTemp->isAlive())
+ {
+ m_bIsSteelbreakerDead = true;
+ if (!m_bHasSupercharge1)
+ {
+ m_bHasSupercharge1 = true;
+ m_uiWhirl_Timer = 10000;
+ }
+ else
+ {
+ m_bHasSupercharge2 = true;
+ m_uiTendrils_start_Timer = 40000;
+ m_uiTendrils_end_Timer = 60000;
+ m_uiTendrils_Change = 6000;
+ }
+ }
+ }
+ }
+ if (!m_bIsMolgeimDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (!pTemp->isAlive())
+ {
+ m_bIsMolgeimDead = true;
+ if (!m_bHasSupercharge1)
+ {
+ m_bHasSupercharge1 = true;
+ m_uiWhirl_Timer = 10000;
+ }
+ else
+ {
+ m_bHasSupercharge2 = true;
+ m_uiTendrils_start_Timer = 40000;
+ m_uiTendrils_end_Timer = 60000;
+ m_uiTendrils_Change = 6000;
+ }
+ }
+ }
+ }
+ m_uiCheckTimer = 1000;
+ }else m_uiCheckTimer -= uiDiff;
+
+ if (!m_bIsTendrils && !m_bMustDie)
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_brundir(Creature* pCreature)
+{
+ return new boss_brundirAI(pCreature);
+}
+
+//Runemaster Molgeim
+struct MANGOS_DLL_DECL boss_molgeimAI : public ScriptedAI
+{
+ boss_molgeimAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiShield_Timer;
+ uint32 m_uiRune_Power_Timer;
+ uint32 m_uiRune_Death_Timer;
+ uint32 m_uiRune_Summon_Timer;
+ uint32 m_uiDie_delay;
+ uint32 m_uiEnrage_Timer;
+ uint32 m_uiCheckTimer;
+
+ bool m_bSupercharge1;
+ bool m_bSupercharge2;
+ bool m_bMustDie;
+ bool m_bBrundirDead;
+ bool m_bSteelbreakerDead;
+ bool m_bEnrage;
+
+ void Reset()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_uiShield_Timer = 20000;
+ m_uiRune_Power_Timer = 10000;
+ m_uiEnrage_Timer = 900000;
+ m_uiCheckTimer = 1000;
+ m_bEnrage = false;
+ m_bBrundirDead = false;
+ m_bSteelbreakerDead = false;
+ m_bSupercharge1 = false;
+ m_bSupercharge2 = false;
+ m_bMustDie = false;
+ if (m_creature->HasAura(SPELL_SUPERCHARGE))
+ m_creature->RemoveAurasDueToSpell(SPELL_SUPERCHARGE);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth() && !m_bMustDie)
+ {
+ uiDamage = 0;
+ m_creature->RemoveAllAuras();
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_SUPERCHARGE);
+ m_uiDie_delay = 500;
+ m_bMustDie = true;
+ }
+ }
+
+ void OnYourSide()
+ {
+ /* hacky way to complete achievements; use only if you have this function
+ Map* pMap = m_creature->GetMap();
+ AchievementEntry const *AchievYourSide = GetAchievementStore()->LookupEntry(m_bIsRegularMode ? ACHIEV_ON_YOUR_SIDE : ACHIEV_ON_YOUR_SIDE_H);
+ if(AchievYourSide && pMap)
+ {
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ if (!lPlayers.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ if (Player* pPlayer = itr->getSource())
+ {
+ if(pPlayer->HasAura(SPELL_IRON_BOOT_AURA, EFFECT_INDEX_0))
+ pPlayer->CompletedAchievement(AchievYourSide);
+ }
+ }
+ }
+ }
+ */
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ //death yell
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (m_pInstance)
+ {
+ // remove supercharge from players -> spell bug
+ //m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SUPERCHARGE);
+ // if the others are dead then give loot
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (!pTemp->isAlive())
+ {
+ if (Creature* p2Temp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (!p2Temp->isAlive())
+ {
+ m_pInstance->SetData(TYPE_ASSEMBLY, DONE);
+ // only the current one has loot, because loot modes are implemented in sql
+ m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ // I'm on your side
+ OnYourSide();
+
+ // ChooseMolgeim
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHOOSE_MOLGEIM : ACHIEV_CHOOSE_MOLGEIM_H);
+ }
+ }
+ }
+ }
+
+ // else make them full hp
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetHealth(pTemp->GetMaxHealth());
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetHealth(pTemp->GetMaxHealth());
+ }
+ }
+
+ if(irand(0,1))
+ DoScriptText(SAY_MOLGEIM_DEATH1, m_creature);
+ else
+ DoScriptText(SAY_MOLGEIM_DEATH2, m_creature);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ if (m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_ASSEMBLY) != IN_PROGRESS)
+ m_pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS);
+ }
+
+ DoScriptText(SAY_MOLGEIM_AGGRO, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ if (m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_ASSEMBLY) != FAIL)
+ m_pInstance->SetData(TYPE_ASSEMBLY, FAIL);
+ }
+ }
+
+ void KilledUnit(Unit *who)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_MOLGEIM_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_MOLGEIM_SLAY2, m_creature);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // level 1 spells
+ if (m_uiShield_Timer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SHIELD : SPELL_SHIELD_H);
+ m_uiShield_Timer = 50000;
+ }else m_uiShield_Timer -= uiDiff;
+
+ if (m_uiRune_Power_Timer < uiDiff)
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (pTemp->isAlive())
+ DoCast(pTemp, SPELL_RUNE_OF_POWER);
+ else
+ DoCast(m_creature, SPELL_RUNE_OF_POWER);
+ }
+ break;
+ case 1:
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (pTemp->isAlive())
+ DoCast(pTemp, SPELL_RUNE_OF_POWER);
+ else
+ DoCast(m_creature, SPELL_RUNE_OF_POWER);
+ }
+ break;
+ case 2:
+ DoCast(m_creature, SPELL_RUNE_OF_POWER);
+ break;
+ }
+ m_uiRune_Power_Timer = 30000;
+ }else m_uiRune_Power_Timer -= uiDiff;
+
+ // level2 spells
+ if (m_uiRune_Death_Timer < uiDiff && m_bSupercharge1)
+ {
+ DoScriptText(SAY_MOLGEIM_DEATH_RUNE, m_creature);
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_RUNE_OF_DEATH : SPELL_RUNE_OF_DEATH_H);
+ m_uiRune_Death_Timer = 30000;
+ }else m_uiRune_Death_Timer -= uiDiff;
+
+ // level 3 spells
+ if (m_uiRune_Summon_Timer < uiDiff && m_bSupercharge2)
+ {
+ DoScriptText(SAY_MOLGEIM_SUMMON, m_creature);
+ m_creature->CastStop();
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_RUNE_OF_SUMMONING);
+ m_uiRune_Summon_Timer = 30000;
+ }else m_uiRune_Summon_Timer -= uiDiff;
+
+ // die after overloading
+ if (m_uiDie_delay < uiDiff && m_bMustDie)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDie_delay -= uiDiff;
+
+ if (m_uiEnrage_Timer < uiDiff && !m_bEnrage)
+ {
+ DoScriptText(SAY_MOLGEIM_BERSERK, m_creature);
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_BERSERK);
+ m_bEnrage = true;
+ }else m_uiEnrage_Timer -= uiDiff;
+
+ if (m_uiCheckTimer < uiDiff)
+ {
+ if (!m_bSteelbreakerDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_STEELBREAKER)))
+ {
+ if (!pTemp->isAlive())
+ {
+ m_bSteelbreakerDead = true;
+ if (!m_bSupercharge1)
+ {
+ m_bSupercharge1 = true;
+ m_uiRune_Death_Timer = 10000;
+ }
+ else
+ {
+ m_bSupercharge2 = true;
+ m_uiRune_Summon_Timer = 20000;
+ }
+ }
+ }
+ }
+ if (!m_bBrundirDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (!pTemp->isAlive())
+ {
+ m_bBrundirDead = true;
+ if (!m_bSupercharge1)
+ {
+ m_bSupercharge1 = true;
+ m_uiRune_Death_Timer = 10000;
+ }
+ else
+ {
+ m_bSupercharge2 = true;
+ m_uiRune_Summon_Timer = 20000;
+ }
+ }
+ }
+ }
+ m_uiCheckTimer = 1000;
+ }else m_uiCheckTimer -= uiDiff;
+
+ if (!m_bMustDie)
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_molgeim(Creature* pCreature)
+{
+ return new boss_molgeimAI(pCreature);
+}
+
+//Steelbreaker
+struct MANGOS_DLL_DECL boss_steelbreakerAI : public ScriptedAI
+{
+ boss_steelbreakerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiFusion_Punch_Timer;
+ uint32 m_uiStatic_Disruption_Timer;
+ uint32 m_uiPower_Timer;
+ uint32 m_uiDie_delay;
+ uint32 m_uiEnrage_Timer;
+ uint32 m_uiCheckTimer;
+
+ bool m_bBrundirDead;
+ bool m_bMolgeimDead;
+ bool m_bSupercharge1;
+ bool m_bSupercharge2;
+ bool m_bMustDie;
+ bool m_bEnrage;
+
+ void Reset()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_uiFusion_Punch_Timer = 20000;
+ m_uiEnrage_Timer = 900000;
+ m_uiCheckTimer = 1000;
+ m_bEnrage = false;
+ m_bBrundirDead = false;
+ m_bMolgeimDead = false;
+ m_bSupercharge1 = false;
+ m_bSupercharge2 = false;
+ m_bMustDie = false;
+ if (m_creature->HasAura(SPELL_SUPERCHARGE))
+ m_creature->RemoveAurasDueToSpell(SPELL_SUPERCHARGE);
+ if (m_creature->HasAura(SPELL_ELECTRICAL_CHARGE))
+ m_creature->RemoveAurasDueToSpell(SPELL_ELECTRICAL_CHARGE);
+ if (m_creature->HasAura(SPELL_HIGH_VOLTAGE))
+ m_creature->RemoveAurasDueToSpell(SPELL_HIGH_VOLTAGE);
+ if (m_creature->HasAura(SPELL_HIGH_VOLTAGE_H))
+ m_creature->RemoveAurasDueToSpell(SPELL_HIGH_VOLTAGE_H);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (m_bSupercharge2)
+ DoCast(m_creature, SPELL_ELECTRICAL_CHARGE);
+
+ if(irand(0,1))
+ DoScriptText(SAY_STEEL_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_STEEL_SLAY2, m_creature);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth() && !m_bMustDie)
+ {
+ uiDamage = 0;
+ m_creature->CastStop();
+ m_creature->RemoveAllAuras();
+ DoCast(m_creature, SPELL_SUPERCHARGE);
+ m_uiDie_delay = 500;
+ m_bMustDie = true;
+ }
+ }
+
+ void OnYourSide()
+ {
+ /* hacky way to complete achievements; use only if you have this function
+ Map* pMap = m_creature->GetMap();
+ AchievementEntry const *AchievYourSide = GetAchievementStore()->LookupEntry(m_bIsRegularMode ? ACHIEV_ON_YOUR_SIDE : ACHIEV_ON_YOUR_SIDE_H);
+ if(AchievYourSide && pMap)
+ {
+ Map::PlayerList const &lPlayers = pMap->GetPlayers();
+ if (!lPlayers.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ if (Player* pPlayer = itr->getSource())
+ {
+ if(pPlayer->HasAura(SPELL_IRON_BOOT_AURA, EFFECT_INDEX_0))
+ pPlayer->CompletedAchievement(AchievYourSide);
+ }
+ }
+ }
+ }
+ */
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if (m_pInstance)
+ {
+ // remove supercharge from players -> spell bug
+ // m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SUPERCHARGE);
+ // if the others are dead then give loot
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (!pTemp->isAlive())
+ {
+ if (Creature* p2Temp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (!p2Temp->isAlive())
+ {
+ m_pInstance->SetData(TYPE_ASSEMBLY, DONE);
+ m_pInstance->SetData(TYPE_ASSEMBLY_HARD, DONE);
+ // only the current one has loot, because loot modes are implemented in sql
+ m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+
+ // I'm on your side
+ OnYourSide();
+
+ // ChooseSteelbreaker
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_CHOOSE_STEELBREAKER : ACHIEV_CHOOSE_STEELBREAKER_H);
+ }
+ }
+ }
+ }
+
+ // else make them full hp
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetHealth(pTemp->GetMaxHealth());
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetHealth(pTemp->GetMaxHealth());
+ }
+ }
+
+ if(irand(0,1))
+ DoScriptText(SAY_STEEL_DEATH1, m_creature);
+ else
+ DoScriptText(SAY_STEEL_DEATH2, m_creature);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_HIGH_VOLTAGE : SPELL_HIGH_VOLTAGE_H);
+ if (m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_ASSEMBLY) != IN_PROGRESS)
+ m_pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS);
+ }
+
+ DoScriptText(SAY_STEEL_AGGRO, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ if (m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_ASSEMBLY) != FAIL)
+ m_pInstance->SetData(TYPE_ASSEMBLY, FAIL);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // level 1 spells
+ if (m_uiFusion_Punch_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FUSION_PUNCH : SPELL_FUSION_PUNCH_H);
+ m_uiFusion_Punch_Timer = 20000;
+ }else m_uiFusion_Punch_Timer -= uiDiff;
+
+ // level 2 spells
+ if (m_uiStatic_Disruption_Timer < uiDiff && m_bSupercharge1)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_STATIC_DISRUPTION : SPELL_STATIC_DISRUPTION_H);
+ m_uiStatic_Disruption_Timer = 60000;
+ }else m_uiStatic_Disruption_Timer -= uiDiff;
+
+ // level 3 spells
+ if (m_uiPower_Timer < uiDiff && m_bSupercharge2)
+ {
+ m_creature->CastStop();
+ DoScriptText(SAY_STEEL_OVERWHELMING, m_creature);
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_POWER : SPELL_POWER_H);
+ m_uiPower_Timer = m_bIsRegularMode ? 65000 : 35000;
+ }else m_uiPower_Timer -= uiDiff;
+
+ if (m_uiDie_delay < uiDiff && m_bMustDie)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDie_delay -= uiDiff;
+
+ if (m_uiEnrage_Timer < uiDiff && !m_bEnrage)
+ {
+ DoScriptText(SAY_STEEL_BERSERK, m_creature);
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_BERSERK);
+ m_bEnrage = true;
+ }else m_uiEnrage_Timer -= uiDiff;
+
+ if (m_uiCheckTimer < uiDiff)
+ {
+ if (!m_bBrundirDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_BRUNDIR)))
+ {
+ if (!pTemp->isAlive())
+ {
+ m_bBrundirDead = true;
+ if (!m_bSupercharge1)
+ {
+ m_bSupercharge1 = true;
+ m_uiStatic_Disruption_Timer = 12000;
+ }
+ else
+ {
+ m_bSupercharge2 = true;
+ m_uiPower_Timer = 5000;
+ }
+ }
+ }
+ }
+ if (!m_bMolgeimDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MOLGEIM)))
+ {
+ if (!pTemp->isAlive())
+ {
+ m_bMolgeimDead = true;
+ if (!m_bSupercharge1)
+ {
+ m_bSupercharge1 = true;
+ m_uiStatic_Disruption_Timer = 22000;
+ }
+ else
+ {
+ m_bSupercharge2 = true;
+ m_uiPower_Timer = 5000;
+ }
+ }
+ }
+ }
+ m_uiCheckTimer = 1000;
+ }else m_uiCheckTimer -= uiDiff;
+
+ if (!m_bMustDie)
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_steelbreaker(Creature* pCreature)
+{
+ return new boss_steelbreakerAI(pCreature);
+}
+
+void AddSC_boss_iron_council()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_brundir";
+ NewScript->GetAI = GetAI_boss_brundir;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_molgeim";
+ NewScript->GetAI = GetAI_boss_molgeim;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_steelbreaker";
+ NewScript->GetAI = GetAI_boss_steelbreaker;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_rune_of_power";
+ NewScript->GetAI = &GetAI_mob_rune_of_power;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_rune_of_summoning";
+ NewScript->GetAI = &GetAI_mob_rune_of_summoning;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_ulduar_lightning_elemental";
+ NewScript->GetAI = &GetAI_mob_ulduar_lightning_elemental;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp b/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp
index 37980c8..775a7c0 100644
--- a/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp
@@ -1,47 +1,633 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_kologarn
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: stone grip and arms need vehicles
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_AGGRO = -1603126,
- SAY_SHOCKWAVE = -1603127,
- SAY_GRAB = -1603128,
- SAY_ARM_LOST_LEFT = -1603129,
- SAY_ARM_LOST_RIGHT = -1603130,
- SAY_SLAY_1 = -1603131,
- SAY_SLAY_2 = -1603132,
- SAY_BERSERK = -1603133,
- SAY_DEATH = -1603134,
-
- EMOTE_ARM_RIGHT = -1603135,
- EMOTE_ARM_LEFT = -1603136,
- EMOTE_STONE_GRIP = -1603137,
+ //yells
+ SAY_AGGRO = -1603150,
+ SAY_SHOCKWEAVE = -1603151,
+ SAY_GRAB = -1603152,
+ SAY_LEFT_ARM_LOST = -1603153,
+ SAY_RIGHT_ARM_LOST = -1603154,
+ SAY_SLAY1 = -1603155,
+ SAY_SLAY2 = -1603156,
+ SAY_BERSERK = -1603157,
+ SAY_DEATH = -1603158,
+ EMOTE_RIGHT_ARM = -1603355,
+ EMOTE_LEFT_ARM = -1603356,
+ EMOTE_STONE_GRIP = -1603357,
+
+ //kologarn
+ SPELL_OVERHEAD_SMASH = 63356,
+ SPELL_OVERHEAD_SMASH_H = 64003,
+ SPELL_ONE_ARMED_SMASH = 63573,
+ SPELL_ONE_ARMED_SMASH_H = 64006,
+ SPELL_STONE_SHOUT = 63716,
+ SPELL_STONE_SHOUT_H = 64005,
+ SPELL_PETRIFYING_BREATH = 62030,
+ SPELL_PETRIFYING_BREATH_H = 63980,
+ SPELL_FOCUSED_EYEBEAM = 63346,
+ SPELL_FOCUSED_EYEBEAM_H = 63976,
+ SPELL_FOCUSED_EYEBEAM_TRIG = 63369,
+ SPELL_FOCUSED_EYEBEAM_VISUAL= 63368,
+ SPELL_ENRAGE = 26662,
+ //left arm
+ SPELL_SHOCKWAVE = 63783,
+ SPELL_SHOCKWAVE_H = 63982,
+ //right arm
+ SPELL_STONE_GRIP_GRAB = 63981, // not working
+ SPELL_STONE_GRIP = 64290,
+ SPELL_STONE_GRIP_H = 64292,
+ //both
+ SPELL_ARM_VISUAL = 64753,
+ //rubble
+ SPELL_RUMBLE = 63818, // on 10 man
+ SPELL_STONE_NOVA = 63978, // on 25 man
+ //NPC ids
+ MOB_RUBBLE = 33768,
+
+ ACHIEV_RUBBLE_AND_ROLL = 2959,
+ ACHIEV_RUBBLE_AND_ROLL_H = 2960,
+ ACHIEV_WITH_OPEN_ARMS = 2951,
+ ACHIEV_WITH_OPEN_ARMS_H = 2952,
+ ACHIEV_DISARMED = 2953,
+ ACHIEV_DISARMED_H = 2954,
+ ACHIEV_IF_LOOKS_COULD_KILL = 2955,
+ ACHIEV_IF_LOOKS_COULD_KILL_H= 2956,
};
-void AddSC_boss_kologarn()
+float LeftArm[3] = {1784.742f, -39.962f, 448.805f};
+float RightArm[3] = {1785.615f, -5.516f, 448.810f};
+const float KoloFront[3] = {1771.683f, -24.230f, 448.806f};
+
+// Rubble
+struct MANGOS_DLL_DECL mob_ulduar_rubbleAI : public ScriptedAI
+{
+ mob_ulduar_rubbleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiStone_Nova_Timer;
+
+ void Reset()
+ {
+ m_uiStone_Nova_Timer = urand(8000, 12000);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_KOLOGARN) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiStone_Nova_Timer < diff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_RUMBLE : SPELL_STONE_NOVA);
+ m_uiStone_Nova_Timer = urand(7000, 9000);
+ }else m_uiStone_Nova_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_ulduar_rubble(Creature* pCreature)
+{
+ return new mob_ulduar_rubbleAI(pCreature);
+}
+
+// Left Arm
+struct MANGOS_DLL_DECL boss_left_armAI : public ScriptedAI
+{
+ boss_left_armAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiShockwave_Timer;
+
+ void Reset()
+ {
+ m_uiShockwave_Timer = 30000;
+ DoCast(m_creature, SPELL_ARM_VISUAL);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM)))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN)))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN)))
+ {
+ DoScriptText(SAY_LEFT_ARM_LOST, pTemp);
+ if (pTemp->isAlive())
+ pTemp->DealDamage(pTemp, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiShockwave_Timer < diff)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN)))
+ DoScriptText(SAY_SHOCKWEAVE, pTemp);
+
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SHOCKWAVE : SPELL_SHOCKWAVE_H);
+ m_uiShockwave_Timer = 17000;
+ }else m_uiShockwave_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_left_arm(Creature* pCreature)
+{
+ return new boss_left_armAI(pCreature);
+}
+
+// Right Arm
+struct MANGOS_DLL_DECL boss_right_armAI : public ScriptedAI
+{
+ boss_right_armAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiStone_Grip_Timer;
+ uint32 m_uiFreeDamage;
+ uint32 m_uiMaxDamage;
+ uint64 m_uiGripTargetGUID[3];
+ uint8 m_uiMaxTargets;
+
+ void Reset()
+ {
+ m_uiStone_Grip_Timer = 20000;
+ m_uiMaxTargets = m_bIsRegularMode ? 1 : 3;
+ for(int i = 0; i < m_uiMaxTargets; i++)
+ m_uiGripTargetGUID[i] = 0;
+ m_uiFreeDamage = 0;
+ m_uiMaxDamage = m_bIsRegularMode ? 100000 : 480000;
+
+ DoCast(m_creature, SPELL_ARM_VISUAL);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM)))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN)))
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim)
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H);
+ }
+
+ void JustReachedHome()
+ {
+ //if (m_pInstance)
+ //m_pInstance->DoRemoveAurasDueToSpellOnPlayers(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ m_uiFreeDamage += uiDamage;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!m_pInstance)
+ return;
+
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN)))
+ {
+ DoScriptText(SAY_RIGHT_ARM_LOST, pTemp);
+ if (pTemp->isAlive())
+ pTemp->DealDamage(pTemp, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ for(int i = 0; i < m_uiMaxTargets; i++)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiGripTargetGUID[i]))
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiFreeDamage > m_uiMaxDamage)
+ {
+ m_uiFreeDamage = 0;
+ for(int i = 0; i < m_uiMaxTargets; i++)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiGripTargetGUID[i]))
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H);
+ }
+ }
+
+ if (m_uiStone_Grip_Timer < diff)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_KOLOGARN)))
+ DoScriptText(SAY_GRAB, pTemp);
+
+ DoScriptText(EMOTE_STONE_GRIP, m_creature);
+
+ // this needs vehicles!
+ for(int i = 0; i < m_uiMaxTargets; i++)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)){
+ pTarget->CastSpell(pTarget, m_bIsRegularMode ? SPELL_STONE_GRIP : SPELL_STONE_GRIP_H, false);
+ m_uiGripTargetGUID[i] = pTarget->GetGUID();
+ }
+ }
+ m_uiStone_Grip_Timer = 30000;
+ }else m_uiStone_Grip_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_right_arm(Creature* pCreature)
+{
+ return new boss_right_armAI(pCreature);
+}
+
+// Kologarn
+struct MANGOS_DLL_DECL boss_kologarnAI : public ScriptedAI
{
+ boss_kologarnAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiSpell_Timer;
+ uint32 m_uiCheck_Timer;
+ uint32 m_uiEyebeah_Timer;
+ uint32 m_uiRespawnRightTimer;
+ uint32 m_uiRespawnLeftTimer;
+ uint32 m_uiEnrageTimer;
+
+ uint32 m_uiRubbleNo;
+ bool m_bHasLeftDied;
+ bool m_bHasRightDied;
+ uint32 m_uiDisarmedTimer;
+ bool m_bOpenArms;
+
+ bool m_bIsRightDead;
+ bool m_bIsLeftDead;
+
+ void Reset()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+
+ m_uiSpell_Timer = 10000;
+ m_uiCheck_Timer = 6300;
+ m_uiEnrageTimer = 600000;
+ m_uiEyebeah_Timer = 10000 + urand(1000, 5000);
+ m_bIsRightDead = false;
+ m_bIsLeftDead = false;
+
+ m_uiRubbleNo = 0;
+ m_bHasLeftDied = false;
+ m_bHasRightDied = false;
+ m_bOpenArms = true;
+ m_uiDisarmedTimer = 0;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ // hacky way to complete achievements; use only if you have this function
+ // Rubble and roll
+ if (m_uiRubbleNo >= 25)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_RUBBLE_AND_ROLL : ACHIEV_RUBBLE_AND_ROLL_H);
+ }
+
+ // With open arms
+ if (m_bOpenArms)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_WITH_OPEN_ARMS : ACHIEV_WITH_OPEN_ARMS_H);
+ }
+
+ // Disarmed
+ if (m_bHasLeftDied && m_bHasRightDied && m_uiDisarmedTimer <= 12000)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_DISARMED : ACHIEV_DISARMED_H);
+ }
+
+ //death yell
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_KOLOGARN, DONE);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->ForcedDespawn();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->ForcedDespawn();
+ }
+ }
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_KOLOGARN, IN_PROGRESS);
+
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM)))
+ {
+ if (pTemp->isAlive())
+ pTemp->SetInCombatWithZone();
+ }
+ }
+ //aggro yell
+ DoScriptText(SAY_AGGRO, m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_SLAY2, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_KOLOGARN, FAIL);
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM)))
+ {
+ if (!pTemp->isAlive())
+ pTemp->Respawn();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ if (!m_bIsRightDead && !m_bIsLeftDead)
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_OVERHEAD_SMASH : SPELL_OVERHEAD_SMASH_H);
+ else if (m_bIsRightDead && m_bIsLeftDead)
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_STONE_SHOUT : SPELL_STONE_SHOUT_H);
+ else
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ONE_ARMED_SMASH : SPELL_ONE_ARMED_SMASH_H);
+ m_uiSpell_Timer = 20000;
+ }else m_uiSpell_Timer -= uiDiff;
+ // to be fixed -> only damage, no animation
+ if (m_uiEyebeah_Timer < uiDiff)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ DoCast(target, SPELL_FOCUSED_EYEBEAM_VISUAL);
+ DoCast(target, m_bIsRegularMode ? SPELL_FOCUSED_EYEBEAM : SPELL_FOCUSED_EYEBEAM_H, true);
+ }
+ m_uiEyebeah_Timer = 20000;
+ }else m_uiEyebeah_Timer -= uiDiff;
+
+ // respawn arms
+ if (m_uiRespawnLeftTimer < uiDiff && m_bIsLeftDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM)))
+ {
+ if (!pTemp->isAlive())
+ {
+ pTemp->Respawn();
+ m_bIsLeftDead = false;
+ m_bHasLeftDied = false;
+ DoScriptText(EMOTE_LEFT_ARM, m_creature);
+ }
+ }
+ }else m_uiRespawnLeftTimer -= uiDiff;
+
+ if (m_uiRespawnRightTimer < uiDiff && m_bIsRightDead)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM)))
+ {
+ if (!pTemp->isAlive())
+ {
+ pTemp->Respawn();
+ m_bIsRightDead = false;
+ m_bHasRightDied = false;
+ DoScriptText(EMOTE_RIGHT_ARM, m_creature);
+ }
+ }
+ }else m_uiRespawnRightTimer -= uiDiff;
+
+ // check if arms are dead and if there is no player in melee range
+ if (m_uiCheck_Timer < uiDiff)
+ {
+ if (Creature* lArm = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEFT_ARM)))
+ {
+ if (!lArm->isAlive() && !m_bIsLeftDead)
+ {
+ m_bHasLeftDied = true;
+ m_bOpenArms = false;
+ m_uiDisarmedTimer = 0;
+
+ for(uint8 i = 0; i < 5; i ++)
+ {
+ if(Creature* pRubble = m_creature->SummonCreature(MOB_RUBBLE, LeftArm[0] - urand(0, 5), LeftArm[1] + urand(0, 10), LeftArm[2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ pRubble->GetMotionMaster()->MovePoint(0, KoloFront[0], KoloFront[1], KoloFront[2]);
+
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pRubble->AddThreat(pTarget,0.0f);
+ pRubble->AI()->AttackStart(pTarget);
+ pRubble->SetInCombatWithZone();
+ }
+
+ m_uiRubbleNo += 1;
+ }
+ }
+ m_bIsLeftDead = true;
+ m_uiRespawnLeftTimer = 47000;
+ }
+ }
+ if (Creature* rArm = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RIGHT_ARM)))
+ {
+ if (!rArm->isAlive() && !m_bIsRightDead)
+ {
+ m_bHasRightDied = true;
+ m_bOpenArms = false;
+ m_uiDisarmedTimer = 0;
+
+ for(uint8 i = 0; i < 5; i ++)
+ {
+ if(Creature* pRubble = m_creature->SummonCreature(MOB_RUBBLE, RightArm[0] - urand(0, 5), RightArm[1] + urand(0, 10), RightArm[2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ pRubble->GetMotionMaster()->MovePoint(0, KoloFront[0], KoloFront[1], KoloFront[2]);
+
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pRubble->AddThreat(pTarget,0.0f);
+ pRubble->AI()->AttackStart(pTarget);
+ pRubble->SetInCombatWithZone();
+ }
+
+ m_uiRubbleNo += 1;
+ }
+ }
+ m_bIsRightDead = true;
+ m_uiRespawnRightTimer = 47000;
+ }
+ }
+
+ //Petrifying breath
+ if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 5))
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_PETRIFYING_BREATH : SPELL_PETRIFYING_BREATH_H);
+
+ m_uiCheck_Timer = 500;
+ }else m_uiCheck_Timer -= uiDiff;
+
+ // disarmed achiev check
+ if (m_bHasLeftDied || m_bHasRightDied)
+ m_uiDisarmedTimer += uiDiff;
+
+ if(m_uiEnrageTimer < uiDiff)
+ {
+ DoScriptText(SAY_BERSERK, m_creature);
+ DoCast(m_creature, SPELL_ENRAGE);
+ m_uiEnrageTimer = 30000;
+ }
+ else m_uiEnrageTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_kologarn(Creature* pCreature)
+{
+ return new boss_kologarnAI(pCreature);
}
+
+void AddSC_boss_kologarn()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_kologarn";
+ NewScript->GetAI = GetAI_boss_kologarn;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_ulduar_rubble";
+ NewScript->GetAI = &GetAI_mob_ulduar_rubble;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_left_arm";
+ NewScript->GetAI = &GetAI_boss_left_arm;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_right_arm";
+ NewScript->GetAI = &GetAI_boss_right_arm;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_leviathan.cpp b/scripts/northrend/ulduar/ulduar/boss_leviathan.cpp
new file mode 100644
index 0000000..c87c9e4
--- /dev/null
+++ b/scripts/northrend/ulduar/ulduar/boss_leviathan.cpp
@@ -0,0 +1,397 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_leviathan
+SD%Complete:
+SDComment: needs vehicles
+SDCategory: Ulduar
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ulduar.h"
+#include "Vehicle.h"
+
+enum say
+{
+ SAY_AGGRO = -1603203,
+ SAY_DEATH = -1603202,
+ SAY_SLAY = -1603201,
+ SAY_CHANGE1 = -1603204,
+ SAY_CHANGE2 = -1603205,
+ SAY_CHANGE3 = -1603206,
+ SAY_PLAYER_ON_TOP = -1603207,
+ SAY_OVERLOAD1 = -1603208,
+ SAY_OVERLOAD2 = -1603209,
+ SAY_OVERLOAD3 = -1603210,
+ SAY_HARD_MODE = -1603211,
+ SAY_TOWERS_DOWN = -1603212,
+ SAY_FROST_TOWER = -1603213,
+ SAY_FIRE_TOWER = -1603214,
+ SAY_ENERGY_TOWER = -1603215,
+ SAY_NATURE_TOWER = -1603216,
+
+ EMOTE_PURSUE = -1603352,
+};
+
+enum spells
+{
+ SPELL_PURSUED = 62374,
+
+ SPELL_MISSILE_BARRAGE = 62400,
+ SPELL_FLAME_VENTS = 62396,
+ SPELL_BATTERING_RAM = 62376,
+
+ SPELL_GATHERING_SPEED = 62375,
+ // interupted by
+ SPELL_OVERLOAD_CIRCUIT = 62399,
+
+ SPELL_SEARING_FLAME = 62402, // used by defense turret
+ // interupted by
+ SPELL_SYSTEMS_SHUTDOWN = 62475,
+
+ SPELL_FLAME_CANNON = 62395,
+ //SPELL_FLAME_CANNON = 64692, trigger the same spell
+ SPELL_BLAZE = 62292,
+
+ // used by players -> to be added later
+ SPELL_ELECTROSHOCK = 62522,
+ SPELL_SMOKE_TRAIL = 63575,
+
+ // tower of nature
+ SPELL_FREYAS_WARD = 62906,
+ SPELL_TOWER_OF_LIFE = 64482,
+ // tower of flames
+ SPELL_MIMIRON_INFERNO = 62910,
+ SPELL_TOWER_OF_FLAMES = 65075,
+ // tower of frost
+ SPELL_HODIR_FURY = 62297, // also + 10% hp
+ // tower of storms
+ SPELL_THORIMS_HAMMER = 62912,
+ SPELL_TOWER_OF_STORMS = 65076
+};
+
+enum Mobs
+{
+ MOB_MECHANOLIFT = 33214,
+ MOB_LIQUID = 33189,
+ MOB_CONTAINER = 33218,
+
+ DEFENSE_TURRET = 33142,
+ KEEPER_OF_NORGANNON = 33686
+};
+
+enum Seats
+{
+ SEAT_PLAYER = 0,
+ SEAT_TURRET = 1,
+ SEAT_DEVICE = 2,
+};
+
+
+struct MANGOS_DLL_DECL boss_flame_leviathan : public ScriptedAI
+{
+ boss_flame_leviathan(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ // ### unit disabled, please remove if you want to test it!
+// pCreature->setFaction(35); // remove this when vehicules fixed!
+// pCreature->SetVisibility(VISIBILITY_OFF);
+ // ###
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiBatteringRamTimer;
+ uint32 m_uiFlameVentsTimer;
+ uint32 m_uiMissileBarrageTimer;
+ uint32 m_uiPursueTimer;
+ uint32 m_uiGatheringSpeedTimer;
+ uint32 m_uiSummonFlyerTimer;
+ uint8 maxFlyers;
+
+ bool isHardMode;
+ bool isHodirsTower;
+ bool isFreyasTower;
+ bool isMimironsTower;
+ bool isThorimsTower;
+
+ uint32 m_uiFreyaWardTimer;
+ uint32 m_uiMimironInfernoTimer;
+ uint32 m_uiHodirFuryTimer;
+ uint32 m_uiThorimHammerTimer;
+
+ void Reset()
+ {
+ m_uiBatteringRamTimer = 15000 + rand()%20000;
+ m_uiFlameVentsTimer = 15000 + rand()%10000;
+ m_uiMissileBarrageTimer = 1000;
+ m_uiPursueTimer = 30000;
+ m_uiGatheringSpeedTimer = 50000;
+ m_uiSummonFlyerTimer = 2000;
+ maxFlyers = 10;
+
+ isHardMode = false;
+ isHodirsTower = false;
+ isFreyasTower = false;
+ isMimironsTower = false;
+ isThorimsTower = false;
+
+ m_uiFreyaWardTimer = 40000 + urand(1000, 10000);
+ m_uiMimironInfernoTimer = 40000 + urand(1000, 10000);
+ m_uiHodirFuryTimer = 40000 + urand(1000, 10000);
+ m_uiThorimHammerTimer = 40000 + urand(1000, 10000);
+
+ m_creature->SetSpeedRate(MOVE_RUN, 0.3f);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_LEVIATHAN, IN_PROGRESS);
+ if(m_pInstance->GetData(TYPE_LEVIATHAN_TP) != DONE)
+ m_pInstance->SetData(TYPE_LEVIATHAN_TP, DONE);
+ }
+
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_LEVIATHAN, DONE);
+ if(isHardMode)
+ m_pInstance->SetData(TYPE_LEVIATHAN_HARD, DONE);
+ }
+
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_LEVIATHAN, FAIL);
+ }
+
+ void KilledUnit(Unit *who)
+ {
+ DoScriptText(SAY_SLAY, m_creature);
+ }
+
+ // TODO: effect 0 and effect 1 may be on different target
+ void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_PURSUED)
+ AttackStart(pTarget);
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ /*if(spell->Id == 62472)
+ vehicle->InstallAllAccessories();
+ else if(spell->Id == SPELL_ELECTROSHOCK)
+ m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL);*/
+ }
+
+ void DamageTaken(Unit *pDoneBy, uint32 &uiDamage)
+ {
+ uiDamage *= 4;
+ if(m_creature->HasAura(SPELL_SYSTEMS_SHUTDOWN, EFFECT_INDEX_0))
+ uiDamage += uiDamage/2;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // pursue
+ if(m_uiPursueTimer < uiDiff)
+ {
+ switch(urand(0, 3))
+ {
+ case 0: DoScriptText(SAY_CHANGE1, m_creature); break;
+ case 1: DoScriptText(SAY_CHANGE2, m_creature); break;
+ case 2: DoScriptText(SAY_CHANGE3, m_creature); break;
+ }
+ DoScriptText(EMOTE_PURSUE, m_creature);
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ m_creature->AddThreat(pTarget, 100.0f);
+ DoCast(pTarget, SPELL_PURSUED);
+ }
+
+ m_uiPursueTimer = 30000;
+ }
+ else m_uiPursueTimer -= uiDiff;
+
+ // flame vents
+ if(m_uiFlameVentsTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_FLAME_VENTS);
+ m_uiFlameVentsTimer = 30000 + rand()%20000;
+ }
+ else m_uiFlameVentsTimer -= uiDiff;
+
+ // battering ram
+ if(m_uiBatteringRamTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_BATTERING_RAM);
+ m_uiBatteringRamTimer = 25000 + rand()%15000;
+ }
+ else m_uiBatteringRamTimer -= uiDiff;
+
+ /* flyers
+ it should summon some flyers. needs more research!
+ if(m_uiSummonFlyerTimer < uiDiff)
+ {
+ m_creature->SummonCreature(MOB_MECHANOLIFT, m_creature->GetPositionX() + rand()%20, m_creature->GetPositionY() + rand()%20, m_creature->GetPositionZ() + 50, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 40000);
+ m_uiSummonFlyerTimer = 2000;
+ }
+ else m_uiSummonFlyerTimer -= uiDiff;*/
+
+ // missile barrage
+ if(m_uiMissileBarrageTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_MISSILE_BARRAGE);
+ m_uiMissileBarrageTimer = 3000 + rand()%2000;
+ }
+ else m_uiMissileBarrageTimer -= uiDiff;
+
+ if(m_uiGatheringSpeedTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_GATHERING_SPEED);
+ m_uiGatheringSpeedTimer = urand(50000, 60000);
+ }
+ else m_uiGatheringSpeedTimer -= uiDiff;
+
+ // Hard mode event. need more research and scripting
+ // this part should be done in other way
+
+ // tower of freya
+ if(isFreyasTower)
+ {
+ DoCast(m_creature, SPELL_TOWER_OF_LIFE);
+
+ if(m_uiFreyaWardTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_FREYAS_WARD);
+ m_uiFreyaWardTimer = 40000 + urand(1000, 10000);
+ }
+ else m_uiFreyaWardTimer -= uiDiff;
+ }
+
+ // tower of mimiron
+ if(isMimironsTower)
+ {
+ DoCast(m_creature, SPELL_TOWER_OF_FLAMES);
+
+ if(m_uiMimironInfernoTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_FREYAS_WARD);
+ m_uiMimironInfernoTimer = 40000 + urand(1000, 10000);
+ }
+ else m_uiMimironInfernoTimer -= uiDiff;
+ }
+
+ // tower of hodir
+ if(isHodirsTower)
+ {
+ m_creature->SetHealth(m_creature->GetHealth() + 0.1* m_creature->GetHealth());
+
+ if(m_uiHodirFuryTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_HODIR_FURY);
+ m_uiHodirFuryTimer = 40000 + urand(1000, 10000);
+ }
+ else m_uiHodirFuryTimer -= uiDiff;
+ }
+
+ // tower of thorim
+ if(isThorimsTower)
+ {
+ DoCast(m_creature, SPELL_TOWER_OF_STORMS);
+
+ if(m_uiThorimHammerTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_THORIMS_HAMMER);
+ m_uiThorimHammerTimer = 40000 + urand(1000, 10000);
+ }
+ else m_uiThorimHammerTimer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_defense_turretAI : public ScriptedAI
+{
+ mob_defense_turretAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(10000, 15000);
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ if(spell->Id == SPELL_SYSTEMS_SHUTDOWN)
+ m_creature->ForcedDespawn();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_SEARING_FLAME);
+ m_uiSpell_Timer = urand(10000, 15000);
+ }else m_uiSpell_Timer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_defense_turret(Creature* pCreature)
+{
+ return new mob_defense_turretAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature)
+{
+ return new boss_flame_leviathan(pCreature);
+}
+
+void AddSC_boss_leviathan()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_flame_leviathan";
+ newscript->GetAI = &GetAI_boss_flame_leviathan;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_defense_turret";
+ newscript->GetAI = &GetAI_mob_defense_turret;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp b/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp
index 0e09458..1824101 100644
--- a/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp
@@ -1,61 +1,2265 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_mimiron
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: needs vehicles
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_AGGRO = -1603176,
- SAY_HARD_MODE = -1603177,
- SAY_BERSERK = -1603178,
+ //yells
+ SAY_AGGRO = -1603241,
+ SAY_HARD_MODE = -1603242,
+ SAY_BERSERK = -1603243,
+ SAY_TANK_ACTIVE = -1603244,
+ SAY_TANK_SLAY1 = -1603245,
+ SAY_TANK_SLAY2 = -1603246,
+ SAY_TANK_DEATH = -1603247,
+ SAY_TORSO_ACTIVE = -1603248,
+ SAY_TORSO_SLAY1 = -1603249,
+ SAY_TORSO_SLAY2 = -1603250,
+ SAY_TORSO_DEATH = -1603251,
+ SAY_HEAD_ACTIVE = -1603252,
+ SAY_HEAD_SLAY1 = -1603253,
+ SAY_HEAD_SLAY2 = -1603254,
+ SAY_HEAD_DEATH = -1603255,
+ SAY_ROBOT_ACTIVE = -1603256,
+ SAY_ROBOT_SLAY1 = -1603257,
+ SAY_ROBOT_SLAY2 = -1603258,
+ SAY_ROBOT_DEATH = -1603259,
- SAY_TANK_ACTIVE = -1603179,
- SAY_TANK_SLAY_1 = -1603180,
- SAY_TANK_SLAY_2 = -1603181,
- SAY_TANK_DEATH = -1603182,
+ EMOTE_PLASMA_BLAST = -1603371,
- SAY_TORSO_ACTIVE = -1603183,
- SAY_TORSO_SLAY_1 = -1603184,
- SAY_TORSO_SLAY_2 = -1603185,
- SAY_TORSO_DEATH = -1603186,
+ SPELL_JET_PACK = 63341, // used by mimiron to change seats
+ SPELL_SELF_REPAIR = 64383,
- SAY_HEAD_ACTIVE = -1603187,
- SAY_HEAD_SLAY_1 = -1603188,
- SAY_HEAD_SLAY_2 = -1603189,
- SAY_HEAD_DEATH = -1603190,
+ // hard mode spells
+ SPELL_SELF_DESTRUCTION = 64613, // visual aura
+ SPELL_SELF_DESTRUCT = 64610, // damage aura
+ SPELL_EMERGENCY_MODE_AURA = 65101,
+ NPC_MIMIRON_INFERNO = 33370, // used to cast the self destruct
- SAY_ROBOT_ACTIVE = -1603191,
- SAY_ROBOT_SLAY_1 = -1603192,
- SAY_ROBOT_SLAY_2 = -1603193,
- SAY_ROBOT_DEATH = -1603194,
+ SPELL_FLAMES = 64561, // may be the fires spells
+ SPELL_FLAMES_SUMMON = 64563, // 64567
+ SPELL_FLAMES_SPREAD = 64562,
+ NPC_FLAME = 34121,
+ NPC_FLAME_INITIAL = 34363,
- SAY_HELP_YOGG = -1603195,
+ //spells
+ //leviathan
+ SPELL_PROXIMITY_MINES = 63016, // also in phase 4
+ SPELL_MINE_SUMMON = 65347,
+ MOB_PROXIMITY_MINE = 34362,
+ SPELL_EXPLOSION = 66351,
+ SPELL_EXPLOSION_H = 63009,
+ SPELL_NAPALM_SHELL = 63666,
+ SPELL_NAPALM_SHELL_H = 65026,
+ SPELL_PLASMA_BLAST = 62997,
+ SPELL_PLASMA_BLAST_H = 64529,
+ SPELL_SHOCK_BLAST = 63631, // also in phase 4
+ SPELL_FLAME_SUPRESSANT = 64570, // hard mode
+ LEVIATHAN_TURRET = 34071,
- EMOTE_PLASMA_BLAST = -1603196,
+ //vx001
+ SPELL_RAPID_BURST = 63387,
+ SPELL_RAPID_BURST_H = 64531,
+ SPELL_LASER_BARRAGE = 63293, // also in phase 4
+ SPELL_LASER_VISUAL = 63300,
+ SPELL_LASER_TRIGG = 63274,
+ SPELL_ROCKET_STRIKE = 64064,
+ NPC_MIMIRON_FOCUS = 33835, //33369
+ SPELL_HEAT_WAVE = 63677,
+ SPELL_HEAT_WAVE_H = 64533,
+ SPELL_HAND_PULSE = 64348, // only in phase 4
+ SPELL_FLAME_SUPRESS = 65192, // used by robot in melee range
+ SPELL_HAND_PULSE_H = 64536,
+
+ // frostbomb
+ SPELL_FROST_BOMB_EXPL = 64626,
+ SPELL_FROST_BOMB_AURA = 64624, // before explode
+ SPELL_FROST_BOMB_VISUAL = 64625, // bomb grows
+ SPELL_FROST_BOMB_SUMMON = 64627, // summon the frostbomb
+
+ //aerial unit
+ SPELL_PLASMA_BALL = 63689, // also in phase 4
+ SPELL_PLASMA_BALL_H = 64535, // also in phase 4
+ MOB_ASSALT_BOT = 34057,
+ MOB_BOMB_BOT = 33836,
+ MOB_BOMB_BOT_321 = 33346,
+ MOB_BOMB_BOT_500 = 34192,
+ MOB_JUNK_BOT = 33855,
+ SPELL_MAGNETIC_FIELD = 64668,
+ SPELL_MAGNETIC_CORE = 64436, // increase dmg taken by 50%, used by magnetic core
+ MOB_MAGNETIC_CORE = 34068,
+ ITEM_MAGNETIC_CORE = 46029,
+ SPELL_BOMB_BOT_SUMMON = 63811,
+ SPELL_BOMB_BOT = 63767,
+
+ //hard mode
+ // summons fires
+ SPELL_EMERGENCY_MODE = 64582,
+ MOB_FROST_BOMB = 34149,
+ MOB_EMERGENCY_FIRE_BOT = 34147,
+ SPELL_DEAFENING_SIREN = 64616,
+ SPELL_WATER_SPRAY = 64619,
+
+ SPELL_MIMIRONS_INFERNO = 62910, // maybe used by rocket
+ SPELL_MIMIRONS_INFERNO2 = 62909, // maybe hard mode
+ SPELL_BERSERK = 26662,
+
+ ACHIEV_FIREFIGHTER = 3180,
+ ACHIEV_FIREFIGHTER_H = 3189,
+};
+
+enum MimironPhase
+{
+ PHASE_IDLE = 0,
+ PHASE_INTRO = 1,
+ PHASE_LEVIATHAN = 2,
+ PHASE_TRANS_1 = 3,
+ PHASE_VX001 = 4,
+ PHASE_TRANS_2 = 5,
+ PHASE_AERIAL = 6,
+ PHASE_TRANS_3 = 7,
+ PHASE_ROBOT = 8,
+ PHASE_OUTRO = 9,
+};
+
+#define CENTER_X 2744.732f
+#define CENTER_Y 2569.479f
+#define CENTER_Z 364.312f
+
+const float PosTankHome[2]= {2794.86f, 2597.83f};
+struct LocationsXY
+{
+ float x, y;
+ uint32 id;
+};
+static LocationsXY SummonLoc[]=
+{
+ {2753.665f, 2584.712f},
+ {2754.150f, 2554.445f},
+ {2726.966f, 2569.032f},
+ {2759.085f, 2594.249f},
+ {2759.977f, 2544.345f},
+ {2715.542f, 2569.160f},
+ {2765.070f, 2604.337f},
+ {2765.676f, 2534.558f},
+ {2703.810f, 2569.132f},
+};
+
+// Leviathan Mk script
+struct MANGOS_DLL_DECL boss_leviathan_mkAI : public ScriptedAI
+{
+ boss_leviathan_mkAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ bool m_bStartAttack;
+
+ uint32 m_uiMinesTimer;
+ uint32 m_uiNapalmTimer;
+ uint32 m_uiPlasmaBlastTimer;
+ uint32 m_uiShockBlastTimer;
+
+ bool m_bHasSuppresed;
+ uint32 m_uiSupressTimer;
+ uint32 m_uiSetFireTimer;
+
+ // outro
+ bool m_bIsOutro;
+ uint32 m_uiOutroTimer;
+ uint32 m_uiOutroStep;
+
+ bool m_bMustRepair;
+ uint32 m_uiRepairTimer;
+
+ void Reset()
+ {
+ m_bStartAttack = false;
+ m_uiMinesTimer = 5000;
+ m_uiNapalmTimer = 20000;
+ m_uiPlasmaBlastTimer = 10000;
+ m_uiShockBlastTimer = 30000;
+ m_bHasSuppresed = false;
+ m_uiSetFireTimer = 10000;
+ m_uiSupressTimer = 10000;
+
+ m_uiOutroTimer = 10000;
+ m_uiOutroStep = 1;
+ m_bIsOutro = false;
+ m_bMustRepair = false;
+ m_uiRepairTimer = 15000;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_LEVIATHAN_MK, NOT_STARTED);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if(!m_bStartAttack)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN)
+ DoStartMovement(pWho);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN)
+ {
+ if(m_creature->GetHealthPercent() < 1.0f)
+ {
+ uiDamage = 0;
+ m_bIsOutro = true;
+ }
+ }
+ // hacky way for feign death
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT)
+ {
+ if(uiDamage > m_creature->GetHealth() && !m_bMustRepair)
+ {
+ uiDamage = 0;
+ m_creature->SetHealth(0);
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->RemoveAllAuras();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->CombatStop();
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+ m_bMustRepair = true;
+ m_uiRepairTimer = 15000;
+ DoCast(m_creature, SPELL_SELF_REPAIR);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_LEVIATHAN_MK, SPECIAL);
+ }
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON)))
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_TANK_SLAY1, pMimiron);
+ else
+ DoScriptText(SAY_TANK_SLAY2, pMimiron);
+ }
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_ROBOT_SLAY1, pMimiron);
+ else
+ DoScriptText(SAY_ROBOT_SLAY2, pMimiron);
+ }
+ }
+ }
+
+ // hacky way for phase 4. needs rewriging when vehicles are fixed
+ void SetPhase()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bIsOutro = false;
+ m_uiMinesTimer = 10000;
+ m_uiShockBlastTimer = 30000;
+ m_bStartAttack = true;
+ // look like a robot
+ SetCombatMovement(false);
+ }
+
+ // hacky way for phase 4. needs rewriging when vehicles are fixed
+ void Repair()
+ {
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_creature->SetHealth(m_creature->GetMaxHealth() * 0.5);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->AI()->AttackStart(m_creature->getVictim());
+ SetPhase();
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_LEVIATHAN_MK, IN_PROGRESS);
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ pSummon->SetInCombatWithZone();
+ }
+
+ void SuppressFires()
+ {
+ std::list lFires;
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lFires.empty())
+ {
+ for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->ForcedDespawn();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(!m_bIsOutro)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiRepairTimer < uiDiff && m_bMustRepair)
+ {
+ SetPhase();
+ Repair();
+ m_bMustRepair = false;
+ }
+ else m_uiRepairTimer -= uiDiff;
+
+ // return if repairing
+ if(m_bMustRepair)
+ return;
+
+ // this should be removed when vehicles are implemented! The are casted by the turret
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN)
+ {
+ if(m_uiPlasmaBlastTimer < uiDiff)
+ {
+ DoScriptText(EMOTE_PLASMA_BLAST, m_creature);
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_PLASMA_BLAST : SPELL_PLASMA_BLAST_H);
+ m_uiPlasmaBlastTimer = 30000;
+ }
+ else m_uiPlasmaBlastTimer -= uiDiff;
+
+ if(m_uiNapalmTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ if(!m_creature->IsWithinDistInMap(pTarget, 15))
+ {
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_NAPALM_SHELL : SPELL_NAPALM_SHELL_H);
+ m_uiNapalmTimer = 7000;
+ }
+ }
+ }
+ else m_uiNapalmTimer -= uiDiff;
+ }
+
+ // proximity mines
+ if(m_uiMinesTimer < uiDiff)
+ {
+ //DoCast(m_crreature, SPELL_PROXIMITY_MINES);
+ for(uint8 i = 0; i < urand(8, 10); i++)
+ {
+ float angle = (float) rand()*360/RAND_MAX + 1;
+ float homeX = m_creature->GetPositionX() + 15*cos(angle*(M_PI/180));
+ float homeY = m_creature->GetPositionY() + 15*sin(angle*(M_PI/180));
+ m_creature->SummonCreature(MOB_PROXIMITY_MINE, homeX, homeY, m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 10000);
+ }
+ m_uiMinesTimer = 30000;
+ }
+ else m_uiMinesTimer -= uiDiff;
+
+ // shock blast
+ if(m_uiShockBlastTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_SHOCK_BLAST);
+ m_uiShockBlastTimer = 50000;
+ }
+ else m_uiShockBlastTimer -= uiDiff;
+
+ // hard mode script
+ if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS && m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_LEVIATHAN)
+ {
+ if(m_creature->GetHealthPercent() < 50.0f && !m_bHasSuppresed)
+ {
+ m_creature->InterruptNonMeleeSpells(true);
+ DoCast(m_creature, SPELL_FLAME_SUPRESSANT);
+ m_bHasSuppresed = true;
+ m_uiSupressTimer = 2000;
+ m_uiSetFireTimer = 10000;
+ }
+
+ if(m_uiSupressTimer < uiDiff && m_bHasSuppresed)
+ {
+ SuppressFires();
+ m_uiSupressTimer = 600000;
+ }
+ else m_uiSupressTimer -= uiDiff;
+
+ if(m_uiSetFireTimer < uiDiff && m_bHasSuppresed)
+ {
+ // start again 3 fires
+ for(uint8 i = 0; i < 3; i++)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTarget->InterruptNonMeleeSpells(true);
+ pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false);
+ }
+ }
+ m_uiSetFireTimer = 600000;
+ }
+ else m_uiSetFireTimer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ // outro for phase 1
+ if(m_bIsOutro)
+ {
+ switch(m_uiOutroStep)
+ {
+ case 1:
+ m_bStartAttack = false;
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->GetMotionMaster()->MovePoint(0, PosTankHome[0], PosTankHome[1], CENTER_Z);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON)))
+ DoScriptText(SAY_TANK_DEATH, pMimiron);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 12000;
+ break;
+ case 3:
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_TRANS_1);
+ // reset the miniboss for phase 4
+ EnterEvadeMode();
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 3000;
+ break;
+ }
+ }
+ else return;
+
+ if (m_uiOutroTimer <= uiDiff)
+ {
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 330000;
+ } m_uiOutroTimer -= uiDiff;
+ }
+};
+
+// VX001 script
+struct MANGOS_DLL_DECL boss_vx001AI : public ScriptedAI
+{
+ boss_vx001AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ bool m_bStartAttack;
+ uint32 m_uiAttackStartTimer;
+
+ uint32 m_uiRapidBurstTimer;
+ uint32 m_uiLaserBarrageTimer;
+ uint32 m_uiRocketStrikeTimer;
+ uint32 m_uiHeatWaveTimer;
+ uint32 m_uiHandPulseTimer;
+
+ uint32 m_uiFlameSuppressTimer;
+ uint32 m_uiFrostBombTimer;
+ uint32 m_uiSpreadFiresTimer;
+
+ uint32 m_uiRepairTimer;
+ bool m_bMustRepair;
+
+ void Reset()
+ {
+ m_bStartAttack = false;
+ m_uiAttackStartTimer = 12000;
+ m_bMustRepair = false;
+ m_uiRepairTimer = 15000;
+
+ m_uiRapidBurstTimer = 1000;
+ m_uiLaserBarrageTimer = 60000;
+ m_uiRocketStrikeTimer = 25000;
+ m_uiHeatWaveTimer = 20000;
+ m_uiHandPulseTimer = 1000;
+
+ m_uiFlameSuppressTimer = urand(10000, 15000);
+ m_uiFrostBombTimer = urand(25000, 30000);
+ m_uiSpreadFiresTimer = urand(40000, 50000);
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_VX001, NOT_STARTED);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if(!m_bStartAttack)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON)))
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_TORSO_SLAY1, pMimiron);
+ else
+ DoScriptText(SAY_TORSO_SLAY2, pMimiron);
+ }
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_ROBOT_SLAY1, pMimiron);
+ else
+ DoScriptText(SAY_ROBOT_SLAY2, pMimiron);
+ }
+ }
+ }
+
+ // hacky way for phase 4. needs rewriging when vehicles are fixed
+ void SetPhase()
+ {
+ //SetCombatMovement(true);
+ m_uiLaserBarrageTimer = 60000;
+ m_uiRocketStrikeTimer = 25000;
+ m_uiHandPulseTimer = 1000;
+
+ // look like a robot
+ m_creature->GetMotionMaster()->MoveIdle();
+ SetCombatMovement(false);
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 3, 0.0f);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 3, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001)
+ {
+ if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON)))
+ DoScriptText(SAY_TORSO_DEATH, pMimiron);
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_TRANS_2);
+ m_pInstance->SetData(TYPE_VX001, DONE);
+ }
+ }
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001)
+ return;
+
+ // hacky way for feign death, needs fixing
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT)
+ {
+ if(uiDamage > m_creature->GetHealth())
+ {
+ uiDamage = 0;
+ m_creature->SetHealth(0);
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->RemoveAllAuras();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->CombatStop();
+ m_bMustRepair = true;
+ m_uiRepairTimer = 15000;
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_VX001, SPECIAL);
+ }
+ }
+ }
+
+ // hacky way for phase 4. needs rewriging when vehicles are fixed
+ void Repair()
+ {
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_creature->SetHealth(m_creature->GetMaxHealth() * 0.5);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->AI()->AttackStart(m_creature->getVictim());
+ SetPhase();
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_VX001, IN_PROGRESS);
+ }
+
+ void SuppressFires()
+ {
+ std::list lFires;
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, 10.0f);
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, 10.0f);
+ if (!lFires.empty())
+ {
+ for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->ForcedDespawn();
+ }
+ }
+ }
+
+ Creature* SelectRandomFire()
+ {
+ std::list lFires;
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, DEFAULT_VISIBILITY_INSTANCE);
+
+ //This should not appear!
+ if (lFires.empty()){
+ m_uiFrostBombTimer = 5000;
+ return NULL;
+ }
+
+ std::list::iterator iter = lFires.begin();
+ advance(iter, urand(0, lFires.size()-1));
+
+ if((*iter)->isAlive())
+ return *iter;
+ else
+ {
+ m_uiFrostBombTimer = 500;
+ return NULL;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiAttackStartTimer < uiDiff && !m_bStartAttack)
+ {
+ if(GameObject* pLift = GetClosestGameObjectWithEntry(m_creature, GO_MIMIRON_ELEVATOR, DEFAULT_VISIBILITY_INSTANCE))
+ pLift->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWithZone();
+ m_bStartAttack = true;
+ }
+ else m_uiAttackStartTimer -= uiDiff;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiRepairTimer < uiDiff && m_bMustRepair)
+ {
+ SetPhase();
+ Repair();
+ m_bMustRepair = false;
+ }
+ else m_uiRepairTimer -= uiDiff;
+
+ // return if repairing
+ if(m_bMustRepair)
+ return;
+
+ // only in VX001 phase
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001)
+ {
+ if(m_uiRapidBurstTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_RAPID_BURST : SPELL_RAPID_BURST_H);
+ m_uiRapidBurstTimer = 1000;
+ }
+ else m_uiRapidBurstTimer -= uiDiff;
+
+ if(m_uiHeatWaveTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_HEAT_WAVE : SPELL_HEAT_WAVE_H);
+ m_uiHeatWaveTimer = 10000;
+ }
+ else m_uiHeatWaveTimer -= uiDiff;
+ }
+
+ // only in robot phase
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT)
+ {
+ if(m_uiHandPulseTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_HAND_PULSE : SPELL_HAND_PULSE_H);
+ m_uiHandPulseTimer = 1000;
+ }
+ else m_uiHandPulseTimer -= uiDiff;
+ }
+
+ if(m_uiLaserBarrageTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_LASER_TRIGG);
+ m_uiLaserBarrageTimer = urand(50000, 60000);
+ }
+ else m_uiLaserBarrageTimer -= uiDiff;
+
+ // this needs vehicles in order to make the rocket move to the target
+ if(m_uiRocketStrikeTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ if(Creature* pTemp = m_creature->SummonCreature(NPC_MIMIRON_FOCUS, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000))
+ {
+ pTemp->setFaction(14);
+ pTemp->GetMotionMaster()->MoveIdle();
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pTemp->CombatStop();
+ pTemp->SetDisplayId(11686); // make invisible
+ pTemp->CastSpell(pTemp, SPELL_ROCKET_STRIKE, false);
+ }
+ }
+ m_uiRocketStrikeTimer = urand(25000, 30000);
+ }
+ else m_uiRocketStrikeTimer -= uiDiff;
+
+ // hard mode
+ if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS)
+ {
+ // only in VX001 phase
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_VX001)
+ {
+ if(m_uiFlameSuppressTimer < uiDiff)
+ {
+ m_creature->InterruptNonMeleeSpells(true);
+ DoCast(m_creature, SPELL_FLAME_SUPRESS);
+ SuppressFires();
+ m_uiFlameSuppressTimer = urand(9000, 10000);
+ }
+ else m_uiFlameSuppressTimer -= uiDiff;
+ }
+
+ if(m_uiFrostBombTimer < uiDiff)
+ {
+ if(Creature* pFire = SelectRandomFire())
+ m_creature->SummonCreature(MOB_FROST_BOMB, pFire->GetPositionX(), pFire->GetPositionY(), pFire->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 10000);
+ m_uiFrostBombTimer = urand(50000, 60000);
+ m_uiSpreadFiresTimer = urand(15000, 20000);
+ }
+ else m_uiFrostBombTimer -= uiDiff;
+
+ if(m_uiSpreadFiresTimer < uiDiff)
+ {
+ // start again 3 fires
+ for(uint8 i = 0; i < 3; i++)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTarget->InterruptNonMeleeSpells(true);
+ pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false);
+ }
+ }
+ m_uiSpreadFiresTimer = 60000;
+ }
+ else m_uiSpreadFiresTimer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+// Aerial command unit script
+struct MANGOS_DLL_DECL boss_aerial_command_unitAI : public ScriptedAI
+{
+ boss_aerial_command_unitAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ bool m_bStartAttack;
+ uint32 m_uiAttackStartTimer;
+
+ uint32 m_uiPlasmaBallTimer;
+ uint32 m_uiSummonWavesTimer;
+ uint32 m_uiGroundTimer;
+ bool m_bIsGrounded;
+ uint32 m_uiSpreadFiresTimer;
+
+ uint32 m_uiRepairTimer;
+ bool m_bMustRepair;
+
+ void Reset()
+ {
+ m_bStartAttack = false;
+ m_uiAttackStartTimer = 5000;
+ m_uiSpreadFiresTimer = urand(40000, 50000);
+
+ m_uiPlasmaBallTimer = 3000;
+ m_uiSummonWavesTimer = 10000;
+ m_bIsGrounded = false;
+
+ m_bMustRepair = false;
+ m_uiRepairTimer = 15000;
+
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_AERIAL_UNIT, NOT_STARTED);
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if(!m_bStartAttack)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL)
+ {
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->GetMotionMaster()->MoveIdle();
+ SetCombatMovement(false);
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, 0.0f);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL)
+ {
+ if(m_creature->HasAura(SPELL_MAGNETIC_CORE, EFFECT_INDEX_0))
+ uiDamage += uiDamage;
+ return;
+ }
+
+ // hacky way for feign death
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT)
+ {
+ if(uiDamage > m_creature->GetHealth())
+ {
+ uiDamage = 0;
+ m_creature->SetHealth(0);
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->RemoveAllAuras();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MovementExpired(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->CombatStop();
+ m_bMustRepair = true;
+ m_uiRepairTimer = 15000;
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_AERIAL_UNIT, SPECIAL);
+ }
+ }
+ }
+
+ // hacky way for phase 4. needs rewriging when vehicles are fixed
+ void Repair()
+ {
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_creature->SetHealth(m_creature->GetMaxHealth() * 0.5);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_creature->AI()->AttackStart(m_creature->getVictim());
+ SetPhase();
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_AERIAL_UNIT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance)
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL)
+ {
+ if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON)))
+ DoScriptText(SAY_HEAD_DEATH, pMimiron);
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_TRANS_3);
+ m_pInstance->SetData(TYPE_AERIAL_UNIT, DONE);
+ }
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (Creature* pMimiron = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_MIMIRON)))
+ {
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_HEAD_SLAY1, pMimiron);
+ else
+ DoScriptText(SAY_HEAD_SLAY2, pMimiron);
+ }
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_ROBOT)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_ROBOT_SLAY1, pMimiron);
+ else
+ DoScriptText(SAY_ROBOT_SLAY2, pMimiron);
+ }
+ }
+ }
+
+ // hacky way for phase 4. needs rewriging when vehicles are fixed
+ void SetPhase()
+ {
+ m_uiPlasmaBallTimer = 3000;
+
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ SetCombatMovement(false);
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 6.5f, 0.0f);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 6.5f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+
+ // get the boss down by the magnetic core
+ void SetToGround()
+ {
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), CENTER_Z, 0);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), CENTER_Z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ m_bIsGrounded = true;
+ // make boss land
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_uiGroundTimer = 20000;
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ pSummon->SetInCombatWithZone();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiAttackStartTimer < uiDiff && !m_bStartAttack)
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWithZone();
+ m_bStartAttack = true;
+ }
+ else m_uiAttackStartTimer -= uiDiff;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiRepairTimer < uiDiff && m_bMustRepair)
+ {
+ SetPhase();
+ Repair();
+ m_bMustRepair = false;
+ }
+ else m_uiRepairTimer -= uiDiff;
+
+ // return if repairing
+ if(m_bMustRepair)
+ return;
+
+ if (m_creature->HasAura(SPELL_MAGNETIC_CORE, EFFECT_INDEX_0))
+ return;
+
+ if (m_uiGroundTimer < uiDiff && m_bIsGrounded)
+ {
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, 0.0f);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ m_bIsGrounded = false;
+ // make boss fly
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->InterruptNonMeleeSpells(true);
+ DoCast(m_creature, SPELL_BOMB_BOT_SUMMON);
+ }else m_uiGroundTimer -= uiDiff;
+
+ if(m_uiPlasmaBallTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_PLASMA_BALL : SPELL_PLASMA_BALL_H);
+ m_uiPlasmaBallTimer = urand(3000, 5000);
+ }
+ else m_uiPlasmaBallTimer -= uiDiff;
+
+ // spawn adds in arena, only in phase 3
+ if(m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_AERIAL)
+ {
+ if(m_uiSummonWavesTimer < uiDiff)
+ {
+ uint32 m_uiCreatureEntry;
+ // summon emergency boots
+ if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS)
+ {
+ switch(urand(0, 4))
+ {
+ case 0:
+ case 1:
+ m_uiCreatureEntry = MOB_JUNK_BOT;
+ break;
+ case 2:
+ case 3:
+ m_uiCreatureEntry = MOB_EMERGENCY_FIRE_BOT;
+ break;
+ case 4:
+ m_uiCreatureEntry = MOB_ASSALT_BOT;
+ break;
+ }
+ }
+ else
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ case 1:
+ m_uiCreatureEntry = MOB_JUNK_BOT;
+ break;
+ case 2:
+ m_uiCreatureEntry = MOB_ASSALT_BOT;
+ break;
+ }
+ }
+ uint8 m_uiSummonLoc = urand(0, 8);
+ if(m_uiCreatureEntry != 0)
+ m_creature->SummonCreature(m_uiCreatureEntry, SummonLoc[m_uiSummonLoc].x, SummonLoc[m_uiSummonLoc].y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
+
+ m_uiSummonWavesTimer = urand (10000, 15000);
+ }
+ else m_uiSummonWavesTimer -= uiDiff;
+
+ if(m_pInstance->GetData(TYPE_MIMIRON_HARD) == IN_PROGRESS)
+ {
+ if(m_uiSpreadFiresTimer < uiDiff)
+ {
+ // start again 3 fires
+ for(uint8 i = 0; i < 3; i++)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTarget->InterruptNonMeleeSpells(true);
+ pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false);
+ }
+ }
+ m_uiSpreadFiresTimer = urand(40000, 50000);
+ }
+ else m_uiSpreadFiresTimer -= uiDiff;
+ }
+ }
+ }
};
+// Mimiron, event controller
+// boss should be placed inside the vehicles when they are supported by mangos
+struct MANGOS_DLL_DECL boss_mimironAI : public ScriptedAI
+{
+ boss_mimironAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance *m_pInstance;
+
+ bool m_bIsHardMode;
+ uint32 m_uiSelfDestructTimer;
+ uint32 m_uiUseLiftTimer;
+ uint32 m_uiPhaseDelayTimer;
+ uint32 m_uiRobotDelayTimer;
+ uint32 m_uiSelfRepairTimer;
+ uint32 m_uiBerserkTimer;
+ bool m_bHasChecked;
+ uint32 m_uiOutroTimer;
+ uint32 m_uiHpCheckTimer;
+ bool m_bHasMoreHp;
+
+ uint32 m_uiIntroTimer;
+ uint32 m_uiIntroStep;
+ bool m_bIsIntro;
+ bool m_bIsRobotReady;
+
+ uint64 m_uiTankGUID;
+ uint64 m_uiTorsoGUID;
+ uint64 m_uiHeadGUID;
+
+ bool m_bIsTankDead;
+ bool m_bIsTorsoDead;
+ bool m_bIsHeadDead;
+
+ void Reset()
+ {
+ m_bIsHardMode = false;
+ m_uiSelfDestructTimer = 460000; // 8 min
+ m_bIsIntro = true;
+ m_uiPhaseDelayTimer = 7000;
+ m_uiUseLiftTimer = 4000;
+ m_uiBerserkTimer = 900000; // 15 min
+ m_bHasChecked = false;
+ m_bHasMoreHp = false;
+ m_bIsRobotReady = false;
+
+ m_uiIntroTimer = 10000;
+ m_uiIntroStep = 1;
+
+ m_bIsTankDead = false;
+ m_bIsTorsoDead = false;
+ m_bIsHeadDead = false;
+
+ m_uiTankGUID = 0;
+ m_uiTorsoGUID = 0;
+ m_uiHeadGUID = 0;
+
+ // reset button
+ if(GameObject* pButton = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_MIMIRON_BUTTON)))
+ pButton->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+
+ // reset elevator
+ if(GameObject* pLift = GetClosestGameObjectWithEntry(m_creature, GO_MIMIRON_ELEVATOR, DEFAULT_VISIBILITY_INSTANCE))
+ pLift->SetGoState(GO_STATE_ACTIVE);
+
+ // kill torso and Head
+ if(Creature* pTorso = GetClosestCreatureWithEntry(m_creature, NPC_VX001, 80.0f))
+ pTorso->DealDamage(pTorso, pTorso->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+ if(Creature* pHead = GetClosestCreatureWithEntry(m_creature, NPC_AERIAL_UNIT, 80.0f))
+ pHead->DealDamage(pHead, pHead->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+ // reset tank
+ if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK)))
+ {
+ if(pTank->isAlive())
+ pTank->AI()->EnterEvadeMode();
+ else
+ pTank->Respawn();
+ }
+
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_IDLE);
+ m_pInstance->SetData(TYPE_MIMIRON_HARD, NOT_STARTED);
+ }
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void JustReachedHome()
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_MIMIRON, NOT_STARTED);
+ }
+
+ // start event
+ void Aggro(Unit *who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_MIMIRON, IN_PROGRESS);
+ // activate teleporter
+ if(m_pInstance->GetData(TYPE_MIMIRON_TP) != DONE)
+ m_pInstance->SetData(TYPE_MIMIRON_TP, DONE);
+ // start intro
+ if(m_pInstance->GetData(TYPE_MIMIRON) != DONE)
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_INTRO);
+ }
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void DoOutro()
+ {
+ if(m_pInstance)
+ {
+ if(m_bIsHardMode)
+ {
+ m_pInstance->SetData(TYPE_MIMIRON_HARD, DONE);
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_FIREFIGHTER : ACHIEV_FIREFIGHTER_H);
+ }
+ m_pInstance->SetData(TYPE_MIMIRON, DONE);
+ }
+ m_creature->ForcedDespawn();
+ }
+
+ // for debug only
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_MIMIRON, DONE);
+ if(m_bIsHardMode)
+ m_pInstance->SetData(TYPE_MIMIRON_HARD, DONE);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(m_pInstance->GetData(TYPE_MIMIRON_PHASE))
+ {
+ case PHASE_INTRO:
+ {
+ if(m_bIsIntro)
+ {
+ //hard mode check
+ switch(m_uiIntroStep)
+ {
+ case 1:
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 10000;
+ break;
+ case 3:
+ if(GameObject* pButton = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_MIMIRON_BUTTON)))
+ pButton->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ if(m_bIsHardMode)
+ {
+ DoScriptText(SAY_HARD_MODE, m_creature);
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 15000;
+ }
+ else
+ {
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 1000;
+ }
+ break;
+ case 5:
+ if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK)))
+ {
+ if(pTank->isAlive())
+ {
+ DoScriptText(SAY_TANK_ACTIVE, m_creature);
+ pTank->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z);
+ m_uiTankGUID = pTank->GetGUID();
+ }
+ else
+ EnterEvadeMode();
+ }
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 18000;
+ break;
+ case 7:
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ {
+ if(m_bIsHardMode)
+ {
+ pTank->CastSpell(pTank, SPELL_EMERGENCY_MODE, false);
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 1000;
+ }
+ else
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_LEVIATHAN);
+ ((boss_leviathan_mkAI*)pTank->AI())->m_bStartAttack = true;
+ pTank->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTank->SetInCombatWithZone();
+ m_uiBerserkTimer = 900000; // 15 min
+ m_bIsIntro = false;
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 9000;
+ }
+ }
+ break;
+ case 9:
+ if(m_bIsHardMode)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_LEVIATHAN);
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ {
+ pTank->SetHealth(pTank->GetMaxHealth()+ (pTank->GetMaxHealth() * 0.3));
+ ((boss_leviathan_mkAI*)pTank->AI())->m_bStartAttack = true;
+ pTank->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTank->SetInCombatWithZone();
+ }
+ m_uiSelfDestructTimer = 460000; // 8 min
+ m_bIsIntro = false;
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 9000;
+ }
+ break;
+ }
+ }
+ else return;
+
+ if (m_uiIntroTimer <= uiDiff)
+ {
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 330000;
+ }
+ m_uiIntroTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_LEVIATHAN:
+ // leviathan MK phase: see above script
+ break;
+ case PHASE_TRANS_1:
+ {
+ if(m_uiUseLiftTimer < uiDiff)
+ {
+ if(GameObject* pLift = GetClosestGameObjectWithEntry(m_creature, GO_MIMIRON_ELEVATOR, DEFAULT_VISIBILITY_INSTANCE))
+ m_pInstance->DoUseDoorOrButton(pLift->GetGUID());
+ m_uiUseLiftTimer = 60000;
+ }
+ else m_uiUseLiftTimer -= uiDiff;
+
+ if(m_uiPhaseDelayTimer < uiDiff && !m_bHasMoreHp)
+ {
+ DoScriptText(SAY_TORSO_ACTIVE, m_creature);
+ if(Creature* pTorso = m_creature->SummonCreature(NPC_VX001, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ {
+ if(m_bIsHardMode)
+ {
+ pTorso->CastSpell(pTorso, SPELL_EMERGENCY_MODE, false);
+ m_bHasMoreHp = true;
+ m_uiHpCheckTimer = 1000;
+ m_uiTorsoGUID = pTorso->GetGUID();
+ }
+ else
+ {
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_VX001);
+ m_uiPhaseDelayTimer = 10000;
+ }
+ }
+ }
+ else m_uiPhaseDelayTimer -= uiDiff;
+
+ if (m_uiHpCheckTimer <= uiDiff && m_bHasMoreHp)
+ {
+ if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID))
+ pTorso->SetHealth(pTorso->GetMaxHealth()+ (pTorso->GetMaxHealth() * 0.3));
+ m_bHasMoreHp = false;
+ m_uiPhaseDelayTimer = 10000;
+ m_uiHpCheckTimer = 10000;
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_VX001);
+ // start again 3 fires
+ for(uint8 i = 0; i < 3; i++)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTarget->InterruptNonMeleeSpells(true);
+ pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false);
+ }
+ }
+ }
+ else m_uiHpCheckTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_VX001:
+ // VX001 phase: see above script
+ break;
+ case PHASE_TRANS_2:
+ {
+ if(m_uiPhaseDelayTimer < uiDiff && !m_bHasMoreHp)
+ {
+ DoScriptText(SAY_HEAD_ACTIVE, m_creature);
+ if(Creature* pHead = m_creature->SummonCreature(NPC_AERIAL_UNIT, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ {
+ if(m_bIsHardMode)
+ {
+ pHead->CastSpell(pHead, SPELL_EMERGENCY_MODE, false);
+ m_bHasMoreHp = true;
+ m_uiHpCheckTimer = 1000;
+ }
+ else
+ {
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_AERIAL);
+ m_uiPhaseDelayTimer = 15000;
+ }
+ m_uiHeadGUID = pHead->GetGUID();
+ }
+ }
+ else m_uiPhaseDelayTimer -= uiDiff;
+
+ if (m_uiHpCheckTimer <= uiDiff && m_bHasMoreHp)
+ {
+ if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID))
+ pHead->SetHealth(pHead->GetMaxHealth()+ (pHead->GetMaxHealth() * 0.3));
+ m_bHasMoreHp = false;
+ m_uiPhaseDelayTimer = 15000;
+ m_uiHpCheckTimer = 10000;
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_AERIAL);
+ // start again 3 fires
+ for(uint8 i = 0; i < 3; i++)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTarget->InterruptNonMeleeSpells(true);
+ pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false);
+ }
+ }
+ }
+ else m_uiHpCheckTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_AERIAL:
+ // Aerial Unit phase: see above script
+ break;
+ case PHASE_TRANS_3:
+ {
+ if(m_uiPhaseDelayTimer < uiDiff && !m_bIsRobotReady)
+ {
+ if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK)))
+ {
+ if(pTank->isAlive())
+ {
+ pTank->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z);
+ m_uiTankGUID = pTank->GetGUID();
+ m_bIsRobotReady = true;
+ m_uiRobotDelayTimer = 15000;
+ }
+ else
+ EnterEvadeMode();
+ }
+ m_uiPhaseDelayTimer = 100000;
+ }
+ else m_uiPhaseDelayTimer -= uiDiff;
+
+ if(m_uiRobotDelayTimer < uiDiff && m_bIsRobotReady && !m_bHasMoreHp)
+ {
+ DoScriptText(SAY_ROBOT_ACTIVE, m_creature);
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ ((boss_leviathan_mkAI*)pTank->AI())->SetPhase();
+
+ if(Creature* pTorso = m_creature->SummonCreature(NPC_VX001, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000))
+ {
+ ((boss_vx001AI*)pTorso->AI())->SetPhase();
+ m_uiTorsoGUID = pTorso->GetGUID();
+ }
+
+ if(Creature* pHead = m_creature->SummonCreature(NPC_AERIAL_UNIT, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000))
+ {
+ ((boss_aerial_command_unitAI*)pHead->AI())->SetPhase();
+ m_uiHeadGUID = pHead->GetGUID();
+ }
+
+ if(m_bIsHardMode)
+ {
+ if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID))
+ pTorso->CastSpell(pTorso, SPELL_EMERGENCY_MODE, false);
+ if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID))
+ pHead->CastSpell(pHead, SPELL_EMERGENCY_MODE, false);
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ pTank->CastSpell(pTank, SPELL_EMERGENCY_MODE, false);
+ m_bHasMoreHp = true;
+ m_uiHpCheckTimer = 1000;
+ }
+ else
+ {
+ if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID))
+ pTorso->SetHealth(pTorso->GetMaxHealth() * 0.5);
+ if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID))
+ pHead->SetHealth(pHead->GetMaxHealth() * 0.5);
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ pTank->SetHealth(pTank->GetMaxHealth() * 0.5);
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_ROBOT);
+ }
+ m_uiRobotDelayTimer = 100000;
+ }
+ else m_uiRobotDelayTimer -= uiDiff;
+
+ if (m_uiHpCheckTimer <= uiDiff && m_bHasMoreHp)
+ {
+ if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID))
+ pHead->SetHealth(pHead->GetMaxHealth() * 0.5);
+ if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID))
+ pTorso->SetHealth(pTorso->GetMaxHealth()* 0.5);
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ pTank->SetHealth(pTank->GetMaxHealth()* 0.5);
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_ROBOT);
+ // start again 3 fires
+ for(uint8 i = 0; i < 3; i++)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTarget->InterruptNonMeleeSpells(true);
+ pTarget->CastSpell(pTarget, SPELL_FLAMES_SUMMON, false);
+ }
+ }
+ m_uiHpCheckTimer = 10000;
+ }
+ else m_uiHpCheckTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_ROBOT:
+ {
+ if(m_pInstance->GetData(TYPE_LEVIATHAN_MK) == SPECIAL && !m_bHasChecked)
+ {
+ m_uiSelfRepairTimer = 15000;
+ m_bIsTankDead = true;
+ m_bHasChecked = true;
+ }
+ if(m_pInstance->GetData(TYPE_VX001) == SPECIAL && !m_bHasChecked)
+ {
+ m_uiSelfRepairTimer = 15000;
+ m_bIsTorsoDead = true;
+ m_bHasChecked = true;
+ }
+ if(m_pInstance->GetData(TYPE_AERIAL_UNIT) == SPECIAL && !m_bHasChecked)
+ {
+ m_uiSelfRepairTimer = 15000;
+ m_bIsHeadDead = true;
+ m_bHasChecked = true;
+ }
+
+ if(m_uiSelfRepairTimer < uiDiff && m_bHasChecked)
+ {
+ if(m_pInstance->GetData(TYPE_LEVIATHAN_MK) == SPECIAL)
+ m_bIsTankDead = true;
+ if(m_pInstance->GetData(TYPE_VX001) == SPECIAL)
+ m_bIsTorsoDead = true;
+ if(m_pInstance->GetData(TYPE_AERIAL_UNIT) == SPECIAL)
+ m_bIsHeadDead = true;
+
+ if(m_bIsTankDead && m_bIsTorsoDead && m_bIsHeadDead)
+ {
+ DoScriptText(SAY_ROBOT_DEATH, m_creature);
+ m_uiOutroTimer = 15000;
+ m_pInstance->SetData(TYPE_MIMIRON_PHASE, PHASE_OUTRO);
+ }
+ else
+ {
+ m_bHasChecked = false;
+ if(m_bIsTankDead)
+ {
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ ((boss_leviathan_mkAI*)pTank->AI())->Repair();
+ }
+ if(m_bIsTorsoDead)
+ {
+ if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID))
+ ((boss_vx001AI*)pTorso->AI())->Repair();
+ }
+ if(m_bIsHeadDead)
+ {
+ if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID))
+ ((boss_aerial_command_unitAI*)pHead->AI())->Repair();
+ }
+ }
+ m_uiSelfRepairTimer = 1000;
+ }
+ else m_uiSelfRepairTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_OUTRO:
+ {
+ if(m_uiOutroTimer < uiDiff)
+ {
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ m_creature->DealDamage(pTank, pTank->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID))
+ m_creature->DealDamage(pHead, pHead->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID))
+ m_creature->DealDamage(pTorso, pTorso->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ DoOutro();
+ m_uiOutroTimer = 60000;
+ }
+ else m_uiOutroTimer -= uiDiff;
+
+ break;
+ }
+ }
+
+ // berserk
+ if (m_uiBerserkTimer <= uiDiff)
+ {
+ if(Creature* pTank = m_pInstance->instance->GetCreature(m_uiTankGUID))
+ {
+ if(pTank && pTank->isAlive())
+ pTank->CastSpell(pTank, SPELL_BERSERK, false);
+ }
+
+ if(Creature* pTorso = m_pInstance->instance->GetCreature(m_uiTorsoGUID))
+ {
+ if(pTorso && pTorso->isAlive())
+ pTorso->CastSpell(pTorso, SPELL_BERSERK, false);
+ }
+
+ if(Creature* pHead = m_pInstance->instance->GetCreature(m_uiHeadGUID))
+ {
+ if(pHead && pHead->isAlive())
+ pHead->CastSpell(pHead, SPELL_BERSERK, false);
+ }
+
+ m_uiBerserkTimer = 330000;
+ }
+ else
+ m_uiBerserkTimer -= uiDiff;
+
+ // self destruct platform in hard mode
+ if (m_uiSelfDestructTimer < uiDiff && m_bIsHardMode)
+ {
+ m_creature->SummonCreature(NPC_MIMIRON_INFERNO, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
+ // visual part, hacky way
+ if(Creature* pTemp = m_creature->SummonCreature(NPC_MIMIRON_FOCUS, CENTER_X, CENTER_Y, CENTER_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000))
+ {
+ pTemp->GetMotionMaster()->MoveIdle();
+ pTemp->CombatStop();
+ pTemp->SetDisplayId(11686); // make invisible
+ pTemp->CastSpell(pTemp, SPELL_SELF_DESTRUCTION, false);
+ }
+ m_uiSelfDestructTimer = 60000;
+ }
+ else m_uiSelfDestructTimer -= uiDiff;
+ }
+};
+
+// Leviathan MK turret
+// used in phase 1; should be attached by a vehicle seat to the Leviathan MK
+struct MANGOS_DLL_DECL leviathan_turretAI : public ScriptedAI
+{
+ leviathan_turretAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ //pCreature->setFaction(14);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiPlasmaBlastTimer;
+ uint32 m_uiNapalmShellTimer;
+
+ void Reset()
+ {
+ m_uiPlasmaBlastTimer = 20000;
+ m_uiNapalmShellTimer = 10000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiPlasmaBlastTimer < uiDiff)
+ {
+ if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK)))
+ {
+ DoScriptText(EMOTE_PLASMA_BLAST, m_creature);
+ if (Unit* pTarget = pTank->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_PLASMA_BLAST : SPELL_PLASMA_BLAST_H);
+ }
+ m_uiPlasmaBlastTimer = 30000;
+ }
+ else m_uiPlasmaBlastTimer -= uiDiff;
+
+ if(m_uiNapalmShellTimer < uiDiff)
+ {
+ if (Creature* pTank = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_LEVIATHAN_MK)))
+ {
+ if (Unit* pTarget = pTank->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ if(!pTank->IsWithinDistInMap(pTarget, 15))
+ {
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_NAPALM_SHELL : SPELL_NAPALM_SHELL_H);
+ m_uiNapalmShellTimer = 7000;
+ }
+ }
+ }
+ }
+ else m_uiNapalmShellTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL mob_proximity_mineAI : public ScriptedAI
+{
+ mob_proximity_mineAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiExplosionTimer;
+ uint32 m_uiRangeCheckTimer;
+ uint32 m_uiDieTimer;
+
+ void Reset()
+ {
+ m_uiExplosionTimer = 60000;
+ m_uiRangeCheckTimer = 1000;
+ m_uiDieTimer = 65000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_MIMIRON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiDieTimer < uiDiff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else
+ m_uiDieTimer -= uiDiff;
+
+ if(m_uiExplosionTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLOSION : SPELL_EXPLOSION_H);
+ m_uiDieTimer = 500;
+ m_uiExplosionTimer = 20000;
+ }
+ else m_uiExplosionTimer -= uiDiff;
+
+ if (m_uiRangeCheckTimer < uiDiff)
+ {
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 2))
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLOSION : SPELL_EXPLOSION_H);
+ m_uiDieTimer = 500;
+ m_uiRangeCheckTimer = 5000;
+ }
+ else
+ m_uiRangeCheckTimer = 500;
+ }
+ else m_uiRangeCheckTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL mob_bomb_botAI : public ScriptedAI
+{
+ mob_bomb_botAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 m_uiRangeCheckTimer;
+ uint32 m_uiDieTimer;
+
+ void Reset()
+ {
+ m_uiRangeCheckTimer = 1000;
+ m_uiDieTimer = 600000;
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if(uiDamage > m_creature->GetHealth())
+ {
+ DoCast(m_creature, SPELL_BOMB_BOT);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ uiDamage = 0;
+ m_uiDieTimer = 500;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiDieTimer < uiDiff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else
+ m_uiDieTimer -= uiDiff;
+
+ if (m_uiRangeCheckTimer < uiDiff)
+ {
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 2))
+ {
+ DoCast(m_creature, SPELL_BOMB_BOT);
+ m_uiDieTimer = 500;
+ m_uiRangeCheckTimer = 5000;
+ }
+ else
+ m_uiRangeCheckTimer = 500;
+ }
+ else m_uiRangeCheckTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_assault_botAI : public ScriptedAI
+{
+ mob_assault_botAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 m_uiMagneticFieldTimer;
+
+ void Reset()
+ {
+ m_uiMagneticFieldTimer = 5000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiMagneticFieldTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_MAGNETIC_FIELD);
+ m_uiMagneticFieldTimer = urand(10000, 15000);
+ }
+ else m_uiMagneticFieldTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_emergency_botAI : public ScriptedAI
+{
+ mob_emergency_botAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ uint32 m_uiWaterSprayTimer;
+
+ void Reset()
+ {
+ m_uiWaterSprayTimer = urand(5000, 10000);
+ if(!m_bIsRegularMode)
+ DoCast(m_creature, SPELL_DEAFENING_SIREN);
+ }
+
+ void SuppressFires()
+ {
+ std::list lFires;
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, 15.0f);
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, 15.0f);
+ if (!lFires.empty())
+ {
+ for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->ForcedDespawn();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiWaterSprayTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_WATER_SPRAY);
+ SuppressFires();
+ m_uiWaterSprayTimer = urand(7000, 12000);
+ }
+ else m_uiWaterSprayTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_frost_bomb_ulduarAI : public ScriptedAI
+{
+ mob_frost_bomb_ulduarAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->setFaction(14);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiExplosionTimer;
+ uint32 m_uiDieTimer;
+
+ void Reset()
+ {
+ m_uiExplosionTimer = 10000;
+ m_uiDieTimer = 15000;
+ DoCast(m_creature, SPELL_FROST_BOMB_VISUAL);
+ }
+
+ void SuppressFires()
+ {
+ std::list lFires;
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34363, 30.0f);
+ GetCreatureListWithEntryInGrid(lFires, m_creature, 34121, 30.0f);
+ if (!lFires.empty())
+ {
+ for(std::list::iterator iter = lFires.begin(); iter != lFires.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->ForcedDespawn();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiDieTimer < uiDiff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else
+ m_uiDieTimer -= uiDiff;
+
+ if (m_uiExplosionTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_FROST_BOMB_EXPL);
+ SuppressFires();
+ m_uiExplosionTimer = 100000;
+ m_uiDieTimer = 500;
+ }
+ else m_uiExplosionTimer -= uiDiff;
+ }
+};
+
+// Flames used in hard mode
+struct MANGOS_DLL_DECL mob_mimiron_flamesAI : public ScriptedAI
+{
+ mob_mimiron_flamesAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->setFaction(14);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiFlamesSpreadTimer;
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_FLAMES);
+ m_uiFlamesSpreadTimer = 5000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_MIMIRON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ // spread flames
+ if(m_uiFlamesSpreadTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_FLAMES_SPREAD);
+ m_uiFlamesSpreadTimer = urand(2000, 5000);
+ }
+ else m_uiFlamesSpreadTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL mob_mimiron_infernoAI : public ScriptedAI
+{
+ mob_mimiron_infernoAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->setFaction(14);
+ pCreature->SetDisplayId(11686); // make invisible
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiFlamesTimer;
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_SELF_DESTRUCTION);
+ m_uiFlamesTimer = 2000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_MIMIRON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if(m_uiFlamesTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_SELF_DESTRUCT);
+ m_uiFlamesTimer = 1000;
+ }
+ else m_uiFlamesTimer -= uiDiff;
+ }
+};
+
+// item script, used to bring the aerial unit down
+struct MANGOS_DLL_DECL mob_magnetic_coreAI : public ScriptedAI
+{
+ mob_magnetic_coreAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiSpellTimer;
+ uint32 m_uiDieTimer;
+
+ void Reset()
+ {
+ m_uiSpellTimer = 2000;
+ m_uiDieTimer = 23000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiSpellTimer < uiDiff)
+ {
+ if(Creature* pAerial = GetClosestCreatureWithEntry(m_creature, NPC_AERIAL_UNIT, 10.0f))
+ {
+ DoCast(pAerial, SPELL_MAGNETIC_CORE);
+ ((boss_aerial_command_unitAI*)pAerial->AI())->SetToGround();
+ }
+ m_uiSpellTimer = 100000;
+ }
+ else m_uiSpellTimer -= uiDiff;
+
+ if (m_uiDieTimer < uiDiff)
+ m_creature->ForcedDespawn();
+ else
+ m_uiDieTimer -= uiDiff;
+ }
+};
+
+// Red button -> used to start the hard mode
+bool GOHello_go_red_button(Player* pPlayer, GameObject* pGo)
+{
+ ScriptedInstance* m_pInstance = (ScriptedInstance*)pGo->GetInstanceData();
+
+ if (!m_pInstance)
+ return false;
+
+ if (Creature* pMimiron = pGo->GetMap()->GetCreature(m_pInstance->GetData64(NPC_MIMIRON)))
+ {
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ pPlayer->CastSpell(pPlayer, SPELL_FLAMES_SUMMON, false);
+ if(pMimiron->isAlive() && m_pInstance->GetData(TYPE_MIMIRON_PHASE) == PHASE_INTRO)
+ ((boss_mimironAI*)pMimiron->AI())->m_bIsHardMode = true;
+ m_pInstance->SetData(TYPE_MIMIRON_HARD, IN_PROGRESS);
+ }
+
+ return false;
+}
+
+CreatureAI* GetAI_boss_mimiron(Creature* pCreature)
+{
+ return new boss_mimironAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_leviathan_mk(Creature* pCreature)
+{
+ return new boss_leviathan_mkAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_vx001(Creature* pCreature)
+{
+ return new boss_vx001AI(pCreature);
+}
+
+CreatureAI* GetAI_boss_aerial_command_unit(Creature* pCreature)
+{
+ return new boss_aerial_command_unitAI(pCreature);
+}
+
+CreatureAI* GetAI_leviathan_turret(Creature* pCreature)
+{
+ return new leviathan_turretAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_proximity_mine(Creature* pCreature)
+{
+ return new mob_proximity_mineAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_bomb_bot(Creature* pCreature)
+{
+ return new mob_bomb_botAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_assault_bot(Creature* pCreature)
+{
+ return new mob_assault_botAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_emergency_bot(Creature* pCreature)
+{
+ return new mob_emergency_botAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_frost_bomb_ulduar(Creature* pCreature)
+{
+ return new mob_frost_bomb_ulduarAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_mimiron_flames(Creature* pCreature)
+{
+ return new mob_mimiron_flamesAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_mimiron_inferno(Creature* pCreature)
+{
+ return new mob_mimiron_infernoAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_magnetic_core(Creature* pCreature)
+{
+ return new mob_magnetic_coreAI(pCreature);
+}
+
void AddSC_boss_mimiron()
{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_mimiron";
+ newscript->GetAI = &GetAI_boss_mimiron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_leviathan_mk";
+ newscript->GetAI = &GetAI_boss_leviathan_mk;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "leviathan_turret";
+ newscript->GetAI = &GetAI_leviathan_turret;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_vx001";
+ newscript->GetAI = &GetAI_boss_vx001;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_aerial_command_unit";
+ newscript->GetAI = &GetAI_boss_aerial_command_unit;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_proximity_mine";
+ newscript->GetAI = &GetAI_mob_proximity_mine;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_bomb_bot";
+ newscript->GetAI = &GetAI_mob_bomb_bot;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_assault_bot";
+ newscript->GetAI = &GetAI_mob_assault_bot;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_emergency_bot";
+ newscript->GetAI = &GetAI_mob_emergency_bot;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_bomb_ulduar";
+ newscript->GetAI = &GetAI_mob_frost_bomb_ulduar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_mimiron_flames";
+ newscript->GetAI = &GetAI_mob_mimiron_flames;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_mimiron_inferno";
+ newscript->GetAI = &GetAI_mob_mimiron_inferno;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_magnetic_core";
+ newscript->GetAI = &GetAI_mob_magnetic_core;
+ newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "go_red_button";
+ newscript->pGOHello = &GOHello_go_red_button;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp b/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp
index 6c401d1..560b26e 100644
--- a/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp
@@ -1,5 +1,5 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
- * This program is free software; you can redistribute it and/or modify
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
@@ -16,29 +16,874 @@
/* ScriptData
SDName: boss_razorscale
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: harpoons display should change when clicked
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_INTRO_WELCOME = -1603036,
- SAY_INTRO_1 = -1603037,
- SAY_INTRO_2 = -1603038,
- SAY_INTRO_3 = -1603039,
- SAY_GROUNDED = -1603040,
- SAY_EXTINGUISH_FIRE = -1603041,
+ //yells/emotes
+ SAY_INTRO = -1603020,
+ SAY_AGGRO1 = -1603021,
+ SAY_AGGRO2 = -1603022,
+ SAY_AGGRO3 = -1603023,
+ SAY_GROUND = -1603024,
+ EMOTE_DEEP_BREATH = -1603025,
+ SAY_FIRES_EXTINGUISH = -1603026,
+ EMOTE_HARPOON = -1603353,
+ EMOTE_GROUNDED = -1603354,
- EMOTE_BREATH = -1603042,
- EMOTE_HARPOON_READY = -1603043,
- EMOTE_GROUNDED = -1603044,
+ //razorscale air phase
+ SPELL_FIREBALL = 62796,
+ SPELL_FIREBALL_H = 63815,
+ SPELL_WING_BUFFET = 62666,
+ SPELL_STUN = 62794,
+ SPELL_SUMMON_DWARF = 62916,
+ //both
+ SPELL_BERSERK = 47008,
+ DEVOURING_FLAME_VISUAL = 63236,
+ SPELL_FLAME_BREATH = 63317,
+ SPELL_FLAME_BREATH_H = 64021,
+ //ground
+ SPELL_FLAME_BUFFET = 64016,
+ SPELL_FLAME_BUFFET_H = 64023,
+ SPELL_FUSE_ARMOR = 64771,
+
+ //devouring flame target
+ AURA_DEVOURING_FLAME = 64709,
+ AURA_DEVOURING_FLAME_H = 64734,
+
+ // mole machine
+ NPC_MOLE_MACHINE = 33245, // used to summon adds in phase 1
+ NPC_HARPOONS_DUMMY = 33282, // used to cast spells for harpoons
+ SPELL_SUMMON_MOLE_MACHINE = 73071,
+
+ // harpoons
+ SPELL_HARPOON_SHOT = 63659,
+ GO_HARPOON = 194543, // 41, 42, 194519
+
+ //dark rune watcher
+ SPELL_LIGHTNING_BOLT = 63809,
+ SPELL_LIGHTNING_BOLT_H = 64696,
+ SPELL_CHAIN_LIGHTNING = 64758,
+ SPELL_CHAIN_LIGHTNING_H = 64759,
+
+ //dark rune sentinel
+ SPELL_BATTLE_SHOUT = 46763,
+ SPELL_BATTLE_SHOUT_H = 64062,
+ SPELL_WHIRLWIND = 63808,
+
+ //dark rune guardian
+ SPELL_STORMSTRIKE = 64757,
+
+ //NPC ids
+ MOB_DARK_RUNE_WATCHER = 33453,
+ MOB_DARK_RUNE_SENTINEL = 33846,
+ MOB_DARK_RUNE_GUARDIAN = 33388,
+
+ NPC_EXP_ENGINEER = 33287,
+
+ ACHIEV_QUICK_SHAVE = 2919,
+ ACHIEV_QUICK_SHAVE_H = 2921,
+ ACHIEV_MEDIUM_RARE = 2923,
+ ACHIEV_MEDIUM_RARE_H = 2924,
};
-void AddSC_boss_razorscale()
+//Positional defines
+struct LocationsXY
+{
+ float x, y, z, o;
+ uint32 id;
+};
+
+static LocationsXY PositionLoc[]=
+{
+ {621.633301f, -228.671371f, 391.180328f},//right
+ {564.140198f, -222.049149f, 391.517212f},//left
+ {591.629761f, -209.629761f, 392.629761f},//middle
+ {587.629761f, -179.022522f, 391.625061f},//ground
+ {587.629761f, -179.022522f, 435.415070f},//air
+};
+
+#define HOME_X 587.546997f
+#define HOME_Y -174.927002f
+
+#define GOSSIP_START "Bring Razorscale down!"
+
+//expedition commander
+// start the event
+struct MANGOS_DLL_DECL npc_expedition_commanderAI : public ScriptedAI
+{
+ npc_expedition_commanderAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bHasPlayerNear = false;
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bHasPlayerNear;
+ bool m_bIsIntro;
+ uint64 m_uiPlayerGUID;
+ uint32 m_uiSpeech_Timer;
+ uint32 m_uiIntro_Phase;
+
+ void Reset()
+ {
+ m_uiPlayerGUID = 0;
+ m_uiSpeech_Timer = 3000;
+ m_bIsIntro = false;
+ m_uiIntro_Phase = 0;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_bHasPlayerNear && m_creature->IsWithinDistInMap(pWho, 40.0f))
+ {
+ DoScriptText(SAY_INTRO, m_creature);
+ m_bHasPlayerNear = true;
+ }
+ }
+
+ void GetRazorDown()
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RAZORSCALE)))
+ {
+ pTemp->SetInCombatWithZone();
+ if(Unit* pPlayer = m_creature->GetMap()->GetUnit( m_uiPlayerGUID))
+ {
+ pTemp->AddThreat(pPlayer,0.0f);
+ pTemp->AI()->AttackStart(pPlayer);
+ }
+ }
+ }
+
+ void BeginRazorscaleEvent(Player* pPlayer)
+ {
+ m_uiPlayerGUID = pPlayer->GetGUID();
+ m_bIsIntro = true;
+ m_uiSpeech_Timer = 3000;
+ m_uiIntro_Phase = 0;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_bIsIntro)
+ {
+ if(m_uiSpeech_Timer < uiDiff)
+ {
+ switch(m_uiIntro_Phase)
+ {
+ case 0:
+ if(Creature* pEngineer = GetClosestCreatureWithEntry(m_creature, NPC_EXP_ENGINEER, 50.0f))
+ DoScriptText(SAY_AGGRO1, pEngineer);
+ GetRazorDown();
+ ++m_uiIntro_Phase;
+ m_uiSpeech_Timer = 5000;
+ break;
+ case 1:
+ DoScriptText(SAY_AGGRO2, m_creature);
+ ++m_uiIntro_Phase;
+ m_uiSpeech_Timer = 7000;
+ break;
+ case 2:
+ if(Creature* pEngineer = GetClosestCreatureWithEntry(m_creature, NPC_EXP_ENGINEER, 50.0f))
+ DoScriptText(SAY_AGGRO3, pEngineer);
+ ++m_uiIntro_Phase;
+ m_uiSpeech_Timer = 5000;
+ break;
+ case 3:
+ m_bIsIntro = false;
+ ++m_uiIntro_Phase;
+ m_uiSpeech_Timer = 10000;
+ break;
+ default:
+ m_uiSpeech_Timer = 100000;
+ }
+ }else m_uiSpeech_Timer -= uiDiff;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_expedition_commander(Creature* pCreature)
+{
+ return new npc_expedition_commanderAI(pCreature);
+}
+
+bool GossipHello_npc_expedition_commander(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance* pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+
+ if(pInstance->GetData(TYPE_RAZORSCALE) != DONE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_expedition_commander(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ ((npc_expedition_commanderAI*)pCreature->AI())->BeginRazorscaleEvent(pPlayer);
+ }
+
+ return true;
+}
+
+// devouring_flame_target
+struct MANGOS_DLL_DECL mob_devouring_flame_targetAI : public ScriptedAI
+{
+ mob_devouring_flame_targetAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiDeath_Timer;
+
+ void Reset()
+ {
+ m_uiDeath_Timer = 25500;
+ m_creature->SetDisplayId(11686);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(m_creature, m_bIsRegularMode ? AURA_DEVOURING_FLAME : AURA_DEVOURING_FLAME_H);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiDeath_Timer < uiDiff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDeath_Timer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_devouring_flame_target(Creature* pCreature)
+{
+ return new mob_devouring_flame_targetAI(pCreature);
+}
+
+// dark rune watcher
+struct MANGOS_DLL_DECL mob_dark_rune_watcherAI : public ScriptedAI
+{
+ mob_dark_rune_watcherAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(5000, 10000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < diff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_LIGHTNING_BOLT : SPELL_LIGHTNING_BOLT_H);
+ break;
+ case 1:
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H);
+ break;
+ }
+ m_uiSpell_Timer = urand(5000, 10000);
+ }else m_uiSpell_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_watcher(Creature* pCreature)
+{
+ return new mob_dark_rune_watcherAI(pCreature);
+}
+
+// dark rune sentinel
+struct MANGOS_DLL_DECL mob_dark_rune_sentinelAI : public ScriptedAI
+{
+ mob_dark_rune_sentinelAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiWhirl_Timer;
+ uint32 m_uiShout_Timer;
+
+ void Reset()
+ {
+ m_uiWhirl_Timer = 10000;
+ m_uiShout_Timer = 2000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiWhirl_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_WHIRLWIND);
+ m_uiWhirl_Timer = urand(10000, 15000);
+ }else m_uiWhirl_Timer -= diff;
+
+ if (m_uiShout_Timer < diff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_BATTLE_SHOUT : SPELL_BATTLE_SHOUT_H);
+ m_uiShout_Timer = 30000;
+ }else m_uiShout_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+};
+
+CreatureAI* GetAI_mob_dark_rune_sentinel(Creature* pCreature)
+{
+ return new mob_dark_rune_sentinelAI(pCreature);
+}
+
+// dark rune guardian
+struct MANGOS_DLL_DECL mob_dark_rune_guardianAI : public ScriptedAI
+{
+ mob_dark_rune_guardianAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiStormstrike_Timer;
+
+ void Reset()
+ {
+ m_uiStormstrike_Timer = 10000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiStormstrike_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_STORMSTRIKE);
+ m_uiStormstrike_Timer = urand(7000, 13000);
+ }else m_uiStormstrike_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_guardian(Creature* pCreature)
{
+ return new mob_dark_rune_guardianAI(pCreature);
+}
+
+/// mole machine
+// used to summon dwarfes
+struct MANGOS_DLL_DECL mob_mole_machineAI : public ScriptedAI
+{
+ mob_mole_machineAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetDisplayId(11686); // make invisible
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_uiSummonTimer;
+ bool m_bIsSentinel;
+
+ void Reset()
+ {
+ m_uiSummonTimer = 8000;
+ m_bIsSentinel = false;
+ DoCast(m_creature, SPELL_SUMMON_MOLE_MACHINE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_uiSummonTimer < diff)
+ {
+ // summon 2 dwarfes
+ if(!m_bIsSentinel)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_WATCHER, m_creature->GetPositionX() + 5, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ pTemp->SetInCombatWithZone();
+ pTemp->GetMotionMaster()->MovePoint(0, HOME_X, HOME_Y, m_creature->GetPositionZ());
+ }
+ if (Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_GUARDIAN, m_creature->GetPositionX() - 5, m_creature->GetPositionY() - 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ pTemp->SetInCombatWithZone();
+ pTemp->GetMotionMaster()->MovePoint(0, HOME_X, HOME_Y, m_creature->GetPositionZ());
+ }
+ }
+ // summon 1 sentinel
+ else
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_SENTINEL, m_creature->GetPositionX() - 5, m_creature->GetPositionY() - 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
+ {
+ pTemp->SetInCombatWithZone();
+ pTemp->GetMotionMaster()->MovePoint(0, HOME_X, HOME_Y, m_creature->GetPositionZ());
+ }
+ }
+ m_uiSummonTimer = 60000;
+ }else m_uiSummonTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_mole_machine(Creature* pCreature)
+{
+ return new mob_mole_machineAI(pCreature);
}
+
+//razorscale
+struct MANGOS_DLL_DECL boss_razorscaleAI : public ScriptedAI
+{
+ boss_razorscaleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiFireball_Timer;
+ uint32 m_uiDevouring_Flame_Timer;
+ uint32 m_uiFlame_Buffet_Timer;
+ uint32 m_uiFuse_Armor_Timer;
+ uint32 m_uiFlame_Breath_Timer;
+ uint32 m_uiWave1_spawn; //right side, 1 of each
+ uint32 m_uiWave2_spawn; //left side, 1 of each
+ uint32 m_uiWave3_spawn; // big guy
+ uint32 m_uiBerserk_Timer;
+ uint32 m_uiGrounded_Timer; // 8 secs after ground fase is over, adds come
+ uint32 m_uiGround_Cast;
+ uint32 m_uiGround_Knockback;
+ uint32 m_uiRepairHarpoonTimer;
+ uint8 m_uiHarpoonsRepaired;
+ uint8 m_uiMaxHarpoons;
+ uint64 m_uiHarpoonsGUID[4];
+ uint32 m_uiTimetoground;
+ uint32 m_uiStun_Timer;
+ bool m_bAirphase;
+ bool m_bIsGrounded;
+ bool m_bHasBerserk;
+ bool m_bKnockback;
+ uint8 m_uiHarpoonsUsed;
+ uint8 m_uiFlyNo;
+
+ std::list lHarpoons;
+
+ void Reset()
+ {
+ m_uiFireball_Timer = 10000; // 10 secs for the first, fckin spam after that ~2secs
+ m_uiDevouring_Flame_Timer = 18000; // 18 secs first, 12 seconds after
+ m_uiWave1_spawn = urand(5000, 10000);
+ m_uiWave2_spawn = urand(5000, 10000);
+ m_uiWave3_spawn = urand(5000, 10000);
+ m_uiBerserk_Timer = 600000; // 10 min
+ m_uiTimetoground = 80000;
+ m_uiRepairHarpoonTimer = 53000;
+ m_uiHarpoonsRepaired = 0;
+ m_uiMaxHarpoons = m_bIsRegularMode ? 2 : 4;
+ for(int i = 0; i < m_uiMaxHarpoons; i++)
+ m_uiHarpoonsGUID[i] = 0;
+ m_bAirphase = false;
+ m_bIsGrounded = false;
+ m_bHasBerserk = false;
+ m_bKnockback = false;
+ m_uiFlyNo = 0;
+ m_uiHarpoonsUsed = 0;
+ lHarpoons.clear();
+
+ if(m_creature->GetPositionZ() < 435.0f)
+ {
+ m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f);
+ m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->GetMotionMaster()->MoveConfused();
+
+ if (Creature* pCommander = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_COMMANDER)))
+ pCommander->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_RAZORSCALE, DONE);
+
+ if (m_uiFlyNo < 2)
+ {
+ // hacky way to complete achievements; use only if you have this function
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_QUICK_SHAVE : ACHIEV_QUICK_SHAVE_H);
+ }
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_RAZORSCALE, IN_PROGRESS);
+
+ GetGameObjectListWithEntryInGrid(lHarpoons, m_creature, GO_BROKEN_HARPOON, 200.0f);
+ if (!lHarpoons.empty())
+ {
+ int i = 0;
+ for(std::list::iterator iter = lHarpoons.begin(); iter != lHarpoons.end(); ++iter)
+ {
+ if ((*iter))
+ {
+ m_uiHarpoonsGUID[i] = (*iter)->GetGUID();
+ i += 1;
+ }
+ }
+ }
+
+ m_bAirphase = true;
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f);
+ m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_RAZORSCALE, NOT_STARTED);
+
+ BreakHarpoons();
+ }
+
+ void BreakHarpoons()
+ {
+ // reset harpoons
+ if (!lHarpoons.empty())
+ {
+ for(std::list::iterator iter = lHarpoons.begin(); iter != lHarpoons.end(); ++iter)
+ {
+ if ((*iter))
+ {
+ (*iter)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ //(*iter)->SetUInt32Value(GAMEOBJECT_DISPLAYID, 8631);
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // AIR PHASE
+ // air position check (sometimes it falls to the ground like a rock
+ if(m_creature->GetPositionZ() < 430.0f && m_bAirphase && !m_bIsGrounded)
+ {
+ m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f);
+ m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+
+ // air spells
+ if (m_uiFireball_Timer < uiDiff && m_bAirphase && !m_bIsGrounded)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, m_bIsRegularMode ? SPELL_FIREBALL : SPELL_FIREBALL_H);
+ m_uiFireball_Timer = 2000;
+ }else m_uiFireball_Timer -= uiDiff;
+
+ if (m_uiDevouring_Flame_Timer < uiDiff && !m_bIsGrounded)
+ {
+ if (m_bAirphase)
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(target, DEVOURING_FLAME_VISUAL);
+ }
+ else
+ {
+ if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(target, DEVOURING_FLAME_VISUAL);
+ }
+ m_uiDevouring_Flame_Timer = 12000;
+ }else m_uiDevouring_Flame_Timer -= uiDiff;
+
+ // repair harpoons
+ if (m_uiRepairHarpoonTimer < uiDiff && m_bAirphase && !m_bIsGrounded && m_uiHarpoonsRepaired <= m_uiMaxHarpoons)
+ {
+ if(GameObject* pHarpoon = m_pInstance->instance->GetGameObject(m_uiHarpoonsGUID[m_uiHarpoonsRepaired]))
+ {
+ pHarpoon->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ //pHarpoon->SetUInt32Value(GAMEOBJECT_DISPLAYID, 8245);
+ m_uiHarpoonsRepaired += 1;
+ }
+ DoScriptText(EMOTE_HARPOON, m_creature);
+ m_uiRepairHarpoonTimer = 20000;
+ }
+ else m_uiRepairHarpoonTimer -= uiDiff;
+
+ // ground adds
+ if (m_uiWave1_spawn < uiDiff && m_bAirphase && !m_bIsGrounded)
+ {
+ m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[0].x, PositionLoc[0].y, PositionLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000);
+ m_uiWave1_spawn = urand(40000, 50000);
+ }else m_uiWave1_spawn -= uiDiff;
+
+ if (m_uiWave2_spawn < uiDiff && m_bAirphase && !m_bIsGrounded)
+ {
+ m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[1].x, PositionLoc[1].y, PositionLoc[1].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000);
+ m_uiWave2_spawn = urand(40000, 50000);
+ }else m_uiWave2_spawn -= uiDiff;
+
+ if (m_uiWave3_spawn < uiDiff && m_bAirphase && !m_bIsGrounded)
+ {
+ switch(urand(0, 2)) //33% chance of spawning
+ {
+ case 0:
+ break;
+ case 1:
+ if(Creature* pTemp = m_creature->SummonCreature(NPC_MOLE_MACHINE, PositionLoc[2].x, PositionLoc[2].y, PositionLoc[2].z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000))
+ ((mob_mole_machineAI*)pTemp->AI())->m_bIsSentinel = true;
+ break;
+ case 2:
+ break;
+ }
+ m_uiWave3_spawn = urand(40000, 50000);
+ }else m_uiWave3_spawn -= uiDiff;
+
+ // berserk
+ if (m_uiBerserk_Timer < uiDiff && !m_bHasBerserk)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_bHasBerserk = true;
+ }else m_uiBerserk_Timer -= uiDiff;
+
+ if (m_uiHarpoonsUsed == m_uiMaxHarpoons && m_bAirphase)
+ {
+ if(Creature* pCommander = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_COMMANDER)))
+ DoScriptText(SAY_GROUND, pCommander);
+ m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[3].x, PositionLoc[3].y, PositionLoc[3].z, 1.5);
+ m_creature->SendMonsterMove(PositionLoc[3].x, PositionLoc[3].y, PositionLoc[3].z, SPLINETYPE_FACINGSPOT, m_creature->GetSplineFlags(), 1);
+ // timers
+ m_uiHarpoonsUsed = 0;
+ m_bIsGrounded = true;
+ m_uiStun_Timer = 2000;
+ m_uiGround_Cast = 35000;
+ m_uiGrounded_Timer = 45000;
+ // make boss land
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ }else m_uiTimetoground -= uiDiff;
+
+ if (m_uiStun_Timer < uiDiff && m_bIsGrounded)
+ {
+ DoCast(m_creature, SPELL_STUN);
+ m_uiStun_Timer = 60000;
+ }else m_uiStun_Timer -= uiDiff;
+
+ if (m_uiGround_Cast < uiDiff && m_bIsGrounded)
+ {
+ if (Creature* pCommander = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_COMMANDER)))
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pCommander->GetGUID());
+ m_creature->RemoveAurasDueToSpell(SPELL_STUN);
+ DoScriptText(EMOTE_DEEP_BREATH, m_creature);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H);
+ m_uiGround_Cast = 15000;
+ m_uiGround_Knockback = 7000;
+ }else m_uiGround_Cast -= uiDiff;
+
+ if (m_uiGround_Knockback < uiDiff && m_bIsGrounded)
+ {
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_WING_BUFFET);
+ m_uiGround_Knockback = 15000;
+ m_uiGrounded_Timer = 3000;
+ }else m_uiGround_Knockback -= uiDiff;
+
+ if (m_uiGrounded_Timer < uiDiff && m_bIsGrounded)
+ {
+ m_creature->GetMap()->CreatureRelocation(m_creature, PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, 0.0f);
+ m_creature->SendMonsterMove(PositionLoc[4].x, PositionLoc[4].y, PositionLoc[4].z, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+
+ m_bIsGrounded = false;
+ m_uiFireball_Timer = 10000;
+ m_uiDevouring_Flame_Timer = 18000;
+ m_uiWave1_spawn = urand(5000, 10000);
+ m_uiWave2_spawn = urand(5000, 10000);
+ m_uiWave3_spawn = urand(5000, 10000);
+ m_uiRepairHarpoonTimer = 50000;
+ m_uiHarpoonsRepaired = 0;
+ BreakHarpoons();
+ // make boss fly
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ // achiev counter
+ m_uiFlyNo += 1;
+ }else m_uiGrounded_Timer -= uiDiff;
+
+ // make boss land at 50% hp
+ if (m_bAirphase && m_creature->GetHealthPercent() < 50)
+ {
+ if (m_creature->HasAura(SPELL_STUN))
+ m_creature->RemoveAurasDueToSpell(SPELL_STUN);
+
+ DoScriptText(EMOTE_GROUNDED, m_creature);
+ m_uiGround_Knockback = m_bIsGrounded ? 0 : 3000;
+ m_bAirphase = false;
+ m_bIsGrounded = false;
+ m_uiDevouring_Flame_Timer = 12000;
+ m_uiFlame_Buffet_Timer = 10000; //every 10 secs
+ m_uiFuse_Armor_Timer = 13000; //every ~13
+ m_uiFlame_Breath_Timer = 6000; //every 14
+ SetCombatMovement(true);
+
+ // make boss land
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ }
+
+ // LAND PHASE
+ // knockback at the beginning at the land phase
+ if (m_uiGround_Knockback < uiDiff && !m_bKnockback && !m_bAirphase)
+ {
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_WING_BUFFET);
+ m_bKnockback = true;
+ }else m_uiGround_Knockback -= uiDiff;
+
+ if (m_uiFuse_Armor_Timer < uiDiff && !m_bAirphase)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, SPELL_FUSE_ARMOR);
+ m_uiFuse_Armor_Timer = 13000;
+ } else m_uiFuse_Armor_Timer -= uiDiff;
+
+ if (m_uiFlame_Buffet_Timer < uiDiff && !m_bAirphase)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BUFFET : SPELL_FLAME_BUFFET_H);
+ m_uiFlame_Buffet_Timer = 13000;
+ }else m_uiFlame_Buffet_Timer -= uiDiff;
+
+ if (m_uiFlame_Breath_Timer < uiDiff && !m_bAirphase)
+ {
+ DoScriptText(EMOTE_DEEP_BREATH, m_creature);
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H);
+ m_uiFlame_Breath_Timer = 14000;
+ }else m_uiFlame_Breath_Timer -= uiDiff;
+
+ if (!m_bAirphase && !m_bIsGrounded)
+ DoMeleeAttackIfReady();
+
+ if (m_creature->GetDistance2d(HOME_X, HOME_Y) > 100)
+ EnterEvadeMode();
+ }
+};
+
+CreatureAI* GetAI_boss_razorscale(Creature* pCreature)
+{
+ return new boss_razorscaleAI(pCreature);
+}
+
+bool GOHello_go_broken_harpoon(Player* pPlayer, GameObject* pGo)
+{
+ ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData();
+
+ if (!pInstance)
+ return false;
+
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ if (Creature* pRazor = pGo->GetMap()->GetCreature(pInstance->GetData64(NPC_RAZORSCALE)))
+ ((boss_razorscaleAI*)pRazor->AI())->m_uiHarpoonsUsed += 1;
+
+ return false;
+}
+
+void AddSC_boss_razorscale()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_razorscale";
+ NewScript->GetAI = GetAI_boss_razorscale;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_devouring_flame_target";
+ NewScript->GetAI = &GetAI_mob_devouring_flame_target;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_dark_rune_watcher";
+ NewScript->GetAI = &GetAI_mob_dark_rune_watcher;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_dark_rune_sentinel";
+ NewScript->GetAI = &GetAI_mob_dark_rune_sentinel;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_dark_rune_guardian";
+ NewScript->GetAI = &GetAI_mob_dark_rune_guardian;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_mole_machine";
+ NewScript->GetAI = &GetAI_mob_mole_machine;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_expedition_commander";
+ NewScript->GetAI = &GetAI_npc_expedition_commander;
+ NewScript->pGossipHello = &GossipHello_npc_expedition_commander;
+ NewScript->pGossipSelect = &GossipSelect_npc_expedition_commander;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "go_broken_harpoon";
+ NewScript->pGOHello = &GOHello_go_broken_harpoon;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_thorim.cpp b/scripts/northrend/ulduar/ulduar/boss_thorim.cpp
index 837b785..7eed66b 100644
--- a/scripts/northrend/ulduar/ulduar/boss_thorim.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_thorim.cpp
@@ -1,61 +1,1765 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_thorim
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: Implement lightning orbs, summon Sit on the platform in the first 3 min.
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_AGGRO_1 = -1603138,
- SAY_AGGRO_2 = -1603139,
- SAY_SPECIAL_1 = -1603140,
- SAY_SPECIAL_2 = -1603141,
- SAY_SPECIAL_3 = -1603142,
- SAY_JUMP = -1603143,
+ //yells
+ SAY_AGGRO1 = -1603221,
+ SAY_AGGRO2 = -1603222,
+ SAY_SPECIAL1 = -1603223,
+ SAY_SPECIAL2 = -1603224,
+ SAY_SPECIAL3 = -1603225,
+ SAY_JUMP = -1603226,
+ SAY_SLAY1 = -1603227,
+ SAY_SLAY2 = -1603228,
+ SAY_BERSERK = -1603229,
+ SAY_ARENA_WIPE = -1603230,
+ SAY_DEATH = -1603231,
+ SAY_OUTRO1 = -1603232,
+ SAY_OUTRO2 = -1603233,
+ SAY_OUTRO3 = -1603234,
+ SAY_OUTRO_HARD1 = -1603235,
+ SAY_OUTRO_HARD2 = -1603236,
+ SAY_OUTRO_HARD3 = -1603237,
- SAY_SLAY_1 = -1603144,
- SAY_SLAY_2 = -1603145,
- SAY_BERSERK = -1603146,
+ // Sif
+ SAY_SIF_INTRO = -1603185,
+ SAY_SIF_EVENT = -1603186,
+ SAY_SIF_DESPAWN = -1603187,
- SAY_ARENA_WIPE = -1603147,
- SAY_DEFEATED = -1603148,
+ // spells
+ // phase1
+ SPELL_SHEAT_OF_LIGHTNING = 62276,
+ SPELL_STORMHAMMER = 62042,
+ SPELL_DEAFENING_THUNDER = 62470,
+ SPELL_LIGHTNING_SHOCK = 62017,
+ SPELL_CHARGE_ORB = 62016,
+ NPC_THUNDER_ORB = 33378, // npc used to cast charged orb
+ SPELL_BERSERK_ADDS = 62560, // 5 min phase 1 -> for adds
+ SPELL_SUMMON_LIGHTNING_ORB = 62391,
+ // phase2
+ SPELL_TOUTCH_OF_DOMINION = 62565, // not available in hard mode
+ SPELL_CHAIN_LIGHTNING = 62131,
+ SPELL_CHAIN_LIGHTNING_H = 64390,
+ SPELL_LIGHTNING_CHARGE = 62279,
+ SPELL_LIGHTNING_CHARGE_ORB = 62466,
+ SPELL_UNBALANCING_STRIKE = 62130,
+ SPELL_BERSERK = 26662, // 5 min phase 2
- SAY_OUTRO_1 = -1603149,
- SAY_OUTRO_2 = -1603150,
- SAY_OUTRO_3 = -1603151,
+ // hard mode
+ SPELL_FROSTBOLT_VOLLEY = 62580,
+ SPELL_FROSTBOLT_VOLLEY_H = 62604,
+ SPELL_FROST_NOVA = 62597,
+ SPELL_FROST_NOVA_H = 62605,
+ SPELL_BLIZZARD = 62576,
+ SPELL_BLIZZARD_H = 62602,
+ NPC_SIF = 33196,
+ SPELL_SOUL_CHANNEL = 40401,
- SAY_OUTRO_HARD_1 = -1603152,
- SAY_OUTRO_HARD_2 = -1603153,
- SAY_OUTRO_HARD_3 = -1603154,
+ // arena
+ MOB_DARK_RUNE_CHAMPION = 32876,
+ MOB_DARK_RUNE_COMMONER = 32904,
+ MOB_DARK_RUNE_EVOKER = 32878,
+ MOB_DARK_RUNE_WARBRINGER = 32877,
- SAY_HELP_YOGG = -1603155,
+ // traps
+ NPC_TRAP_BUNNY = 33725,
+ NPC_TRAP_BUNNY2 = 33054,
+ SPELL_PARALYTIC_FIELD = 63540,
+ SPELL_PARALYTIC_FIELD2 = 62241,
- SAY_SIF_BEGIN = -1603156,
- SAY_SIF_EVENT = -1603157,
- SAY_SIF_DESPAWN = -1603158,
+ // mobs spells
+ // acolyte
+ SPELL_GREATER_HEAL = 62334,
+ SPELL_GREATER_HEAL_H = 62442,
+ SPELL_RENEW = 62333,
+ SPELL_RENEW_H = 62441,
+ SPELL_HOLY_SMITE = 62335,
+ SPELL_HOLY_SMITE_H = 62443,
+ // champion
+ SPELL_MORTAL_STRIKE = 35054,
+ SPELL_CHARGE_CHAMPION = 32323,
+ SPELL_WHIRLWIND = 15578,
+ // commoner
+ SPELL_LOW_BLOW = 62326,
+ SPELL_PUMMEL = 38313,
+ // evoker
+ SPELL_RUNIC_LIGHTNING = 62327,
+ SPELL_RUNIC_LIGHTNING_H = 62445,
+ SPELL_RUNIC_MENDING = 62328,
+ SPELL_RUNIC_MENDING_H = 62446,
+ SPELL_RUNIC_SHIELD = 62321,
+ SPELL_RUNIC_SHIELD_H = 62529,
+ // warbringer
+ SPELL_RUNIC_STRIKE = 62322,
+ SPELL_AURA_CELERITY = 62320,
+
+ // ring guard
+ SPELL_WHIRLING_TRIP = 64151,
+ SPELL_IMPALE = 62331,
+ SPELL_IMPALE_H = 62418,
+ // honor guard
+ SPELL_CLEAVE = 42724,
+ SPELL_HAMSTRING = 48639,
+ SPELL_SHIELD_SMASH = 62332,
+ SPELL_SHIELD_SMASH_H = 62420,
+
+ // hallway
+ MOB_DARK_RUNE_ACOLYTE = 33110,
+ MOB_IRON_RING_GUARD = 32874,
+ MINIBOSS_RUNIC_COLOSSUS = 32872,
+ SPELL_SMASH = 62339,
+ //SPELL_SMASH_RIGHT = 62414,
+ SPELL_RUNIC_SMASH = 62058,
+ SPELL_RUNIC_SMASH2 = 62057,
+ SPELL_RUNIC_SMASH_DMG = 62465,
+ SPELL_RUNIC_BARRIER = 62338,
+ SPELL_CHARGE = 62613,
+ SPELL_CHARGE_H = 62614,
+
+ MOB_IRON_HOHOR_GUARD = 32875,
+ MINIBOSS_ANCIENT_RUNE_GIANT = 32873,
+ SPELL_RUNIC_FORTIFICATION = 62942,
+ SPELL_STOMP = 62411,
+ SPELL_STOMP_H = 62413,
+ SPELL_RUNE_DETONATION = 62526,
+
+ // pre adds:
+ SPELL_ACID_BREATH = 62315,
+ SPELL_ACID_BREATH_H = 62415,
+ SPELL_SWEEP = 62316,
+ SPELL_SWEEP_H = 62417,
+ // captains
+ NPC_CAPTAIN_ALY = 32908,
+ NPC_CAPTAIN_HORDE = 32907,
+ SPELL_DEVASTATE = 62317,
+ SPELL_HEROIC_STRIKE = 62444,
+ // mercenary
+ NPC_MERCENARY_ALY = 32885,
+ NPC_MERCENARY_HORDE = 32883,
+ SPELL_SHOOT = 16496,
+ SPELL_BARBED_SHOT = 62318,
+ SPELL_WING_CLIP = 40652,
+
+ ACHIEV_LOSE_ILLUSION = 3176,
+ ACHIEV_LOSE_ILLUSION_H = 3183,
+ ACHIEV_SIFFED = 2977,
+ ACHIEV_SIFFED_H = 2978,
+};
+
+enum phases
+{
+ PHASE_PREADDS = 0,
+ PHASE_INTRO = 1,
+ PHASE_BALCONY = 2,
+ PHASE_ARENA = 3,
+ PHASE_OUTRO = 4,
+};
+
+#define LOC_Z 419.5f
+struct LocationsXY
+{
+ float x, y, z;
+ uint32 id;
+};
+static LocationsXY ArenaLoc[]=
+{
+ {2158.082f, -240.572f},
+ {2111.883f, -240.561f},
+ {2105.243f, -274.499f},
+ {2163.927f, -277.834f},
+ {2104.865f, -251.027f},
+ {2167.612f, -262.128f},
+};
+
+static LocationsXY OrbLoc[]=
+{
+ {2134.57f, -440.31f, 438.33f},
+ {2225.91f, -431.68f, 412.17f},
+ {2228.26f, -266.46f, 412.17f},
+};
+
+// trap bunny
+struct MANGOS_DLL_DECL mob_thorim_trap_bunnyAI : public ScriptedAI
+{
+ mob_thorim_trap_bunnyAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ SetCombatMovement(false);
+ pCreature->setFaction(14);
+ Reset();
+ }
+
+ bool m_bHasStunAura;
+ uint32 m_uiAuraExpireTimer;
+
+ void Reset()
+ {
+ m_bHasStunAura = false;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && !m_bHasStunAura &&
+ pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 12) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ m_bHasStunAura = true;
+ m_uiAuraExpireTimer = 15000;
+ DoCast(m_creature, SPELL_PARALYTIC_FIELD);
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiAuraExpireTimer < uiDiff && m_bHasStunAura)
+ m_bHasStunAura = false;
+ else m_uiAuraExpireTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_thorim_trap_bunny(Creature* pCreature)
+{
+ return new mob_thorim_trap_bunnyAI(pCreature);
+}
+
+// dark rune acolyte
+struct MANGOS_DLL_DECL mob_dark_rune_acolyteAI : public ScriptedAI
+{
+ mob_dark_rune_acolyteAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(3000, 6000);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ switch(urand(0, 4))
+ {
+ case 0:
+ case 1:
+ if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_GREATER_HEAL : SPELL_GREATER_HEAL_H);
+ break;
+ case 2:
+ case 3:
+ if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H);
+ break;
+ case 4:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_HOLY_SMITE : SPELL_HOLY_SMITE_H);
+ break;
+ }
+ m_uiSpell_Timer = urand(3000, 6000);
+ }else m_uiSpell_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_acolyte(Creature* pCreature)
+{
+ return new mob_dark_rune_acolyteAI(pCreature);
+}
+
+// dark rune champion
+struct MANGOS_DLL_DECL mob_dark_rune_championAI : public ScriptedAI
+{
+ mob_dark_rune_championAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(3000, 6000);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE);
+ break;
+ case 1:
+ DoCast(m_creature->getVictim(), SPELL_CHARGE_CHAMPION);
+ break;
+ case 2:
+ DoCast(m_creature->getVictim(), SPELL_WHIRLWIND);
+ break;
+ }
+ m_uiSpell_Timer = urand(3000, 6000);
+ }else m_uiSpell_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_champion(Creature* pCreature)
+{
+ return new mob_dark_rune_championAI(pCreature);
+}
+
+// dark rune commoner
+struct MANGOS_DLL_DECL mob_dark_rune_commonerAI : public ScriptedAI
+{
+ mob_dark_rune_commonerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(3000, 6000);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), SPELL_LOW_BLOW);
+ break;
+ case 1:
+ DoCast(m_creature->getVictim(), SPELL_PUMMEL);
+ break;
+ }
+ m_uiSpell_Timer = urand(3000, 6000);
+ }else m_uiSpell_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_commoner(Creature* pCreature)
+{
+ return new mob_dark_rune_commonerAI(pCreature);
+}
+
+// dark rune evoker
+struct MANGOS_DLL_DECL mob_dark_rune_evokerAI : public ScriptedAI
+{
+ mob_dark_rune_evokerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(3000, 6000);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ switch(urand(0, 4))
+ {
+ case 0:
+ case 1:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_RUNIC_LIGHTNING : SPELL_RUNIC_LIGHTNING_H);
+ break;
+ case 2:
+ case 3:
+ if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_RUNIC_MENDING : SPELL_RUNIC_MENDING_H);
+ break;
+ case 4:
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_RUNIC_SHIELD : SPELL_RUNIC_SHIELD_H);
+ break;
+ }
+ m_uiSpell_Timer = urand(3000, 6000);
+ }else m_uiSpell_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_evoker(Creature* pCreature)
+{
+ return new mob_dark_rune_evokerAI(pCreature);
+}
+
+// dark rune warbringer
+struct MANGOS_DLL_DECL mob_dark_rune_warbringerAI : public ScriptedAI
+{
+ mob_dark_rune_warbringerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(4000, 7000);
+ DoCast(m_creature, SPELL_AURA_CELERITY);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_RUNIC_STRIKE);
+ m_uiSpell_Timer = urand(4000, 7000);
+ }else m_uiSpell_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_warbringer(Creature* pCreature)
+{
+ return new mob_dark_rune_warbringerAI(pCreature);
+}
+
+// dark rune ring guard
+struct MANGOS_DLL_DECL mob_dark_rune_ring_guardAI : public ScriptedAI
+{
+ mob_dark_rune_ring_guardAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(3000, 6000);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), SPELL_WHIRLING_TRIP);
+ break;
+ case 1:
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_IMPALE : SPELL_IMPALE_H);
+ break;
+ }
+ m_uiSpell_Timer = urand(3000, 6000);
+ }else m_uiSpell_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_ring_guard(Creature* pCreature)
+{
+ return new mob_dark_rune_ring_guardAI(pCreature);
+}
+
+// dark rune honor guard
+struct MANGOS_DLL_DECL mob_dark_rune_honor_guardAI : public ScriptedAI
+{
+ mob_dark_rune_honor_guardAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ uint32 m_uiSpell_Timer;
+
+ void Reset()
+ {
+ m_uiSpell_Timer = urand(3000, 6000);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpell_Timer < uiDiff)
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), SPELL_CLEAVE);
+ break;
+ case 1:
+ DoCast(m_creature->getVictim(), SPELL_HAMSTRING);
+ break;
+ case 2:
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHIELD_SMASH : SPELL_SHIELD_SMASH_H);
+ break;
+ }
+ m_uiSpell_Timer = urand(3000, 6000);
+ }else m_uiSpell_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_dark_rune_honor_guard(Creature* pCreature)
+{
+ return new mob_dark_rune_honor_guardAI(pCreature);
+}
+
+// thorim
+struct MANGOS_DLL_DECL boss_thorimAI : public ScriptedAI
+{
+ boss_thorimAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiPhase;
+
+ uint32 m_uiArenaBerserkTimer;
+ uint32 m_uiBerserkTimer;
+ uint32 m_uiArenaYellTimer;
+ uint32 m_uiStormHammerTimer;
+ uint32 m_uiDeafeningThunderTimer;
+ uint32 m_uiChargeOrbTimer;
+ uint32 m_uiSummonWavesTimer;
+ uint64 m_uiStormTargetGUID;
+
+ uint32 m_uiChainLightningTimer;
+ uint32 m_uiLightningChargeTimer;
+ uint32 m_uiOrbChargeTimer;
+ uint32 m_uiUnbalancingStrikeTimer;
+
+ uint32 m_uiPhase2Timer;
+ uint32 m_uiHardModeTimer;
+
+ bool m_bIsPhaseEnd;
+ bool m_bIsHardMode;
+ uint32 m_uiPreAddsKilled;
+
+ uint64 m_uiSifGUID;
+
+ // intro & outro
+ bool m_bIsOutro;
+ uint32 m_uiOutroTimer;
+ uint32 m_uiOutroStep;
+ bool m_bIsIntro;
+ uint32 m_uiIntroTimer;
+ uint32 m_uiIntroStep;
+
+ // mob list check
+ std::list lIronDwarfes;
+ std::list m_lOrbsGUIDList;
+
+ void Reset()
+ {
+ m_uiPreAddsKilled = 0;
+ m_uiPhase = PHASE_PREADDS;
+ SetCombatMovement(false);
+
+ m_bIsHardMode = true;
+ m_bIsPhaseEnd = false;
+
+ m_uiArenaBerserkTimer = 280000; // 5 min - 20 secs intro
+ m_uiBerserkTimer = 300000; // 5 min
+ m_uiHardModeTimer = 160000; // 3 min - 20 sec intro
+ m_uiArenaYellTimer = 30000;
+ m_uiSummonWavesTimer = 10000;
+
+ m_uiStormHammerTimer = 20000;
+ m_uiDeafeningThunderTimer = 22000;
+ m_uiChargeOrbTimer = 15000;
+
+ m_uiChainLightningTimer = urand(10000, 15000);
+ m_uiLightningChargeTimer = urand(10000, 15000);
+ m_uiUnbalancingStrikeTimer = urand(15000, 20000);
+ m_uiOrbChargeTimer = 20000;
+
+ m_uiOutroTimer = 10000;
+ m_uiOutroStep = 1;
+ m_bIsIntro = false;
+ m_uiIntroTimer = 10000;
+ m_uiIntroStep = 1;
+ m_bIsOutro = false;
+ m_uiSifGUID = 0;
+ lIronDwarfes.clear();
+ m_lOrbsGUIDList.clear();
+
+ // exploit check
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ // respawn adds
+ GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, MOB_IRON_RING_GUARD, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, MOB_DARK_RUNE_ACOLYTE, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, MOB_IRON_HOHOR_GUARD, DEFAULT_VISIBILITY_INSTANCE);
+ // preadds
+ GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_MERCENARY_ALY, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_MERCENARY_HORDE, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_CAPTAIN_ALY, DEFAULT_VISIBILITY_INSTANCE);
+ GetCreatureListWithEntryInGrid(lIronDwarfes, m_creature, NPC_CAPTAIN_HORDE, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lIronDwarfes.empty())
+ {
+ for(std::list::iterator iter = lIronDwarfes.begin(); iter != lIronDwarfes.end(); ++iter)
+ {
+ if ((*iter) && !(*iter)->isAlive())
+ (*iter)->Respawn();
+ }
+ }
+
+ if(m_pInstance)
+ {
+ // respawn runic colossus
+ if (Creature* pColossus = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RUNIC_COLOSSUS)))
+ {
+ if (!pColossus->isAlive())
+ pColossus->Respawn();
+ }
+
+ // respawn ancient rune giant
+ if (Creature* pRuneGiant = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_RUNE_GIANT)))
+ {
+ if (!pRuneGiant->isAlive())
+ pRuneGiant->Respawn();
+ }
+
+ // respawn jormungar
+ if (Creature* pJormungar = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_JORMUNGAR_BEHEMOTH)))
+ {
+ if (!pJormungar->isAlive())
+ pJormungar->Respawn();
+ }
+ }
+ }
+
+ void SpellHitTarget(Unit* pSpellTarget, const SpellEntry* pSpell)
+ {
+ if(pSpell->Id == SPELL_STORMHAMMER)
+ pSpellTarget->CastSpell(pSpellTarget, SPELL_DEAFENING_THUNDER, false);
+ }
+
+ void JustReachedHome()
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_THORIM, NOT_STARTED);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_SLAY2, m_creature);
+ }
+
+ void DoOutro()
+ {
+ if(m_pInstance)
+ {
+ if(m_bIsHardMode)
+ {
+ m_pInstance->SetData(TYPE_THORIM_HARD, DONE);
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_LOSE_ILLUSION : ACHIEV_LOSE_ILLUSION_H);
+ }
+ m_pInstance->SetData(TYPE_THORIM, DONE);
+ }
+
+ m_creature->ForcedDespawn();
+ }
+
+ // for debug only
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ {
+ if(m_bIsHardMode)
+ m_pInstance->SetData(TYPE_THORIM_HARD, DONE);
+ m_pInstance->SetData(TYPE_THORIM, DONE);
+ }
+ }
+
+ // start phase 2 and outro
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ // phase 2
+ if(uiDamage > 0 && m_uiPhase == PHASE_BALCONY && !m_bIsPhaseEnd)
+ {
+ if(m_pInstance->GetData(TYPE_RUNIC_COLOSSUS) == DONE && m_pInstance->GetData(TYPE_RUNE_GIANT) == DONE)
+ {
+ // say
+ DoScriptText(SAY_JUMP, m_creature);
+ // move in arena
+ m_creature->GetMotionMaster()->MovePoint(0, 2134.719f, -263.148f, 419.846f);
+ m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ m_creature->SetSplineFlags(SPLINEFLAG_FALLING);
+ m_bIsPhaseEnd = true;
+ m_uiPhase2Timer = 9000;
+ }
+ }
+
+ // outro
+ if(m_creature->GetHealthPercent() < 1.0f && m_uiPhase == PHASE_ARENA)
+ {
+ uiDamage = 0;
+ m_uiPhase = PHASE_OUTRO;
+ }
+ }
+
+ void StartEncounter()
+ {
+ m_uiPhase = PHASE_INTRO;
+ m_bIsIntro = true;
+ }
+
+ // hacky way for berserk in phase 1 :)
+ void KillPlayers()
+ {
+ Map *map = m_creature->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && m_creature->GetDistance(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ()) < 200.0f)
+ i->getSource()->DealDamage(i->getSource(), i->getSource()->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+ }
+
+ Creature* SelectRandomOrb()
+ {
+ std::list lThunderList;
+ GetCreatureListWithEntryInGrid(lThunderList, m_creature, NPC_THUNDER_ORB, 100.0f);
+
+ //This should not appear!
+ if (lThunderList.empty()){
+ m_uiChargeOrbTimer = 5000;
+ return NULL;
+ }
+
+ std::list::iterator iter = lThunderList.begin();
+ advance(iter, urand(0, lThunderList.size()-1));
+
+ return *iter;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ switch(m_uiPhase)
+ {
+ // start the encounter when all the preadds have died
+ case PHASE_PREADDS:
+ if(m_uiPreAddsKilled == 4)
+ StartEncounter();
+ break;
+ // do intro
+ case PHASE_INTRO:
+ {
+ // intro
+ if(m_bIsIntro)
+ {
+ switch(m_uiIntroStep)
+ {
+ case 1:
+ // wait 10 secs
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 10000;
+ break;
+ case 3:
+ DoScriptText(SAY_AGGRO1, m_creature);
+ DoCast(m_creature, SPELL_SHEAT_OF_LIGHTNING);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetInCombatWithZone();
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_THORIM, IN_PROGRESS);
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 10000;
+ break;
+ case 5:
+ DoScriptText(SAY_AGGRO2, m_creature);
+ if(Creature* pSif = m_creature->SummonCreature(NPC_SIF, m_creature->GetPositionX() + 10, m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 700000))
+ {
+ pSif->setFaction(35);
+ m_uiSifGUID = pSif->GetGUID();
+ }
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 9000;
+ break;
+ case 7:
+ if(Creature* pSif = m_pInstance->instance->GetCreature(m_uiSifGUID))
+ DoScriptText(SAY_SIF_INTRO, pSif);
+ m_uiPhase = PHASE_BALCONY;
+ m_bIsIntro = false;
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 9000;
+ break;
+ }
+ }
+ else return;
+
+ if (m_uiIntroTimer <= uiDiff)
+ {
+ ++m_uiIntroStep;
+ m_uiIntroTimer = 330000;
+ } m_uiIntroTimer -= uiDiff;
+
+ break;
+ }
+ // balcony phase
+ case PHASE_BALCONY:
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // phase 2 prepared
+ if(m_uiPhase2Timer < uiDiff && m_bIsPhaseEnd)
+ {
+ m_creature->RemoveSplineFlag(SPLINEFLAG_FALLING);
+ m_creature->RemoveAurasDueToSpell(SPELL_SHEAT_OF_LIGHTNING);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if(!m_bIsHardMode)
+ DoCast(m_creature, SPELL_TOUTCH_OF_DOMINION);
+ if(m_bIsHardMode)
+ {
+ if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID))
+ {
+ Sif->setFaction(14);
+ DoScriptText(SAY_SIF_EVENT, Sif);
+ Sif->SetInCombatWithZone();
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_SIFFED : ACHIEV_SIFFED_H);
+ }
+ }
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ SetCombatMovement(true);
+ m_uiPhase = PHASE_ARENA;
+ m_bIsPhaseEnd = false;
+ }
+ else m_uiPhase2Timer -= uiDiff;
+
+ // return if jumping to second phase
+ if(m_bIsPhaseEnd)
+ return;
+
+ // hard mode check
+ if (m_uiHardModeTimer <= uiDiff && m_bIsHardMode)
+ {
+ m_bIsHardMode = false;
+ if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID))
+ {
+ if(Sif && Sif->isAlive())
+ {
+ DoScriptText(SAY_SIF_DESPAWN, Sif);
+ Sif->ForcedDespawn();
+ }
+ }
+ m_uiHardModeTimer = 330000;
+ } m_uiHardModeTimer -= uiDiff;
+
+ // spawn adds in arena
+ if(m_uiSummonWavesTimer < uiDiff)
+ {
+ // 1-2 warbringer
+ // 1 evoker
+ // 5-6 commoners
+ // 1 champion
+ // 1 acolyte
+ uint8 i;
+ uint8 k;
+ switch(urand(0, 4))
+ {
+ case 0:
+ i = urand(0, 5);
+ if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_CHAMPION, ArenaLoc[i].x, ArenaLoc[i].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f);
+ if(pTemp->IsWithinLOSInMap(m_creature->getVictim()))
+ {
+ pTemp->AI()->AttackStart(m_creature->getVictim());
+ pTemp->AddThreat(m_creature->getVictim(), 100.0f);
+ }
+ }
+ break;
+ case 1:
+ i = urand(0, 5);
+ if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_EVOKER, ArenaLoc[i].x, ArenaLoc[i].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f);
+ if(pTemp->IsWithinLOSInMap(m_creature->getVictim()))
+ {
+ pTemp->AI()->AttackStart(m_creature->getVictim());
+ pTemp->AddThreat(m_creature->getVictim(), 100.0f);
+ }
+ }
+ break;
+ case 2:
+ i = urand(5, 6);
+ for(uint8 j = 0; j < i; j++)
+ {
+ if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_COMMONER, ArenaLoc[j].x, ArenaLoc[j].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f);
+ if(pTemp->IsWithinLOSInMap(m_creature->getVictim()))
+ {
+ pTemp->AI()->AttackStart(m_creature->getVictim());
+ pTemp->AddThreat(m_creature->getVictim(), 100.0f);
+ }
+ }
+ }
+ break;
+ case 3:
+ k = urand(0, 3);
+ i = urand(k + 1, k + 2);
+ for(uint8 j = k; j < i; j++)
+ {
+ if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_WARBRINGER, ArenaLoc[j].x, ArenaLoc[j].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f);
+ if(pTemp->IsWithinLOSInMap(m_creature->getVictim()))
+ {
+ pTemp->AI()->AttackStart(m_creature->getVictim());
+ pTemp->AddThreat(m_creature->getVictim(), 100.0f);
+ }
+ }
+ }
+ break;
+ case 4:
+ i = urand(0, 5);
+ if(Creature* pTemp = m_creature->SummonCreature(MOB_DARK_RUNE_ACOLYTE, ArenaLoc[i].x, ArenaLoc[i].y, LOC_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MovePoint(0, 2134.72f, -263.148f, 419.846f);
+ if(pTemp->IsWithinLOSInMap(m_creature->getVictim()))
+ {
+ pTemp->AI()->AttackStart(m_creature->getVictim());
+ pTemp->AddThreat(m_creature->getVictim(), 100.0f);
+ }
+ }
+ break;
+ }
+ m_uiSummonWavesTimer = urand (7000, 10000);
+ }
+ else m_uiSummonWavesTimer -= uiDiff;
+
+ // phase 1 spells
+ // charge orb
+ // doesn't work right, needs fixing
+ if(m_uiChargeOrbTimer < uiDiff)
+ {
+ if (Creature* pOrb = SelectRandomOrb())
+ DoCast(pOrb, SPELL_CHARGE_ORB);
+ m_uiChargeOrbTimer = 20000;
+ }
+ else m_uiChargeOrbTimer -= uiDiff;
+
+ // storm hammer
+ if(m_uiStormHammerTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ // should target only the players in the arena!
+ //if(pTarget->IsWithinLOSInMap(m_creature))
+ {
+ DoCast(pTarget, SPELL_STORMHAMMER);
+ m_uiStormHammerTimer = 15000;
+ }
+ }
+ }
+ else m_uiStormHammerTimer -= uiDiff;
+
+ if(m_uiArenaYellTimer < uiDiff)
+ {
+ switch(urand(0, 2))
+ {
+ case 0: DoScriptText(SAY_SPECIAL1, m_creature); break;
+ case 1: DoScriptText(SAY_SPECIAL2, m_creature); break;
+ case 2: DoScriptText(SAY_SPECIAL3, m_creature); break;
+ }
+ m_uiArenaYellTimer = 30000;
+ }
+ else m_uiArenaYellTimer -= uiDiff;
+
+ // phase 1 berserk
+ if(m_uiArenaBerserkTimer < uiDiff)
+ {
+ DoScriptText(SAY_ARENA_WIPE, m_creature);
+ //DoCast(m_creature, SPELL_BERSERK_ADDS);
+ // workaround because berserk doesn't work. It's casted on players not on adds. Needs core fix
+ KillPlayers();
+ DoCast(m_creature, SPELL_SUMMON_LIGHTNING_ORB);
+ m_uiArenaBerserkTimer = 30000;
+ }
+ else m_uiArenaBerserkTimer -= uiDiff;
+
+ break;
+ }
+ // arena phase
+ case PHASE_ARENA:
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // all spells
+ // chain lightning
+ if(m_uiChainLightningTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H);
+ m_uiChainLightningTimer = 10000 + rand()%5000;
+ }
+ else m_uiChainLightningTimer -= uiDiff;
+
+ // lightning charge
+ if(m_uiLightningChargeTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_LIGHTNING_CHARGE);
+ m_uiLightningChargeTimer = 15000;
+ m_uiOrbChargeTimer = 2000;
+ }
+ else m_uiLightningChargeTimer -= uiDiff;
+
+ if(m_uiOrbChargeTimer < uiDiff)
+ {
+ if (Creature* pOrb = SelectRandomOrb())
+ DoCast(pOrb, SPELL_LIGHTNING_CHARGE_ORB);
+ m_uiOrbChargeTimer = 20000;
+ }
+ else m_uiOrbChargeTimer -= uiDiff;
+
+ // unbalancing strike
+ if(m_uiUnbalancingStrikeTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, SPELL_UNBALANCING_STRIKE);
+ m_uiUnbalancingStrikeTimer = 25000;
+ }
+ else m_uiUnbalancingStrikeTimer -= uiDiff;
+
+ // phase 2 berserk
+ if(m_uiBerserkTimer < uiDiff)
+ {
+ m_creature->InterruptNonMeleeSpells(true);
+ DoScriptText(SAY_BERSERK, m_creature);
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserkTimer = 30000;
+ }
+ else m_uiBerserkTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ break;
+ }
+ // outro
+ case PHASE_OUTRO:
+ {
+ switch(m_uiOutroStep)
+ {
+ case 1:
+ m_creature->setFaction(35);
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 1000;
+ break;
+ case 3:
+ m_creature->SetOrientation(4.99f);
+ DoScriptText(SAY_DEATH, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 3000;
+ break;
+ case 5:
+ if(m_bIsHardMode)
+ {
+ DoScriptText(SAY_OUTRO_HARD1, m_creature);
+ if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID))
+ DoCast(Sif, SPELL_STORMHAMMER);
+ }
+ else
+ DoScriptText(SAY_OUTRO1, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 1000;
+ break;
+ case 7:
+ if(m_bIsHardMode)
+ {
+ if(Creature* Sif = m_pInstance->instance->GetCreature(m_uiSifGUID))
+ {
+ //summon a tentacule
+ if(Creature* pTentacule = m_creature->SummonCreature(34266, Sif->GetPositionX(), Sif->GetPositionY(), Sif->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000))
+ {
+ pTentacule->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pTentacule->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ Sif->ForcedDespawn();
+ }
+ }
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 7000;
+ break;
+ case 9:
+ if(m_bIsHardMode)
+ DoScriptText(SAY_OUTRO_HARD2, m_creature);
+ else
+ DoScriptText(SAY_OUTRO2, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 13000;
+ break;
+ case 11:
+ if(m_bIsHardMode)
+ DoScriptText(SAY_OUTRO_HARD3, m_creature);
+ else
+ DoScriptText(SAY_OUTRO3, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 15000;
+ break;
+ case 13:
+ DoOutro();
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 10000;
+ break;
+ }
+
+ if (m_uiOutroTimer <= uiDiff)
+ {
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 330000;
+ } m_uiOutroTimer -= uiDiff;
+
+ break;
+ }
+ }
+ }
};
+CreatureAI* GetAI_boss_thorim(Creature* pCreature)
+{
+ return new boss_thorimAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL boss_runic_colossusAI : public ScriptedAI
+{
+ boss_runic_colossusAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiSpellTimer;
+ uint32 m_uiRunicBarrierTimer;
+ uint32 m_uiSmashTimer;
+ uint64 m_uiSmashTargetGUID;
+ bool m_bIsSmash;
+ bool m_bMustSmash;
+
+ void Reset()
+ {
+ m_uiSpellTimer = urand(5000, 10000);
+ m_uiRunicBarrierTimer = 15000;
+ m_uiSmashTimer = 3000;
+ m_uiSmashTargetGUID = 0;
+ m_bIsSmash = false;
+ m_bMustSmash = true;
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_RUNIC_COLOSSUS, NOT_STARTED);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_RUNIC_COLOSSUS, DONE);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ // start smashing
+ if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) &&
+ !m_bIsSmash && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 70) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ m_uiSmashTargetGUID = pWho->GetGUID();
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_bIsSmash = true;
+ }
+
+ if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) &&
+ m_bIsSmash && pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 5) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ m_bMustSmash = false;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ // smash, doesn't work. Spell needs core fix
+ if(m_uiSmashTimer < uiDiff && m_bIsSmash && m_bMustSmash)
+ {
+ if(Unit* pTarget = m_creature->GetMap()->GetUnit( m_uiSmashTargetGUID))
+ DoCast(pTarget, SPELL_RUNIC_SMASH_DMG);
+ m_uiSmashTimer = 10000;
+ }
+ else m_uiSmashTimer -= uiDiff;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpellTimer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ DoCast(m_creature, SPELL_SMASH);
+ break;
+ case 1:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_CHARGE : SPELL_CHARGE_H);
+ break;
+ }
+ m_uiSpellTimer = urand(5000, 10000);
+ }else m_uiSpellTimer -= uiDiff;
+
+ if (m_uiRunicBarrierTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_RUNIC_BARRIER);
+ m_uiRunicBarrierTimer = urand(25000, 30000);
+ }else m_uiRunicBarrierTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_runic_colossus(Creature* pCreature)
+{
+ return new boss_runic_colossusAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL boss_ancient_rune_giantAI : public ScriptedAI
+{
+ boss_ancient_rune_giantAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiSpellTimer;
+ uint32 m_uiSummonTimer;
+ bool m_bIsSummoning;
+ bool m_bSummonStop;
+
+ void Reset()
+ {
+ m_uiSpellTimer = urand(5000, 10000);
+ m_uiSummonTimer = 10000;
+ m_bIsSummoning = false;
+ m_bSummonStop = false;
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_RUNE_GIANT, NOT_STARTED);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_RUNE_GIANT, DONE);
+ }
+
+ void Aggro(Unit *who)
+ {
+ // should be cast on adds, spell needs core fix
+ //DoCast(m_creature, SPELL_RUNIC_FORTIFICATION);
+ m_bSummonStop = true;
+ m_bIsSummoning = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_pInstance->GetData(TYPE_RUNIC_COLOSSUS) == DONE && !m_bIsSummoning && !m_bSummonStop)
+ m_bIsSummoning = true;
+
+ // summon adds before aggro and after the runic colossus has died
+ if(m_uiSummonTimer < uiDiff && m_bIsSummoning)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ // ring guard
+ if(Creature* pTemp = m_creature->SummonCreature(32874, OrbLoc[0].x + 30, OrbLoc[0].y, OrbLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MovePoint(0, OrbLoc[1].x, OrbLoc[1].y, OrbLoc[1].z);
+ pTemp->SetInCombatWithZone();
+ }
+ break;
+ case 1:
+ // honor guard
+ if(Creature* pTemp = m_creature->SummonCreature(33125, OrbLoc[0].x + 30, OrbLoc[0].y, OrbLoc[0].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MovePoint(0, OrbLoc[1].x, OrbLoc[1].y, OrbLoc[1].z);
+ pTemp->SetInCombatWithZone();
+ }
+ break;
+ }
+ m_uiSummonTimer = 10000;
+ }
+ else m_uiSummonTimer -= uiDiff;
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpellTimer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), m_bIsRegularMode? SPELL_STOMP : SPELL_STOMP_H);
+ break;
+ case 1:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_RUNE_DETONATION);
+ break;
+ }
+ m_uiSpellTimer = urand(5000,10000);
+ }else m_uiSpellTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_ancient_rune_giant(Creature* pCreature)
+{
+ return new boss_ancient_rune_giantAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL mob_thorim_preaddsAI : public ScriptedAI
+{
+ mob_thorim_preaddsAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance* m_pInstance;
+
+ // jormungar
+ uint32 m_uiAcidBreathTimer;
+ uint32 m_uiSweepTimer;
+
+ // captain
+ uint32 m_uiDevastateTimer;
+ uint32 m_uiHeroicStrikeTimer;
+
+ // mercenary
+ uint32 m_uiShootTimer;
+ uint32 m_uiBarbedShotTimer;
+ uint32 m_uiWingClipTimer;
+
+ void Reset()
+ {
+ // jormungar
+ m_uiAcidBreathTimer = urand(7000, 14000);
+ m_uiSweepTimer = urand(15000, 20000);
+
+ // captain
+ m_uiDevastateTimer = urand(3000, 7000);
+ m_uiHeroicStrikeTimer = urand(8000, 15000);
+
+ // mercenary
+ m_uiShootTimer = 1000;
+ m_uiBarbedShotTimer = urand(7000, 10000);
+ m_uiWingClipTimer = urand(10000, 15000);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ if(m_creature->GetEntry() == NPC_MERCENARY_ALY || m_creature->GetEntry() == NPC_MERCENARY_HORDE)
+ DoStartMovement(pWho, 20);
+ else
+ DoStartMovement(pWho);
+ }
+ }
+
+ void JustDied(Unit *killer)
+ {
+ // start the encounter
+ if (Creature* pThorim = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_THORIM)))
+ {
+ if(pThorim->isAlive())
+ ((boss_thorimAI*)pThorim->AI())->m_uiPreAddsKilled += 1;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ switch(m_creature->GetEntry())
+ {
+ case NPC_JORMUNGAR_BEHEMOTH:
+ {
+ if(m_uiAcidBreathTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ACID_BREATH : SPELL_ACID_BREATH_H);
+ m_uiAcidBreathTimer = urand(7000, 14000);
+ }
+ else m_uiAcidBreathTimer -= uiDiff;
+
+ if(m_uiSweepTimer < uiDiff)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SWEEP : SPELL_SWEEP_H);
+ m_uiSweepTimer = urand(15000, 23000);
+ }
+ else m_uiSweepTimer -= uiDiff;
+
+ break;
+ }
+ case NPC_CAPTAIN_ALY:
+ case NPC_CAPTAIN_HORDE:
+ {
+ if(m_uiDevastateTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, SPELL_DEVASTATE);
+ m_uiDevastateTimer = urand(4000, 7000);
+ }
+ else m_uiDevastateTimer -= uiDiff;
+
+ if(m_uiHeroicStrikeTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_HEROIC_STRIKE);
+ m_uiHeroicStrikeTimer = urand(10000, 15000);
+ }
+ else m_uiHeroicStrikeTimer -= uiDiff;
+
+ break;
+ }
+ case NPC_MERCENARY_ALY:
+ case NPC_MERCENARY_HORDE:
+ {
+ if(m_uiShootTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHOOT);
+ m_uiShootTimer = urand(1000, 3000);
+ }
+ else m_uiShootTimer -= uiDiff;
+
+ if(m_uiBarbedShotTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BARBED_SHOT);
+ m_uiBarbedShotTimer = urand(7000, 10000);
+ }
+ else m_uiBarbedShotTimer -= uiDiff;
+
+ if(m_uiWingClipTimer < uiDiff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_WING_CLIP);
+ m_uiWingClipTimer = urand(10000, 15000);
+ }
+ else m_uiWingClipTimer -= uiDiff;
+
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_thorim_preadds(Creature* pCreature)
+{
+ return new mob_thorim_preaddsAI(pCreature);
+}
+
+// sif
+struct MANGOS_DLL_DECL npc_sifAI : public ScriptedAI
+{
+ npc_sifAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiSpellTimer;
+
+ void Reset()
+ {
+ m_uiSpellTimer = urand(5000, 10000);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ DoStartMovement(pWho, 10.0f);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_THORIM) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSpellTimer < uiDiff)
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ DoCast(m_creature, m_bIsRegularMode? SPELL_FROSTBOLT_VOLLEY : SPELL_FROSTBOLT_VOLLEY_H);
+ break;
+ case 1:
+ DoCast(m_creature, m_bIsRegularMode? SPELL_FROST_NOVA : SPELL_FROST_NOVA_H);
+ break;
+ case 2:
+ // it should be casted around the room!
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode? SPELL_BLIZZARD : SPELL_BLIZZARD_H);
+ break;
+ }
+
+ m_uiSpellTimer = urand(3000, 6000);
+ }else m_uiSpellTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_sif(Creature* pCreature)
+{
+ return new npc_sifAI(pCreature);
+}
+
+// script for the orb on the hallway which should wipe the raid. Needs more research!
+struct MANGOS_DLL_DECL npc_lightning_orbAI : public ScriptedAI
+{
+ npc_lightning_orbAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pCreature->setFaction(14);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiMoveTimer;
+ uint8 m_uiWaypoint;
+
+ void Reset()
+ {
+ m_uiMoveTimer = 1000;
+ m_uiWaypoint = 0;
+ m_creature->SetRespawnDelay(DAY);
+ // find the correct aura for raid wipe!!!
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_THORIM) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_uiMoveTimer < uiDiff && m_uiWaypoint < 4)
+ {
+ m_creature->GetMotionMaster()->MovePoint(0, OrbLoc[m_uiWaypoint].x, OrbLoc[m_uiWaypoint].y, OrbLoc[m_uiWaypoint].z);
+ m_uiWaypoint +=1;
+ m_uiMoveTimer = 10000;
+ }
+ else m_uiMoveTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_lightning_orb(Creature* pCreature)
+{
+ return new npc_lightning_orbAI(pCreature);
+}
+
+
void AddSC_boss_thorim()
{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_thorim";
+ newscript->GetAI = &GetAI_boss_thorim;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_runic_colossus";
+ newscript->GetAI = &GetAI_boss_runic_colossus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_ancient_rune_giant";
+ newscript->GetAI = &GetAI_boss_ancient_rune_giant;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_sif";
+ newscript->GetAI = &GetAI_npc_sif;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_lightning_orb";
+ newscript->GetAI = &GetAI_npc_lightning_orb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_rune_acolyte";
+ newscript->GetAI = &GetAI_mob_dark_rune_acolyte;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_rune_champion";
+ newscript->GetAI = &GetAI_mob_dark_rune_champion;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_rune_commoner";
+ newscript->GetAI = &GetAI_mob_dark_rune_commoner;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_rune_evoker";
+ newscript->GetAI = &GetAI_mob_dark_rune_evoker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_rune_warbringer";
+ newscript->GetAI = &GetAI_mob_dark_rune_warbringer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_rune_ring_guard";
+ newscript->GetAI = &GetAI_mob_dark_rune_ring_guard;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dark_rune_honor_guard";
+ newscript->GetAI = &GetAI_mob_dark_rune_honor_guard;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_thorim_preadds";
+ newscript->GetAI = &GetAI_mob_thorim_preadds;
+ newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "mob_thorim_trap_bunny";
+ newscript->GetAI = &GetAI_mob_thorim_trap_bunny;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/ulduar/ulduar/boss_vezax.cpp b/scripts/northrend/ulduar/ulduar/boss_vezax.cpp
new file mode 100644
index 0000000..f15e0e9
--- /dev/null
+++ b/scripts/northrend/ulduar/ulduar/boss_vezax.cpp
@@ -0,0 +1,486 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_vezax
+SD%Complete:
+SDComment: mark of the faceless needs core support. Searing flames needs fixing, cannot be interrupted
+SDCategory: Ulduar
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ulduar.h"
+
+enum
+{
+ SAY_AGGRO = -1603120,
+ SAY_SURGE = -1603123,
+ SAY_HARD = -1603126,
+ SAY_SLAY1 = -1603121,
+ SAY_SLAY2 = -1603122,
+ SAY_BERSERK = -1603125,
+ SAY_DEATH = -1603124,
+ EMOTE_VAPORS = -1603366,
+ EMOTE_SURGE = -1603367,
+ EMOTE_ANIMUS = -1603368,
+
+ SPELL_AURA_OF_DESPAIR = 62692,
+ SPELL_SHADOW_CRASH = 62660,
+ SPELL_MARK_OF_FACELESS = 63276,
+ SPELL_MARK_SIMPHON = 63278,
+ SPELL_SEARING_FLAMES = 62661,
+ SPELL_SURGE_OF_DARKNESS = 62662,
+ SPELL_BERSERK = 26662,
+ SPELL_SARONITE_BARRIER = 63364,
+ SPELL_SUMMON_ANIMUS = 63145,
+ SPELL_SUMMON_VAPORS = 63081,
+
+ NPC_SARONITE_VAPOR = 33488,
+ SPELL_SARONITE_VAPORS = 63323,
+
+ NPC_SARONITE_ANIMUS = 33524,
+ SPELL_PROFOUND_DARKNESS = 63420,
+ SPELL_ANIMUS_FORMATION = 63319,
+
+ ACHIEV_MORNING_SARONITE = 3181,
+ ACHIEV_MORNING_SARONITE_H = 3188,
+};
+
+uint8 m_uiSaroniteVaporCount;
+
+struct MANGOS_DLL_DECL boss_vezaxAI : public ScriptedAI
+{
+ boss_vezaxAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiEnrageTimer;
+ uint32 m_uiCrashTimer;
+ uint32 m_uiMarkTimer;
+ uint32 m_uiFlamesTimer;
+ uint32 m_uiSurgeTimer;
+ uint32 m_uiSaroniteVaporTimer;
+ uint32 m_uiSimphonTimer;
+ uint32 m_uiEndSimphonTimer;
+ uint32 m_uiSummonAnimusTimer;
+ uint64 m_uiAnimusGUID;
+ uint64 m_uiMarkTargetGUID;
+ uint32 m_uiMarkCheckTimer;
+ uint32 m_uiMarkEndTimer;
+
+ std::list lVapors;
+
+ bool m_bIsHardMode;
+ bool m_bActiveHardMode;
+ bool m_bHasMark;
+ bool m_bHasSimphon;
+ bool m_bIsAnimusAlive;
+
+ void Reset()
+ {
+ m_uiEnrageTimer = 600000; //10 minutes
+ m_uiFlamesTimer = urand(8000, 10000);
+ m_uiSaroniteVaporTimer = 30000;
+ m_bIsHardMode = false;
+ m_bActiveHardMode = false;
+ m_bHasMark = false;
+ m_bHasSimphon = false;
+ m_bIsAnimusAlive = false;
+
+ m_uiSurgeTimer = 60000;
+ m_uiMarkTimer = urand(10000, 35000);
+ m_uiCrashTimer = 10000;
+ m_uiSimphonTimer = 1000;
+ m_uiEndSimphonTimer = 10000;
+ m_uiAnimusGUID = 0;
+ m_uiMarkTargetGUID = 0;
+
+ lVapors.clear();
+
+ m_uiSaroniteVaporCount = 0;
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_VEZAX, IN_PROGRESS);
+
+ DoCast(m_creature, SPELL_AURA_OF_DESPAIR);
+
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_VEZAX, FAIL);
+
+ m_creature->RemoveAurasDueToSpell(SPELL_SARONITE_BARRIER);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_VEZAX, DONE);
+
+ if(m_bIsHardMode)
+ {
+ m_pInstance->SetData(TYPE_VEZAX_HARD, DONE);
+
+ // hacky way to complete achievements; use only if you have this function
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_MORNING_SARONITE : ACHIEV_MORNING_SARONITE_H);
+ // hack used when the hard mode loot is within the Animus corpse
+ // PLEASE REMOVE FOR REVISION
+ if(Creature* pAnimus = m_pInstance->instance->GetCreature(m_uiAnimusGUID))
+ pAnimus->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_SLAY2, m_creature);
+ }
+
+ void PrepareHardMode()
+ {
+ m_bActiveHardMode = true;
+ m_uiSummonAnimusTimer = 7000;
+
+ GetCreatureListWithEntryInGrid(lVapors, m_creature, NPC_SARONITE_VAPOR, 200.0f);
+
+ if (!lVapors.empty())
+ {
+ // vapors need more speed
+ for(std::list::iterator iter = lVapors.begin(); iter != lVapors.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ {
+ (*iter)->RemoveAllAuras();
+ (*iter)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ (*iter)->SetSpeedRate(MOVE_RUN, 3.0f);
+ (*iter)->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
+ (*iter)->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
+ }
+ }
+ }
+ }
+
+ void ActivateHardMode()
+ {
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_SARONITE_BARRIER);
+ //DoCast(m_creature, SPELL_SUMMON_ANIMUS); // make it by summon creature because of better handling the auras
+ DoScriptText(EMOTE_ANIMUS, m_creature);
+ DoScriptText(SAY_HARD, m_creature);
+
+ if(Creature* pAnimus = m_creature->SummonCreature(NPC_SARONITE_ANIMUS, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 900000))
+ {
+ pAnimus->SetInCombatWithZone();
+ m_uiAnimusGUID = pAnimus->GetGUID();
+ }
+
+ if (!lVapors.empty())
+ {
+ for(std::list::iterator iter = lVapors.begin(); iter != lVapors.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->ForcedDespawn();
+ }
+ }
+
+ m_bIsHardMode = true;
+ m_bIsAnimusAlive = true;
+ }
+
+ // hacky way for the mark of the faceless, needs core support
+ // PLEASE REMOVE FOR REVISION!
+ void CheckForMark(uint64 m_uiTargetGUID)
+ {
+ if(m_uiTargetGUID == 0)
+ return;
+
+ m_bHasSimphon = false;
+ Map *map = m_creature->GetMap();
+ Unit* pTarget = m_creature->GetMap()->GetUnit( m_uiTargetGUID);
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if(pTarget && pTarget->isAlive() && !m_bHasSimphon && m_uiTargetGUID != i->getSource()->GetGUID())
+ {
+ if (i->getSource()->isAlive() && pTarget->GetDistance2d(i->getSource()) < 10.0f)
+ {
+ DoCast(pTarget, SPELL_MARK_SIMPHON);
+ m_bHasSimphon = true;
+ }
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // prepare hard mode
+ if(m_uiSaroniteVaporCount == 6 && !m_bIsHardMode && !m_bActiveHardMode)
+ PrepareHardMode();
+
+ // summon animus
+ if(m_uiSummonAnimusTimer < uiDiff && !m_bIsHardMode && m_bActiveHardMode)
+ ActivateHardMode();
+ else m_uiSummonAnimusTimer -= uiDiff;
+
+ // saronite vapor
+ if(m_uiSaroniteVaporTimer < uiDiff && !m_bIsHardMode)
+ {
+ m_creature->CastStop();
+ DoCast(m_creature, SPELL_SUMMON_VAPORS);
+ DoScriptText(EMOTE_VAPORS, m_creature);
+ m_uiSaroniteVaporCount += 1;
+ m_uiSaroniteVaporTimer = 30000;
+ }
+ else m_uiSaroniteVaporTimer -= uiDiff;
+
+ // searing flames
+ if(m_uiFlamesTimer < uiDiff && !m_bIsAnimusAlive)
+ {
+ DoCast(m_creature, SPELL_SEARING_FLAMES);
+ m_uiFlamesTimer = urand(5000, 10000);
+ }
+ else m_uiFlamesTimer -= uiDiff;
+
+ // surge of darkness
+ if(m_uiSurgeTimer < uiDiff)
+ {
+ m_creature->CastStop();
+ DoScriptText(SAY_SURGE, m_creature);
+ DoScriptText(EMOTE_SURGE, m_creature);
+ DoCast(m_creature, SPELL_SURGE_OF_DARKNESS);
+ m_uiSurgeTimer = 60000;
+ }
+ else m_uiSurgeTimer -= uiDiff;
+
+ // mark of faceless
+ if(m_uiMarkTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ {
+ m_uiMarkTargetGUID = pTarget->GetGUID();
+ DoCast(pTarget, SPELL_MARK_OF_FACELESS);
+ }
+ m_bHasMark = true;
+ m_uiMarkCheckTimer = 1000;
+ m_uiMarkEndTimer = 10000;
+ m_uiMarkTimer = urand(25000, 30000);
+ }
+ else m_uiMarkTimer -= uiDiff;
+
+ // HACK FOR MARK OF THE FACELESS
+ // mark check ending
+ if(m_uiMarkEndTimer < uiDiff && m_bHasMark)
+ m_bHasMark = false;
+ else m_uiMarkEndTimer -= uiDiff;
+
+ // simphon life every sec
+ if(m_uiMarkCheckTimer < uiDiff && m_bHasMark)
+ {
+ CheckForMark(m_uiMarkTargetGUID);
+ m_uiMarkCheckTimer = 1000;
+ }
+ else m_uiMarkCheckTimer -= uiDiff;
+
+ // shadow crash
+ if(m_uiCrashTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
+ DoCast(pTarget, SPELL_SHADOW_CRASH);
+ m_uiCrashTimer = 10000;
+ }
+ else m_uiCrashTimer -= uiDiff;
+
+ // enrage 10 min
+ if(m_uiEnrageTimer < uiDiff)
+ {
+ DoScriptText(SAY_BERSERK, m_creature);
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiEnrageTimer = 30000;
+ }
+ else m_uiEnrageTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+// Saronite animus
+struct MANGOS_DLL_DECL mob_saronite_animusAI : public ScriptedAI
+{
+ mob_saronite_animusAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiProfoundDarknessTimer;
+
+ void Reset()
+ {
+ m_uiProfoundDarknessTimer = 3000;
+ DoCast(m_creature, SPELL_ANIMUS_FORMATION);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(m_pInstance)
+ {
+ if (Creature* pVezax = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_VEZAX)))
+ {
+ if (pVezax->isAlive())
+ {
+ pVezax->RemoveAurasDueToSpell(SPELL_SARONITE_BARRIER);
+ ((boss_vezaxAI*)pVezax->AI())->m_bIsAnimusAlive = false;
+ }
+ }
+ }
+ // used for hard mode loot
+ // REMOVE THIS FOR REVISION
+ //m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_VEZAX) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(m_uiProfoundDarknessTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_PROFOUND_DARKNESS);
+ m_uiProfoundDarknessTimer = urand(2000, 3000);
+ }
+ else m_uiProfoundDarknessTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_saronite_vaporAI : public ScriptedAI
+{
+ mob_saronite_vaporAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiDieTimer;
+
+ void Reset()
+ {
+ m_uiDieTimer = 600000;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void AttackStart(Unit *pWho)
+ {
+ return;
+ }
+
+ void JustDied(Unit *killer)
+ {
+ m_uiSaroniteVaporCount -= 1;
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ // Mana regen pool
+ if(uiDamage >= m_creature->GetHealth())
+ {
+ uiDamage = 0;
+ m_uiDieTimer = 500;
+ DoCast(m_creature, SPELL_SARONITE_VAPORS);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_VEZAX) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_uiDieTimer < diff)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDieTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_vezax(Creature* pCreature)
+{
+ return new boss_vezaxAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_saronite_animus(Creature* pCreature)
+{
+ return new mob_saronite_animusAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_saronite_vapor(Creature* pCreature)
+{
+ return new mob_saronite_vaporAI(pCreature);
+}
+
+void AddSC_boss_vezax()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_vezax";
+ newscript->GetAI = &GetAI_boss_vezax;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_saronite_animus";
+ newscript->GetAI = &GetAI_mob_saronite_animus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_saronite_vapor";
+ newscript->GetAI = &GetAI_mob_saronite_vapor;
+ newscript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_xt002.cpp b/scripts/northrend/ulduar/ulduar/boss_xt002.cpp
new file mode 100644
index 0000000..fb8a775
--- /dev/null
+++ b/scripts/northrend/ulduar/ulduar/boss_xt002.cpp
@@ -0,0 +1,804 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_xt002
+SD%Complete:
+SDComment: need core support for light and gravity bomb. correct number of adds in 25man missing
+SDCategory: Ulduar
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ulduar.h"
+
+enum
+{
+ //xt yells
+ SAY_AGGRO = -1603038,
+ SAY_DEATH = -1603030,
+ SAY_TANCTRUM = -1603037,
+ SAY_SLAY_01 = -1603036,
+ SAY_SLAY_02 = -1603035,
+ SAY_BERSERK = -1603031,
+ SAY_ADDS = -1603032,
+ SAY_HEART_OPEN = -1603034,
+ SAY_HEART_CLOSE = -1603033,
+ EMOTE_HEART = -1603350,
+ EMOTE_REPAIR = -1603351,
+
+ //xt-002
+ SPELL_TANCTRUM = 62776,
+ SPELL_LIGHT_BOMB_TRIG = 65598,
+ SPELL_LIGHT_BOMB = 63018,
+ SPELL_LIGHT_BOMB_H = 65121,
+ SPELL_GRAVITY_BOMB = 63024,
+ SPELL_GRAVITY_BOMB_H = 64234,
+ SPELL_ENRAGE = 47008,
+ SPELL_STUN = 3618,
+
+ // hard mode
+ SPELL_HEARTBREAK = 65737,
+ SPELL_HEARTBREAK_H = 64193,
+ SPELL_VOIDZONE = 64203,
+ SPELL_VOIDZONE_H = 64235,
+ SPELL_LIFE_SPARK = 64210,
+ SPELL_STATIC_CHARGED = 64227,
+
+ NPC_VOIDZONE = 34001,
+ NPC_LIFESPARK = 34004,
+
+ //heart of the deconstructor
+ SPELL_EXPOSED_HEART = 63849,
+
+ //XE-321 Boombot
+ SPELL_BOOM = 38831, // replacing real spell
+
+ //XM-024 Pummeller
+ SPELL_CLEAVE = 8374,
+ SPELL_TRAMPLE = 5568,
+ SPELL_UPPERCUT = 10966,
+
+ //NPC ids
+ NPC_HEART = 33329,
+ NPC_SCRAPBOT = 33343,
+ NPC_BOOMBOT = 33346,
+ NPC_PUMMELER = 33344,
+
+ // Achievs
+ ACHIEV_HEARTBREAKER = 3058,
+ ACHIEV_HEARTBREAKER_H = 3059,
+ ACHIEV_DECONSTRUCT_FAST = 2937,
+ ACHIEV_DECONSTRUCT_FAST_H = 2938,
+ ACHIEV_NERF_ENGINEERING = 2931,
+ ACHIEV_NERF_ENGINEERING_H = 2932,
+ ACHIEV_NERF_GRAVITY_BOMBS = 2934,
+ ACHIEV_NERF_GRAVITY_BOMBS_H = 2936,
+ ACHIEV_NERF_SCRAPBOTS = 2933,
+ ACHIEV_NERF_SCRAPBOTS_H = 2935,
+};
+
+//Positional defines
+struct LocationsXY
+{
+ float x, y, z, o;
+ uint32 id;
+};
+
+static LocationsXY SummonLoc[]=
+{
+ {792.706f, 64.033f, 409.632f}, // lower left
+ {879.750f, 64.815f, 409.804f}, // upper left
+ {896.488f, -93.018f, 409.731f}, // upper right
+ {791.016f, -83.516f, 409.804f}, // lower right
+};
+
+// void zone
+struct MANGOS_DLL_DECL mob_voidzoneAI : public ScriptedAI
+{
+ mob_voidzoneAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->setFaction(14);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ uint32 Spell_Timer;
+ bool m_bIsRegularMode;
+
+ void Reset()
+ {
+ Spell_Timer = 4000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // should be an aura here. Couldn't find it
+ // hacky way, needs fixing!
+ if (Spell_Timer < diff)
+ {
+ Map *map = m_creature->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) < 2)
+ i->getSource()->DealDamage(i->getSource(), m_bIsRegularMode ? 5000 : 7500, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false);
+ }
+ }
+ Spell_Timer = 4000;
+ }else Spell_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_voidzone(Creature* pCreature)
+{
+ return new mob_voidzoneAI(pCreature);
+}
+
+// lifespark
+struct MANGOS_DLL_DECL mob_lifesparkAI : public ScriptedAI
+{
+ mob_lifesparkAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_STATIC_CHARGED);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_mob_lifespark(Creature* pCreature)
+{
+ return new mob_lifesparkAI(pCreature);
+}
+
+// XM-024 Pummeller
+struct MANGOS_DLL_DECL mob_pummelerAI : public ScriptedAI
+{
+ mob_pummelerAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+
+ uint32 Spell_Timer;
+
+ void Reset()
+ {
+ Spell_Timer = urand(5000, 10000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (Spell_Timer < diff)
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ DoCast(m_creature->getVictim(), SPELL_CLEAVE);
+ break;
+ case 1:
+ DoCast(m_creature->getVictim(), SPELL_TRAMPLE);
+ break;
+ case 2:
+ DoCast(m_creature->getVictim(), SPELL_UPPERCUT);
+ break;
+ }
+ Spell_Timer = urand(5000, 10000);
+ }else Spell_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_pummeler(Creature* pCreature)
+{
+ return new mob_pummelerAI(pCreature);
+}
+
+// XE-321 Boombot
+struct MANGOS_DLL_DECL mob_boombotAI : public ScriptedAI
+{
+ mob_boombotAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+
+ void Reset()
+ {
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth())
+ {
+ uiDamage = 0;
+ DoCast(m_creature, SPELL_BOOM);
+ }
+ }
+
+ void DoMeleeAttackIfReady()
+ {
+ //If we are within range melee the target
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
+ DoCast(m_creature, SPELL_BOOM);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_boombot(Creature* pCreature)
+{
+ return new mob_boombotAI(pCreature);
+}
+
+// Heart of the Deconstructor
+struct MANGOS_DLL_DECL mob_xtheartAI : public ScriptedAI
+{
+ mob_xtheartAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiDeathTimer;
+ uint32 m_uiTotalDamage;
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_EXPOSED_HEART);
+ m_creature->SetRespawnDelay(DAY);
+ m_uiTotalDamage = 0;
+ m_uiDeathTimer = 30000;
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ m_uiTotalDamage += uiDamage;
+ // double damage
+ uiDamage += uiDamage;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ // used for hard mode loot only when hard mode loot is within the heart's corpse
+ // remove this for revision
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_XT002_HARD, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ // despawns the creature if not killed in 30 secs
+ if(m_uiDeathTimer < diff)
+ {
+ // pass damage to boss
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_XT002)))
+ {
+ if (pTemp->isAlive())
+ pTemp->DealDamage(pTemp, m_uiTotalDamage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ m_creature->ForcedDespawn();
+ }
+ else
+ m_uiDeathTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_xtheart(Creature* pCreature)
+{
+ return new mob_xtheartAI(pCreature);
+}
+
+//XT-002 Deconstructor
+struct MANGOS_DLL_DECL boss_xt002AI : public ScriptedAI
+{
+ boss_xt002AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ std::list m_lScrapbotsGUIDList;
+ std::list m_lBoombotsGUIDList;
+ std::list m_lPummelerGUIDList;
+
+ // spell timers
+ uint32 m_uiHeart_Timer;
+ uint32 m_uiLight_Bomb_Timer;
+ uint32 m_uiGravity_Bomb_Timer;
+ uint32 m_uiTanctrum_Timer;
+ uint32 m_uiEnrage_Timer;
+ uint32 m_uiRange_Check_Timer;
+ uint32 m_uiVoidZoneTimer;
+ uint32 m_uiLifeSparkTimer;
+
+ // summon timers
+ uint32 m_uiScrapbotTimer;
+ uint32 m_uiBoombotTimer;
+ uint32 m_uiPummellerTimer;
+ uint32 m_uiScrapbotCount;
+ uint32 m_uiBoombotCount;
+ uint32 m_uiPummellerCount;
+ uint32 m_uiMaxScrapbot;
+ uint32 m_uiMaxBoombot;
+
+ // health timers
+ uint32 m_uiHealthPercent;
+ uint32 m_uiHpDelayTimer;
+ bool m_bIsEnrage;
+ bool m_bPhase2;
+
+ uint64 pLightBombTarGUID;
+ uint64 pGravityBombTarGUID;
+ uint64 m_uiXtHeartGUID;
+
+ bool m_bIsHardMode;
+ bool m_bHasMoreHealth;
+
+ uint32 uiEncounterTimer;
+ bool m_bIsEngineer;
+
+ void Reset()
+ {
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+
+ // spell timers
+ m_uiLight_Bomb_Timer = 5000; // 7 seconds the first 14 secs all after(7 secs in 25man)
+ m_uiGravity_Bomb_Timer = 30000; // 11 seconds first 18 secs all after(11 secs in 25man)
+ m_uiTanctrum_Timer = 35000; // 38 seconds first 40 secs all after
+ m_uiEnrage_Timer = 600000; // 10 min
+ m_uiRange_Check_Timer = 1000;
+ m_uiVoidZoneTimer = 60000;
+ m_uiLifeSparkTimer = urand (5000, 10000);
+ // summon timers
+ m_uiScrapbotTimer = 5000;
+ m_uiBoombotTimer = 5000;
+ m_uiPummellerTimer = 5000;
+ m_uiScrapbotCount = 0;
+ m_uiBoombotCount = 0;
+ m_uiPummellerCount = 0;
+ m_uiMaxScrapbot = 0;
+ m_uiMaxBoombot = 0;
+ // health timers
+ m_uiHealthPercent = 75;
+
+ m_bIsEnrage = false;
+ m_bPhase2 = false;
+ m_bIsHardMode = false;
+ m_bHasMoreHealth = false;
+ m_lScrapbotsGUIDList.clear();
+ m_lBoombotsGUIDList.clear();
+ m_lPummelerGUIDList.clear();
+
+ pLightBombTarGUID = 0;
+ pGravityBombTarGUID = 0;
+ m_uiXtHeartGUID = 0;
+
+ uiEncounterTimer = 0;
+ m_bIsEngineer = true;
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_XT002, DONE);
+ if(m_bIsHardMode)
+ {
+ m_pInstance->SetData(TYPE_XT002_HARD, DONE);
+ // make the heart give the loot for hard mode
+ // hacky way of giving hard mode loot, used only when hard mode loot is within the heart's corpse
+ // PLEASE REMOVE FOR REVISION!
+ if(Creature* pHeart = m_pInstance->instance->GetCreature(m_uiXtHeartGUID))
+ pHeart->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ DoScriptText(SAY_DEATH, m_creature);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (!m_lScrapbotsGUIDList.empty())
+ {
+ for(std::list::iterator itr = m_lScrapbotsGUIDList.begin(); itr != m_lScrapbotsGUIDList.end(); ++itr)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ pTemp->ForcedDespawn();
+ }
+ if (!m_lBoombotsGUIDList.empty())
+ {
+ for(std::list::iterator itr = m_lBoombotsGUIDList.begin(); itr != m_lBoombotsGUIDList.end(); ++itr)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ pTemp->ForcedDespawn();
+ }
+ if (!m_lPummelerGUIDList.empty())
+ {
+ for(std::list::iterator itr = m_lPummelerGUIDList.begin(); itr != m_lPummelerGUIDList.end(); ++itr)
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ pTemp->ForcedDespawn();
+ }
+
+ // hacky way to complete achievements; use only if you have this function
+ // Deconstruct Fast
+ if (uiEncounterTimer < 205000)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_DECONSTRUCT_FAST : ACHIEV_DECONSTRUCT_FAST_H);
+ }
+
+ // Heartbreaker
+ if (m_bIsHardMode)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_HEARTBREAKER : ACHIEV_HEARTBREAKER_H);
+ }
+
+ // Nerf Engineer
+ if(m_bIsEngineer)
+ {
+ if(m_pInstance)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_NERF_ENGINEERING : ACHIEV_NERF_ENGINEERING_H);
+ }
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_XT002, IN_PROGRESS);
+ if(m_pInstance->GetData(TYPE_XT002_TP) != DONE)
+ m_pInstance->SetData(TYPE_XT002_TP, DONE);
+ }
+
+ DoScriptText(SAY_AGGRO, m_creature);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_XT002, FAIL);
+ m_pInstance->SetData(TYPE_XT002_HARD, NOT_STARTED);
+ }
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ switch(urand(0, 1))
+ {
+ case 0: DoScriptText(SAY_SLAY_01, m_creature); break;
+ case 1: DoScriptText(SAY_SLAY_02, m_creature); break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // Achiev timer
+ uiEncounterTimer += uiDiff;
+
+ // light bomb
+ if (m_uiLight_Bomb_Timer < uiDiff && !m_bPhase2)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ // fix spell range
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_LIGHT_BOMB : SPELL_LIGHT_BOMB_H);
+ pLightBombTarGUID = pTarget->GetGUID();
+ }
+
+ // spawn a life spark from the target
+ if(m_bIsHardMode)
+ m_uiLifeSparkTimer = 9000;
+
+ m_uiLight_Bomb_Timer = urand(10000, 14000);
+ }else m_uiLight_Bomb_Timer -= uiDiff;
+
+ // graviti bomb
+ if (m_uiGravity_Bomb_Timer < uiDiff && !m_bPhase2)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ // fix spell range
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_GRAVITY_BOMB : SPELL_GRAVITY_BOMB_H);
+ pGravityBombTarGUID = pTarget->GetGUID();
+ }
+
+ // spawn a void zone from the target
+ if(m_bIsHardMode)
+ m_uiVoidZoneTimer = 9000;
+
+ m_uiGravity_Bomb_Timer = urand(25000, 30000);
+ }else m_uiGravity_Bomb_Timer -= uiDiff;
+
+ if (m_uiTanctrum_Timer < uiDiff && !m_bPhase2)
+ {
+ DoCast(m_creature, SPELL_TANCTRUM);
+ DoScriptText(SAY_TANCTRUM, m_creature);
+ m_uiTanctrum_Timer = 60000;
+ }else m_uiTanctrum_Timer -= uiDiff;
+
+ // enrage timer
+ if (m_uiEnrage_Timer < uiDiff && !m_bIsEnrage && !m_bPhase2)
+ {
+ DoCast(m_creature, SPELL_ENRAGE);
+ if (m_creature->HasAura(SPELL_ENRAGE))
+ {
+ m_bIsEnrage = true;
+ DoScriptText(SAY_BERSERK, m_creature);
+ }
+ else
+ m_uiEnrage_Timer = 5000;
+ }else m_uiEnrage_Timer -= uiDiff;
+
+ // adds range check
+ if (m_uiRange_Check_Timer < uiDiff)
+ {
+ if (!m_lScrapbotsGUIDList.empty())
+ {
+ for(std::list::iterator itr = m_lScrapbotsGUIDList.begin(); itr != m_lScrapbotsGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ {
+ if (pTemp->isAlive() && m_creature->IsWithinDistInMap(pTemp, ATTACK_DISTANCE))
+ {
+ m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.01);
+ pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_bIsEngineer = false;
+ DoScriptText(EMOTE_REPAIR, m_creature);
+ }
+ }
+ }
+ }
+ if (!m_lBoombotsGUIDList.empty())
+ {
+ for(std::list::iterator itr = m_lBoombotsGUIDList.begin(); itr != m_lBoombotsGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
+ {
+ if (pTemp->isAlive() && m_creature->IsWithinDistInMap(pTemp, ATTACK_DISTANCE))
+ pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+ }
+ m_uiRange_Check_Timer = 1000;
+ }else m_uiRange_Check_Timer -= uiDiff;
+
+ // Hard mode
+ if (m_pInstance->GetData(TYPE_XT002_HARD) == IN_PROGRESS && !m_bIsHardMode)
+ {
+ DoScriptText(SAY_HEART_CLOSE, m_creature);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_creature->RemoveAurasDueToSpell(SPELL_STUN);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->AI()->AttackStart(m_creature->getVictim());
+
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_HEARTBREAK : SPELL_HEARTBREAK_H);
+ m_uiHpDelayTimer = 500;
+ m_bHasMoreHealth = true;
+ m_bIsHardMode = true;
+ }
+
+ if(m_bIsHardMode)
+ {
+ m_bPhase2 = false;
+
+ // the spell doesn't increase the boss' heart. Override
+ if(m_uiHpDelayTimer < uiDiff && m_bHasMoreHealth)
+ {
+ m_creature->SetHealth(m_creature->GetMaxHealth()+ (m_creature->GetMaxHealth() * m_bIsRegularMode ? 0.5 : 0.6));
+ m_bHasMoreHealth = false;
+ }else m_uiHpDelayTimer -= uiDiff;
+
+ if (m_uiLifeSparkTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->GetMap()->GetUnit( pLightBombTarGUID))
+ {
+ Creature * LifeSpark = m_creature->SummonCreature(NPC_LIFESPARK, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
+ if(m_bIsRegularMode)
+ LifeSpark->SetHealth(50400);
+ }
+ m_uiLifeSparkTimer = 60000;
+ }else m_uiLifeSparkTimer -= uiDiff;
+
+ if (m_uiVoidZoneTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->GetMap()->GetUnit( pGravityBombTarGUID))
+ m_creature->SummonCreature(NPC_VOIDZONE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
+ m_uiVoidZoneTimer = 60000;
+ }else m_uiVoidZoneTimer -= uiDiff;
+ }
+
+ if (!m_bPhase2 && m_creature->GetHealthPercent() < m_uiHealthPercent && !m_bIsHardMode)
+ {
+ m_uiHeart_Timer = 30000;
+ m_creature->CastStop();
+ m_uiHealthPercent = m_uiHealthPercent - 25;
+ m_bPhase2 = true;
+ DoScriptText(SAY_HEART_OPEN, m_creature);
+ DoCast(m_creature, SPELL_STUN);
+ DoScriptText(EMOTE_HEART, m_creature);
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ // timers
+ m_uiScrapbotTimer = urand(3000, 5000);
+ m_uiBoombotTimer = urand(3000, 5000);
+ m_uiPummellerTimer = 5000;
+ m_uiMaxScrapbot = urand(7, 10) * 5;
+ m_uiMaxBoombot = urand(3, 7);
+ m_uiScrapbotCount = 0;
+ m_uiBoombotCount = 0;
+ m_uiPummellerCount = 0;
+
+ if(Creature *Heart = m_creature->SummonCreature(NPC_HEART, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 900000))
+ {
+ m_uiXtHeartGUID = Heart->GetGUID();
+ // this needs fixing in DB
+ if(!m_bIsRegularMode)
+ Heart->SetMaxHealth(7199999);
+ }
+ }
+
+ if (m_bPhase2 && m_uiHeart_Timer < uiDiff)
+ {
+ DoScriptText(SAY_HEART_CLOSE, m_creature);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_creature->RemoveAurasDueToSpell(SPELL_STUN);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->AI()->AttackStart(m_creature->getVictim());
+ m_bPhase2 = false;
+ m_uiLight_Bomb_Timer = 7000;
+ m_uiGravity_Bomb_Timer = 11000;
+ m_uiTanctrum_Timer = 38000;
+ }else m_uiHeart_Timer -= uiDiff;
+
+ //adds
+ if(m_bPhase2 && !m_bIsHardMode)
+ {
+ // pummeller
+ if(m_uiPummellerTimer < uiDiff && m_uiPummellerCount < 2)
+ {
+ if(m_uiPummellerCount == 0)
+ DoScriptText(SAY_ADDS, m_creature);
+ uint8 i = urand(0, 4);
+ if (Creature* pTemp = m_creature->SummonCreature(NPC_PUMMELER, SummonLoc[i].x + urand(0, 10), SummonLoc[i].y + urand(0, 10), SummonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ pTemp->AddThreat(pTarget,0.0f);
+ pTemp->AI()->AttackStart(pTarget);
+ m_lPummelerGUIDList.push_back(pTemp->GetGUID());
+ }
+ }
+ m_uiPummellerCount += 1;
+ m_uiPummellerTimer = 4000;
+ }
+ else m_uiPummellerTimer -= uiDiff;
+
+ // boombot
+ if(m_uiBoombotTimer < uiDiff && m_uiBoombotCount < m_uiMaxBoombot)
+ {
+ uint8 i = urand(0, 4);
+ if (Creature* pTemp = m_creature->SummonCreature(NPC_BOOMBOT, SummonLoc[i].x + urand(0, 10), SummonLoc[i].y + urand(0, 10), SummonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->AddThreat(m_creature->getVictim(),1000.0f);
+ pTemp->AI()->AttackStart(m_creature->getVictim());
+ m_lBoombotsGUIDList.push_back(pTemp->GetGUID());
+ }
+ m_uiBoombotCount += 1;
+ m_uiBoombotTimer = 4000;
+ }
+ else m_uiBoombotTimer -= uiDiff;
+
+ // scrapbot
+ if(m_uiScrapbotTimer < uiDiff && m_uiScrapbotCount < m_uiMaxScrapbot)
+ {
+ uint8 i = urand(0, 4);
+ for(int j = 0; j < 5; j++)
+ {
+ if (Creature* pTemp = m_creature->SummonCreature(NPC_SCRAPBOT, SummonLoc[i].x + urand(0, 10), SummonLoc[i].y + urand(0, 10), SummonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ pTemp->GetMotionMaster()->MoveFollow(m_creature, 0, 0);
+ m_lScrapbotsGUIDList.push_back(pTemp->GetGUID());
+ m_uiScrapbotCount += 1;
+ }
+ }
+ m_uiScrapbotTimer = 3000;
+ }
+ else m_uiScrapbotTimer -= uiDiff;
+ }
+
+ if (!m_bPhase2)
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_xt002(Creature* pCreature)
+{
+ return new boss_xt002AI(pCreature);
+}
+
+void AddSC_boss_xt002()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_xt002";
+ NewScript->GetAI = GetAI_boss_xt002;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_pummeler";
+ NewScript->GetAI = &GetAI_mob_pummeler;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_boombot";
+ NewScript->GetAI = &GetAI_mob_boombot;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_xtheart";
+ NewScript->GetAI = &GetAI_mob_xtheart;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_voidzone";
+ NewScript->GetAI = &GetAI_mob_voidzone;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "mob_lifespark";
+ NewScript->GetAI = &GetAI_mob_lifespark;
+ NewScript->RegisterSelf();
+}
\ No newline at end of file
diff --git a/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp b/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp
index 00bb162..d98f73a 100644
--- a/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp
+++ b/scripts/northrend/ulduar/ulduar/boss_yogg_saron.cpp
@@ -1,78 +1,2769 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public 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_yogg_saron
-SD%Complete: 0%
-SDComment:
+SD%Complete:
+SDComment: Implement sanity, some other spells need core support. If the topaggro target is teleported into a vision, the boss resets -> needs fixing!
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
enum
{
- SAY_SARA_INTRO_1 = -1603197,
- SAY_SARA_INTRO_2 = -1603198,
- SAY_SARA_AGGRO = -1603199,
- SAY_SARA_HELP_1 = -1603200,
- SAY_SARA_HELP_2 = -1603201,
- SAY_SARA_SLAY_1 = -1603202,
- SAY_SARA_SLAY_2 = -1603203,
- SAY_WIPE_PHASE_1 = -1603204,
-
- SAY_PHASE_2_INTRO = -1603205,
- SAY_SARA_PHASE_2_INTRO_A = -1603206,
- SAY_SARA_PHASE_2_INTRO_B = -1603207,
-
- SAY_MADNESS = -1603209,
- SAY_PHASE_3 = -1603210,
- SAY_SLAY_1 = -1603211,
- SAY_SLAY_2 = -1603212,
- SAY_DEATH = -1603213,
- SAY_TO_INSANE_1 = -1603214,
- SAY_TO_INSANE_2 = -1603215,
-
- SAY_LICH_KING_1 = -1603216,
- SAY_CHAMPION_1 = -1603217,
- SAY_CHAMPION_2 = -1603218,
- SAY_LICH_KING_2 = -1603219,
- SAY_YOGG_V3_1 = -1603220,
- SAY_YOGG_V3_2 = -1603221,
-
- SAY_NELTHARION_1 = -1603222,
- SAY_YSERA = -1603223,
- SAY_NELTHARION_2 = -1603224,
- SAY_MALYGOS = -1603225,
- SAY_YOGG_V2 = -1603226,
-
- SAY_GARONA_1 = -1603227,
- SAY_GARONA_2 = -1603228,
- SAY_YOGG_V1_1 = -1603229,
- SAY_YOGG_V1_2 = -1603230,
- SAY_GARONA_3 = -1603231,
- SAY_GARONA_4 = -1603232,
- SAY_YOGG_V1_3 = -1603233,
-
- EMOTE_VISION_BLAST = -1603234,
- EMOTE_SHATTER_BLAST = -1603235,
+ //yells
+ //sara
+ SAY_INTRO1 = -1603307,
+ SAY_INTRO2 = -1603308,
+ SAY_AGGRO = -1603300,
+ SAY_HELP1 = -1603301,
+ SAY_HELP2 = -1603302,
+ SAY_SPECIAL1 = -1603305,
+ SAY_SPECIAL2 = -1603306,
+ SAY_KILL1 = -1603303,
+ SAY_KILL2 = -1603304,
+ SAY_WIPE = -1603309,
+
+ //yogg
+ SAY_PHASE2 = -1603321,
+ SAY_VISION = -1603322,
+ EMOTE_PORTALS = -1603372,
+ EMOTE_SHATTER = -1603373,
+ SAY_PHASE3 = -1603323,
+ SAY_SLAY1 = -1603324,
+ SAY_SLAY2 = -1603325,
+ SAY_DEATH = -1603326,
+ SAY_INSANITY1 = -1603327,
+ SAY_INSANITY2 = -1603328,
+
+ //visions
+ //stormwind
+ SAY_GARONA1 = -1603341,
+ SAY_GARONA2 = -1603342,
+ SAY_YOGG_V1_1 = -1603343,
+ SAY_YOGG_V1_2 = -1603344,
+ SAY_GARONA3 = -1603345,
+ SAY_GARONA4 = -1603346,
+ SAY_YOGG_V1_3 = -1603347,
+
+ //dragons
+ SAY_NELTHARION1 = -1603336,
+ SAY_YSERA = -1603337,
+ SAY_NELTHARION2 = -1603338,
+ SAY_MALYGOS = -1603339,
+ SAY_YOGG_V2 = -1603340,
+
+ //lich king
+ SAY_LICH_KING1 = -1603330,
+ SAY_CHAMPION1 = -1603331,
+ SAY_CHAMPION2 = -1603332,
+ SAY_LICH_KING2 = -1603333,
+ SAY_YOGG_V3_1 = -1603334,
+ SAY_YOGG_V3_2 = -1603335,
+
+ //keepers yells
+ SAY_HODIR_ACTIVE = -1603086,
+ SAY_FREYA_ACTIVE = -1603009,
+ SAY_THORIM_ACTIVE = -1603238,
+ SAY_MIMIRON_ACTIVE = -1603260,
+
+ //vision npc
+ //stormwind
+ NPC_GARONA = 33436,
+ NPC_KING_LLANE = 33437,
+
+ MOB_SUIT_OF_ARMOR = 33433,
+
+ //dragons
+ NPC_NELTHARION = 33523,
+ NPC_YSERA = 33495,
+ NPC_MALYGOS = 33535,
+ NPC_ALEXSTRASZA = 33536,
+ GO_DRAGON_SOUL = 194462,
+
+ MOB_RUBY_CONSORT = 33716,
+ MOB_AZURE_CONSORT = 33717,
+ MOB_BRONZE_CONSORT = 33718,
+ MOB_EMERALD_CONSORT = 33719,
+ MOB_OBSIDIAN_CONSORT = 33720,
+
+
+ //lich king
+ NPC_LICH_KING = 33441,
+ NPC_IMMOLATED_CHAMPION = 33442,
+
+ NPC_VOICE_OF_YOGG_SARON = 33280,
+ MOB_VISION_TENTACLE = 33943,
+ SPELL_GRIM_REPRISAL = 63305,
+ // npc hp: 15k on 10 man; 40k on 25 man
+ // npc no: 10
+
+ //spells
+ //phase1
+ SPELL_SARAS_FERVOR = 63138,
+ SPELL_SARAS_BLESSING = 63134,
+ SPELL_SARAS_ANGER = 63147,
+
+ MOB_GUARDIAN_OF_YOGG = 33136,
+ SPELL_DARK_VOLLEY = 63038,
+ SPELL_SHADOW_NOVA = 62714, //when dies
+ SPELL_SHADOW_NOVA_H = 65209,
+ SPELL_DOMINATE_MIND = 63713,
+
+ // clouds
+ SPELL_OMINOUS_CLOUD_VISUAL = 63084,
+ SPELL_SUMMON_GUARDIAN = 62978,
+ SPELL_SUMMON_GUARDIAN2 = 63031,
+ NPC_OMINOUS_CLOUD = 33292,
+
+ //phase2
+ SPELL_SHADOWY_BARRIER = 64775,
+ SPELL_SHADOWY_BARRIER_YOGG = 63894,
+ SPELL_SANITY = 63050,
+ SPELL_PHYCHOSIS = 65301,
+ SPELL_PHYCHOSIS_H = 63795,
+ SPELL_MALADY_OF_THE_MIND = 63830,
+ SPELL_BRAIN_LINK = 63802,
+ SPELL_BRAIN_LINK_DMG = 63803,
+ SPELL_BRAIN_LINK_NON_DMG = 63804,
+ SPELL_DEATH_RAY = 63891, //summons orb
+ SPELL_DEATH_RAY_TRIGG = 63883,
+ SPELL_DEATH_RAY_VISUAL = 63886,
+ SPELL_DEATH_RAY_VISUAL_ORI = 63893,
+ MOB_DEATH_ORB = 33882,
+
+ MODEL_SARA_VALKYR = 29182,
+ MODEL_SARA_HUMAN = 29117,
+
+ // sanity
+ SPELL_CLEAR_INSANE = 63122,
+ SPELL_INSANE = 63120,
+ SPELL_INSANE_VISUAL = 64464,
+ SPELL_INSANE_TRIGG = 64554,
+
+ SPELL_LOW_SANITY_EFFECT = 63752,
+ SPELL_SANITY_TRIGG = 63786,
+
+ // portals
+ MOB_DESCEND_INTO_MADNESS = 34072,
+ SPELL_LUNATIC_GAZE = 64167, //affects players which take the portal to madness
+ NPC_LAUGHING_SKULL = 33990,
+ SKULL_DISPLAY_ID = 25206,
+
+ // brain's chamber
+ MOB_BRAIN_OF_YOGG_SARON = 33890,
+ SPELL_SHATTERED_ILLUSION = 64173,
+ SPELL_INDUCE_MADNESS = 64059,
+ SPELL_ILLUSION_ROOM = 63988, // reduce speed
+ SPELL_ILLUSION_CANCEL = 63993,
+
+
+ // tentacules
+ MOB_CRUSHER_TENTACLE = 33966,
+ SPELL_ERUPT = 64144, //also used by the corruptor tentacle
+ SPELL_DIMINISH_POWER = 64145,
+ SPELL_FOCUSED_ANGER = 57689,
+ SPELL_FOCUSED_ANGER_TRIGG = 57688,
+ SPELL_SUMMON_CRUSHER = 64139,
+
+ MOB_CONSTRICTOR_TENTACLE = 33983,
+ SPELL_SQUEEZE = 64125,
+ SPELL_SQUEEZE_H = 64126,
+ SPELL_SUMMON_CONSTRICTOR = 64133,
+
+ MOB_CORRUPTOR_TENTACLE = 33985,
+ SPELL_APATHY = 64156,
+ SPELL_BLACK_PLAGUE = 64153,
+ SPELL_CURSE_OF_DOOM = 64157,
+ SPELL_DRAINING_POISON = 64152,
+
+ // phase 3
+ SPELL_LUNATIC_GAZE_YOGG = 64163,
+ SPELL_SHADOW_BEACON = 64465,
+ SPELL_EMPOWERING_SHADOWS = 64468,
+ SPELL_EMPOWERING_SHADOWS_H = 64486,
+ SPELL_DEAFENING_ROAR = 64189, //only cast on 25 player with 0-3 keepes active
+
+ MOB_IMMORTAL_GUARDIAN = 33988,
+ SPELL_EMPOWERED = 65294, //starts with 9 stacks and loses 1 stak at 10% hp
+ SPELL_EMPOWERED_AURA = 64161,
+
+ SPELL_BERSERK = 64166, //extinguish all life
+
+ // keepers
+ // freya
+ SPELL_RESILIENCE_OF_NATURE = 62670,
+ MOB_SANITY_WELL = 33991,
+ SPELL_SANITY_WELL = 64169, // regen sanity
+ SPELL_SANITY_WELL_VISUAL = 63288,
+ SPELL_SUMMON_SANITY_WELL = 64170,
+
+ // hodir
+ SPELL_FORTITUDE_OF_FROST = 62650,
+ SPELL_HODIRS_PROTECTIVE_GAZE= 64174, // saves players from killing blows ~25secs cd
+
+ // thorim
+ SPELL_SPEED_OF_INVENTION = 62671,
+ SPELL_DESTABILIZATION_MATRIX= 65210, // cast in phase 2 on the tentacules
+
+ // mimiron
+ SPELL_FURY_OF_THE_STORM = 62702,
+ SPELL_TITANIC_STORM = 64171, // used in phase 3 to kill guardians
+ SPELL_TITANIC_STORM_DMG = 64172,
+};
+
+enum phases
+{
+ // yogg phases
+ PHASE_IDLE = 0,
+ PHASE_SARA = 1,
+ PHASE_TENTACLES = 2,
+ PHASE_OLD_GOD = 3,
+ // vision phases
+ PHASE_VISION_STORMWIND = 1,
+ PHASE_VISION_WYRMREST = 2,
+ PHASE_VISION_ICECROWN = 3,
+ PHASE_VISION_RETURN = 4, // used to set the portals to return to main chamber = idle
+};
+
+enum achievs
+{
+ ACHIEV_ALONE = 3159,
+ ACHIEV_ALONE_H = 3164,
+ ACHIEV_ONE_LIGHT = 3158,
+ ACHIEV_ONE_LIGHT_H = 3163,
+ ACHIEV_TWO_LIGHTS = 3141,
+ ACHIEV_TWO_LIGHTS_H = 3162,
+ ACHIEV_THREE_LIGHTS = 3157,
+ ACHIEV_THREE_LIGHTS_H = 3161,
+ ACHIEV_NOT_GETTING_OLDER = 3012,
+ ACHIEV_NOT_GETTING_OLDER_H = 3013,
+};
+
+//Positional defines
+struct LocationsXY
+{
+ float x, y, z, o;
+ uint32 id;
+};
+static LocationsXY SummonLoc[]=
+{
+ {1951.097412f,-25.42042f, 326.162598f},
+ {1970.677490f,-0.211162f, 325.478638f},
+ {2001.049805f,-4.201718f, 325.751831f},
+ {2009.346924f,-26.001806f,325.603271f},
+ {1998.081665f,-46.625187f,325.551605f},
+ {1962.782715f,-51.363148f,325.458160f},
+ {1988.847778f,-71.143738f,328.647614f},
+ {2024.004150f,-40.749989f,327.876617f},
+ {2018.806885f,-3.451158f,327.593933f},
+ {1978.651001f,18.373478f,328.420532f},
+ {1940.641602f,1.761525f, 327.921661f},
+ {1941.203735f,-52.999535f,327.246948f},
+};
+
+static LocationsXY SanityWellLoc[]=
+{
+ {1901.237915f, -46.305782f, 331.960754f},
+ {1900.753052f, -2.259287f, 332.061249f},
+ {1991.020996f, 43.943943f, 331.746979f},
+ {2044.219482f, -21.878244f, 329.776855f},
+ {1986.226807f, -95.087761f, 330.253998f},
+};
+
+static LocationsXY KeepersLoc[]=
+{
+ {2036.859863f, -74.113884f, 338.415222f, 2.488684f}, //thorim
+ {1938.328247f, -90.742043f, 338.459442f, 0.992500f}, //hodir
+ {2036.107056f, 25.702380f, 338.415192f, 4.019527f}, // freya
+ {1939.021240f, 43.221031f, 338.460663f, 5.214388f}, // mimiron
+};
+
+static LocationsXY TeleportLoc[]=
+{
+ {1941.587402f, 43.526680f, 239.666336f}, // stormwind
+ {2055.460938f, -25.619570f, 239.721176f}, // dragons
+ {1941.131226f, -94.654694f, 239.989639f}, // icecrown
+ {1951.097f, -25.420f, 326.162f}, // yogg
+};
+
+static LocationsXY YoggPortalLoc[]=
+{
+ {1959.765137f, -20.697853f, 325.352966f},
+ {1973.407837f, -6.656567f, 324.889526f},
+ {1990.271851f, -47.992981f, 324.959991f},
+ {1978.893433f, -49.858326f, 324.777618f},
+ {1967.471924f, -46.298458f, 324.840759f},
+ {1959.654297f, -39.954502f, 324.997253f},
+ {1956.343872f, -25.642859f, 325.188354f},
+ {1985.072021f, -2.515451f, 325.20010f},
+ {1993.541626f, -10.527716f, 324.889587f},
+ {2003.674316f, -23.050785f, 325.384064f},
+};
+
+static LocationsXY MadnessPortalLoc[]=
+{
+ {2001.015f, 4.185f, 242.747f},
+ {1999.690f, -54.931f, 242.418f},
+ {1946.898f, -25.769f, 242.169f},
+};
+// vison pos
+//Positional defines
+struct VisionLocXY
+{
+ float x, y, z, o;
+ uint32 id;
+};
+// dragons
+const float PosYsera[4] = {2114.504f, -16.118f, 242.646f, 3.91f};
+const float PosMalygos[4] = {2113.388f, -34.381f, 242.646f, 2.26f};
+const float PosNeltharion[4] = {2117.588f, -25.318f, 242.646f, 3.15f};
+const float PosAlexstrasza[4] = {2091.679f, -25.289f, 242.646f, 6.282f};
+const float PosVoiceDragon[3] = {2104.555f, -25.635f, 242.646f};
+const float DisplayDragons[10] = {2718, 2718, 2717, 2717, 12869, 12869, 1687, 1687, 2719, 2719};
+
+static VisionLocXY DragonLoc[]=
+{
+ {2071.951660f, 1.881840f, 239.794922f, 5.590341f},
+ {2093.910156f, 19.939915f, 239.766830f, 4.962034f},
+ {2114.737061f, 20.441664f, 239.757309f, 4.259104f},
+ {2136.709473f, 4.874056f, 239.718658f, 3.889961f},
+ {2147.894287f, -12.416141f, 239.757980f, 3.210588f},
+ {2148.479004f, -37.655373f, 239.720169f, 3.033874f},
+ {2136.296631f, -56.800838f, 239.754654f, 2.287745f},
+ {2114.370117f, -68.110947f, 239.721100f, 1.789017f},
+ {2093.946289f, -67.447899f, 239.720734f, 1.305995f},
+ {2071.001709f, -54.414040f, 239.719345f, 0.528450f},
+};
+
+static VisionLocXY SkullDragonLoc[]=
+{
+ {2075.898193f, -5.637041f, 239.787735f},
+ {2137.949219f, -26.778023f, 239.717712f},
+ {2084.131836f, -52.716999f, 239.720703f},
+};
+
+// stormwind
+const float PosGarona[4] = {1935.398926f, 54.017738f, 240.376465f, 2.008213f};
+const float PosKing[4] = {1930.465670f, 62.674065f, 242.376373f, 5.196925f};
+const float PosVoiceStormwind[3] = {1927.326f, 68.120f, 242.376f};
+
+static VisionLocXY KeepLoc[]=
+{
+ {1930.854370f, 39.910034f, 239.666443f, 1.641476f},
+ {1909.771240f, 45.685230f, 239.666443f, 0.962106f},
+ {1898.966309f, 64.644989f, 239.666443f, 0.157073f},
+ {1904.273926f, 85.369118f, 239.666443f, 5.662714f},
+ {1923.474487f, 96.419815f, 239.666443f, 4.826267f},
+ {1944.612061f, 91.062439f, 239.666443f, 4.076213f},
+ {1955.231079f, 71.870926f, 239.666443f, 3.255475f},
+ {1949.701416f, 51.040390f, 239.666443f, 2.481856f},
+};
+
+static VisionLocXY SkullKeepLoc[]=
+{
+ {1908.942261f, 58.934380f, 239.666382f},
+ {1916.902954f, 86.755638f, 239.66662f},
+ {1944.789307f, 78.614716f, 239.666382f},
+};
+
+// lich king
+const float PosLichKing[4] = {1910.499268f,-147.709961f,239.989639f, 0.943203f};
+const float PosChampion[4] = {1915.371094f,-139.934219f,239.989639f, 4.159409f};
+const float PosVoiceIcecrown[3] = {1914.332f, -139.317f, 239.989f};
+
+static VisionLocXY IcecrownLoc[]=
+{
+ {1952.521606f, -137.052094f, 239.989716f, 2.513270f},
+ {1946.220337f, -130.236008f, 239.989716f, 5.387829f},
+ {1942.029541f, -136.833328f, 239.989716f, 0.192416f},
+ {1896.965210f, -104.922951f, 239.989716f, 5.647007f},
+ {1904.356079f, -113.879349f, 239.989716f, 2.163766f},
+ {1907.664795f, -106.186508f, 239.989716f, 2.976653f},
+ {1919.831421f, -131.184784f, 239.989716f, 4.213656f},
+ {1919.120728f, -145.960281f, 239.989716f, 1.908511f},
+ {1907.462891f, -139.149307f, 239.989716f, 0.176708f},
+};
+
+static VisionLocXY SkullIcecrownLoc[]=
+{
+ {1962.658569f, -111.356392f, 239.98986f},
+ {1940.515625f, -152.933945f, 239.989868f},
+ {1889.130371f, -122.932549f, 239.98986f},
+ {1908.828003f, -88.593613f, 239.98986f},
+};
+
+// location of the minds eye:
+// X: 1981.422974 Y: -22.442831 Z: 236.104813
+
+// transfer from brain
+// X: 1951.097412 Y: -25.420420 Z: 326.162598 Orientation: 0.131792
+// brain room portal loc:
+// sara -> type_flags = 108; original
+
+// SanityAura, needs core support, not used here
+class MANGOS_DLL_DECL SanityAura : public Aura
+{
+public:
+ SanityAura(const SpellEntry *spell, SpellEffectIndex eff, int32 *bp, SpellAuraHolder *holder, Unit *target, Unit *caster) : Aura(spell, eff, bp, holder, target, caster, NULL)
+ {}
+};
+
+// Yogg Saron, main event controller
+struct MANGOS_DLL_DECL boss_yogg_saronAI : public ScriptedAI
+{
+ boss_yogg_saronAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiBerserkTimer;
+ uint32 m_uiSanityTimer;
+ uint32 m_uiKeepersActive;
+
+ uint32 m_uiLunaticGazaTimer;
+ uint32 m_uiShadowBeaconTimer;
+ uint32 m_uiEmpoweringShadowsTimer;
+ uint32 m_uiSummonTimer;
+ uint32 m_uiDeafeningRoarTimer;
+ bool m_bIsShatter;
+
+ uint32 m_uiAchievTimer;
+
+ std::list lClouds;
+
+ void Reset()
+ {
+ m_uiSanityTimer = 10000;
+ m_uiKeepersActive = 0;
+
+ // phase 3
+ m_uiLunaticGazaTimer = 20000;
+ m_uiShadowBeaconTimer = 15000;
+ m_uiEmpoweringShadowsTimer = 60000;
+ m_uiSummonTimer = 40000;
+ m_uiDeafeningRoarTimer = 30000;
+ m_uiAchievTimer = 0;
+ m_bIsShatter = false;
+ m_uiBerserkTimer = 900000; // 15 min
+
+ m_creature->SetVisibility(VISIBILITY_OFF);
+
+ if(m_creature->HasAura(SPELL_SHADOWY_BARRIER_YOGG))
+ m_creature->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER_YOGG);
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_IDLE);
+ m_pInstance->SetData(TYPE_VISION_PHASE, PHASE_VISION_RETURN);
+ }
+
+ // respawn clouds
+ GetCreatureListWithEntryInGrid(lClouds, m_creature, NPC_OMINOUS_CLOUD, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lClouds.empty())
+ {
+ for(std::list::iterator iter = lClouds.begin(); iter != lClouds.end(); ++iter)
+ {
+ if ((*iter) && !(*iter)->isAlive())
+ (*iter)->Respawn();
+ }
+ }
+ }
+
+ void Aggro(Unit *who)
+ {
+ m_creature->SetInCombatWithZone();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ //StartSanity();
+
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_YOGGSARON, IN_PROGRESS);
+ m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_SARA);
+ // summon thorim
+ if(m_pInstance->GetData(TYPE_KEEPER_THORIM) == DONE)
+ {
+ m_creature->SummonCreature(KEEPER_THORIM, KeepersLoc[0].x, KeepersLoc[0].y, KeepersLoc[0].z, KeepersLoc[0].o, TEMPSUMMON_MANUAL_DESPAWN, 0);
+ m_uiKeepersActive += 1;
+ }
+ // summon hodir
+ if(m_pInstance->GetData(TYPE_KEEPER_HODIR) == DONE)
+ {
+ m_creature->SummonCreature(KEEPER_HODIR, KeepersLoc[1].x, KeepersLoc[1].y, KeepersLoc[1].z, KeepersLoc[1].o, TEMPSUMMON_MANUAL_DESPAWN, 0);
+ m_uiKeepersActive += 1;
+ }
+ // summon freya
+ if(m_pInstance->GetData(TYPE_KEEPER_FREYA) == DONE)
+ {
+ m_creature->SummonCreature(KEEPER_FREYA, KeepersLoc[2].x, KeepersLoc[2].y, KeepersLoc[2].z, KeepersLoc[2].o, TEMPSUMMON_MANUAL_DESPAWN, 0);
+ m_uiKeepersActive += 1;
+ }
+ // summon mimiron
+ if(m_pInstance->GetData(TYPE_KEEPER_MIMIRON) == DONE)
+ {
+ m_creature->SummonCreature(KEEPER_MIMIRON, KeepersLoc[3].x, KeepersLoc[3].y, KeepersLoc[3].z, KeepersLoc[3].o, TEMPSUMMON_MANUAL_DESPAWN, 0);
+ m_uiKeepersActive += 1;
+ }
+
+ if(Creature* pSara = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SARA)))
+ DoScriptText(SAY_AGGRO, pSara);
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_YOGGSARON, NOT_STARTED);
+
+ if(Creature* pSara = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(NPC_SARA)))
+ {
+ if(!pSara->isAlive())
+ pSara->Respawn();
+ else
+ pSara->AI()->EnterEvadeMode();
+ }
+
+ if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN)))
+ {
+ if(!pYoggBrain->isAlive())
+ pYoggBrain->Respawn();
+ else
+ pYoggBrain->AI()->EnterEvadeMode();
+ }
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_SLAY1, m_creature);
+ else
+ DoScriptText(SAY_SLAY2, m_creature);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_YOGGSARON, DONE);
+ m_pInstance->SetData(TYPE_YOGGSARON_HARD, 0);
+
+ // hacky way to complete achievements; use only if you have this function
+ if(m_uiKeepersActive == 0)
+ {
+ m_pInstance->SetData(TYPE_YOGGSARON_HARD, 4);
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_ALONE : ACHIEV_ALONE_H);
+ }
+ else if (m_uiKeepersActive == 1)
+ {
+ m_pInstance->SetData(TYPE_YOGGSARON_HARD, 3);
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_ONE_LIGHT : ACHIEV_ONE_LIGHT_H);
+ }
+ else if (m_uiKeepersActive == 2)
+ {
+ m_pInstance->SetData(TYPE_YOGGSARON_HARD, 2);
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_TWO_LIGHTS : ACHIEV_TWO_LIGHTS_H);
+ }
+ else if (m_uiKeepersActive == 3)
+ {
+ m_pInstance->SetData(TYPE_YOGGSARON_HARD, 1);
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_THREE_LIGHTS : ACHIEV_THREE_LIGHTS_H);
+ }
+
+ // under 7 min
+ if(m_uiAchievTimer < 420000)
+ m_pInstance->DoCompleteAchievement(m_bIsRegularMode ? ACHIEV_NOT_GETTING_OLDER : ACHIEV_NOT_GETTING_OLDER_H);
+
+ }
+
+ if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA)))
+ {
+ if(pSara->isAlive())
+ pSara->DealDamage(pSara, pSara->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN)))
+ {
+ if(pYoggBrain->isAlive())
+ pYoggBrain->DealDamage(pYoggBrain, pYoggBrain->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+
+ void StartSecondPhase()
+ {
+ m_creature->SetVisibility(VISIBILITY_ON);
+ DoCast(m_creature, SPELL_SHADOWY_BARRIER_YOGG);
+ StartSanity();
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ GetCreatureListWithEntryInGrid(lClouds, m_creature, NPC_OMINOUS_CLOUD, DEFAULT_VISIBILITY_INSTANCE);
+ if (!lClouds.empty())
+ {
+ for(std::list::iterator iter = lClouds.begin(); iter != lClouds.end(); ++iter)
+ {
+ if ((*iter) && (*iter)->isAlive())
+ (*iter)->ForcedDespawn();
+ }
+ }
+
+ m_uiSummonTimer = urand(3000, 7000);
+ }
+
+ void StartThirdPhase()
+ {
+ DoScriptText(SAY_PHASE3, m_creature);
+ m_creature->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER_YOGG);
+ m_creature->SetHealth(m_creature->GetMaxHealth() * 0.3);
+
+ m_uiSummonTimer = urand(15000, 20000);
+
+ if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA)))
+ pSara->ForcedDespawn();
+
+ if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN)))
+ pYoggBrain->DealDamage(pYoggBrain, pYoggBrain->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ // hacky way of doing sanity before the recent aura changes
+ void StartSanity()
+ {
+ Map *map = m_creature->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ SpellEntry* spell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_SANITY);
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive())
+ {
+ /* if(i->getSource()->HasAura(SPELL_SANITY, EFFECT_INDEX_0))
+ i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0)->SetStackAmount(100);
+ else
+ {
+ if(i->getSource()->AddAura(new SanityAura(spell, EFFECT_INDEX_0, NULL, i->getSource(), m_creature)))
+ i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0)->SetStackAmount(100);
+ }*/
+ }
+ }
+ }
+ }
+
+ void DoCastSanity()
+ {
+ uint8 m_uiStacks;
+ Map *map = m_creature->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive())
+ {
+ // reduce sanity
+ if(i->getSource()->HasAura(SPELL_SANITY, EFFECT_INDEX_0))
+ {
+ if(Aura *aura = i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0))
+ {
+ m_uiStacks = aura->GetStackAmount();
+ if(m_uiStacks == 100)
+ DoCast(i->getSource(), SPELL_INSANE);
+ /*if(m_uiStacks > 1)
+ i->getSource()->GetAura(SPELL_SANITY, EFFECT_INDEX_0)->SetStackAmount(stack - 1);
+ else
+ {
+ i->getSource()->RemoveAurasDueToSpell(SPELL_SANITY);
+ DoCast(i->getSource(), SPELL_INSANE);
+ }*/
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Creature* SelectRandomGuardian(float fRange)
+ {
+ std::list lGuardiansList;
+ GetCreatureListWithEntryInGrid(lGuardiansList, m_creature, MOB_IMMORTAL_GUARDIAN, fRange);
+
+ //This should not appear!
+ if (lGuardiansList.empty()){
+ m_uiEmpoweringShadowsTimer = 30000;
+ return NULL;
+ }
+
+ std::list::iterator iter = lGuardiansList.begin();
+ advance(iter, urand(0, lGuardiansList.size()-1));
+
+ return *iter;
+ }
+
+ void SummonTentacles()
+ {
+ float homeZ = 0;
+ float creatureDist = 0;
+ // set tentacle entry
+ uint32 m_uiTentacles[] = {MOB_CONSTRICTOR_TENTACLE, MOB_CORRUPTOR_TENTACLE, MOB_CRUSHER_TENTACLE};
+ uint32 m_uiEntry = urand(0, 2);
+ if(Creature* pTemp = GetClosestCreatureWithEntry(m_creature, MOB_CRUSHER_TENTACLE, 100.0f))
+ {
+ if(pTemp->isAlive())
+ m_uiEntry = urand(0, 1);
+ }
+ uint32 m_uiTentacleEntry = m_uiTentacles[m_uiEntry];
+
+ // set distance
+ // Z factor needs some fixing, in some cases it should be smaller
+ switch(urand(0, 1))
+ {
+ case 0:
+ creatureDist = urand(20, 30);
+ homeZ = 326 + creatureDist * 0.05f;
+ break;
+ case 1:
+ creatureDist = urand(30, 45);
+ homeZ = 328 + creatureDist * 0.05f;
+ break;
+ }
+
+ // set coordonates
+ float angle = (float) rand()*360/RAND_MAX + 1;
+ float homeX = m_creature->GetPositionX() + creatureDist*cos(angle*(M_PI/180));
+ float homeY = m_creature->GetPositionY() + creatureDist*sin(angle*(M_PI/180));
+ // summon tentacle
+ if(Creature *pTemp = m_creature->SummonCreature(m_uiTentacleEntry, homeX, homeY, homeZ, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
+ pTemp->SetInCombatWithZone();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // achiev timer
+ m_uiAchievTimer += uiDiff;
+
+ switch(m_pInstance->GetData(TYPE_YOGG_PHASE))
+ {
+ case PHASE_SARA:
+ // Friendly Sara phase: see script below
+ break;
+ case PHASE_TENTACLES:
+ {
+ if (m_uiSanityTimer < uiDiff)
+ {
+ //DoCastSanity();
+ //DoCast(m_creature, SPELL_SANITY);
+ m_uiSanityTimer = 20000;
+ }
+ else m_uiSanityTimer -= uiDiff;
+
+ // summon tentacles
+ if (m_uiSummonTimer < uiDiff && !m_bIsShatter)
+ {
+ SummonTentacles();
+ m_uiSummonTimer = urand(10000, 15000);
+ }
+ else m_uiSummonTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_OLD_GOD:
+ {
+ if (m_uiSummonTimer < uiDiff)
+ {
+ if(Creature *pTemp = m_creature->SummonCreature(MOB_IMMORTAL_GUARDIAN, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ pTemp->SetInCombatWithZone();
+ m_uiSummonTimer = 30000;
+ }
+ else m_uiSummonTimer -= uiDiff;
+
+ if (m_uiLunaticGazaTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_LUNATIC_GAZE_YOGG);
+ m_uiLunaticGazaTimer = urand(10000, 13000);
+ }
+ else m_uiLunaticGazaTimer -= uiDiff;
+
+ if (m_uiEmpoweringShadowsTimer < uiDiff)
+ {
+ if (Creature* pGuardian = SelectRandomGuardian(80.0f))
+ DoCast(pGuardian, SPELL_SHADOW_BEACON);
+ m_uiEmpoweringShadowsTimer = 45000;
+ }
+ else m_uiEmpoweringShadowsTimer -= uiDiff;
+
+ if (m_uiDeafeningRoarTimer < uiDiff && !m_bIsRegularMode && m_uiKeepersActive < 4)
+ {
+ DoCast(m_creature, SPELL_DEAFENING_ROAR);
+ m_uiDeafeningRoarTimer = 30000;
+ }
+ else m_uiDeafeningRoarTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ break;
+ }
+ }
+
+ // extinguish all life
+ if (m_uiBerserkTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_BERSERK);
+ m_uiBerserkTimer = 10000;
+ }
+ else m_uiBerserkTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL mob_madness_portalAI : public ScriptedAI
+{
+ mob_madness_portalAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint8 m_uiDestination;
+ uint32 m_uiCheckTimer;
+ bool m_bHasTeleported;
+
+ void Reset()
+ {
+ m_uiCheckTimer = 500;
+ m_bHasTeleported = false;
+ m_creature->SetRespawnDelay(DAY);
+ if(m_pInstance)
+ m_uiDestination = m_pInstance->GetData(TYPE_VISION_PHASE) - 1;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_creature->GetPositionZ() < 245.0f)
+ m_uiDestination = 3;
+
+ // hacky way. This should be done by a spell
+ // this uses the Type_vision_phase in order to set vision destination
+ if(m_uiCheckTimer < uiDiff && !m_bHasTeleported)
+ {
+ Map *map = m_creature->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) < 2)
+ {
+ i->getSource()->TeleportTo(i->getSource()->GetMapId(), TeleportLoc[m_uiDestination].x, TeleportLoc[m_uiDestination].y, TeleportLoc[m_uiDestination].z, i->getSource()->GetOrientation());
+ if(m_uiDestination < 3)
+ {
+ i->getSource()->CastSpell(i->getSource(), SPELL_ILLUSION_ROOM, false);
+ m_creature->ForcedDespawn();
+ }
+ else
+ i->getSource()->RemoveAurasDueToSpell(SPELL_ILLUSION_ROOM);
+ }
+ }
+ }
+ m_uiCheckTimer = 500;
+ }else m_uiCheckTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL boss_brain_of_yogg_saronAI : public ScriptedAI
+{
+ boss_brain_of_yogg_saronAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiVisionPhase;
+ uint32 m_uiSpeechTimer;
+ uint32 m_uiMadnessTimer;
+ uint32 m_uiTentacleCheckTimer;
+
+ bool m_bIsPhaseFinished;
+ bool m_bIsVisionFinished;
+ bool m_bHasShattered;
+
+ uint64 m_uiLichKingGUID;
+ uint64 m_uiChampionGUID;
+ uint64 m_uiGaronaGUID;
+ uint64 m_uiKingLlaneGUID;
+ uint64 m_uiNeltharionGUID;
+ uint64 m_uiMalygosGUID;
+ uint64 m_uiYseraGUID;
+ uint64 m_uiVoiceOfYoggGUID;
+
+ void Reset()
+ {
+ m_bIsPhaseFinished = false;
+ m_bIsVisionFinished = false;
+ m_bHasShattered = false;
+ m_uiLichKingGUID = 0;
+ m_uiChampionGUID = 0;
+ m_uiGaronaGUID = 0;
+ m_uiKingLlaneGUID = 0;
+ m_uiNeltharionGUID = 0;
+ m_uiMalygosGUID = 0;
+ m_uiYseraGUID = 0;
+ m_uiVoiceOfYoggGUID = 0;
+
+ m_uiVisionPhase = 0;
+ m_uiSpeechTimer = 1000;
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_YOGG_BRAIN, NOT_STARTED);
+
+ // close doors on reset
+ if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR1, 100.0f))
+ pVisionDoor->SetGoState(GO_STATE_READY);
+ if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR2, 100.0f))
+ pVisionDoor->SetGoState(GO_STATE_READY);
+ if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR3, 100.0f))
+ pVisionDoor->SetGoState(GO_STATE_READY);
+ }
+
+ // for debug
+ void Aggro(Unit *who)
+ {
+ // For vision debug only
+ //StartVisions();
+ //m_pInstance->SetData(TYPE_VISION_PHASE, PHASE_VISION_STORMWIND);
+ //m_creature->GetMotionMaster()->MoveIdle();
+ //m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), 255.011f, 0.0f);
+ //m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), 255.011f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(uiDamage > 0 && !m_bHasShattered)
+ {
+ if (Creature* pYogg = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ ((boss_yogg_saronAI*)pYogg->AI())->m_bIsShatter = true;
+ // spell bugged, need core fix. It should be cast on tentacles, not on players!
+ //pYogg->CastSpell(pYogg, SPELL_SHATTERED_ILLUSION, false);
+ }
+ m_bHasShattered = true;
+ }
+ }
+
+ void SummonPortals()
+ {
+ for(uint8 i = 0; i < 3; i++)
+ m_creature->SummonCreature(MOB_DESCEND_INTO_MADNESS, MadnessPortalLoc[i].x, MadnessPortalLoc[i].y, MadnessPortalLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
+ }
+
+ void StartVisions()
+ {
+ DoCast(m_creature, SPELL_INDUCE_MADNESS);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_uiVisionPhase = 0;
+ m_uiSpeechTimer = 1000;
+ m_uiTentacleCheckTimer = 1000;
+ m_uiMadnessTimer = 60000;
+ m_bIsVisionFinished = false;
+ m_bHasShattered = false;
+ }
+
+ // check if all the tentacles are dead
+ bool IsThereAnyAdd(WorldObject *pSource)
+ {
+ if(GetClosestCreatureWithEntry(pSource, MOB_VISION_TENTACLE, 80.0f))
+ return true;
+
+ if(m_pInstance)
+ {
+ // open doors
+ switch(m_pInstance->GetData(TYPE_VISION_PHASE))
+ {
+ case PHASE_VISION_STORMWIND:
+ if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR3, 100.0f))
+ pVisionDoor->SetGoState(GO_STATE_ACTIVE);
+ break;
+ case PHASE_VISION_WYRMREST:
+ if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR1, 100.0f))
+ pVisionDoor->SetGoState(GO_STATE_ACTIVE);
+ break;
+ case PHASE_VISION_ICECROWN:
+ if(GameObject* pVisionDoor = GetClosestGameObjectWithEntry(m_creature, GO_BRAIN_DOOR2, 100.0f))
+ pVisionDoor->SetGoState(GO_STATE_ACTIVE);
+ break;
+ }
+ }
+ return false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ switch(m_pInstance->GetData(TYPE_VISION_PHASE))
+ {
+ case PHASE_VISION_STORMWIND:
+ {
+ if(m_uiSpeechTimer < uiDiff)
+ {
+ switch(m_uiVisionPhase)
+ {
+ case 0:
+ if(Creature* Garona = m_creature->SummonCreature(NPC_GARONA, PosGarona[0], PosGarona[1], PosGarona[2], PosGarona[3], TEMPSUMMON_TIMED_DESPAWN, 60000))
+ m_uiGaronaGUID = Garona->GetGUID();
+ if(Creature* KingLlane = m_creature->SummonCreature(NPC_KING_LLANE, PosKing[0], PosKing[1], PosKing[2], PosKing[3], TEMPSUMMON_TIMED_DESPAWN, 60000))
+ m_uiKingLlaneGUID = KingLlane->GetGUID();
+ if(Creature* VoiceOfYogg = m_creature->SummonCreature(NPC_VOICE_OF_YOGG_SARON, PosVoiceStormwind[0], PosVoiceStormwind[1], PosVoiceStormwind[2], 0, TEMPSUMMON_TIMED_DESPAWN, 60000))
+ {
+ m_uiVoiceOfYoggGUID = VoiceOfYogg->GetGUID();
+ VoiceOfYogg->SetDisplayId(11686); // make invisible
+ }
+ for(uint8 i = 0; i < 8; i++)
+ {
+ if(Creature *pTemp = m_creature->SummonCreature(MOB_VISION_TENTACLE, KeepLoc[i].x, KeepLoc[i].y, KeepLoc[i].z, KeepLoc[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 80000))
+ {
+ pTemp->SetDisplayId(28621);
+ pTemp->SetMaxHealth(m_bIsRegularMode ? 15000 : 40000);
+ pTemp->setFaction(7);
+ pTemp->CastSpell(pTemp, SPELL_GRIM_REPRISAL, false);
+ }
+ }
+ for(uint8 i = 0; i < 3; i++)
+ m_creature->SummonCreature(NPC_LAUGHING_SKULL, SkullKeepLoc[i].x, SkullKeepLoc[i].y, SkullKeepLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 1000;
+ break;
+ case 1:
+ if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID))
+ DoScriptText(SAY_GARONA1, Garona);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 12000;
+ break;
+ case 2:
+ if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID))
+ DoScriptText(SAY_GARONA2, Garona);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 12000;
+ break;
+ case 3:
+ if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID))
+ DoScriptText(SAY_YOGG_V1_1, VoiceOfYogg);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 4000;
+ break;
+ case 4:
+ if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID))
+ DoScriptText(SAY_YOGG_V1_2, VoiceOfYogg);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 4000;
+ break;
+ case 5:
+ if(Creature* KingLlane = m_pInstance->instance->GetCreature(m_uiKingLlaneGUID))
+ DoScriptText(SAY_GARONA3, KingLlane);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 6000;
+ break;
+ case 6:
+ if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID))
+ Garona->GetMotionMaster()->MovePoint(0, 1931.348f, 61.033f, 241.709f);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 6000;
+ break;
+ case 7:
+ if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID))
+ {
+ DoScriptText(SAY_GARONA4, Garona);
+ if(Creature* KingLlane = m_pInstance->instance->GetCreature(m_uiKingLlaneGUID))
+ {
+ KingLlane->SetStandState(UNIT_STAND_STATE_DEAD);
+ KingLlane->SetHealth(0);
+ Garona->Attack(KingLlane, true);
+ }
+ }
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 6000;
+ break;
+ case 8:
+ if(Creature* Garona = m_pInstance->instance->GetCreature(m_uiGaronaGUID))
+ Garona->AttackStop();
+ if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID))
+ DoScriptText(SAY_YOGG_V1_3, VoiceOfYogg);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 8000;
+ break;
+ default:
+ m_uiSpeechTimer = 100000;
+ }
+ }
+ else m_uiSpeechTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_VISION_WYRMREST:
+ {
+ if(m_uiSpeechTimer < uiDiff)
+ {
+ switch(m_uiVisionPhase)
+ {
+ case 0:
+ m_creature->SummonCreature(NPC_ALEXSTRASZA, PosAlexstrasza[0], PosAlexstrasza[1], PosAlexstrasza[2], PosAlexstrasza[3], TEMPSUMMON_TIMED_DESPAWN, 60000);
+ if(Creature* Neltharion = m_creature->SummonCreature(NPC_NELTHARION, PosNeltharion[0], PosNeltharion[1], PosNeltharion[2], PosNeltharion[3], TEMPSUMMON_TIMED_DESPAWN, 60000))
+ m_uiNeltharionGUID = Neltharion->GetGUID();
+ if(Creature* Malygos = m_creature->SummonCreature(NPC_MALYGOS, PosMalygos[0], PosMalygos[1], PosMalygos[2], PosMalygos[3], TEMPSUMMON_TIMED_DESPAWN, 60000))
+ m_uiMalygosGUID = Malygos->GetGUID();
+ if(Creature* Ysera = m_creature->SummonCreature(NPC_YSERA, PosYsera[0], PosYsera[1], PosYsera[2], PosYsera[3], TEMPSUMMON_TIMED_DESPAWN, 60000))
+ m_uiYseraGUID = Ysera->GetGUID();
+ if(Creature* VoiceOfYogg = m_creature->SummonCreature(NPC_VOICE_OF_YOGG_SARON, PosVoiceDragon[0], PosVoiceDragon[1], PosVoiceDragon[2], 0, TEMPSUMMON_TIMED_DESPAWN, 60000))
+ {
+ m_uiVoiceOfYoggGUID = VoiceOfYogg->GetGUID();
+ VoiceOfYogg->SetVisibility(VISIBILITY_OFF);
+ }
+ for(uint8 i = 0; i < 10; i++)
+ {
+ if(Creature *pTemp = m_creature->SummonCreature(MOB_VISION_TENTACLE, DragonLoc[i].x, DragonLoc[i].y, DragonLoc[i].z, DragonLoc[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 80000))
+ {
+ pTemp->SetDisplayId(DisplayDragons[i]);
+ pTemp->SetMaxHealth(m_bIsRegularMode ? 15000 : 40000);
+ pTemp->setFaction(7);
+ pTemp->CastSpell(pTemp, SPELL_GRIM_REPRISAL, false);
+ }
+ }
+ for(uint8 i = 0; i < 3; i++)
+ m_creature->SummonCreature(NPC_LAUGHING_SKULL, SkullDragonLoc[i].x, SkullDragonLoc[i].y, SkullDragonLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 1000;
+ break;
+ case 1:
+ if(Creature* Neltharion = m_pInstance->instance->GetCreature(m_uiNeltharionGUID))
+ DoScriptText(SAY_NELTHARION1, Neltharion);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 10000;
+ break;
+ case 2:
+ if(Creature* Ysera = m_pInstance->instance->GetCreature(m_uiYseraGUID))
+ DoScriptText(SAY_YSERA, Ysera);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 7000;
+ break;
+ case 3:
+ if(Creature* Neltharion = m_pInstance->instance->GetCreature(m_uiNeltharionGUID))
+ DoScriptText(SAY_NELTHARION2, Neltharion);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 6000;
+ break;
+ case 4:
+ if(Creature* Malygos = m_pInstance->instance->GetCreature(m_uiMalygosGUID))
+ DoScriptText(SAY_MALYGOS, Malygos);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 9000;
+ break;
+ case 5:
+ if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID))
+ DoScriptText(SAY_YOGG_V2, VoiceOfYogg);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 10000;
+ break;
+ default:
+ m_uiSpeechTimer = 100000;
+ }
+ }else m_uiSpeechTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_VISION_ICECROWN:
+ {
+ if(m_uiSpeechTimer < uiDiff)
+ {
+ switch(m_uiVisionPhase)
+ {
+ case 0:
+ if(Creature* LichKing = m_creature->SummonCreature(NPC_LICH_KING, PosLichKing[0], PosLichKing[1], PosLichKing[2], PosLichKing[3], TEMPSUMMON_TIMED_DESPAWN, 60000))
+ m_uiLichKingGUID = LichKing->GetGUID();
+ if(Creature* Champion = m_creature->SummonCreature(NPC_IMMOLATED_CHAMPION, PosChampion[0], PosChampion[1], PosChampion[2], PosChampion[3], TEMPSUMMON_TIMED_DESPAWN, 60000))
+ m_uiChampionGUID = Champion->GetGUID();
+ if(Creature* VoiceOfYogg = m_creature->SummonCreature(NPC_VOICE_OF_YOGG_SARON, PosVoiceIcecrown[0], PosVoiceIcecrown[1], PosVoiceIcecrown[2], 0, TEMPSUMMON_TIMED_DESPAWN, 60000))
+ {
+ m_uiVoiceOfYoggGUID = VoiceOfYogg->GetGUID();
+ VoiceOfYogg->SetVisibility(VISIBILITY_OFF);
+ }
+ for(uint8 i = 0; i < 9; i++)
+ {
+ if(Creature *pTemp = m_creature->SummonCreature(MOB_VISION_TENTACLE, IcecrownLoc[i].x, IcecrownLoc[i].y, IcecrownLoc[i].z, IcecrownLoc[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 80000))
+ {
+ pTemp->SetMaxHealth(m_bIsRegularMode ? 15000 : 40000);
+ pTemp->SetDisplayId(25627);
+ pTemp->setFaction(7);
+ pTemp->CastSpell(pTemp, SPELL_GRIM_REPRISAL, false);
+ }
+ }
+ for(uint8 i = 0; i < 4; i++)
+ m_creature->SummonCreature(NPC_LAUGHING_SKULL, SkullIcecrownLoc[i].x, SkullIcecrownLoc[i].y, SkullIcecrownLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 1000;
+ break;
+ case 1:
+ if(Creature* Champion = m_pInstance->instance->GetCreature(m_uiChampionGUID))
+ {
+ Champion->SetStandFlags(UNIT_STAND_STATE_KNEEL);
+ if(Creature* LichKing = m_pInstance->instance->GetCreature(m_uiLichKingGUID))
+ {
+ LichKing->CastSpell(Champion, 54142, false);
+ DoScriptText(SAY_LICH_KING1, LichKing);
+ }
+ }
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 5000;
+ break;
+ case 2:
+ if(Creature* Champion = m_pInstance->instance->GetCreature(m_uiChampionGUID))
+ DoScriptText(SAY_CHAMPION1, Champion);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 8000;
+ break;
+ case 3:
+ if(Creature* Champion = m_pInstance->instance->GetCreature(m_uiChampionGUID))
+ DoScriptText(SAY_CHAMPION2, Champion);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 8000;
+ break;
+ case 4:
+ if(Creature* LichKing = m_pInstance->instance->GetCreature(m_uiLichKingGUID))
+ DoScriptText(SAY_LICH_KING2, LichKing);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 7000;
+ break;
+ case 5:
+ if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID))
+ DoScriptText(SAY_YOGG_V3_1, VoiceOfYogg);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 5000;
+ break;
+ case 6:
+ if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID))
+ DoScriptText(SAY_YOGG_V3_2, VoiceOfYogg);
+ ++m_uiVisionPhase;
+ m_uiSpeechTimer = 10000;
+ break;
+ default:
+ m_uiSpeechTimer = 100000;
+ }
+ }else m_uiSpeechTimer -= uiDiff;
+
+ break;
+ }
+ }
+
+ // End phase after 30%
+ if(m_creature->GetHealthPercent() < 30 && !m_bIsPhaseFinished)
+ {
+ if(m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_YOGG_BRAIN, DONE);
+ m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_OLD_GOD);
+ }
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (Creature* pYogg = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ ((boss_yogg_saronAI*)pYogg->AI())->StartThirdPhase();
+ pYogg->RemoveAurasDueToSpell(SPELL_SHATTERED_ILLUSION);
+ }
+ m_creature->CastStop();
+ m_bIsPhaseFinished = true;
+ }
+
+ // check if tentacles are dead
+ if (m_uiTentacleCheckTimer < uiDiff && !m_bIsVisionFinished)
+ {
+ if(Creature* VoiceOfYogg = m_pInstance->instance->GetCreature(m_uiVoiceOfYoggGUID))
+ {
+ if(!IsThereAnyAdd(VoiceOfYogg))
+ {
+ SummonPortals();
+ m_pInstance->SetData(TYPE_VISION_PHASE, PHASE_VISION_RETURN);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_uiTentacleCheckTimer = 300000;
+ }
+ else
+ m_uiTentacleCheckTimer = 500;
+ }
+ }
+ else m_uiTentacleCheckTimer -= uiDiff;
+
+ // make boss unattackable -> exploit check
+ // Induced madness need core support, it should make the players insane
+ if (m_uiMadnessTimer < uiDiff)
+ {
+ if (Creature* pYogg = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ ((boss_yogg_saronAI*)pYogg->AI())->m_bIsShatter = false;
+ ((boss_yogg_saronAI*)pYogg->AI())->m_uiSummonTimer = urand(5000, 8000);
+ pYogg->RemoveAurasDueToSpell(SPELL_SHATTERED_ILLUSION);
+ }
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_bIsVisionFinished = true;
+ m_uiMadnessTimer = 300000;
+ }
+ else m_uiMadnessTimer -= uiDiff;
+ }
+};
+
+// Sara script
+struct MANGOS_DLL_DECL boss_saraAI : public ScriptedAI
+{
+ boss_saraAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ m_bIsIntroDone = false;
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ // intro
+ bool m_bIsIntro;
+ uint32 m_uiIntro_Phase;
+ uint32 m_uiSpeech_Timer;
+ bool m_bIsIntroDone;
+ bool m_bIsFactionSet;
+
+ // phase 1
+ uint32 m_uiPhaseYellTimer;
+ uint32 m_uiSummonTimer;
+ uint32 m_uiSarasFervorTimer;
+ uint32 m_uiSarasBlessingTimer;
+ uint32 m_uiSarasAngerTimer;
+ uint32 m_uiAllVisions;
+
+ // transition
+ bool m_bIsOutro;
+ uint32 m_uiOutroTimer;
+ uint32 m_uiOutroStep;
+
+ // phase 2
+ uint32 m_uiPsychosisTimer;
+ uint32 m_uiPortalsTimer;
+ uint32 m_uiMaladyTimer;
+ uint32 m_uiBrainLinkTimer;
+ uint32 m_uiDeathRayTimer;
+ uint32 m_uiBrainLinkEndTimer;
+ uint32 m_uiBrainLinkTickTimer;
+ bool m_bIsBrainLink;
+
+ uint32 m_uiFirstVision;
+ uint32 m_uiSecondVision;
+
+ uint64 m_uiLinkTarget1GUID;
+ uint64 m_uiLinkTarget2GUID;
+
+ void Reset()
+ {
+ // intro
+ m_bIsIntro = false;
+ m_uiIntro_Phase = 0;
+ m_uiSpeech_Timer = 1000;
+ m_bIsFactionSet = false;
+
+ // phase 1
+ m_uiPhaseYellTimer = 30000;
+ m_uiSummonTimer = 10000 + urand (1000, 5000);
+ m_uiSarasFervorTimer = urand(10000, 15000);
+ m_uiSarasBlessingTimer = urand(15000, 20000);
+ m_uiSarasAngerTimer = urand(20000, 25000);
+ m_uiAllVisions = 0;
+
+ // transition
+ m_bIsOutro = false;
+ m_uiOutroTimer = 10000;
+ m_uiOutroStep = 1;
+
+ // phase 2
+ m_uiPortalsTimer = 60000;
+ m_uiPsychosisTimer = 15000;
+ m_uiMaladyTimer = 20000;
+ m_uiBrainLinkTimer = 25000;
+ m_uiDeathRayTimer = 30000;
+ m_uiBrainLinkTickTimer = 1000;
+ m_uiBrainLinkEndTimer = 0;
+ m_bIsBrainLink = false;
+
+ m_uiFirstVision = 0;
+ m_uiSecondVision = 0;
+
+ m_uiLinkTarget1GUID = 0;
+ m_uiLinkTarget2GUID = 0;
+
+ if(m_creature->HasAura(SPELL_SHADOWY_BARRIER))
+ m_creature->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER);
+
+ m_creature->SetDisplayId(MODEL_SARA_HUMAN);
+ m_creature->setFaction(35);
+ m_creature->SetMaxHealth(199999);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->SetSplineFlags(SPLINEFLAG_FLYING);
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, 5.9f);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if(irand(0,1))
+ DoScriptText(SAY_KILL1, m_creature);
+ else
+ DoScriptText(SAY_KILL2, m_creature);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(uiDamage > m_creature->GetHealth())
+ {
+ m_bIsOutro = true;
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ uiDamage = 0;
+ }
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ // start intro speech
+ if(m_pInstance->GetData(TYPE_YOGG_PHASE) == PHASE_IDLE)
+ {
+ if (pWho->isTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature) && !m_bIsIntro && !m_bIsIntroDone &&
+ pWho->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(pWho, 110) && m_creature->IsWithinLOSInMap(pWho))
+ m_bIsIntro = true;
+ }
+ }
+
+ // return a random npc from the selected entry
+ Creature* SelectRandomNpc(float fRange, uint32 uiEntry)
+ {
+ std::list lNpcList;
+ GetCreatureListWithEntryInGrid(lNpcList, m_creature, uiEntry, fRange);
+
+ //This should not appear!
+ if (lNpcList.empty()){
+ return NULL;
+ }
+
+ std::list::iterator iter = lNpcList.begin();
+ advance(iter, urand(0, lNpcList.size()-1));
+
+ return *iter;
+ }
+
+ void DoBrainLink()
+ {
+ // workaround here
+ }
+
+ void SummonPortals()
+ {
+ uint8 maxPortals = m_bIsRegularMode ? 4 : 10;
+ for(uint8 i = 0; i < maxPortals; i++)
+ m_creature->SummonCreature(MOB_DESCEND_INTO_MADNESS, YoggPortalLoc[i].x, YoggPortalLoc[i].y, YoggPortalLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
+ }
+
+ // set a random vision
+ uint32 GetCurrentVision()
+ {
+ switch(urand(0, 2))
+ {
+ case 0:
+ return PHASE_VISION_STORMWIND;
+ break;
+ case 1:
+ return PHASE_VISION_WYRMREST;
+ break;
+ case 2:
+ return PHASE_VISION_ICECROWN;
+ break;
+ }
+
+ return 0;
+ }
+
+ // start a vision
+ void SetVisionPhase()
+ {
+ uint32 m_uiVisionType = 0;
+
+ // set random different destination
+ if(m_uiFirstVision == 0 && m_uiSecondVision == 0)
+ {
+ m_uiVisionType = GetCurrentVision();
+ m_uiFirstVision = m_uiVisionType;
+ }
+ else if(m_uiSecondVision == 0)
+ {
+ do m_uiVisionType = GetCurrentVision();
+ while(m_uiVisionType == m_uiFirstVision);
+ m_uiSecondVision = m_uiVisionType;
+ }
+ else
+ {
+ do m_uiVisionType = GetCurrentVision();
+ while(m_uiVisionType == m_uiFirstVision || m_uiVisionType == m_uiSecondVision);
+ }
+
+ // set instance data for vision
+ if(m_uiVisionType != 0)
+ m_pInstance->SetData(TYPE_VISION_PHASE, m_uiVisionType);
+
+ // summon portals
+ SummonPortals();
+ // start the vision
+ if (Creature* pYoggBrain = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(NPC_YOGG_BRAIN)))
+ {
+ if(pYoggBrain->isAlive())
+ ((boss_brain_of_yogg_saronAI*)pYoggBrain->AI())->StartVisions();
+ }
+ // increase the vision no.
+ m_uiAllVisions += 1;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ switch(m_pInstance->GetData(TYPE_YOGG_PHASE))
+ {
+ case PHASE_IDLE:
+ {
+ // intro
+ if (m_bIsIntro && !m_bIsIntroDone)
+ {
+ if(m_uiSpeech_Timer < uiDiff)
+ {
+ switch(m_uiIntro_Phase)
+ {
+ case 0:
+ DoScriptText(SAY_INTRO1, m_creature);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->GetMotionMaster()->MoveIdle();
+ SetCombatMovement(false);
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, 5.9f);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), 329.397f, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ ++m_uiIntro_Phase;
+ m_uiSpeech_Timer = 8000;
+ break;
+ case 1:
+ DoScriptText(SAY_INTRO2, m_creature);
+ ++m_uiIntro_Phase;
+ m_uiSpeech_Timer = 8000;
+ break;
+ case 2:
+ m_bIsIntro = false;
+ m_bIsIntroDone = true;
+ m_uiSpeech_Timer = 12000;
+ break;
+ default:
+ m_uiSpeech_Timer = 100000;
+ }
+ }
+ else m_uiSpeech_Timer -= uiDiff;
+ }
+ break;
+ }
+ case PHASE_SARA:
+ {
+ if(!m_bIsOutro)
+ {
+ // wipe check
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ if(!pYogg->getVictim() || !pYogg->SelectHostileTarget() || pYogg->getVictim() == m_creature)
+ {
+ pYogg->AI()->EnterEvadeMode();
+ DoScriptText(SAY_WIPE, m_creature);
+ }
+ }
+
+ if (m_uiPhaseYellTimer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0: DoScriptText(SAY_HELP1, m_creature); break;
+ case 1: DoScriptText(SAY_HELP2, m_creature); break;
+ }
+ m_uiPhaseYellTimer = 30000;
+ }else m_uiPhaseYellTimer -= uiDiff;
+
+ if (m_uiSummonTimer < uiDiff)
+ {
+ if (Creature* pCloud = SelectRandomNpc(120.0f, NPC_OMINOUS_CLOUD))
+ pCloud->CastSpell(pCloud, SPELL_SUMMON_GUARDIAN2, false);
+ m_uiSummonTimer = urand(15000, 20000);
+ }else m_uiSummonTimer -= uiDiff;
+
+ if (m_uiSarasFervorTimer < uiDiff)
+ {
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ if (Unit* pTarget = pYogg->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ if(pTarget != m_creature)
+ {
+ DoCast(pTarget, SPELL_SARAS_FERVOR);
+ m_uiSarasFervorTimer = urand(20000, 30000);
+ }
+ }
+ }
+ }else m_uiSarasFervorTimer -= uiDiff;
+
+ if (m_uiSarasBlessingTimer < uiDiff)
+ {
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ if (Unit* pTarget = pYogg->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ if(pTarget != m_creature)
+ {
+ DoCast(pTarget, SPELL_SARAS_BLESSING);
+ m_uiSarasBlessingTimer = urand(20000, 30000);
+ }
+ }
+ }
+ }else m_uiSarasBlessingTimer -= uiDiff;
+
+ if (m_uiSarasAngerTimer < uiDiff)
+ {
+ if (Creature* pGuardian = SelectRandomNpc(80.0f, MOB_GUARDIAN_OF_YOGG))
+ DoCast(pGuardian, SPELL_SARAS_ANGER);
+ m_uiSarasAngerTimer = urand(20000, 30000);
+ }else m_uiSarasAngerTimer -= uiDiff;
+ }
+ // Phase 1 outro
+ if(m_bIsOutro)
+ {
+ switch(m_uiOutroStep)
+ {
+ case 1:
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->CombatStop(true);
+ m_creature->InterruptNonMeleeSpells(false);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 5000;
+ break;
+ case 3:
+ DoScriptText(SAY_PHASE2, m_creature);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 15000;
+ break;
+ case 5:
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ if (Unit* pTarget = pYogg->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ m_creature->AddThreat(pTarget, 100.0f);
+ m_creature->AI()->AttackStart(pTarget);
+ }
+ }
+ m_creature->setFaction(14);
+ m_creature->SetInCombatWithZone();
+ SetCombatMovement(false);
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->SetDisplayId(MODEL_SARA_VALKYR);
+ DoCast(m_creature, SPELL_SHADOWY_BARRIER);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 10, 5.9f);
+ m_creature->SendMonsterMove(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 10, SPLINETYPE_NORMAL, m_creature->GetSplineFlags(), 1);
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ ((boss_yogg_saronAI*)pYogg->AI())->StartSecondPhase();
+ m_uiPhaseYellTimer = 30000 + urand(5000, 10000);
+ m_pInstance->SetData(TYPE_YOGG_PHASE, PHASE_TENTACLES);
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 3000;
+ break;
+ }
+ }
+ else return;
+
+ if (m_uiOutroTimer <= uiDiff)
+ {
+ ++m_uiOutroStep;
+ m_uiOutroTimer = 330000;
+ }
+ m_uiOutroTimer -= uiDiff;
+
+ break;
+ }
+ case PHASE_TENTACLES:
+ {
+ // wipe check
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ if(!pYogg->getVictim() || !pYogg->SelectHostileTarget())
+ pYogg->AI()->EnterEvadeMode();
+ }
+
+ if (m_uiPhaseYellTimer < uiDiff)
+ {
+ switch(urand(0, 1))
+ {
+ case 0: DoScriptText(SAY_SPECIAL1, m_creature); break;
+ case 1: DoScriptText(SAY_SPECIAL2, m_creature); break;
+ }
+ m_uiPhaseYellTimer = 30000 + urand(5000, 10000);
+ }
+ else m_uiPhaseYellTimer -= uiDiff;
+
+ // summon madness portals
+ if (m_uiPortalsTimer < uiDiff && m_uiAllVisions < 3)
+ {
+ SetVisionPhase();
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ DoScriptText(SAY_VISION, pYogg);
+ m_uiPortalsTimer = 85000;
+ }
+ else m_uiPortalsTimer -= uiDiff;
+
+ if (m_uiPsychosisTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, m_bIsRegularMode ? SPELL_PHYCHOSIS : SPELL_PHYCHOSIS_H);
+ m_uiPsychosisTimer = urand(15000, 20000);
+ }
+ else m_uiPsychosisTimer -= uiDiff;
+
+ if (m_uiMaladyTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_MALADY_OF_THE_MIND);
+ m_uiMaladyTimer = urand(20000, 25000);
+ }
+ else m_uiMaladyTimer -= uiDiff;
+
+ if (m_uiBrainLinkTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ m_uiLinkTarget1GUID = pTarget->GetGUID();
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ m_uiLinkTarget2GUID = pTarget->GetGUID();
+ DoCast(m_creature, SPELL_BRAIN_LINK);
+ m_bIsBrainLink = true;
+ m_uiBrainLinkEndTimer = 30000;
+ m_uiBrainLinkTickTimer = 1000;
+ m_uiBrainLinkTimer = urand(25000, 30000);
+ }
+ else m_uiBrainLinkTimer -= uiDiff;
+
+ // workaround for brainlink
+ // spell need core support
+ // REMOVE FOR REVISION!
+ if (m_uiBrainLinkTickTimer < uiDiff && m_bIsBrainLink)
+ {
+ DoBrainLink();
+ m_uiBrainLinkTickTimer = 1000;
+ }
+ else m_uiBrainLinkTickTimer -= uiDiff;
+
+ if (m_uiBrainLinkEndTimer < uiDiff && m_bIsBrainLink)
+ m_bIsBrainLink = false;
+ else m_uiBrainLinkEndTimer -= uiDiff;
+
+ // workaround, should be done by spell
+ if (m_uiDeathRayTimer < uiDiff)
+ {
+ if(Creature* pYogg = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_YOGGSARON)))
+ {
+ for(int i = 0; i < irand(3, 4); i++)
+ {
+ float angle = (float) rand()*360/RAND_MAX + 1;
+ float homeX = pYogg->GetPositionX() + urand(20, 40)*cos(angle*(M_PI/180));
+ float homeY = pYogg->GetPositionY() + urand(20, 40)*sin(angle*(M_PI/180));
+ m_creature->SummonCreature(MOB_DEATH_ORB, homeX, homeY, pYogg->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
+ }
+ }
+ //DoCast(m_creature, SPELL_DEATH_RAY);
+ m_uiDeathRayTimer = 30000;
+ }
+ else m_uiDeathRayTimer -= uiDiff;
+
+ break;
+ }
+ }
+ }
+};
+
+/*
+* Keepers
+*/
+struct MANGOS_DLL_DECL keeper_hodirAI : public ScriptedAI
+{
+ keeper_hodirAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiHodirProtectivGazeTimer;
+
+ void Reset()
+ {
+ m_uiHodirProtectivGazeTimer = 30000;
+ m_creature->SetRespawnDelay(DAY);
+ DoCast(m_creature, SPELL_FORTITUDE_OF_FROST);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_uiHodirProtectivGazeTimer < uiDiff)
+ {
+ if(Unit* pTemp = DoSelectLowestHpFriendly(100.0f))
+ DoCast(pTemp, SPELL_HODIRS_PROTECTIVE_GAZE);
+ m_uiHodirProtectivGazeTimer = 30000 + urand(10000,30000);
+ }
+ else m_uiHodirProtectivGazeTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL keeper_freyaAI : public ScriptedAI
+{
+ keeper_freyaAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_RESILIENCE_OF_NATURE);
+ m_creature->SetRespawnDelay(DAY);
+ // Summon Wells
+ SummonSanityWells();
+ }
+
+ void SummonSanityWells()
+ {
+ for(uint8 i = 0; i < 5; i++)
+ m_creature->SummonCreature(MOB_SANITY_WELL, SanityWellLoc[i].x, SanityWellLoc[i].y, SanityWellLoc[i].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 30000);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+ }
+};
+
+struct MANGOS_DLL_DECL keeper_thorimAI : public ScriptedAI
+{
+ keeper_thorimAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bHasTitanicStorm;
+
+ void Reset()
+ {
+ m_bHasTitanicStorm = false;
+ m_creature->SetRespawnDelay(DAY);
+ DoCast(m_creature, SPELL_FURY_OF_THE_STORM);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_pInstance->GetData(TYPE_YOGG_PHASE) == PHASE_OLD_GOD && !m_bHasTitanicStorm)
+ {
+ DoCast(m_creature, SPELL_TITANIC_STORM);
+ m_bHasTitanicStorm = true;
+ }
+ }
+};
+
+struct MANGOS_DLL_DECL keeper_mimironAI : public ScriptedAI
+{
+ keeper_mimironAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiDestabilizationMatrixTimer;
+ std::list lTentacleList;
+
+ void Reset()
+ {
+ lTentacleList.clear();
+ m_uiDestabilizationMatrixTimer = 10000;
+ m_creature->SetRespawnDelay(DAY);
+ DoCast(m_creature, SPELL_SPEED_OF_INVENTION);
+ }
+
+ Creature* SelectRandomTentacle(float fRange)
+ {
+ GetCreatureListWithEntryInGrid(lTentacleList, m_creature, MOB_CRUSHER_TENTACLE, fRange);
+ GetCreatureListWithEntryInGrid(lTentacleList, m_creature, MOB_CORRUPTOR_TENTACLE, fRange);
+
+ if (lTentacleList.empty()){
+ m_uiDestabilizationMatrixTimer = 30000;
+ return NULL;
+ }
+
+ std::list::iterator iter = lTentacleList.begin();
+ advance(iter, urand(0, lTentacleList.size()-1));
+
+ return *iter;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_pInstance->GetData(TYPE_YOGG_PHASE) == PHASE_TENTACLES)
+ {
+ if (m_uiDestabilizationMatrixTimer < uiDiff)
+ {
+ if(Unit* pTentacle = SelectRandomTentacle(120.0f))
+ DoCast(pTentacle, SPELL_DESTABILIZATION_MATRIX);
+ m_uiDestabilizationMatrixTimer = 30000 + urand(10000,30000);
+ }
+ else m_uiDestabilizationMatrixTimer -= uiDiff;
+ }
+ }
+};
+
+/*
+* Guardians
+*/
+struct MANGOS_DLL_DECL mob_immortal_guardianAI : public ScriptedAI
+{
+ mob_immortal_guardianAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiStack;
+ uint32 m_uiHealth;
+ bool m_bHasAura;
+
+ void Reset()
+ {
+ m_uiStack = 0;
+ m_uiHealth = 90;
+ m_bHasAura = false;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(m_creature->GetHealthPercent() < 5)
+ {
+ if(uiDamage > m_creature->GetHealth())
+ uiDamage = 0;
+ }
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ if(m_creature->GetHealthPercent() < 5)
+ {
+ if(spell->Id == SPELL_TITANIC_STORM_DMG && caster->GetEntry() == KEEPER_THORIM)
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+
+ void Aggro(Unit *who)
+ {
+ DoCast(m_creature, SPELL_EMPOWERED);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ // hacky way of stacking aura, needs fixing
+ if(SpellAuraHolder* empoweredAura = m_creature->GetSpellAuraHolder(SPELL_EMPOWERED))
+ {
+ if(empoweredAura->GetStackAmount() < 9 && !m_bHasAura)
+ {
+ m_bHasAura = true;
+ empoweredAura->SetStackAmount(9);
+ }
+ }
+
+ if(m_creature->GetHealthPercent() > 10)
+ {
+ if(m_creature->GetHealthPercent() < m_uiHealth)
+ {
+ if(SpellAuraHolder* empoweredAura = m_creature->GetSpellAuraHolder(SPELL_EMPOWERED))
+ {
+ if(empoweredAura->ModStackAmount(-1))
+ m_creature->RemoveAurasDueToSpell(SPELL_EMPOWERED);
+ }
+ m_uiHealth -= 10;
+ }
+ }
+
+ // empowering shadows, needs more research and core fix
+ if(m_creature->GetHealthPercent() > m_uiHealth + 10)
+ {
+ DoCast(m_creature, SPELL_EMPOWERED);
+ m_uiHealth += 10;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_guardian_of_yogg_saronAI : public ScriptedAI
+{
+ mob_guardian_of_yogg_saronAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiDarkVolleyTimer;
+ uint32 m_uiDieTimer;
+ uint32 m_uiDominateMindTimer;
+ bool m_bHasCasted;
+
+ void Reset()
+ {
+ m_uiDarkVolleyTimer = 10000;
+ m_uiDominateMindTimer = 30000;
+ m_bHasCasted = false;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(uiDamage > m_creature->GetHealth())
+ {
+ uiDamage = 0;
+ if(!m_bHasCasted)
+ {
+ DoCast(m_creature, m_bIsRegularMode ? SPELL_SHADOW_NOVA : SPELL_SHADOW_NOVA_H);
+ m_bHasCasted = true;
+ m_uiDieTimer = 500;
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+
+ // workaround for dmg Sara
+ // need to find a way to damage Sara by spell!
+ if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA)))
+ {
+ if(m_creature->IsWithinDist2d(pSara->GetPositionX(), pSara->GetPositionY(), 15.0f))
+ {
+ uint32 maxHealth = m_bIsRegularMode ? 21994 : 27500;
+ if(pSara->GetHealth() > maxHealth)
+ pSara->DealDamage(pSara, m_bIsRegularMode ? urand(20000, 21994) : urand(25000, 27500), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW, NULL, false);
+ else
+ {
+ ((boss_saraAI*)pSara->AI())->m_bIsOutro = true;
+ pSara->SetHealth(pSara->GetMaxHealth());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(Creature* pSara = (Creature*)m_creature->GetMap()->GetUnit(m_pInstance->GetData64(NPC_SARA)))
+ {
+ if(m_creature->getVictim() == pSara)
+ {
+ m_creature->AddThreat(pSara, -100000.0f);
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO, 0))
+ m_creature->AddThreat(pTarget, 1000000.0f);
+ }
+ }
+
+ if (m_uiDarkVolleyTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_DARK_VOLLEY);
+ m_uiDarkVolleyTimer = 15000;
+ }
+ else m_uiDarkVolleyTimer -= uiDiff;
+
+ if (m_uiDominateMindTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_DOMINATE_MIND);
+ m_uiDominateMindTimer = 30000;
+ }
+ else m_uiDominateMindTimer -= uiDiff;
+
+ if (m_uiDieTimer < uiDiff && m_bHasCasted)
+ m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ else m_uiDieTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*
+* Tentacules
+*/
+struct MANGOS_DLL_DECL mob_corruptor_tentacleAI : public ScriptedAI
+{
+ mob_corruptor_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiEruptTimer;
+ bool m_bHasErupted;
+ uint32 m_uiSpellTimer;
+
+ void Reset()
+ {
+ m_uiEruptTimer = 500;
+ m_bHasErupted = false;
+ m_uiSpellTimer = 10000;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiEruptTimer < uiDiff && !m_bHasErupted)
+ {
+ DoCast(m_creature, SPELL_ERUPT);
+ m_bHasErupted = true;
+ }else m_uiEruptTimer -= uiDiff;
+
+ if (m_uiSpellTimer < uiDiff)
+ {
+ switch(urand(0, 3))
+ {
+ case 0:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BLACK_PLAGUE);
+ break;
+ case 1:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_APATHY);
+ break;
+ case 2:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_CURSE_OF_DOOM);
+ break;
+ case 3:
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_DRAINING_POISON);
+ break;
+ }
+ m_uiSpellTimer = urand(5000, 10000);
+ }
+ else m_uiSpellTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_constrictor_tentacleAI : public ScriptedAI
+{
+ mob_constrictor_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance *m_pInstance;
+
+ uint32 m_uiSqueezeTimer;
+ uint64 m_uiVictimGUID;
+
+ void Reset()
+ {
+ m_uiSqueezeTimer = 10000;
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (uiDamage > m_creature->GetHealth())
+ {
+ if (m_uiVictimGUID)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID))
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H);
+ }
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID))
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H);
+
+ if (pKiller)
+ pKiller->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H);
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim)
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ {
+ if (Unit* pVictim = m_creature->GetMap()->GetUnit( m_uiVictimGUID))
+ pVictim->RemoveAurasDueToSpell(m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H);
+ m_creature->ForcedDespawn();
+ }
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiSqueezeTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ {
+ // spell needs vehicles
+ //pTarget->CastSpell(pTarget, m_bIsRegularMode ? SPELL_SQUEEZE : SPELL_SQUEEZE_H, false);
+ m_uiVictimGUID = pTarget->GetGUID();
+ }
+ m_uiSqueezeTimer = 30000;
+ }else m_uiSqueezeTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_crusher_tentacleAI : public ScriptedAI
+{
+ mob_crusher_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+ bool m_bIsRegularMode;
+
+ uint32 m_uiEruptTimer;
+ bool m_bHasErupted;
+ uint32 m_uiDiminishPowerTimer;
+
+ void Reset()
+ {
+ m_uiEruptTimer = 500;
+ m_bHasErupted = false;
+ m_uiDiminishPowerTimer = 10000;
+ m_creature->SetRespawnDelay(DAY);
+ DoCast(m_creature, SPELL_FOCUSED_ANGER_TRIGG);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiEruptTimer < uiDiff && !m_bHasErupted)
+ {
+ DoCast(m_creature, SPELL_ERUPT);
+ m_bHasErupted = true;
+ }
+ else m_uiEruptTimer -= uiDiff;
+
+ if (m_uiDiminishPowerTimer < uiDiff)
+ {
+ DoCast(m_creature, SPELL_DIMINISH_POWER);
+ m_uiDiminishPowerTimer = 10000 + urand(1000, 5000);
+ }
+ else m_uiDiminishPowerTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct MANGOS_DLL_DECL mob_vision_tentacleAI : public ScriptedAI
+{
+ mob_vision_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_GRIM_REPRISAL);
+ }
+
+ void DamageTaken(Unit *done_by, uint32 &uiDamage)
+ {
+ if(uiDamage > 0 && m_creature->GetDisplayId() != 28813)
+ m_creature->SetDisplayId(28813);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*
+* Other
+*/
+struct MANGOS_DLL_DECL mob_death_orbAI : public ScriptedAI
+{
+ mob_death_orbAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ pCreature->setFaction(14);
+ Reset();
+ }
+
+ uint32 m_uiAuraTimer;
+ bool m_bHasAura;
+
+ void Reset()
+ {
+ m_uiAuraTimer = 500;
+ m_bHasAura = false;
+ DoCast(m_creature, SPELL_DEATH_RAY_VISUAL);
+ m_creature->GetMotionMaster()->MoveConfused();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if(m_uiAuraTimer < uiDiff && !m_bHasAura)
+ {
+ DoCast(m_creature, SPELL_DEATH_RAY_TRIGG);
+ m_bHasAura = true;
+ }
+ else m_uiAuraTimer -= uiDiff;
+ }
+};
+
+struct MANGOS_DLL_DECL mob_sanity_wellAI : public ScriptedAI
+{
+ mob_sanity_wellAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->SetDisplayId(11686); // make invisible
+ pCreature->setFaction(14);
+ SetCombatMovement(false);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiAuraDelayTimer;
+ bool m_bHasAura;
+
+ void Reset()
+ {
+ m_uiAuraDelayTimer = 1000;
+ m_bHasAura = false;
+ DoCast(m_creature, SPELL_SANITY_WELL_VISUAL);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_pInstance && m_pInstance->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
+ m_creature->ForcedDespawn();
+
+ if (m_uiAuraDelayTimer < uiDiff && !m_bHasAura)
+ {
+ // spell partially broken, it should be triggered by the visual aura
+ //DoCast(m_creature, SPELL_SANITY_WELL);
+ m_bHasAura = true;
+ }
+ else m_uiAuraDelayTimer -= uiDiff;
+ }
};
+struct MANGOS_DLL_DECL mob_laughing_skullAI : public ScriptedAI
+{
+ mob_laughing_skullAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->SetDisplayId(SKULL_DISPLAY_ID);
+ pCreature->setFaction(14);
+ SetCombatMovement(false);
+ pCreature->GetMotionMaster()->MoveConfused();
+ Reset();
+ }
+
+ void Reset()
+ {
+ m_creature->SetRespawnDelay(DAY);
+ DoCast(m_creature, SPELL_LUNATIC_GAZE);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ }
+};
+
+struct MANGOS_DLL_DECL mob_ominous_cloudAI : public ScriptedAI
+{
+ mob_ominous_cloudAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ SetCombatMovement(false);
+ pCreature->setFaction(14);
+ Reset();
+ }
+
+ ScriptedInstance *m_pInstance;
+
+ uint32 m_uiRangeCheckTimer;
+ bool m_bSummonGuardian;
+
+ void Reset()
+ {
+ m_uiRangeCheckTimer = 1000;
+ m_bSummonGuardian = false;
+ DoCast(m_creature, SPELL_OMINOUS_CLOUD_VISUAL);
+ m_creature->SetRespawnDelay(DAY);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ return;
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ pSummon->SetInCombatWithZone();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiRangeCheckTimer < uiDiff)
+ {
+ Map *map = m_creature->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && m_creature->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) <= 5)
+ m_bSummonGuardian = true;
+
+ }
+ }
+ // cast summon guard
+ if(m_bSummonGuardian)
+ {
+ DoCast(m_creature, SPELL_SUMMON_GUARDIAN2);
+ m_uiRangeCheckTimer = 11000;
+ m_bSummonGuardian = false;
+ }
+ else
+ m_uiRangeCheckTimer = 1000;
+ }
+ else m_uiRangeCheckTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_boss_yogg_saron(Creature* pCreature)
+{
+ return new boss_yogg_saronAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_sara(Creature* pCreature)
+{
+ return new boss_saraAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_madness_portal(Creature* pCreature)
+{
+ return new mob_madness_portalAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_brain_of_yogg_saron(Creature* pCreature)
+{
+ return new boss_brain_of_yogg_saronAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_corruptor_tentacle(Creature* pCreature)
+{
+ return new mob_corruptor_tentacleAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_constrictor_tentacle(Creature* pCreature)
+{
+ return new mob_constrictor_tentacleAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_crusher_tentacle(Creature* pCreature)
+{
+ return new mob_crusher_tentacleAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_vision_tentacle(Creature* pCreature)
+{
+ return new mob_vision_tentacleAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_guardian_of_yogg_saron(Creature* pCreature)
+{
+ return new mob_guardian_of_yogg_saronAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_immortal_guardian(Creature* pCreature)
+{
+ return new mob_immortal_guardianAI(pCreature);
+}
+
+CreatureAI* GetAI_keeper_hodir(Creature* pCreature)
+{
+ return new keeper_hodirAI(pCreature);
+}
+
+CreatureAI* GetAI_keeper_freya(Creature* pCreature)
+{
+ return new keeper_freyaAI(pCreature);
+}
+
+CreatureAI* GetAI_keeper_thorim(Creature* pCreature)
+{
+ return new keeper_thorimAI(pCreature);
+}
+
+CreatureAI* GetAI_keeper_mimiron(Creature* pCreature)
+{
+ return new keeper_mimironAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_death_orb(Creature* pCreature)
+{
+ return new mob_death_orbAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_sanity_well(Creature* pCreature)
+{
+ return new mob_sanity_wellAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_laughing_skull(Creature* pCreature)
+{
+ return new mob_laughing_skullAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_ominous_cloud(Creature* pCreature)
+{
+ return new mob_ominous_cloudAI(pCreature);
+}
+
void AddSC_boss_yogg_saron()
{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_yogg_saron";
+ newscript->GetAI = &GetAI_boss_yogg_saron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_sara";
+ newscript->GetAI = &GetAI_boss_sara;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_madness_portal";
+ newscript->GetAI = &GetAI_mob_madness_portal;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_brain_of_yogg_saron";
+ newscript->GetAI = &GetAI_boss_brain_of_yogg_saron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_corruptor_tentacle";
+ newscript->GetAI = &GetAI_mob_corruptor_tentacle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_constrictor_tentacle";
+ newscript->GetAI = &GetAI_mob_constrictor_tentacle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_crusher_tentacle";
+ newscript->GetAI = &GetAI_mob_crusher_tentacle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_vision_tentacle";
+ newscript->GetAI = &GetAI_mob_vision_tentacle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_guardian_of_yogg_saron";
+ newscript->GetAI = &GetAI_mob_guardian_of_yogg_saron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_immortal_guardian";
+ newscript->GetAI = &GetAI_mob_immortal_guardian;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "keeper_hodir";
+ newscript->GetAI = &GetAI_keeper_hodir;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "keeper_freya";
+ newscript->GetAI = &GetAI_keeper_freya;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "keeper_thorim";
+ newscript->GetAI = &GetAI_keeper_thorim;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "keeper_mimiron";
+ newscript->GetAI = &GetAI_keeper_mimiron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_death_orb";
+ newscript->GetAI = &GetAI_mob_death_orb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_sanity_well";
+ newscript->GetAI = &GetAI_mob_sanity_well;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_laughing_skull";
+ newscript->GetAI = &GetAI_mob_laughing_skull;
+ newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "mob_ominous_cloud";
+ newscript->GetAI = &GetAI_mob_ominous_cloud;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/ulduar/ulduar/def_ulduar.h b/scripts/northrend/ulduar/ulduar/def_ulduar.h
new file mode 100644
index 0000000..1145e16
--- /dev/null
+++ b/scripts/northrend/ulduar/ulduar/def_ulduar.h
@@ -0,0 +1,213 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software licensed under GPL version 2
+* Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_ULDUAR_H
+#define DEF_ULDUAR_H
+
+enum
+{
+ // encounters
+ MAX_ENCOUNTER = 14,
+ HARD_ENCOUNTER = 9,
+ KEEPER_ENCOUNTER = 4,
+
+ // boss types
+ TYPE_LEVIATHAN = 0,
+ TYPE_IGNIS = 1,
+ TYPE_RAZORSCALE = 2,
+ TYPE_XT002 = 3,
+ TYPE_ASSEMBLY = 4,
+ TYPE_KOLOGARN = 5,
+ TYPE_AURIAYA = 6,
+ TYPE_MIMIRON = 7,
+ TYPE_HODIR = 8,
+ TYPE_THORIM = 9,
+ TYPE_FREYA = 10,
+ TYPE_VEZAX = 11,
+ TYPE_YOGGSARON = 12,
+ TYPE_ALGALON = 13,
+
+ // hard mode bosses
+ TYPE_LEVIATHAN_HARD = 37,
+ TYPE_XT002_HARD = 38,
+ TYPE_ASSEMBLY_HARD = 39,
+ TYPE_MIMIRON_HARD = 40,
+ TYPE_HODIR_HARD = 41,
+ TYPE_THORIM_HARD = 42,
+ TYPE_FREYA_HARD = 43,
+ TYPE_VEZAX_HARD = 44,
+ TYPE_YOGGSARON_HARD = 45,
+
+ // keepers help at Yogg
+ TYPE_KEEPER_HODIR = 46,
+ TYPE_KEEPER_FREYA = 47,
+ TYPE_KEEPER_THORIM = 48,
+ TYPE_KEEPER_MIMIRON = 49,
+
+ // teleporters
+ TYPE_LEVIATHAN_TP = 50,
+ TYPE_XT002_TP = 51,
+ TYPE_MIMIRON_TP = 52,
+
+ //other-> these won't be saved to db
+ TYPE_RUNE_GIANT = 14,
+ TYPE_RUNIC_COLOSSUS = 15,
+ TYPE_LEVIATHAN_MK = 16,
+ TYPE_VX001 = 17,
+ TYPE_AERIAL_UNIT = 18,
+ TYPE_YOGG_BRAIN = 22,
+ TYPE_MIMIRON_PHASE = 23,
+ TYPE_YOGG_PHASE = 24,
+ TYPE_VISION_PHASE = 25,
+
+ // siege
+ NPC_LEVIATHAN = 33113,
+ NPC_IGNIS = 33118,
+ NPC_RAZORSCALE = 33186,
+ NPC_COMMANDER = 33210,
+ NPC_XT002 = 33293,
+ // antechamber
+ NPC_STEELBREAKER = 32867,
+ NPC_MOLGEIM = 32927,
+ NPC_BRUNDIR = 32857,
+ NPC_KOLOGARN = 32930,
+ NPC_RIGHT_ARM = 32934,
+ NPC_LEFT_ARM = 32933,
+ NPC_AURIAYA = 33515,
+ NPC_SANCTUM_SENTRY = 34014,
+ NPC_FERAL_DEFENDER = 34035,
+ // keepers
+ NPC_MIMIRON = 33350,
+ NPC_LEVIATHAN_MK = 33432,
+ NPC_VX001 = 33651,
+ NPC_AERIAL_UNIT = 33670,
+ NPC_HODIR = 32845,
+ NPC_THORIM = 32865,
+ NPC_RUNIC_COLOSSUS = 32872,
+ NPC_RUNE_GIANT = 32873,
+ NPC_JORMUNGAR_BEHEMOTH = 32882,
+ NPC_FREYA = 32906,
+ NPC_BRIGHTLEAF = 32915,
+ NPC_IRONBRACH = 32913,
+ NPC_STONEBARK = 32914,
+ // madness
+ NPC_VEZAX = 33271,
+ NPC_ANIMUS = 33524,
+ NPC_YOGGSARON = 33288,
+ NPC_ALGALON = 32871,
+ NPC_SARA = 33134,
+ NPC_YOGG_BRAIN = 33890,
+ // keepers images used to start the encounter
+ THORIM_IMAGE = 33413,
+ MIMIRON_IMAGE = 33412,
+ HODIR_IMAGE = 33411,
+ FREYA_IMAGE = 33410,
+ // Keepers used at yogg saron encounter
+ KEEPER_FREYA = 33241,
+ KEEPER_HODIR = 33213,
+ KEEPER_MIMIRON = 33244,
+ KEEPER_THORIM = 33242,
+
+ // loot chests
+ // Kologarn
+ GO_CACHE_OF_LIVING_STONE = 195046,
+ GO_CACHE_OF_LIVING_STONE_H = 195047,
+ // Hodir
+ GO_CACHE_OF_WINTER = 194307,
+ GO_CACHE_OF_WINTER_H = 194308,
+ GO_CACHE_OF_RARE_WINTER = 194200,
+ GO_CACHE_OF_RARE_WINTER_H = 194201,
+ // Thorim
+ GO_CACHE_OF_STORMS = 194312,
+ GO_CACHE_OF_RARE_STORMS = 194313,
+ GO_CACHE_OF_STORMS_H = 194314,
+ GO_CACHE_OF_RARE_STORMS_H = 194315,
+ // Alagon
+ GO_GIFT_OF_OBSERVER_H = 194821,
+ GO_GIFT_OF_OBSERVER = 194822,
+ GO_GIFT_OF_OBSERVER_HH = 194823, // unk
+ // Freya -> each chest is for a mode = more elders alive = more items in chest
+ // 10 man
+ GO_FREYA_GIFT = 194324,//10 normal
+ GO_FREYA_GIFT_1 = 194325,//10 1 elder
+ GO_FREYA_GIFT_2 = 194326,//10 2 elders
+ GO_FREYA_GIFT_3 = 194327,//10 3 elders
+ // 25 man
+ GO_FREYA_GIFT_H = 194328,//25 normal
+ GO_FREYA_GIFT_H_1 = 194329,//25 1 elder
+ GO_FREYA_GIFT_H_2 = 194330,//25 2 elder
+ GO_FREYA_GIFT_H_3 = 194331,//25 3 elders
+ // Mimiron
+ GO_CACHE_OF_INOV = 194789,
+ GO_CACHE_OF_INOV_H = 194956,
+ GO_CACHE_OF_INOV_HARD = 194957,
+ GO_CACHE_OF_INOV_HARD_H = 194958,
+
+ // doors
+ // the siege
+ GO_SHIELD_WALL = 194416,
+ GO_LEVIATHAN_GATE = 194630,
+ GO_XT002_GATE = 194631,
+ GO_BROKEN_HARPOON = 194565,
+ // archivum
+ GO_KOLOGARN_BRIDGE = 194232,
+ GO_SHATTERED_DOOR = 194553,
+ GO_IRON_ENTRANCE_DOOR = 194554,
+ GO_ARCHIVUM_DOOR = 194556,
+ GO_ARCHIVUM_CONSOLE = 194555,
+ // planetarium: algalon
+ GO_CELESTIAL_ACCES = 194628,
+ GO_CELESTIAL_ACCES_H = 194752,
+ GO_CELESTIAL_DOOR = 194767,
+ GO_UNIVERSE_FLOOR_ARCHIVUM = 194715,
+ GO_UNIVERSE_FLOOR_CELESTIAL = 194716,
+ GO_AZEROTH_GLOBE = 194148,
+ // the keepers
+ // hodir
+ GO_HODIR_EXIT = 194634,
+ GO_HODIR_ICE_WALL = 194441,
+ GO_HODIR_ENTER = 194442,
+ // mimiron
+ GO_MIMIRON_TRAM = 194675,
+ GO_MIMIRON_BUTTON = 194739,
+ GO_MIMIRON_DOOR_1 = 194774,
+ GO_MIMIRON_DOOR_2 = 194775,
+ GO_MIMIRON_DOOR_3 = 194776,
+ GO_MIMIRON_TEL1 = 194741,
+ GO_MIMIRON_TEL2 = 194742,
+ GO_MIMIRON_TEL3 = 194743,
+ GO_MIMIRON_TEL4 = 194744,
+ GO_MIMIRON_TEL5 = 194740,
+ GO_MIMIRON_TEL6 = 194746,
+ GO_MIMIRON_TEL7 = 194747,
+ GO_MIMIRON_TEL8 = 194748,
+ GO_MIMIRON_TEL9 = 194745,
+ GO_MIMIRON_ELEVATOR = 194749,
+ // Thorim
+ GO_DARK_IRON_PORTCULIS = 194560,
+ GO_RUNED_STONE_DOOR = 194557,
+ GO_THORIM_STONE_DOOR = 194558,
+ GO_LIGHTNING_DOOR = 194905,
+ GO_LIGHTNING_FIELD = 194559,
+ GO_DOOR_LEVER = 194264,
+ //Yogg
+ GO_ANCIENT_GATE = 194255,
+ GO_VEZAX_GATE = 194750,
+ GO_YOGG_GATE = 194773,
+ GO_BRAIN_DOOR1 = 194635,
+ GO_BRAIN_DOOR2 = 194636,
+ GO_BRAIN_DOOR3 = 194637,
+
+ ACHIEV_IRON_COUNCIL = 2888,
+ ACHIEV_IRON_COUNCIL_H = 2889,
+
+ ACHIEV_KEEPERS = 2890,
+ ACHIEV_KEEPERS_H = 2891,
+
+ ACHIEV_CELESTIAL_DEFENDER = 3259, // realm first algalon
+ SPELL_ALGALON_ACHIEV_TRIGG = 65184,
+ ACHIEV_DEATHS_DEMISE = 3117, // realm first yogg
+};
+
+#endif
diff --git a/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp b/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp
index 87b5a16..697c032 100644
--- a/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp
+++ b/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2010 ScriptDev2
+/* Copyright (C) 2006 - 2009 ScriptDev2
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,140 +15,254 @@
*/
/* ScriptData
-SDName: instance_ulduar
+SDName: Instance_Ulduar
SD%Complete:
SDComment:
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
+#include "def_ulduar.h"
-struct sSpawnLocation
+struct MANGOS_DLL_DECL instance_ulduar : public ScriptedInstance
{
- float m_fX, m_fY, m_fZ, m_fO;
-};
+ instance_ulduar(Map* pMap) : ScriptedInstance(pMap)
+ {
+ Regular = pMap->IsRegularDifficulty();
+ Initialize();
+ }
-static sSpawnLocation m_aKeepersSpawnLocs[] =
-{
- {2036.892f, 25.621f, 411.358f, 3.83f}, // Freya
- {1939.215f, 42.677f, 411.355f, 5.31f}, // Mimiron
- {1939.195f, -90.662f, 411.357f, 1.06f}, // Hodir
- {2036.674f, -73.814f, 411.355f, 2.51f}, // Thorim
-};
+ bool Regular;
+
+ // initialize the encouter variables
+ std::string m_strInstData;
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint32 m_auiHardBoss[HARD_ENCOUNTER];
+ uint32 m_auiUlduarKeepers[KEEPER_ENCOUNTER];
+ uint32 m_auiUlduarTeleporters[3];
+ uint32 m_auiMiniBoss[6];
+
+ // boss phases which need to be used inside the instance script
+ uint32 m_uiMimironPhase;
+ uint32 m_uiYoggPhase;
+ uint32 m_uiVisionPhase;
-instance_ulduar::instance_ulduar(Map* pMap) : ScriptedInstance(pMap),
- // Creatures
- m_uiLeviathanGUID(0),
- m_uiIgnisGUID(0),
- m_uiRazorscaleGUID(0),
- m_uiCommanderGUID(0),
- m_uiXT002GUID(0),
- m_uiBrundirGUID(0),
- m_uiMolgeimGUID(0),
- m_uiSteelbreakerGUID(0),
- m_uiKologarnGUID(0),
- m_uiAuriayaGUID(0),
- m_uiMimironGUID(0),
- m_uiHodirGUID(0),
- m_uiThorimGUID(0),
- m_uiFreyaGUID(0),
- m_uiVezaxGUID(0),
- m_uiYoggSaronGUID(0),
- m_uiAlgalonGUID(0),
- m_uiRightArmGUID(0),
- m_uiLeftArmGUID(0),
- m_uiFeralDefenderGUID(0),
- m_uiElderBrightleafGUID(0),
- m_uiElderStonebarkGUID(0),
- m_uiElderIronbrachGUID(0),
- m_uiSaroniteAnimusGUID(0),
- m_uiRunicColossusGUID(0),
- m_uiRuneGiantGUID(0),
- m_uiJormungarGUID(0),
- m_uiLeviathanMkGUID(0),
- m_uiSaraGUID(0),
- m_uiYoggBrainGUID(0),
-
- // Chests
- m_uiKologarnLootGUID(0),
- m_uiHodirLootGUID(0),
- m_uiHodirRareLootGUID(0),
- m_uiThorimLootGUID(0),
- m_uiThorimRareLootGUID(0),
- m_uiMimironLootGUID(0),
- m_uiMimironHardLootGUID(0),
- m_uiAlagonLootGUID(0),
-
- // Doors
+ // creature guids
+ uint64 m_uiLeviathanGUID;
+ uint64 m_uiIgnisGUID;
+ uint64 m_uiRazorscaleGUID;
+ uint64 m_uiCommanderGUID;
+ uint64 m_uiXT002GUID;
+ uint64 m_auiAssemblyGUIDs[3];
+ uint64 m_uiKologarnGUID;
+ uint64 m_uiAuriayaGUID;
+ uint64 m_uiMimironGUID;
+ uint64 m_uiHodirGUID;
+ uint64 m_uiThorimGUID;
+ uint64 m_uiFreyaGUID;
+ uint64 m_uiVezaxGUID;
+ uint64 m_uiYoggSaronGUID;
+ uint64 m_uiAlgalonGUID;
+ uint64 m_uiRightArmGUID;
+ uint64 m_uiLeftArmGUID;
+ uint64 m_uiFeralDefenderGUID;
+ uint64 m_uiElderBrightleafGUID;
+ uint64 m_uiElderStonebarkGUID;
+ uint64 m_uiElderIronbrachGUID;
+ uint64 m_uiSaroniteAnimusGUID;
+ uint64 m_uiRunicColossusGUID;
+ uint64 m_uiRuneGiantGUID;
+ uint64 m_uiJormungarGUID;
+ uint64 m_uiLeviathanMkGUID;
+ uint64 m_uiHodirImageGUID;
+ uint64 m_uiFreyaImageGUID;
+ uint64 m_uiThorimImageGUID;
+ uint64 m_uiMimironImageGUID;
+ uint64 m_uiSaraGUID;
+ uint64 m_uiYoggBrainGUID;
+
+ //doors & objects
// The siege
- m_uiShieldWallGUID(0),
- m_uiLeviathanGateGUID(0),
- m_uiXT002GateGUID(0),
- m_uiBrokenHarpoonGUID(0),
+ uint64 m_uiShieldWallGUID;
+ uint64 m_uiLeviathanGateGUID;
+ uint64 m_uiXT002GateGUID;
+ uint64 m_uiBrokenHarpoonGUID;
// Archivum
- m_uiIronCouncilDoorGUID(0),
- m_uiArchivumDoorGUID(0),
- m_uiArchivumConsoleGUID(0),
- m_uiUniverseFloorArchivumGUID(0),
+ uint64 m_uiIronCouncilDoorGUID;
+ uint64 m_uiArchivumDoorGUID;
+ uint64 m_uiArchivumConsoleGUID;
+ uint64 m_uiUniverseFloorArchivumGUID;
// Celestial planetarium
- m_uiCelestialDoorGUID(0),
- m_uiCelestialConsoleGUID(0),
- m_uiUniverseFloorCelestialGUID(0),
- m_uiAzerothGlobeGUID(0),
+ uint64 m_uiCelestialDoorGUID;
+ uint64 m_uiCelestialConsoleGUID;
+ uint64 m_uiUniverseFloorCelestialGUID;
+ uint64 m_uiAzerothGlobeGUID;
// Kologarn
- m_uiShatteredHallsDoorGUID(0),
- m_uiKologarnBridgeGUID(0),
+ uint64 m_uiShatteredHallsDoorGUID;
+ uint64 m_uiKologarnBridgeGUID;
// Hodir
- m_uiHodirEnterDoorGUID(0),
- m_uiHodirWallGUID(0),
- m_uiHodirExitDoorGUID(0),
+ uint64 m_uiHodirEnterDoorGUID;
+ uint64 m_uiHodirWallGUID;
+ uint64 m_uiHodirExitDoorGUID;
// Mimiron
- m_uiMimironButtonGUID(0),
- m_uiMimironDoor1GUID(0),
- m_uiMimironDoor2GUID(0),
- m_uiMimironDoor3GUID(0),
- m_uiMimironElevatorGUID(0),
+ uint64 m_uiMimironTramGUID;
+ uint64 m_uiMimironButtonGUID;
+ uint64 m_uiMimironDoor1GUID;
+ uint64 m_uiMimironDoor2GUID;
+ uint64 m_uiMimironDoor3GUID;
+ uint64 m_uiMimironElevatorGUID;
+ uint64 m_uiMimironTelGUID[9];
// Thorim
- m_uiArenaEnterDoorGUID(0),
- m_uiArenaExitDoorGUID(0),
- m_uiHallwayDoorGUID(0),
- m_uiThorimEnterDoorGUID(0),
- m_uiThorimLeverGUID(0),
+ uint64 m_uiArenaEnterDoorGUID;
+ uint64 m_uiArenaExitDoorGUID;
+ uint64 m_uiHallwayDoorGUID;
+ uint64 m_uiThorimEnterDoorGUID;
+ uint64 m_uiThorimLeverGUID;
// Prison
- m_uiAncientGateGUID(0),
- m_uiVezaxGateGUID(0),
- m_uiYoggGateGUID(0),
- m_uiBrainDoor1GUID(0),
- m_uiBrainDoor2GUID(0),
- m_uiBrainDoor3GUID(0)
-{
- Initialize();
-}
+ uint64 m_uiAncientGateGUID;
+ uint64 m_uiVezaxGateGUID;
+ uint64 m_uiYoggGateGUID;
+ uint64 m_uiBrainDoor1GUID;
+ uint64 m_uiBrainDoor2GUID;
+ uint64 m_uiBrainDoor3GUID;
-void instance_ulduar::Initialize()
-{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
- memset(&m_auiHardBoss, 0, sizeof(m_auiHardBoss));
- memset(&m_auiUlduarKeepers, 0, sizeof(m_auiUlduarKeepers));
- memset(&m_auiUlduarTeleporters, 0, sizeof(m_auiUlduarTeleporters));
- memset(&m_auiMimironTelGUID, 0, sizeof(m_auiMimironTelGUID));
-}
+ // chests
+ uint64 m_uiKologarnLootGUID;
+ uint64 m_uiHodirLootGUID;
+ uint64 m_uiHodirRareLootGUID;
+ uint64 m_uiThorimLootGUID;
+ uint64 m_uiThorimRareLootGUID;
+ uint64 m_uiFreyaLootGUID;
+ uint64 m_uiFreyaLoot1GUID;
+ uint64 m_uiFreyaLoot2GUID;
+ uint64 m_uiFreyaLoot3GUID;
+ uint64 m_uiMimironLootGUID;
+ uint64 m_uiMimironHardLootGUID;
+ uint64 m_uiAlagonLootGUID;
-bool instance_ulduar::IsEncounterInProgress() const
-{
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ memset(&m_auiHardBoss, 0, sizeof(m_auiHardBoss));
+ memset(&m_auiUlduarKeepers, 0, sizeof(m_auiUlduarKeepers));
+ memset(&m_auiUlduarTeleporters, 0, sizeof(m_auiUlduarTeleporters));
+
+ for(uint8 i = 0; i < 6; i++)
+ m_auiMiniBoss[i] = NOT_STARTED;
+
+ for(uint8 i = 0; i < 9; i++)
+ m_uiMimironTelGUID[i] = 0;
+
+ m_uiMimironPhase = 0;
+ m_uiYoggPhase = 0;
+ m_uiVisionPhase = 0;
+
+ m_uiLeviathanGUID = 0;
+ m_uiIgnisGUID = 0;
+ m_uiRazorscaleGUID = 0;
+ m_uiCommanderGUID = 0;
+ m_uiXT002GUID = 0;
+ m_uiKologarnGUID = 0;
+ m_uiAuriayaGUID = 0;
+ m_uiMimironGUID = 0;
+ m_uiHodirGUID = 0;
+ m_uiThorimGUID = 0;
+ m_uiFreyaGUID = 0;
+ m_uiVezaxGUID = 0;
+ m_uiYoggSaronGUID = 0;
+ m_uiAlgalonGUID = 0;
+ m_uiRightArmGUID = 0;
+ m_uiLeftArmGUID = 0;
+ m_uiFeralDefenderGUID = 0;
+ m_uiElderBrightleafGUID = 0;
+ m_uiElderStonebarkGUID = 0;
+ m_uiElderIronbrachGUID = 0;
+ m_uiSaroniteAnimusGUID = 0;
+ m_uiRunicColossusGUID = 0;
+ m_uiRuneGiantGUID = 0;
+ m_uiJormungarGUID = 0;
+ m_uiLeviathanMkGUID = 0;
+ m_uiHodirImageGUID = 0;
+ m_uiFreyaImageGUID = 0;
+ m_uiThorimImageGUID = 0;
+ m_uiMimironImageGUID = 0;
+ m_uiSaraGUID = 0;
+ m_uiYoggBrainGUID = 0;
+
+ // loot
+ m_uiKologarnLootGUID = 0;
+ m_uiHodirLootGUID = 0;
+ m_uiHodirRareLootGUID = 0;
+ m_uiThorimLootGUID = 0;
+ m_uiThorimRareLootGUID = 0;
+ m_uiFreyaLootGUID = 0;
+ m_uiFreyaLoot1GUID = 0;
+ m_uiFreyaLoot2GUID = 0;
+ m_uiFreyaLoot3GUID = 0;
+ m_uiMimironLootGUID = 0;
+ m_uiMimironHardLootGUID = 0;
+ m_uiAlagonLootGUID = 0;
+
+ // doors
+ // The siege
+ m_uiShieldWallGUID = 0;
+ m_uiLeviathanGateGUID = 0;
+ m_uiXT002GateGUID = 0;
+ m_uiBrokenHarpoonGUID = 0;
+ // Archivum
+ m_uiIronCouncilDoorGUID = 0;
+ m_uiArchivumDoorGUID = 0;
+ m_uiArchivumConsoleGUID = 0;
+ m_uiUniverseFloorArchivumGUID = 0;
+ // Celestial planetarium
+ m_uiCelestialDoorGUID = 0;
+ m_uiCelestialConsoleGUID = 0;
+ m_uiUniverseFloorCelestialGUID = 0;
+ m_uiAzerothGlobeGUID = 0;
+ // Kologarn
+ m_uiShatteredHallsDoorGUID = 0;
+ m_uiKologarnBridgeGUID = 0;
+ // Hodir
+ m_uiHodirEnterDoorGUID = 0;
+ m_uiHodirWallGUID = 0;
+ m_uiHodirExitDoorGUID = 0;
+ // Mimiron
+ m_uiMimironTramGUID = 0;
+ m_uiMimironButtonGUID = 0;
+ m_uiMimironDoor1GUID = 0;
+ m_uiMimironDoor2GUID = 0;
+ m_uiMimironDoor3GUID = 0;
+ m_uiMimironElevatorGUID = 0;
+ // Thorim
+ m_uiArenaEnterDoorGUID = 0;
+ m_uiArenaExitDoorGUID = 0;
+ m_uiHallwayDoorGUID = 0;
+ m_uiThorimEnterDoorGUID = 0;
+ m_uiThorimLeverGUID = 0;
+ // Prison
+ m_uiAncientGateGUID = 0;
+ m_uiVezaxGateGUID = 0;
+ m_uiYoggGateGUID = 0;
+ m_uiBrainDoor1GUID = 0;
+ m_uiBrainDoor2GUID = 0;
+ m_uiBrainDoor3GUID = 0;
+ }
+
+ bool IsEncounterInProgress() const
{
- if (m_auiEncounter[i] == IN_PROGRESS)
- return true;
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ return true;
+ }
+
+ return false;
}
- return false;
-}
-void instance_ulduar::OnCreatureCreate(Creature* pCreature)
-{
- switch (pCreature->GetEntry())
+ void OnCreatureCreate(Creature* pCreature)
{
+ switch(pCreature->GetEntry())
+ {
case NPC_LEVIATHAN:
m_uiLeviathanGUID = pCreature->GetGUID();
break;
@@ -164,15 +278,18 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature)
case NPC_XT002:
m_uiXT002GUID = pCreature->GetGUID();
break;
+
+ // Assembly of Iron
case NPC_STEELBREAKER:
- m_uiSteelbreakerGUID = pCreature->GetGUID();
+ m_auiAssemblyGUIDs[0] = pCreature->GetGUID();
break;
case NPC_MOLGEIM:
- m_uiMolgeimGUID = pCreature->GetGUID();
+ m_auiAssemblyGUIDs[1] = pCreature->GetGUID();
break;
case NPC_BRUNDIR:
- m_uiBrundirGUID = pCreature->GetGUID();
+ m_auiAssemblyGUIDs[2] = pCreature->GetGUID();
break;
+
case NPC_KOLOGARN:
m_uiKologarnGUID = pCreature->GetGUID();
break;
@@ -190,21 +307,15 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature)
break;
case NPC_MIMIRON:
m_uiMimironGUID = pCreature->GetGUID();
- if(m_auiEncounter[7] == DONE)
- SpawnFriendlyKeeper(NPC_MIMIRON_IMAGE);
break;
case NPC_LEVIATHAN_MK:
m_uiLeviathanMkGUID = pCreature->GetGUID();
break;
case NPC_HODIR:
m_uiHodirGUID = pCreature->GetGUID();
- if(m_auiEncounter[8] == DONE)
- SpawnFriendlyKeeper(NPC_HODIR_IMAGE);
break;
case NPC_THORIM:
m_uiThorimGUID = pCreature->GetGUID();
- if(m_auiEncounter[9] == DONE)
- SpawnFriendlyKeeper(NPC_THORIM_IMAGE);
break;
case NPC_RUNIC_COLOSSUS:
m_uiRunicColossusGUID = pCreature->GetGUID();
@@ -217,22 +328,20 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature)
break;
case NPC_FREYA:
m_uiFreyaGUID = pCreature->GetGUID();
- if(m_auiEncounter[10] == DONE)
- SpawnFriendlyKeeper(NPC_FREYA_IMAGE);
break;
- case NPC_ELDER_BRIGHTLEAF:
+ case NPC_BRIGHTLEAF:
m_uiElderBrightleafGUID = pCreature->GetGUID();
break;
- case NPC_ELDER_IRONBRACH:
+ case NPC_IRONBRACH:
m_uiElderIronbrachGUID = pCreature->GetGUID();
break;
- case NPC_ELDER_STONEBARK:
+ case NPC_STONEBARK:
m_uiElderStonebarkGUID = pCreature->GetGUID();
break;
case NPC_VEZAX:
m_uiVezaxGUID = pCreature->GetGUID();
break;
- case NPC_SARONITE_ANIMUS:
+ case NPC_ANIMUS:
m_uiSaroniteAnimusGUID = pCreature->GetGUID();
break;
case NPC_YOGGSARON:
@@ -247,28 +356,54 @@ void instance_ulduar::OnCreatureCreate(Creature* pCreature)
case NPC_ALGALON:
m_uiAlgalonGUID = pCreature->GetGUID();
break;
- }
-}
+ // used to handle the keepers images
+ // set to invisible by default and only made visible if the encounter is done
+ case HODIR_IMAGE:
+ m_uiHodirImageGUID = pCreature->GetGUID();
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ if(m_auiEncounter[8] == DONE)
+ pCreature->SetVisibility(VISIBILITY_ON);
+ break;
+ case FREYA_IMAGE:
+ m_uiFreyaImageGUID = pCreature->GetGUID();
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ if(m_auiEncounter[10] == DONE)
+ pCreature->SetVisibility(VISIBILITY_ON);
+ break;
+ case THORIM_IMAGE:
+ m_uiThorimImageGUID = pCreature->GetGUID();
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ if(m_auiEncounter[9] == DONE)
+ pCreature->SetVisibility(VISIBILITY_ON);
+ break;
+ case MIMIRON_IMAGE:
+ m_uiMimironImageGUID = pCreature->GetGUID();
+ pCreature->SetVisibility(VISIBILITY_OFF);
+ if(m_auiEncounter[7] == DONE)
+ pCreature->SetVisibility(VISIBILITY_ON);
+ break;
+ }
+ }
-void instance_ulduar::OnObjectCreate(GameObject* pGo)
-{
- switch(pGo->GetEntry())
+ void OnObjectCreate(GameObject *pGo)
{
- // ----------------- Doors & Other -----------------
- // The siege
+ switch(pGo->GetEntry())
+ {
+ // doors & other
+ // The siege
case GO_SHIELD_WALL:
m_uiShieldWallGUID = pGo->GetGUID();
break;
case GO_LEVIATHAN_GATE:
m_uiLeviathanGateGUID = pGo->GetGUID();
- if (m_auiEncounter[0] == DONE)
+ if(m_auiEncounter[0] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_XT002_GATE:
pGo->SetGoState(GO_STATE_READY);
- if (m_auiEncounter[3] == DONE)
+ if(m_auiEncounter[3] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
- if (m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE)
+ if(m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
m_uiXT002GateGUID = pGo->GetGUID();
break;
@@ -277,13 +412,13 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo)
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
break;
- // Archivum
+ // Archivum
case GO_IRON_ENTRANCE_DOOR:
m_uiIronCouncilDoorGUID = pGo->GetGUID();
break;
case GO_ARCHIVUM_DOOR:
m_uiArchivumDoorGUID = pGo->GetGUID();
- if (m_auiEncounter[4])
+ if(m_auiEncounter[4])
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_ARCHIVUM_CONSOLE:
@@ -292,7 +427,7 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo)
case GO_UNIVERSE_FLOOR_ARCHIVUM:
m_uiUniverseFloorArchivumGUID = pGo->GetGUID();
break;
- // Celestial Planetarium
+ // Celestial Planetarium
case GO_CELESTIAL_ACCES:
m_uiCelestialConsoleGUID = pGo->GetGUID();
break;
@@ -305,34 +440,45 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo)
case GO_AZEROTH_GLOBE:
m_uiAzerothGlobeGUID = pGo->GetGUID();
break;
- // Shattered Hallway
+ // Shattered Hallway
case GO_KOLOGARN_BRIDGE:
m_uiKologarnBridgeGUID = pGo->GetGUID();
pGo->SetGoState(GO_STATE_ACTIVE);
- if (m_auiEncounter[5] == DONE)
+ if(m_auiEncounter[5] == DONE)
+ {
+ pGo->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
pGo->SetGoState(GO_STATE_READY);
+ }
break;
case GO_SHATTERED_DOOR:
m_uiShatteredHallsDoorGUID = pGo->GetGUID();
break;
- // ----------------- The Keepers -----------------
- // Hodir
+ // The keepers
+ // Hodir
case GO_HODIR_EXIT:
m_uiHodirExitDoorGUID = pGo->GetGUID();
- if (m_auiEncounter[8])
+ if(m_auiEncounter[8])
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_HODIR_ICE_WALL:
m_uiHodirWallGUID = pGo->GetGUID();
- if (m_auiEncounter[8])
+ if(m_auiEncounter[8])
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_HODIR_ENTER:
m_uiHodirEnterDoorGUID = pGo->GetGUID();
break;
- // Mimiron
- case G0_MIMIRON_BUTTON:
+ // Mimiron
+ case GO_MIMIRON_TRAM:
+ m_uiMimironTramGUID = pGo->GetGUID();
+ if (m_auiEncounter[6] == DONE)
+ {
+ pGo->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
+ pGo->SetGoState(GO_STATE_READY);
+ }
+ break;
+ case GO_MIMIRON_BUTTON:
m_uiMimironButtonGUID = pGo->GetGUID();
if (m_auiEncounter[7] == NOT_STARTED)
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
@@ -350,33 +496,33 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo)
m_uiMimironElevatorGUID = pGo->GetGUID();
break;
case GO_MIMIRON_TEL1:
- m_auiMimironTelGUID[0] = pGo->GetGUID();
+ m_uiMimironTelGUID[0] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL2:
- m_auiMimironTelGUID[1] = pGo->GetGUID();
+ m_uiMimironTelGUID[1] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL3:
- m_auiMimironTelGUID[2] = pGo->GetGUID();
+ m_uiMimironTelGUID[2] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL4:
- m_auiMimironTelGUID[3] = pGo->GetGUID();
+ m_uiMimironTelGUID[3] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL5:
- m_auiMimironTelGUID[4] = pGo->GetGUID();
+ m_uiMimironTelGUID[4] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL6:
- m_auiMimironTelGUID[5] = pGo->GetGUID();
+ m_uiMimironTelGUID[5] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL7:
- m_auiMimironTelGUID[6] = pGo->GetGUID();
+ m_uiMimironTelGUID[6] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL8:
- m_auiMimironTelGUID[7] = pGo->GetGUID();
+ m_uiMimironTelGUID[7] = pGo->GetGUID();
break;
case GO_MIMIRON_TEL9:
- m_auiMimironTelGUID[8] = pGo->GetGUID();
+ m_uiMimironTelGUID[8] = pGo->GetGUID();
break;
- // Thorim
+ // Thorim
case GO_DARK_IRON_PORTCULIS:
m_uiArenaExitDoorGUID = pGo->GetGUID();
break;
@@ -394,15 +540,15 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo)
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
break;
- // Prison
+ // Prison
case GO_ANCIENT_GATE:
m_uiAncientGateGUID = pGo->GetGUID();
- DoOpenMadnessDoorIfCan();
+ OpenMadnessDoor();
break;
case GO_VEZAX_GATE:
m_uiVezaxGateGUID = pGo->GetGUID();
pGo->SetGoState(GO_STATE_READY);
- if (m_auiEncounter[11])
+ if(m_auiEncounter[11])
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_YOGG_GATE:
@@ -418,119 +564,216 @@ void instance_ulduar::OnObjectCreate(GameObject* pGo)
m_uiBrainDoor3GUID = pGo->GetGUID();
break;
- // ----------------- Chests -----------------
- // Kologarn
+ // loot
+ // Kologarn
case GO_CACHE_OF_LIVING_STONE:
+ if(Regular)
+ m_uiKologarnLootGUID = pGo->GetGUID();
+ break;
case GO_CACHE_OF_LIVING_STONE_H:
- m_uiKologarnLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiKologarnLootGUID = pGo->GetGUID();
break;
- // Hodir
+ // Hodir
case GO_CACHE_OF_WINTER:
+ if(Regular)
+ m_uiHodirLootGUID = pGo->GetGUID();
+ break;
case GO_CACHE_OF_WINTER_H:
- m_uiHodirLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiHodirLootGUID = pGo->GetGUID();
break;
+ // Hodir rare
case GO_CACHE_OF_RARE_WINTER:
+ if(Regular)
+ m_uiHodirRareLootGUID = pGo->GetGUID();
+ break;
case GO_CACHE_OF_RARE_WINTER_H:
- m_uiHodirRareLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiHodirRareLootGUID = pGo->GetGUID();
break;
- // Thorim
+ // Freya
+ case GO_FREYA_GIFT:
+ if(Regular)
+ m_uiFreyaLootGUID = pGo->GetGUID();
+ break;
+ case GO_FREYA_GIFT_H:
+ if(!Regular)
+ m_uiFreyaLootGUID = pGo->GetGUID();
+ break;
+ // Freya rare
+ case GO_FREYA_GIFT_1:
+ if(Regular)
+ m_uiFreyaLoot1GUID = pGo->GetGUID();
+ break;
+ case GO_FREYA_GIFT_H_1:
+ if(!Regular)
+ m_uiFreyaLoot1GUID = pGo->GetGUID();
+ break;
+ case GO_FREYA_GIFT_2:
+ if(Regular)
+ m_uiFreyaLoot2GUID = pGo->GetGUID();
+ break;
+ case GO_FREYA_GIFT_H_2:
+ if(!Regular)
+ m_uiFreyaLoot2GUID = pGo->GetGUID();
+ break;
+ case GO_FREYA_GIFT_3:
+ if(Regular)
+ m_uiFreyaLoot3GUID = pGo->GetGUID();
+ break;
+ case GO_FREYA_GIFT_H_3:
+ if(!Regular)
+ m_uiFreyaLoot3GUID = pGo->GetGUID();
+ break;
+
+ // Thorim
case GO_CACHE_OF_STORMS:
+ if(Regular)
+ m_uiThorimLootGUID = pGo->GetGUID();
+ break;
case GO_CACHE_OF_STORMS_H:
- m_uiThorimLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiThorimLootGUID = pGo->GetGUID();
break;
+ // Thorim rare
case GO_CACHE_OF_RARE_STORMS:
+ if(Regular)
+ m_uiThorimRareLootGUID = pGo->GetGUID();
+ break;
case GO_CACHE_OF_RARE_STORMS_H:
- m_uiThorimRareLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiThorimRareLootGUID = pGo->GetGUID();
break;
- // Mimiron
+ // Mimiron
case GO_CACHE_OF_INOV:
+ if(Regular)
+ m_uiMimironLootGUID = pGo->GetGUID();
+ break;
case GO_CACHE_OF_INOV_H:
- m_uiMimironLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiMimironLootGUID = pGo->GetGUID();
break;
case GO_CACHE_OF_INOV_HARD:
+ if(Regular)
+ m_uiMimironHardLootGUID = pGo->GetGUID();
+ break;
case GO_CACHE_OF_INOV_HARD_H:
- m_uiMimironHardLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiMimironHardLootGUID = pGo->GetGUID();
break;
- // Alagon
+ // Alagon
case GO_GIFT_OF_OBSERVER:
+ if(Regular)
+ m_uiAlagonLootGUID = pGo->GetGUID();
+ break;
case GO_GIFT_OF_OBSERVER_H:
- m_uiAlagonLootGUID = pGo->GetGUID();
+ if(!Regular)
+ m_uiAlagonLootGUID = pGo->GetGUID();
break;
+ }
}
-}
-Player* instance_ulduar::GetPlayerInMap()
-{
- Map::PlayerList const& players = instance->GetPlayers();
+ // functions to open or close some doors
+ void OpenDoor(uint64 guid)
+ {
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_ACTIVE);
+ }
- if (!players.isEmpty())
+ void CloseDoor(uint64 guid)
{
- for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- {
- if (Player* plr = itr->getSource())
- return plr;
- }
+ if(!guid) return;
+ GameObject* pGo = instance->GetGameObject(guid);
+ if(pGo) pGo->SetGoState(GO_STATE_READY);
}
- return NULL;
-}
-// Used in order to unlock the door to Vezax
-void instance_ulduar::DoOpenMadnessDoorIfCan()
-{
- if (m_auiEncounter[TYPE_MIMIRON] == DONE && m_auiEncounter[TYPE_HODIR] == DONE && m_auiEncounter[TYPE_THORIM] == DONE && m_auiEncounter[TYPE_FREYA] == DONE)
+ // used in order to unlock the door to Vezax and make vezax attackable
+ void OpenMadnessDoor()
{
- if (GameObject* pDoor = instance->GetGameObject(m_uiAncientGateGUID))
- pDoor->SetGoState(GO_STATE_ACTIVE);
+ if(m_auiEncounter[7] == DONE && m_auiEncounter[8] == DONE && m_auiEncounter[9] == DONE && m_auiEncounter[10] == DONE)
+ OpenDoor(m_uiAncientGateGUID);
+ OpenDoor(m_uiAncientGateGUID);
}
-}
-void instance_ulduar::SetData(uint32 uiType, uint32 uiData)
-{
- switch (uiType)
+ // used to open the door to XT (custom script because Leviathan is disabled)
+ // this will be removed when the Leviathan will be implemented
+ void OpenXtDoor()
+ {
+ if(m_auiEncounter[1] == DONE && m_auiEncounter[2] == DONE)
+ OpenDoor(m_uiXT002GateGUID);
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
{
+ switch(uiType)
+ {
case TYPE_LEVIATHAN:
m_auiEncounter[0] = uiData;
DoUseDoorOrButton(m_uiShieldWallGUID);
if (uiData == DONE)
{
- DoUseDoorOrButton(m_uiXT002GateGUID);
- DoUseDoorOrButton(m_uiLeviathanGateGUID);
+ OpenDoor(m_uiXT002GateGUID);
+ OpenDoor(m_uiLeviathanGateGUID);
}
break;
case TYPE_IGNIS:
m_auiEncounter[1] = uiData;
+ OpenXtDoor(); // remove when leviathan implemented
break;
case TYPE_RAZORSCALE:
m_auiEncounter[2] = uiData;
+ OpenXtDoor(); // remove when leviathan implemented
break;
case TYPE_XT002:
m_auiEncounter[3] = uiData;
- DoUseDoorOrButton(m_uiXT002GateGUID);
+ if (uiData == DONE)
+ OpenDoor(m_uiXT002GateGUID);
+ else if (uiData == IN_PROGRESS)
+ CloseDoor(m_uiXT002GateGUID);
break;
case TYPE_ASSEMBLY:
m_auiEncounter[4] = uiData;
- DoUseDoorOrButton(m_uiIronCouncilDoorGUID);
if (uiData == DONE)
- DoUseDoorOrButton(m_uiArchivumDoorGUID);
+ {
+ OpenDoor(m_uiIronCouncilDoorGUID);
+ OpenDoor(m_uiArchivumDoorGUID);
+ CheckIronCouncil(); // used for a hacky achiev, remove for revision!
+ } else if (uiData == IN_PROGRESS)
+ CloseDoor(m_uiIronCouncilDoorGUID);
break;
case TYPE_KOLOGARN:
m_auiEncounter[5] = uiData;
- DoUseDoorOrButton(m_uiShatteredHallsDoorGUID);
if (uiData == DONE)
{
DoRespawnGameObject(m_uiKologarnLootGUID, 30*MINUTE);
- if(GameObject* pBridge = instance->GetGameObject(m_uiKologarnBridgeGUID))
- pBridge->SetGoState(GO_STATE_READY);
+ if(m_auiEncounter[5] == DONE)
+ if (GameObject* pGo = instance->GetGameObject(m_uiKologarnBridgeGUID))
+ {
+ pGo->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
+ pGo->SetGoState(GO_STATE_READY);
+ }
}
break;
case TYPE_AURIAYA:
m_auiEncounter[6] = uiData;
+ if (uiData == DONE)
+ {
+// CheckIronCouncil(); // used for a hacky achiev, remove for revision!
+ if (GameObject* pGO = instance->GetGameObject(m_uiMimironTramGUID))
+ {
+ pGO->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
+ pGO->SetGoState(GO_STATE_READY);
+ }
+ }
break;
- // Keepers
+
+ // Keepers
case TYPE_MIMIRON:
m_auiEncounter[7] = uiData;
DoUseDoorOrButton(m_uiMimironDoor1GUID);
@@ -538,9 +781,13 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData)
DoUseDoorOrButton(m_uiMimironDoor3GUID);
if (uiData == DONE)
{
- if (m_auiHardBoss[3] != DONE)
+ if(m_auiHardBoss[3] != DONE)
DoRespawnGameObject(m_uiMimironLootGUID, 30*MINUTE);
- SpawnFriendlyKeeper(NPC_MIMIRON_IMAGE);
+ // used to make the friendly keeper visible
+ if(Creature* pImage = instance->GetCreature(m_uiMimironImageGUID))
+ pImage->SetVisibility(VISIBILITY_ON);
+ OpenMadnessDoor();
+ CheckKeepers(); // used for a hacky achiev, remove for revision!
}
break;
case TYPE_HODIR:
@@ -551,27 +798,51 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData)
DoUseDoorOrButton(m_uiHodirWallGUID);
DoUseDoorOrButton(m_uiHodirExitDoorGUID);
DoRespawnGameObject(m_uiHodirLootGUID, 30*MINUTE);
- SpawnFriendlyKeeper(NPC_HODIR_IMAGE);
+ // used to make the friendly keeper visible
+ if(Creature* pImage = instance->GetCreature(m_uiHodirImageGUID))
+ pImage->SetVisibility(VISIBILITY_ON);
+ OpenMadnessDoor();
+ CheckKeepers(); // used for a hacky achiev, remove for revision!
}
break;
case TYPE_THORIM:
- m_auiEncounter[9] = uiData;
+ m_auiEncounter[9] = uiData;
DoUseDoorOrButton(m_uiArenaEnterDoorGUID);
if (uiData == IN_PROGRESS)
DoUseDoorOrButton(m_uiArenaExitDoorGUID);
if (uiData == DONE)
{
- if (m_auiHardBoss[5] != DONE)
+ if(m_auiHardBoss[5] != DONE)
DoRespawnGameObject(m_uiThorimLootGUID, 30*MINUTE);
- SpawnFriendlyKeeper(NPC_THORIM_IMAGE);
+ // used to make the friendly keeper visible
+ if(Creature* pImage = instance->GetCreature(m_uiThorimImageGUID))
+ pImage->SetVisibility(VISIBILITY_ON);
+ OpenMadnessDoor();
+ CheckKeepers(); // used for a hacky achiev, remove for revision!
}
break;
case TYPE_FREYA:
m_auiEncounter[10] = uiData;
if (uiData == DONE)
- SpawnFriendlyKeeper(NPC_FREYA_IMAGE);
+ {
+ // do this in order to see how many elders were alive and spawn the correct chest
+ if(m_auiHardBoss[6] == 0)
+ DoRespawnGameObject(m_uiFreyaLootGUID, 30*MINUTE);
+ else if(m_auiHardBoss[6] == 1)
+ DoRespawnGameObject(m_uiFreyaLoot1GUID, 30*MINUTE);
+ else if(m_auiHardBoss[6] == 2)
+ DoRespawnGameObject(m_uiFreyaLoot2GUID, 30*MINUTE);
+ else if(m_auiHardBoss[6] == 3)
+ DoRespawnGameObject(m_uiFreyaLoot3GUID, 30*MINUTE);
+ // used to make the friendly keeper visible
+ if(Creature* pImage = instance->GetCreature(m_uiFreyaImageGUID))
+ pImage->SetVisibility(VISIBILITY_ON);
+ OpenMadnessDoor();
+ CheckKeepers(); // used for a hacky achiev, remove for revision!
+ }
break;
- // Prison
+
+ // Prison
case TYPE_VEZAX:
m_auiEncounter[11] = uiData;
if (uiData == DONE)
@@ -582,52 +853,51 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData)
DoUseDoorOrButton(m_uiYoggGateGUID);
break;
- // Celestial Planetarium
+ // Celestial Planetarium
case TYPE_ALGALON:
m_auiEncounter[13] = uiData;
- //TODO: need to find the proper way to use these
DoUseDoorOrButton(m_uiCelestialDoorGUID);
DoUseDoorOrButton(m_uiUniverseFloorCelestialGUID);
if (uiData == DONE)
DoRespawnGameObject(m_uiAlagonLootGUID, 30*MINUTE);
break;
- // Hard modes
+ // Hard modes
case TYPE_LEVIATHAN_HARD:
- m_auiHardBoss[0] = uiData; // TODO: add extra loot
+ m_auiHardBoss[0] = uiData; // todo: add extra loot
break;
case TYPE_XT002_HARD:
- m_auiHardBoss[1] = uiData; // TODO: add extra loot
+ m_auiHardBoss[1] = uiData; // hard mode loot in sql -> hacky way
break;
case TYPE_HODIR_HARD:
m_auiHardBoss[4] = uiData;
- if (uiData == DONE)
+ if(uiData == DONE)
DoRespawnGameObject(m_uiHodirRareLootGUID, 30*MINUTE);
break;
case TYPE_ASSEMBLY_HARD:
- m_auiHardBoss[2] = uiData; // TODO: add extra loot
+ m_auiHardBoss[2] = uiData; // hard mode loot in sql
break;
case TYPE_FREYA_HARD:
- m_auiHardBoss[6] = uiData; // Hard mode loot in in script
+ m_auiHardBoss[6] = uiData; // hard mode loot in the script above
break;
case TYPE_THORIM_HARD:
m_auiHardBoss[5] = uiData;
- if (uiData == DONE)
+ if(uiData == DONE)
DoRespawnGameObject(m_uiThorimRareLootGUID, 30*MINUTE);
break;
case TYPE_MIMIRON_HARD:
m_auiHardBoss[3] = uiData;
- if (uiData == DONE)
+ if(uiData == DONE)
DoRespawnGameObject(m_uiMimironHardLootGUID, 30*MINUTE);
break;
case TYPE_VEZAX_HARD:
- m_auiHardBoss[7] = uiData; // TODO: add extra loot
+ m_auiHardBoss[7] = uiData; // hard mode loot in sql -> hacky way
break;
case TYPE_YOGGSARON_HARD:
- m_auiHardBoss[8] = uiData; // TODO: add extra loot
+ m_auiHardBoss[8] = uiData; // todo: add extra loot
break;
- // Ulduar keepers
+ // Ulduar keepers
case TYPE_KEEPER_HODIR:
m_auiUlduarKeepers[0] = uiData;
break;
@@ -641,7 +911,7 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData)
m_auiUlduarKeepers[3] = uiData;
break;
- // Teleporters
+ // teleporters
case TYPE_LEVIATHAN_TP:
m_auiUlduarTeleporters[0] = uiData;
break;
@@ -651,38 +921,81 @@ void instance_ulduar::SetData(uint32 uiType, uint32 uiData)
case TYPE_MIMIRON_TP:
m_auiUlduarTeleporters[2] = uiData;
break;
- }
- DoOpenMadnessDoorIfCan();
+ // mini boss
+ case TYPE_RUNIC_COLOSSUS:
+ m_auiMiniBoss[0] = uiData;
+ if (uiData == DONE)
+ OpenDoor(m_uiHallwayDoorGUID);
+ else
+ CloseDoor(m_uiHallwayDoorGUID);
+ break;
+ case TYPE_RUNE_GIANT:
+ m_auiMiniBoss[1] = uiData;
+ if (uiData == DONE)
+ OpenDoor(m_uiThorimEnterDoorGUID);
+ else
+ CloseDoor(m_uiThorimEnterDoorGUID);
+ break;
+ case TYPE_LEVIATHAN_MK:
+ m_auiMiniBoss[2] = uiData;
+ break;
+ case TYPE_VX001:
+ m_auiMiniBoss[3] = uiData;
+ if (uiData == DONE) // just for animation :)
+ {
+ for(uint8 i = 0; i < 9; i++)
+ DoUseDoorOrButton(m_uiMimironTelGUID[i]);
+ }
+ break;
+ case TYPE_AERIAL_UNIT:
+ m_auiMiniBoss[4] = uiData;
+ break;
+ case TYPE_YOGG_BRAIN:
+ m_auiMiniBoss[5] = uiData;
+ break;
+
+ //phases
+ case TYPE_MIMIRON_PHASE:
+ m_uiMimironPhase = uiData;
+ break;
+ case TYPE_YOGG_PHASE:
+ m_uiYoggPhase = uiData;
+ break;
+ case TYPE_VISION_PHASE:
+ m_uiVisionPhase = uiData;
+ break;
+ }
- if (uiData == DONE || uiData == FAIL)
- {
- OUT_SAVE_INST_DATA;
-
- // Save all encounters, hard bosses, keepers and teleporters
- std::ostringstream saveStream;
- saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
- << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
- << m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8] << " "
- << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11] << " "
- << m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiHardBoss[0] << " "
- << m_auiHardBoss[1] << " " << m_auiHardBoss[2] << " " << m_auiHardBoss[2] << " "
- << m_auiHardBoss[4] << " " << m_auiHardBoss[5] << " " << m_auiHardBoss[6] << " "
- << m_auiHardBoss[7] << " " << m_auiHardBoss[8] << " " << m_auiUlduarKeepers[0] << " "
- << m_auiUlduarKeepers[1] << " " << m_auiUlduarKeepers[2] << " " << m_auiUlduarKeepers[3];
-
- strInstData = saveStream.str();
-
- SaveToDB();
- OUT_SAVE_INST_DATA_COMPLETE;
+ if (uiData == DONE || uiData == FAIL)
+ {
+ OUT_SAVE_INST_DATA;
+
+ // save all encounters, hard bosses and keepers
+ std::ostringstream saveStream;
+ saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
+ << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
+ << m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8] << " "
+ << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11] << " "
+ << m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiHardBoss[0] << " "
+ << m_auiHardBoss[1] << " " << m_auiHardBoss[2] << " " << m_auiHardBoss[2] << " "
+ << m_auiHardBoss[4] << " " << m_auiHardBoss[5] << " " << m_auiHardBoss[6] << " "
+ << m_auiHardBoss[7] << " " << m_auiHardBoss[8] << " " << m_auiUlduarKeepers[0] << " "
+ << m_auiUlduarKeepers[1] << " " << m_auiUlduarKeepers[2] << " " << m_auiUlduarKeepers[3] << " "
+ << m_auiUlduarTeleporters[0] << " " << m_auiUlduarTeleporters[1] << " " << m_auiUlduarTeleporters[2];
+
+ m_strInstData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
}
-}
-uint64 instance_ulduar::GetData64(uint32 uiData)
-{
- switch (uiData)
+ uint64 GetData64(uint32 uiData)
{
- // Siege
+ switch(uiData)
+ {
+ // Siege
case NPC_LEVIATHAN:
return m_uiLeviathanGUID;
case NPC_IGNIS:
@@ -693,13 +1006,13 @@ uint64 instance_ulduar::GetData64(uint32 uiData)
return m_uiCommanderGUID;
case NPC_XT002:
return m_uiXT002GUID;
- // Antechamber
+ // Antechamber
case NPC_STEELBREAKER:
- return m_uiSteelbreakerGUID;
+ return m_auiAssemblyGUIDs[0];
case NPC_MOLGEIM:
- return m_uiMolgeimGUID;
+ return m_auiAssemblyGUIDs[1];
case NPC_BRUNDIR:
- return m_uiBrundirGUID;
+ return m_auiAssemblyGUIDs[2];
case NPC_KOLOGARN:
return m_uiKologarnGUID;
case NPC_LEFT_ARM:
@@ -708,7 +1021,7 @@ uint64 instance_ulduar::GetData64(uint32 uiData)
return m_uiRightArmGUID;
case NPC_AURIAYA:
return m_uiAuriayaGUID;
- // Keepers
+ // Keepers
case NPC_MIMIRON:
return m_uiMimironGUID;
case NPC_LEVIATHAN_MK:
@@ -725,11 +1038,11 @@ uint64 instance_ulduar::GetData64(uint32 uiData)
return m_uiJormungarGUID;
case NPC_FREYA:
return m_uiFreyaGUID;
- case NPC_ELDER_BRIGHTLEAF:
+ case NPC_BRIGHTLEAF:
return m_uiElderBrightleafGUID;
- case NPC_ELDER_IRONBRACH:
+ case NPC_IRONBRACH:
return m_uiElderIronbrachGUID;
- case NPC_ELDER_STONEBARK:
+ case NPC_STONEBARK:
return m_uiElderStonebarkGUID;
case NPC_VEZAX:
return m_uiVezaxGUID;
@@ -742,35 +1055,47 @@ uint64 instance_ulduar::GetData64(uint32 uiData)
case NPC_ALGALON:
return m_uiAlgalonGUID;
- // Mimiron hard mode button
- case G0_MIMIRON_BUTTON:
+ // mimiron hard mode button
+ case GO_MIMIRON_BUTTON:
return m_uiMimironButtonGUID;
- // Celestial door
+ // thorim encounter starter lever
+ case GO_DOOR_LEVER:
+ return m_uiThorimLeverGUID;
+ // celestial door
case GO_CELESTIAL_DOOR:
return m_uiCelestialDoorGUID;
- }
+ }
- return 0;
-}
+ return 0;
+ }
-// TODO: implement all hard mode loot here!
-bool instance_ulduar::CheckConditionCriteriaMeet(Player const* pSource, uint32 uiMapId, uint32 uiInstanceConditionId)
-{
- if (uiMapId != instance->GetId())
+ // TODO: implement all achievs here!
+ bool CheckAchievementCriteriaMeet(uint32 criteria_id, const Player *source)
+ {
+ switch(criteria_id)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ break;
+ }
return false;
+ }
- switch (uiInstanceConditionId)
- {
- case TYPE_XT002_HARD:
- break;
- }
- return false;
-}
+ // TODO: implement all hard mode loot here!
+ bool CheckConditionCriteriaMeet(Player const* source, uint32 map_id, uint32 instance_condition_id)
+ {
+ if (map_id != instance->GetId())
+ return false;
+ switch (instance_condition_id)
+ {
+ case TYPE_XT002_HARD:
+ break;
+ }
+ }
-uint32 instance_ulduar::GetData(uint32 uiType)
-{
- switch (uiType)
- {
+ uint32 GetData(uint32 uiType)
+ {
+ switch(uiType)
+ {
case TYPE_LEVIATHAN:
return m_auiEncounter[0];
case TYPE_IGNIS:
@@ -800,7 +1125,7 @@ uint32 instance_ulduar::GetData(uint32 uiType)
case TYPE_ALGALON:
return m_auiEncounter[13];
- // Hard modes
+ // hard modes
case TYPE_LEVIATHAN_HARD:
return m_auiHardBoss[0];
case TYPE_XT002_HARD:
@@ -820,7 +1145,7 @@ uint32 instance_ulduar::GetData(uint32 uiType)
case TYPE_YOGGSARON_HARD:
return m_auiHardBoss[8];
- // Ulduar Keepers
+ // ulduar keepers
case TYPE_KEEPER_HODIR:
return m_auiUlduarKeepers[0];
case TYPE_KEEPER_THORIM:
@@ -830,61 +1155,91 @@ uint32 instance_ulduar::GetData(uint32 uiType)
case TYPE_KEEPER_MIMIRON:
return m_auiUlduarKeepers[3];
- // Teleporters
+ // teleporters
case TYPE_LEVIATHAN_TP:
return m_auiUlduarTeleporters[0];
case TYPE_XT002_TP:
return m_auiUlduarTeleporters[1];
case TYPE_MIMIRON_TP:
return m_auiUlduarTeleporters[2];
- }
- return 0;
-}
+ // mini boss
+ case TYPE_RUNE_GIANT:
+ return m_auiMiniBoss[1];
+ case TYPE_RUNIC_COLOSSUS:
+ return m_auiMiniBoss[0];
+ case TYPE_LEVIATHAN_MK:
+ return m_auiMiniBoss[2];
+ case TYPE_VX001:
+ return m_auiMiniBoss[3];
+ case TYPE_AERIAL_UNIT:
+ return m_auiMiniBoss[4];
+ case TYPE_YOGG_BRAIN:
+ return m_auiMiniBoss[5];
-// Spawn the friendly keepers in the central chamber
-void instance_ulduar::SpawnFriendlyKeeper(uint32 uiWho)
-{
- Player* pPlayer = GetPlayerInMap();
- if (!pPlayer)
- return;
+ case TYPE_MIMIRON_PHASE:
+ return m_uiMimironPhase;
+ case TYPE_YOGG_PHASE:
+ return m_uiYoggPhase;
+ case TYPE_VISION_PHASE:
+ return m_uiVisionPhase;
+ }
- switch(uiWho)
- {
- case NPC_MIMIRON_IMAGE: pPlayer->SummonCreature(NPC_MIMIRON_IMAGE, m_aKeepersSpawnLocs[1].m_fX, m_aKeepersSpawnLocs[1].m_fY, m_aKeepersSpawnLocs[1].m_fZ, m_aKeepersSpawnLocs[1].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break;
- case NPC_HODIR_IMAGE: pPlayer->SummonCreature(NPC_HODIR_IMAGE, m_aKeepersSpawnLocs[2].m_fX, m_aKeepersSpawnLocs[2].m_fY, m_aKeepersSpawnLocs[2].m_fZ, m_aKeepersSpawnLocs[2].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break;
- case NPC_THORIM_IMAGE: pPlayer->SummonCreature(NPC_THORIM_IMAGE, m_aKeepersSpawnLocs[3].m_fX, m_aKeepersSpawnLocs[3].m_fY, m_aKeepersSpawnLocs[3].m_fZ, m_aKeepersSpawnLocs[3].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break;
- case NPC_FREYA_IMAGE: pPlayer->SummonCreature(NPC_FREYA_IMAGE, m_aKeepersSpawnLocs[0].m_fX, m_aKeepersSpawnLocs[0].m_fY, m_aKeepersSpawnLocs[0].m_fZ, m_aKeepersSpawnLocs[0].m_fO, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); break;
+ return 0;
}
-}
-void instance_ulduar::Load(const char* strIn)
-{
- if (!strIn)
+ const char* Save()
{
- OUT_LOAD_INST_DATA_FAIL;
- return;
+ return m_strInstData.c_str();
}
- OUT_LOAD_INST_DATA(strIn);
+ void Load(const char* strIn)
+ {
+ if (!strIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(strIn);
- std::istringstream loadStream(strIn);
- loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
+ std::istringstream loadStream(strIn);
+ loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
>> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7]
>> m_auiEncounter[8] >> m_auiEncounter[9] >> m_auiEncounter[10] >> m_auiEncounter[11]
>> m_auiEncounter[12] >> m_auiEncounter[13] >> m_auiHardBoss[0] >> m_auiHardBoss[1]
>> m_auiHardBoss[2] >> m_auiHardBoss[3] >> m_auiHardBoss[4] >> m_auiHardBoss[5]
>> m_auiHardBoss[6] >> m_auiHardBoss[7] >> m_auiHardBoss[8] >> m_auiUlduarKeepers[0]
- >> m_auiUlduarKeepers[1] >> m_auiUlduarKeepers[2] >> m_auiUlduarKeepers[3];
+ >> m_auiUlduarKeepers[1] >> m_auiUlduarKeepers[2] >> m_auiUlduarKeepers[3] >> m_auiUlduarTeleporters[0]
+ >> m_auiUlduarTeleporters[1] >> m_auiUlduarTeleporters[2];
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
- for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ // Hacky way of completing some achievs
+ // PLEASE REMOVE FOR REVISION!
+ void CheckIronCouncil()
{
- if (m_auiEncounter[i] == IN_PROGRESS)
- m_auiEncounter[i] = NOT_STARTED;
+ // check if the other bosses in the antechamber are dead
+ // hacky way to complete achievements; use only if you have this function
+ if(m_auiEncounter[4] == DONE && m_auiEncounter[5] == DONE && m_auiEncounter[6] == DONE)
+ DoCompleteAchievement(instance->IsRegularDifficulty() ? ACHIEV_IRON_COUNCIL : ACHIEV_IRON_COUNCIL_H);
}
- OUT_LOAD_INST_DATA_COMPLETE;
-}
+ void CheckKeepers()
+ {
+ // check if the other bosses in the antechamber are dead
+ // hacky way to complete achievements; use only if you have this function
+ if(m_auiEncounter[7] == DONE && m_auiEncounter[8] == DONE && m_auiEncounter[9] == DONE && m_auiEncounter[10] == DONE)
+ DoCompleteAchievement(instance->IsRegularDifficulty() ? ACHIEV_KEEPERS : ACHIEV_KEEPERS_H);
+ }
+};
InstanceData* GetInstanceData_instance_ulduar(Map* pMap)
{
@@ -893,10 +1248,9 @@ InstanceData* GetInstanceData_instance_ulduar(Map* pMap)
void AddSC_instance_ulduar()
{
- Script* pNewScript;
-
- pNewScript = new Script;
- pNewScript->Name = "instance_ulduar";
- pNewScript->GetInstanceData = &GetInstanceData_instance_ulduar;
- pNewScript->RegisterSelf();
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_ulduar";
+ newscript->GetInstanceData = &GetInstanceData_instance_ulduar;
+ newscript->RegisterSelf();
}
diff --git a/scripts/northrend/ulduar/ulduar/ulduar.cpp b/scripts/northrend/ulduar/ulduar/ulduar.cpp
index d7da144..96dd5c6 100644
--- a/scripts/northrend/ulduar/ulduar/ulduar.cpp
+++ b/scripts/northrend/ulduar/ulduar/ulduar.cpp
@@ -1,55 +1,201 @@
-/* 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
- */
+/* Copyright (C) 2006 - 2009 ScriptDev2
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
/* ScriptData
-SDName: ulduar
-SD%Complete: 0%
+SDName: Ulduar teleport
+SD%Complete:
SDComment:
SDCategory: Ulduar
EndScriptData */
#include "precompiled.h"
-#include "ulduar.h"
-
-/*#####
-## Teleporters
-#####*/
-enum TeleporterSpells
-{
- SPELL_TELE_EXPEDITION_BASE_CAMP = 64014,
- SPELL_TELE_FORMATION_GROUNDS = 64032,
- SPELL_TELE_COLOSSAL_FORGE = 64028,
- SPELL_TELE_SCRAPYARD = 64031,
- SPELL_TELE_ANTECHAMBER_OF_ULDUAR = 64030,
- SPELL_TELE_SHATTERED_WALKWAY = 64029,
- SPELL_TELE_CONSERVATORY_OF_LIFE = 64024,
- SPELL_TELE_SPARK_OF_IMAGINATION = 65061,
- SPELL_TELE_PRISON_OF_YOGG = 65042,
-};
-
-// Teleporter Gossip handled by SD2 because depending on Instance Data
-enum TeleporterGossipItems
-{
- GOSSIP_ITEM_TELE_BASE_CAMP = -3603000,
- GOSSIP_ITEM_TELE_FORMATION_GROUNDS = -3603001,
- GOSSIP_ITEM_TELE_COLOSSAR_FORGE = -3603002,
- GOSSIP_ITEM_TELE_SCRAPYARD = -3603003,
- GOSSIP_ITEM_TELE_ANTECHAMBER = -3603004,
- GOSSIP_ITEM_TELE_WALKWAY = -3603005,
- GOSSIP_ITEM_TELE_CONSERVATORY = -3603006,
- GOSSIP_ITEM_TELE_SPARK_IMAGINATION = -3603007,
- GOSSIP_ITEM_TELE_YOGG_SARON = -3603008,
-};
+#include "def_ulduar.h"
+
+#define REQUEST_HELP "Help me fight Yogg-Saron!"
+#define DENY_HELP "I don't need your help."
+
+/*
+* Here is the gossip for the keepers images
+* Each image appears in the centra chamber after the corrupted keeper is defeated
+* They should be spawned in script, but I added them into the DB by default as invisilbe
+* After the players make theyr choice if the want help or not, this option is saved and there is no turning back, until raid reset
+* If they are asked for help, at the beginning of the Yogg encounter each requested keeper will be summoned inside the chamber
+* There should be more text in the gossip menu, I couldn't find it anywhere yet
+*/
+
+/*#######
+*### Keepers images
+#######*/
+// HODIR
+bool GossipHello_hodir_image(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_HODIR) != DONE && m_pInstance->GetData(TYPE_KEEPER_HODIR) != FAIL)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_hodir_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_HODIR, DONE);
+ }
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_HODIR, FAIL);
+ }
+ return true;
+}
+
+// FREYA
+bool GossipHello_freya_image(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_FREYA) != DONE && m_pInstance->GetData(TYPE_KEEPER_FREYA) != FAIL)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_freya_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_FREYA, DONE);
+ }
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_FREYA, FAIL);
+ }
+ return true;
+}
+// MIMIRON
+bool GossipHello_mimiron_image(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_MIMIRON) != DONE && m_pInstance->GetData(TYPE_KEEPER_MIMIRON) != FAIL)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_mimiron_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_MIMIRON, DONE);
+ }
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_MIMIRON, FAIL);
+ }
+ return true;
+}
+
+// THORIM
+bool GossipHello_thorim_image(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+
+ if(m_pInstance && m_pInstance->GetData(TYPE_KEEPER_THORIM) != DONE && m_pInstance->GetData(TYPE_KEEPER_THORIM) != FAIL)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, REQUEST_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, DENY_HELP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_thorim_image(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ ScriptedInstance *m_pInstance = (ScriptedInstance *) pCreature->GetInstanceData();
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_THORIM, DONE);
+ }
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_KEEPER_THORIM, FAIL);
+ }
+ return true;
+}
+
+void AddSC_ulduar()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "hodir_image";
+ newscript->pGossipHello = &GossipHello_hodir_image;
+ newscript->pGossipSelect = &GossipSelect_hodir_image;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "freya_image";
+ newscript->pGossipHello = &GossipHello_freya_image;
+ newscript->pGossipSelect = &GossipSelect_freya_image;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "thorim_image";
+ newscript->pGossipHello = &GossipHello_thorim_image;
+ newscript->pGossipSelect = &GossipSelect_thorim_image;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mimiron_image";
+ newscript->pGossipHello = &GossipHello_mimiron_image;
+ newscript->pGossipSelect = &GossipSelect_mimiron_image;
+ newscript->RegisterSelf();
+
+}
diff --git a/scripts/northrend/ulduar/ulduar/ulduar_teleport.cpp b/scripts/northrend/ulduar/ulduar/ulduar_teleport.cpp
new file mode 100644
index 0000000..bc6d903
--- /dev/null
+++ b/scripts/northrend/ulduar/ulduar/ulduar_teleport.cpp
@@ -0,0 +1,119 @@
+/* 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: ulduar_teleport
+SD%Complete: 95%
+SDComment: by /dev/rsa
+SDCategory: Ulduar instance
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_ulduar.h"
+
+enum
+{
+ PORTALS_COUNT = 9,
+ TELEPORT_GOSSIP_MESSAGE = 14424,
+
+ // spells
+ SPELL_TELEPORT_BASE_CAMP = 64014,
+ SPELL_TELEPORT_GROUNDS = 64032,
+ SPELL_TELEPORT_FORGE = 64028,
+ SPELL_TELEPORT_SCRAPYARD = 64031,
+ SPELL_TELEPORT_ANTECHAMBER = 64030,
+ SPELL_TELEPORT_WALKWAY = 64029,
+ SPELL_TELEPORT_CONSERVATORY = 64024,
+ SPELL_TELEPORT_SPARK = 65061,
+ SPELL_TELEPORT_PRISON = 65042,
+};
+
+struct t_Locations
+{
+ int textNum;
+ uint32 map_num;
+ float x, y, z, o;
+ uint32 spellID;
+ bool state;
+ bool active;
+ uint32 encounter;
+};
+
+static t_Locations PortalLoc[]=
+{
+{-3050001,603, -706.122f, -92.6024f, 430.176f, 4.19f, SPELL_TELEPORT_BASE_CAMP, true,true, TYPE_LEVIATHAN}, // base camp
+{-3050002,603, 131.248f, -35.3802f, 410.104f, 0, SPELL_TELEPORT_GROUNDS, true,true, TYPE_LEVIATHAN_TP}, // formation ground
+{-3050003,603, 553.233f, -12.3247f, 409.979f, 0, SPELL_TELEPORT_FORGE, false,true,TYPE_LEVIATHAN}, //
+{-3050004,603, 926.292f, -11.4635f, 418.895f, 3.19f, SPELL_TELEPORT_SCRAPYARD, false,true,TYPE_XT002_TP}, //
+{-3050005,603, 1498.09f, -24.246f, 421.267f, 0, SPELL_TELEPORT_ANTECHAMBER, false,true,TYPE_XT002}, //
+{-3050006,603, 1859.45f, -24.1f, 449.2f, 0, SPELL_TELEPORT_WALKWAY, false,true,TYPE_KOLOGARN}, //
+{-3050007,603, 2086.27f, -24.3134f, 421.539f, 0, SPELL_TELEPORT_CONSERVATORY,false,true,TYPE_AURIAYA}, //
+{-3050008,603, 2517.3979f, 2568.89f, 412.99f, 6.17f, SPELL_TELEPORT_SPARK, false,true,TYPE_MIMIRON_TP}, //
+{-3050009,603, 1854.782f, -11.3819f, 335.27f, 5.86f, SPELL_TELEPORT_PRISON, false,true,TYPE_VEZAX}, //
+};
+
+
+bool GOGossipSelect_go_ulduar_teleporter(Player *pPlayer, GameObject* pGo, uint32 sender, uint32 action)
+{
+ int32 damage = 0;
+ if(sender != GOSSIP_SENDER_MAIN) return false;
+
+ if(!pPlayer->getAttackers().empty()) return false;
+
+ if(action >= 0 && action <= PORTALS_COUNT)
+ pPlayer->TeleportTo(PortalLoc[action].map_num, PortalLoc[action].x, PortalLoc[action].y, PortalLoc[action].z, PortalLoc[action].o);
+ if (PortalLoc[action].spellID != 0 )
+ if (SpellEntry const* spell = (SpellEntry *)GetSpellStore()->LookupEntry(PortalLoc[action].spellID))
+ {
+ SpellAuraHolder *holder = CreateSpellAuraHolder(spell, pPlayer, pPlayer);
+ Aura *aura = CreateAura(spell, EFFECT_INDEX_2, NULL, holder, pPlayer);
+ holder->AddAura(aura, EFFECT_INDEX_2);
+ pPlayer->AddSpellAuraHolder(holder);
+ }
+
+ pPlayer->CLOSE_GOSSIP_MENU();
+ return true;
+}
+
+bool GOGossipHello_go_ulduar_teleporter(Player *pPlayer, GameObject* pGo)
+{
+ ScriptedInstance *pInstance = (ScriptedInstance *) pGo->GetInstanceData();
+
+ if (!pInstance || !pPlayer) return false;
+ if (pPlayer->isInCombat()) return true;
+
+ for(uint8 i = 0; i < PORTALS_COUNT; i++) {
+ if ((PortalLoc[i].active == true &&
+ (PortalLoc[i].state == true ||
+ pInstance->GetData(PortalLoc[i].encounter) == DONE ||
+ pInstance->GetData(PortalLoc[i].encounter) == IN_PROGRESS))
+ || pPlayer->isGameMaster())
+ pPlayer->ADD_GOSSIP_ITEM_ID(GOSSIP_ICON_TAXI, PortalLoc[i].textNum, GOSSIP_SENDER_MAIN, i);
+ };
+ pPlayer->SEND_GOSSIP_MENU(TELEPORT_GOSSIP_MESSAGE, pGo->GetGUID());
+ return true;
+}
+
+void AddSC_ulduar_teleport()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "go_ulduar_teleporter";
+ newscript->pGOGossipHello = &GOGossipHello_go_ulduar_teleporter;
+ newscript->pGOGossipSelect = &GOGossipSelect_go_ulduar_teleporter;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/vault_of_archavon/boss_archavon.cpp b/scripts/northrend/vault_of_archavon/boss_archavon.cpp
new file mode 100644
index 0000000..4410054
--- /dev/null
+++ b/scripts/northrend/vault_of_archavon/boss_archavon.cpp
@@ -0,0 +1,274 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Archavon_The_Stone_Watcher
+SD%Complete: 0%
+SDComment:
+SDCategory: Vault of Archavon
+EndScriptData */
+
+#include "precompiled.h"
+#include "vault_of_archavon.h"
+
+enum
+{
+ SPELL_ROCK_SHARDS_LEFT_N = 58695,
+ SPELL_ROCK_SHARDS_LEFT_H = 60883,
+ SPELL_ROCK_SHARDS_RIGHT_N = 58696,
+ SPELL_ROCK_SHARDS_RIGHT_H = 60884,
+ SPELL_CRUSHING_LEAP_N = 58963,
+ SPELL_CRUSHING_LEAP_H = 60895,
+ SPELL_STOMP_N = 58663,
+ SPELL_STOMP_H = 60880,
+ SPELL_IMPALE_DMG_N = 58666,
+ SPELL_IMPALE_DMG_H = 60882,
+ SPELL_IMPALE_STUN = 50839,
+ SPELL_BERSERK = 47008
+};
+
+struct MANGOS_DLL_DECL boss_archavonAI : public ScriptedAI
+{
+ boss_archavonAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ m_fDefaultMoveSpeed = pCreature->GetSpeedRate(MOVE_RUN);
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+ float m_fDefaultMoveSpeed;
+ uint32 m_uiEvadeCheckCooldown;
+
+ uint32 m_uiBerserkTimer;
+ uint32 m_uiRockShardsTimer;
+ bool m_bRockShardsInProgress;
+ uint32 m_uiRockShardsProgressTimer;
+ uint32 m_uiRockShardTimer;
+ bool m_bRLRockShard;
+ Unit* m_pRockShardsTarget;
+ uint32 m_uiCrushingLeapTimer;
+ Unit* m_pCrushingLeapTarget;
+ bool m_bCrushingLeapInProgress;
+ uint32 m_uiCrushingLeapSecureTimer;
+ uint32 m_uiStompTimer;
+ uint32 m_uiImpaleAfterStompTimer;
+ bool m_bImpaleInProgress;
+
+ void Reset()
+ {
+ m_uiEvadeCheckCooldown = 2000;
+ m_creature->SetSpeedRate(MOVE_RUN, m_fDefaultMoveSpeed);
+ m_uiBerserkTimer = 300000;
+ m_uiRockShardsTimer = 15000;
+ m_bRockShardsInProgress = false;
+ m_uiRockShardsProgressTimer = 3000;
+ m_uiRockShardTimer = 0;
+ m_bRLRockShard = true;
+ m_pRockShardsTarget = NULL;
+ m_uiCrushingLeapTimer = 30000;
+ m_pCrushingLeapTarget = NULL;
+ m_bCrushingLeapInProgress = false;
+ m_uiCrushingLeapSecureTimer = 2000;
+ m_uiStompTimer = 45000;
+ m_uiImpaleAfterStompTimer = 1000;
+ m_bImpaleInProgress = false;
+
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_ARCHAVON, NOT_STARTED);
+ }
+
+ void Aggro(Unit *pWho)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_ARCHAVON, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if(m_pInstance)
+ m_pInstance->SetData(TYPE_ARCHAVON, DONE);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiEvadeCheckCooldown < uiDiff)
+ {
+ if (m_creature->GetDistance2d(140.34f, -102.34f) > 80.0f)
+ EnterEvadeMode();
+ m_uiEvadeCheckCooldown = 2000;
+ }
+ else
+ m_uiEvadeCheckCooldown -= uiDiff;
+
+ if (m_bImpaleInProgress)
+ {
+ if (m_uiImpaleAfterStompTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->getVictim())
+ {
+ DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_IMPALE_DMG_N : SPELL_IMPALE_DMG_H);
+ pTarget->CastSpell(pTarget, SPELL_IMPALE_STUN, true);
+ }
+ m_bImpaleInProgress = false;
+ }
+ else
+ {
+ m_uiImpaleAfterStompTimer -= uiDiff;
+ return;
+ }
+ }
+
+ if (m_bCrushingLeapInProgress)
+ {
+ if (m_pCrushingLeapTarget)
+ {
+ if (m_pCrushingLeapTarget->isDead() || !m_pCrushingLeapTarget->IsInWorld() && !m_pCrushingLeapTarget->IsInMap(m_creature))
+ {
+ m_bCrushingLeapInProgress = false;
+ return;
+ }
+ }
+ else
+ {
+ m_bCrushingLeapInProgress = false;
+ return;
+ }
+ if ((m_uiCrushingLeapSecureTimer < uiDiff) || (m_pCrushingLeapTarget && m_creature->IsWithinDist(m_pCrushingLeapTarget, 5.0f)))
+ {
+ m_creature->getThreatManager().addThreat(m_pCrushingLeapTarget, -100000000.0f);
+ m_creature->SetSpeedRate(MOVE_RUN, m_fDefaultMoveSpeed);
+ DoCastSpellIfCan(m_pCrushingLeapTarget, m_bIsRegularMode ? SPELL_CRUSHING_LEAP_N : SPELL_CRUSHING_LEAP_H, true);
+ m_bCrushingLeapInProgress = false;
+ }
+ else
+ m_uiCrushingLeapSecureTimer -= uiDiff;
+
+ return;
+ }
+
+ if (m_bRockShardsInProgress)
+ {
+ if (m_uiRockShardsProgressTimer < uiDiff)
+ {
+ m_bRockShardsInProgress = false;
+ if (m_pRockShardsTarget)
+ m_creature->getThreatManager().addThreat(m_pRockShardsTarget, -100000000.0f);
+ return;
+ }
+ else
+ m_uiRockShardsProgressTimer -= uiDiff;
+
+ if (m_uiRockShardTimer < uiDiff)
+ {
+ if (m_pRockShardsTarget && m_pRockShardsTarget->isAlive())
+ {
+ DoCast(m_pRockShardsTarget, m_bIsRegularMode ? (m_bRLRockShard ? SPELL_ROCK_SHARDS_LEFT_N : SPELL_ROCK_SHARDS_RIGHT_N) : (m_bRLRockShard ? SPELL_ROCK_SHARDS_LEFT_H : SPELL_ROCK_SHARDS_RIGHT_H));
+ m_bRLRockShard = !m_bRLRockShard;
+ }
+ m_uiRockShardTimer = 100;
+ }
+ else
+ m_uiRockShardsTimer -= uiDiff;
+
+ return;
+ }
+
+ if (m_uiRockShardsTimer < uiDiff)
+ {
+ m_bRockShardsInProgress = true;
+ m_uiRockShardsProgressTimer = 3000;
+ m_bRLRockShard = true;
+ m_pRockShardsTarget = NULL;
+ if (m_pRockShardsTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ m_creature->getThreatManager().addThreat(m_pRockShardsTarget, 100000000.0f);
+ m_uiRockShardsTimer = 15000+rand()%15000;
+ return;
+ }
+ else
+ m_uiRockShardsTimer -= uiDiff;
+
+ if (m_uiCrushingLeapTimer < uiDiff)
+ {
+ ThreatList const& tList = m_creature->getThreatManager().getThreatList();
+ std::list lTargets;
+ for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr)
+ {
+ Unit *pTemp = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());
+ if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && !m_creature->IsWithinDist(pTemp, 10.0f) && m_creature->IsWithinDist(pTemp, 80.0f))
+ lTargets.push_back(pTemp);
+ }
+ m_pCrushingLeapTarget = NULL;
+ if (!lTargets.empty())
+ {
+ std::list::iterator pTarget = lTargets.begin();
+ advance(pTarget, (rand() % lTargets.size()));
+ m_pCrushingLeapTarget = *pTarget;
+ if (m_pCrushingLeapTarget)
+ {
+ m_creature->MonsterSay(m_pCrushingLeapTarget->GetName(), LANG_UNIVERSAL);
+ m_creature->getThreatManager().addThreat(m_pCrushingLeapTarget, 100000000.0f);
+ m_creature->SetSpeedRate(MOVE_RUN, m_fDefaultMoveSpeed*10.0f);
+ m_bCrushingLeapInProgress = true;
+ m_uiCrushingLeapSecureTimer = 2000;
+ }
+ }
+ m_uiCrushingLeapTimer = 30000+rand()%15000;
+ return;
+ }
+ else
+ m_uiCrushingLeapTimer -= uiDiff;
+
+ if (m_uiStompTimer < uiDiff)
+ {
+ DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_STOMP_N : SPELL_STOMP_H);
+ m_uiImpaleAfterStompTimer = 1000;
+ m_bImpaleInProgress = true;
+ m_uiStompTimer = 45000+rand()%15000;
+ }
+ else
+ m_uiStompTimer -= uiDiff;
+
+ if (m_uiBerserkTimer < uiDiff)
+ {
+ DoCastSpellIfCan(m_creature, SPELL_BERSERK);
+ m_uiBerserkTimer = 60000;
+ }
+ else
+ m_uiBerserkTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_archavon(Creature *pCreature)
+{
+ return new boss_archavonAI (pCreature);
+};
+
+void AddSC_boss_archavon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_archavon";
+ newscript->GetAI = &GetAI_boss_archavon;
+ newscript->RegisterSelf();
+};
diff --git a/scripts/northrend/vault_of_archavon/boss_emalon.cpp b/scripts/northrend/vault_of_archavon/boss_emalon.cpp
new file mode 100644
index 0000000..4a0215b
--- /dev/null
+++ b/scripts/northrend/vault_of_archavon/boss_emalon.cpp
@@ -0,0 +1,445 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Emalon_The_Storm_Watcher
+SD%Complete: 0%
+SDComment:
+SDCategory: Vault of Archavon
+EndScriptData */
+
+#include "precompiled.h"
+#include "vault_of_archavon.h"
+
+enum
+{
+ // Emalon spells
+ SPELL_CHAIN_LIGHTNING_N = 64213,
+ SPELL_CHAIN_LIGHTNING_H = 64215,
+ SPELL_LIGHTNING_NOVA_N = 64216,
+ SPELL_LIGHTNING_NOVA_H = 65279,
+ SPELL_OVERCHARGE = 64379, //This spell is used by Time Warder, and temporary by Emalon, because 64218 is bugged
+ SPELL_BERSERK = 26662,
+
+ // Tempest Minion spells
+ SPELL_SHOCK = 64363,
+ SPELL_OVERCHARGED_BLAST = 64219,
+ SPELL_OVERCHARGED = 64217
+};
+
+/*######
+## npc_tempest_minion
+######*/
+
+struct MANGOS_DLL_DECL npc_tempest_minionAI : public ScriptedAI
+{
+ npc_tempest_minionAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_fDefaultX = m_creature->GetPositionX();
+ m_fDefaultY = m_creature->GetPositionY();
+ m_fDefaultZ = m_creature->GetPositionZ();
+ m_fDefaultO = m_creature->GetOrientation();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 m_uiEvadeCheckCooldown;
+
+ uint32 m_uiShockTimer;
+ uint32 m_uiRespawnTimer;
+ uint32 m_uiOverchargedStacksCheckTimer;
+ bool m_bDead;
+ bool m_bTimeToDie;
+ float m_fDefaultX;
+ float m_fDefaultY;
+ float m_fDefaultZ;
+ float m_fDefaultO;
+
+ void Init()
+ {
+ m_uiEvadeCheckCooldown = 2000;
+ m_uiShockTimer = 8000+rand()%4000;
+ m_bDead = false;
+ m_bTimeToDie = false;
+ m_uiRespawnTimer = 4000;
+ m_uiOverchargedStacksCheckTimer = 2000;
+
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ m_creature->SetVisibility(VISIBILITY_ON);
+ }
+
+ void Reset()
+ {
+ Init();
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ m_creature->CallForHelp(80.0f);
+ }
+
+ void FakeDeath()
+ {
+ m_bDead = true;
+ m_bTimeToDie = false;
+ m_uiRespawnTimer = 4000;
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->SetHealth(0);
+ m_creature->StopMoving();
+ m_creature->ClearComboPointHolders();
+ m_creature->RemoveAllAurasOnDeath();
+ m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
+ m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->ClearAllReactives();
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET,0);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+ m_creature->GetMap()->CreatureRelocation(m_creature, m_fDefaultX, m_fDefaultY, m_fDefaultZ, m_fDefaultO);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (uiDamage < m_creature->GetHealth())
+ return;
+
+ if (m_pInstance && (m_pInstance->GetData(TYPE_EMALON) != DONE))
+ {
+ uiDamage = 0;
+ FakeDeath();
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiEvadeCheckCooldown < uiDiff)
+ {
+ Creature* pEmalon = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_EMALON));
+ if ((pEmalon && pEmalon->IsInEvadeMode()) || (m_creature->GetDistance2d(-219.119f, -289.037f) > 80.0f))
+ {
+ EnterEvadeMode();
+ return;
+ }
+ m_uiEvadeCheckCooldown = 2000;
+ }
+ else
+ m_uiEvadeCheckCooldown -= uiDiff;
+
+ if (m_bTimeToDie)
+ {
+ FakeDeath();
+ return;
+ }
+
+ if (m_bDead)
+ {
+ if (m_uiRespawnTimer < uiDiff)
+ {
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ Init();
+ m_creature->MonsterTextEmote("%s appears to defend Emalon!", NULL, true);
+ m_creature->SetInCombatWithZone();
+ DoResetThreat();
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ m_creature->GetMotionMaster()->MoveChase(pTarget);
+ }
+ else
+ m_uiRespawnTimer -= uiDiff;
+
+ return;
+ }
+
+ if (m_uiOverchargedStacksCheckTimer < uiDiff)
+ {
+ m_uiOverchargedStacksCheckTimer = 2000;
+ Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, EFFECT_INDEX_0);
+ if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10)
+ {
+ DoCastSpellIfCan(m_creature, SPELL_OVERCHARGED_BLAST);
+ m_bTimeToDie = true;
+ return;
+ }
+ }
+ else
+ m_uiOverchargedStacksCheckTimer -= uiDiff;
+
+ if (m_uiShockTimer < uiDiff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK);
+ m_uiShockTimer = 8000+rand()%4000;
+ }
+ else
+ m_uiShockTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## boss_emalon
+######*/
+
+struct MANGOS_DLL_DECL boss_emalonAI : public ScriptedAI
+{
+ boss_emalonAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+ bool m_bIsRegularMode;
+ uint32 m_uiEvadeCheckCooldown;
+
+ uint64 m_auiTempestMinionGUID[4];
+ uint32 m_uiChainLightningTimer;
+ uint32 m_uiChainLightningCount;
+ uint32 m_uiLightningNovaTimer;
+ uint32 m_uiOverchargeTimer;
+ uint32 m_uiEnrageTimer;
+
+ void Reset()
+ {
+ m_uiEvadeCheckCooldown = 2000;
+ memset(&m_auiTempestMinionGUID, 0, sizeof(m_auiTempestMinionGUID));
+ m_uiChainLightningTimer = 15000;
+ m_uiChainLightningCount = 0;
+ m_uiLightningNovaTimer = 20000;
+ m_uiOverchargeTimer = 45000;
+ m_uiEnrageTimer = 360000;
+
+ if (m_pInstance)
+ {
+ m_auiTempestMinionGUID[0] = m_pInstance->GetData64(DATA_TEMPEST_MINION_1);
+ m_auiTempestMinionGUID[1] = m_pInstance->GetData64(DATA_TEMPEST_MINION_2);
+ m_auiTempestMinionGUID[2] = m_pInstance->GetData64(DATA_TEMPEST_MINION_3);
+ m_auiTempestMinionGUID[3] = m_pInstance->GetData64(DATA_TEMPEST_MINION_4);
+ }
+
+ for (uint8 i=0; i<4; ++i)
+ {
+ Creature* pMinion = m_creature->GetMap()->GetCreature( m_auiTempestMinionGUID[i]);
+ if (pMinion && pMinion->isDead())
+ pMinion->Respawn();
+ }
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_EMALON, NOT_STARTED);
+ }
+
+ void Aggro(Unit* pWho)
+ {
+ if (m_pInstance)
+ {
+ m_auiTempestMinionGUID[0] = m_pInstance->GetData64(DATA_TEMPEST_MINION_1);
+ m_auiTempestMinionGUID[1] = m_pInstance->GetData64(DATA_TEMPEST_MINION_2);
+ m_auiTempestMinionGUID[2] = m_pInstance->GetData64(DATA_TEMPEST_MINION_3);
+ m_auiTempestMinionGUID[3] = m_pInstance->GetData64(DATA_TEMPEST_MINION_4);
+ }
+
+ m_creature->CallForHelp(80.0f);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_EMALON, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_EMALON, DONE);
+ for (uint8 i=0; i<4; ++i)
+ {
+ Creature *pMinion = m_creature->GetMap()->GetCreature( m_auiTempestMinionGUID[i]);
+ if (pMinion)
+ pMinion->DealDamage(pMinion, pMinion->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_uiEvadeCheckCooldown < uiDiff)
+ {
+ if (m_creature->GetDistance2d(-219.119f, -289.037f) > 80.0f)
+ EnterEvadeMode();
+ m_creature->CallForHelp(80.0f);
+ m_uiEvadeCheckCooldown = 2000;
+ }
+ else
+ m_uiEvadeCheckCooldown -= uiDiff;
+
+ if (m_uiOverchargeTimer < uiDiff)
+ {
+ Creature* pMinion = m_creature->GetMap()->GetCreature( m_auiTempestMinionGUID[rand()%4]);
+ if(pMinion && pMinion->isAlive())
+ {
+ m_creature->MonsterTextEmote("%s overcharges Tempest Minion!",NULL, true);
+ pMinion->SetHealth(pMinion->GetMaxHealth());
+ pMinion->CastSpell(pMinion, SPELL_OVERCHARGE, false);
+ }
+ m_uiOverchargeTimer = 45000;
+ }
+ else
+ m_uiOverchargeTimer -= uiDiff;
+
+ if (m_uiChainLightningTimer < uiDiff)
+ {
+ if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING_N : SPELL_CHAIN_LIGHTNING_H);
+ m_uiChainLightningTimer = 10000 + rand()%15000;
+ }
+ else
+ m_uiChainLightningTimer -= uiDiff;
+
+ if (m_uiLightningNovaTimer < uiDiff)
+ {
+ DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_NOVA_N : SPELL_LIGHTNING_NOVA_H);
+ m_uiLightningNovaTimer = 45000;
+ }
+ else
+ m_uiLightningNovaTimer -= uiDiff;
+
+ if (m_uiEnrageTimer < uiDiff)
+ {
+ DoCastSpellIfCan(m_creature, SPELL_BERSERK);
+ m_uiEnrageTimer = 30000;
+ }
+ else
+ m_uiEnrageTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## npc_tempest_warder
+######*/
+
+struct MANGOS_DLL_DECL npc_tempest_warderAI : public ScriptedAI
+{
+ npc_tempest_warderAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiShockTimer;
+ bool m_bOvercharged;
+ uint32 m_uiOverchargedStacksCheckTimer;
+ bool m_bTimeToDie;
+
+ void Reset()
+ {
+ m_uiShockTimer = 8000+rand()%4000;
+ m_bOvercharged = false;
+ uint32 m_uiOverchargedStacksCheckTimer = 2000;
+ m_bTimeToDie = false;
+ }
+
+ void Aggro(Unit* pWho) {}
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if (m_bTimeToDie)
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ return;
+ }
+
+ if (!m_bOvercharged && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 37))
+ {
+ DoCastSpellIfCan(m_creature, SPELL_OVERCHARGE);
+ m_bOvercharged = true;
+ }
+
+ if (m_bOvercharged)
+ {
+ if (m_uiOverchargedStacksCheckTimer < uiDiff)
+ {
+ m_uiOverchargedStacksCheckTimer = 2000;
+ Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, EFFECT_INDEX_0);
+ if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10)
+ {
+ DoCastSpellIfCan(m_creature, SPELL_OVERCHARGED_BLAST);
+ m_bTimeToDie = true;
+ return;
+ }
+ }
+ else
+ m_uiOverchargedStacksCheckTimer -= uiDiff;
+ }
+
+ if (m_uiShockTimer < uiDiff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK);
+ m_uiShockTimer = 8000+rand()%4000;
+ }
+ else
+ m_uiShockTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_emalonAI(Creature* pCreature)
+{
+ return new boss_emalonAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_tempest_minionAI(Creature* pCreature)
+{
+ return new npc_tempest_minionAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_tempest_warderAI(Creature* pCreature)
+{
+ return new npc_tempest_warderAI(pCreature);
+}
+
+void AddSC_boss_emalon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_emalon";
+ newscript->GetAI = &GetAI_boss_emalonAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_tempest_minion";
+ newscript->GetAI = &GetAI_npc_tempest_minionAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_tempest_warder";
+ newscript->GetAI = &GetAI_npc_tempest_warderAI;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/vault_of_archavon/boss_koralon.cpp b/scripts/northrend/vault_of_archavon/boss_koralon.cpp
new file mode 100644
index 0000000..181d5fa
--- /dev/null
+++ b/scripts/northrend/vault_of_archavon/boss_koralon.cpp
@@ -0,0 +1,117 @@
+#include "precompiled.h"
+#include "vault_of_archavon.h"
+
+#define SP_BURNING_FURY_AURA 66895
+#define SP_BURNING_FURY_AURA2 68168
+#define SP_BURNING_FURY_EFFECT 66721
+
+#define SP_BURNING_BREATH 66665
+#define H_SP_BURNING_BREATH 67328 //DBM
+#define SP_BB_EFFECT 66670
+#define H_SP_BB_EFFECT 67329
+
+#define SP_METEOR_FISTS 66725 //DBM
+#define H_SP_METEOR_FISTS 68161
+#define SP_METEOR_FISTS_EFF 66765
+#define H_SP_METEOR_FISTS_EFF 67333
+
+#define SP_CINDER 66684
+#define H_SP_CINDER 67332
+
+struct MANGOS_DLL_DECL boss_koralonAI : public ScriptedAI
+{
+ boss_koralonAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Regular = pCreature->GetMap()->IsRegularDifficulty();
+ Reset();
+ }
+
+ ScriptedInstance* pInstance;
+ bool Regular;
+ uint32 BurningBreathTimer;
+ uint32 MeteorFistsTimer;
+ uint32 FlamesTimer;
+
+ uint32 BBTickTimer;
+ uint32 BBTicks;
+ bool BB;
+
+ void Reset()
+ {
+ BurningBreathTimer = 25000;
+ MeteorFistsTimer = 47000;
+ FlamesTimer = 15000;
+
+ BB = false;
+
+ if(pInstance) pInstance->SetData(TYPE_KORALON, NOT_STARTED);
+ }
+
+ void Aggro(Unit *who)
+ {
+ DoCastSpellIfCan(m_creature, SP_BURNING_FURY_AURA);
+
+ if(pInstance) pInstance->SetData(TYPE_KORALON, IN_PROGRESS);
+ };
+
+ void JustDied(Unit *killer)
+ {
+ if(pInstance) pInstance->SetData(TYPE_KORALON, DONE);
+ };
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(BurningBreathTimer < diff)
+ {
+ DoCastSpellIfCan(m_creature, Regular ? SP_BURNING_BREATH : H_SP_BURNING_BREATH);
+ BurningBreathTimer = 45000;
+
+ BB = true;
+ BBTickTimer = 1000;
+ BBTicks = 0;
+ }
+ else BurningBreathTimer -= diff;
+
+
+ if(FlamesTimer < diff)
+ {
+ int flames = Regular ? 3 : 5;
+ int i;
+ for(i=0; i< flames; ++i)
+ {
+ Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
+ if(target) DoCastSpellIfCan(target, Regular ? SP_CINDER : H_SP_CINDER);
+ }
+ FlamesTimer = 20000;
+ }
+ else FlamesTimer -= diff;
+
+ if(MeteorFistsTimer < diff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SP_METEOR_FISTS_EFF);
+ MeteorFistsTimer = 45000;
+ }
+ else MeteorFistsTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_koralonAI(Creature* pCreature)
+{
+ return new boss_koralonAI(pCreature);
+}
+
+void AddSC_boss_koralon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_koralon";
+ newscript->GetAI = &GetAI_boss_koralonAI;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/vault_of_archavon/boss_toravon.cpp b/scripts/northrend/vault_of_archavon/boss_toravon.cpp
new file mode 100644
index 0000000..febca32
--- /dev/null
+++ b/scripts/northrend/vault_of_archavon/boss_toravon.cpp
@@ -0,0 +1,122 @@
+/* ScriptData
+SDName: Toravon the Ice Watcher
+SDAuthor: Lutik
+SD%Complete: 0%
+SDComment:
+SDCategory: Vault of Archavon
+EndScriptData */
+
+#include "precompiled.h"
+#include "vault_of_archavon.h"
+
+enum
+{
+ SP_WHITEOUT = 72034,
+ H_SP_WHITEOUT = 72096,
+ SP_FREEZING_GROUND = 72090,
+ H_SP_FREEZING_GROUND = 72104,
+ SP_FROZEN_MALLET = 71993,
+ FROZEN_ORB_AURA = 72081,
+
+ CR_FROZEN_ORB = 38456
+};
+
+
+struct MANGOS_DLL_DECL boss_toravonAI : public ScriptedAI
+{
+ boss_toravonAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
+ orbsNum = m_bIsRegularMode ? 1 : 3;
+ pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
+ Reset();
+ }
+
+ bool m_bIsRegularMode;
+ ScriptedInstance *pInstance;
+
+ int orbsNum;
+ uint32 WhiteoutTimer;
+ uint32 OrbsTimer;
+ uint32 FreezeTimer;
+
+ void Reset()
+ {
+ WhiteoutTimer = 40000;
+ OrbsTimer = 15000;
+ FreezeTimer = 20000 + rand()%5000;
+
+ if(pInstance)
+ pInstance->SetData(TYPE_TORAVON, NOT_STARTED);
+ }
+
+ void Aggro(Unit *who)
+ {
+ DoCastSpellIfCan(m_creature, SP_FROZEN_MALLET);
+
+ if(pInstance)
+ pInstance->SetData(TYPE_TORAVON, IN_PROGRESS);
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if(pInstance)
+ pInstance->SetData(TYPE_TORAVON, DONE);
+ }
+
+ void JustSummoned(Creature *orb)
+ {
+ orb->CastSpell(orb, FROZEN_ORB_AURA, false);
+ orb->SetInCombatWithZone();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+ return;
+
+ if(WhiteoutTimer < diff)
+ {
+ DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SP_WHITEOUT : H_SP_WHITEOUT);
+ WhiteoutTimer = 40000;
+ }
+ else
+ WhiteoutTimer -= diff;
+
+ if(OrbsTimer < diff)
+ {
+ for(int i=0; iSelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
+ m_creature->SummonCreature(CR_FROZEN_ORB, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
+ }
+ OrbsTimer = 40000;
+ }
+ else
+ OrbsTimer -= diff;
+
+ if(FreezeTimer < diff)
+ {
+ DoCastSpellIfCan(m_creature, SP_FREEZING_GROUND);
+ FreezeTimer = 20000 + rand()%5000;
+ }
+ else
+ FreezeTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_toravon(Creature *pCreature)
+{
+ return new boss_toravonAI (pCreature);
+};
+
+void AddSC_boss_toravon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_toravon";
+ newscript->GetAI = &GetAI_boss_toravon;
+ newscript->RegisterSelf();
+};
diff --git a/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp b/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp
new file mode 100644
index 0000000..f0db618
--- /dev/null
+++ b/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp
@@ -0,0 +1,210 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Instance_Vault_of_Archavon
+SD%Complete: 0
+SDComment:
+SDCategory: Vault of Archavon
+EndScriptData */
+
+#include "precompiled.h"
+#include "vault_of_archavon.h"
+
+struct MANGOS_DLL_DECL instance_vault_of_archavon : public ScriptedInstance
+{
+ instance_vault_of_archavon(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+ std::string strInstData;
+
+ uint64 m_uiArchavonGUID;
+ uint64 m_uiEmalonGUID;
+ uint64 m_uiKoralonGUID;
+ uint64 m_uiTempestMinion1GUID;
+ uint64 m_uiTempestMinion2GUID;
+ uint64 m_uiTempestMinion3GUID;
+ uint64 m_uiTempestMinion4GUID;
+ uint8 m_uiMinion;
+
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ m_uiArchavonGUID = 0;
+ m_uiEmalonGUID = 0;
+ m_uiKoralonGUID = 0;
+ m_uiTempestMinion1GUID = 0;
+ m_uiTempestMinion2GUID = 0;
+ m_uiTempestMinion3GUID = 0;
+ m_uiTempestMinion4GUID = 0;
+ m_uiMinion = 0;
+ }
+
+ void OnCreatureCreate(Creature* pCreature)
+ {
+ switch (pCreature->GetEntry())
+ {
+ case NPC_ARCHAVON:
+ m_uiArchavonGUID = pCreature->GetGUID();
+ break;
+ case NPC_EMALON:
+ m_uiEmalonGUID = pCreature->GetGUID();
+ break;
+ case NPC_KORALON:
+ m_uiKoralonGUID = pCreature->GetGUID();
+ break;
+ case NPC_TEMPEST_MINION:
+ ++m_uiMinion;
+ switch (m_uiMinion)
+ {
+ case 1:
+ m_uiTempestMinion1GUID = pCreature->GetGUID();
+ break;
+ case 2:
+ m_uiTempestMinion2GUID = pCreature->GetGUID();
+ break;
+ case 3:
+ m_uiTempestMinion3GUID = pCreature->GetGUID();
+ break;
+ case 4:
+ m_uiTempestMinion4GUID = pCreature->GetGUID();
+ break;
+ case 5:
+ m_uiMinion = 0;
+ break;
+ }
+ break;
+ }
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ switch (uiType)
+ {
+ case TYPE_ARCHAVON:
+ m_auiEncounter[0] = uiData;
+ break;
+ case TYPE_EMALON:
+ m_auiEncounter[1] = uiData;
+ break;
+ case TYPE_KORALON:
+ m_auiEncounter[2] = uiData;
+ break;
+ case TYPE_TORAVON:
+ m_auiEncounter[3] = uiData;
+ break;
+ }
+
+ if (uiData == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
+
+ strInstData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint32 GetData(uint32 uiType)
+ {
+ switch (uiType)
+ {
+ case TYPE_ARCHAVON:
+ return m_auiEncounter[0];
+ case TYPE_EMALON:
+ return m_auiEncounter[1];
+ case TYPE_KORALON:
+ return m_auiEncounter[2];
+ case TYPE_TORAVON:
+ return m_auiEncounter[3];
+ }
+ return 0;
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch (uiData)
+ {
+ case DATA_ARCHAVON:
+ return m_uiArchavonGUID;
+ case DATA_EMALON:
+ return m_uiEmalonGUID;
+ case DATA_KORALON:
+ return m_uiKoralonGUID;
+ case DATA_TEMPEST_MINION_1:
+ return m_uiTempestMinion1GUID;
+ case DATA_TEMPEST_MINION_2:
+ return m_uiTempestMinion2GUID;
+ case DATA_TEMPEST_MINION_3:
+ return m_uiTempestMinion3GUID;
+ case DATA_TEMPEST_MINION_4:
+ return m_uiTempestMinion4GUID;
+ }
+ return 0;
+ }
+ const char* Save()
+ {
+ return strInstData.c_str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ std::istringstream loadStream(in);
+ loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3];
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ return true;
+ return false;
+ }
+};
+
+InstanceData* GetInstanceData_instance_vault_of_archavon(Map* pMap)
+{
+ return new instance_vault_of_archavon(pMap);
+}
+
+void AddSC_instance_vault_of_archavon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_vault_of_archavon";
+ newscript->GetInstanceData = &GetInstanceData_instance_vault_of_archavon;
+ newscript->RegisterSelf();
+}
diff --git a/scripts/northrend/vault_of_archavon/vault_of_archavon.h b/scripts/northrend/vault_of_archavon/vault_of_archavon.h
new file mode 100644
index 0000000..3267282
--- /dev/null
+++ b/scripts/northrend/vault_of_archavon/vault_of_archavon.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_VAULT_OF_ARCHAVON_H
+#define DEF_VAULT_OF_ARCHAVON_H
+
+enum
+{
+ MAX_ENCOUNTER = 4,
+
+ DATA_ARCHAVON = 1,
+ DATA_EMALON = 2,
+ DATA_KORALON = 3,
+ DATA_TEMPEST_MINION_1 = 4,
+ DATA_TEMPEST_MINION_2 = 5,
+ DATA_TEMPEST_MINION_3 = 6,
+ DATA_TEMPEST_MINION_4 = 7,
+
+ TYPE_ARCHAVON = 8,
+ TYPE_EMALON = 9,
+ TYPE_KORALON = 10,
+ TYPE_TORAVON = 11,
+
+ NPC_ARCHAVON = 31125,
+ NPC_EMALON = 33993,
+ NPC_KORALON = 35013,
+ NPC_TEMPEST_MINION = 33998
+};
+
+#endif
diff --git a/scripts/northrend/violet_hold/def_violet_hold.h b/scripts/northrend/violet_hold/def_violet_hold.h
new file mode 100644
index 0000000..1ba5264
--- /dev/null
+++ b/scripts/northrend/violet_hold/def_violet_hold.h
@@ -0,0 +1,195 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_VIOLET_HOLD_H
+#define DEF_VIOLET_HOLD_H
+
+enum
+{
+ MAX_ENCOUNTER = 11,
+
+ TYPE_EVENT = 0,
+ TYPE_RIFT = 1,
+ TYPE_EREKEM = 2,
+ TYPE_MORAGG = 3,
+ TYPE_ICHORON = 4,
+ TYPE_XEVOZZ = 5,
+ TYPE_LAVANTHOR = 6,
+ TYPE_ZURAMAT = 7,
+ TYPE_CYANIGOSA = 8,
+ TYPE_PORTAL6 = 9,
+ TYPE_PORTAL12 = 10,
+
+
+ WORLD_STATE_VH = 3816,
+ WORLD_STATE_VH_PRISON = 3815,
+ WORLD_STATE_VH_PORTALS = 3810,
+
+ TYPE_LASTBOSS = 19,
+ TYPE_DOOR = 21,
+ TYPE_PORTAL_TIME = 22,
+
+ TYPE_DISRUPTIONS = 101,
+ TYPE_LASTBOSS_ID = 102,
+
+ DATA_EREKEM = 23,
+ DATA_MORAGG = 24,
+ DATA_ICHORON = 25,
+ DATA_XEVOZZ = 26,
+ DATA_LAVANTHOR = 27,
+ DATA_ZURAMAT = 28,
+ DATA_SINCLARI = 29,
+ DATA_BOSSTIME = 30,
+ DATA_NPC_SEAL_DOOR = 31,
+
+ DATA_SEAL_DOOR = 32,
+ DATA_EREKEM_DOOR = 33,
+ DATA_MORAGG_DOOR = 34,
+ DATA_ICHORON_DOOR = 35,
+ DATA_XEVOZZ_DOOR = 36,
+ DATA_LAVANTHOR_DOOR = 37,
+ DATA_ZURAMAT_DOOR = 38,
+ DATA_EREKEM_DOOR_L = 39,
+ DATA_EREKEM_DOOR_R = 40,
+
+ NPC_EREKEM = 29315,
+ NPC_EREKEM_GUARD = 29395,
+ NPC_MORAGG = 29316,
+ NPC_ICHORON = 29313,
+ NPC_XEVOZZ = 29266,
+ NPC_LAVANTHOR = 29312,
+ NPC_ZURAMAT = 29314,
+ NPC_CYANIGOSA = 31134,
+
+ NPC_AZURE_SABOTEUR = 31079, // Open boss's cell
+
+ NPC_AZURE_CAPTAIN = 30666, //Melee, 40k - 60k hp, 3 for 1-11, 4 for 13-17
+ NPC_AZURE_RAIDER = 30668, //Melee, 40k - 60k hp
+ NPC_AZURE_SORCEROR = 30667, //Caster, 40k - 60k hp
+ NPC_AZURE_STALKER = 32191, //Melee, 40k - 60k hp
+ NPC_GUARDIAN = 30660,
+ NPC_KEEPER = 30695,
+ NPC_AZURE_BINDER = 30663, //Caster, 7k - 10k hp
+ NPC_AZURE_INVADER = 30661, //Melee, 8k - 12k hp
+ NPC_AZURE_MAGE_SLAYER = 30664, //Melee, 10k - 15k hp
+ NPC_AZURE_SPELLBREAKER = 30662, //Caster, 10k - 15k hp
+
+ NPC_SINCLARI = 30658,
+ NPC_GUARD = 30659,
+ NPC_PORTAL = 31011,
+ NPC_DOOR_SEAL = 30896,
+
+ GO_DOOR_SEAL = 191723,
+ GO_DOOR_EREKEM = 191564,
+ GO_DOOR_EREKEM_RIGHT = 191563,
+ GO_DOOR_EREKEM_LEFT = 191562,
+ GO_DOOR_MORAGG = 191606,
+ GO_DOOR_ICHORON = 191722,
+ GO_DOOR_XEVOZZ = 191556,
+ GO_DOOR_LAVANTHOR = 191566,
+ GO_DOOR_ZURAMAT = 191565,
+
+ SPELL_PORTAL_CHANNEL = 58012,
+ SPELL_CORRUPT = 58040,
+
+ EMOTE_GUARDIAN_PORTAL = -1608005,
+ EMOTE_DRAGONFLIGHT_PORTAL = -1608006,
+ EMOTE_KEEPER_PORTAL = -1608007
+};
+
+struct Locations
+{
+ float x, y, z;
+ uint32 id;
+};
+
+struct WayPoints
+{
+ WayPoints(uint32 _id, float _x, float _y, float _z)
+ {
+ id = _id;
+ x = _x;
+ y = _y;
+ z = _z;
+ }
+ uint32 id;
+ float x, y, z;
+};
+
+static Locations SinclariWP[]=
+{
+ {1830.5f, 799.357f, 44.3418f}, // 0 use activation
+ {1832.46f, 800.431f, 44.3117f}, // 1 SAY_BEGIN call back guards
+ {1824.79f, 803.828f, 44.3634f}, // 2 SAY_LOCK_DOOR close door
+ {1807.25f, 803.904f, 44.3634f}, // 3
+ {1808.07f, 804.259f, 44.3641f}, // 4
+
+};
+
+static Locations PortalLoc[]=
+{
+ {1888.271f, 810.781f, 38.441f}, // 0 center
+ {1857.125f, 763.295f, 38.654f}, // 1 Lavanthor
+ {1925.480f, 849.981f, 47.174f}, // 2 Zuramat
+ {1892.737f, 744.589f, 47.666f}, // 3 Moragg
+ {1878.198f, 850.005f, 43.333f}, // 4 Portal in front of Erekem
+ {1909.381f, 806.796f, 38.645f}, // 5 Portal outside of Ichoron
+ {1936.101f, 802.950f, 52.417f}, // 6 at the highest platform
+};
+
+static Locations BossLoc[]=
+{
+ {0,0,0},
+ {0,0,0},
+ {1876.100f, 857.079f, 43.333f}, // Erekem
+ {1892.737f, 744.589f, 47.666f}, // Moragg
+ {1908.863f, 785.647f, 37.435f}, // Ichoron
+ {1905.364f, 840.607f, 38.670f}, // Xevozz
+ {1857.125f, 763.295f, 38.654f}, // Lavanthor
+ {1925.480f, 849.981f, 47.174f}, // Zuramat
+};
+
+static Locations DragonsWP[]=
+{
+ //center, ichoron
+ {1869.393f, 803.902f, 38.768f}, // 0
+ {1859.843f, 804.222f, 44.008f}, // 1
+ {1829.64f, 804.194f, 44.355f}, // 2
+
+ //From left side (lavanthor)
+ {1861.016f, 789.717f, 38.908f}, // 3
+ {1856.217f, 796.705f, 44.008f}, // 4
+ {1829.64f, 804.194f, 44.355f}, // 5
+
+ //From Zuramat
+ {1931.446f, 826.734f, 47.556f}, // 6
+ {1913.049f, 823.930f, 38.792f}, // 7
+ {1827.960f, 804.208f, 44.364f}, // 8
+ {1869.393f, 803.902f, 38.768f}, // 9
+ {1859.843f, 804.222f, 44.008f}, // 10
+ {1829.64f, 804.194f, 44.355f}, // 11
+
+ //From Morag
+ {1887.500f, 763.096f, 47.666f}, // 12
+ {1880.837f, 775.769f, 38.796f}, // 13
+ {1861.016f, 789.717f, 38.908f}, // 14
+ {1856.217f, 796.705f, 44.008f}, // 15
+ {1829.64f, 804.194f, 44.355f}, // 16
+
+ //From erekem
+ {1878.280f, 843.267f, 43.333f}, // 17
+ {1872.311f, 835.531f, 38.780f}, // 18
+ {1861.997f, 818.766f, 38.650f}, // 19
+ {1857.348f, 811.230f, 44.008f}, // 20
+ {1829.64f, 804.194f, 44.355f}, // 21
+
+ //From Highest platform
+ {1937.298f, 824.557f, 52.332f}, // 22
+ {1913.049f, 823.930f, 38.792f}, // 23
+ {1869.393f, 803.902f, 38.768f}, // 24
+ {1859.843f, 804.222f, 44.008f}, // 25
+ {1829.64f, 804.194f, 44.355f}, // 26
+};
+
+#endif
diff --git a/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak.cpp b/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak.cpp
new file mode 100644
index 0000000..c7c32a2
--- /dev/null
+++ b/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak.cpp
@@ -0,0 +1,28 @@
+/* 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_shirrak
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Auchindoun, Auchenai Crypts
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_boss_shirrak()
+{
+}
\ No newline at end of file
diff --git a/scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp b/scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp
new file mode 100644
index 0000000..bc59c27
--- /dev/null
+++ b/scripts/outland/auchindoun/sethekk_halls/boss_anzu.cpp
@@ -0,0 +1,28 @@
+/* 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_anzu
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Auchindoun, Sethekk Halls
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_boss_anzu()
+{
+}
diff --git a/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp b/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp
index 5d331ad..e22a3a4 100644
--- a/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp
+++ b/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp
@@ -110,6 +110,9 @@ struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
case 1: DoScriptText(SAY_AGGRO_2, m_creature); break;
case 2: DoScriptText(SAY_AGGRO_3, m_creature); break;
}
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_IKISS, IN_PROGRESS);
}
void JustDied(Unit* Killer)
@@ -117,7 +120,13 @@ struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
DoScriptText(SAY_DEATH, m_creature);
if (m_pInstance)
- m_pInstance->SetData(DATA_IKISSDOOREVENT, DONE);
+ m_pInstance->SetData(TYPE_IKISS, DONE);
+ }
+
+ void JustReachedHome()
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_IKISS, FAIL);
}
void KilledUnit(Unit* victim)
@@ -184,8 +193,7 @@ struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
float Y = target->GetPositionY();
float Z = target->GetPositionZ();
- m_creature->GetMap()->CreatureRelocation(m_creature,X,Y,Z,0.0f);
- m_creature->SendMonsterMove(X, Y, Z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, 1);
+ m_creature->MonsterMove(X, Y, Z, 1);
DoCastSpellIfCan(target,SPELL_BLINK_TELEPORT);
Blink = true;
diff --git a/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp b/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp
index 2a2d65b..e1f2110 100644
--- a/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp
+++ b/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp
@@ -24,36 +24,98 @@ EndScriptData */
#include "precompiled.h"
#include "sethekk_halls.h"
-#define IKISS_DOOR 177203
+instance_sethekk_halls::instance_sethekk_halls(Map* pMap) : ScriptedInstance(pMap),
+ m_uiIkissDoorGUID(0)
+{
+ Initialize();
+}
+void instance_sethekk_halls::Initialize()
+{
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+}
-struct MANGOS_DLL_DECL instance_sethekk_halls : public ScriptedInstance
+void instance_sethekk_halls::OnObjectCreate(GameObject* pGo)
{
- instance_sethekk_halls(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+ if (pGo->GetEntry() == GO_IKISS_DOOR)
+ {
+ m_uiIkissDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[TYPE_IKISS] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ }
+}
- uint64 m_uiIkissDoorGUID;
+void instance_sethekk_halls::SetData(uint32 uiType, uint32 uiData)
+{
+ switch(uiType)
+ {
+ case TYPE_SYTH:
+ case TYPE_ANZU:
+ m_auiEncounter[uiType] = uiData;
+ break;
+ case TYPE_IKISS:
+ if (uiData == DONE)
+ DoUseDoorOrButton(m_uiIkissDoorGUID, DAY*IN_MILLISECONDS);
+ m_auiEncounter[uiType] = uiData;
+ break;
+ default:
+ return;
+ }
- void Initialize()
+ if (uiData == DONE)
{
- m_uiIkissDoorGUID = 0;
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2];
+
+ m_strInstData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
}
+}
- void OnObjectCreate(GameObject* pGo)
+uint32 instance_sethekk_halls::GetData(uint32 uiType)
+{
+ if (uiType < MAX_ENCOUNTER)
+ return m_auiEncounter[uiType];
+
+ return 0;
+}
+
+void instance_sethekk_halls::Load(const char* chrIn)
+{
+ if (!chrIn)
{
- if (pGo->GetEntry() == IKISS_DOOR)
- m_uiIkissDoorGUID = pGo->GetGUID();
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
}
- void SetData(uint32 uiType, uint32 uiData)
+ OUT_LOAD_INST_DATA(chrIn);
+
+ std::istringstream loadStream(chrIn);
+ loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2];
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
{
- switch(uiType)
- {
- case DATA_IKISSDOOREVENT:
- if (uiData == DONE)
- DoUseDoorOrButton(m_uiIkissDoorGUID,DAY*IN_MILLISECONDS);
- break;
- }
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
}
-};
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+}
+
+bool instance_sethekk_halls::CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/)
+{
+ if (uiCriteriaId != ACHIEV_CRITA_TURKEY_TIME)
+ return false;
+
+ if (!pSource)
+ return false;
+
+ return pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_HAT, 1) && (pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_DRESS, 1)
+ || pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_ROBE, 1) || pSource->HasItemOrGemWithIdEquipped(ITEM_PILGRIMS_ATTIRE, 1));
+}
InstanceData* GetInstanceData_instance_sethekk_halls(Map* pMap)
{
@@ -62,9 +124,10 @@ InstanceData* GetInstanceData_instance_sethekk_halls(Map* pMap)
void AddSC_instance_sethekk_halls()
{
- Script *newscript;
- newscript = new Script;
- newscript->Name = "instance_sethekk_halls";
- newscript->GetInstanceData = &GetInstanceData_instance_sethekk_halls;
- newscript->RegisterSelf();
+ Script* pNewScript;
+
+ pNewScript = new Script;
+ pNewScript->Name = "instance_sethekk_halls";
+ pNewScript->GetInstanceData = &GetInstanceData_instance_sethekk_halls;
+ pNewScript->RegisterSelf();
}
diff --git a/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h b/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h
index e51ce8b..7cd8b8a 100644
--- a/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h
+++ b/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h
@@ -5,5 +5,45 @@
#ifndef DEF_SETHEKK_HALLS_H
#define DEF_SETHEKK_HALLS_H
-#define DATA_IKISSDOOREVENT 1
+enum
+{
+ MAX_ENCOUNTER = 3,
+
+ TYPE_SYTH = 0,
+ TYPE_ANZU = 1,
+ TYPE_IKISS = 2,
+
+ GO_IKISS_DOOR = 177203,
+
+ ACHIEV_CRITA_TURKEY_TIME = 11142,
+ ITEM_PILGRIMS_HAT = 46723,
+ ITEM_PILGRIMS_DRESS = 44785,
+ ITEM_PILGRIMS_ROBE = 46824,
+ ITEM_PILGRIMS_ATTIRE = 46800,
+};
+
+class MANGOS_DLL_DECL instance_sethekk_halls : public ScriptedInstance
+{
+ public:
+ instance_sethekk_halls(Map* pMap);
+ ~instance_sethekk_halls() {}
+
+ void Initialize();
+ void OnObjectCreate(GameObject* pGo);
+
+ void SetData(uint32 uiType, uint32 uiData);
+ uint32 GetData(uint32 uiType);
+
+ bool CheckAchievementCriteriaMeet(uint32 uiCriteriaId, Player const* pSource, Unit const* pTarget, uint32 uiMiscValue1 /* = 0*/);
+
+ const char* Save() { return m_strInstData.c_str(); }
+ void Load(const char* chrIn);
+
+ private:
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+ std::string m_strInstData;
+
+ uint64 m_uiIkissDoorGUID;
+};
+
#endif
diff --git a/scripts/outland/black_temple/boss_supremus.cpp b/scripts/outland/black_temple/boss_supremus.cpp
index 64ee18c..ed2c694 100644
--- a/scripts/outland/black_temple/boss_supremus.cpp
+++ b/scripts/outland/black_temple/boss_supremus.cpp
@@ -120,7 +120,7 @@ struct MANGOS_DLL_DECL npc_volcanoAI : public ScriptedAI
CheckTimer = 1000;
SupremusGUID = 0;
FireballTimer = 500;
- GeyserTimer = 0;
+ GeyserTimer = 2000;
}
void AttackStart(Unit* who) {}
diff --git a/scripts/outland/boss_doomlord_kazzak.cpp b/scripts/outland/boss_doomlord_kazzak.cpp
index cdea9a4..0bb1edf 100644
--- a/scripts/outland/boss_doomlord_kazzak.cpp
+++ b/scripts/outland/boss_doomlord_kazzak.cpp
@@ -140,11 +140,12 @@ struct MANGOS_DLL_DECL boss_doomlordkazzakAI : public ScriptedAI
if (MarkOfKazzak_Timer < diff)
{
Unit* victim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
- if (victim->GetPower(POWER_MANA))
- {
- DoCastSpellIfCan(victim, SPELL_MARKOFKAZZAK);
- MarkOfKazzak_Timer = 20000;
- }
+ if (victim)
+ if (victim->GetPower(POWER_MANA))
+ {
+ DoCastSpellIfCan(victim, SPELL_MARKOFKAZZAK);
+ MarkOfKazzak_Timer = 20000;
+ }
}else MarkOfKazzak_Timer -= diff;
//Enrage_Timer
diff --git a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp
index 2618f7e..430e343 100644
--- a/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp
+++ b/scripts/outland/coilfang_reservoir/serpent_shrine/boss_the_lurker_below.cpp
@@ -31,6 +31,7 @@ enum
SPELL_GEYSER = 37478,
SPELL_SPOUT = 37433, // TODO should sweep the room 360degrees, related spells 37429 37430 37431
SPELL_WATERBOLT = 37138, // TODO is used when no enemy in melee range (unknown if on random or top-most aggro holder in this case
+ ACHIEVEMENT_LURKER = 144,
};
enum Phases
@@ -42,6 +43,7 @@ enum Phases
};
// TODO This boss should infact be a Scripted_NoMovementAI, but selecting only melee targets is not supported yet, change when implemented
+
struct MANGOS_DLL_DECL boss_the_lurker_belowAI : public ScriptedAI
{
boss_the_lurker_belowAI(Creature* pCreature) : ScriptedAI(pCreature)
@@ -128,6 +130,7 @@ bool GOHello_go_strange_pool(Player* pPlayer, GameObject* pGo)
if (pInstance->GetData(TYPE_THELURKER_EVENT) == NOT_STARTED)
{
pPlayer->CastSpell(pPlayer, SPELL_LURKER_SPAWN_TRIGGER, true);
+ pPlayer->CompletedAchievement(ACHIEVEMENT_LURKER);
pInstance->SetData(TYPE_THELURKER_EVENT, IN_PROGRESS);
return true;
}
diff --git a/scripts/outland/coilfang_reservoir/slave_pens/boss_ahune.cpp b/scripts/outland/coilfang_reservoir/slave_pens/boss_ahune.cpp
new file mode 100644
index 0000000..d95b51f
--- /dev/null
+++ b/scripts/outland/coilfang_reservoir/slave_pens/boss_ahune.cpp
@@ -0,0 +1,28 @@
+/* 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_ahune
+SD%Complete: 0
+SDComment: Placeholder
+SDCategory: Slave Pens
+EndScriptData */
+
+#include "precompiled.h"
+
+void AddSC_boss_ahune()
+{
+}
diff --git a/scripts/outland/gruuls_lair/boss_gruul.cpp b/scripts/outland/gruuls_lair/boss_gruul.cpp
index 3c9b648..0928527 100644
--- a/scripts/outland/gruuls_lair/boss_gruul.cpp
+++ b/scripts/outland/gruuls_lair/boss_gruul.cpp
@@ -197,7 +197,7 @@ struct MANGOS_DLL_DECL boss_gruulAI : public ScriptedAI
if (m_uiHurtfulStrike_Timer < uiDiff)
{
// Find 2nd-aggro target within melee range.
- Unit *pTarget = NULL;
+ Unit* pTarget = NULL;
ThreatList const& tList = m_creature->getThreatManager().getThreatList();
ThreatList::const_iterator itr = tList.begin();
std::advance(itr, 1);
@@ -206,7 +206,7 @@ struct MANGOS_DLL_DECL boss_gruulAI : public ScriptedAI
pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());
// exclude pets, totems & player out of melee range
- if (pTarget->GetTypeId() != TYPEID_PLAYER || !pTarget->IsWithinDist(m_creature, ATTACK_DISTANCE, false))
+ if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER || !pTarget->IsWithinDist(m_creature, ATTACK_DISTANCE, false))
{
pTarget = NULL;
continue;
diff --git a/scripts/world/boss_lethon.cpp b/scripts/world/boss_lethon.cpp
index 623a4ac..a46d917 100644
--- a/scripts/world/boss_lethon.cpp
+++ b/scripts/world/boss_lethon.cpp
@@ -22,3 +22,7 @@ SDCategory: Bosses
EndScriptData */
#include "precompiled.h"
+
+void AddSC_boss_lethon()
+{
+}
diff --git a/scripts/world/go_scripts.cpp b/scripts/world/go_scripts.cpp
index a06958f..a4ba5e8 100644
--- a/scripts/world/go_scripts.cpp
+++ b/scripts/world/go_scripts.cpp
@@ -17,7 +17,7 @@
/* ScriptData
SDName: GO_Scripts
SD%Complete: 100
-SDComment: Quest support: 4285,4287,4288(crystal pylons), 4296, 5088, 5097, 5098, 6481, 10990, 10991, 10992, 14092/14076. Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089
+SDComment: Quest support: 4285,4287,4288(crystal pylons), 4296, 5088, 5097, 5098, 6481, 10990, 10991, 10992, 12557, 14092/14076. Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089
SDCategory: Game Objects
EndScriptData */
@@ -41,6 +41,7 @@ go_tele_to_dalaran_crystal
go_tele_to_violet_stand
go_andorhal_tower
go_scourge_enclosure
+go_lab_work_reagents
EndContentData */
#include "precompiled.h"
@@ -537,6 +538,45 @@ bool GOHello_go_scourge_enclosure(Player* pPlayer, GameObject* pGo)
return true;
}
+/*######
+## go_lab_work_reagents
+######*/
+
+enum
+{
+ QUEST_LAB_WORK = 12557,
+
+ SPELL_WIRHERED_BATWING_KILL_CREDIT = 51226,
+ SPELL_MUDDY_MIRE_MAGGOT_KILL_CREDIT = 51227,
+ SPELL_AMBERSEED_KILL_CREDIT = 51228,
+ SPELL_CHILLED_SERPENT_MUCUS_KILL_CREDIT = 51229,
+
+ GO_AMBERSEED = 190459,
+ GO_CHILLED_SERPENT_MUCUS = 190462,
+ GO_WITHERED_BATWING = 190473,
+ GO_MUDDY_MIRE_MAGGOTS = 190478,
+};
+
+bool GOHello_go_lab_work_reagents(Player* pPlayer, GameObject* pGo)
+{
+ if (pPlayer->GetQuestStatus(QUEST_LAB_WORK) == QUEST_STATUS_INCOMPLETE)
+ {
+ uint32 uiCreditSpellId = 0;
+ switch (pGo->GetEntry())
+ {
+ case GO_AMBERSEED: uiCreditSpellId = SPELL_AMBERSEED_KILL_CREDIT; break;
+ case GO_CHILLED_SERPENT_MUCUS: uiCreditSpellId = SPELL_CHILLED_SERPENT_MUCUS_KILL_CREDIT; break;
+ case GO_WITHERED_BATWING: uiCreditSpellId = SPELL_WIRHERED_BATWING_KILL_CREDIT; break;
+ case GO_MUDDY_MIRE_MAGGOTS: uiCreditSpellId = SPELL_MUDDY_MIRE_MAGGOT_KILL_CREDIT; break;
+ }
+
+ if (uiCreditSpellId)
+ pPlayer->CastSpell(pPlayer, uiCreditSpellId, true);
+ }
+
+ return false;
+}
+
void AddSC_go_scripts()
{
Script* pNewScript;
@@ -650,4 +690,10 @@ void AddSC_go_scripts()
pNewScript->Name = "go_scourge_enclosure";
pNewScript->pGOHello = &GOHello_go_scourge_enclosure;
pNewScript->RegisterSelf();
+
+ pNewScript = new Script;
+ pNewScript->Name = "go_lab_work_reagents";
+ pNewScript->pGOHello = &GOHello_go_lab_work_reagents;
+ pNewScript->RegisterSelf();
+
}
diff --git a/scripts/world/npcs_special.cpp b/scripts/world/npcs_special.cpp
index 926eea9..7962348 100644
--- a/scripts/world/npcs_special.cpp
+++ b/scripts/world/npcs_special.cpp
@@ -43,6 +43,7 @@ npc_rogue_trainer 80% Scripted trainers, so they are able to offer ite
npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given
npc_tabard_vendor 50% allow recovering quest related tabards, achievement related ones need core support
npc_locksmith 75% list of keys needs to be confirmed
+npc_death_knight_gargoyle AI for summoned gargoyle of deathknights
EndContentData */
/*########
@@ -1750,6 +1751,448 @@ bool GossipSelect_npc_locksmith(Player* pPlayer, Creature* pCreature, uint32 uiS
return true;
}
+/*######
+## npc_mirror_image
+######*/
+
+enum MirrorImageSpells
+{
+ SPELL_CLONE_CASTER = 45204,
+ SPELL_CLONE_CASTER_1 = 69837,
+// SPELL_CLONE_CASTER_1 = 58836,
+ SPELL_CLONE_THREAT = 58838,
+ SPELL_FIREBLAST = 59637,
+ SPELL_FROSTBOLT = 59638,
+ SPELL_FROSTSHIELD = 43008,
+ SPELL_FIRESHIELD = 43046,
+ SPELL_ICEBLOCK = 65802,
+ SPELL_ICERING = 42917,
+};
+
+struct MANGOS_DLL_DECL npc_mirror_imageAI : public ScriptedAI
+{
+ npc_mirror_imageAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+
+ uint32 m_uiFrostboltTimer;
+ uint32 m_uiFrostringTimer;
+ uint32 m_uiFireblastTimer;
+ bool inCombat;
+ Unit *owner;
+ float angle;
+ bool blocked;
+ bool movement;
+
+ void Reset()
+ {
+ owner = m_creature->GetOwner();
+ if (!owner)
+ return;
+
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_2,owner->GetUInt32Value(UNIT_FIELD_BYTES_2));
+ m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
+ m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f);
+
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, owner->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID));
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, owner->GetUInt32Value(PLAYER_VISIBLE_ITEM_17_ENTRYID));
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+2, owner->GetUInt32Value(PLAYER_VISIBLE_ITEM_18_ENTRYID));
+ m_creature->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN), true);
+
+ m_uiFrostboltTimer = urand(0,3000);
+ m_uiFrostringTimer = urand(2000,6000);
+ m_uiFireblastTimer = urand(0,3000);
+ inCombat = false;
+ blocked = false;
+ movement = false;
+
+
+ if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ {
+ angle = m_creature->GetAngle(owner);
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f, angle);
+ }
+
+ if(owner->IsPvP())
+ m_creature->SetPvP(true);
+ if(owner->IsFFAPvP())
+ m_creature->SetFFAPvP(true);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho) return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ if (owner)
+ m_creature->CastSpell(m_creature, SPELL_CLONE_THREAT, true, NULL, NULL, owner->GetGUID());
+ m_creature->clearUnitState(UNIT_STAT_FOLLOW);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 100.0f);
+ DoStartMovement(pWho, 30.0f);
+ SetCombatMovement(true);
+ inCombat = true;
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ if (m_creature->IsInEvadeMode() || !m_creature->isAlive())
+ return;
+
+ inCombat = false;
+
+ m_creature->AttackStop();
+ m_creature->CombatStop(true);
+ if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ {
+ angle = m_creature->GetAngle(owner);
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f,angle);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!owner || !owner->isAlive())
+ m_creature->ForcedDespawn();
+
+ if (owner && !m_creature->HasAura(SPELL_CLONE_CASTER))
+ m_creature->CastSpell(m_creature, SPELL_CLONE_CASTER, true, NULL, NULL, owner->GetGUID());
+
+ if (owner && !m_creature->HasAura(SPELL_CLONE_CASTER_1))
+ m_creature->CastSpell(m_creature, SPELL_CLONE_CASTER_1, true, NULL, NULL, owner->GetGUID());
+
+ if (owner && owner->HasAura(SPELL_FROSTSHIELD) && !m_creature->HasAura(SPELL_FROSTSHIELD))
+ m_creature->CastSpell(m_creature, SPELL_FROSTSHIELD, false);
+
+ if (owner && owner->HasAura(SPELL_FIRESHIELD) && !m_creature->HasAura(SPELL_FIRESHIELD))
+ m_creature->CastSpell(m_creature, SPELL_FIRESHIELD, false);
+
+ if (!m_creature->getVictim())
+ if (owner && owner->getVictim())
+ AttackStart(owner->getVictim());
+
+ if (m_creature->getVictim() && m_creature->getVictim() != owner->getVictim())
+ AttackStart(owner->getVictim());
+
+ if (inCombat && !m_creature->getVictim())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ if (!inCombat)
+ return;
+
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(),30.0f))
+ {
+ movement = false;
+ if (m_uiFrostboltTimer <= diff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(),SPELL_FROSTBOLT);
+ m_uiFrostboltTimer = urand(1000,6000);
+ } else m_uiFrostboltTimer -= diff;
+
+ if (m_uiFireblastTimer <= diff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(),SPELL_FIREBLAST);
+ m_uiFireblastTimer = urand(1000,6000);
+ } else m_uiFireblastTimer -= diff;
+
+ if (m_uiFrostringTimer <= diff && m_creature->IsWithinDistInMap(m_creature->getVictim(),5.0f))
+ {
+ DoCastSpellIfCan(m_creature->getVictim(),SPELL_ICERING);
+ m_uiFrostringTimer = urand(4000,8000);
+ } else m_uiFrostringTimer -= diff;
+
+ if (!blocked && m_creature->GetHealthPercent() < 10.0f)
+ {
+ DoCastSpellIfCan(m_creature,SPELL_ICEBLOCK);
+ blocked = true;
+ }
+ }
+ else
+ if (!movement)
+ {
+ DoStartMovement(m_creature->getVictim(), 20.0f);
+ movement = true;
+ }
+
+// DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_mirror_image(Creature* pCreature)
+{
+ return new npc_mirror_imageAI(pCreature);
+};
+
+/*####
+ ## npc_snake_trap_serpents - Summonned snake id are 19921 and 19833
+ ####*/
+
+#define SPELL_MIND_NUMBING_POISON 25810 //Viper
+#define SPELL_CRIPPLING_POISON 30981 //Viper
+#define SPELL_DEADLY_POISON 34655 //Venomous Snake
+
+#define MOB_VIPER 19921
+#define MOB_VENOM_SNIKE 19833
+
+struct MANGOS_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI
+{
+ npc_snake_trap_serpentsAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+ uint32 SpellTimer;
+ Unit* Owner;
+
+ void Reset()
+ {
+ SpellTimer = 500;
+ Owner = m_creature->GetCharmerOrOwner();
+ if (!Owner) return;
+
+ m_creature->SetLevel(Owner->getLevel());
+ m_creature->setFaction(Owner->getFaction());
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho) return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->SetInCombatWith(pWho);
+ m_creature->AddThreat(pWho, 100.0f);
+ SetCombatMovement(true);
+ m_creature->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->getVictim())
+ {
+ if (Owner && Owner->getVictim())
+ AttackStart(Owner->getVictim());
+ return;
+ }
+
+ if (SpellTimer <= diff)
+ {
+ if (m_creature->GetEntry() == MOB_VIPER ) //Viper - 19921
+ {
+ if (!urand(0,2)) //33% chance to cast
+ {
+ uint32 spell;
+ if (urand(0,1))
+ spell = SPELL_MIND_NUMBING_POISON;
+ else
+ spell = SPELL_CRIPPLING_POISON;
+ DoCast(m_creature->getVictim(), spell);
+ }
+
+ SpellTimer = urand(3000, 5000);
+ }
+ else if (m_creature->GetEntry() == MOB_VENOM_SNIKE ) //Venomous Snake - 19833
+ {
+ if (urand(0,1) == 0) //80% chance to cast
+ DoCast(m_creature->getVictim(), SPELL_DEADLY_POISON);
+ SpellTimer = urand(2500, 4500);
+ }
+ }
+ else SpellTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_snake_trap_serpents(Creature* pCreature)
+{
+ return new npc_snake_trap_serpentsAI(pCreature);
+}
+
+struct MANGOS_DLL_DECL npc_rune_blade : public ScriptedAI
+{
+ npc_rune_blade(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
+
+ Unit* owner;
+
+ void Reset()
+ {
+ owner = m_creature->GetOwner();
+ if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Cannot be Selected or Attacked
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ m_creature->SetLevel(owner->getLevel());
+ m_creature->setFaction(owner->getFaction());
+
+ // Add visible weapon
+ if (Item const * item = ((Player *)owner)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, item->GetProto()->ItemId);
+
+ // Add stats scaling
+ int32 damageDone=owner->CalculateDamage(BASE_ATTACK, true); // might be average damage instead ?
+ int32 meleeSpeed=owner->m_modAttackSpeedPct[BASE_ATTACK];
+ m_creature->CastCustomSpell(m_creature, 51906, &damageDone, &meleeSpeed, NULL, true);
+
+ // Visual Glow
+ m_creature->CastSpell(m_creature, 53160, true);
+
+ SetCombatMovement(true);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!owner) return;
+
+ if (!m_creature->getVictim())
+ {
+ if (owner->getVictim())
+ AttackStart(owner->getVictim());
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_rune_blade(Creature* pCreature)
+{
+ return new npc_rune_blade(pCreature);
+}
+/*########
+# mob_death_knight_gargoyle AI
+#########*/
+
+// UPDATE `creature_template` SET `ScriptName` = 'mob_death_knight_gargoyle' WHERE `entry` = '27829';
+
+enum GargoyleSpells
+{
+ SPELL_GARGOYLE_STRIKE = 51963 // Don't know if this is the correct spell, it does about 700-800 damage points
+};
+
+struct MANGOS_DLL_DECL npc_death_knight_gargoyle : public ScriptedAI
+{
+ npc_death_knight_gargoyle(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ Reset();
+ }
+ uint32 m_uiGargoyleStrikeTimer;
+ bool inCombat;
+ Unit *owner;
+
+
+ void Reset()
+ {
+ owner = m_creature->GetOwner();
+ if (!owner) return;
+
+ m_creature->SetLevel(owner->getLevel());
+ m_creature->setFaction(owner->getFaction());
+
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_0, 50331648);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 50331648);
+ m_creature->AddSplineFlag(SPLINEFLAG_FLYING);
+
+ inCombat = false;
+ m_uiGargoyleStrikeTimer = urand(3000, 5000);
+
+ float fPosX, fPosY, fPosZ;
+ owner->GetPosition(fPosX, fPosY, fPosZ);
+
+ m_creature->NearTeleportTo(fPosX, fPosY, fPosZ+10.0f, m_creature->GetAngle(owner));
+
+
+ if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ {
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f, m_creature->GetAngle(owner));
+ }
+
+ if(owner->IsPvP())
+ m_creature->SetPvP(true);
+ if(owner->IsFFAPvP())
+ m_creature->SetFFAPvP(true);
+ }
+
+ void EnterEvadeMode()
+ {
+ if (m_creature->IsInEvadeMode() || !m_creature->isAlive())
+ return;
+
+ inCombat = false;
+
+ m_creature->AttackStop();
+ m_creature->CombatStop(true);
+ if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ {
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST + 3.0f, m_creature->GetAngle(owner));
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho) return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->clearUnitState(UNIT_STAT_FOLLOW);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 100.0f);
+ DoStartMovement(pWho, 10.0f);
+ SetCombatMovement(true);
+ inCombat = true;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+
+ if (!owner || !owner->IsInWorld())
+ {
+ m_creature->ForcedDespawn();
+ return;
+ }
+
+ if (!m_creature->getVictim())
+ if (owner && owner->getVictim())
+ AttackStart(owner->getVictim());
+
+ if (m_creature->getVictim() && m_creature->getVictim() != owner->getVictim())
+ AttackStart(owner->getVictim());
+
+ if (inCombat && !m_creature->getVictim())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ if (!inCombat) return;
+
+ if (m_uiGargoyleStrikeTimer <= uiDiff)
+ {
+ DoCastSpellIfCan(m_creature->getVictim(), SPELL_GARGOYLE_STRIKE);
+ m_uiGargoyleStrikeTimer = urand(3000, 5000);
+ }
+ else m_uiGargoyleStrikeTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_death_knight_gargoyle(Creature* pCreature)
+{
+ return new npc_death_knight_gargoyle(pCreature);
+}
/*######
## npc_training_dummy
######*/
@@ -1897,6 +2340,21 @@ void AddSC_npcs_special()
newscript->pGossipSelect = &GossipSelect_npc_locksmith;
newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name = "npc_mirror_image";
+ newscript->GetAI = &GetAI_npc_mirror_image;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_snake_trap_serpents";
+ newscript->GetAI = &GetAI_npc_snake_trap_serpents;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_runeblade";
+ newscript->GetAI = &GetAI_npc_rune_blade;
+ newscript->RegisterSelf();
+
newscript = new Script;
newscript->Name = "npc_training_dummy";
newscript->GetAI = &GetAI_npc_training_dummy;
@@ -1906,4 +2364,9 @@ void AddSC_npcs_special()
newscript->Name = "npc_lightwell";
newscript->pGossipHello = &GossipHello_npc_lightwell;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_death_knight_gargoyle";
+ newscript->GetAI = &GetAI_npc_death_knight_gargoyle;
+ newscript->RegisterSelf();
}
diff --git a/sql/Updates/Makefile.am b/sql/Updates/Makefile.am
index 384e2ba..cba782f 100644
--- a/sql/Updates/Makefile.am
+++ b/sql/Updates/Makefile.am
@@ -201,5 +201,8 @@ pkgdata_DATA = \
r1889_scriptdev2.sql \
r1890_mangos.sql \
r1890_scriptdev2.sql \
- r1891_mangos.sql
-
+ r1891_mangos.sql \
+ r1899_mangos.sql \
+ r1899_scriptdev2.sql \
+ r1908_scriptdev2.sql \
+ r1913_mangos.sql
diff --git a/sql/Updates/r1632_mangos.sql b/sql/Updates/r1632_mangos.sql
index bc9112e..d493d2b 100644
--- a/sql/Updates/r1632_mangos.sql
+++ b/sql/Updates/r1632_mangos.sql
@@ -3,7 +3,7 @@ UPDATE creature_template SET ScriptName='boss_gormok' WHERE entry=34796;
UPDATE creature_template SET ScriptName='boss_acidmaw' WHERE entry=35144;
UPDATE creature_template SET ScriptName='boss_dreadscale' WHERE entry=34799;
UPDATE creature_template SET ScriptName='boss_icehowl' WHERE entry=34797;
-UPDATE creature_template SET ScriptName='boss_jaraxxis' WHERE entry=34780;
+UPDATE creature_template SET ScriptName='boss_jaraxxus' WHERE entry=34780;
UPDATE creature_template SET ScriptName='boss_anubarak_trial' WHERE entry=34564;
UPDATE creature_template SET ScriptName='boss_fjola' WHERE entry=34497;
UPDATE creature_template SET ScriptName='boss_eydis' WHERE entry=34496;
diff --git a/sql/Updates/r1899_mangos.sql b/sql/Updates/r1899_mangos.sql
new file mode 100644
index 0000000..6231b90
--- /dev/null
+++ b/sql/Updates/r1899_mangos.sql
@@ -0,0 +1 @@
+UPDATE creature_template SET ScriptName='npc_greer_orehammer' WHERE entry=23859;
diff --git a/sql/Updates/r1899_scriptdev2.sql b/sql/Updates/r1899_scriptdev2.sql
new file mode 100644
index 0000000..3ea1157
--- /dev/null
+++ b/sql/Updates/r1899_scriptdev2.sql
@@ -0,0 +1,5 @@
+DELETE FROM gossip_texts WHERE entry BETWEEN -3000108 AND -3000106;
+INSERT INTO gossip_texts (entry,content_default,comment) VALUES
+(-3000106,'Show me where I can fly.','greer orehammer GOSSIP_ITEM_TAXI'),
+(-3000107,'[PH] Get Presicion Bombs','greer orehammer GOSSIP_ITEM_GET_BOMBS'),
+(-3000108,'[PH] Start bombing mission','greer orehammer GOSSIP_ITEM_FLIGHT');
diff --git a/sql/Updates/r1908_scriptdev2.sql b/sql/Updates/r1908_scriptdev2.sql
new file mode 100644
index 0000000..64e1cb1
--- /dev/null
+++ b/sql/Updates/r1908_scriptdev2.sql
@@ -0,0 +1,12 @@
+DELETE FROM script_texts WHERE entry BETWEEN -1554005 AND -1554000;
+INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES
+(-1554000,'REUSE_ME',0,0,0,0,'REUSE_ME'),
+(-1554001,'REUSE_ME',0,0,0,0,'REUSE_ME'),
+(-1554002,'REUSE_ME',0,0,0,0,'REUSE_ME'),
+(-1554003,'REUSE_ME',0,0,0,0,'REUSE_ME'),
+(-1554004,'REUSE_ME',0,0,0,0,'REUSE_ME'),
+(-1554005,'REUSE_ME',0,0,0,0,'REUSE_ME');
+
+DELETE FROM gossip_texts WHERE entry=-3000102;
+INSERT INTO gossip_texts (entry,content_default,comment) VALUES
+(-3000102,'Pay up, Harry!','silvermoon harry GOSSIP_ITEM_PAYING');
diff --git a/sql/Updates/r1913_mangos.sql b/sql/Updates/r1913_mangos.sql
new file mode 100644
index 0000000..cd04992
--- /dev/null
+++ b/sql/Updates/r1913_mangos.sql
@@ -0,0 +1 @@
+UPDATE gameobject_template SET ScriptName='go_lab_work_reagents' WHERE entry IN (190462, 190473, 190478, 190459);
diff --git a/sql/mangos_scriptname_full.sql b/sql/mangos_scriptname_full.sql
index bc614c9..359f264 100644
--- a/sql/mangos_scriptname_full.sql
+++ b/sql/mangos_scriptname_full.sql
@@ -79,6 +79,7 @@ UPDATE gameobject_template SET ScriptName='go_blood_filled_orb' WHERE entry=1820
UPDATE gameobject_template SET ScriptName='go_andorhal_tower' WHERE entry IN (176094,176095,176096,176097);
UPDATE gameobject_template SET ScriptName='go_scourge_enclosure' WHERE entry=191548;
UPDATE gameobject_template SET ScriptName='go_veil_skith_cage' WHERE entry IN (185202,185203,185204,185205);
+UPDATE gameobject_template SET ScriptName='go_lab_work_reagents' WHERE entry IN (190462, 190473, 190478, 190459);
/* GUARD */
UPDATE creature_template SET ScriptName='guard_azuremyst' WHERE entry=18038;
@@ -655,6 +656,7 @@ UPDATE creature_template SET ScriptName='npc_rinji' WHERE entry=7780;
UPDATE creature_template SET ScriptName='npc_daegarn' WHERE entry=24151;
UPDATE creature_template SET ScriptName='npc_deathstalker_razael' WHERE entry=23998;
UPDATE creature_template SET ScriptName='npc_dark_ranger_lyana' WHERE entry=23778;
+UPDATE creature_template SET ScriptName='npc_greer_orehammer' WHERE entry=23859;
UPDATE creature_template SET ScriptName='npc_mcgoyver' WHERE entry=24040;
UPDATE creature_template SET ScriptName='npc_silvermoon_harry' WHERE entry=24539;
diff --git a/sql/scriptdev2_script_full.sql b/sql/scriptdev2_script_full.sql
index af7e088..adeb5f0 100644
--- a/sql/scriptdev2_script_full.sql
+++ b/sql/scriptdev2_script_full.sql
@@ -3354,10 +3354,13 @@ INSERT INTO gossip_texts (entry,content_default,comment) VALUES
-- -3 000 100 GENERAL MAPS (not instance maps)
INSERT INTO gossip_texts (entry,content_default,comment) VALUES
(-3000101,'Taruk send me to collect what you owe.','silvermoon harry GOSSIP_ITEM_GAMBLING_DEBT'),
-(-3000102,'Here\'s the money.','silvermoon harry GOSSIP_ITEM_PAYING'),
+(-3000102,'Pay up, Harry!','silvermoon harry GOSSIP_ITEM_PAYING'),
(-3000103,'I am ready to travel to you village now.','rainspeaker GOSSIP_ITEM_READY'),
(-3000104,'','mosswalker victim GOSSIP_ITEM_PULSE'),
-(-3000105,'Ezekiel said that you might have a certain book...','dirty larry GOSSIP_ITEM_BOOK');
+(-3000105,'Ezekiel said that you might have a certain book...','dirty larry GOSSIP_ITEM_BOOK'),
+(-3000106,'Show me where I can fly.','greer orehammer GOSSIP_ITEM_TAXI'),
+(-3000107,'[PH] Get Presicion Bombs','greer orehammer GOSSIP_ITEM_GET_BOMBS'),
+(-3000108,'[PH] Start bombing mission','greer orehammer GOSSIP_ITEM_FLIGHT');
-- -3 090 000 GNOMEREGAN
INSERT INTO gossip_texts (entry,content_default,comment) VALUES
diff --git a/system/ScriptLoader.cpp b/system/ScriptLoader.cpp
index c21bb0c..7ece369 100644
--- a/system/ScriptLoader.cpp
+++ b/system/ScriptLoader.cpp
@@ -11,6 +11,8 @@ extern void AddSC_battleground();
extern void AddSC_boss_pusillin();
extern void AddSC_instance_dire_maul();
extern void AddSC_custom_cybernetic();
+extern void AddSC_npc_arena_honor();
+extern void AddSC_mob_teleguy();
//examples
extern void AddSC_example_creature();
@@ -214,8 +216,6 @@ extern void AddSC_boss_epoch_hunter();
extern void AddSC_boss_lieutenant_drake();
extern void AddSC_instance_old_hillsbrad();
extern void AddSC_old_hillsbrad();
-extern void AddSC_culling_of_stratholme(); //Culling of Stratholme
-extern void AddSC_instance_culling_of_stratholme();
extern void AddSC_boss_celebras_the_cursed(); //maraudon
extern void AddSC_boss_landslide();
extern void AddSC_boss_noxxion();
@@ -242,6 +242,17 @@ extern void AddSC_instance_wailing_caverns(); // Wailing Caverns
extern void AddSC_zulfarrak(); //zulfarrak
extern void AddSC_instance_zulfarrak();
+// culling of stratholme
+extern void AddSC_boss_lord_epoch();
+extern void AddSC_boss_malganis();
+extern void AddSC_boss_meathook();
+extern void AddSC_boss_salramm();
+extern void AddSC_boss_infinite_corruptor();
+extern void AddSC_culling_of_stratholme();
+extern void AddSC_culling_of_stratholmeAI();
+extern void AddSC_instance_culling_of_stratholme();
+extern void AddSC_trash_culling_of_stratholme();
+
extern void AddSC_ashenvale();
extern void AddSC_azshara();
extern void AddSC_azuremyst_isle();
@@ -266,23 +277,34 @@ extern void AddSC_ungoro_crater();
extern void AddSC_winterspring();
//northrend
+
+extern void AddSC_trial_of_the_champion(); //trial_of_the_champion
+extern void AddSC_boss_argent_challenge();
+extern void AddSC_boss_black_knight();
+extern void AddSC_boss_grand_champions();
+extern void AddSC_instance_trial_of_the_champion();
+
extern void AddSC_boss_jedoga(); //ahnkahet
+extern void AddSC_boss_amanitar();
extern void AddSC_boss_nadox();
extern void AddSC_boss_taldaram();
extern void AddSC_boss_volazj();
-extern void AddSC_boss_amanitar();
extern void AddSC_instance_ahnkahet();
extern void AddSC_boss_anubarak(); //azjol-nerub
extern void AddSC_boss_hadronox();
extern void AddSC_boss_krikthir();
extern void AddSC_instance_azjol_nerub();
-extern void AddSC_boss_anubarak_trial(); //trial_of_the_crusader
+
+extern void AddSC_northrend_beasts(); //Crusaders' Coliseum, trial_of_the_crusader
extern void AddSC_boss_jaraxxus();
+extern void AddSC_boss_anubarak_trial();
+extern void AddSC_boss_faction_champions();
+extern void AddSC_twin_valkyr();
extern void AddSC_instance_trial_of_the_crusader();
-extern void AddSC_northrend_beasts();
extern void AddSC_trial_of_the_crusader();
-extern void AddSC_twin_valkyr();
+
extern void AddSC_boss_novos(); //draktharon_keep
+extern void AddSC_boss_dred();
extern void AddSC_boss_tharonja();
extern void AddSC_boss_trollgore();
extern void AddSC_instance_draktharon_keep();
@@ -292,20 +314,19 @@ extern void AddSC_boss_galdarah();
extern void AddSC_boss_moorabi();
extern void AddSC_boss_sladran();
extern void AddSC_instance_gundrak();
-extern void AddSC_boss_bronjahm(); // ICC, forge_of_souls
-extern void AddSC_boss_devourer_of_souls();
-extern void AddSC_instance_forge_of_souls();
+
extern void AddSC_boss_gafrost(); // ICC, pit_of_saron
extern void AddSC_boss_krick_and_ick();
extern void AddSC_boss_tyrannus();
extern void AddSC_instance_pit_of_saron();
extern void AddSC_pit_of_saron();
+
extern void AddSC_boss_anubrekhan(); //naxxramas
extern void AddSC_boss_four_horsemen();
extern void AddSC_boss_faerlina();
+extern void AddSC_boss_grobbulus();
extern void AddSC_boss_gluth();
extern void AddSC_boss_gothik();
-extern void AddSC_boss_grobbulus();
extern void AddSC_boss_kelthuzad();
extern void AddSC_boss_loatheb();
extern void AddSC_boss_maexxna();
@@ -316,13 +337,27 @@ extern void AddSC_boss_razuvious();
extern void AddSC_boss_sapphiron();
extern void AddSC_boss_thaddius();
extern void AddSC_instance_naxxramas();
+
extern void AddSC_boss_anomalus(); //nexus
extern void AddSC_boss_keristrasza();
extern void AddSC_boss_ormorok();
extern void AddSC_boss_telestra();
extern void AddSC_instance_nexus();
+
+extern void AddSC_oculus(); //Oculus
+extern void AddSC_instance_oculus();
+extern void AddSC_boss_drakos();
+extern void AddSC_boss_varos();
+extern void AddSC_boss_urom();
+extern void AddSC_boss_eregos();
+
extern void AddSC_boss_sartharion(); //obsidian_sanctum
extern void AddSC_instance_obsidian_sanctum();
+extern void AddSC_instance_vault_of_archavon(); //vault_of_archavon
+extern void AddSC_boss_toravon();
+extern void AddSC_boss_koralon();
+extern void AddSC_boss_emalon();
+extern void AddSC_boss_archavon();
extern void AddSC_boss_bjarngrim(); //Ulduar, halls_of_lightning
extern void AddSC_boss_ionar();
extern void AddSC_boss_loken();
@@ -330,23 +365,26 @@ extern void AddSC_boss_volkhan();
extern void AddSC_instance_halls_of_lightning();
extern void AddSC_boss_maiden_of_grief(); //Ulduar, halls_of_stone
extern void AddSC_boss_sjonnir();
+extern void AddSC_boss_krystallus();
extern void AddSC_halls_of_stone();
extern void AddSC_instance_halls_of_stone();
-extern void AddSC_boss_assembly_of_iron(); //ulduar
-extern void AddSC_boss_algalon();
+extern void AddSC_boss_algalon(); //Ulduar raid
extern void AddSC_boss_auriaya();
-extern void AddSC_boss_flame_leviathan();
extern void AddSC_boss_freya();
-extern void AddSC_boss_general_vezax();
extern void AddSC_boss_hodir();
extern void AddSC_boss_ignis();
+extern void AddSC_boss_iron_council();
extern void AddSC_boss_kologarn();
+extern void AddSC_boss_leviathan();
extern void AddSC_boss_mimiron();
extern void AddSC_boss_razorscale();
extern void AddSC_boss_thorim();
-extern void AddSC_boss_xt_002();
+extern void AddSC_boss_vezax();
+extern void AddSC_boss_xt002();
extern void AddSC_boss_yogg_saron();
extern void AddSC_instance_ulduar();
+extern void AddSC_ulduar();
+extern void AddSC_ulduar_teleport();
extern void AddSC_boss_ingvar(); //utgarde_keep
extern void AddSC_boss_keleseth();
extern void AddSC_boss_skarvald_and_dalronn();
@@ -357,15 +395,6 @@ extern void AddSC_boss_skadi();
extern void AddSC_boss_svala();
extern void AddSC_boss_ymiron();
extern void AddSC_instance_pinnacle();
-extern void AddSC_boss_erekem(); //violet_hold
-extern void AddSC_boss_ichoron();
-extern void AddSC_boss_lavanthor();
-extern void AddSC_boss_moragg();
-extern void AddSC_boss_xevozz();
-extern void AddSC_boss_zuramat();
-extern void AddSC_boss_cyanigosa();
-extern void AddSC_instance_violet_hold();
-extern void AddSC_violet_hold();
extern void AddSC_borean_tundra();
extern void AddSC_dalaran();
@@ -377,6 +406,50 @@ extern void AddSC_sholazar_basin();
extern void AddSC_storm_peaks();
extern void AddSC_zuldrak();
+extern void AddSC_instance_violet_hold();
+extern void AddSC_violet_hold();
+extern void AddSC_boss_cyanigosa();
+extern void AddSC_boss_moragg();
+extern void AddSC_boss_erekem();
+extern void AddSC_boss_xevozz();
+extern void AddSC_boss_ichoron();
+extern void AddSC_boss_zuramat();
+extern void AddSC_boss_lavanthor();
+//IceCrown Citadel
+extern void AddSC_instance_icecrown_spire();
+extern void AddSC_icecrown_spire();
+extern void AddSC_icecrown_teleporter();
+extern void AddSC_boss_lord_marrowgar();
+extern void AddSC_boss_lady_deathwhisper();
+extern void AddSC_boss_deathbringer_saurfang();
+extern void AddSC_boss_rotface();
+extern void AddSC_boss_festergut();
+extern void AddSC_boss_proffesor_putricide();
+extern void AddSC_blood_prince_council();
+extern void AddSC_boss_blood_queen_lanathel();
+extern void AddSC_boss_valithria_dreamwalker();
+extern void AddSC_boss_sindragosa();
+extern void AddSC_boss_lich_king_icc();
+
+extern void AddSC_instance_forge_of_souls();
+extern void AddSC_boss_devourer_of_souls();
+extern void AddSC_boss_bronjahm();
+extern void AddSC_trash_forge_of_souls();
+extern void AddSC_forge_of_souls();
+
+extern void AddSC_instance_halls_of_reflection();
+extern void AddSC_halls_of_reflection();
+extern void AddSC_boss_falric();
+extern void AddSC_boss_marwyn();
+extern void AddSC_boss_lich_king_hr();
+
+extern void AddSC_instance_ruby_sanctum(); // Ruby Sanctum
+extern void AddSC_ruby_sanctum();
+extern void AddSC_boss_halion();
+extern void AddSC_boss_ragefire();
+extern void AddSC_boss_zarithrian();
+extern void AddSC_boss_baltharus();
+
//outland
extern void AddSC_boss_exarch_maladaar(); //auchindoun, auchenai_crypts
extern void AddSC_boss_nexusprince_shaffar(); //auchindoun, mana_tombs
@@ -465,6 +538,9 @@ void AddScripts()
AddSC_boss_pusillin();
AddSC_instance_dire_maul();
AddSC_custom_cybernetic();
+ AddSC_npc_arena_honor();
+ AddSC_mob_teleguy();
+
//examples
AddSC_example_creature();
AddSC_example_escort();
@@ -667,8 +743,6 @@ void AddScripts()
AddSC_boss_lieutenant_drake();
AddSC_instance_old_hillsbrad();
AddSC_old_hillsbrad();
- AddSC_culling_of_stratholme(); // Culling of Stratholme
- AddSC_instance_culling_of_stratholme();
AddSC_boss_celebras_the_cursed(); //maraudon
AddSC_boss_landslide();
AddSC_boss_noxxion();
@@ -719,23 +793,33 @@ void AddScripts()
AddSC_winterspring();
//northrend
+ AddSC_trial_of_the_champion(); //trial_of_the_champion
+ AddSC_boss_argent_challenge();
+ AddSC_boss_black_knight();
+ AddSC_boss_grand_champions();
+ AddSC_instance_trial_of_the_champion();
+
AddSC_boss_jedoga(); //ahnkahet
+ AddSC_boss_amanitar();
AddSC_boss_nadox();
AddSC_boss_taldaram();
AddSC_boss_volazj();
- AddSC_boss_amanitar();
AddSC_instance_ahnkahet();
AddSC_boss_anubarak(); //azjol-nerub
AddSC_boss_hadronox();
AddSC_boss_krikthir();
AddSC_instance_azjol_nerub();
- AddSC_boss_anubarak_trial(); //trial_of_the_crusader
+
+ AddSC_northrend_beasts(); //Crusaders' Coliseum, trial_of_the_crusader
AddSC_boss_jaraxxus();
+ AddSC_boss_anubarak_trial();
+ AddSC_boss_faction_champions();
+ AddSC_twin_valkyr();
AddSC_instance_trial_of_the_crusader();
- AddSC_northrend_beasts();
AddSC_trial_of_the_crusader();
- AddSC_twin_valkyr();
+
AddSC_boss_novos(); //draktharon_keep
+ AddSC_boss_dred();
AddSC_boss_tharonja();
AddSC_boss_trollgore();
AddSC_instance_draktharon_keep();
@@ -745,37 +829,50 @@ void AddScripts()
AddSC_boss_moorabi();
AddSC_boss_sladran();
AddSC_instance_gundrak();
- AddSC_boss_bronjahm(); // ICC, forge_of_souls
- AddSC_boss_devourer_of_souls();
- AddSC_instance_forge_of_souls();
+
AddSC_boss_gafrost(); // ICC, pit_of_saron
AddSC_boss_krick_and_ick();
AddSC_boss_tyrannus();
AddSC_instance_pit_of_saron();
AddSC_pit_of_saron();
+
AddSC_boss_anubrekhan(); //naxxramas
AddSC_boss_four_horsemen();
AddSC_boss_faerlina();
AddSC_boss_gluth();
AddSC_boss_gothik();
- AddSC_boss_grobbulus();
AddSC_boss_kelthuzad();
AddSC_boss_loatheb();
AddSC_boss_maexxna();
AddSC_boss_noth();
+ AddSC_boss_grobbulus();
AddSC_boss_heigan();
AddSC_boss_patchwerk();
AddSC_boss_razuvious();
AddSC_boss_sapphiron();
AddSC_boss_thaddius();
AddSC_instance_naxxramas();
+
AddSC_boss_anomalus(); //nexus
AddSC_boss_keristrasza();
AddSC_boss_ormorok();
AddSC_boss_telestra();
AddSC_instance_nexus();
+
+ AddSC_oculus(); //Oculus
+ AddSC_instance_oculus();
+ AddSC_boss_drakos();
+ AddSC_boss_varos();
+ AddSC_boss_urom();
+ AddSC_boss_eregos();
+
AddSC_boss_sartharion(); //obsidian_sanctum
AddSC_instance_obsidian_sanctum();
+ AddSC_instance_vault_of_archavon(); //vault_of_archavon
+ AddSC_boss_toravon();
+ AddSC_boss_koralon();
+ AddSC_boss_emalon();
+ AddSC_boss_archavon();
AddSC_boss_bjarngrim(); //Ulduar, halls_of_lightning
AddSC_boss_ionar();
AddSC_boss_loken();
@@ -783,23 +880,26 @@ void AddScripts()
AddSC_instance_halls_of_lightning();
AddSC_boss_maiden_of_grief(); //Ulduar, halls_of_stone
AddSC_boss_sjonnir();
+ AddSC_boss_krystallus();
AddSC_halls_of_stone();
AddSC_instance_halls_of_stone();
- AddSC_boss_assembly_of_iron(); //ulduar
- AddSC_boss_algalon();
+ AddSC_boss_algalon(); //Ulduar
AddSC_boss_auriaya();
- AddSC_boss_flame_leviathan();
AddSC_boss_freya();
- AddSC_boss_general_vezax();
AddSC_boss_hodir();
AddSC_boss_ignis();
+ AddSC_boss_iron_council();
AddSC_boss_kologarn();
+ AddSC_boss_leviathan();
AddSC_boss_mimiron();
AddSC_boss_razorscale();
AddSC_boss_thorim();
- AddSC_boss_xt_002();
+ AddSC_boss_vezax();
+ AddSC_boss_xt002();
AddSC_boss_yogg_saron();
AddSC_instance_ulduar();
+ AddSC_ulduar();
+ AddSC_ulduar_teleport();
AddSC_boss_ingvar(); //utgarde_keep
AddSC_boss_keleseth();
AddSC_boss_skarvald_and_dalronn();
@@ -810,15 +910,6 @@ void AddScripts()
AddSC_boss_svala();
AddSC_boss_ymiron();
AddSC_instance_pinnacle();
- AddSC_boss_erekem(); //violet_hold
- AddSC_boss_ichoron();
- AddSC_boss_lavanthor();
- AddSC_boss_moragg();
- AddSC_boss_xevozz();
- AddSC_boss_zuramat();
- AddSC_boss_cyanigosa();
- AddSC_instance_violet_hold();
- AddSC_violet_hold();
AddSC_borean_tundra();
AddSC_dalaran();
@@ -830,6 +921,50 @@ void AddScripts()
AddSC_storm_peaks();
AddSC_zuldrak();
+ AddSC_instance_violet_hold();
+ AddSC_boss_cyanigosa();
+ AddSC_boss_moragg();
+ AddSC_boss_erekem();
+ AddSC_boss_xevozz();
+ AddSC_boss_ichoron();
+ AddSC_boss_zuramat();
+ AddSC_boss_lavanthor();
+ AddSC_violet_hold();
+
+ AddSC_instance_icecrown_spire();
+ AddSC_icecrown_spire();
+ AddSC_icecrown_teleporter();
+ AddSC_boss_lord_marrowgar();
+ AddSC_boss_lady_deathwhisper();
+ AddSC_boss_deathbringer_saurfang();
+ AddSC_boss_rotface();
+ AddSC_boss_festergut();
+ AddSC_boss_proffesor_putricide();
+ AddSC_blood_prince_council();
+ AddSC_boss_blood_queen_lanathel();
+ AddSC_boss_valithria_dreamwalker();
+ AddSC_boss_sindragosa();
+ AddSC_boss_lich_king_icc();
+
+ AddSC_instance_forge_of_souls();
+ AddSC_boss_devourer_of_souls();
+ AddSC_boss_bronjahm();
+ AddSC_trash_forge_of_souls();
+ AddSC_forge_of_souls();
+
+ AddSC_instance_halls_of_reflection();
+ AddSC_halls_of_reflection();
+ AddSC_boss_falric();
+ AddSC_boss_marwyn();
+ AddSC_boss_lich_king_hr();
+
+ AddSC_instance_ruby_sanctum(); // Ruby Sanctum
+ AddSC_ruby_sanctum();
+ AddSC_boss_halion();
+ AddSC_boss_ragefire();
+ AddSC_boss_zarithrian();
+ AddSC_boss_baltharus();
+
//outland
AddSC_boss_exarch_maladaar(); //auchindoun, auchenai_crypts
AddSC_boss_nexusprince_shaffar(); //auchindoun, mana_tombs
@@ -898,6 +1033,16 @@ void AddScripts()
AddSC_boss_pathaleon_the_calculator();
AddSC_instance_mechanar();
+ AddSC_boss_lord_epoch(); //culling of stratholme
+ AddSC_boss_malganis();
+ AddSC_boss_meathook();
+ AddSC_boss_salramm();
+ AddSC_boss_infinite_corruptor();
+ AddSC_culling_of_stratholme();
+ AddSC_culling_of_stratholmeAI();
+ AddSC_instance_culling_of_stratholme();
+ AddSC_trash_culling_of_stratholme();
+
AddSC_blades_edge_mountains();
AddSC_boss_doomlordkazzak();
AddSC_boss_doomwalker();